patches by Rostislav Beneš: mc-20-dir
[midnight-commander.git] / mhl / escape.h
blob25333884254694698b2fb97cf63d4f2b86b5bcf7
1 #ifndef __MHL_SHELL_ESCAPE_H
2 #define __MHL_SHELL_ESCAPE_H
4 /* Micro helper library: shell escaping functions */
6 #include <string.h>
7 #include <stdlib.h>
9 #define mhl_shell_escape_toesc(x) \
10 (((x)==' ')||((x)=='!')||((x)=='#')||((x)=='$')||((x)=='%')|| \
11 ((x)=='(')||((x)==')')||((x)=='\'')||((x)=='&')||((x)=='~')|| \
12 ((x)=='{')||((x)=='}')||((x)=='[')||((x)==']')||((x)=='`')|| \
13 ((x)=='?')||((x)=='|')||((x)=='<')||((x)=='>')||((x)==';')|| \
14 ((x)=='*')||((x)=='\\')||((x)=='"'))
16 #define mhl_shell_escape_nottoesc(x) \
17 (((x)!=0) && (!mhl_shell_escape_toesc((x))))
19 static inline char* mhl_shell_escape_dup(const char* src)
21 if ((src==NULL)||(!(*src)))
22 return strdup("");
24 char* buffer = calloc(1, strlen(src)*2+2);
25 char* ptr = buffer;
27 /* look for the first char to escape */
28 while (1)
30 char c;
31 /* copy over all chars not to escape */
32 while ((c=(*src)) && mhl_shell_escape_nottoesc(c))
34 *ptr = c;
35 ptr++;
36 src++;
39 /* at this point we either have an \0 or an char to escape */
40 if (!c)
41 return buffer;
43 *ptr = '\\';
44 ptr++;
45 *ptr = c;
46 ptr++;
47 src++;
51 /* shell-unescape within a given buffer (writing to it!) */
52 static inline char* mhl_shell_unescape_buf(char* text)
54 if (!text)
55 return NULL;
57 // look for the first \ - that's quick skipover if there's nothing to escape
58 char* readptr = text;
59 while ((*readptr) && ((*readptr)!='\\')) readptr++;
60 if (!(*readptr)) return text;
62 // if we're here, we're standing on the first '\'
63 char* writeptr = readptr;
64 char c;
65 while ((c = *readptr))
67 if (c=='\\')
69 readptr++;
70 switch ((c = *readptr))
72 case 'n': (*writeptr) = '\n'; writeptr++; break;
73 case 'r': (*writeptr) = '\r'; writeptr++; break;
74 case 't': (*writeptr) = '\t'; writeptr++; break;
76 case ' ':
77 case '\\':
78 case '#':
79 case '$':
80 case '%':
81 case '(':
82 case ')':
83 case '[':
84 case ']':
85 case '{':
86 case '}':
87 case '<':
88 case '>':
89 case '!':
90 case '*':
91 case '?':
92 case '~':
93 case '`':
94 case '"':
95 case ';':
96 default:
97 (*writeptr) = c; writeptr++; break;
100 else // got a normal character
102 (*writeptr) = *readptr;
103 writeptr++;
105 readptr++;
107 *writeptr = 0;
109 return text;
112 #endif