B
    b<                 @   s  d Z ddlZddlZddlZddlZG dd dejjZG dd deZ	G dd dejjZ
G d	d
 d
e
ZG dd dejjZG dd deZG dd dejjZG dd deZeje eje	 eje
 eje eje eje eje eje G dd dZedejaedejad4ddZddlmZ G dd deZdejjfddZG dd dZd d! Zd"d# Zd$d% Z d&d' Z!d(d) Z"d*d+ Z#d,d- Z$d.d/ Z%d0d1 Z&d2d3 Z'dS )5zOCommon routines for gettext tools

Used by several tools of `gettext` toolset.
    Nc               @   s   e Zd ZdS )XgettextToolWarningN)__name__
__module____qualname__ r   r   7lib/python3.7/site-packages/SCons/Tool/GettextCommon.pyr   #   s   r   c               @   s   e Zd ZdS )XgettextNotFoundN)r   r   r   r   r   r   r   r   '   s   r   c               @   s   e Zd ZdS )MsginitToolWarningN)r   r   r   r   r   r   r   r	   +   s   r	   c               @   s   e Zd ZdS )MsginitNotFoundN)r   r   r   r   r   r   r   r
   /   s   r
   c               @   s   e Zd ZdS )MsgmergeToolWarningN)r   r   r   r   r   r   r   r   3   s   r   c               @   s   e Zd ZdS )MsgmergeNotFoundN)r   r   r   r   r   r   r   r   7   s   r   c               @   s   e Zd ZdS )MsgfmtToolWarningN)r   r   r   r   r   r   r   r   ;   s   r   c               @   s   e Zd ZdS )MsgfmtNotFoundN)r   r   r   r   r   r   r   r   ?   s   r   c               @   s8   e Zd ZdZdddZdddZdd	d
ZdddZdS )_POTargetFactoryz A factory of `PO` target files.

    Factory defaults differ from these of `SCons.Node.FS.FS`.  We set `precious`
    (this is required by builders and actions gettext) and `noclean` flags by
    default for all produced nodes.
    TNc             C   s"   || _ || _|| _|| _|| _dS )ab   Object constructor.

        **Arguments**

            - *env* (`SCons.Environment.Environment`)
            - *nodefault* (`boolean`) - if `True`, produced nodes will be ignored
              from default target `'.'`
            - *alias* (`string`) - if provided, produced nodes will be automatically
              added to this alias, and alias will be set as `AlwaysBuild`
            - *precious* (`boolean`) - if `True`, the produced nodes will be set as
              `Precious`.
            - *noclen* (`boolean`) - if `True`, the produced nodes will be excluded
              from `Clean`.
        N)envaliaspreciousnoclean	nodefault)selfr   r   r   r   r   r   r   r   __init__U   s
    z_POTargetFactory.__init__   c             C   sZ   ||||}| | j || j | jr8| jd| | jrV| j| j	| j| |S )z1 Create node, and set it up to factory settings. .)
Zset_nocleanr   Zset_preciousr   r   r   Ignorer   ZAlwaysBuildZAlias)r   namefactory	directorycreatenoder   r   r   _create_nodek   s    z_POTargetFactory._create_nodec             C   s   |  || jjj||S )z Create `SCons.Node.FS.Entry` )r   r   fsEntry)r   r   r   r   r   r   r   r!   v   s    z_POTargetFactory.Entryc             C   s   |  || jjj||S )z Create `SCons.Node.FS.File` )r   r   r    File)r   r   r   r   r   r   r   r"   z   s    z_POTargetFactory.File)TNTT)Nr   )Nr   )Nr   )r   r   r   __doc__r   r   r!   r"   r   r   r   r   r   M   s    


r   z(#[^\n\r]+)$z([a-zA-Z0-9_]+)c             C   s   t j|s2t j|s2t|t jjjs2|r2dg}|dkr>g S | |}g }x:|D ]2}t	
d| }dd t|D }|| qRW |S )z= Parse `LINGUAS` file and return list of extracted languages ZLINGUASN c             S   s   g | ]}|r|qS r   r   ).0lr   r   r   
<listcomp>   s    z,_read_linguas_from_files.<locals>.<listcomp>)SConsUtilis_ListZ	is_String
isinstanceNodeFSBaseZ	arg2nodes_re_commentsubZget_text_contents_re_langfindallextend)r   linguas_filesZfnodeslinguasZfnodecontentsZlsr   r   r   _read_linguas_from_files   s    

r7   )BuilderBasec                   s(   e Zd ZdZ fddZdd Z  ZS )_POFileBuildera   `PO` file builder.

    This is multi-target single-source builder. In typical situation the source
    is single `POT` file, e.g. `messages.pot`, and there are multiple `PO`
    targets to be updated from this `POT`. We must run
    `SCons.Builder.BuilderBase._execute()` separatelly for each target to track
    dependencies separatelly for each target file.

    **NOTE**: if we call `SCons.Builder.BuilderBase._execute(.., target, ...)`
    with target being list of all targets, all targets would be rebuilt each time
    one of the targets from this list is missing. This would happen, for example,
    when new language `ll` enters `LINGUAS_FILE` (at this moment there is no
    `ll.po` file yet). To avoid this, we override
    `SCons.Builder.BuilerBase._execute()` and call it separatelly for each
    target. Here we also append to the target list the languages read from
    `LINGUAS_FILE`.
    c                s   d|krd|d< d|kr d|d< d|kr0d|d< d|kr@d|d< d }d	|krZ|d	 }|d	= d
|krtt ||dj|d
< t jf | d S )Nsuffixz	$POSUFFIXZ
src_suffixz
$POTSUFFIXZsrc_builderZ_POTUpdateBuilderZsingle_sourceTZtarget_aliasZtarget_factory)r   )r   r"   superr   )r   r   kwr   )	__class__r   r   r      s    z_POFileBuilder.__init__c             O   s   ddl }d}d|krf|d rf|d }d|d< t||}|j|rN|| n|dk	rb|g| }n|}|stj| |||f||S |j|s|g}g }	x0|D ](}
tj| ||
g|f||}|	| qW |dk	r||d< |j|	S )a,   Execute builder's actions.

        Here we append to `target` the languages read from `$LINGUAS_FILE` and
        apply `SCons.Builder.BuilderBase._execute()` separatelly to each target.
        The arguments and return value are same as for
        `SCons.Builder.BuilderBase._execute()`.
        r   NZLINGUAS_FILE)	Z
SCons.Noder7   r)   r*   r3   r8   _executer,   ZNodeList)r   r   targetsourceargsr<   r(   r4   r5   resulttgtrr   r   r   r>      s,    

z_POFileBuilder._execute)r   r   r   r#   r   r>   __classcell__r   r   )r=   r   r9      s   r9   c             O   s8   |dkrg }| j d|f||}| j||f||}|S )z+ Function for `Translate()` pseudo-builder N)Z	POTUpdateZPOUpdate)r   r?   r@   rA   r<   ZpotZpor   r   r   
_translate   s
     rF   c               @   s    e Zd ZdZdd Zdd ZdS )RPathsa)   Callable object, which returns pathnames relative to SCons current
    working directory.

    It seems like `SCons.Node.FS.Base.get_path()` returns absolute paths
    for nodes that are outside of current working directory (`env.fs.getcwd()`).
    Here, we often have `SConscript`, `POT` and `PO` files within `po/`
    directory and source files (e.g. `*.c`) outside of it. When generating `POT`
    template file, references to source files are written to `POT` template, so
    a translator may later quickly jump to appropriate source file and line from
    its `PO` editor (e.g. `poedit`).  Relative paths in  `PO` file are usually
    interpreted by `PO` editor as paths relative to the place, where `PO` file
    lives. The absolute paths would make resultant `POT` file nonportable, as
    the references would be correct only on the machine, where `POT` file was
    recently re-created. For such reason, we need a function, which always
    returns relative paths. This is the purpose of `RPaths` callable object.

    The `__call__` method returns paths relative to current working directory, but
    we assume, that *xgettext(1)* is run from the directory, where target file is
    going to be created.

    Note, that this may not work for files distributed over several hosts or
    across different drives on windows. We assume here, that single local
    filesystem holds both source files and target `POT` templates.

    Intended use of `RPaths` - in `xgettext.py`::

      def generate(env):
          from GettextCommon import RPaths
          ...
          sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET, SOURCES)} $)'
          env.Append(
            ...
            XGETTEXTCOM = 'XGETTEXT ... ' + sources,
            ...
            XgettextRPaths = RPaths(env)
          )
    c             C   s
   || _ dS )z Initialize `RPaths` callable object.

          **Arguments**:

            - *env* - a `SCons.Environment.Environment` object, defines *current
              working dir*.
        N)r   )r   r   r   r   r   r   /  s    zRPaths.__init__c       	      O   sf   ddl }d}| jj  }xD|D ]<}d}t||jjjrLt	j
| |}|dk	r"||f7 }q"W |S )a   Return nodes' paths (strings) relative to current working directory.

          **Arguments**:

            - *nodes* ([`SCons.Node.FS.Base`]) - list of nodes.
            - *args* -  currently unused.
            - *kw* - currently unused.

          **Returns**:

           - Tuple of strings, which represent paths relative to current working
             directory (for given environment).
        r   Nr   )ZSCons.Node.FSr   r    getcwdZget_abspathr+   r,   r-   r.   ospathrelpath)	r   ZnodesrA   r<   r(   Zrpathscwdr   Zrpathr   r   r   __call__;  s    
zRPaths.__call__N)r   r   r   r#   r   rM   r   r   r   r   rG      s   %
rG   c       	      C   s   dd }d|kr|d }nd}xh| D ]`}|  s$|rDtjdd}n*dtt| d d	 d }tj||}||g||}|r$|S q$W d
S )z' Action function for `POInit` builder. c             S   s   dS )Nr   r   )r?   r@   r   r   r   r   <lambda>X      z _init_po_files.<locals>.<lambda>Z
POAUTOINITFz$MSGINITCOMz$MSGINITCOMSTRzFile z does not exist. z5If you are a translator, you can create it through: 
r   )existsr(   ZActionreprstr)	r?   r@   r   ZnopZautoinitrC   actionmsgZstatusr   r   r   _init_po_filesV  s    

 rU   c             C   s4   d| kr| d S |  d}|r"|S tjtddS )z Detects *xgettext(1)* binary ZXGETTEXTxgettextzCould not detect xgettextN)Detectr(   Errors	StopErrorr   )r   rV   r   r   r   _detect_xgettextn  s    
rZ   c             C   s   t | S )N)rZ   )r   r   r   r   _xgettext_existsy  s    r[   c             C   s4   d| kr| d S |  d}|r"|S tjtddS )z Detects *msginit(1)* program. ZMSGINITmsginitzCould not detect msginitN)rW   r(   rX   rY   r
   )r   r\   r   r   r   _detect_msginit}  s    
r]   c             C   s   t | S )N)r]   )r   r   r   r   _msginit_exists  s    r^   c             C   s4   d| kr| d S |  d}|r"|S tjtddS )z  Detects *msgmerge(1)* program. ZMSGMERGEmsgmergezCould not detect msgmergeN)rW   r(   rX   rY   r   )r   r_   r   r   r   _detect_msgmerge  s    
r`   c             C   s   t | S )N)r`   )r   r   r   r   _msgmerge_exists  s    ra   c             C   s4   d| kr| d S |  d}|r"|S tjtddS )z Detects *msgmfmt(1)* program. ZMSGFMTmsgfmtzCould not detect msgfmtN)rW   r(   rX   rY   r   )r   rb   r   r   r   _detect_msgfmt  s    
rc   c             C   s   t | S )N)rc   )r   r   r   r   _msgfmt_exists  s    rd   c             C   s   ddddgS )z@ List tools that shall be generated by top-level `gettext` tool rV   r\   r_   rb   r   )platformr   r   r   r   	tool_list  s    rf   )N)(r#   rI   reZ
SCons.Utilr(   ZSCons.WarningsZWarningsZSConsWarningr   r   r	   r
   r   r   r   r   ZenableWarningClassr   compileMr/   r1   r7   ZSCons.Builderr8   r9   ZEnvironmentZ_nullrF   rG   rU   rZ   r[   r]   r^   r`   ra   rc   rd   rf   r   r   r   r   <module>   sL   2
]V