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);
328 memcpy(p, s, length);
332 memcpy(p, from+at, size-at);
346 #if __GSUB_REENTRANT__
348 wfree(substitutions);
355 int EST_String::gsub_internal (
EST_Regex &ex,
const char *s,
int length)
363 int pos=0, n=0, change=0;
369 #if __GSUB_REENTRANT__
370 struct subst *substitutions=NULL;
372 int num_substitutions=0;
380 int start, starts[EST_Regex_max_subexpressions], ends[EST_Regex_max_subexpressions], mlen;
381 while ((start =
search(ex, mlen, pos, starts, ends))>=0)
384 if (num_substitutions <= n)
385 substitutions = wrealloc(substitutions,
struct subst, (num_substitutions +=10));
387 substitutions[n].start = start;
388 substitutions[n].end = start+mlen;
391 change += length - mlen;
394 int slen = ends[bracket_num]-starts[bracket_num];
395 change += slen - mlen;
396 substitutions[n].slen = slen;
397 substitutions[n].s = walloc(
char, slen);
398 memcpy(substitutions[n].s, (
const char *)memory+starts[bracket_num], slen);
409 from = (
const char *)memory;
414 {new_memory = chunk_allocate(size+change+1);}
419 cp_make_updatable(memory, size);
428 int start = substitutions[i].start;
429 int end = substitutions[i].end;
430 memcpy(p, from+at, start-at);
434 memcpy(p, s, length);
439 memcpy(p, substitutions[i].s, substitutions[i].slen);
440 wfree(substitutions[i].s);
441 substitutions[i].s=NULL;
442 p += substitutions[i].slen;
446 memcpy(p, from+at, size-at);
457 #if __GSUB_REENTRANT__
459 wfree(substitutions);
467 int (&starts)[EST_Regex_max_subexpressions],
468 int (&ends)[EST_Regex_max_subexpressions])
476 #if __GSUB_REENTRANT__
477 struct subst *substitutions=NULL;
479 int num_substitutions=0;
489 for(i=0; i<size; i++)
493 if (memory[i] >=
'0' &&memory[i] <=
'9')
495 int snum = memory[i] -
'0';
496 if (ends[snum] >= 0 && starts[snum] >=0)
498 if (num_substitutions <= n)
499 substitutions = wrealloc(substitutions,
struct subst, (num_substitutions +=10));
501 substitutions[n].start = i-1;
502 substitutions[n].end = i+1;
503 substitutions[n].s = ((
char *)(
void *)(
const char *)source.memory) + starts[snum];
504 substitutions[n].slen = ends[snum] - starts[snum];
505 change += substitutions[n].slen - 2;
512 else if (memory[i] ==
'\\')
519 from = (
const char *)memory;
524 {new_memory = chunk_allocate(size+change+1);}
529 cp_make_updatable(memory, size);
538 int start = substitutions[i].start;
539 int end = substitutions[i].end;
540 memcpy(p, from+at, start-at);
543 memcpy(p, substitutions[i].s, substitutions[i].slen);
544 substitutions[i].s=NULL;
545 p += substitutions[i].slen;
548 memcpy(p, from+at, size-at);
559 #if __GSUB_REENTRANT__
561 wfree(substitutions);
571 int EST_String::split_internal(
EST_String result[],
int max,
572 const char *s_seperator,
int slen,
587 if ((*
this)(pos) == quote)
593 if ((*
this)(pos) == quote)
596 if ((*
this)(pos) != quote)
608 int mstart, mend, matched;
610 matched = locate(s_seperator, slen, pos, mstart, mend);
612 matched = locate(*re_seperator, pos, mstart, mend);
622 else if (pos ==lastspace)
642 result[n++] =
EST_String(*
this, start, end-start);
660 int len=safe_strlen(s);
662 if (extract(s, len, pos, start, end))
663 return start==pos && end==len;
672 if (extract(s.
str(), s.size, pos, start, end))
673 return start==pos && end==s.size;
681 return e.
run_match(
"", pos, starts, ends) >0;
692 int bl = safe_strlen(b);
702 memmove((
char *)c + al, b, bl);
720 memmove((
char *)c+al,b.
str(),bl);
730 int al = safe_strlen(a);
740 memmove((
char *)c + al, b.
str(), bl);
758 for(
int j=0; j<n; j++)
759 strncpy(((
char *)it)+j*l, (
const char *)s, l);
769 int bl = safe_strlen(b);
773 memory = chunk_allocate(bl+1, b, bl);
778 grow_chunk(memory, size, size+bl+1);
780 memmove((
char *)memory + size,b,bl);
781 memory(size+bl)=
'\0';
794 memory = NON_CONST_CHUNKPTR(b.memory);
799 grow_chunk(memory, size, size+bl+1);
802 memmove((
char *)memory + size,b.
str(),bl);
804 memory(size+bl)=
'\0';
817 memory = chunk_allocate(size+1, s, size);
828 int start= start_or_fill;
830 len=safe_strlen(s)-start;
834 memory = chunk_allocate(len+1, s+start, len);
840 char fill = start_or_fill;
845 memory = chunk_allocate(len+1);
847 for(
int j=0; j<len;j++)
865 memory = chunk_allocate(len+1, s+start, len);
877 if (start == 0 && len == s.size)
878 memory = NON_CONST_CHUNKPTR(s.memory);
880 memory = chunk_allocate(len+1, s.memory, start, len);
898 #if __FSF_COMPATIBILITY__
902 memory= chunk_allocate(2, &c, 1);
908 CHECK_STRING_ARG(str);
909 int len = safe_strlen(str);
912 else if (!shareing() && len < size)
913 memcpy((
char *)memory, str, len+1);
915 memory = chunk_allocate(len+1, str, len);
922 memory = chunk_allocate(2, &c, 1);
931 memory = NON_CONST_CHUNKPTR(s.memory);
934 *(
struct EST_dumb_string *)
this = *(
struct EST_dumb_string *)(&s);
944 for (i=0; i < s.
length(); i++)
946 t[i] = tolower(s(i));
957 for (i=0; i < s.
length(); i++)
959 t[i] = toupper(s(i));
973 while (locate(s, pos, start, end))
989 int len=safe_strlen(s);
991 while (locate(s, len, pos, start, end))
1006 while (locate(ex, pos, start, end))
1017 const char quotequote[3] = {quotec, quotec,
'\0'};
1021 result.
gsub(quotequote+1, quotequote+0);
1029 const char quotequote[3] = {quotec, quotec,
'\0'};
1035 result.
gsub(quotequote+0, quotequote+1);
1039 if (result[0] == quotec && result[result.
length()-1] == quotec )
1046 return result.
at(1, result.
length()-2);
1057 return quote(quotec);
1066 if ((*
this)(0) == quotec && (*
this)(
length()-1) == quotec )
1076 return (s << str.
str());
1098 result.memory= chunk_allocate(len+1, (
const char *)s1, s1.
length());
1102 { strncpy((
char *)result.memory + p, (
const char *)s2, s2.
length()); p += s2.
length(); }
1104 { strncpy((
char *)result.memory + p, (
const char *)s3, s3.
length()); p += s3.
length(); }
1106 { strncpy((
char *)result.memory + p, (
const char *)s4, s4.
length()); p += s4.
length(); }
1108 { strncpy((
char *)result.memory + p, (
const char *)s5, s5.
length()); p += s5.
length(); }
1110 { strncpy((
char *)result.memory + p, (
const char *)s6, s6.
length()); p += s6.
length(); }
1112 { strncpy((
char *)result.memory + p, (
const char *)s7, s7.
length()); p += s7.
length(); }
1114 { strncpy((
char *)result.memory + p, (
const char *)s8, s8.
length()); p += s8.
length(); }
1116 { strncpy((
char *)result.memory + p, (
const char *)s9, s9.
length()); p += s9.
length(); }
1118 result.memory(p) =
'\0';
1125 if (a.size == 0 && b.size == 0)
1127 else if (a.size == 0)
1129 else if (b.size == 0)
1132 return strcmp(a.
str(), b.
str());
1135 int compare(
const EST_String &a,
const char *b)
1137 if (a.size == 0 && (b==NULL || *b ==
'\0'))
1139 else if (a.size == 0)
1141 else if (b == NULL || *b ==
'\0')
1144 return strcmp(a.
str(), b);
1148 const unsigned char *table)
1150 if (a.size == 0 && b.size == 0)
1152 else if (a.size == 0)
1154 else if (b.size == 0)
1157 return EST_strcasecmp(a.
str(), b.
str(), table);
1160 int fcompare(
const EST_String &a,
const char *b,
1161 const unsigned char *table)
1163 int bsize = (b ? strlen((
const char *)b) : 0);
1164 if (a.size == 0 && bsize == 0)
1166 else if (a.size == 0)
1168 else if (bsize == 0)
1171 return EST_strcasecmp(a.
str(), (
const char *)b, table);
1174 int operator == (
const char *a,
const EST_String &b)
1176 CHECK_STRING_ARG(a);
1183 return (*a == b(0)) && strcmp(a, b.
str())==0;
1190 else if (b.size == 0)
1193 return a.size == b.size && a(0) == b(0) && memcmp(a.
str(),b.
str(),a.size)==0;
1216 sprintf(buf, format, i);
1241 sprintf(buf, format, i);
1250 sprintf(buf,
"%f", f);
1259 sprintf(buf,
"%f", d);
1264 long EST_String::Long(
bool *valid)
const
1268 long val = strtol(
str(), &end, 10);
1270 if (end==NULL|| *end !=
'\0')
1279 printf(
"bad integer number format '%s'\n",
1280 (
const char *)
str());
1291 int EST_String::Int(
bool *valid)
const
1293 long val = Long(valid);
1295 if (valid && !*valid)
1298 if (val > INT_MAX || val < INT_MIN)
1307 printf(
"number out of range for integer %ld",
1316 double EST_String::Double(
bool *valid)
const
1320 double val = strtod(
str(), &end);
1322 if (end==NULL|| *end !=
'\0')
1331 printf(
"bad decimal number format '%s'",
1332 (
const char *)
str());
1343 float EST_String::Float(
bool *valid)
const
1345 double val = Double(valid);
1347 if (valid && !*valid)
1350 if (val > FLT_MAX || val < -FLT_MAX)
1359 printf(
"number out of range for float %f",