5#include "wvbackslash.h"
9#include "wvstringmask.h"
10#include "wvtclstring.h"
13const WvStringMask WVTCL_NASTY_SPACES(WVTCL_NASTY_SPACES_STR);
14const WvStringMask WVTCL_NASTY_NEWLINES(WVTCL_NASTY_NEWLINES_STR);
15const WvStringMask WVTCL_SPLITCHARS(WVTCL_SPLITCHARS_STR);
17static 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();
145static 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();
250const size_t WVTCL_GETWORD_NONE (UINT_MAX);
252static 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();
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
void rewind()
Rewinds the iterator to make it point to an imaginary element preceeding the first element of the lis...
WvLink * next()
Moves the iterator along the list to point to the next element.
The iterator type for linked lists.
A linked list container class.
void append(T *data, bool autofree, const char *id=NULL)
Appends the element to the end of the list.
A class used to provide a masked lookup for characters in a string.
const char first() const
Get the first character set into the mask.
WvString is an implementation of a simple and efficient printable-string class.
char * edit()
make the string editable, and return a non-const (char*)
WvString wvtcl_encode(WvList< WvString > &l, const WvStringMask &nasties=WVTCL_NASTY_SPACES, const WvStringMask &splitchars=WVTCL_SPLITCHARS)
encode a tcl-style list.
WvString wvtcl_unescape(WvStringParm s)
tcl-unescape a string.
WvString wvtcl_escape(WvStringParm s, const WvStringMask &nasties=WVTCL_NASTY_SPACES)
tcl-escape a string.
WvString wvtcl_getword(WvBuf &buf, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
Get a single tcl word from an input buffer, and return the rest of the buffer untouched.
void wvtcl_decode(WvList< WvString > &l, WvStringParm _s, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
split a tcl-style list.