U
    ]#                     @   s   d Z ddlZddlZddlmZmZmZmZmZm	Z	m
Z
mZmZmZ ddlmZ ddlmZ ddlZeeZG dd deZG dd	 d	eZd
d Zdd Zdd Zdd Zdd ZG dd deZdS )z6Very low-level nginx config parser based on pyparsing.    N)
LiteralWhiteForwardGroupOptional	OneOrMoreQuotedStringRegex
ZeroOrMoreCombine)	stringEnd)
restOfLinec                   @   sn  e Zd ZdZee  Ze  Ze	d
 Zee	d
  Ze	d
 Zeddddd	Zed
dddd	ZeeB ZedZedZeeee Zeee	d ee ZeeB eB Zee eee  e Zee Zee	d e Ze Ze ee eB e eB Z!e eZ"e ee!e  Z#ee"e e# e >  e$e!e e% Z&e&'   dd Z(dd Z)dd Z*dS )RawNginxParserz7A class that parses nginx configuration with pyparsing.{};"TF\)Z	multilineZunquoteResultsZescChar'z(\$\{)|[^{};\s'\"]z(\$\{)|[^{;\s])#c                 C   s
   || _ d S Nsource)selfr    r   ;/usr/lib/python3/dist-packages/certbot_nginx/nginxparser.py__init__6   s    zRawNginxParser.__init__c                 C   s   | j | jS )zReturns the parsed tree.)scriptZparseStringr   r   r   r   r   parse9   s    zRawNginxParser.parsec                 C   s   |    S )z"Returns the parsed tree as a list.)r    ZasListr   r   r   r   as_list=   s    zRawNginxParser.as_listN)+__name__
__module____qualname____doc__r   r   ZleaveWhitespaceZspaceZrequired_spacer   suppressZleft_bracketZright_bracket	semicolonr   ZdquotedZsquotedZquotedr	   Zhead_tokencharsZtail_tokencharsr   r
   Z
tokencharsZparen_quote_extendtokenZwhitespace_token_groupZ
assignmentr   Zcommentr   blockr   contentsZblock_beginZblock_innardsr   r   r   ZparseWithTabsr   r    r!   r   r   r   r   r      s6   
r   c                   @   s*   e Zd ZdZdd Zd	ddZdd ZdS )
RawNginxDumperz>A class that dumps nginx configuration from the provided tree.c                 C   s
   || _ d S r   blocks)r   r-   r   r   r   r   D   s    zRawNginxDumper.__init__Nc                 c   s   |p| j }|D ]}t|tjr&|V  qt|}t|d rN|dV  |sNqt|d trd	|dd V  |dD ]}| 
|gD ]
}|V  qq|dV  qd}t|d tjr|d  dkrd}d	|| V  qdS )z"Iterates the dumped nginx content.r    r   r   r   r   N)r-   
isinstancesixstring_typescopydeepcopyspaceypoplistjoin__iter__strip)r   r-   Zb0itemZ	parameterliner'   r   r   r   r8   G   s(    


 zRawNginxDumper.__iter__c                 C   s
   d | S )z$Return the parsed block as a string.r.   )r7   r   r   r   r   __str__`   s    zRawNginxDumper.__str__)N)r"   r#   r$   r%   r   r8   r<   r   r   r   r   r+   A   s   
r+   c                 C   s   t t|  S )zvParses from a string.

    :param str source: The string to parse
    :returns: The parsed tree
    :rtype: list

    )UnspacedListr   r!   r   r   r   r   loadsh   s    r>   c                 C   s   t |  S )zrParses from a file.

    :param file _file: The file to parse
    :returns: The parsed tree
    :rtype: list

    )r>   read)_filer   r   r   loads   s    rA   c                 C   s   t t| jS )zDump to a string.

    :param UnspacedList block: The parsed tree
    :param int indentation: The number of spaces to indent
    :rtype: str

    )strr+   spacedr,   r   r   r   dumps~   s    rD   c                 C   s   | t| S )zDump to a file.

    :param UnspacedList block: The parsed tree
    :param file _file: The file to dump to
    :param int indentation: The number of spaces to indent
    :rtype: NoneType

    )writerD   )r-   r@   r   r   r   dump   s    	rF   c                 C   s   t | tjr|  p| dkS )Nr.   )r/   r0   r1   isspace)xr   r   r   <lambda>       rI   c                   @   s   e Zd Zd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dZdd Zdd Zdd Zdd Zdd  Zd!d" ZdS )%r=   zIWrap a list [of lists], making any whitespace entries magically invisiblec                 C   s   t t|| _d| _t| | ttt| D ]Z\}}t|trht	|}t
| || |j| j|< q2t|r2d| d | kr2t| | q2d S )NFr   )r2   r3   r6   rC   dirtyr   reversed	enumerater/   r=   __setitem__r4   __delitem__)r   Zlist_sourceientryZsublistr   r   r   r      s    
zUnspacedList.__init__c                 C   s2   t |ts||fS t|ds$t|}||jfS dS )z
        Coerce some inbound object to be appropriately usable in this object

        :param inbound: string or None or list or UnspacedList
        :returns: (coerced UnspacedList or string or None, spaced equivalent)
        :rtype: tuple

        rC   N)r/   r6   hasattrr=   rC   )r   Zinboundr   r   r   _coerce   s
    	

zUnspacedList._coercec                 C   s\   |  |\}}|t| k r$| |nt| j}| j|| t|sRt| || d| _d S NT)rS   len_spaced_positionrC   insertr4   r6   rK   )r   rP   rH   r:   spaced_itemZsliceposr   r   r   rW      s     zUnspacedList.insertc                 C   s8   |  |\}}| j| t|s.t| | d| _d S rT   )rS   rC   appendr4   r6   rK   r   rH   r:   rX   r   r   r   rY      s
    zUnspacedList.appendc                 C   s0   |  |\}}| j| t| | d| _d S rT   )rS   rC   extendr6   rK   rZ   r   r   r   r[      s    zUnspacedList.extendc                 C   s   t | }|| d|_|S rT   )r2   r3   r[   rK   )r   otherlr   r   r   __add__   s    

zUnspacedList.__add__Nc                 C   s   t dd S )Nz&UnspacedList.pop() not yet implementedNotImplementedError)r   _ir   r   r   r5      s    zUnspacedList.popc                 C   s   t dd S )Nz)UnspacedList.remove() not yet implementedr_   )r   _r   r   r   remove   s    zUnspacedList.removec                 C   s   t dd S )Nz*UnspacedList.reverse() not yet implementedr_   r   r   r   r   reverse   s    zUnspacedList.reversec                 C   s   t dd S )Nz'UnspacedList.sort() not yet implementedr_   )r   Z_cmpZ_keyZ_Revr   r   r   sort   s    zUnspacedList.sortc                 C   s   t dd S )N5Slice operations on UnspacedLists not yet implementedr_   )r   ra   Z_jZ	_newslicer   r   r   __setslice__   s    zUnspacedList.__setslice__c                 C   sT   t |trtd| |\}}| j| || t|sJt| || d| _	d S )Nrf   T)
r/   slicer`   rS   rC   rN   rV   r4   r6   rK   )r   rP   valuer:   rX   r   r   r   rN      s    
zUnspacedList.__setitem__c                 C   s(   | j | | t| | d| _d S rT   )rC   rO   rV   r6   rK   )r   rP   r   r   r   rO      s    zUnspacedList.__delitem__c                 C   s$   t j| j|d}t|}| j|_|S )N)memo)r2   r3   rC   r=   rK   )r   rj   Z
new_spacedr]   r   r   r   __deepcopy__   s    zUnspacedList.__deepcopy__c                 C   s   | j r
dS tdd | D S )zFRecurse through the parse tree to figure out if any sublists are dirtyTc                 s   s    | ]}t |to| V  qd S r   )r/   r=   is_dirty).0rH   r   r   r   	<genexpr>   s     z(UnspacedList.is_dirty.<locals>.<genexpr>)rK   anyr   r   r   r   rl      s    zUnspacedList.is_dirtyc                 C   s|   d }}|dk rt | | }d|  kr4t | k s>n td|}|dkrtt| j| rb|d7 }n|d8 }|d7 }qB|| S )zHConvert from indexes in the unspaced list to positions in the spaced oner   zlist index out of range   )rU   
IndexErrorr4   rC   )r   idxposZspacesZidx0r   r   r   rV      s    

zUnspacedList._spaced_position)N)NNN)r"   r#   r$   r%   r   rS   rW   rY   r[   r^   r5   rc   rd   re   rg   rN   rO   rk   rl   rV   r   r   r   r   r=      s"   

	r=   )r%   r2   ZloggingZ	pyparsingr   r   r   r   r   r   r   r	   r
   r   r   r   r0   Z	getLoggerr"   Zloggerobjectr   r+   r>   rA   rD   rF   r4   r6   r=   r   r   r   r   <module>   s   0
3'