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",