QVariant Cell::computeFormula(const QString &formula, SpreadSheet *widget) const
{
    QVariant result = QVariant::Invalid,
             firstOperand = QVariant::Invalid,
             secondOperand = QVariant::Invalid;
    QString aux = formula;
    int firstOp = firstOperatorPosition(aux);
    if (firstOp == -1)
        result = parseMember(aux, widget);
    while (firstOp != -1)
    {
        if (result == QVariant::Invalid)
            firstOperand = parseMember(aux.left(firstOp), widget);
        else
            firstOperand = result;
        QChar firstOperator = aux[firstOp];
        aux = aux.mid(firstOp+1);
        firstOp = firstOperatorPosition(aux);
        if (firstOp == -1)
            secondOperand = parseMember(aux, widget);
        else
            secondOperand = parseMember(aux.left(firstOp), widget);

        switch (firstOperator.toAscii())
        {
            case '+':
                result = firstOperand.toDouble() + secondOperand.toDouble();
                break;
            case '-':
                result = firstOperand.toDouble() - secondOperand.toDouble();
                break;
            case '*':
                result = firstOperand.toDouble() * secondOperand.toDouble();
                break;
            case '/':
                result = firstOperand.toDouble() / secondOperand.toDouble();
                break;
        }
    }
    return result;
}
static void
parseStruct(xmlrpc_env *    const envP,
            unsigned int    const maxRecursion,
            xml_element *   const elemP,
            xmlrpc_value ** const structPP) {
/*----------------------------------------------------------------------------
   Parse the <struct> element 'elemP'.
-----------------------------------------------------------------------------*/
    xmlrpc_value * structP;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT(elemP != NULL);

    structP = xmlrpc_struct_new(envP);
    if (!envP->fault_occurred) {
        /* Iterate over our children, extracting key/value pairs. */

        xml_element ** const members = xml_element_children(elemP);
        unsigned int const size = xml_element_children_size(elemP);

        unsigned int i;

        for (i = 0; i < size && !envP->fault_occurred; ++i) {
            const char * const elemName = xml_element_name(members[i]);

            if (!xmlrpc_streq(elemName, "member"))
                setParseFault(envP, "<%s> element found where only <member> "
                              "makes sense", elemName);
            else {
                xmlrpc_value * keyP;
                xmlrpc_value * valueP;

                parseMember(envP, members[i], maxRecursion, &keyP, &valueP);

                if (!envP->fault_occurred) {
                    xmlrpc_struct_set_value_v(envP, structP, keyP, valueP);

                    xmlrpc_DECREF(keyP);
                    xmlrpc_DECREF(valueP);
                }
            }
        }
        if (envP->fault_occurred)
            xmlrpc_DECREF(structP);
        else
            *structPP = structP;
    }
}
QVariant Cell::parseMember(const QString &formula, SpreadSheet *widget) const
{
    int fOp = firstOperatorPosition(formula);
    if (fOp == -1)
        fOp = formula.length();
    QChar first = formula.at(0);
    
    QRegExp importedData("([\\w\\s]+:[A-Z][1-9][0-9]*)");
    QRegExp cellId("([A-Z][1-9][0-9]*)");
    
    //paranteza
    if (first=='(')
    {
        int end = 0;
        int open_p_count = 0;
        int closed_p_count = 0;
        for (int c=0; c<formula.length(); c++)
        {
            if (formula.at(c) == '(')
                open_p_count++;
            else if (formula.at(c) == ')')
                closed_p_count++;
            if (open_p_count == closed_p_count)
            {
                end = c;
                break;
            }
        }
        return computeFormula(formula.mid(1,end-1), widget);
    }
    //numar 0 sau 0.0
    else if (first.isDigit())
    {
        QString s = formula.left(fOp);
        if (s.count('.') <= 1)
        {
            bool ok;
            double x = s.toDouble(&ok);
            if (ok)
                return x;
        }
        emit invalidFormula(QString("Invalid number or number format in %1").arg(s));
        return "#####";
    }
    //tabela:identificator
    else if (formula.indexOf(importedData) == 0)
    {
        int idx = 0;
        QHash<QString,QString> matches = QHash<QString,QString>();
        while ((idx = formula.indexOf(importedData, idx)) != -1)
        {
            QString match = formula.mid(idx, importedData.matchedLength());
            int delim = match.indexOf(':');
            QString table = match.left(delim);
            QString id = match.mid(delim+1);
            matches.insertMulti(table, id);
            idx += importedData.matchedLength();
        }
        QString result = widget->getLinkData(formula, matches);
        if (isValidFormula(result))
            return display(result);
        else
            return result;
    }
    //celula A2
    else if (cellId.exactMatch(formula))
    {
        QVariant cellVal = getCellValue(formula,widget);
        if (cellVal == "#####")
            emit invalidFormula(QString("Invalid cell data in %1").arg(formula));
        return cellVal;
    }
    //functie nume_functie(A1;A2;A3)
    else if (first.isLower())
    {
        QStringList simple_function_names;
        QStringList cond_function_names;
        QStringList parameters;
        simple_function_names << "sum" << "avg" << "count";
        cond_function_names << "if" << "countif";
        QString s = formula.left(fOp);

        QString params = s.mid(s.lastIndexOf('(')+1,
                               s.indexOf(')')-s.lastIndexOf('(')-1);
        if (s.count('(') == s.count(')'))
            parameters = params.split(';');
        else
        {
            emit invalidFormula(QString("Invalid paranthesis number ").append(s));
            return "#####";
        }
        s = formula.left(formula.indexOf('('));
        if (simple_function_names.contains(s))
        {
            QVariantList values;
            QListIterator<QString> it(parameters);
            while (it.hasNext())
            {
                QString str = it.next();
                QVariant val = parseMember(str, widget);
                if (val != "#####")
                    values.append(val);
            }

            if (s == "sum")
            {
                double tmp = 0;
                bool ok = true;
                QListIterator<QVariant> valIt(values);
                while (valIt.hasNext())
                {
                    QVariant aux = valIt.next();
                    tmp += aux.toDouble(&ok);
                    if (!ok)
                    {
                        emit invalidFormula(QString("Not a number: ").append(aux.toString()));
                        return "#####";
                    }
                }
                return tmp;
            }
            else if (s == "avg")
            {
                double tmp = 0;
                bool ok = true;
                QListIterator<QVariant> valIt(values);
                while (valIt.hasNext())
                {
                    QVariant aux = valIt.next();
                    tmp += aux.toDouble(&ok);
                    if (!ok)
                    {
                        emit invalidFormula(QString("Not a number: ").append(aux.toString()));
                        return "#####";
                    }
                }
                tmp /= parameters.length();
                return tmp;
            }
            else if (s == "count")
            {
                return values.length();
            }
        }
        else if (cond_function_names.contains(s))
        {
            int param_no = parameters.length();
            if (param_no < 2)
            {
                emit invalidFormula(QString("Invalid parameter number: %1").arg(param_no));
                return "#####";
            }
            
            if (s == "if")
            {
                //if(A1<5;"Picat";n)
                //if(A1<5;4)
                QRegExp pattern("^(([\\w\\s]+:)?[A-Z][1-9][0-9]*"
                                "(<|<=|>|>=|<>|=)"
                                "((([\\w\\s]+:)?[A-Z][1-9][0-9]*)|(\\d+(\\.\\d+)?)))$");
                QString condition = parameters.at(0);
                if (pattern.exactMatch(condition) && param_no <= 3)
                {
                    int length = 1;
                    int opPos = condition.indexOf(QRegExp("(<|>|=)"));
                    if (condition.indexOf(QRegExp("(<=|>=|<>)")) > -1)
                        length = 2;
                    QString op = condition.mid(opPos,length);
                    bool ok1, ok2;
                    double firstOperand = parseMember(condition.left(opPos), widget).toDouble(&ok1);
                    double secondOperand = parseMember(condition.mid(opPos+length), widget).toDouble(&ok2);
                    if (!ok1 || !ok2)
                    {
                        emit invalidFormula(QString("Invalid condition parameters: %1").arg(condition));
                        return "#####";
                    }
                    if (param_no == 2)
                        return compareMembers(param_no, op,
                                              firstOperand, secondOperand,
                                              parameters.at(1), "#####");
                    else if (param_no == 3)
                        return compareMembers(param_no, op,
                                              firstOperand, secondOperand,
                                              parameters.at(1), parameters.at(2));
                }
                else
                {
                    emit invalidFormula(QString("Invalid formula syntax: ").append(condition));
                    return "#####";
                }
            }
            else if (s == "countif")
            {
                //countif(A1;A2...An;>5)
                if (param_no > 2)
                {
                    int count = 0;
                    int length = 1;
                    QString condition = parameters.last();
                    int opPos = condition.indexOf(QRegExp("(<|>|=)"));
                    if (condition.indexOf(QRegExp("(<=|>=|<>)")) > -1)
                        length = 2;
                    if (opPos == -1)
                    {
                        emit invalidFormula(QString("Invalid condition syntax: ").append(condition));
                        return "#####";
                    } 
                    QString op = condition.mid(opPos,length);
                    bool ok;
                    double firstOperand;
                    double secondOperand = parseMember(condition.mid(opPos+length), widget).toDouble(&ok);
                    if (!ok)
                    {
                        emit invalidFormula(QString("Invalid second operand: %1").
                                            arg(condition.mid(opPos+length)));
                        return "#####";
                    }
                    for (int i=0; i<param_no-1; i++)
                    {
                        firstOperand = parseMember(parameters.at(i), widget).toDouble(&ok);
                        if (!ok)
                        {
                            emit invalidFormula(QString("Invalid operand: %1").
                                                arg(parameters.at(i)));
                            return "#####";
                        }
                        if (compareMembers(op, firstOperand, secondOperand))
                            count++;
                    }
                    return count;
                }
            }
        }
        else
        {
            emit invalidFormula("Invalid formula");
            return "#####";
        }
    }
    return formula;
}
Beispiel #4
0
ClassDef::ClassDef( char * defFile ):openErr(0)
{

  // allocate for the input line from the class defination file.
  //
  char * classDefLine = new char[256];

  // open the needed files:
  //
  ifstream classDef(defFile);
  if( ! classDef )
  {
     cerr << "Could not open class definition file: " << defFile << endl;
     openErr = true;
  }

  cppFile = defFile;
  hppFile = defFile;
  cppFile += ".cpp";
  hppFile += ".hpp";

  if( !openErr )
  {
    char * result;
    const char * Level2;
    const char * Level3;

    // expect the first line in the class def to contain the CLASS
    // keyword.
    //
    if ( classDef.getline( classDefLine, 80 ) )
    {

      cout << classDefLine << endl;

      result = strtok( classDefLine," " );

      cout << result << endl;

      if( !strcmp( result, tokClassHeader ) )
      {
	result = strtok( '\0', " " );
	cout << result << endl;
	className = result;
        className.trim();
      }
    }

    while ( classDef.getline( classDefLine, 80 ) && className.max() )
    {
      trim( classDefLine );

      if( strlen( classDefLine ) )
      {
        cout << classDefLine << endl;

        // level 2
        if( strstr( classDefLine, tokPrivate ) )
        {
		 Level2 = tokPrivate;
        }
        else if( strstr( classDefLine, tokPublic ) )
        {
		 Level2 = tokPublic;
        }
        else if( strstr( classDefLine, tokData ) )
        {
		 Level3 = tokData;
        }
        else if( strstr( classDefLine, tokMethods ) )
        {
		 Level3 = tokMethods;
        }
        else if( strstr( classDefLine, tokParents ) )
        {
		 Level3 = tokParents;
        }
        else if( strstr( classDefLine, tokInclude ) )
        {
	  hString * incLine = new hString;
	  *incLine = classDefLine;
	  includes.add(incLine);
        }
        else
        {
	  if( Level3 == tokData )
	  {
	    classMember * member = new classMember;

	    if( parseMember( *member, classDefLine ) )
	    {

	      findType( *member );
	      accessDefs( *member );
              accessImps( *member );
              initAndDestroy( *member );

	      if( Level2 == tokPublic )
	      {
	        publicMembers.add(member);
	      }
	      else if( Level2 == tokPrivate )
	      {
	        privateMembers.add(member);
	      }
              if( member->type.matchIn("*") )
              {
	        classMember * sizMember = new classMember;
                sizMember->name = "size";
                sizMember->name += member->name.upperS();
                sizMember->type = "unsigned long";
	        findType( *sizMember );
	        accessDefs( *sizMember );
                accessImps( *sizMember );
                initAndDestroy( *sizMember );
	        sizeMembers.add( sizMember );

              }

	    }
	  }
	  else if ( Level3 == tokMethods )
	  {

	    hString * method = new hString;
	    *method = classDefLine;
	    if( Level2 == tokPublic )
	    {
	      publicMethods.add(method);
	    }
	    else if( Level2 == tokPrivate )
	    {
	      privateMethods.add(method);
	    }

	  }
	  else if ( Level3 == tokParents )
	  {

	    hString * dad = new hString;
	    *dad = classDefLine;
	    if( Level2 == tokPublic )
	    {
	      publicParents.add(dad);
	    }
	    else if( Level2 == tokPrivate )
	    {
	      privateParents.add(dad);
	    }

	  }

        }

      } // end if length

    } // end while

  } // end if

  delete [] classDefLine;

}
Beispiel #5
0
			inline static JSONObject* parseObject(const char* string)
			{
				int index = 0;
				int stringLength = strlen(string);
				char c = string[index];

				JSONObject* object = new JSONObject;

				bool parsing = true;

				while (parsing)
				{
					//We've hit a member; determine how long until the next member and then parse it
					if (c == '\"')
					{
						int startIndex = index;
						int memberLength = 0;
						char m = c;
						char targetChar = ',';

						int nestedObjects = 0;
						int nestedArrays = 0;

						while (m != targetChar || nestedObjects > 0 || nestedArrays > 0)
						{
							//If we've read past our string length we can just break
							if (index + memberLength >= stringLength)
							{
								parsing = false;
								break;
							}

							m = string[startIndex + memberLength];							
							
							if (m == '}' && nestedObjects == 0)
								break;

							if (m == '{')
								nestedObjects++;
							else if (m == '}' && nestedObjects > 0)
								nestedObjects--;

							if (m == '[')
								nestedArrays++;
							else if (m == ']' && nestedArrays > 0)
								nestedArrays--;

							memberLength++;
						}

						//If we get a member that's less than 5 chars (by accident) just increment the index counter and keep going
						//5 because the least number of chars for a member is 5
						//Ex. "a":1
						if (memberLength < 5)
						{
							index++;
							continue;
						}
				
						char* memberString = new char[memberLength + 1];
						memcpy(memberString, string + startIndex, memberLength);

						//We MAY want to trim off the last character
						if (memberString[memberLength - 1] == ','
							|| (!strstr(memberString, "{") && memberString[memberLength - 1] == '}'))
							memberString[memberLength - 1] = '\0';
						//Regardless the string needs a null terminator
						else
							memberString[memberLength] = '\0';

						JSONPair member = parseMember(memberString);

						//If the key is never set then there was a problem
						if (member.getKey() != "")
							object->addPair(member);
						else
							std::cout << "Error parsing member in object" << std::endl;
						
						delete[] memberString;

						index += (memberLength - 1);
					}

					c = string[index++];

					//If we've read past our string length we can just break
					if (index >= stringLength)
						parsing = false;
				}

				return object;
			}