17 #include "string_base.h" 
   30 #include <unicode/ustring.h> 
   50 int CDECL 
vseprintf(
char *str, 
const char *last, 
const char *format, va_list ap)
 
   52   ptrdiff_t diff = last - str;
 
   53   if (diff < 0) 
return 0;
 
   54   return min((
int)diff, vsnprintf(str, diff + 1, format, ap));
 
   73 char *
strecat(
char *dst, 
const char *src, 
const char *last)
 
   76   while (*dst != 
'\0') {
 
   77     if (dst == last) 
return dst;
 
  101 char *
strecpy(
char *dst, 
const char *src, 
const char *last)
 
  104   while (dst != last && *src != 
'\0') {
 
  109   if (dst == last && *src != 
'\0') {
 
  110 #if defined(STRGEN) || defined(SETTINGSGEN) 
  111     error(
"String too long for destination buffer");
 
  113     DEBUG(misc, 0, 
"String too long for destination buffer");
 
  126 char *
stredup(
const char *s, 
const char *last)
 
  128   size_t len = last == NULL ? strlen(s) : 
ttd_strnlen(s, last - s + 1);
 
  129   char *tmp = CallocT<char>(len + 1);
 
  147   char *p = MallocT<char>(len + 1);
 
  148   memcpy(p, buf, len + 1);
 
  160   while (str <= last && *str != 
'\0') {
 
  162     if ((len == 0 && str + 4 > last) || str + len > last) 
break;
 
  166     if (c == 
'\0') 
break;
 
  168     if (c == 0xE028 || c == 0xE02A) {
 
  189   while (str <= last && *str != 
'\0') {
 
  196     if ((len == 0 && str + 4 > last) || str + len > last) 
break;
 
  203     if (c == 
'\0') 
break;
 
  205     if ((IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END)) || ((settings & 
SVS_ALLOW_CONTROL_CODE) != 0 && c == SCC_ENCODED)) {
 
  211       } 
while (--len != 0);
 
  215       if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == 
'\r' && str[1] == 
'\n') {
 
  236   str_validate(const_cast<char *>(str), str + strlen(str) + 1);
 
  251   while (str <= last && *str != 
'\0') {
 
  257     if (len == 0 || str + len > last) 
return false;
 
  261     if (!IsPrintable(c) || (c >= SCC_SPRITE_START && c <= SCC_SPRITE_END)) {
 
  279     if (c < SCC_BLUE || c > SCC_BLACK) {
 
  285       } 
while (--len != 0);
 
  304   while (Utf8Consume(&t) != 0) len++;
 
  322   bool changed = 
false;
 
  323   for (; *str != 
'\0'; str++) {
 
  324     char new_str = tolower(*str);
 
  325     changed |= new_str != *str;
 
  342     case CS_NUMERAL:       
return (key >= 
'0' && key <= 
'9');
 
  344     case CS_ALPHA:         
return IsPrintable(key) && !(key >= 
'0' && key <= 
'9');
 
  345     case CS_HEXADECIMAL:   
return (key >= 
'0' && key <= 
'9') || (key >= 
'a' && key <= 'f') || (key >= 
'A' && key <= 
'F');
 
  352 #if defined(_MSC_VER) && _MSC_VER < 1900 
  360 int CDECL vsnprintf(
char *str, 
size_t size, 
const char *format, va_list ap)
 
  362   if (size == 0) 
return 0;
 
  365   int ret = _vsnprintf(str, size, format, ap);
 
  368     if (errno != ERANGE) {
 
  373   } 
else if ((
size_t)ret < size) {
 
  382   str[size - 1] = 
'\0';
 
  398 int CDECL 
seprintf(
char *str, 
const char *last, 
const char *format, ...)
 
  402   va_start(ap, format);
 
  403   int ret = 
vseprintf(str, last, format, ap);
 
  420   for (uint i = 0; i < 16; i++) {
 
  421     p += 
seprintf(p, last, 
"%02X", md5sum[i]);
 
  445   } 
else if (
GB(s[0], 5, 3) == 6) {
 
  446     if (IsUtf8Part(s[1])) {
 
  448       *c = 
GB(s[0], 0, 5) << 6 | 
GB(s[1], 0, 6);
 
  449       if (*c >= 0x80) 
return 2;
 
  451   } 
else if (
GB(s[0], 4, 4) == 14) {
 
  452     if (IsUtf8Part(s[1]) && IsUtf8Part(s[2])) {
 
  454       *c = 
GB(s[0], 0, 4) << 12 | 
GB(s[1], 0, 6) << 6 | 
GB(s[2], 0, 6);
 
  455       if (*c >= 0x800) 
return 3;
 
  457   } 
else if (
GB(s[0], 3, 5) == 30) {
 
  458     if (IsUtf8Part(s[1]) && IsUtf8Part(s[2]) && IsUtf8Part(s[3])) {
 
  460       *c = 
GB(s[0], 0, 3) << 18 | 
GB(s[1], 0, 6) << 12 | 
GB(s[2], 0, 6) << 6 | 
GB(s[3], 0, 6);
 
  461       if (*c >= 0x10000 && *c <= 0x10FFFF) 
return 4;
 
  482   } 
else if (c < 0x800) {
 
  483     *buf++ = 0xC0 + 
GB(c,  6, 5);
 
  484     *buf   = 0x80 + 
GB(c,  0, 6);
 
  486   } 
else if (c < 0x10000) {
 
  487     *buf++ = 0xE0 + 
GB(c, 12, 4);
 
  488     *buf++ = 0x80 + 
GB(c,  6, 6);
 
  489     *buf   = 0x80 + 
GB(c,  0, 6);
 
  491   } 
else if (c < 0x110000) {
 
  492     *buf++ = 0xF0 + 
GB(c, 18, 3);
 
  493     *buf++ = 0x80 + 
GB(c, 12, 6);
 
  494     *buf++ = 0x80 + 
GB(c,  6, 6);
 
  495     *buf   = 0x80 + 
GB(c,  0, 6);
 
  515   for (
const char *ptr = strchr(s, 
'\0'); *s != 
'\0';) {
 
  518     if (len == 0) len = 1;
 
  522     if (length + len >= maxlen || (s + len > ptr)) 
break;
 
  531 #ifdef DEFINE_STRCASESTR 
  532 char *strcasestr(
const char *haystack, 
const char *needle)
 
  534   size_t hay_len = strlen(haystack);
 
  535   size_t needle_len = strlen(needle);
 
  536   while (hay_len >= needle_len) {
 
  537     if (strncasecmp(haystack, needle, needle_len) == 0) 
return const_cast<char *
>(haystack);
 
  569 int strnatcmp(
const char *s1, 
const char *s2, 
bool ignore_garbage_at_front)
 
  571   if (ignore_garbage_at_front) {
 
  577     UErrorCode status = U_ZERO_ERROR;
 
  579     if (U_SUCCESS(status)) 
return result;
 
  585   return strcasecmp(s1, s2);
 
  590 #include <unicode/utext.h> 
  591 #include <unicode/brkiter.h> 
  605     UErrorCode status = U_ZERO_ERROR;
 
  621     const char *string_base = s;
 
  631       size_t idx = s - string_base;
 
  633       WChar c = Utf8Consume(&s);
 
  647     UText text = UTEXT_INITIALIZER;
 
  648     UErrorCode status = U_ZERO_ERROR;
 
  650     this->
char_itr->setText(&text, status);
 
  651     this->
word_itr->setText(&text, status);
 
  670     this->
char_itr->isBoundary(utf16_pos);
 
  687         while (pos != icu::BreakIterator::DONE &&
 
  689           int32_t new_pos = this->
word_itr->next();
 
  692           if (new_pos == icu::BreakIterator::DONE) 
break;
 
  719         while (pos != icu::BreakIterator::DONE &&
 
  721           int32_t new_pos = this->
word_itr->previous();
 
  724           if (new_pos == icu::BreakIterator::DONE) 
break;
 
  754   DefaultStringIterator() : string(NULL), len(0), cur_pos(0)
 
  761     this->len = strlen(s);
 
  767     assert(this->
string != NULL && pos <= this->len);
 
  769     while (pos > 0 && IsUtf8Part(this->
string[pos])) pos--;
 
  770     return this->cur_pos = pos;
 
  773   virtual size_t Next(IterType what)
 
  775     assert(this->
string != NULL);
 
  778     if (this->cur_pos >= this->len) 
return END;
 
  781       case ITER_CHARACTER: {
 
  783         this->cur_pos += 
Utf8Decode(&c, this->
string + this->cur_pos);
 
  784         return this->cur_pos;
 
  790         size_t offs = 
Utf8Decode(&c, this->
string + this->cur_pos);
 
  792           this->cur_pos += offs;
 
  793           offs = 
Utf8Decode(&c, this->
string + this->cur_pos);
 
  797           this->cur_pos += offs;
 
  798           offs = 
Utf8Decode(&c, this->
string + this->cur_pos);
 
  801         return this->cur_pos;
 
  811   virtual size_t Prev(IterType what)
 
  813     assert(this->
string != NULL);
 
  816     if (this->cur_pos == 0) 
return END;
 
  820         return this->cur_pos = 
Utf8PrevChar(this->
string + this->cur_pos) - this->string;
 
  823         const char *s = this->
string + this->cur_pos;
 
  838         return this->cur_pos = s - this->string;
 
  851   return new DefaultStringIterator();