00001
00002
00003
00004
00005
#include "wvtclstring.h"
00006
#include "wvbackslash.h"
00007
#include "wvbuf.h"
00008
#include <wvstream.h>
00009
00010 WvString wvtcl_escape(
WvStringParm s,
const char *nasties)
00011 {
00012
WvString allnasties(
WVTCL_ALWAYS_NASTY);
00013 allnasties.
append(nasties);
00014
00015
bool backslashify =
false, inescape =
false;
00016
int unprintables = 0, bracecount = 0;
00017
const char *cptr;
00018
00019
00020
if (!(
const char *)s)
00021
return s;
00022
00023
00024
if (!s)
00025
return "{}";
00026
00027
00028
00029
00030
for (cptr = s; *cptr; cptr++)
00031 {
00032
if (!inescape && *cptr ==
'{')
00033 bracecount++;
00034
else if (!inescape && *cptr ==
'}')
00035 bracecount--;
00036
if (bracecount < 0)
00037 backslashify =
true;
00038
00039
if (strchr(allnasties.
cstr(), *cptr))
00040 unprintables++;
00041
00042
if (*cptr ==
'\\')
00043 inescape = !inescape;
00044
else
00045 inescape =
false;
00046 }
00047
00048
00049
if (bracecount != 0)
00050 backslashify =
true;
00051
00052
if (!backslashify && !unprintables)
00053
return s;
00054
00055
if (backslashify)
00056 {
00057
00058
return WvBackslashEncoder(allnasties).strflushstr(s,
true);
00059 }
00060
else
00061 {
00062
00063
return WvString(
"{%s}", s);
00064 }
00065 }
00066
00067
00068 WvString wvtcl_unescape(
WvStringParm s)
00069 {
00070
00071
00072
00073
if (!s)
00074
return s;
00075
00076
int slen = s.
len();
00077
bool skipquotes =
false;
00078
00079
00080
if (s[0] ==
'{' && s[slen-1] ==
'}')
00081 {
00082
WvString out;
00083
char *optr;
00084
00085 out = s+1;
00086 optr = out.
edit() + slen - 2;
00087 *optr = 0;
00088
return out;
00089 }
00090
00091
00092
if (s[0] ==
'"' && s[slen-1] ==
'"')
00093 skipquotes =
true;
00094
00095
00096
if (!skipquotes && !strchr(s,
'\\'))
00097
return s;
00098
00099
00100
return WvBackslashDecoder().strflushmem(
00101 s.cstr() + int(skipquotes),
00102 slen - int(skipquotes) * 2,
true);
00103 }
00104
00105
00106 WvString wvtcl_encode(
WvList<WvString> &l,
const char *nasties,
00107
const char *splitchars)
00108 {
00109
WvDynBuf b;
00110
WvList<WvString>::Iter i(l);
00111
for (i.rewind(); i.next(); )
00112 {
00113
00114
if (b.
used())
00115 b.
put(splitchars, 1);
00116
00117
00118 b.putstr(
wvtcl_escape(*i, nasties));
00119 }
00120
00121
return b.getstr();
00122 }
00123
00124 WvString wvtcl_getword(
WvBuf &buf,
const char *splitchars,
bool do_unescape)
00125 {
00126
int origsize = buf.
used();
00127
if (origsize == 0)
00128
return WvString::null;
00129
00130
bool inescape =
false;
00131
bool inquote =
false;
00132
bool incontinuation =
false;
00133
int bracecount = 0;
00134
const char *sptr = (
const char*)buf.
get(origsize);
00135
int len = 0;
00136
00137
00138
while (strchr(splitchars, *sptr) && origsize > 0)
00139 {
00140 sptr++;
00141 origsize--;
00142 }
00143
00144
if (origsize == 0)
00145
return WvString::null;
00146
00147
00148
if (*sptr ==
'"')
00149 {
00150 inquote =
true;
00151 len = 1;
00152 }
00153
00154
00155
for (; len < origsize; ++len)
00156 {
00157
char ch = sptr[len];
00158
00159
00160
00161
00162 incontinuation =
false;
00163
if (inescape)
00164 {
00165
if (ch ==
'\n')
00166
00167 incontinuation =
true;
00168
else
00169 inescape =
false;
00170
continue;
00171 }
00172
else
00173 {
00174
if (ch ==
'\\')
00175 {
00176 inescape =
true;
00177
continue;
00178 }
00179 }
00180
00181
00182
if (bracecount == 0)
00183 {
00184
if (inquote)
00185 {
00186
if (ch ==
'"')
00187 {
00188 len += 1;
00189
goto returnstring;
00190 }
00191 }
00192
else
00193 {
00194
if (strchr(splitchars, ch))
00195 {
00196 origsize -= 1;
00197
goto returnstring;
00198 }
00199 }
00200 }
00201
00202
if (! inquote)
00203 {
00204
if (ch ==
'{')
00205 bracecount += 1;
00206
else if (ch ==
'}')
00207 bracecount -= 1;
00208 }
00209 }
00210
00211
00212
if (bracecount == 0 && len != 0 && !inquote && !inescape && !incontinuation)
00213
goto returnstring;
00214
00215
00216 buf.
unget(origsize);
00217
return WvString::null;
00218
00219 returnstring:
00220
char *str = (
char*) alloca(len + 1);
00221 memcpy(str, sptr, len);
00222 str[len] =
'\0';
00223 buf.
unget(origsize - len);
00224
00225
if (do_unescape)
00226
return wvtcl_unescape(str).
unique();
00227
return WvString(str).unique();
00228 }
00229
00230 void wvtcl_decode(
WvList<WvString> &l,
WvStringParm _s,
00231
const char *splitchars,
bool do_unescape)
00232 {
00233
00234
if (!_s)
00235
return;
00236
00237
WvConstStringBuffer buf(_s);
00238
while (buf.
used() > 0)
00239 {
00240
WvString appendword =
wvtcl_getword(buf, splitchars, do_unescape);
00241
if (! appendword.
isnull())
00242 {
00243 l.
append(
new WvString(appendword),
true);
00244 }
00245
else
00246
break;
00247 }
00248 }