LCOV - code coverage report
Current view: top level - asar - libstr.h (source / functions) Coverage Total Hit
Test: asar.info Lines: 92.0 % 237 218
Test Date: 2024-01-15 16:26:31 Functions: 89.8 % 49 44
Branches: 84.8 % 158 134

             Branch data     Line data    Source code
       1                 :             : #pragma once
       2                 :             : 
       3                 :             : #include "std-includes.h"
       4                 :             : //ty alcaro
       5                 :             : extern const unsigned char char_props[256];
       6                 :    13602389 : static inline int to_lower(unsigned char c) { return c|(char_props[c]&0x20); }
       7                 :       63247 : static inline int to_upper(unsigned char c) { return c&~(char_props[c]&0x20); }
       8                 :             : 
       9                 :        1044 : inline bool is_space(unsigned char c) { return char_props[c] & 0x80; } // C standard says \f \v are space, but this one disagrees
      10                 :     5035284 : inline bool is_digit(unsigned char c) { return char_props[c] & 0x40; }
      11                 :        1378 : inline bool is_alpha(unsigned char c) { return char_props[c] & 0x20; }
      12                 :        1470 : inline bool is_lower(unsigned char c) { return char_props[c] & 0x04; }
      13                 :        1977 : inline bool is_upper(unsigned char c) { return char_props[c] & 0x02; }
      14                 :       11845 : inline bool is_alnum(unsigned char c) { return char_props[c] & 0x60; }
      15                 :             : inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; }
      16                 :      666252 : inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; }
      17                 :       14929 : inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; }
      18                 :             : 
      19                 :             : inline char *copy(const char *source, int copy_length, char *dest)
      20                 :             : {
      21                 :     8294127 :         memmove(dest, source, copy_length*sizeof(char));
      22                 :             :         return dest;
      23                 :             : }
      24                 :             : 
      25                 :             : inline int min_val(int a, int b)
      26                 :             : {
      27                 :             :         return a > b ? b : a;
      28                 :             : }
      29                 :             : 
      30                 :        4563 : inline int bit_round(int v)
      31                 :             : {
      32                 :        4563 :         v--;
      33                 :        4563 :         v |= v >> 1;
      34                 :        4563 :         v |= v >> 2;
      35                 :        4563 :         v |= v >> 4;
      36                 :        4563 :         v |= v >> 8;
      37                 :        4563 :         v |= v >> 16;
      38                 :        4563 :         v++;
      39                 :        4563 :         return v;
      40                 :             : }
      41                 :             : 
      42                 :             : class string {
      43                 :             : public:
      44                 :             : const char *data() const
      45                 :             : {
      46                 :     6967374 :         return cached_data;
      47                 :             : }
      48                 :             : 
      49                 :             : char *temp_raw() const  //things to cleanup and take a look at
      50                 :             : {
      51                 :      875298 :         return cached_data;
      52                 :             : }
      53                 :             : 
      54                 :             : char *raw() const
      55                 :             : {
      56                 :    27099636 :         return cached_data;
      57                 :             : }
      58                 :             : 
      59                 :             : int length() const
      60                 :             : {
      61                 :    25188230 :         return is_inlined() ? inlined.len : allocated.len;
      62                 :             : }
      63                 :             : 
      64                 :    13992149 : void set_length(int length)
      65                 :             : {
      66         [ +  + ]:    13992149 :         if(length > max_inline_length_){
      67                 :       19871 :                 inlined.len = (unsigned char)-1;
      68                 :       19871 :                 allocated.len = length;
      69                 :             :         }else{
      70                 :    13972278 :                 inlined.len = length;
      71                 :             :         }
      72                 :    13992149 : }
      73                 :             : 
      74                 :             : void truncate(int newlen)
      75                 :             : {
      76                 :      872500 :         resize(newlen);
      77                 :      546015 : }
      78                 :             : 
      79                 :     2669329 : void assign(const char * newstr)
      80                 :             : {
      81         [ +  + ]:     2669329 :         if (!newstr) newstr = "";
      82                 :     2669329 :         assign(newstr, strlen(newstr));
      83                 :     2669329 : }
      84                 :             : 
      85                 :     2941926 : void assign(const string &newstr)
      86                 :             : {
      87                 :     2941926 :         assign(newstr, newstr.length());
      88                 :     2941926 : }
      89                 :             : 
      90                 :     7831248 : void assign(const char * newstr, int end)
      91                 :             : {
      92                 :     7831248 :         resize(end);
      93                 :             :         copy(newstr, length(), raw());
      94                 :     7831248 : }
      95                 :             : 
      96                 :             : 
      97                 :             : string& operator=(const char * newstr)
      98                 :             : {
      99                 :      549504 :         assign(newstr);
     100                 :      546232 :         return *this;
     101                 :             : }
     102                 :             : 
     103                 :             : string& operator=(const string &newstr)
     104                 :             : {
     105                 :     1318774 :         assign(newstr);
     106                 :        5464 :         return *this;
     107                 :             : }
     108                 :             : 
     109                 :      436822 : string& operator+=(const string& other)
     110                 :             : {
     111                 :             :         int current_end = length();
     112                 :      436822 :         resize(length() + other.length());
     113                 :      436822 :         copy(other.data(), other.length(), raw() + current_end);
     114                 :      436822 :         return *this;
     115                 :             : }
     116                 :             : 
     117                 :       21755 : string& operator+=(const char *other)
     118                 :             : {
     119                 :             :         int current_end = length();
     120                 :       21755 :         int otherlen=(int)strlen(other);
     121                 :       21755 :         resize(length() + otherlen);
     122                 :       21755 :         copy(other, otherlen, raw() + current_end);
     123                 :       21755 :         return *this;
     124                 :             : }
     125                 :             : 
     126                 :     4829363 : string& operator+=(char c)
     127                 :             : {
     128                 :     4829363 :         resize(length() + 1);
     129                 :     4829363 :         raw()[length() - 1] = c;
     130                 :     4829363 :         return *this;
     131                 :             : }
     132                 :             : 
     133                 :             : string operator+(char right) const
     134                 :             : {
     135                 :             :         string ret=*this;
     136                 :             :         ret+=right;
     137                 :             :         return ret;
     138                 :             : }
     139                 :             : 
     140                 :             : string operator+(const char * right) const
     141                 :             : {
     142                 :       20672 :         string ret=*this;
     143                 :       20672 :         ret+=right;
     144                 :          69 :         return ret;
     145                 :             : }
     146                 :             : 
     147                 :        2605 : bool operator==(const char * right) const
     148                 :             : {
     149                 :        2605 :         return !strcmp(data(), right);
     150                 :             : }
     151                 :             : 
     152                 :          52 : bool operator==(const string& right) const
     153                 :             : {
     154                 :          52 :         return !strcmp(data(), right.data());
     155                 :             : }
     156                 :             : 
     157                 :         817 : bool operator!=(const char * right) const
     158                 :             : {
     159                 :         817 :         return (strcmp(data(), right) != 0);
     160                 :             : }
     161                 :             : 
     162                 :             : bool operator!=(const string& right) const
     163                 :             : {
     164                 :             :         return (strcmp(data(), right.data()) != 0);
     165                 :             : }
     166                 :             : 
     167                 :             : operator const char*() const
     168                 :             : {
     169                 :             :         return data();
     170                 :             : }
     171                 :             : 
     172                 :      214521 : explicit operator bool() const
     173                 :             : {
     174                 :      214521 :         return length();
     175                 :             : }
     176                 :             : 
     177                 :     8227982 : string()
     178                 :     8227982 : {
     179                 :             :         //todo reduce I know this isn't all needed
     180                 :     8227982 :         allocated.bufferlen = 0;
     181                 :     8227982 :         allocated.str = 0;
     182                 :     8227982 :         allocated.len = 0;
     183                 :     8227982 :         inlined.len = 0;
     184                 :     8227982 :         cached_data = inlined.str;
     185                 :     8227982 :         next_resize = max_inline_length_+1;
     186                 :             : 
     187                 :     8227982 : }
     188                 :     1885859 : string(const char * newstr) : string()
     189                 :             : {
     190                 :     1885859 :         assign(newstr);
     191                 :     1885859 : }
     192                 :     1305810 : string(const char * newstr, int newlen) : string()
     193                 :             : {
     194                 :     1305810 :         assign(newstr, newlen);
     195                 :     1305810 : }
     196                 :      233966 : string(const string& old) : string()
     197                 :             : {
     198                 :      233966 :         assign(old.data());
     199                 :      233966 : }
     200                 :             : 
     201                 :         537 : string(string &&move) : string()
     202                 :             : {
     203                 :             :         *this = move;
     204                 :         537 : }
     205                 :             : 
     206                 :     1411975 : string& operator=(string&& move)
     207                 :             : {
     208                 :         350 :         if(!is_inlined()) free(allocated.str);
     209                 :     1411975 :         if(!move.is_inlined()){
     210                 :         461 :                 allocated.str = move.allocated.str;
     211                 :         461 :                 allocated.bufferlen = move.allocated.bufferlen;
     212                 :         461 :                 set_length(move.allocated.len);
     213                 :             :                 
     214                 :         461 :                 move.inlined.len = 0;
     215                 :         461 :                 move.inlined.str[0] = 0;
     216                 :         461 :                 cached_data = allocated.str;
     217                 :         461 :                 next_resize = move.next_resize;
     218                 :             :                 
     219                 :             :         }else{
     220                 :     1411514 :                 inlined.len = 0;
     221                 :     1411514 :                 cached_data = inlined.str;
     222                 :     1411514 :                 next_resize = max_inline_length_+1;
     223                 :     1411514 :                 assign(move);
     224                 :             :         }
     225                 :     1411975 :         return *this;
     226                 :             : }
     227                 :             : 
     228                 :     8227971 : ~string()
     229                 :             : {
     230                 :     8227971 :         if(!is_inlined()){
     231                 :        3840 :                 free(allocated.str);
     232                 :             :         }
     233                 :     8227971 : }
     234                 :             : 
     235                 :             : string& replace(const char * instr, const char * outstr, bool all=true);
     236                 :             : string& qreplace(const char * instr, const char * outstr, bool all=true);
     237                 :             : 
     238                 :             : #ifdef SERIALIZER
     239                 :             : void serialize(serializer & s)
     240                 :             : {
     241                 :             :         s(str, allocated.bufferlen);
     242                 :             :         set_length(strlen(str));
     243                 :             : }
     244                 :             : #endif
     245                 :             : #define SERIALIZER_BANNED
     246                 :             : 
     247                 :             : private:
     248                 :             : static const int scale_factor = 3; //scale sso
     249                 :             : static const int max_inline_length_ = ((sizeof(char *) + sizeof(int) * 2) * scale_factor) - 2;
     250                 :             : char *cached_data;
     251                 :             : int next_resize;
     252                 :             : struct si{
     253                 :             :                 char str[max_inline_length_ + 1];
     254                 :             :                 unsigned char len;
     255                 :             : };
     256                 :             : 
     257                 :             : struct sa{
     258                 :             :                 char *str;
     259                 :             :                 int len;
     260                 :             :                 int bufferlen ;
     261                 :             : };
     262                 :             : union{
     263                 :             :         si inlined;
     264                 :             :         sa allocated;
     265                 :             : };
     266                 :             :                 
     267                 :             : 
     268                 :    13991688 : void resize(int new_length)
     269                 :             : {
     270                 :             :         const char *old_data = data();
     271   [ +  +  +  + ]:    14006591 :         if(new_length >= next_resize || (!is_inlined() && new_length <= max_inline_length_)) {
     272   [ +  +  -  + ]:        4936 :                 if(new_length > max_inline_length_ && (is_inlined() || allocated.bufferlen <= new_length)){ //SSO or big to big
     273                 :        4563 :                         int new_size = bit_round(new_length + 1);
     274         [ +  + ]:        4563 :                         if(old_data == inlined.str){
     275                 :        8492 :                                 allocated.str = copy(old_data, min_val(length(), new_length), (char *)malloc(new_size));
     276                 :             :                         }else{
     277                 :         317 :                                 allocated.str = (char *)realloc(allocated.str, new_size);
     278                 :             :                                 old_data = inlined.str; //this will prevent freeing a dead realloc ptr
     279                 :             :                         }
     280                 :        4563 :                         allocated.bufferlen = new_size;
     281                 :        4563 :                         cached_data = allocated.str;
     282                 :        4563 :                         next_resize = allocated.bufferlen;
     283   [ -  +  -  + ]:          56 :                 }else if(length() > max_inline_length_ && new_length <= max_inline_length_){ //big to SSO
     284                 :          56 :                         copy(old_data, new_length, inlined.str);
     285                 :          56 :                         cached_data = inlined.str;
     286                 :          56 :                         next_resize = max_inline_length_+1;
     287                 :             :                 }
     288   [ +  +  +  - ]:        4619 :                 if(old_data != inlined.str && old_data != data()){
     289                 :          56 :                         free((char *)old_data);
     290                 :             :                 }
     291                 :             :         }
     292                 :    13991688 :         set_length(new_length);
     293                 :             :         
     294                 :    13991688 :         raw()[new_length] = 0; //always ensure null terminator
     295                 :    13991688 : }
     296                 :             : 
     297                 :             : bool is_inlined() const
     298                 :             : {
     299   [ +  +  +  +  :    48815968 :         return inlined.len != (unsigned char)-1;
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  -  -  -  
                      - ]
     300                 :             : }
     301                 :             : };
     302                 :             : #define STR (string)
     303                 :             : 
     304                 :             : char * readfile(const char * fname, const char * basepath);
     305                 :             : char * readfilenative(const char * fname);
     306                 :             : bool readfile(const char * fname, const char * basepath, char ** data, int * len);//if you want an uchar*, cast it
     307                 :             : char ** nsplit(char * str, const char * key, int maxlen, int * len);
     308                 :             : char ** qnsplit(char * str, const char * key, int maxlen, int * len);
     309                 :             : char ** qpnsplit(char * str, const char * key, int maxlen, int * len);
     310                 :         563 : inline char ** split(char * str, const char * key, int * len= nullptr) { return nsplit(str, key, 0, len); }
     311                 :      873228 : inline char ** qsplit(char * str, const char * key, int * len= nullptr) { return qnsplit(str, key, 0, len); }
     312                 :      110033 : inline char ** qpsplit(char * str, const char * key, int * len= nullptr) { return qpnsplit(str, key, 0, len); }
     313                 :             : inline char ** split1(char * str, const char * key, int * len= nullptr) { return nsplit(str, key, 2, len); }
     314                 :             : inline char ** qsplit1(char * str, const char * key, int * len= nullptr) { return qnsplit(str, key, 2, len); }
     315                 :             : inline char ** qpsplit1(char * str, const char * key, int * len= nullptr) { return qpnsplit(str, key, 2, len); }
     316                 :             : //void replace(string& str, const char * instr, const char * outstr, bool all);
     317                 :             : //void qreplace(string& str, const char * instr, const char * outstr, bool all);
     318                 :             : bool confirmquotes(const char * str);
     319                 :             : bool confirmqpar(const char * str);
     320                 :             : char* strqpchr(const char* str, char key);
     321                 :             : char* strqpstr(const char* str, const char* key);
     322                 :             : 
     323                 :           0 : inline string hex(unsigned int value)
     324                 :             : {
     325                 :             :         char buffer[64];
     326                 :             :         if(0);
     327         [ #  # ]:           0 :         else if (value<=0x000000FF) sprintf(buffer, "%.2X", value);
     328         [ #  # ]:           0 :         else if (value<=0x0000FFFF) sprintf(buffer, "%.4X", value);
     329         [ #  # ]:           0 :         else if (value<=0x00FFFFFF) sprintf(buffer, "%.6X", value);
     330                 :           0 :         else sprintf(buffer, "%.8X", value);
     331                 :           0 :         return buffer;
     332                 :             : }
     333                 :             : 
     334                 :             : inline string hex(unsigned int value, int width)
     335                 :             : {
     336                 :             :         char buffer[64];
     337                 :             :         sprintf(buffer, "%.*X", width, value);
     338                 :             :         return buffer;
     339                 :             : }
     340                 :             : 
     341                 :             : inline string hex0(unsigned int value)
     342                 :             : {
     343                 :             :         char buffer[64];
     344                 :             :         sprintf(buffer, "%X", value);
     345                 :             :         return buffer;
     346                 :             : }
     347                 :             : 
     348                 :           0 : inline string hex2(unsigned int value)
     349                 :             : {
     350                 :             :         char buffer[64];
     351                 :           0 :         sprintf(buffer, "%.2X", value);
     352                 :           0 :         return buffer;
     353                 :             : }
     354                 :             : 
     355                 :             : inline string hex3(unsigned int value)
     356                 :             : {
     357                 :             :         char buffer[64];
     358                 :             :         sprintf(buffer, "%.3X", value);
     359                 :             :         return buffer;
     360                 :             : }
     361                 :             : 
     362                 :           0 : inline string hex4(unsigned int value)
     363                 :             : {
     364                 :             :         char buffer[64];
     365                 :           0 :         sprintf(buffer, "%.4X", value);
     366                 :           0 :         return buffer;
     367                 :             : }
     368                 :             : 
     369                 :             : inline string hex5(unsigned int value)
     370                 :             : {
     371                 :             :         char buffer[64];
     372                 :             :         sprintf(buffer, "%.5X", value);
     373                 :             :         return buffer;
     374                 :             : }
     375                 :             : 
     376                 :           1 : inline string hex6(unsigned int value)
     377                 :             : {
     378                 :             :         char buffer[64];
     379                 :           1 :         sprintf(buffer, "%.6X", value);
     380                 :           1 :         return buffer;
     381                 :             : }
     382                 :             : 
     383                 :           0 : inline string hex8(unsigned int value)
     384                 :             : {
     385                 :             :         char buffer[64];
     386                 :           0 :         sprintf(buffer, "%.8X", value);
     387                 :           0 :         return buffer;
     388                 :             : }
     389                 :             : 
     390                 :         805 : inline string dec(int value)
     391                 :             : {
     392                 :             :         char buffer[64];
     393                 :         805 :         sprintf(buffer, "%i", value);
     394                 :         805 :         return buffer;
     395                 :             : }
     396                 :             : 
     397                 :      105603 : inline string ftostr(double value)
     398                 :             : {
     399                 :             :         // randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100,
     400                 :             :         // but let's be safe here https://stackoverflow.com/questions/7235456
     401                 :             :         char rval[512];
     402                 :             :         // RPG Hacker: Ridiculously high precision, I know, but we're working with doubles
     403                 :             :         // here and can afford it, so no need to waste any precision
     404                 :      105603 :         sprintf(rval, "%.100f", value);
     405         [ +  - ]:      105603 :         if (strchr(rval, '.'))//nuke useless zeroes
     406                 :             :         {
     407                 :      105603 :                 char * end=strrchr(rval, '\0')-1;
     408         [ +  + ]:    10665729 :                 while (*end=='0')
     409                 :             :                 {
     410                 :    10560126 :                         *end='\0';
     411                 :    10560126 :                         end--;
     412                 :             :                 }
     413         [ +  + ]:      105603 :                 if (*end=='.') *end='\0';
     414                 :             :         }
     415                 :      105603 :         return rval;
     416                 :             : }
     417                 :             : 
     418                 :             : // Same as above, but with variable precision
     419                 :          23 : inline string ftostrvar(double value, int precision)
     420                 :             : {
     421                 :             :         int clampedprecision = precision;
     422                 :             :         if (clampedprecision < 0) clampedprecision = 0;
     423                 :          23 :         if (clampedprecision > 100) clampedprecision = 100;
     424                 :             :         
     425                 :             :         // see above
     426                 :             :         char rval[512];
     427                 :          23 :         sprintf(rval, "%.*f", clampedprecision, (double)value);
     428         [ +  + ]:          23 :         if (strchr(rval, '.'))//nuke useless zeroes
     429                 :             :         {
     430                 :          22 :                 char * end = strrchr(rval, '\0') - 1;
     431         [ +  + ]:          91 :                 while (*end == '0')
     432                 :             :                 {
     433                 :          69 :                         *end = '\0';
     434                 :          69 :                         end--;
     435                 :             :                 }
     436         [ +  + ]:          22 :                 if (*end == '.') *end = '\0';
     437                 :             :         }
     438                 :          23 :         return rval;
     439                 :             : }
     440                 :             : 
     441                 :     1398871 : inline bool stribegin(const char * str, const char * key)
     442                 :             : {
     443         [ +  + ]:     2139278 :         for (int i=0;key[i];i++)
     444                 :             :         {
     445         [ +  + ]:     2029628 :                 if (to_lower(str[i])!=to_lower(key[i])) return false;
     446                 :             :         }
     447                 :             :         return true;
     448                 :             : }
     449                 :             : 
     450                 :        3930 : inline bool striend(const char * str, const char * key)
     451                 :             : {
     452                 :             :         const char * keyend=strrchr(key, '\0');
     453                 :             :         const char * strend=strrchr(str, '\0');
     454         [ +  + ]:        5091 :         while (key!=keyend)
     455                 :             :         {
     456                 :        4374 :                 keyend--;
     457                 :        4374 :                 strend--;
     458         [ +  + ]:        4374 :                 if (to_lower(*strend)!=to_lower(*keyend)) return false;
     459                 :             :         }
     460                 :             :         return true;
     461                 :             : }
     462                 :             : 
     463                 :       56635 : inline bool stricmpwithupper(const char *word1, const char *word2)
     464                 :             : {
     465         [ +  + ]:       65085 :         while(*word2)
     466                 :             :         {
     467         [ +  + ]:       63247 :                 if(to_upper(*word1++) != *word2++) return true;
     468                 :             :         }
     469                 :        1838 :         return *word1;
     470                 :             : }
     471                 :             : 
     472                 :     5234383 : inline bool stricmpwithlower(const char *word1, const char *word2)
     473                 :             : {
     474         [ +  + ]:    10343011 :         while(*word2)
     475                 :             :         {
     476         [ +  + ]:     9491453 :                 if(to_lower(*word1++) != *word2++) return true;
     477                 :             :         }
     478                 :      851558 :         return *word1;
     479                 :             : }
     480                 :             : 
     481                 :             : //function: return the string without quotes around it, if any exists
     482                 :             : //if they don't exist, return it unaltered
     483                 :             : //it is not guaranteed to return str
     484                 :             : //it is not guaranteed to not edit str
     485                 :             : //the input must be freed even though it's garbage, the output must not
     486                 :         754 : inline const char * dequote(char * str)
     487                 :             : {
     488         [ +  + ]:         754 :         if (*str!='"') return str;
     489                 :             :         int inpos=1;
     490                 :             :         int outpos=0;
     491                 :             :         while (true)
     492                 :             :         {
     493         [ +  + ]:        9193 :                 if (str[inpos]=='"')
     494                 :             :                 {
     495         [ +  + ]:         784 :                         if (str[inpos+1]=='"') inpos++;
     496         [ +  - ]:         712 :                         else if (str[inpos+1]=='\0') break;
     497                 :             :                         else return nullptr;
     498                 :             :                 }
     499         [ +  - ]:        8481 :                 if (!str[inpos]) return nullptr;
     500                 :        8481 :                 str[outpos++]=str[inpos++];
     501                 :             :         }
     502                 :         712 :         str[outpos]=0;
     503                 :         712 :         return str;
     504                 :             : }
     505                 :             : 
     506                 :       11145 : inline char * strqchr(const char * str, char key)
     507                 :             : {
     508         [ +  + ]:       94677 :         while (*str != '\0')
     509                 :             :         {
     510         [ +  + ]:       85652 :                 if (*str == key) { return const_cast<char*>(str); }
     511   [ +  +  +  + ]:       83534 :                 else if (*str == '"' || *str == '\'')
     512                 :             :                 {
     513                 :             :                         // Special case hack for ''', which is currently our official way of handling the ' character.
     514                 :             :                         // Even though it really stinks.
     515   [ +  +  +  +  :         480 :                         if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; }
                   +  - ]
     516                 :             :                         else
     517                 :             :                         {
     518                 :             :                                 char delimiter = *str;
     519                 :             : 
     520                 :             :                                 do
     521                 :             :                                 {
     522                 :        6561 :                                         str++;
     523                 :             : 
     524                 :             :                                         // If we want to support backslash escapes, we'll have to add that right here.
     525   [ +  +  +  + ]:        6561 :                                 } while (*str != delimiter && *str != '\0');
     526                 :             : 
     527                 :             :                                 // This feels like a superfluous check, but I can't really find a clean way to avoid it.
     528         [ +  + ]:         476 :                                 if (*str == '\0') { return nullptr; }
     529                 :             :                         }
     530                 :             :                 }
     531                 :             : 
     532                 :       83532 :                 str++;
     533                 :             :         }
     534                 :             : 
     535                 :             :         return nullptr;
     536                 :             : }
     537                 :             : 
     538                 :             : // RPG Hacker: WOW, these functions are poopy!
     539                 :        5686 : inline char * strqrchr(const char * str, char key)
     540                 :             : {
     541                 :             :         const char * ret= nullptr;
     542         [ +  + ]:       41522 :         while (*str)
     543                 :             :         {
     544   [ +  +  +  + ]:       35836 :                 if (*str=='"' || *str=='\'')
     545                 :             :                 {
     546                 :             :                         char token = *str;
     547                 :             : 
     548                 :         335 :                         str++;
     549                 :             : 
     550                 :             :                         // Special case hack for '''
     551   [ +  +  +  + ]:         335 :                         if (str[0] == '\'' && str[1] == '\'') { str += 2; }
     552                 :             :                         else
     553                 :             :                         {
     554         [ +  + ]:        3493 :                                 while (*str != token)
     555                 :             :                                 {
     556         [ +  - ]:        3160 :                                         if (!*str) return nullptr;
     557                 :        3160 :                                         str++;
     558                 :             :                                 }
     559                 :         333 :                                 str++;
     560                 :             :                         }
     561                 :             :                 }
     562                 :             :                 else
     563                 :             :                 {
     564         [ +  + ]:       35501 :                         if (*str==key) ret=str;
     565                 :       35501 :                         str++;
     566                 :             :                 }
     567                 :             :         }
     568                 :             :         return const_cast<char*>(ret);
     569                 :             : }
     570                 :             : 
     571                 :             : inline string substr(const char * str, int len)
     572                 :             : {
     573                 :        1320 :         return string(str, len);
     574                 :             : }
     575                 :             : 
     576                 :             : string &strip_prefix(string &str, char c, bool multi=false);
     577                 :             : string &strip_suffix(string &str, char c, bool multi=false);
     578                 :             : string &strip_both(string &str, char c, bool multi=false);
     579                 :             : string &strip_whitespace(string &str);
     580                 :             : 
     581                 :             : char * itrim(char * str, const char * left, const char * right, bool multi=false);
     582                 :             : string &itrim(string &str, const char * left, const char * right, bool multi=false);
     583                 :             : 
     584                 :             : inline string &upper(string &old)
     585                 :             : {
     586                 :             :         int length = old.length();
     587                 :             :         for (int i=0;i<length;i++) old.raw()[i]=(char)to_upper(old.data()[i]);
     588                 :             :         return old;
     589                 :             : }
     590                 :             : 
     591                 :           0 : inline string &lower(string &old)
     592                 :             : {
     593                 :             :         int length = old.length();
     594         [ #  # ]:           0 :         for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]);
     595                 :           0 :         return old;
     596                 :             : }
     597                 :             : 
     598                 :             : inline const char * stristr(const char * string, const char * pattern)
     599                 :             : {
     600                 :             :         if (!*pattern) return string;
     601                 :             :         const char * pptr;
     602                 :             :         const char * sptr;
     603                 :             :         const char * start;
     604                 :             :         for (start=string;*start!=0;start++)
     605                 :             :         {
     606                 :             :                 for (;(*start && (to_lower(*start)!=to_lower(*pattern)));start++);
     607                 :             :                 if (!*start) return nullptr;
     608                 :             :                 pptr=pattern;
     609                 :             :                 sptr=start;
     610                 :             :                 while (to_lower(*sptr)==to_lower(*pptr))
     611                 :             :                 {
     612                 :             :                         sptr++;
     613                 :             :                         pptr++;
     614                 :             :                         if (!*pptr) return start;
     615                 :             :                 }
     616                 :             :         }
     617                 :             :         return nullptr;
     618                 :             : }
     619                 :             : 
     620                 :             : 
     621                 :             : 
     622                 :             : // Returns number of connected lines - 1
     623                 :             : template<typename stringarraytype>
     624                 :      436216 : inline int getconnectedlines(stringarraytype& lines, int startline, string& out)
     625                 :             : {
     626                 :      436216 :         out = string("");
     627                 :             :         int count = 1;
     628                 :             : 
     629         [ +  - ]:      436744 :         for (int i = startline; lines[i]; i++)
     630                 :             :         {
     631                 :             :                 // The line should already be stripped of any comments at this point
     632                 :      436225 :                 int linestartpos = (int)strlen(lines[i]);
     633                 :             : 
     634                 :             :                 bool found = false;
     635                 :             : 
     636         [ +  + ]:      867558 :                 for (int j = linestartpos; j > 0; j--)
     637                 :             :                 {
     638   [ +  -  +  +  :      864133 :                         if (!is_space(lines[i][j]) && lines[i][j] != '\0' && lines[i][j] != ';')
                   +  - ]
     639                 :             :                         {
     640         [ +  + ]:      431243 :                                 if (lines[i][j] == '\\')
     641                 :             :                                 {
     642                 :           9 :                                         count++;
     643                 :           9 :                                         out += string(lines[i], j);
     644                 :             :                                         found = true;
     645                 :           9 :                                         break;
     646                 :             :                                 }
     647                 :             :                                 else
     648                 :             :                                 {
     649                 :      431234 :                                         out += string(lines[i], j + 1);
     650                 :      431234 :                                         return count - 1;
     651                 :             :                                 }
     652                 :             :                         }
     653                 :             :                 }
     654                 :             : 
     655         [ +  + ]:        4991 :                 if (!found)
     656                 :             :                 {
     657                 :        4982 :                         out += string(lines[i], 1);
     658                 :        4982 :                         return count - 1;
     659                 :             :                 }
     660                 :             :         }
     661                 :             : 
     662                 :           0 :         return count - 1;
     663                 :             : }
        

Generated by: LCOV version 2.0-1