5 #include "wvbackslash.h"
9 #include "wvstringmask.h"
13 const WvStringMask WVTCL_NASTY_SPACES(WVTCL_NASTY_SPACES_STR);
14 const WvStringMask WVTCL_NASTY_NEWLINES(WVTCL_NASTY_NEWLINES_STR);
15 const WvStringMask WVTCL_SPLITCHARS(WVTCL_SPLITCHARS_STR);
17 static size_t wvtcl_escape(
char *dst,
const char *s,
size_t s_len,
20 if (verbatim) *verbatim =
false;
36 bool backslashify =
false, inescape =
false;
37 int len = 0, unprintables = 0, bracecount = 0;
38 const char *cptr, *cptr_end = s + s_len;
43 for (cptr = s; cptr != cptr_end; cptr++)
46 if (dst) dst[len] = *cptr;
49 if (!inescape && *cptr ==
'{')
51 else if (!inescape && *cptr ==
'}')
59 case WVTCL_ALWAYS_NASTY_CASE:
76 if (bracecount != 0 || inescape)
79 if (!backslashify && !unprintables)
81 if (verbatim) *verbatim =
true;
90 for (cptr = s; cptr != cptr_end; ++cptr)
95 case WVTCL_ALWAYS_NASTY_CASE:
109 else return len+unprintables;
118 for (cptr = s; cptr != cptr_end; ++cptr)
130 size_t s_len = s.len();
133 size_t len =
wvtcl_escape(NULL, s, s_len, nasties, &verbatim);
134 if (verbatim)
return s;
138 char *e = result.
edit();
145 static size_t wvtcl_unescape(
char *dst,
const char *s,
size_t s_len,
146 bool *verbatim = NULL)
153 if (verbatim) *verbatim =
true;
157 if (verbatim) *verbatim =
false;
160 if (s[0] ==
'{' && s[s_len-1] ==
'}')
162 if (dst) memcpy(dst, &s[1], s_len-2);
166 bool skipquotes =
false;
168 if (s[0] ==
'"' && s[s_len-1] ==
'"')
172 const char *start = s, *end = &s[s_len];
179 bool inescape =
false;
180 for (; start != end; ++start)
186 if (dst) dst[len] = *start;
196 if (dst) dst[len] = *start;
206 size_t s_len = s.len();
210 if (verbatim)
return s;
213 result.setsize(len+1);
214 char *e = result.
edit();
235 result.setsize(size+(count-1)+1);
237 char *p = result.
edit();
243 *p++ = splitchars.
first();
250 const size_t WVTCL_GETWORD_NONE (UINT_MAX);
252 static size_t wvtcl_getword(
char *dst,
const char *s,
size_t s_len,
254 bool do_unescape,
size_t *end = NULL)
257 if (!s_len)
return WVTCL_GETWORD_NONE;
259 bool inescape =
false, inquote =
false, incontinuation =
false;
261 const char *origend = s + s_len;
262 const char *sptr, *eptr;
265 for (sptr = s; sptr != origend; sptr++)
267 if (!splitchars[*sptr])
272 return WVTCL_GETWORD_NONE;
284 for (; eptr != origend; eptr++)
288 incontinuation =
false;
305 incontinuation =
true;
327 else if (splitchars[ch])
336 else if (bracecount > 0 && ch ==
'}')
342 if (bracecount || sptr==eptr || inquote || inescape || incontinuation)
344 return WVTCL_GETWORD_NONE;
347 if (end) *end = eptr - s;
353 if (dst) memcpy(dst, sptr, eptr-sptr);
362 int origsize = buf.
used();
363 const char *origptr = (
const char *)buf.
get(origsize);
367 splitchars, do_unescape, &end);
368 if (len == WVTCL_GETWORD_NONE)
371 return WvString::null;
375 result.setsize(len+1);
376 char *e = result.
edit();
377 e +=
wvtcl_getword(e, origptr, origsize, splitchars, do_unescape);
380 buf.
unget(origsize - end);
390 size_t s_len = _s.len();
395 splitchars, do_unescape, &end);
396 if (len == WVTCL_GETWORD_NONE)
400 word->setsize(len+1);
402 char *e = word->
edit();