50 #include "EST_String.h"
52 #include "string_version.h"
71 #if !__GSUB_REENTRANT__
72 static struct subst *substitutions=NULL;
73 int num_substitutions=0;
85 int EST_String::locate(
const char *s,
int len,
int from,
int &start,
int &end)
const
94 if (from < 0 && -from < size)
96 int endpos=size+from+1;
100 while ((nextsub=strstr(
str()+p, s)))
108 else if (from>=0 && from <= size)
109 sub= strstr(
str()+from, s);
124 int EST_String::locate(
EST_Regex &ex,
int from,
int &start,
int &end,
int *starts,
int *ends)
const
126 int match_start, match_end;
128 if (from < 0 && -from < size)
130 int endpos=size+from+1;
134 while (ex.
run(
str(), p, match_start, match_end, starts, ends))
145 else if (from >=0 && from <= size)
147 if (ex.
run(
str(), from, match_start, match_end, starts, ends))
160 int EST_String::extract(
const char *s,
int len,
int pos,
int &start,
int &end)
const
168 return locate(s, len, 0, start, end);
170 if (pos <= size-len && memcmp(
str()+pos, s, len)==0)
180 int EST_String::extract(
EST_Regex &ex,
int pos,
int &start,
int &end)
const
182 int match_start, match_end;
185 return locate(ex, 0, start, end);
187 if (pos < size && ex.
run(
str(), pos, match_start, match_end) && match_start == pos)
197 EST_String EST_String::chop_internal(
int from,
int len, EST_chop_direction mode)
const
212 if (start >=0 && end <=size && size > 0)
226 EST_String EST_String::chop_internal(
const char *it,
int len,
int from, EST_chop_direction mode)
const
228 CHECK_STRING_ARG(it);
232 if (it && locate(it, len, from, start, end))
246 EST_String EST_String::chop_internal (
EST_Regex &it,
int from, EST_chop_direction mode)
const
250 if (locate(it, from, start, end))
265 int EST_String::gsub_internal (
const char *os,
int olength,
const char *s,
int length)
267 CHECK_STRING_ARG(os);
270 int pos=0, n=0, change=0;
276 #if __GSUB_REENTRANT__
279 } *substitutions=NULL;
281 int num_substitutions=0;
284 if (s && os && size > 0 && *os !=
'\0')
288 while (locate(os, olength, pos, start, end))
290 if (num_substitutions <= n)
291 substitutions = wrealloc(substitutions,
struct subst, (num_substitutions +=10));
293 substitutions[n].start = start;
294 substitutions[n].end = end;
296 change +=
length - (end-start);
305 from = (
const char *)memory;
310 {new_memory = chunk_allocate(size+change+1);}
315 cp_make_updatable(memory, size);
324 int start = substitutions[i].start;
325 int end = substitutions[i].end;
326 memcpy(p, from+
at, start-
at);
333 memcpy(p, from+
at, size-
at);
347 #if __GSUB_REENTRANT__
349 wfree(substitutions);
356 int EST_String::gsub_internal (
EST_Regex &ex,
const char *s,
int length)
364 int pos=0, n=0, change=0;
370 #if __GSUB_REENTRANT__
371 struct subst *substitutions=NULL;
373 int num_substitutions=0;
381 int start, starts[EST_Regex_max_subexpressions], ends[EST_Regex_max_subexpressions], mlen;
382 while ((start =
search(ex, mlen, pos, starts, ends))>=0)
385 if (num_substitutions <= n)
386 substitutions = wrealloc(substitutions,
struct subst, (num_substitutions +=10));
388 substitutions[n].start = start;
389 substitutions[n].end = start+mlen;
395 int slen = ends[bracket_num]-starts[bracket_num];
396 change += slen - mlen;
397 substitutions[n].slen = slen;
398 substitutions[n].s = walloc(
char, slen);
399 memcpy(substitutions[n].s, (
const char *)memory+starts[bracket_num], slen);
410 from = (
const char *)memory;
415 {new_memory = chunk_allocate(size+change+1);}
420 cp_make_updatable(memory, size);
429 int start = substitutions[i].start;
430 int end = substitutions[i].end;
431 memcpy(p, from+
at, start-
at);
440 memcpy(p, substitutions[i].s, substitutions[i].slen);
441 wfree(substitutions[i].s);
442 substitutions[i].s=NULL;
443 p += substitutions[i].slen;
447 memcpy(p, from+
at, size-
at);
458 #if __GSUB_REENTRANT__
460 wfree(substitutions);
468 int (&starts)[EST_Regex_max_subexpressions],
469 int (&ends)[EST_Regex_max_subexpressions])
477 #if __GSUB_REENTRANT__
478 struct subst *substitutions=NULL;
480 int num_substitutions=0;
490 for(i=0; i<size; i++)
494 if (memory[i] >=
'0' &&memory[i] <=
'9')
496 int snum = memory[i] -
'0';
497 if (ends[snum] >= 0 && starts[snum] >=0)
499 if (num_substitutions <= n)
500 substitutions = wrealloc(substitutions,
struct subst, (num_substitutions +=10));
502 substitutions[n].start = i-1;
503 substitutions[n].end = i+1;
504 substitutions[n].s = ((
char *)(
void *)(
const char *)source.memory) + starts[snum];
505 substitutions[n].slen = ends[snum] - starts[snum];
506 change += substitutions[n].slen - 2;
513 else if (memory[i] ==
'\\')
520 from = (
const char *)memory;
525 {new_memory = chunk_allocate(size+change+1);}
530 cp_make_updatable(memory, size);
539 int start = substitutions[i].start;
540 int end = substitutions[i].end;
541 memcpy(p, from+
at, start-
at);
544 memcpy(p, substitutions[i].s, substitutions[i].slen);
545 substitutions[i].s=NULL;
546 p += substitutions[i].slen;
549 memcpy(p, from+
at, size-
at);
560 #if __GSUB_REENTRANT__
562 wfree(substitutions);
572 int EST_String::split_internal(
EST_String result[],
int max,
573 const char *s_seperator,
int slen,
588 if ((*
this)(pos) ==
quote)
594 if ((*
this)(pos) ==
quote)
597 if ((*
this)(pos) !=
quote)
609 int mstart, mend, matched;
611 matched = locate(s_seperator, slen, pos, mstart, mend);
613 matched = locate(*re_seperator, pos, mstart, mend);
623 else if (pos ==lastspace)
643 result[n++] =
EST_String(*
this, start, end-start);
661 int len=safe_strlen(s);
663 if (extract(s, len, pos, start, end))
664 return start==pos && end==len;
673 if (extract(s.
str(), s.size, pos, start, end))
674 return start==pos && end==s.size;
682 return e.
run_match(
"", pos, starts, ends) >0;
693 int bl = safe_strlen(b);
703 memmove((
char *)c + al, b, bl);
721 memmove((
char *)c+al,b.
str(),bl);
731 int al = safe_strlen(a);
741 memmove((
char *)c + al, b.
str(), bl);
759 for(
int j=0; j<n; j++)
760 strncpy(((
char *)it)+j*l, (
const char *)s, l);
770 int bl = safe_strlen(b);
774 memory = chunk_allocate(bl+1, b, bl);
779 grow_chunk(memory, size, size+bl+1);
781 memmove((
char *)memory + size,b,bl);
782 memory(size+bl)=
'\0';
795 memory = NON_CONST_CHUNKPTR(b.memory);
800 grow_chunk(memory, size, size+bl+1);
803 memmove((
char *)memory + size,b.
str(),bl);
805 memory(size+bl)=
'\0';
818 memory = chunk_allocate(size+1, s, size);
829 int start= start_or_fill;
831 len=safe_strlen(s)-start;
835 memory = chunk_allocate(len+1, s+start, len);
841 char fill = start_or_fill;
846 memory = chunk_allocate(len+1);
848 for(
int j=0; j<len;j++)
866 memory = chunk_allocate(len+1, s+start, len);
878 if (start == 0 && len == s.size)
879 memory = NON_CONST_CHUNKPTR(s.memory);
881 memory = chunk_allocate(len+1, s.memory, start, len);
899 #if __FSF_COMPATIBILITY__
903 memory= chunk_allocate(2, &c, 1);
909 CHECK_STRING_ARG(
str);
910 int len = safe_strlen(
str);
913 else if (!shareing() && len < size)
914 memcpy((
char *)memory,
str, len+1);
916 memory = chunk_allocate(len+1,
str, len);
924 memory = chunk_allocate(2, &c, 1);
931 const char *
str = (
const char *)s;
932 CHECK_STRING_ARG(
str);
933 int len = safe_strlen(
str);
936 else if (!shareing() && len < size)
937 memcpy((
char *)memory,
str, len+1);
939 memory = chunk_allocate(len+1,
str, len);
959 for (i=0; i < s.
length(); i++)
961 t[i] = tolower(s(i));
972 for (i=0; i < s.
length(); i++)
974 t[i] = toupper(s(i));
988 while (locate(s, pos, start, end))
1004 int len=safe_strlen(s);
1006 while (locate(s, len, pos, start, end))
1021 while (locate(ex, pos, start, end))
1032 const char quotequote[3] = {quotec, quotec,
'\0'};
1036 result.
gsub(quotequote+1, quotequote+0);
1044 const char quotequote[3] = {quotec, quotec,
'\0'};
1050 result.
gsub(quotequote+0, quotequote+1);
1054 if (result[0] == quotec && result[result.
length()-1] == quotec )
1061 return result.
at(1, result.
length()-2);
1072 return quote(quotec);
1081 if ((*
this)(0) == quotec && (*
this)(
length()-1) == quotec )
1091 return (s << str.
str());
1113 result.memory= chunk_allocate(len+1, (
const char *)s1, s1.
length());
1115 int p = s1.length();
1117 { strncpy((
char *)result.memory + p, (
const char *)s2, s2.
length()); p += s2.length(); }
1119 { strncpy((
char *)result.memory + p, (
const char *)s3, s3.
length()); p += s3.length(); }
1121 { strncpy((
char *)result.memory + p, (
const char *)s4, s4.
length()); p += s4.length(); }
1123 { strncpy((
char *)result.memory + p, (
const char *)s5, s5.
length()); p += s5.length(); }
1125 { strncpy((
char *)result.memory + p, (
const char *)s6, s6.
length()); p += s6.length(); }
1127 { strncpy((
char *)result.memory + p, (
const char *)s7, s7.
length()); p += s7.length(); }
1129 { strncpy((
char *)result.memory + p, (
const char *)s8, s8.
length()); p += s8.length(); }
1131 { strncpy((
char *)result.memory + p, (
const char *)s9, s9.
length()); p += s9.length(); }
1133 result.memory(p) =
'\0';
1140 if (a.size == 0 && b.size == 0)
1142 else if (a.size == 0)
1144 else if (b.size == 0)
1147 return strcmp(a.
str(), b.
str());
1150 int compare(
const EST_String &a,
const char *b)
1152 if (a.size == 0 && (b==NULL || *b ==
'\0'))
1154 else if (a.size == 0)
1156 else if (b == NULL || *b ==
'\0')
1159 return strcmp(a.
str(), b);
1163 const unsigned char *table)
1165 if (a.size == 0 && b.size == 0)
1167 else if (a.size == 0)
1169 else if (b.size == 0)
1172 return EST_strcasecmp(a.
str(), b.
str(), table);
1175 int fcompare(
const EST_String &a,
const char *b,
1176 const unsigned char *table)
1178 int bsize = (b ? strlen((
const char *)b) : 0);
1179 if (a.size == 0 && bsize == 0)
1181 else if (a.size == 0)
1183 else if (bsize == 0)
1186 return EST_strcasecmp(a.
str(), (
const char *)b, table);
1189 int operator == (
const char *a,
const EST_String &b)
1191 CHECK_STRING_ARG(a);
1198 return (*a == b(0)) && strcmp(a, b.
str())==0;
1205 else if (b.size == 0)
1208 return a.size == b.size && a(0) == b(0) && memcmp(a.
str(),b.
str(),a.size)==0;
1231 sprintf(buf, format, i);
1256 sprintf(buf, format, i);
1265 sprintf(buf,
"%f", f);
1274 sprintf(buf,
"%f", d);
1279 long EST_String::Long(
bool *valid)
const
1283 long val = strtol(
str(), &end, 10);
1285 if (end==NULL|| *end !=
'\0')
1294 printf(
"bad integer number format '%s'\n",
1295 (
const char *)
str());
1306 int EST_String::Int(
bool *valid)
const
1308 long val = Long(valid);
1310 if (valid && !*valid)
1313 if (val > INT_MAX || val < INT_MIN)
1322 printf(
"number out of range for integer %ld",
1331 double EST_String::Double(
bool *valid)
const
1335 double val = strtod(
str(), &end);
1337 if (end==NULL|| *end !=
'\0')
1346 printf(
"bad decimal number format '%s'",
1347 (
const char *)
str());
1358 float EST_String::Float(
bool *valid)
const
1360 double val = Double(valid);
1362 if (valid && !*valid)
1365 if (val > FLT_MAX || val < -FLT_MAX)
1374 printf(
"number out of range for float %f",