23#define errno GetLastError()
24#define strcasecmp _stricmp
43 p =
string + strlen(
string) - 1;
46 if (*p ==
'\r' || *p ==
'\n')
71 q =
string + strlen(
string) - 1;
73 while (q >= p && isspace(*q))
93 while (*p != 0 && *p != c)
116 size_t alen = strlen(a);
117 size_t blen = strlen(b);
122 while (a[alen-1] == sep)
129 s.setsize(alen + blen + 2);
130 char *cptr = s.
edit();
132 memcpy(cptr, a, alen);
141 while (b[boffset] == sep)
146 memcpy(cptr+alen+1, b.
cstr()+boffset, blen-boffset);
147 cptr[alen+1+blen-boffset] = 0;
163 if (isspace(*
string))
164 buf.putstr(
" ");
171 char *nbstr =
new char[s.len() + 1];
172 return strcpy(nbstr, s.
edit());
180 char *
string = (
char *)_string;
181 for (
int i=0; i < length; i++)
182 if (*(
string+i) == c1)
193 char *p = strstr(haystack, needle);
194 if(!p || p != haystack)
197 return haystack + strlen(needle);
247 const unsigned char *buf = (
const unsigned char *)_buf;
248 size_t count, count2, top;
251 out.setsize(len / 16 * 80 + 80);
252 char *cptr = out.
edit();
254 for (count = 0; count < len; count+=16)
256 top = len-count < 16 ? len-count : 16;
257 cptr += sprintf(cptr,
"[%03X] ", (
unsigned int)count);
260 for (count2 = 0; count2 < top; count2++)
262 if (count2 && !(count2 % 4))
264 cptr += sprintf(cptr,
"%02X", buf[count+count2]);
268 for (count2 = top; count2 < 16; count2++)
270 if (count2 && !(count2 % 4))
287 for (count2 = 0; count2 < top; count2++)
291 *cptr++ = (isprint(buf[count+count2])
292 ? buf[count+count2] :
'.');
306 return c==
'\n' || c==
'\r';
318 const char *idx1, *idx2;
319 static const char hex[] =
"0123456789ABCDEF";
323 out.setsize(strlen(in) + 1);
326 for (iptr = in, optr = out.
edit(); *iptr; iptr++)
328 if (*iptr ==
'+' && !no_space)
330 else if (*iptr ==
'%' && iptr[1] && iptr[2])
332 idx1 = strchr(hex, toupper((
unsigned char) iptr[1]));
333 idx2 = strchr(hex, toupper((
unsigned char) iptr[2]));
336 *optr++ = ((idx1 - hex) << 4) | (idx2 - hex);
356 for (i=0; i < str.len(); i++)
358 if (((!!unsafe && !strchr(unsafe, str[i])) ||
359 (!unsafe && (isalnum(str[i]) || strchr(
"_.!~*'()-", str[i])))) &&
362 retval.
put(&str[i], 1);
367 sprintf(buf,
"%%%02X", str[i] & 0xff);
372 return retval.getstr();
379 double diff = difftime(t1, t2);
382 if(diff > (60 * 60 * 24))
384 sprintf(out,
"%.1f day(s)", diff / (60 * 60 * 24));
385 else if(diff > (60 * 60))
386 sprintf(out,
"%.0f hour(s)", diff / (60 * 60));
388 sprintf(out,
"%.0f minute(s)", diff / 60);
390 sprintf(out,
"%.0f second(s)", diff);
403 struct tm *tmwhen = localtime(&when);
404 strftime(out.
edit(), 80,
"%a, %d %b %Y %H:%M:%S %z", tmwhen);
417 s2.setsize(s1.len() * 2 + 1);
420 char *p2 = s2.
edit();
437 while ((p=strchr(p, c)) != NULL && p++)
449 WvStringList::Iter i(fqdnlist);
452 for (i.rewind(); i.next(); )
453 dn.append(
"dc=%s,", *i);
463 char *optr, *optr_start;
467 nice.setsize(name.len() + 2);
470 optr = optr_start = nice.
edit();
471 if (!isascii(*iptr) || !isalnum(*(
const unsigned char *)iptr))
474 last_was_dash =
false;
475 for (; *iptr; iptr++)
480 if (*iptr ==
'-' || *iptr ==
'_')
484 last_was_dash =
true;
487 else if (isalnum(*(
const unsigned char *)iptr) || *iptr ==
'.')
490 last_was_dash =
false;
494 if (optr > optr_start && !isalnum(*(
const unsigned char *)(optr-1)))
509 char *cptr = strrchr(tmp.
edit(),
'/');
526 char *cptr = strrchr(tmp.edit(),
'/');
533 return getdirname(tmp);
552 unsigned long long base;
560 {
"M", 1000ull * 1000ull },
561 {
"G", 1000ull * 1000ull * 1000ull },
562 {
"T", 1000ull * 1000ull * 1000ull * 1000ull },
563 {
"P", 1000ull * 1000ull * 1000ull * 1000ull * 1000ull},
564 {
"E", 1000ull * 1000ull * 1000ull * 1000ull * 1000ull * 1000ull},
575 {
"Mi", 1024ull * 1024ull},
576 {
"Gi", 1024ull * 1024ull * 1024ull },
577 {
"Ti", 1024ull * 1024ull * 1024ull * 1024ull },
578 {
"Pi", 1024ull * 1024ull * 1024ull * 1024ull * 1024ull},
579 {
"Ei", 1024ull * 1024ull * 1024ull * 1024ull * 1024ull * 1024ull},
587static inline unsigned long long _sizetoa_rounder(RoundingMethod method,
588 unsigned long long size,
589 unsigned long long remainder,
590 unsigned long long base)
592 unsigned long long half = base / 2;
593 unsigned long long significant_digits = size / base;
600 if (remainder || (size % base))
601 ++significant_digits;
604 case ROUND_UP_AT_POINT_FIVE:
605 if ((size % base) >= half)
606 ++significant_digits;
609 case ROUND_DOWN_AT_POINT_FIVE:
610 unsigned long long r = size % base;
611 if ((r > half) || (remainder && (r == half)))
612 ++significant_digits;
615 return significant_digits;
627static WvString _sizetoa(
unsigned long long size,
unsigned long blocksize,
628 RoundingMethod rounding_method,
645 const unsigned long long group_base = prefixes[0].base;
647 unsigned long prev_blocksize = 0;
648 while (blocksize >= group_base)
650 prev_blocksize = blocksize;
651 blocksize /= group_base;
657 if (prev_blocksize && prev_blocksize != group_base)
659 blocksize = prev_blocksize;
664 unsigned long long significant_digits = size * 10;
665 unsigned int remainder = 0;
666 if (significant_digits < size)
669 remainder = size % group_base;
673 while (size >= group_base)
676 significant_digits = _sizetoa_rounder(rounding_method,
680 if (significant_digits < (group_base * 10)
681 || !prefixes[p + shift + 1].name)
688 significant_digits *= blocksize;
689 while (significant_digits >= (group_base * 10)
690 && prefixes[p + shift + 1].name)
692 significant_digits = _sizetoa_rounder(rounding_method,
702 significant_digits / 10,
703 significant_digits % 10,
704 prefixes[p + shift].name,
709 RoundingMethod rounding_method)
711 unsigned long long bytes = blocks * blocksize;
714 if (bytes < 1000 && bytes >= blocks)
717 return _sizetoa(blocks, blocksize, rounding_method, si,
"B");
726 return sizetoa(kbytes, 1000, rounding_method);
730 RoundingMethod rounding_method)
732 unsigned long long bytes = blocks * blocksize;
735 if (bytes < 1024 && bytes >= blocks)
738 return _sizetoa(blocks, blocksize, rounding_method, iec,
"B");
747 return sizeitoa(kbytes, 1024, rounding_method);
754 unsigned int days = total_seconds / (3600*24);
755 total_seconds %= (3600*24);
756 unsigned int hours = total_seconds / 3600;
757 total_seconds %= 3600;
758 unsigned int mins = total_seconds / 60;
759 unsigned int secs = total_seconds % 60;
761 int num_elements = (days > 0) + (hours > 0) + (mins > 0);
766 result.append(days > 1 ?
" days" :
" day");
768 if (num_elements > 1)
770 else if (num_elements == 1)
771 result.append(
" and ");
775 result.append(hours);
776 result.append(hours > 1 ?
" hours" :
" hour");
778 if (num_elements > 1)
780 else if (num_elements == 1)
781 result.append(
" and ");
786 result.append(mins > 1 ?
" minutes" :
" minute");
788 if (days == 0 && hours == 0 && mins == 0)
791 result.append(secs != 1 ?
" seconds" :
" second");
800 const char *sptr = s, *eptr;
802 while ((eptr = strstr(sptr, a)) != NULL)
804 buf.
put(sptr, eptr-sptr);
806 sptr = eptr + strlen(a);
809 buf.
put(sptr, strlen(sptr));
820 for (
int i = 0; s[i] !=
'\0'; i++)
840 struct tm *tm = gmtime(&t);
844 strftime(s.
edit(), 128,
"%a, %d %b %Y %H:%M:%S GMT", tm);
850int lookup(
const char *str,
const char *
const *table,
bool case_sensitive)
852 for (
int i = 0; table[i]; ++i)
856 if (strcmp(str, table[i]) != 0)
861 if (strcasecmp(str, table[i]) != 0)
876 char *name =
new char[maxlen];
877 int result = gethostname(name, maxlen);
885 assert(errno == WSAEFAULT);
887 assert(errno == EINVAL);
895 struct hostent *myhost;
899 return myhost->h_name;
901 return WvString::null;
911 char *name =
new char[maxlen];
912 char *res = getcwd(name, maxlen);
919 if (errno == EACCES || errno == ENOENT)
921 assert(errno == ERANGE);
942 res.setsize(digits + ((digits - 1) / 3) + ((j < 0) ? 1 : 0));
950 p += digits + ((digits - 1) / 3);
953 for (digit=0; digit<digits; digit++)
955 *p-- =
'0' + ( j%10 );
956 if (((digit+1) % 3) == 0 && digit < digits - 1)
968 return WvString::null;
970 const char *loc = strstr(line, a);
984 return WvString::null;
988 char *loc = strstr(ret.
edit(), a);
1000 const char *tmp = line.
cstr();
1001 if (pos > line.len()-1)
1006 char *tmp2 = ret.
edit();
1007 if (pos + len < line.len())
1020static inline const char *cstr_escape_char(
char ch)
1022 static const char *xlat[256] =
1024 "\\0",
"\\x01",
"\\x02",
"\\x03",
"\\x04",
"\\x05",
"\\x06",
"\\a",
1025 "\\b",
"\\t",
"\\n",
"\\v",
"\\x0C",
"\\r",
"\\x0E",
"\\x0F",
1026 "\\x10",
"\\x11",
"\\x12",
"\\x13",
"\\x14",
"\\x15",
"\\x16",
"\\x17",
1027 "\\x18",
"\\x19",
"\\x1A",
"\\x1B",
"\\x1C",
"\\x1D",
"\\x1E",
"\\x1F",
1028 " ",
"!",
"\\\"",
"#",
"$",
"%",
"&",
"'",
1029 "(",
")",
"*",
"+",
",",
"-",
".",
"/",
1030 "0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
1031 "8",
"9",
":",
";",
"<",
"=",
">",
"?",
1032 "@",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
1033 "H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
1034 "P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
1035 "X",
"Y",
"Z",
"[",
"\\\\",
"]",
"^",
"_",
1036 "`",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
1037 "h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
1038 "p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
1039 "x",
"y",
"z",
"{",
"|",
"}",
"~",
"\\x7F",
1040 "\\x80",
"\\x81",
"\\x82",
"\\x83",
"\\x84",
"\\x85",
"\\x86",
"\\x87",
1041 "\\x88",
"\\x89",
"\\x8A",
"\\x8B",
"\\x8C",
"\\x8D",
"\\x8E",
"\\x8F",
1042 "\\x90",
"\\x91",
"\\x92",
"\\x93",
"\\x94",
"\\x95",
"\\x96",
"\\x97",
1043 "\\x98",
"\\x99",
"\\x9A",
"\\x9B",
"\\x9C",
"\\x9D",
"\\x9E",
"\\x9F",
1044 "\\xA0",
"\\xA1",
"\\xA2",
"\\xA3",
"\\xA4",
"\\xA5",
"\\xA6",
"\\xA7",
1045 "\\xA8",
"\\xA9",
"\\xAA",
"\\xAB",
"\\xAC",
"\\xAD",
"\\xAE",
"\\xAF",
1046 "\\xB0",
"\\xB1",
"\\xB2",
"\\xB3",
"\\xB4",
"\\xB5",
"\\xB6",
"\\xB7",
1047 "\\xB8",
"\\xB9",
"\\xBA",
"\\xBB",
"\\xBC",
"\\xBD",
"\\xBE",
"\\xBF",
1048 "\\xC0",
"\\xC1",
"\\xC2",
"\\xC3",
"\\xC4",
"\\xC5",
"\\xC6",
"\\xC7",
1049 "\\xC8",
"\\xC9",
"\\xCA",
"\\xCB",
"\\xCC",
"\\xCD",
"\\xCE",
"\\xCF",
1050 "\\xD0",
"\\xD1",
"\\xD2",
"\\xD3",
"\\xD4",
"\\xD5",
"\\xD6",
"\\xD7",
1051 "\\xD8",
"\\xD9",
"\\xDA",
"\\xDB",
"\\xDC",
"\\xDD",
"\\xDE",
"\\xDF",
1052 "\\xE0",
"\\xE1",
"\\xE2",
"\\xE3",
"\\xE4",
"\\xE5",
"\\xE6",
"\\xE7",
1053 "\\xE8",
"\\xE9",
"\\xEA",
"\\xEB",
"\\xEC",
"\\xED",
"\\xEE",
"\\xEF",
1054 "\\xF0",
"\\xF1",
"\\xF2",
"\\xF3",
"\\xF4",
"\\xF5",
"\\xF6",
"\\xF7",
1055 "\\xF8",
"\\xF9",
"\\xFA",
"\\xFB",
"\\xFC",
"\\xFD",
"\\xFE",
"\\xFF"
1057 return xlat[(
unsigned char)ch];
1060static inline int hex_digit_val(
char ch)
1062 static int val[256] =
1064 -1, -1, -1, -1, -1, -1, -1, -1,
1065 -1, -1, -1, -1, -1, -1, -1, -1,
1066 -1, -1, -1, -1, -1, -1, -1, -1,
1067 -1, -1, -1, -1, -1, -1, -1, -1,
1068 -1, -1, -1, -1, -1, -1, -1, -1,
1069 -1, -1, -1, -1, -1, -1, -1, -1,
1070 0, 1, 2, 3, 4, 5, 6, 7,
1071 8, 9, -1, -1, -1, -1, -1, -1,
1072 -1, 10, 11, 12, 13, 14, 15, -1,
1073 -1, -1, -1, -1, -1, -1, -1, -1,
1074 -1, -1, -1, -1, -1, -1, -1, -1,
1075 -1, -1, -1, -1, -1, -1, -1, -1,
1076 -1, 10, 11, 12, 13, 14, 15, -1,
1077 -1, -1, -1, -1, -1, -1, -1, -1,
1078 -1, -1, -1, -1, -1, -1, -1, -1,
1079 -1, -1, -1, -1, -1, -1, -1, -1,
1080 -1, -1, -1, -1, -1, -1, -1, -1,
1081 -1, -1, -1, -1, -1, -1, -1, -1,
1082 -1, -1, -1, -1, -1, -1, -1, -1,
1083 -1, -1, -1, -1, -1, -1, -1, -1,
1084 -1, -1, -1, -1, -1, -1, -1, -1,
1085 -1, -1, -1, -1, -1, -1, -1, -1,
1086 -1, -1, -1, -1, -1, -1, -1, -1,
1087 -1, -1, -1, -1, -1, -1, -1, -1,
1088 -1, -1, -1, -1, -1, -1, -1, -1,
1089 -1, -1, -1, -1, -1, -1, -1, -1,
1090 -1, -1, -1, -1, -1, -1, -1, -1,
1091 -1, -1, -1, -1, -1, -1, -1, -1,
1092 -1, -1, -1, -1, -1, -1, -1, -1,
1093 -1, -1, -1, -1, -1, -1, -1, -1,
1094 -1, -1, -1, -1, -1, -1, -1, -1,
1095 -1, -1, -1, -1, -1, -1, -1, -1
1097 return val[(
unsigned char)ch];
1100static inline bool cstr_unescape_char(
const char *&cstr,
char &ch)
1108 case '"': ch =
'"';
break;
1109 case 't': ch =
'\t';
break;
1110 case 'n': ch =
'\n';
break;
1111 case '\\': ch =
'\\';
break;
1112 case 'r': ch =
'\r';
break;
1113 case 'a': ch =
'\a';
break;
1114 case 'v': ch =
'\v';
break;
1115 case 'b': ch =
'\b';
break;
1116 case '0': ch =
'\0';
break;
1123 if ((vals[i] = hex_digit_val(*++cstr)) == -1)
1126 ch = (vals[0] << 4) | vals[1];
1129 default:
return false;
1146 if (!data)
return WvString::null;
1148 const char *cdata = (
const char *)data;
1151 result.setsize(4*size + 3);
1152 char *cstr = result.
edit();
1157 const char *esc = NULL;
1161 while (extra->ch && extra->esc)
1163 if (*cdata == extra->ch)
1172 if (!esc) esc = cstr_escape_char(*cdata);
1174 while (*esc) *cstr++ = *esc++;
1185 const char *q = cstr;
1186 char *cdata = (
char *)data;
1188 if (!q)
goto misformatted;
1193 while (isspace(*q)) q++;
1194 if (*q ==
'\0')
break;
1196 if (*q++ !=
'\"')
goto misformatted;
1197 while (*q && *q !=
'\"')
1204 while (extra->ch && extra->esc)
1206 size_t len = strlen(extra->esc);
1207 if (strncmp(extra->esc, q, len) == 0)
1218 if (!found && !cstr_unescape_char(q, unesc))
goto misformatted;
1219 if (size++ < max_size && cdata) *cdata++ = unesc;
1221 if (*q++ !=
'\"')
goto misformatted;
1224 return size <= max_size;
1240 struct tm *tmwhen = localtime(&when);
1241 strftime(out.
edit(), 80,
"%b %d %I:%M:%S %p", tmwhen);
1254 struct tm *tmwhen = localtime(&when);
1255 strftime(out.
edit(), 12,
"%H:%M:%S", tmwhen);
1268 struct tm *tmwhen = localtime(&when);
1269 strftime(out.
edit(), 16,
"%Y-%m-%d", tmwhen);
1282 struct tm *tmwhen = localtime(&when);
1283 strftime(out.
edit(), 24,
"%Y-%m-%d %H:%M:%S", tmwhen);
1296 struct tm *l = localtime(&t);
1298 time_t local = mktime(l);
1299 time_t gmt = mktime(gmtime(&t));
1309 char * edit = ret.
edit();
1310 int last = ret.len() - 1;
1311 if (edit[last] ==
'.' || edit[last] ==
'?' || edit[last] ==
'!')
1320 char buf[(
sizeof(ptr) * 2) + 3];
1323 rv = snprintf(buf,
sizeof(buf),
"%p", ptr);
void put(const T *data, size_t count)
Writes the specified number of elements from the specified storage location into the buffer at its ta...
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
const char * cstr() const
return a (const char *) for this string.
This is a WvList of WvStrings, and is a really handy way to parse strings.
void split(WvStringParm s, const char *splitchars=" \t\r\n", int limit=0)
split s and form a list ignoring splitchars (except at beginning and end) ie.
WvString is an implementation of a simple and efficient printable-string class.
WvString & unique()
make the buf and str pointers owned only by this WvString.
char * edit()
make the string editable, and return a non-const (char*)
bool cstr_unescape(WvStringParm cstr, void *data, size_t max_size, size_t &size, const CStrExtraEscape extra_escapes[]=NULL)
Converts a C-style string constant into data.
bool isnewline(char c)
Returns true if 'c' is a newline or carriage return character.
WvString beforestr(WvStringParm line, WvStringParm a)
Returns everything in line (exclusively) before 'a'.
char * terminate_string(char *string, char c)
Add character c to the end of a string after removing terminating carriage returns/linefeeds if any.
WvString fqdomainname()
Get the fqdn of the local host, using gethostbyname() and gethostname()
WvString encode_hostname_as_DN(WvStringParm hostname)
Example: encode_hostname_as_DN("www.fizzle.com") will result in dc=www,dc=fizzle,dc=com,...
WvString strreplace(WvStringParm s, WvStringParm a, WvStringParm b)
Replace any instances of "a" with "b" in "s".
WvString backslash_escape(WvStringParm s1)
Returns a string with a backslash in front of every non alphanumeric character in s1.
WvString url_encode(WvStringParm str, WvStringParm unsafe="")
Converts all those pesky spaces, colons, and other nasties into nice unreadable Quasi-Unicode codes.
WvString getfilename(WvStringParm fullname)
Take a full path/file name and splits it up into respective pathname and filename.
WvString rfc822_date(time_t _when=-1)
Returns an RFC822-compatible date made out of _when, or, if _when < 0, out of the current time.
WvString hexdump_buffer(const void *buf, size_t len, bool charRep=true)
Produce a hexadecimal dump of the data buffer in 'buf' of length 'len'.
WvString ptr2str(void *ptr)
Converts a pointer into a string, like glibc's p formatter would do.
WvString sizetoa(unsigned long long blocks, unsigned long blocksize=1, RoundingMethod rounding_method=ROUND_UP_AT_POINT_FIVE)
Given a number of blocks and a blocksize (default==1 byte), return a WvString containing a human-read...
int lookup(const char *str, const char *const *table, bool case_sensitive=false)
Finds a string in an array and returns its index.
WvString local_date(time_t _when=-1)
Return the local date (TZ applied) out of _when.
WvString nice_hostname(WvStringParm name)
Given a hostname, turn it into a "nice" one.
bool is_word(const char *string)
Returns true if all characters in 'string' are isalnum() (alphanumeric).
int strcount(WvStringParm s, const char c)
How many times does 'c' occur in "s"?
WvString sizeitoa(unsigned long long blocks, unsigned long blocksize=1, RoundingMethod rounding_method=ROUND_UP_AT_POINT_FIVE)
Given a number of blocks and a blocksize (default==1 byte), return a WvString containing a human-read...
WvString intl_date(time_t _when=-1)
Return the local date (in format of ISO 8601) out of _when.
WvString rfc1123_date(time_t _when)
Returns an RFC1123-compatible date made out of _when.
WvString sizektoa(unsigned long long kbytes, RoundingMethod rounding_method=ROUND_UP_AT_POINT_FIVE)
Given a size in kilobyes, return a human readable size.
WvString diff_dates(time_t t1, time_t t2)
Returns the difference between to dates in a human readable format.
WvString hostname()
Do gethostname() without a fixed-length buffer.
WvString metriculate(const off_t i)
Inserts SI-style spacing into a number (eg passing 9876543210 returns "9 876 543 210")
WvString secondstoa(unsigned int total_seconds)
Given a number of seconds, returns a formatted human-readable string saying how long the period is.
char * non_breaking(const char *string)
Replaces all whitespace characters in the string with non-breaking spaces ( ) for use with web stuff...
WvString sizekitoa(unsigned long long kbytes, RoundingMethod rounding_method=ROUND_UP_AT_POINT_FIVE)
Given a size in kilobytes, return a human readable size.
char * trim_string(char *string)
Trims whitespace from the beginning and end of the character string, including carriage return / line...
time_t intl_gmtoff(time_t t)
Return the number of seconds by which localtime (at the given timestamp) is offset from GMT.
WvString substr(WvString line, unsigned int pos, unsigned int len)
Returns the string of length len starting at pos in line.
WvString url_decode(WvStringParm str, bool no_space=false)
Converts escaped characters (things like %20 etc.) from web URLS into their normal ASCII representati...
WvString afterstr(WvStringParm line, WvStringParm a)
Returns everything in line (exclusively) after a.
void replace_char(void *string, char c1, char c2, int length)
Replace all instances of c1 with c2 for the first 'length' characters in 'string'.
WvString intl_datetime(time_t _when=-1)
Return the local date and time (in format of ISO 8601) out of _when.
WvString cstr_escape(const void *data, size_t size, const CStrExtraEscape extra_escapes[]=NULL)
Converts data into a C-style string constant.
char * strlwr(char *string)
In-place modify a character string so that all contained letters are in lower case.
char * snip_string(char *haystack, char *needle)
Snip off the first part of 'haystack' if it consists of 'needle'.
WvString depunctuate(WvStringParm line)
Removes any trailing punctuation ('.
char * strupr(char *string)
In-place modify a character string so that all contained letters are in upper case.
WvString spacecat(WvStringParm a, WvStringParm b, char sep=' ', bool onesep=false)
return the string formed by concatenating string 'a' and string 'b' with the 'sep' character between ...
WvString undupe(WvStringParm s, char c)
Replace any consecutive instances of character c with a single one.
WvString wvgetcwd()
Get the current working directory without a fixed-length buffer.
WvString intl_time(time_t _when=-1)
Return the local time (in format of ISO 8601) out of _when.