- # -*- coding: utf-8 -*- 
- # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- # See https://llvm.org/LICENSE.txt for license information. 
- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- """ This module implements basic shell escaping/unescaping methods. """ 
-   
- import re 
- import shlex 
-   
- __all__ = ['encode', 'decode'] 
-   
-   
- def encode(command): 
-     """ Takes a command as list and returns a string. """ 
-   
-     def needs_quote(word): 
-         """ Returns true if arguments needs to be protected by quotes. 
-   
-         Previous implementation was shlex.split method, but that's not good 
-         for this job. Currently is running through the string with a basic 
-         state checking. """ 
-   
-         reserved = {' ', '$', '%', '&', '(', ')', '[', ']', '{', '}', '*', '|', 
-                     '<', '>', '@', '?', '!'} 
-         state = 0 
-         for current in word: 
-             if state == 0 and current in reserved: 
-                 return True 
-             elif state == 0 and current == '\\': 
-                 state = 1 
-             elif state == 1 and current in reserved | {'\\'}: 
-                 state = 0 
-             elif state == 0 and current == '"': 
-                 state = 2 
-             elif state == 2 and current == '"': 
-                 state = 0 
-             elif state == 0 and current == "'": 
-                 state = 3 
-             elif state == 3 and current == "'": 
-                 state = 0 
-         return state != 0 
-   
-     def escape(word): 
-         """ Do protect argument if that's needed. """ 
-   
-         table = {'\\': '\\\\', '"': '\\"'} 
-         escaped = ''.join([table.get(c, c) for c in word]) 
-   
-         return '"' + escaped + '"' if needs_quote(word) else escaped 
-   
-     return " ".join([escape(arg) for arg in command]) 
-   
-   
- def decode(string): 
-     """ Takes a command string and returns as a list. """ 
-   
-     def unescape(arg): 
-         """ Gets rid of the escaping characters. """ 
-   
-         if len(arg) >= 2 and arg[0] == arg[-1] and arg[0] == '"': 
-             arg = arg[1:-1] 
-             return re.sub(r'\\(["\\])', r'\1', arg) 
-         return re.sub(r'\\([\\ $%&\(\)\[\]\{\}\*|<>@?!])', r'\1', arg) 
-   
-     return [unescape(arg) for arg in shlex.split(string)] 
-