Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 10, 2008, 12:05:03 AM (16 years ago)
Author:
landauf
Message:

merged revisions 2111-2170 from objecthierarchy branch back to trunk.

Location:
code/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/util

  • code/trunk/src/util/String.cc

    r2087 r2171  
    2828
    2929/**
    30     @file String.cc
     30    @file
    3131    @brief Implementation of several string manipulation functions.
    3232*/
     
    4040#include "Math.h"
    4141
    42 std::string BLANKSTRING("");
    43 
    44 std::string getUniqueNumberString()
     42namespace orxonox
    4543{
    46     return convertToString(getUniqueNumber());
     44    std::string BLANKSTRING("");
     45
     46    std::string getUniqueNumberString()
     47    {
     48        return convertToString(getUniqueNumber());
     49    }
     50
     51    /**
     52        @brief Removes all whitespaces from a string.
     53        @param str The string to strip
     54    */
     55    void strip(std::string* str)
     56    {
     57        size_t pos;
     58        while ((pos = (*str).find(" ")) < (*str).length())
     59            (*str).erase(pos, 1);
     60        while ((pos = (*str).find("\t")) < (*str).length())
     61            (*str).erase(pos, 1);
     62        while ((pos = (*str).find("\n")) < (*str).length())
     63            (*str).erase(pos, 1);
     64    }
     65
     66    /**
     67        @brief Returns a copy of a string without whitespaces.
     68        @param str The string to strip
     69        @return The stripped line
     70    */
     71    std::string getStripped(const std::string& str)
     72    {
     73        std::string output = std::string(str);
     74        strip(&output);
     75        return output;
     76    }
     77
     78    /**
     79        @brief Returns a copy of a string without trailing whitespaces.
     80        @param str The string
     81        @return The modified copy
     82    */
     83    std::string removeTrailingWhitespaces(const std::string& str)
     84    {
     85        size_t pos1 = 0;
     86        int pos2 = str.size() - 1;
     87        for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++);
     88        for (; pos2 > 0         && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--);
     89        return str.substr(pos1, pos2 - pos1 + 1);
     90    }
     91
     92    /**
     93        @brief Returns the position of the next quote in the string, starting with start.
     94        @param str The string
     95        @param start The startposition
     96        @return The position of the next quote (std::string::npos if there is no next quote)
     97    */
     98    size_t getNextQuote(const std::string& str, size_t start)
     99    {
     100        size_t quote = start - 1;
     101
     102        while ((quote = str.find('\"', quote + 1)) != std::string::npos)
     103        {
     104            size_t backslash = quote;
     105            size_t numbackslashes = 0;
     106            for (; backslash > 0; backslash--, numbackslashes++)
     107                if (str[backslash - 1] != '\\')
     108                    break;
     109
     110            if (numbackslashes % 2 == 0)
     111                break;
     112        }
     113
     114        return quote;
     115    }
     116
     117    /**
     118        @brief Returns true if pos is between two quotes.
     119        @param str The string
     120        @param pos The position to check
     121        @return True if pos is between two quotes
     122    */
     123    bool isBetweenQuotes(const std::string& str, size_t pos)
     124    {
     125        if (pos == std::string::npos)
     126            return false;
     127
     128        size_t quotecount = 0;
     129        size_t quote = (size_t)-1;
     130        while ((quote = getNextQuote(str, quote + 1)) < pos)
     131        {
     132            if (quote == pos)
     133                return false;
     134            quotecount++;
     135        }
     136
     137        if (quote == std::string::npos)
     138            return false;
     139
     140        return ((quotecount % 2) == 1);
     141    }
     142
     143    /**
     144        @brief Returns true if the string contains something like '..."between quotes"...'.
     145        @param The string
     146        @return True if there is something between quotes
     147    */
     148    bool hasStringBetweenQuotes(const std::string& str)
     149    {
     150        size_t pos1 = getNextQuote(str, 0);
     151        size_t pos2 = getNextQuote(str, pos1 + 1);
     152        return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1);
     153    }
     154
     155    /**
     156        @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes).
     157        @param The string
     158        @param The string between the quotes
     159    */
     160    std::string getStringBetweenQuotes(const std::string& str)
     161    {
     162        size_t pos1 = getNextQuote(str, 0);
     163        size_t pos2 = getNextQuote(str, pos1 + 1);
     164        if (pos1 != std::string::npos && pos2 != std::string::npos)
     165            return str.substr(pos1, pos2 - pos1 + 1);
     166        else
     167            return "";
     168    }
     169
     170    /**
     171        @brief Removes enclosing quotes if available (including whitespaces at the outside of the quotes).
     172        @brief str The string to strip
     173        @return The string with removed quotes
     174    */
     175    std::string stripEnclosingQuotes(const std::string& str)
     176    {
     177        size_t start = std::string::npos;
     178        size_t end = 0;
     179
     180        for (size_t pos = 0; (pos < str.size()) && (pos < std::string::npos); pos++)
     181        {
     182            if (str[pos] == '"')
     183            {
     184                start = pos;
     185                break;
     186            }
     187
     188            if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))
     189                return str;
     190        }
     191
     192        for (size_t pos = str.size() - 1; pos < std::string::npos; pos--)
     193        {
     194            if (str[pos] == '"')
     195            {
     196                end = pos;
     197                break;
     198            }
     199
     200            if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))
     201                return str;
     202        }
     203
     204        if ((start != std::string::npos) && (end != 0))
     205            return str.substr(start + 1, end - start - 1);
     206        else
     207            return str;
     208    }
     209
     210    /**
     211        @brief Removes enclosing {braces} (braces must be exactly on the beginning and the end of the string).
     212        @param str The string to strip
     213        @return The striped string
     214    */
     215    std::string stripEnclosingBraces(const std::string& str)
     216    {
     217        std::string output = str;
     218
     219        while (output.size() >= 2 && output[0] == '{' && output[output.size() - 1] == '}')
     220            output = output.substr(1, output.size() - 2);
     221
     222        return output;
     223    }
     224
     225    /**
     226        @brief Determines if a string is a comment (starts with a comment-symbol).
     227        @param str The string to check
     228        @return True = it's a comment
     229
     230        A comment is defined by a leading '#', '%', ';' or '//'.
     231    */
     232    bool isComment(const std::string& str)
     233    {
     234        // Strip the line, whitespaces are disturbing
     235        std::string teststring = getStripped(str);
     236
     237        // There are four possible comment-symbols:
     238        //  1) #comment in script-language style
     239        //  2) %comment in matlab style
     240        //  3) ;comment in unreal tournament config-file style
     241        //  4) //comment in code style
     242        if (teststring.size() >= 2)
     243        {
     244            if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/'))
     245                return true;
     246        }
     247        else if (teststring.size() == 1)
     248        {
     249            if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';')
     250                return true;
     251        }
     252
     253        return false;
     254    }
     255
     256    /**
     257        @brief Determines if a string is empty (contains only whitespaces).
     258        @param str The string to check
     259        @return True = it's empty
     260    */
     261    bool isEmpty(const std::string& str)
     262    {
     263        std::string temp = getStripped(str);
     264        return ((temp == "") || (temp.size() == 0));
     265    }
     266
     267    /**
     268        @brief Determines if a string contains only numbers and maximal one '.'.
     269        @param str The string to check
     270        @return True = it's a number
     271    */
     272    bool isNumeric(const std::string& str)
     273    {
     274        bool foundPoint = false;
     275
     276        for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
     277        {
     278            if (((*it) < '0' || (*it) > '9'))
     279            {
     280                if ((*it) != '.' && !foundPoint)
     281                    foundPoint = true;
     282                else
     283                    return false;
     284            }
     285        }
     286
     287        return true;
     288    }
     289
     290    /**
     291        @brief Adds backslashes to the given string which makes special chars visible. Existing slashes will be doubled.
     292        @param str The string to manipulate
     293        @return The string with added slashes
     294    */
     295    std::string addSlashes(const std::string& str)
     296    {
     297        std::string output = str;
     298
     299        for (size_t pos = 0; (pos = output.find('\\', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\\"); }
     300        for (size_t pos = 0; (pos = output.find('\n', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\n"); }
     301        for (size_t pos = 0; (pos = output.find('\t', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\t"); }
     302        for (size_t pos = 0; (pos = output.find('\v', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\v"); }
     303        for (size_t pos = 0; (pos = output.find('\b', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\b"); }
     304        for (size_t pos = 0; (pos = output.find('\r', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\r"); }
     305        for (size_t pos = 0; (pos = output.find('\f', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\f"); }
     306        for (size_t pos = 0; (pos = output.find('\a', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\a"); }
     307        for (size_t pos = 0; (pos = output.find('"', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\""); }
     308        for (size_t pos = 0; (pos = output.find('\0', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\0"); }
     309
     310        return output;
     311    }
     312
     313    /**
     314        @brief Removes backslashes from the given string. Double backslashes are interpreted as one backslash.
     315        @param str The string to manipulate
     316        @return The string with removed slashes
     317    */
     318    std::string removeSlashes(const std::string& str)
     319    {
     320        if (str.size() <= 1)
     321            return str;
     322
     323        std::string output = "";
     324        for (size_t pos = 0; pos < str.size() - 1; )
     325        {
     326            if (str[pos] == '\\')
     327            {
     328                if (str[pos + 1] == '\\') { output += '\\'; pos += 2; continue; }
     329                else if (str[pos + 1] == 'n') { output += '\n'; pos += 2; continue; }
     330                else if (str[pos + 1] == 't') { output += '\t'; pos += 2; continue; }
     331                else if (str[pos + 1] == 'v') { output += '\v'; pos += 2; continue; }
     332                else if (str[pos + 1] == 'b') { output += '\b'; pos += 2; continue; }
     333                else if (str[pos + 1] == 'r') { output += '\r'; pos += 2; continue; }
     334                else if (str[pos + 1] == 'f') { output += '\f'; pos += 2; continue; }
     335                else if (str[pos + 1] == 'a') { output += '\a'; pos += 2; continue; }
     336                else if (str[pos + 1] == '"') { output += '"'; pos += 2; continue; }
     337                else if (str[pos + 1] == '0') { output += '\0'; pos += 2; continue; }
     338            }
     339            output += str[pos];
     340            pos++;
     341            if (pos == str.size() - 1)
     342                output += str[pos];
     343        }
     344
     345        return output;
     346    }
     347
     348    /**
     349        @brief Replaces each char between A and Z with its lowercase equivalent.
     350        @param str The string to convert
     351    */
     352    void lowercase(std::string* str)
     353    {
     354        for (size_t i = 0; i < str->size(); ++i)
     355        {
     356            (*str)[i] = (char)tolower((*str)[i]);
     357        }
     358    }
     359
     360    /**
     361        @brief Returns a copy of the given string without uppercase chars.
     362        @param str The string
     363        @return The copy
     364    */
     365    std::string getLowercase(const std::string& str)
     366    {
     367        std::string output = std::string(str);
     368        lowercase(&output);
     369        return output;
     370    }
     371
     372    /**
     373        @brief Replaces each char between a and z with its uppercase equivalent.
     374        @param str The string to convert
     375    */
     376    void uppercase(std::string* str)
     377    {
     378        for (size_t i = 0; i < str->size(); ++i)
     379        {
     380            (*str)[i] = (char)toupper((*str)[i]);
     381        }
     382    }
     383
     384    /**
     385        @brief Returns a copy of the given string without lowercase chars.
     386        @param str The string
     387        @return The copy
     388    */
     389    std::string getUppercase(const std::string& str)
     390    {
     391        std::string output = std::string(str);
     392        uppercase(&output);
     393        return output;
     394    }
     395
     396    /**
     397        @brief Compares two strings ignoring different casing.
     398        @param s1 First string
     399        @param s2 Second string
     400    */
     401    int nocaseCmp(const std::string& s1, const std::string& s2)
     402    {
     403        std::string::const_iterator it1=s1.begin();
     404        std::string::const_iterator it2=s2.begin();
     405
     406        //stop when either string's end has been reached
     407        while ( (it1!=s1.end()) && (it2!=s2.end()) )
     408        {
     409            if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
     410                // return -1 to indicate smaller than, 1 otherwise
     411                return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
     412            //proceed to the next character in each string
     413            ++it1;
     414            ++it2;
     415        }
     416        size_t size1=s1.size(), size2=s2.size();// cache lengths
     417        //return -1,0 or 1 according to strings' lengths
     418        if (size1==size2)
     419            return 0;
     420        return (size1<size2) ? -1 : 1;
     421    }
     422
     423
     424    /**
     425        @brief Compares the first 'len' chars of two strings ignoring different casing.
     426        @param s1 First string
     427        @param s2 Second string
     428        @param len Maximal number of chars to compare
     429    */
     430    int nocaseCmp(const std::string& s1, const std::string& s2, size_t len)
     431    {
     432        if (len == 0)
     433            return 0;
     434        std::string::const_iterator it1=s1.begin();
     435        std::string::const_iterator it2=s2.begin();
     436
     437        //stop when either string's end has been reached
     438        while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0)
     439        {
     440            if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
     441                // return -1 to indicate smaller than, 1 otherwise
     442                return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
     443            //proceed to the next character in each string
     444            ++it1;
     445            ++it2;
     446        }
     447        return 0;
     448    }
     449
     450    /**
     451        @brief Returns true if the string contains a comment, introduced by #, %, ; or //.
     452        @param str The string
     453        @return True if the string contains a comment
     454    */
     455    bool hasComment(const std::string& str)
     456    {
     457        return (getCommentPosition(str) != std::string::npos);
     458    }
     459
     460    /**
     461        @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise.
     462        @param str The string
     463        @return The comment
     464    */
     465    std::string getComment(const std::string& str)
     466    {
     467        return str.substr(getCommentPosition(str));
     468    }
     469
     470    /**
     471        @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise.
     472        @param str The string
     473        @return The position
     474    */
     475    size_t getCommentPosition(const std::string& str)
     476    {
     477        return getNextCommentPosition(str, 0);
     478    }
     479
     480    /**
     481        @brief Returns the position of the next comment-symbol, starting with start.
     482        @param str The string
     483        @param start The startposition
     484        @return The position
     485    */
     486    size_t getNextCommentPosition(const std::string& str, size_t start)
     487    {
     488        for (size_t i = start; i < str.size(); i++)
     489            if (isComment(str.substr(i)))
     490                return i;
     491
     492        return std::string::npos;
     493    }
    47494}
    48 
    49 /**
    50     @brief Removes all whitespaces from a string.
    51     @param str The string to strip
    52 */
    53 void strip(std::string* str)
    54 {
    55     size_t pos;
    56     while ((pos = (*str).find(" ")) < (*str).length())
    57         (*str).erase(pos, 1);
    58     while ((pos = (*str).find("\t")) < (*str).length())
    59         (*str).erase(pos, 1);
    60     while ((pos = (*str).find("\n")) < (*str).length())
    61         (*str).erase(pos, 1);
    62 }
    63 
    64 /**
    65     @brief Returns a copy of a string without whitespaces.
    66     @param str The string to strip
    67     @return The stripped line
    68 */
    69 std::string getStripped(const std::string& str)
    70 {
    71     std::string output = std::string(str);
    72     strip(&output);
    73     return output;
    74 }
    75 
    76 /**
    77     @brief Returns a copy of a string without trailing whitespaces.
    78     @param str The string
    79     @return The modified copy
    80 */
    81 std::string removeTrailingWhitespaces(const std::string& str)
    82 {
    83     size_t pos1 = 0;
    84     int pos2 = str.size() - 1;
    85     for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++);
    86     for (; pos2 > 0         && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--);
    87     return str.substr(pos1, pos2 - pos1 + 1);
    88 }
    89 
    90 /**
    91     @brief Returns the position of the next quote in the string, starting with start.
    92     @param str The string
    93     @param start The startposition
    94     @return The position of the next quote (std::string::npos if there is no next quote)
    95 */
    96 size_t getNextQuote(const std::string& str, size_t start)
    97 {
    98     size_t quote = start - 1;
    99 
    100     while ((quote = str.find('\"', quote + 1)) != std::string::npos)
    101     {
    102         size_t backslash = quote;
    103         size_t numbackslashes = 0;
    104         for (; backslash > 0; backslash--, numbackslashes++)
    105             if (str[backslash - 1] != '\\')
    106                 break;
    107 
    108         if (numbackslashes % 2 == 0)
    109             break;
    110     }
    111 
    112     return quote;
    113 }
    114 
    115 /**
    116     @brief Returns true if pos is between two quotes.
    117     @param str The string
    118     @param pos The position to check
    119     @return True if pos is between two quotes
    120 */
    121 bool isBetweenQuotes(const std::string& str, size_t pos)
    122 {
    123     if (pos == std::string::npos)
    124         return false;
    125 
    126     size_t quotecount = 0;
    127     size_t quote = (size_t)-1;
    128     while ((quote = getNextQuote(str, quote + 1)) < pos)
    129     {
    130         if (quote == pos)
    131             return false;
    132         quotecount++;
    133     }
    134 
    135     if (quote == std::string::npos)
    136         return false;
    137 
    138     return ((quotecount % 2) == 1);
    139 }
    140 
    141 /**
    142     @brief Returns true if the string contains something like '..."between quotes"...'.
    143     @param The string
    144     @return True if there is something between quotes
    145 */
    146 bool hasStringBetweenQuotes(const std::string& str)
    147 {
    148     size_t pos1 = getNextQuote(str, 0);
    149     size_t pos2 = getNextQuote(str, pos1 + 1);
    150     return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1);
    151 }
    152 
    153 /**
    154     @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes).
    155     @param The string
    156     @param The string between the quotes
    157 */
    158 std::string getStringBetweenQuotes(const std::string& str)
    159 {
    160     size_t pos1 = getNextQuote(str, 0);
    161     size_t pos2 = getNextQuote(str, pos1 + 1);
    162     if (pos1 != std::string::npos && pos2 != std::string::npos)
    163         return str.substr(pos1, pos2 - pos1 + 1);
    164     else
    165         return "";
    166 }
    167 
    168 /**
    169     @brief Removes enclosing quotes if available (including whitespaces at the outside of the quotes).
    170     @brief str The string to strip
    171     @return The string with removed quotes
    172 */
    173 std::string stripEnclosingQuotes(const std::string& str)
    174 {
    175     size_t start = std::string::npos;
    176     size_t end = 0;
    177 
    178     for (size_t pos = 0; (pos < str.size()) && (pos < std::string::npos); pos++)
    179     {
    180         if (str[pos] == '"')
    181         {
    182             start = pos;
    183             break;
    184         }
    185 
    186         if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))
    187             return str;
    188     }
    189 
    190     for (size_t pos = str.size() - 1; pos < std::string::npos; pos--)
    191     {
    192         if (str[pos] == '"')
    193         {
    194             end = pos;
    195             break;
    196         }
    197 
    198         if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))
    199             return str;
    200     }
    201 
    202     if ((start != std::string::npos) && (end != 0))
    203         return str.substr(start + 1, end - start - 1);
    204     else
    205         return str;
    206 }
    207 
    208 /**
    209     @brief Removes enclosing {braces} (braces must be exactly on the beginning and the end of the string).
    210     @param str The string to strip
    211     @return The striped string
    212 */
    213 std::string stripEnclosingBraces(const std::string& str)
    214 {
    215     std::string output = str;
    216 
    217     while (output.size() >= 2 && output[0] == '{' && output[output.size() - 1] == '}')
    218         output = output.substr(1, output.size() - 2);
    219 
    220     return output;
    221 }
    222 
    223 /**
    224     @brief Determines if a string is a comment (starts with a comment-symbol).
    225     @param str The string to check
    226     @return True = it's a comment
    227 
    228     A comment is defined by a leading '#', '%', ';' or '//'.
    229 */
    230 bool isComment(const std::string& str)
    231 {
    232     // Strip the line, whitespaces are disturbing
    233     std::string teststring = getStripped(str);
    234 
    235     // There are four possible comment-symbols:
    236     //  1) #comment in script-language style
    237     //  2) %comment in matlab style
    238     //  3) ;comment in unreal tournament config-file style
    239     //  4) //comment in code style
    240     if (teststring.size() >= 2)
    241     {
    242         if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/'))
    243             return true;
    244     }
    245     else if (teststring.size() == 1)
    246     {
    247         if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';')
    248             return true;
    249     }
    250 
    251     return false;
    252 }
    253 
    254 /**
    255     @brief Determines if a string is empty (contains only whitespaces).
    256     @param str The string to check
    257     @return True = it's empty
    258 */
    259 bool isEmpty(const std::string& str)
    260 {
    261     std::string temp = getStripped(str);
    262     return ((temp == "") || (temp.size() == 0));
    263 }
    264 
    265 /**
    266     @brief Determines if a string contains only numbers and maximal one '.'.
    267     @param str The string to check
    268     @return True = it's a number
    269 */
    270 bool isNumeric(const std::string& str)
    271 {
    272     bool foundPoint = false;
    273 
    274     for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
    275     {
    276         if (((*it) < '0' || (*it) > '9'))
    277         {
    278             if ((*it) != '.' && !foundPoint)
    279                 foundPoint = true;
    280             else
    281                 return false;
    282         }
    283     }
    284 
    285     return true;
    286 }
    287 
    288 /**
    289     @brief Adds backslashes to the given string which makes special chars visible. Existing slashes will be doubled.
    290     @param str The string to manipulate
    291     @return The string with added slashes
    292 */
    293 std::string addSlashes(const std::string& str)
    294 {
    295     std::string output = str;
    296 
    297     for (size_t pos = 0; (pos = output.find('\\', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\\"); }
    298     for (size_t pos = 0; (pos = output.find('\n', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\n"); }
    299     for (size_t pos = 0; (pos = output.find('\t', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\t"); }
    300     for (size_t pos = 0; (pos = output.find('\v', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\v"); }
    301     for (size_t pos = 0; (pos = output.find('\b', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\b"); }
    302     for (size_t pos = 0; (pos = output.find('\r', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\r"); }
    303     for (size_t pos = 0; (pos = output.find('\f', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\f"); }
    304     for (size_t pos = 0; (pos = output.find('\a', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\a"); }
    305     for (size_t pos = 0; (pos = output.find('"', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\""); }
    306     for (size_t pos = 0; (pos = output.find('\0', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\0"); }
    307 
    308     return output;
    309 }
    310 
    311 /**
    312     @brief Removes backslashes from the given string. Double backslashes are interpreted as one backslash.
    313     @param str The string to manipulate
    314     @return The string with removed slashes
    315 */
    316 std::string removeSlashes(const std::string& str)
    317 {
    318     if (str.size() <= 1)
    319         return str;
    320 
    321     std::string output = "";
    322     for (size_t pos = 0; pos < str.size() - 1; )
    323     {
    324         if (str[pos] == '\\')
    325         {
    326             if (str[pos + 1] == '\\') { output += '\\'; pos += 2; continue; }
    327             else if (str[pos + 1] == 'n') { output += '\n'; pos += 2; continue; }
    328             else if (str[pos + 1] == 't') { output += '\t'; pos += 2; continue; }
    329             else if (str[pos + 1] == 'v') { output += '\v'; pos += 2; continue; }
    330             else if (str[pos + 1] == 'b') { output += '\b'; pos += 2; continue; }
    331             else if (str[pos + 1] == 'r') { output += '\r'; pos += 2; continue; }
    332             else if (str[pos + 1] == 'f') { output += '\f'; pos += 2; continue; }
    333             else if (str[pos + 1] == 'a') { output += '\a'; pos += 2; continue; }
    334             else if (str[pos + 1] == '"') { output += '"'; pos += 2; continue; }
    335             else if (str[pos + 1] == '0') { output += '\0'; pos += 2; continue; }
    336         }
    337         output += str[pos];
    338         pos++;
    339         if (pos == str.size() - 1)
    340             output += str[pos];
    341     }
    342 
    343     return output;
    344 }
    345 
    346 /**
    347     @brief Replaces each char between A and Z with its lowercase equivalent.
    348     @param str The string to convert
    349 */
    350 void lowercase(std::string* str)
    351 {
    352     for (size_t i = 0; i < str->size(); ++i)
    353     {
    354         (*str)[i] = (char)tolower((*str)[i]);
    355     }
    356 }
    357 
    358 /**
    359     @brief Returns a copy of the given string without uppercase chars.
    360     @param str The string
    361     @return The copy
    362 */
    363 std::string getLowercase(const std::string& str)
    364 {
    365     std::string output = std::string(str);
    366     lowercase(&output);
    367     return output;
    368 }
    369 
    370 /**
    371     @brief Replaces each char between a and z with its uppercase equivalent.
    372     @param str The string to convert
    373 */
    374 void uppercase(std::string* str)
    375 {
    376     for (size_t i = 0; i < str->size(); ++i)
    377     {
    378         (*str)[i] = (char)toupper((*str)[i]);
    379     }
    380 }
    381 
    382 /**
    383     @brief Returns a copy of the given string without lowercase chars.
    384     @param str The string
    385     @return The copy
    386 */
    387 std::string getUppercase(const std::string& str)
    388 {
    389     std::string output = std::string(str);
    390     uppercase(&output);
    391     return output;
    392 }
    393 
    394 /**
    395     @brief Compares two strings ignoring different casing.
    396     @param s1 First string
    397     @param s2 Second string
    398 */
    399 int nocaseCmp(const std::string& s1, const std::string& s2)
    400 {
    401     std::string::const_iterator it1=s1.begin();
    402     std::string::const_iterator it2=s2.begin();
    403 
    404     //stop when either string's end has been reached
    405     while ( (it1!=s1.end()) && (it2!=s2.end()) )
    406     {
    407         if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
    408             // return -1 to indicate smaller than, 1 otherwise
    409             return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
    410         //proceed to the next character in each string
    411         ++it1;
    412         ++it2;
    413     }
    414     size_t size1=s1.size(), size2=s2.size();// cache lengths
    415     //return -1,0 or 1 according to strings' lengths
    416     if (size1==size2)
    417         return 0;
    418     return (size1<size2) ? -1 : 1;
    419 }
    420 
    421 
    422 /**
    423     @brief Compares the first 'len' chars of two strings ignoring different casing.
    424     @param s1 First string
    425     @param s2 Second string
    426     @param len Maximal number of chars to compare
    427 */
    428 int nocaseCmp(const std::string& s1, const std::string& s2, size_t len)
    429 {
    430     if (len == 0)
    431         return 0;
    432     std::string::const_iterator it1=s1.begin();
    433     std::string::const_iterator it2=s2.begin();
    434 
    435     //stop when either string's end has been reached
    436     while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0)
    437     {
    438         if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
    439             // return -1 to indicate smaller than, 1 otherwise
    440             return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
    441         //proceed to the next character in each string
    442         ++it1;
    443         ++it2;
    444     }
    445     return 0;
    446 }
    447 
    448 /**
    449     @brief Returns true if the string contains a comment, introduced by #, %, ; or //.
    450     @param str The string
    451     @return True if the string contains a comment
    452 */
    453 bool hasComment(const std::string& str)
    454 {
    455     return (getCommentPosition(str) != std::string::npos);
    456 }
    457 
    458 /**
    459     @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise.
    460     @param str The string
    461     @return The comment
    462 */
    463 std::string getComment(const std::string& str)
    464 {
    465     return str.substr(getCommentPosition(str));
    466 }
    467 
    468 /**
    469     @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise.
    470     @param str The string
    471     @return The position
    472 */
    473 size_t getCommentPosition(const std::string& str)
    474 {
    475     return getNextCommentPosition(str, 0);
    476 }
    477 
    478 /**
    479     @brief Returns the position of the next comment-symbol, starting with start.
    480     @param str The string
    481     @param start The startposition
    482     @return The position
    483 */
    484 size_t getNextCommentPosition(const std::string& str, size_t start)
    485 {
    486     for (size_t i = start; i < str.size(); i++)
    487         if (isComment(str.substr(i)))
    488             return i;
    489 
    490     return std::string::npos;
    491 }
Note: See TracChangeset for help on using the changeset viewer.