Exemplo n.º 1
0
char CParser::ExtractEntry(CGeneralInfo& tempinfo)
{
    char c;
    std::string fieldname = extractQuotedPrefix(mfilestream);
    c = getnextnonwhite(mfilestream);
    if(c!=':') throw parseerror::missing_colon;
    if("backgroundfile" == fieldname)
    {
        tempinfo.backgroundfile = filenames::imagepath+extractQuotedPrefix(mfilestream);
    }
    else if("castlefile" == fieldname)
    {
        tempinfo.castlefile = filenames::imagepath+extractQuotedPrefix(mfilestream);
    }
    else if("castlewidth" == fieldname)
    {
        tempinfo.castlewidth = atoi(extractNumber(mfilestream).c_str());
    }
    else if("castleheight" == fieldname)
    {
        tempinfo.castleheight = atoi(extractNumber(mfilestream).c_str());
    }
    else if("startingmoney" == fieldname)
    {
        tempinfo.startingmoney = atoi(extractNumber(mfilestream).c_str());
    }
    else throw parseerror::wrong_fieldname;

    c = getnextnonwhite(mfilestream);
    return c;
}
Exemplo n.º 2
0
Arquivo: fun.c Projeto: code4tots/fun
void testExtractNumber() {
  Token token;
  char text[] = "123 54", *p = text;

  token.type = TOKEN_TYPE_UNKNOWN;
  skipSpaces(&p);
  assert(!extractString(&p, &token));
  assert(extractNumber(&p, &token));
  assert(token.type == TOKEN_TYPE_NUM);
  assert(token.value.number == 123);

  token.type = TOKEN_TYPE_UNKNOWN;
  skipSpaces(&p);
  assert(extractNumber(&p, &token));
  assert(token.type == TOKEN_TYPE_NUM);
  assert(token.value.number == 54);
}
Exemplo n.º 3
0
static LPSTR extractNumber(LPSTR lpPtr, LONG lValue)
{
    if (lValue>=1000L) {
        lpPtr=extractNumber(lpPtr, lValue/1000L);
        lstrcpy(lpPtr, setup.szThousandsSep);
        lpPtr+=wsprintf(lpPtr, "%s%03ld", (LPSTR)setup.szThousandsSep, lValue%1000L);
    } else
        lpPtr+=wsprintf(lpPtr, "%ld", lValue);

    return(lpPtr);
}
Exemplo n.º 4
0
char CParser::ExtractEntry(CEnemyInfo& tempinfo)
{
    char c;
    std::string fieldname = extractQuotedPrefix(mfilestream);
    c = getnextnonwhite(mfilestream);
    if(c!=':') throw parseerror::missing_colon;
    if("filename" == fieldname)
    {
        tempinfo.filename = filenames::imagepath+extractQuotedPrefix(mfilestream);
    }
    else if("width" == fieldname)
    {
        tempinfo.width = atoi(extractNumber(mfilestream).c_str());
    }
    else if("height" == fieldname)
    {
        tempinfo.height = atoi(extractNumber(mfilestream).c_str());
    }
    else if("lives" == fieldname)
    {
        tempinfo.lives = atoi(extractNumber(mfilestream).c_str());
    }
    else if("points" == fieldname)
    {
        tempinfo.points = atoi(extractNumber(mfilestream).c_str());
    }
    else if("movementspeed" == fieldname)
    {
        tempinfo.movementspeed = atof(extractNumber(mfilestream).c_str());
    }
    else if("resistance" == fieldname)
    {
        tempinfo.resistance = parseShotTypeList(mfilestream);
    }
    else throw parseerror::wrong_fieldname;

    c = getnextnonwhite(mfilestream);
    return c;
}
Exemplo n.º 5
0
char CParser::ExtractWave(CWaveInfo &tempinfo)
{
    std::vector<std::pair<unsigned,double>> tempwave{};
    char c = getnextnonwhite(mfilestream);
    while(c!='}')
    {
        c = getnextnonwhite(mfilestream);
        if(c!='(') throw parseerror::missing_opening_bracket;
        unsigned a = atoi(extractNumber(mfilestream).c_str());
        c = getnextnonwhite(mfilestream);
        if(c!=',') throw parseerror::missing_colon;
        double b = atof(extractNumber(mfilestream).c_str());
        c = getnextnonwhite(mfilestream);
        if(c!=')') throw parseerror::missing_closing_bracket;
        std::pair<unsigned,double> nextpair{a,b};
        tempwave.push_back(nextpair);
        c=getnextnonwhite(mfilestream);
        if(c!=','&&c!='}') throw parseerror::missing_colon;
    }
    tempinfo.numberedwaves.push_back(tempwave);
    c = getnextnonwhite(mfilestream);
    return c;
}
Exemplo n.º 6
0
LPCSTR formatLong(LPSTR lpBuff, LPCSTR lpcBefore, LONG lValue, LPCSTR lpcAfter)
{
    LPSTR lpPtr=lpBuff;

    while (*lpcBefore)
        *lpPtr++ = *lpcBefore++;

    if (lValue<0)
        *lpPtr++ ='-';

    lpPtr=extractNumber(lpPtr, lValue);
    lstrcpy(lpPtr, lpcAfter);
    return(lpBuff);
}
Exemplo n.º 7
0
Arquivo: fun.c Projeto: code4tots/fun
int loadTokens(Machine *machine, char *string) {
  skipSpaces(&string);
  while (*string != '\0') {
    Token *token;

    if (machine->tokensSize >= machine->tokensCapacity) {
      machine->tokensCapacity = 2*machine->tokensCapacity+10;
      machine->tokens =
          (Token*) realloc(machine->tokens, sizeof(Token)*machine->tokensCapacity);
    }

    token = machine->tokens+machine->tokensSize++;

    if (!(extractString(&string, token) ||
          extractNumber(&string, token) ||
          extractName(&string, token))) {
      /* Error */
      return 0;
    }

    skipSpaces(&string);
  }
  return 1;
}
Exemplo n.º 8
0
char CParser::ExtractEntry(CTowerInfo& tempinfo)
{
    char c;
    std::string fieldname = extractQuotedPrefix(mfilestream);
    c = getnextnonwhite(mfilestream);
    if(c!=':') throw parseerror::missing_colon;
    if("towerfilename" == fieldname)
    {
        tempinfo.towerfilename = filenames::imagepath+extractQuotedPrefix(mfilestream);
    }
    else if("shotfilename" == fieldname)
    {
        tempinfo.shotfilename = filenames::imagepath+extractQuotedPrefix(mfilestream);
    }
    else if("errorfilename" == fieldname)
    {
        tempinfo.errorfilename = filenames::imagepath+extractQuotedPrefix(mfilestream);
    }
    else if("width" == fieldname)
    {
        tempinfo.width = atoi(extractNumber(mfilestream).c_str());
    }
    else if("height" == fieldname)
    {
        tempinfo.height = atoi(extractNumber(mfilestream).c_str());
    }
    else if("cost" == fieldname)
    {
        tempinfo.cost = atoi(extractNumber(mfilestream).c_str());
    }
    else if("costmultiplier" == fieldname)
    {
        tempinfo.costmultiplier = atof(extractNumber(mfilestream).c_str());
    }
    else if("force" == fieldname)
    {
        tempinfo.force = atoi(extractNumber(mfilestream).c_str());
    }
    else if("shottype" == fieldname)
    {
        std::string shottypename = extractQuotedPrefix(mfilestream);
        if(stringtotype.find(shottypename)==stringtotype.end())
        {
            throw parseerror::invalid_shottype;
        }
        tempinfo.shottype = shottypename;
    }
    else if("reloadtime" == fieldname)
    {
        tempinfo.reloadtime = atof(extractNumber(mfilestream).c_str());
    }
    else if("slow" == fieldname)
    {
        tempinfo.slow = atof(extractNumber(mfilestream).c_str());
    }
    else if("slowduration" == fieldname)
    {
        tempinfo.slowduration = atof(extractNumber(mfilestream).c_str());
    }
    else if("range"==fieldname)
    {
        tempinfo.range = atof(extractNumber(mfilestream).c_str());
    }
    else if("hasupgrade" == fieldname)
    {
        tempinfo.hasupgrade = ("true" == extractQuotedPrefix(mfilestream));
    }
    else throw parseerror::wrong_fieldname;

    c = getnextnonwhite(mfilestream);
    return c;
}
Exemplo n.º 9
0
//This function construct an INSERT SQL and execute it againts the database.
QList<TfieldDef > createSQL(QSqlDatabase db,QVariantMap jsonData,QString table,QList< TfieldDef> fields,QList< TfieldDef> parentkeys,bool mTable = false, QVariantMap jsonData2 = emptyMap)
{
    QString sqlHeader;
    QString sqlValues;
    QString sql;
    QVariant variantValue;
    int pos;

    QList<TfieldDef > resKeys;

    QString fieldValue;

    int tblIndex;

    //log("Table:" + table);

    tblIndex = getLastIndex(table);

    sqlHeader = "INSERT INTO " + table + "(";
    sqlValues = " VALUES (";
    for (pos = 0; pos <= parentkeys.count()-1;pos++)
    {
        sqlHeader = sqlHeader + parentkeys[pos].name + ",";
        sqlValues = sqlValues + "'" + parentkeys[pos].value + "',";
    }
    for (pos = 0; pos <= fields.count()-1;pos++)
    {
        // If a new key is found in the list of fields
        // then we added to the result of keys that will be passes to any possible child table
        if (fields[pos].key == true)
        {
            TfieldDef key;
            key.key = true;
            key.name = fields[pos].name;
            key.xmlCode = fields[pos].xmlCode;


            key.value = extractNumber(jsonData[fields[pos].xmlCode].toString());
            key.value = key.value.simplified();

            // If its empty. The try to find it in jsonData2
            // This happens when the cover information is stored in a repeat of one
            // so part of the information for the main table must be searched in jsonData
            // and part in jsonData2
            if (key.value.isEmpty())
            {
                key.value = jsonData2[fields[pos].xmlCode].toString();
                key.value = key.value.simplified();
            }

            //If the key is empty (Normal as in the JSON such key does not exist) set the key value to tblIndex
            if (key.value.isEmpty())
            {                                
                if (!mTable)
                {
                    key.value = QString::number(tblIndex);
                    sqlHeader = sqlHeader + key.name + ",";
                    sqlValues = sqlValues + "'" + QString::number(tblIndex) + "',";
                }
                else
                {
                    key.value = "";
                    sqlHeader = sqlHeader + key.name + ",";
                    sqlValues = sqlValues + "'',";
                }
            }
            else
            {                
                sqlHeader = sqlHeader + key.name + ",";
                sqlValues = sqlValues + "'" + fixString(key.value) + "',";
            }
            //Append the key to the list of returned keys
            key.value = key.value;
            resKeys.append(key);

        }
        else
        {
            sqlHeader = sqlHeader + fields[pos].name + ",";
            if (mainTable == table)
            {
                if (fields[pos].name == "surveyid")
                  sqlValues = sqlValues + "'" + fileID + "',";
                else
                {
                    if (fields[pos].name == "originid")
                        sqlValues = sqlValues + "'FORMHUB-JSON',";
                    else
                    {
                        fieldValue = fixString(jsonData[fields[pos].xmlCode].toString());
                        if (fieldValue.isEmpty())
                        {
                            // This happens when the cover information is stored in a repeat of one
                            // so part of the information for the main table must be searched in jsonData
                            // and part in jsonData2                            
                            fieldValue = fixString(jsonData2[fields[pos].xmlCode].toString());
                        }

                        sqlValues = sqlValues + "'" + fieldValue + "',";
                    }
                }
            }
            else
            {                                
                variantValue =  jsonData[fields[pos].xmlCode];                
                fieldValue = QString::fromUtf8(variantValue.toByteArray());                
                if (fieldValue.isEmpty())
                {
                    // This happens when the cover information is stored in a repeat of one
                    // so part of the information for the main table must be searched in jsonData
                    // and part in jsonData2
                    variantValue = jsonData2[fields[pos].xmlCode];                    
                    fieldValue = QString::fromUtf8(variantValue.toByteArray());
                }

                sqlValues = sqlValues + "'" + fixString(fieldValue) + "',";
            }
        }
    }

    //Removing final , and appending )
    sqlHeader = sqlHeader.left(sqlHeader.length()-1) + ")";
    sqlValues = sqlValues.left(sqlValues.length()-1) + ")";
    //Create the final sql
    sql = sqlHeader + " " + sqlValues;
    //Change all empty valued to NULL. This minimize foreign key errors in skips
    sql = sql.replace("''","NULL");

    //Execute the SQL to the database

    if (outSQL)
    {
        sqlStream << sql + ";\n";
    }

    if (!mTable)
    {
        QSqlQuery query(db);
        if (!query.exec(sql))
        {
            SQLError = true; //An error occurred. This will trigger a rollback
            logError(db,query.lastError().databaseText(),table,tblIndex,jsonData,fields,sql); //Write the error to the log
        }
    }
    else
    {
        if (!ignorePKError)
        {
            QSqlQuery query(db);
            if (!query.exec(sql))
            {
                SQLError = true; //An error occurred. This will trigger a rollback
                logError(db,query.lastError().databaseText(),table,tblIndex,jsonData,fields,sql); //Write the error to the log
            }
        }
    }



    return resKeys;
}
Exemplo n.º 10
0
int main(int argc, char** argv) {
	
	std::string user_response;			// used to hold user responses
	
	Board gameOfLife;				// the game board

	// Intro
	showIntroArt();
	enterToContinue();

	// Calibration
	std::cout << std::endl;
	std::cout << "IMPORTANT: Please calibrate your window." << std::endl;
	std::cout << "I will show you a " << BOARD_LIMIT_X << " by " << BOARD_LIMIT_Y + 2
			  << " box. If you do not see a box full of '+' signs," << std::endl;
	std::cout << "please adjust your window and type 'again'." << std::endl;
	std::cout << "Type 'done' when you are finished." << std::endl;

	std::cout << std::endl;
	enterToContinue();

	calibrateWindow();

	// menu
	// loop until user quits
	while (user_response != "quit") {
		showMenu();
		std::cout << "Please choose an option: ";
		std::getline(std::cin, user_response);

		// std::cout << "user_response = " << user_response << std::endl;
		if (user_response == "calibrate") {
			calibrateWindow();
		} else if (user_response == "art") {
			showIntroArt();
			enterToContinue();
		} else if (user_response == "rules") {
			showRules();
			enterToContinue();
		} else if (user_response == "start") {
			// the game loop
			while (user_response != "quit") {
				showGameMenu();	
				
				// get user response
				std::cout << "Please choose an option: ";
				std::getline(std::cin, user_response);
				while (!(checkGameMenuValidity(user_response))) {
					std::cout << "Sorry, that isn't a valid option." << std::endl;
					std::cout << "Please choose an option: ";
					std::getline(std::cin, user_response);
				}

				// execute menu option
				if (user_response.find("show board") != std::string::npos) {
					gameOfLife.showBoard();

				} else if (user_response.find("add cell") != std::string::npos) {
					// extract number from response
					int amt = extractNumber(user_response);

					// check for no number
					if (amt == 0) {
						amt = 1;
					}

					// prompt user for cells
					for (int i=0; i<amt; i++) {
						// storage for user vars
						int x, y;

						std::cout << "NEW CELL # " << i+1 << std::endl;
						
						// prompt user
						std::cout << "Enter a x value: ";
						while (!(std::cin >> x)) {
							std::cin.clear();
							std::cin.ignore(256, '\n');
							std::cout << "That's not a valid value." << std::endl;
							std::cout << "Enter a x value: ";
						}

						std::cout << "Enter a y value: ";
						while (!(std::cin >> y)) {
							std::cin.clear();
							std::cin.ignore(256, '\n');
							std::cout << "That's not a valid value." << std::endl;
							std::cout << "Enter a y value: ";
						}

						// check if cell at coord
						if (gameOfLife.isAnyCellAtCoord(x, y)) {
							std::cout << "That coordinate is not available!" << std::endl;
							i--;
						} else {
							gameOfLife.addCell(Cell(x, y));
							std::cout << "New cell added at (" << x
									  << ", " << y << ")." << std::endl;
						}
						
						// clear cin
						std::cin.clear();
						std::cin.ignore(256, '\n');
						std::cout << std::endl;
					}

				} else if (user_response.find("add randoms") != std::string::npos) {
					int amt = extractNumber(user_response);

					if (amt == 0) {
						// no number, default value is 60
						for (int i=0; i<60; i++) {
							Cell c1;
							if (gameOfLife.isAnyCellAtCoord(c1.getX(), c1.getY())) {
								i--;
							} else {
								gameOfLife.addCell(c1);
							}
						}

						gameOfLife.showBoard();

						std::cout << "60 random cells added." << std::endl;
						enterToContinue();

					} else {
						// go by number
						for (int i=0; i<amt; i++) {
							Cell c1;
							if (gameOfLife.isAnyCellAtCoord(c1.getX(), c1.getY())) {
								i--;
							} else {
								gameOfLife.addCell(c1);
							}
						}
						std::cout << amt << " random cells added." << std::endl;
					}

				} else if (user_response.find("advance") != std::string::npos) {
					// extract number from response
					int amt = extractNumber(user_response);
					
					// iterate the board
					if (amt != 0) {
						gameOfLife.iterateGeneration(amt);
					} else {
						gameOfLife.iterateGeneration();
					}

					// pause on board view
					enterToContinue();

				} else if (user_response == "pattern") {
					showPatternMenu();

					std::cout << "Select a pattern: ";
					std::getline(std::cin, user_response);

					while ((user_response != "pinwheel") && (user_response != "big wheel") 
						&& (user_response != "glider") && (user_response != "glider gun") 
						&& (user_response != "o")) {
						std::cout << "That's not a valid pattern." << std::endl;
						std::cout << "Select a pattern: ";
						std::getline(std::cin, user_response);
					}

					int x, y;

					std::cout << "Where should the top left of the pattern be?" << std::endl;

					std::cout << "Enter a x value: ";
					while (!(std::cin >> x)) {
						std::cin.clear();
						std::cin.ignore(256, '\n');
						std::cout << "That's not a valid value." << std::endl;
						std::cout << "Enter a x value: ";
					}

					std::cout << "Enter a y value: ";
					while (!(std::cin >> y)) {
						std::cin.clear();
						std::cin.ignore(256, '\n');
						std::cout << "That's not a valid value." << std::endl;
						std::cout << "Enter a y value: ";
					}

					if (user_response == "pinwheel") {
						addPinwheel(x, y, gameOfLife);
					} else if (user_response == "big wheel") {
						addBigWheel(x, y, gameOfLife);
					} else if (user_response == "glider") {
						addGlider(x, y, gameOfLife);
					} else if (user_response == "glider gun") {
						addGliderGun(x, y, gameOfLife);
					} else if (user_response == "o") {
						addO(x, y, gameOfLife);
					}

					// clear cin
					std::cin.clear();
					std::cin.ignore(256, '\n');
					std::cout << std::endl;

					// display board
					gameOfLife.showBoard();

					// pause board
					enterToContinue();

				} else if (user_response.find("finish") != std::string::npos) {
Exemplo n.º 11
0
TObject* Scanner::get(){
	//first extract the first character from the sourcereader
	char c = getChar();

	if(c==END_OF_BUFFER)
	{
		//FIXME please update this, better handling
		return new TObject(new string(1, char(0)), NULL_TOKEN, line, char_line);
	}
	//next determine the type
	switch(TOKEN_TYPE type = token_type(c)){
	case WHITESPACE:
	{
		//skip the whitespace and return something
		skipWS(c);
		//return the next token
		return get();
	}

	case COMMENT:
	{
		skipCMT(c);

		return get();
	}

	case NUMERIC:
	case DOT:
	{
		//extracts all the numbers
		return extractNumber(c);
	}

	case UNDERSCORE:
	case IDENTIFIER:
	{
		TObject* tok = extractIdentifier(c);

		TOKEN_TYPE key = is_keyword(*tok->str);
		//then check if that is a keyword
		if(key!=UNKNOWN){
			//then change the format
			tok->type = key;
			tok->special = true;
		}
		return tok;
	}

	case GREATER_THAN:
	case LESS_THAN:
	case EQUAL_SIGN:
	{
		//check if we have an = comming
		return extractComparator(c);
	}

	case OPERATOR:
	{
		//get the next
		char ch = getChar();

		if(ch=='='){

			switch(c){
			case '-':
				return new TObject(0, MINUS_EQUALS, line, char_line);
			case '+':
				return new TObject(0, PLUS_EQUALS, line, char_line);
			case '*':
				return new TObject(0, TIMES_EQUALS, line, char_line);
			case '/':
				return new TObject(0, DIVIDE_EQUALS, line, char_line);
			case '%':
				return new TObject(0, MODULO_EQUALS, line, char_line);
			case '^':
				return new TObject(0, EXPO_EQUALS, line, char_line);
			default:
				break;
			}
		}else{
			putback();
		}
		return new TObject(new string(1, c), type, line, char_line);
	}

	case UNKNOWN:
	{
		string error= ERROR_MSG[6]+"\"";
		error.append(getLine().append("\""));

		throw new YottaError(SYNTAX_ERROR, error, line, char_line);
	}

	default:
	{
		return new TObject(new string(1, c), type, line, char_line);
	}
	}
}
Exemplo n.º 12
0
Pgn* getMatchingPgn(int pgnId, uint8_t *dataStart, int length)
{
  Pgn *pgn = searchForPgn(pgnId);
  int prn;
  int i;

  if (!pgn)
  {
    pgn = searchForUnknownPgn(pgnId);
  }

  prn = pgn->pgn;

  if (pgn == pgnListEnd() - 1 || pgn[1].pgn != prn)
  {
    // Don't bother complex search if there is only one PGN with this PRN.
    return pgn;
  }

  for (; pgn->pgn == prn; pgn++) // we never get here for the last pgn, so no need to check for end of list
  {
    int startBit = 0;
    uint8_t *data = dataStart;

    bool matchedFixedField = true;
    bool hasFixedField = false;

    /* There is a next index that we can use as well. We do so if the 'fixed' fields don't match */

    if (!pgn->fieldCount)
    {
      logError("Internal error: %p PGN %d offset %u '%s' has no fields\n", pgn, prn, (unsigned) (pgn - pgnList), pgn->description);
      for (i = 0; pgn->fieldList[i].name; i++)
      {
        logInfo("Field %d: %s\n", i, pgn->fieldList[i].name);
      }
      // exit(2);
      pgn->fieldCount = i;
    }

    // Iterate over fields
    for (i = 0, startBit = 0, data = dataStart; i < pgn->fieldCount; i++)
    {
      const Field *field = &pgn->fieldList[i];
      int bits = field->size;

      if (field->units && field->units[0] == '=')
      {
        int64_t value, desiredValue;
        int64_t maxValue;

        hasFixedField = true;
        extractNumber(field, data, startBit, field->size, &value, &maxValue);
        desiredValue = strtol(field->units + 1, 0, 10);
        if (value != desiredValue)
        {
          matchedFixedField = false;
          break;
        }
      }
      startBit += bits;
      data += startBit / 8;
      startBit %= 8;
    }
    if (!hasFixedField)
    {
      logDebug("Cant determine prn choice, return prn=%d variation '%s'\n", prn, pgn->description);
      return pgn;
    }
    if (matchedFixedField)
    {
      return pgn;
    }
  }
  return 0;
}
Exemplo n.º 13
0
/*! Compares a string using a natural comparison algorithm. In other words,
    it sorts the numbers in value order and the remaining characters in 
    ASCII order.

    The code is based on the LGPL C++ implementation found at 
    http://www.davekoelle.com/alphanum.html

    See this header file for license details.
*/
int Movida::naturalCompare(const QString &string_a, const QString &string_b, Qt::CaseSensitivity cs)
{
    if (string_a.unicode() == string_b.unicode())
        return 0;
    if (string_a.isEmpty())
        return -1;
    if (string_b.isEmpty())
        return +1;

    const bool _cs = cs == Qt::CaseSensitive;

    enum Mode { String, Number } mode = String;

    const QChar* a_begin = string_a.unicode();
    const QChar* a_end = a_begin + string_a.length();
    const QChar* a = a_begin;
    
    const QChar* b_begin = string_b.unicode();
    const QChar* b_end = b_begin + string_b.length();
    const QChar* b = b_begin;

    bool mode_change = false;
    int last_num_compare = 0;
    while (a != a_end && b != b_end) {
        last_num_compare = 0;
        switch (mode) {
        case String:
        {
            while (a != a_end && b != b_end)
	        {
                // Check if this are digit characters
                const bool a_digit = a->isDigit();
                const bool b_digit = b->isDigit();

                // If both characters are digits, we continue in Number mode
                if (a_digit && b_digit) {
                    mode = Number;
                    mode_change = true;
                    break;
                }

                // If only the left character is a digit, we have a result
                if (a_digit)
                    return -1;

                // If only the right character is a digit, we have a result
                if (b_digit)
                    return +1;

                // Compute the difference of both characters
                const quint16 u_a = a->unicode();
                const quint16 u_b = b->unicode();
                const quint16 diff = _cs ? (u_a - u_b) : (QChar::toCaseFolded(u_a) - QChar::toCaseFolded(u_b));
                // If they differ we have a result
                if (diff != 0)
                    return diff;

                // Otherwise process the next characters
                ++a;
                ++b;
            }
        }
        break;

        case Number:
        {
            // Get the left number
            CharBuff a_buff;
            qMemSet(a_buff.data(), 0, a_buff.capacity());
            a = extractNumber(a, a_end, a_buff);
            quint64 a_num = qstrtoll(a_buff.constData(), 0, 10, 0);

            // Get the right number
            CharBuff b_buff;
            qMemSet(b_buff.data(), 0, b_buff.capacity());
            b = extractNumber(b, b_end, b_buff);
            quint64 b_num = qstrtoll(b_buff.constData(), 0, 10, 0);

            // If the difference is not equal to zero, we have a comparison result
            const long diff = a_num - b_num;
            if (diff != 0)
                return diff;

            // If the strings differ only by the number of padding zeros
            // in the current number, we should take it into account and
            // simulate a lexical comparison by comparing the number of 
            // digits.
            last_num_compare = a_buff.size() - b_buff.size();

            // Otherwise we process the next substring in String mode
            mode = String;
        }
        break;
        }

        if (!mode_change && a != a_end && b != b_end) {
            ++a;
            ++b;
        } else mode_change = false;
    }

    if (a == a_end && b == b_end)
        return last_num_compare;
    if (a == a_end)
        return -1;
    if (b == b_end)
        return +1;
    return last_num_compare;
}