50#include "EST_String.h"
52#include "string_version.h"
71#if !__GSUB_REENTRANT__
72static struct subst *substitutions=NULL;
73int num_substitutions=0;
85int EST_String::locate(
const char *s,
int len,
int from,
int &start,
int &end)
const
94 if (from < 0 && -from < size)
108 else if (from>=0 && from <= size)
128 if (from < 0 && -from < size)
145 else if (from >=0 && from <= size)
160int EST_String::extract(
const char *s,
int len,
int pos,
int &start,
int &end)
const
168 return locate(s,
len, 0, start, end);
180int EST_String::extract(
EST_Regex &
ex,
int pos,
int &start,
int &end)
const
185 return locate(
ex, 0, start, end);
197EST_String EST_String::chop_internal(
int from,
int len, EST_chop_direction
mode)
const
226EST_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))
250 if (locate(
it, from, start, end))
265int EST_String::gsub_internal (
const char *
os,
int olength,
const char *s,
int length)
267 CHECK_STRING_ARG(
os);
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;
305 from = (
const char *)memory;
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);
356int EST_String::gsub_internal (
EST_Regex &
ex,
const char *s,
int length)
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;
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;
397 substitutions[n].slen = slen;
398 substitutions[n].s = walloc(
char, slen);
410 from = (
const char *)memory;
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';
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];
506 change += substitutions[n].slen - 2;
513 else if (memory[i] ==
'\\')
520 from = (
const char *)memory;
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);
572int EST_String::split_internal(
EST_String result[],
int max,
588 if ((*
this)(pos) == quote)
594 if ((*
this)(pos) == quote)
597 if ((*
this)(pos) != quote)
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;
693 int bl = safe_strlen(b);
731 int al = safe_strlen(a);
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);
782 memory(size+
bl)=
'\0';
795 memory = NON_CONST_CHUNKPTR(b.memory);
800 grow_chunk(memory, size, size+
bl+1);
805 memory(size+
bl)=
'\0';
818 memory = chunk_allocate(size+1, s, size);
831 len=safe_strlen(s)-start;
835 memory = chunk_allocate(
len+1, s+start,
len);
846 memory = chunk_allocate(
len+1);
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++)
972 for (i=0; i < s.
length(); 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))
1061 return result.
at(1, result.
length()-2);
1091 return (s << str.
str());
1108 s6.length()+
s7.length()+
s8.length()+
s9.length());
1113 result.memory= chunk_allocate(
len+1, (
const char *)s1, 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)
1150int 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')
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)
1175int fcompare(
const EST_String &a,
const char *b,
1176 const unsigned char *
table)
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);
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;
1279long EST_String::Long(
bool *valid)
const
1285 if (end==NULL|| *end !=
'\0')
1294 printf(
"bad integer number format '%s'\n",
1295 (
const char *)
str());
1306int EST_String::Int(
bool *valid)
const
1308 long val = Long(valid);
1310 if (valid && !*valid)
1322 printf(
"number out of range for integer %ld",
1331double EST_String::Double(
bool *valid)
const
1337 if (end==NULL|| *end !=
'\0')
1346 printf(
"bad decimal number format '%s'",
1347 (
const char *)
str());
1358float 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",
static EST_String Number(int i, int base=10)
Build string from an integer.
int gsub(const char *os, const EST_String &s)
Substitute one string for another.
int subst(EST_String source, int(&starts)[EST_Regex_max_subexpressions], int(&ends)[EST_Regex_max_subexpressions])
Substitute the result of a match into a string.
EST_String unquote_if_needed(const char quotec) const
Remove quotes if any.
static const EST_String Empty
Constant empty string.
EST_String unquote(const char quotec) const
Remove quotes and unprotect internal quotes.
int freq(const char *s) const
Number of occurrences of substring.
EST_String(void)
Construct an empty string.
int EST_string_size
Type of string size field.
EST_String quote(const char quotec) const
Return the string in quotes with internal quotes protected.
static EST_String cat(const EST_String s1, const EST_String s2=Empty, const EST_String s3=Empty, const EST_String s4=Empty, const EST_String s5=Empty, const EST_String s6=Empty, const EST_String s7=Empty, const EST_String s8=Empty, const EST_String s9=Empty)
int search(const char *s, int len, int &mlen, int pos=0) const
Find a substring.
int length(void) const
Length of string ({not} length of underlying chunk)
EST_String & operator+=(const char *b)
Add C string to end of EST_String.
int contains(const char *s, int pos=-1) const
Does it contain this substring?
EST_String quote_if_needed(const char quotec) const
Return in quotes if there is something to protect (e.g. spaces)
static const char * version
Global version string.
int matches(const char *e, int pos=0) const
Exactly match this string?
const char * str(void) const
Get a const-pointer to the actual memory.
EST_String at(int from, int len=0) const
Return part at position.
EST_String & operator=(const char *str)
Assign C string to EST_String.