a
    ”$aÜR  ã                   @   s   d Z ddlZddlZddlZddlmZmZmZ ddlZej	dkr\ddl
Z
G dd„ deƒZnddlZdZdZd	Zd
ZdZdejej	ef ZdZdZdZdZdZdZdZdZdZdZe ¡ ZdZ dZ!dZ"dZ#g Z$dd„ Z%G dd„ de&ƒZ'e'defi ƒZ(G dd„ de(ƒZ)i Z*d!dd„Z+d"dd „Z,dS )#z3
Classes and functions enabling the command system
é    N)ÚUtilsÚErrorsÚLogsi  c                   @   s   e Zd Zdd„ ZdS )Úimpc                 C   s
   t  | ¡S )N)ÚtypesÚ
ModuleType)Úx© r	   úi/home/jack/SDK/ZBT-AX3000-OpenWrt-21.02/build_dir/hostpkg/samba-4.14.12/third_party/waf/waflib/Context.pyÚ<lambda>   ó    zimp.<lambda>N)Ú__name__Ú
__module__Ú__qualname__Ú
new_moduler	   r	   r	   r
   r      s   r   i  z2.0.21Z(edde20a6425a5c3eb6b47d5f3f5c4fbc93fed5f4Úwafé   z.wafpickle-%s-%d-%dÚAPPNAMEÚVERSIONÚtopÚoutZwscriptÚ é   éÿÿÿÿc                 O   s>   t D ] }|j| kr||i |¤Ž  S qt|i |¤Ž}| |_|S )a¿  
	Returns a new :py:class:`waflib.Context.Context` instance corresponding to the given command.
	Used in particular by :py:func:`waflib.Scripting.run_command`

	:param cmd_name: command name
	:type cmd_name: string
	:param k: arguments to give to the context class initializer
	:type k: list
	:param k: keyword arguments to give to the context class initializer
	:type k: dict
	:return: Context object
	:rtype: :py:class:`waflib.Context.Context`
	)ÚclassesÚcmdÚContextÚfun)Zcmd_nameÚkÚkwr   Úctxr	   r	   r
   Úcreate_contextS   s    
r!   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )Ústore_contexta  
	Metaclass that registers command classes into the list :py:const:`waflib.Context.classes`
	Context classes must provide an attribute 'cmd' representing the command name, and a function
	attribute 'fun' representing the function name that the command uses.
	c                    sv   t t| ƒ |||¡ | j}|dv r&d S z
| j W n  tyP   t d| ¡‚Y n0 t| dd ƒsf| j| _	t
 d| ¡ d S )N)r    r   z.Missing command for the context class %r (cmd)r   r   )Úsuperr"   Ú__init__r   r   ÚAttributeErrorr   ÚWafErrorÚgetattrr   r   Úinsert)ÚclsÚnameÚbasesÚdct©Ú	__class__r	   r
   r$   n   s    
zstore_context.__init__)r   r   r   Ú__doc__r$   Ú__classcell__r	   r	   r-   r
   r"   h   s   r"   r    c                   @   s    e Zd ZdZeZi Zdd„ Zdd„ Zdd„ Z	dd	„ Z
d
d„ Zdd„ Zd$dd„Zdd„ Zdd„ Zdd„ Zd%dd„Zdd„ Zdd„ Zdd„ Zd d!„ Zg fd"d#„ZdS )&r   aÒ  
	Default context for waf commands, and base class for new command contexts.

	Context objects are passed to top-level functions::

		def foo(ctx):
			print(ctx.__class__.__name__) # waflib.Context.Context

	Subclasses must define the class attributes 'cmd' and 'fun':

	:param cmd: command to execute as in ``waf cmd``
	:type cmd: string
	:param fun: function name to execute when the command is called
	:type fun: string

	.. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext

	c                 K   sŠ   z|d }W n t y"   t}Y n0 tdtjjfi ƒ| _d| j_| | j_|  dd ¡| _d | _	| j 
|¡| _g | _| | | | dœ| _d | _d S )NÚrun_dirÚNod3zwaflib.Noder   )r    ÚconfÚbldÚopt)ÚKeyErrorr1   ÚtypeÚwaflibÚNodeZ
node_classr   r    ÚrootÚ
cur_scriptÚfind_dirÚpathÚ
stack_pathÚ	exec_dictÚlogger)Úselfr   Zrdr	   r	   r
   r$       s    
zContext.__init__c                 C   s6   z
| j }W n ty   Y n0 t |¡ t| dƒ dS )z3
		Called to free resources such as logger files
		r@   N)r@   r%   r   Úfree_loggerÚdelattr)rA   r@   r	   r	   r
   Úfinalize³   s    

zContext.finalizec           
      O   sf   t  |¡}t  | dd¡¡}| dd¡}|D ]4}t|||d}t|| d| j¡dƒ}	|	r,|	| ƒ q,dS )a+  
		Loads a Waf tool as a module, and try calling the function named :py:const:`waflib.Context.Context.fun`
		from it.  A ``tooldir`` argument may be provided as a list of module paths.

		:param tool_list: list of Waf tool names to load
		:type tool_list: list of string or space-separated string
		Útooldirr   Úwith_sys_pathT)rF   r*   N)r   Úto_listÚgetÚ	load_toolr'   r   )
rA   Ú	tool_listr   r   Útoolsr=   rF   ÚtÚmoduler   r	   r	   r
   Úload¿   s    
zContext.loadc                 C   s   |   tj tj¡g¡ dS )z‘
		Here, it calls the function name in the top-level wscript file. Most subclasses
		redefine this method to provide additional functionality.
		N)ÚrecurseÚosr=   ÚdirnameÚg_moduleZ	root_path)rA   r	   r	   r
   ÚexecuteÑ   s    zContext.executec                 C   s    | j  | j¡ || _|j| _dS )a!  
		Method executed immediately before a folder is read by :py:meth:`waflib.Context.Context.recurse`.
		The current script is bound as a Node object on ``self.cur_script``, and the current path
		is bound to ``self.path``

		:param node: script
		:type node: :py:class:`waflib.Node.Node`
		N)r>   Úappendr;   Úparentr=   ©rA   Únoder	   r	   r
   Úpre_recurseØ   s    	zContext.pre_recursec                 C   s    | j  ¡ | _| jr| jj| _dS )z¸
		Restores ``self.cur_script`` and ``self.path`` right after :py:meth:`waflib.Context.Context.recurse` terminates.

		:param node: script
		:type node: :py:class:`waflib.Node.Node`
		N)r>   Úpopr;   rU   r=   rV   r	   r	   r
   Úpost_recurseæ   s    zContext.post_recurseNTc              
   C   s  z
| j }W n ty&   i  }| _ Y n0 t |¡D ]Ê}tj |¡sXtj | j ¡ |¡}tj |t	¡}|d |pt| j
 }	| j |	¡}
|
rè|r”|
|vrèd||
< |  |
¡ z2|
 d|¡}tt||
 ¡ dƒ| jƒ W |  |
¡ n|  |
¡ 0 q2|
s2| j |¡}
|
|p| j
f}|
r²|r||vr²d||< |  |
¡ zrt|
 ¡ |d}t||pP| j
dƒ}|sŽ|spW |  |
¡ q2t d|p€| j
|
 ¡ f ¡‚|| ƒ W |  |
¡ n|  |
¡ 0 q2|
s2|s¾q2zt |¡ W n" tyî   t d| ¡‚Y n0 t d	| ¡‚q2dS )
aÅ  
		Runs user-provided functions from the supplied list of directories.
		The directories can be either absolute, or relative to the directory
		of the wscript file

		The methods :py:meth:`waflib.Context.Context.pre_recurse` and
		:py:meth:`waflib.Context.Context.post_recurse` are called immediately before
		and after a script has been executed.

		:param dirs: List of directories to visit
		:type dirs: list of string or space-separated string
		:param name: Name of function to invoke from the wscript
		:type  name: string
		:param mandatory: whether sub wscript files are required to exist
		:type  mandatory: bool
		:param once: read the script file once for a particular context
		:type once: bool
		Ú_TÚrÚexec)ÚencodingNzNo function %r defined in %szCannot read the folder %rzNo wscript file in directory %s)Zrecurse_cacher%   r   rG   rP   r=   ÚisabsÚjoinÚabspathÚWSCRIPT_FILEr   r:   Ú	find_noderX   Úreadr]   Úcompiler?   rZ   Úload_moduler'   r   r&   ÚlistdirÚOSError)rA   Údirsr*   Ú	mandatoryÚoncer^   ÚcacheÚdZWSCRIPTZWSCRIPT_FUNrW   Zfunction_codeÚtupZwscript_moduleÚuser_functionr	   r	   r
   rO   ñ   sT    



ü
zContext.recursec                 C   sJ   t jrFtj d¡}|dkr.t|tƒs.t |¡}t  	d|¡ t  	d|¡ d S )NZWAF_CMD_FORMATÚstringz
runner: %rzrunner_env: kw=%s)
r   ÚverboserP   ÚenvironrH   Ú
isinstanceÚstrr   Úshell_escapeÚdebug)rA   r   r   Úfmtr	   r	   r
   Úlog_command4  s    

zContext.log_commandc           
   
   K   s  t j}t|tƒ|d< |  ||¡ | jr2| j |¡ d|vrD|j|d< d|vrV|j|d< tj	r„|d s„t  
|d ¡s„t d|d  ¡‚i }d|v r¼tjdkr¶|d |d< d|vr¶d	|d< |d= d
|v rè|d
 râ|d
 |d
< |j|d< |d
= d|v rt|d tƒs|d  ¡ |d< | dt¡}zt  |||¡\}}}W n< tyr }	 z"tjdt|	ƒ |	d‚W Y d}	~	n
d}	~	0 0 |rÂt|tƒs”|j|dd}| jr¬| j d|¡ ntj|tjddœd |rt|tƒsâ|j|dd}| jrü| j d| ¡ ntj|tjddœd |S )a.  
		Runs an external process and returns the exit status::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		If the context has the attribute 'log', then captures and logs the process stderr/stdout.
		Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the
		stdout/stderr values captured.

		:param cmd: command argument for subprocess.Popen
		:type cmd: string or list
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: process exit status
		:rtype: integer
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure
		ÚshellÚstdoutÚstderrr   zProgram %s not found!Útimeouté  Ústart_new_sessionTÚinputÚstdinÚcwdÚ	decode_asúExecution failure: %s©ÚexNÚreplace©Úerrorsúout: %sr   )ÚstreamÚc1)Úextraúerr: %s)r   Ú
subprocessrs   rt   rx   r@   ÚinfoÚPIPEr   rq   Ú	check_exer   r&   ÚsysÚ
hexversionra   rY   Údefault_encodingÚrun_processÚ	ExceptionÚdecoderv   rz   Úerrorr{   )
rA   r   r   rŽ   Úcargsr^   Úretr   ÚerrÚer	   r	   r
   Úexec_command=  sX    




,zContext.exec_commandc              
   K   sP  t j}t|tƒ|d< |  ||¡ | dd¡}| dt¡}tjrf|d sft  	|d ¡sft
 d|d  ¡‚|j |d< |d< |du rŠ|  |¡ i }d	|v rÂtjd
kr¼|d	 |d	< d|vr¼d|d< |d	= d|v rî|d rè|d |d< |j|d< |d= d|v rt|d tƒs|d  ¡ |d< | dt¡}zt  |||¡\}}	}
W n< tyx } z"t
jdt|ƒ |d‚W Y d}~n
d}~0 0 t|	tƒs”|	j|dd}	t|
tƒs®|
j|dd}
|	rÖ|tkrÖ|tkrÖ|  d|	 ¡ |
rþ|tkrþ|tkrþ|  d|
 ¡ |r,t
 d||f ¡}||_|
|_|	|_|‚|tkr>|	|
fS |tkrL|
S |	S )a»  
		Executes a process and returns stdout/stderr if the execution is successful.
		An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
		will be bound to the WafError object (configuration tests)::

			def configure(conf):
				out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(cmd, input='\n'.encode(), output=waflib.Context.STDOUT)
				try:
					conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
				except Errors.WafError as e:
					print(e.stdout, e.stderr)

		:param cmd: args for subprocess.Popen
		:type cmd: list or string
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: a tuple containing the contents of stdout and stderr
		:rtype: string
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object
		ry   ÚquietNÚoutputr   zProgram %r not found!rz   r{   r|   r}   r~   Tr   r€   r   r‚   rƒ   r„   r†   r‡   r‰   r   zCommand %r returned %r)r   rŽ   rs   rt   rx   rY   ÚSTDOUTr   rq   r‘   r   r&   r   Úto_logr’   r“   ra   r”   r•   r–   r—   ÚBOTHÚSTDERRÚ
returncoder{   rz   )rA   r   r   rŽ   rž   Zto_retr™   r^   rš   r   r›   rœ   r	   r	   r
   Úcmd_and_logŠ  sb    



,

zContext.cmd_and_logc                 C   s†   | j r | j  d| j ¡ |f ¡ z| j jd j}W n tyD   Y n.0 tj 	d¡rfd|t
 |¡f }nd||f }| jj||d‚dS )af  
		Prints an error message in red and stops command execution; this is
		usually used in the configuration section::

			def configure(conf):
				conf.fatal('a requirement is missing')

		:param msg: message to display
		:type msg: string
		:param ex: optional exception object
		:type ex: exception
		:raises: :py:class:`waflib.Errors.ConfigurationError`
		zfrom %s: %sr   ZWAF_PRINT_FAILURE_LOGzLog from (%s):
%s
z%s
(complete log in %s)r„   N)r@   r   r=   ra   ÚhandlersÚbaseFilenamer%   rP   rr   rH   r   Úreadfrˆ   ÚConfigurationError)rA   Úmsgr…   Zlogfiler	   r	   r
   Úfatalß  s    zContext.fatalc                 C   s:   |sdS | j r| j  |¡ ntj t|ƒ¡ tj ¡  dS )a  
		Logs information to the logger (if present), or to stderr.
		Empty messages are not printed::

			def build(bld):
				bld.to_log('starting the build')

		Provide a logger on the context class or override this method if necessary.

		:param msg: message
		:type msg: string
		N)r@   r   r’   r{   Úwritert   Úflush)rA   rª   r	   r	   r
   r¡   û  s    zContext.to_logc                 O   sš   z|d }W n t y&   |d }Y n0 | j|fi |¤Ž z|d }W n t y`   |d }Y n0 | d¡}t|tƒs‚|r~dp€d}| j||fi |¤Ž dS )	a  
		Prints a configuration message of the form ``msg: result``.
		The second part of the message will be in colors. The output
		can be disabled easily by setting ``in_msg`` to a positive value::

			def configure(conf):
				self.in_msg = 1
				conf.msg('Checking for library foo', 'ok')
				# no output

		:param msg: message to display to the user
		:type msg: string
		:param result: result to display
		:type result: string or boolean
		:param color: color to use, see :py:const:`waflib.Logs.colors_lst`
		:type color: string
		rª   r   Úresultr   ÚcolorÚGREENÚYELLOWN)r6   Ú	start_msgrH   rs   rt   Úend_msg)rA   r   r   rª   r®   r¯   r	   r	   r
   rª     s    

zContext.msgc                 O   sÞ   |  d¡rdS |  d¡p|d }z| jr<|  jd7  _W dS W n tyV   d| _Y n0 |  jd7  _zt| jt|ƒƒ| _W n" tyž   tdt|ƒƒ| _Y n0 | jd |fD ]}|  |¡ q®tjdd	| 	| j¡ d
d dS )ze
		Prints the beginning of a 'Checking for xxx' message. See :py:meth:`waflib.Context.Context.msg`
		rž   Nrª   r   r   é(   ú-ÚNORMALz%s :r   )Úsep)
rH   Úin_msgr%   ÚmaxZ	line_justÚlenr¡   r   ÚpprintÚljust)rA   r   r   rª   r   r	   r	   r
   r²   5  s"    

zContext.start_msgc                 O   sÂ   |  d¡rdS |  jd8  _| jr&dS |  d¡p6|d }d}|du rJd}n|sXd	}d
}nt|ƒ}|  |¡ z|d }W n: ty°   t|ƒdkr¨|d tjv r¨|d }n|}Y n0 t ||¡ dS )zUPrints the end of a 'Checking for' message. See :py:meth:`waflib.Context.Context.msg`rž   Nr   r®   r   r°   TÚokz	not foundr±   r¯   )	rH   r¸   rt   r¡   r6   rº   r   Ú
colors_lstr»   )rA   r   r   r®   Zdefcolorrª   r¯   r	   r	   r
   r³   M  s*    



zContext.end_msgc                 C   sÞ   t j t¡rL| j t¡ d¡ |¡}|D ] }|j|vr(t|j 	dd¡ƒ q(nŽddl
m} |tƒ}| ¡ }|D ]l}t d| 	dd¡ |¡sŠqlt j |¡}d	}|D ] }	|	 	dd¡}
t |
|¡ržd
}qž|sl| 	dd¡}t|ƒ qldS )a   
		Loads third-party extensions modules for certain programming languages
		by trying to list certain files in the extras/ directory. This method
		is typically called once for a programming language group, see for
		example :py:mod:`waflib.Tools.compiler_c`

		:param var: glob expression, for example 'cxx\_\*.py'
		:type var: string
		:param ban: list of exact file names to exclude
		:type ban: list of string
		zwaflib/extrasz.pyr   r   )Ú	PyZipFilezwaflib/extras/%sÚ*z.*FTN)rP   r=   ÚisdirÚwaf_dirr:   rc   Úant_globr*   rI   r†   Úzipfiler¿   ZnamelistÚreÚmatchÚbasename)rA   ÚvarZbanÚlstr   r¿   ZwaflibsÚfZdobanÚbr\   r	   r	   r
   Úload_special_toolsk  s(    
zContext.load_special_tools)NTTN)N)r   r   r   r/   r   rˆ   rK   r$   rD   rN   rS   rX   rZ   rO   rx   r   r¥   r«   r¡   rª   r²   r³   rÌ   r	   r	   r	   r
   r   ‚   s&   
C	MU
$r   c              	   C   s¸   z
t |  W S  ty   Y n0 t t¡}ztj| d|d}W n  ty\   t 	d|  ¡‚Y n0 t
j | ¡}tj d|¡ z$tt|| dƒ|jƒ W tj |¡ ntj |¡ 0 |t | < |S )zÎ
	Loads a wscript file as a python module. This method caches results in :py:attr:`waflib.Context.cache_modules`

	:param path: file path
	:type path: string
	:return: Loaded Python module
	:rtype: module
	r\   )Úmr^   zCould not read the file %rr   r]   )Úcache_modulesr6   r   r   rb   r   r¨   ÚEnvironmentErrorr   r&   rP   r=   rQ   r’   r(   r]   re   Ú__dict__Úremove)r=   r^   rM   ÚcodeZ
module_dirr	   r	   r
   rf   “  s     	

rf   Tc           	   
   C   s  | dkrd} n|   dd¡} |s*tj}g t_zÈ|rìt|tƒs@J ‚|tj t_zZzt| ƒ W n2 tyŒ } zttjƒ|_‚ W Y d}~n
d}~0 0 W |D ]}tj |¡ q”n|D ]}tj |¡ q¬0 tj	|  }|t
j| < |W |sêt j|7  _S |s tj dt¡ z–zJdD ]8}zt||  ƒ W  qJW n ty<   d}Y n0 qt| ƒ W n4 ty€ } zttjƒ|_‚ W Y d}~n
d}~0 0 W |s¬tj t¡ n|sªtj t¡ 0 tj	||   }|t
j| < |W |sÜt j|7  _S W |st j|7  _n|s
t j|7  _0 dS )a  
	Imports a Waf tool as a python module, and stores it in the dict :py:const:`waflib.Context.Context.tools`

	:type  tool: string
	:param tool: Name of the tool
	:type  tooldir: list
	:param tooldir: List of directories to search for the tool module
	:type  with_sys_path: boolean
	:param with_sys_path: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs
	ÚjavaZjavawz++ZxxNr   )zwaflib.Tools.%szwaflib.extras.%sz	waflib.%sz%s)r†   r’   r=   rs   ÚlistÚ
__import__ÚImportErrorÚwaf_sys_pathrÑ   Úmodulesr   rK   r(   rÂ   )	ÚtoolrE   r    rF   Z	back_pathrœ   rm   rš   r   r	   r	   r
   rI   ±  sh    ÿ

èÿ
ýÿrI   )N)NNT)-r/   rP   rÅ   r’   r8   r   r   r   Zwaflib.Noder“   r   Úobjectr   Ú
HEXVERSIONÚ
WAFVERSIONÚWAFREVISIONÚWAFNAMEÚABIÚplatformZDBFILEr   r   ÚTOPÚOUTrb   Ú
launch_dirr1   Útop_dirÚout_dirrÂ   Úconsole_encodingr”   rR   r    r£   r¢   r   r!   r7   r"   r    r   rÎ   rf   rI   r	   r	   r	   r
   Ú<module>   sP   
    
