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();
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
WvString wvtcl_encode(WvList< WvString > &l, const WvStringMask &nasties=WVTCL_NASTY_SPACES, const WvStringMask &splitchars=WVTCL_SPLITCHARS)
encode a tcl-style list.
Functions to handle "tcl-style" strings and lists.
void rewind()
Rewinds the iterator to make it point to an imaginary element preceeding the first element of the lis...
const char first() const
Get the first character set into the mask.
A class used to provide a masked lookup for characters in a string.
WvLink * next()
Moves the iterator along the list to point to the next element.
char * edit()
make the string editable, and return a non-const (char*)
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 append(T *data, bool autofree, const char *id=NULL)
Appends the element to the end of the list.
void wvtcl_decode(WvList< WvString > &l, WvStringParm _s, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
split a tcl-style list.
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers...
size_t used() const
Returns the number of elements in the buffer currently available for reading.
WvString wvtcl_escape(WvStringParm s, const WvStringMask &nasties=WVTCL_NASTY_SPACES)
tcl-escape a string.
A linked list container class.
The iterator type for linked lists.
WvString is an implementation of a simple and efficient printable-string class.
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
WvString wvtcl_unescape(WvStringParm s)
tcl-unescape a string.
void unget(size_t count)
Ungets exactly the specified number of elements by returning them to the buffer for subsequent reads...