tool/NumberListParser.cpp
changeset 2042 8b358effa78b
parent 2012 ee4782738e30
equal deleted inserted replaced
2041:f5b31f46c38f 2042:8b358effa78b
    48 {
    48 {
    49 }
    49 }
    50 
    50 
    51 /*****************************************************************************/
    51 /*****************************************************************************/
    52 
    52 
    53 NumberListParser::NumberList NumberListParser::parse(const char *data)
    53 NumberListParser::List NumberListParser::parse(const char *data)
    54 {
    54 {
    55     NumberList ret;
    55     List ret;
    56     unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U;
    56     unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U;
    57     typedef enum {
    57     typedef enum {
    58         SectionStart,
    58         SectionStart,
    59         FirstNumber,
    59         FirstNumber,
    60         Range,
    60         Range,
   106                 }
   106                 }
   107                 break;
   107                 break;
   108 
   108 
   109             case Range:
   109             case Range:
   110                 if (i >= size) {
   110                 if (i >= size) {
   111                     secondNum = maximum();
   111                     int max = maximum();
   112                     NumberList r = range(firstNum, secondNum);
   112                     // only increasing ranges if second number omitted
   113                     ret.splice(ret.end(), r);
   113                     if (max >= 0 && firstNum <= (unsigned int) max) {
       
   114                         List r = range(firstNum, max);
       
   115                         ret.splice(ret.end(), r);
       
   116                     }
   114                     state = Finished;
   117                     state = Finished;
   115                 } else if (isNumeric(data[i])) {
   118                 } else if (isNumeric(data[i])) {
   116                     secondNum = parseNumber(data, &i, size);
   119                     secondNum = parseNumber(data, &i, size);
   117                     state = SecondNumber;
   120                     state = SecondNumber;
   118                 } else if (data[i] == ',') {
   121                 } else if (data[i] == ',') {
   119                     i++;
   122                     int max = maximum();
   120                     secondNum = maximum();
   123                     i++;
   121                     NumberList r = range(firstNum, secondNum);
   124                     if (max >= 0) {
       
   125                         List r = range(firstNum, max);
       
   126                         ret.splice(ret.end(), r);
       
   127                     }
       
   128                     state = SectionStart;
       
   129                 } else {
       
   130                     stringstream err;
       
   131                     err << "Invalid character " << data[i]
       
   132                         << " at position " << i << "in state "
       
   133                         << state << "." << endl;
       
   134                     throw runtime_error(err.str());
       
   135                 }
       
   136                 break;
       
   137 
       
   138             case SecondNumber:
       
   139                 if (i >= size) {
       
   140                     List r = range(firstNum, secondNum);
       
   141                     ret.splice(ret.end(), r);
       
   142                     state = Finished;
       
   143                 } else if (data[i] == ',') {
       
   144                     i++;
       
   145                     List r = range(firstNum, secondNum);
   122                     ret.splice(ret.end(), r);
   146                     ret.splice(ret.end(), r);
   123                     state = SectionStart;
   147                     state = SectionStart;
   124                 } else {
   148                 } else {
   125                     stringstream err;
   149                     stringstream err;
   126                     err << "Invalid character " << data[i]
   150                     err << "Invalid character " << data[i]
   128                         << state << "." << endl;
   152                         << state << "." << endl;
   129                     throw runtime_error(err.str());
   153                     throw runtime_error(err.str());
   130                 }
   154                 }
   131                 break;
   155                 break;
   132 
   156 
   133             case SecondNumber:
       
   134                 if (i >= size) {
       
   135                     NumberList r = range(firstNum, secondNum);
       
   136                     ret.splice(ret.end(), r);
       
   137                     state = Finished;
       
   138                 } else if (data[i] == ',') {
       
   139                     i++;
       
   140                     NumberList r = range(firstNum, secondNum);
       
   141                     ret.splice(ret.end(), r);
       
   142                     state = SectionStart;
       
   143                 } else {
       
   144                     stringstream err;
       
   145                     err << "Invalid character " << data[i]
       
   146                         << " at position " << i << "in state "
       
   147                         << state << "." << endl;
       
   148                     throw runtime_error(err.str());
       
   149                 }
       
   150                 break;
       
   151 
       
   152             default:
   157             default:
   153                 {
   158                 {
   154                     stringstream err;
   159                     stringstream err;
   155                     err << "Invalid state " << state << ".";
   160                     err << "Invalid state " << state << ".";
   156                     throw runtime_error(err.str());
   161                     throw runtime_error(err.str());
   161     return ret;
   166     return ret;
   162 }
   167 }
   163 
   168 
   164 /*****************************************************************************/
   169 /*****************************************************************************/
   165 
   170 
   166 unsigned int NumberListParser::maximum()
   171 int NumberListParser::maximum()
   167 {
   172 {
   168     if (!hasMax) {
   173     if (!hasMax) {
   169         max = getMax();
   174         max = getMax();
   170     }
   175     }
   171 
   176 
   205     return ret;
   210     return ret;
   206 }
   211 }
   207 
   212 
   208 /****************************************************************************/
   213 /****************************************************************************/
   209 
   214 
   210 NumberListParser::NumberList NumberListParser::range(
   215 NumberListParser::List NumberListParser::range(
   211         unsigned int i,
   216         unsigned int i,
   212         unsigned int j
   217         unsigned int j
   213         )
   218         )
   214 {
   219 {
   215     NumberList ret;
   220     List ret;
   216 
   221 
   217     if (i <= j) {
   222     if (i <= j) {
   218         for (; i <= j; i++) {
   223         for (; i <= j; i++) {
   219             ret.push_back(i);
   224             ret.push_back(i);
   220         }
   225         }