/** \brief Check whether the token at a given position is a function token.
      \param a_Tok [out] If a value token is found it will be placed here.
      \throw ParserException if Syntaxflags do not allow a function at a_iPos
      \return true if a function token has been found false otherwise.
      \pre [assert] m_pParser!=0
  */
  bool ParserTokenReader::IsFunTok(token_type &a_Tok)
  {
    string_type strTok;
    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
    if (iEnd==m_iPos)
      return false;

    funmap_type::const_iterator item = m_pFunDef->find(strTok);
    if (item==m_pFunDef->end())
      return false;

    // Check if the next sign is an opening bracket
    const char_type *szFormula = m_strFormula.c_str();
    if (szFormula[iEnd]!='(')
      return false;

    a_Tok.Set(item->second, strTok);

    m_iPos = (int)iEnd;
    if (m_iSynFlags & noFUN)
      Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString());

    m_iSynFlags = noANY ^ noBO;
    return true;
  }
/** \brief Check if a string position contains a binary operator. */
bool TokenReader::IsOprt(ptr_tok_type &a_Tok)
{
    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_nPos);
    if (iEnd == m_nPos)
        return false;

    oprt_bin_maptype::reverse_iterator item;
    try
    {
        // Note:
        // All tokens in oprt_bin_maptype are have been sorted by their length
        // Long operators must come first! Otherwise short names (like: "add") that
        // are part of long token names (like: "add123") will be found instead 
        // of the long ones.
        // Length sorting is done with ascending length so we use a reverse iterator here.
        for (item = m_pOprtDef->rbegin(); item != m_pOprtDef->rend(); ++item)
        {
            if (sTok.find(item->first) != 0)
                continue;

            // operator found, check if we expect one...
            if (m_nSynFlags & noOPT)
            {
                // An operator was found but is not expected to occur at
                // this position of the formula, maybe it is an infix 
                // operator, not a binary operator. Both operator types
                // can use the same characters in their identifiers.
                if (IsInfixOpTok(a_Tok))
                    return true;

                // nope, it's no infix operator and we dont expect 
                // an operator
                throw ecUNEXPECTED_OPERATOR;
            }
            else
            {
                a_Tok = ptr_tok_type(item->second->Clone());

                m_nPos += (int)a_Tok->GetIdent().length();
                m_nSynFlags = noBC | noIO | noIC | noOPT | noCOMMA | noEND | noNEWLINE | noPFX | noIF | noELSE;
                return true;
            }
        }

        return false;
    }
    catch (EErrorCodes e)
    {
        ErrorContext err;
        err.Errc = e;
        err.Pos = m_nPos; // - (int)item->first.length();
        err.Ident = item->first;
        err.Expr = m_sExpr;
        throw ParserError(err);
    }
}
/** \brief Check if a string position contains a unary post value operator. */
bool TokenReader::IsPostOpTok(ptr_tok_type &a_Tok)
{
    if (m_nSynFlags & noPFX)
    {
        // <ibg 2014-05-30/> Only look for postfix operators if they are allowed at the given position.
        //                   This will prevent conflicts with variable names such as: 
        //                   "sin(n)" where n is the postfix for "nano"
        return false;
        // </ibg>
    }

    // Tricky problem with equations like "3m+5":
    //     m is a postfix operator, + is a valid sign for postfix operators and 
    //     for binary operators parser detects "m+" as operator string and 
    //     finds no matching postfix operator.
    // 
    // This is a special case so this routine slightly differs from the other
    // token readers.

    // Test if there could be a postfix operator
    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_nPos);
    if (iEnd == m_nPos)
        return false;

    try
    {
        // iteraterate over all postfix operator strings
        oprt_pfx_maptype::const_iterator item;
        for (item = m_pPostOprtDef->begin(); item != m_pPostOprtDef->end(); ++item)
        {
            if (sTok.find(item->first) != 0)
                continue;

            a_Tok = ptr_tok_type(item->second->Clone());
            m_nPos += (int)item->first.length();

            if (m_nSynFlags & noPFX)
                throw ecUNEXPECTED_OPERATOR;

            m_nSynFlags = noVAL | noVAR | noFUN | noBO | noPFX /*| noIO*/ | noIF;
            return true;
        }

        return false;
    }
    catch (EErrorCodes e)
    {
        ErrorContext err;
        err.Errc = e;
        err.Pos = m_nPos - (int)a_Tok->GetIdent().length();
        err.Ident = a_Tok->GetIdent();
        err.Expr = m_sExpr;
        throw ParserError(err);
    }
}
/** \brief Check wheter a token at a given position is a variable token.
    \param a_Tok [out] If a variable token has been found it will be placed here.
    \return true if a variable token has been found.
    */
bool TokenReader::IsVarOrConstTok(ptr_tok_type &a_Tok)
{
    if (!m_pVarDef->size() && !m_pConstDef->size() && !m_pFunDef->size())
        return false;

    string_type sTok;
    int iEnd;
    try
    {
        iEnd = ExtractToken(m_pParser->ValidNameChars(), sTok, m_nPos);
        if (iEnd == m_nPos || (sTok.size() > 0 && sTok[0] >= _T('0') && sTok[0] <= _T('9')))
            return false;

        // Check for variables
        var_maptype::const_iterator item = m_pVarDef->find(sTok);
        if (item != m_pVarDef->end())
        {
            if (m_nSynFlags & noVAR)
                throw ecUNEXPECTED_VAR;

            m_nPos = iEnd;
            m_nSynFlags = noVAL | noVAR | noFUN | noBO | noIFX;
            a_Tok = ptr_tok_type(item->second->Clone());
            a_Tok->SetIdent(sTok);
            m_UsedVar[item->first] = item->second;  // Add variable to used-var-list
            return true;
        }

        // Check for constants
        item = m_pConstDef->find(sTok);
        if (item != m_pConstDef->end())
        {
            if (m_nSynFlags & noVAL)
                throw ecUNEXPECTED_VAL;

            m_nPos = iEnd;
            m_nSynFlags = noVAL | noVAR | noFUN | noBO | noIFX | noIO;
            a_Tok = ptr_tok_type(item->second->Clone());
            a_Tok->SetIdent(sTok);
            return true;
        }
    }
    catch (EErrorCodes e)
    {
        ErrorContext err;
        err.Errc = e;
        err.Pos = m_nPos;
        err.Ident = sTok;
        err.Expr = m_sExpr;
        throw ParserError(err);
    }

    return false;
}
Beispiel #5
0
  /** \brief Check whether the token at a given position is a value token.

    Value tokens are either values or constants.

    \param a_Tok [out] If a value token is found it will be placed here.
    \return true if a value token has been found.
  */
  bool ParserTokenReader::IsValTok(token_type &a_Tok)
  {
    assert(m_pConstDef);
    assert(m_pParser);

    string_type strTok;
    value_type fVal(0);
    int iEnd(0);
    
    // 2.) Check for user defined constant
    // Read everything that could be a constant name
    iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
    if (iEnd!=m_iPos)
    {
      valmap_type::const_iterator item = m_pConstDef->find(strTok);
      if (item!=m_pConstDef->end())
      {
        m_iPos = iEnd;
        a_Tok.SetVal(item->second, strTok);

        if (m_iSynFlags & noVAL)
          Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);

        m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; 
        return true;
      }
    }

    // 3.call the value recognition functions provided by the user
    // Call user defined value recognition functions
    std::list<identfun_type>::const_iterator item = m_vIdentFun.begin();
    for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item)
    {
      int iStart = m_iPos;
      if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 )
      {
        strTok.assign(m_strFormula.c_str(), iStart, m_iPos);
        if (m_iSynFlags & noVAL)
          Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);

        a_Tok.SetVal(fVal, strTok);
        m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
        return true;
      }
    }

    return false;
  }
Beispiel #6
0
  /** \brief Read the next token from the string. */ 
  ParserTokenReader::token_type ParserTokenReader::ReadNextToken()
  {
    assert(m_pParser);

    std::stack<int> FunArgs;
    const char_type *szFormula = m_strFormula.c_str();
    token_type tok;

    // Ignore all non printable characters when reading the expression
    while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20) 
      ++m_iPos;

    if ( IsEOF(tok) )        return SaveBeforeReturn(tok); // Check for end of formula
    if ( IsOprt(tok) )       return SaveBeforeReturn(tok); // Check for user defined binary operator
    if ( IsFunTok(tok) )     return SaveBeforeReturn(tok); // Check for function token
    if ( IsBuiltIn(tok) )    return SaveBeforeReturn(tok); // Check built in operators / tokens
    if ( IsArgSep(tok) )     return SaveBeforeReturn(tok); // Check for function argument separators
    if ( IsValTok(tok) )     return SaveBeforeReturn(tok); // Check for values / constant tokens
    if ( IsVarTok(tok) )     return SaveBeforeReturn(tok); // Check for variable tokens
    if ( IsStrVarTok(tok) )  return SaveBeforeReturn(tok); // Check for string variables
    if ( IsString(tok) )     return SaveBeforeReturn(tok); // Check for String tokens
    if ( IsInfixOpTok(tok) ) return SaveBeforeReturn(tok); // Check for unary operators
    if ( IsPostOpTok(tok) )  return SaveBeforeReturn(tok); // Check for unary operators

    // Check String for undefined variable token. Done only if a 
    // flag is set indicating to ignore undefined variables.
    // This is a way to conditionally avoid an error if 
    // undefined variables occur. 
    // (The GetUsedVar function must suppress the error for
    // undefined variables in order to collect all variable 
    // names including the undefined ones.)
    if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) )  
      return SaveBeforeReturn(tok);

    // Check for unknown token
    // 
    // !!! From this point on there is no exit without an exception possible...
    // 
    string_type strTok;
    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
    if (iEnd!=m_iPos)
      Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok);

    Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos));
    return token_type(); // never reached
  }
Beispiel #7
0
  /** \brief Check if a string position contains a unary post value operator. */
  bool ParserTokenReader::IsPostOpTok(token_type &a_Tok)
  {
    // <ibg 20110629> Do not check for postfix operators if they are not allowed at
    //                the current expression index.
    //
    //  This will fix the bug reported here:  
    //
    //  http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979
    //
    if (m_iSynFlags & noPOSTOP)
      return false;
    // </ibg>

    // Tricky problem with equations like "3m+5":
    //     m is a postfix operator, + is a valid sign for postfix operators and 
    //     for binary operators parser detects "m+" as operator string and 
    //     finds no matching postfix operator.
    // 
    // This is a special case so this routine slightly differs from the other
    // token readers.
    
    // Test if there could be a postfix operator
    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos);
    if (iEnd==m_iPos)
      return false;

    // iteraterate over all postfix operator strings
    funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin();
    for ( ; it!=m_pPostOprtDef->rend(); ++it)
    {
      if (sTok.find(it->first)!=0)
        continue;

      a_Tok.Set(it->second, sTok);
  	  m_iPos += (int)it->first.length();

      m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;
      return true;
    }

    return false;
  }
Beispiel #8
0
  /** \brief Check wheter a token at a given position is an undefined variable. 

      \param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here.
	    \return true if a variable token has been found.
      \throw nothrow
  */
  bool ParserTokenReader::IsUndefVarTok(token_type &a_Tok)
  {
    string_type strTok;
    int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) );
    if ( iEnd==m_iPos )
      return false;

    if (m_iSynFlags & noVAR)
    {
      // <ibg/> 20061021 added token string strTok instead of a_Tok.GetAsString() as the 
      //                 token identifier. 
      // related bug report:
      // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979
      Error(ecUNEXPECTED_VAR, m_iPos - (int)a_Tok.GetAsString().length(), strTok);
    }

    // If a factory is available implicitely create new variables
    if (m_pFactory)
    {
      value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData);
      a_Tok.SetVar(fVar, strTok );

      // Do not use m_pParser->DefineVar( strTok, fVar );
      // in order to define the new variable, it will clear the
      // m_UsedVar array which will kill previousely defined variables
      // from the list
      // This is safe because the new variable can never override an existing one
      // because they are checked first!
      (*m_pVarDef)[strTok] = fVar;
      m_UsedVar[strTok] = fVar;  // Add variable to used-var-list
    }
    else
    {
      a_Tok.SetVar((value_type*)&m_fZero, strTok);
      m_UsedVar[strTok] = 0;  // Add variable to used-var-list
    }

    m_iPos = iEnd;

    // Call the variable factory in order to let it define a new parser variable
    m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR;
    return true;
  }
  /** \brief Check if a string position contains a unary infix operator. 
      \return true if a function token has been found false otherwise.
  */
  bool ParserTokenReader::IsInfixOpTok(token_type &a_Tok)
  {
    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos);
    if (iEnd==m_iPos)
      return false;

    funmap_type::const_iterator item = m_pInfixOprtDef->find(sTok);
    if (item==m_pInfixOprtDef->end())
      return false;

    a_Tok.Set(item->second, sTok);
    m_iPos = (int)iEnd;

    if (m_iSynFlags & noINFIXOP) 
      Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());

    m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; 
    return true;
  }
Beispiel #10
0
  /** \brief Check Expression for the presence of a binary operator token.
  
    Userdefined binary operator "++" gives inconsistent parsing result for
    the equations "a++b" and "a ++ b" if alphabetic characters are allowed
    in operator tokens. To avoid this this function checks specifically
    for operator tokens.
  */
  int ParserTokenReader::ExtractOperatorToken(string_type &a_sTok, 
                                              int a_iPos) const
  {
    int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidInfixOprtChars(), a_iPos);
    if (iEnd==(int)string_type::npos)
      iEnd = (int)m_strFormula.length();

    // Assign token string if there was something found
    if (a_iPos!=iEnd)
    {
      a_sTok = string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd);
      return iEnd;
    }
    else
    {
      // There is still the chance of having to deal with an operator consisting exclusively
      // of alphabetic characters.
      return ExtractToken(MUP_CHARS, a_sTok, a_iPos);
    }
  }
/** \brief Check if a string position contains a unary infix operator.
    \return true if a function token has been found false otherwise.
    */
bool TokenReader::IsInfixOpTok(ptr_tok_type &a_Tok)
{
    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_nPos);

    if (iEnd == m_nPos)
        return false;

    try
    {
        // iteraterate over all infix operator strings
        oprt_ifx_maptype::const_iterator item = m_pInfixOprtDef->begin();
        for (item = m_pInfixOprtDef->begin(); item != m_pInfixOprtDef->end(); ++item)
        {
            if (sTok.find(item->first) != 0)
                continue;

            a_Tok = ptr_tok_type(item->second->Clone());
            m_nPos += (int)item->first.length();

            if (m_nSynFlags & noIFX)
                throw ecUNEXPECTED_OPERATOR;

            m_nSynFlags = noPFX | noIFX | noOPT | noBC | noIC | noIO | noEND | noCOMMA | noNEWLINE | noIF | noELSE;
            return true;
        }

        return false;
    }
    catch (EErrorCodes e)
    {
        ErrorContext err;
        err.Errc = e;
        err.Pos = m_nPos;
        err.Ident = a_Tok->GetIdent();
        err.Expr = m_sExpr;
        throw ParserError(err);
    }
}
Beispiel #12
0
  /** \brief Check if a string position contains a unary infix operator. 
      \return true if a function token has been found false otherwise.
  */
  bool ParserTokenReader::IsInfixOpTok(token_type &a_Tok)
  {
    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos);
    if (iEnd==m_iPos)
      return false;

    // iteraterate over all postfix operator strings
    funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin();
    for ( ; it!=m_pInfixOprtDef->rend(); ++it)
    {
      if (sTok.find(it->first)!=0)
        continue;

      a_Tok.Set(it->second, it->first);
      m_iPos += (int)it->first.length();

      if (m_iSynFlags & noINFIXOP) 
        Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());

      m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN;
      return true;
    }

    return false;

/*
    a_Tok.Set(item->second, sTok);
    m_iPos = (int)iEnd;

    if (m_iSynFlags & noINFIXOP) 
      Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());

    m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; 
    return true;
*/
  }
/** \brief Check expression for function tokens. */
bool TokenReader::IsFunTok(ptr_tok_type &a_Tok)
{
    if (m_pFunDef->size() == 0)
        return false;

    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidNameChars(), sTok, m_nPos);
    if (iEnd == m_nPos)
        return false;

    try
    {
        fun_maptype::iterator item = m_pFunDef->find(sTok);
        if (item == m_pFunDef->end())
            return false;

        m_nPos = (int)iEnd;
        a_Tok = ptr_tok_type(item->second->Clone());
        a_Tok->Compile(_T("xxx"));

        if (m_nSynFlags & noFUN)
            throw ecUNEXPECTED_FUN;

        m_nSynFlags = sfALLOW_NONE ^ noBO;
        return true;
    }
    catch (EErrorCodes e)
    {
        ErrorContext err;
        err.Errc = e;
        err.Pos = m_nPos - (int)a_Tok->GetIdent().length();
        err.Ident = a_Tok->GetIdent();
        err.Expr = m_sExpr;
        throw ParserError(err);
    }
}
/** \brief Read the next token from the string. */
ptr_tok_type TokenReader::ReadNextToken()
{
    assert(m_pParser);

    SkipCommentsAndWhitespaces();

    int token_pos = m_nPos;
    ptr_tok_type pTok;

    // Check for end of expression
    if (IsEOF(pTok))
        return Store(pTok, token_pos);

    if (IsNewline(pTok))
        return Store(pTok, token_pos);

    if (!(m_nSynFlags & noOPT) && IsOprt(pTok))
        return Store(pTok, token_pos); // Check for user defined binary operator

    if (!(m_nSynFlags & noIFX) && IsInfixOpTok(pTok))
        return Store(pTok, token_pos); // Check for unary operators

    if (IsValTok(pTok))
        return Store(pTok, token_pos); // Check for values / constant tokens

    if (IsBuiltIn(pTok))
        return Store(pTok, token_pos); // Check built in operators / tokens

    if (IsVarOrConstTok(pTok))
        return Store(pTok, token_pos); // Check for variable tokens

    if (IsFunTok(pTok))
        return Store(pTok, token_pos);

    if (!(m_nSynFlags & noPFX) && IsPostOpTok(pTok))
        return Store(pTok, token_pos); // Check for unary operators

    // 2.) We have found no token, maybe there is a token that we don't expect here.
    //     Again call the Identifier functions but this time only those we don't expect 
    //     to find.
    if ((m_nSynFlags & noOPT) && IsOprt(pTok))
        return Store(pTok, token_pos); // Check for user defined binary operator

    if ((m_nSynFlags & noIFX) && IsInfixOpTok(pTok))
        return Store(pTok, token_pos); // Check for unary operators

    if ((m_nSynFlags & noPFX) && IsPostOpTok(pTok))
        return Store(pTok, token_pos); // Check for unary operators
    // </ibg>

    // Now we are in trouble because there is something completely unknown....

    // Check the string for an undefined variable token. This is done 
    // only if a flag is set indicating to ignore undefined variables.
    // This is a way to conditionally avoid an error if undefined variables 
    // occur. The GetExprVar function must supress the error for undefined 
    // variables in order to collect all variable names including the 
    // undefined ones.
    if ((m_pParser->m_bIsQueryingExprVar || m_pParser->m_bAutoCreateVar) && IsUndefVarTok(pTok))
        return Store(pTok, token_pos);

    // Check for unknown token
    // 
    // !!! From this point on there is no exit without an exception possible...
    // 
    string_type sTok;
    int iEnd = ExtractToken(m_pParser->ValidNameChars(), sTok, m_nPos);

    ErrorContext err;
    err.Errc = ecUNASSIGNABLE_TOKEN;
    err.Expr = m_sExpr;
    err.Pos = m_nPos;

    if (iEnd != m_nPos)
        err.Ident = sTok;
    else
        err.Ident = m_sExpr.substr(m_nPos);

    throw ParserError(err);
}
Beispiel #15
0
/****************************************************************************
 * 
 *  ROUTINE       :     UnpackAndExpandAcToken
 *
 *  INPUTS        :     INT8 * ExpandedBlock
 *                             Pointer to block structure into which the token
 *                             should be expanded.
 *
 *                      UINT32 * CoeffIndex
 *                             Where we are in the current block.
 *
 *  OUTPUTS       :     
 *
 *  RETURNS       :     The number of bits decoded
 *
 *  FUNCTION      :     Unpacks and expands a AC DCT token.
 *
 *  SPECIAL NOTES :     
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
void UnpackAndExpandAcToken( PB_INSTANCE *pbi, Q_LIST_ENTRY * ExpandedBlock, UINT8 * CoeffIndex  )
{
    INT32           ExtraBits;
    UINT32          Token;

#ifdef DEBUG
    ExtraBits = 0;
#endif

    // Extract a token.   
    Token = ExtractToken(&pbi->br, pbi->HuffRoot_VP3x[pbi->ACHuffChoice]);


    /* Now.. if we are using the DCT optimised coding system, extract any
    *  assosciated additional bits token. 
    */
    if ( ExtraBitLengths_VP31[Token] > 0 )
    {
        /* Extract the appropriate number of extra bits. */
        ExtraBits = bitread(&pbi->br,ExtraBitLengths_VP31[Token]); //0;
    }

    // Take token dependant action
    if ( Token >= DCT_SHORT_ZRL_TOKEN )
    {
        // "Value", "zero run" and "zero run value" tokens
        ExpandToken(  pbi, ExpandedBlock, CoeffIndex, Token, ExtraBits );
        if ( *CoeffIndex >= BLOCK_SIZE )
            pbi->BlocksToDecode --;
    }
    else if ( Token == DCT_EOB_TOKEN )
    {
        *CoeffIndex = BLOCK_SIZE;
        pbi->BlocksToDecode --;
    }
    else
    {
        // Special action and EOB tokens
        switch ( Token )
        {
        case DCT_EOB_PAIR_TOKEN:
            pbi->EOB_Run = 1;
            *CoeffIndex = BLOCK_SIZE;
            pbi->BlocksToDecode --;
            break;
        case DCT_EOB_TRIPLE_TOKEN:
            pbi->EOB_Run = 2;
            *CoeffIndex = BLOCK_SIZE;
            pbi->BlocksToDecode --;
            break;
        case DCT_REPEAT_RUN_TOKEN:
            pbi->EOB_Run = ExtraBits + 3;
            *CoeffIndex = BLOCK_SIZE;
            pbi->BlocksToDecode --;
            break;
        case DCT_REPEAT_RUN2_TOKEN:
            pbi->EOB_Run = ExtraBits + 7;
            *CoeffIndex = BLOCK_SIZE;
            pbi->BlocksToDecode --;
            break;
        case DCT_REPEAT_RUN3_TOKEN:
            pbi->EOB_Run = ExtraBits + 15;
            *CoeffIndex = BLOCK_SIZE;
            pbi->BlocksToDecode --;
            break;
        case DCT_REPEAT_RUN4_TOKEN:
            pbi->EOB_Run = ExtraBits - 1;
            *CoeffIndex = BLOCK_SIZE;
            pbi->BlocksToDecode --;
            break;
        }
    }
}
int NaturalStringCompare( const QString & lhs, const QString & rhs, Qt::CaseSensitivity caseSensitive )
{
	int ii = 0;
	int jj = 0;

	QString lhsBufferQStr;
	QString rhsBufferQStr;

	int retVal = 0;

	// all status values are created on the stack outside the loop to make as fast as possible
	bool lhsNumber = false;
	bool rhsNumber = false;

	double lhsValue = 0.0;
	double rhsValue = 0.0;
	bool ok1;
	bool ok2;

	while ( retVal == 0 && ii < lhs.length() && jj < rhs.length() )
	{
		ExtractToken( lhsBufferQStr, lhs, ii, lhsNumber );
		ExtractToken( rhsBufferQStr, rhs, jj, rhsNumber );

		if ( !lhsNumber && !rhsNumber )
		{
			// both strings curr val is a simple strcmp
			retVal = lhsBufferQStr.compare( rhsBufferQStr, caseSensitive );

			int maxLen = qMin( lhsBufferQStr.length(), rhsBufferQStr.length() );
			QString tmpRight = rhsBufferQStr.left( maxLen );
			QString tmpLeft = lhsBufferQStr.left( maxLen );
			if ( tmpLeft.compare( tmpRight, caseSensitive ) == 0 )
			{
				retVal = lhsBufferQStr.length() - rhsBufferQStr.length();
				if ( retVal )
				{
					QChar nextChar;
					if ( ii < lhs.length() ) // more on the lhs
						nextChar = lhs[ ii ];
					else if ( jj < rhs.length() ) // more on the rhs
						nextChar = rhs[ jj ];

					bool nextIsNum = ( nextChar == '-' || nextChar == '+' || nextChar.isDigit() );

					if ( nextIsNum )
						retVal = -1*retVal;
				}
			}
		}
		else if ( lhsNumber && rhsNumber )
		{
			// both numbers, convert and compare
			lhsValue = lhsBufferQStr.toDouble( &ok1 );
			rhsValue = rhsBufferQStr.toDouble( &ok2 );
			if ( !ok1 || !ok2 )
				retVal = lhsBufferQStr.compare( rhsBufferQStr, caseSensitive );
			else if ( lhsValue > rhsValue )
				retVal = 1;
			else if ( lhsValue < rhsValue )
				retVal = -1;
		}
		else
		{
			// completely arebitrary that a number comes before a string
			retVal = lhsNumber ? -1 : 1;
		}
	}

	if ( retVal != 0 )
		return retVal;
	if ( ii < lhs.length() )
		return -1;
	else if ( jj < rhs.length() )
		return 1;
	else
		return 0;
}
Beispiel #17
0
/**
   Find out operating system name and version

   This method caches system information in m_osName, m_osVersion and m_osAlias.
   It requires m_unameInfo to be set prior to call.

*/
void SCXOSTypeInfo::Init()  // private
{
    m_osVersion = L"";
    m_osName = L"Unknown";

    assert(m_unameIsValid);

#if defined(hpux) || defined(sun)

    if (m_unameIsValid)
    {
        m_osName = StrFromUTF8(m_unameInfo.sysname);
        m_osVersion = StrFromUTF8(m_unameInfo.release);
    }
#if defined(hpux)
    m_osAlias = L"HPUX";
    m_osManufacturer = L"Hewlett-Packard Company";
#elif defined(sun)
    m_osAlias = L"Solaris";
    m_osManufacturer = L"Oracle Corporation";
#endif
#elif defined(aix)

    if (m_unameIsValid)
    {
        m_osName = StrFromUTF8(m_unameInfo.sysname);

        // To get "5.3" we must read "5" and "3" from different fields.
        string ver(m_unameInfo.version);
        ver.append(".");
        ver.append(m_unameInfo.release);
        m_osVersion = StrFromUTF8(ver);
    }
    m_osAlias = L"AIX";
    m_osManufacturer = L"International Business Machines Corporation";
#elif defined(linux)
    vector<wstring> lines;
    SCXStream::NLFs nlfs;
#if defined(PF_DISTRO_SUSE)
    static const string relFileName = "/etc/SuSE-release";
    wifstream relfile(relFileName.c_str());
    wstring version(L"");
    wstring patchlevel(L"");

    SCXStream::ReadAllLines(relfile, lines, nlfs);

    if (!lines.empty()) {
        m_osName = ExtractOSName(lines[0]);
    }

    // Set the Linux Caption (get first line of the /etc/SuSE-release file)
    m_linuxDistroCaption = lines[0];
    if (0 == m_linuxDistroCaption.length())
    {
        // Fallback - should not normally happen
        m_linuxDistroCaption = L"SuSE";
    }

    // File contains one or more lines looking like this:
    // SUSE Linux Enterprise Server 10 (i586)
    // VERSION = 10
    // PATCHLEVEL = 1
    for (size_t i = 0; i<lines.size(); i++)
    {
        if (StrIsPrefix(StrTrim(lines[i]), L"VERSION", true))
        {
            wstring::size_type n = lines[i].find_first_of(L"=");
            if (n != wstring::npos)
            {
                version = StrTrim(lines[i].substr(n+1));
            }
        }
        else if (StrIsPrefix(StrTrim(lines[i]), L"PATCHLEVEL", true))
        {
            wstring::size_type n = lines[i].find_first_of(L"=");
            if (n != wstring::npos)
            {
                patchlevel = StrTrim(lines[i].substr(n+1));
            }
        }
    }

    if (version.length() > 0)
    {
        m_osVersion = version;

        if (patchlevel.length() > 0)
        {
            m_osVersion = version.append(L".").append(patchlevel);
        }
    }

    if (std::wstring::npos != m_osName.find(L"Desktop"))
    {
        m_osAlias = L"SLED";
    }
    else
    {   // Assume server.
        m_osAlias = L"SLES";
    }
    m_osManufacturer = L"SUSE GmbH";
#elif defined(PF_DISTRO_REDHAT)
    static const string relFileName = "/etc/redhat-release";
    wifstream relfile(relFileName.c_str());

    SCXStream::ReadAllLines(relfile, lines, nlfs);

    if (!lines.empty()) {
        m_osName = ExtractOSName(lines[0]);
    }

    // Set the Linux Caption (get first line of the /etc/redhat-release file)
    m_linuxDistroCaption = lines[0];
    if (0 == m_linuxDistroCaption.length())
    {
        // Fallback - should not normally happen
        m_linuxDistroCaption = L"Red Hat";
    }

    // File should contain one line that looks like this:
    // Red Hat Enterprise Linux Server release 5.1 (Tikanga)
    if (lines.size() > 0)
    {
        wstring::size_type n = lines[0].find_first_of(L"0123456789");
        if (n != wstring::npos)
        {
            wstring::size_type n2 = lines[0].substr(n).find_first_of(L" \t\n\t");
            m_osVersion = StrTrim(lines[0].substr(n,n2));
        }
    }

    if ((std::wstring::npos != m_osName.find(L"Client")) // RHED5
            || (std::wstring::npos != m_osName.find(L"Desktop"))) // RHED4
    {
        m_osAlias = L"RHED";
    }
    else
    {   // Assume server.
        m_osAlias = L"RHEL";
    }
    m_osManufacturer = L"Red Hat, Inc.";

#elif defined(PF_DISTRO_ULINUX)
    // The release file is created at agent start time by init.d startup script
    // This is done to insure that we can write to the appropriate directory at
    // the time (since, at agent run-time, we may not have root privileges).
    //
    // If we CAN create the file here (if we're running as root), then we'll
    // do so here. But in the normal case, this shouldn't be necessary.  Only
    // in "weird" cases (i.e. starting omiserver by hand, for example).

    // Create the release file by running GetLinuxOS.sh script
    // (if we have root privileges)

    try
    {
        if ( !SCXFile::Exists(m_deps->getReleasePath()) &&
                SCXFile::Exists(m_deps->getScriptPath()) &&
                m_deps->isReleasePathWritable() )
        {
            std::istringstream in;
            std::ostringstream out;
            std::ostringstream err;

            int ret = SCXCoreLib::SCXProcess::Run(m_deps->getScriptPath().c_str(), in, out, err, 10000);

            if ( ret || out.str().length() || err.str().length() )
            {
                wostringstream sout;
                sout << L"Unexpected errors running script: " << m_deps->getScriptPath().c_str()
                     << L", return code: " << ret
                     << L", stdout: " << StrFromUTF8(out.str())
                     << L", stderr: " << StrFromUTF8(err.str());

                SCX_LOGERROR(m_log, sout.str() );
            }
        }
    }
    catch(SCXCoreLib::SCXInterruptedProcessException &e)
    {
        wstring msg;
        msg = L"Timeout running script \"" + m_deps->getScriptPath() +
              L"\", " + e.Where() + L'.';
        SCX_LOGERROR(m_log, msg );
    };

    // Look in release file for O/S information

    string sFile = StrToUTF8(m_deps->getReleasePath());
    wifstream fin(sFile.c_str());
    SCXStream::ReadAllLines(fin, lines, nlfs);

    if (!lines.empty())
    {
        ExtractToken(L"OSName",     lines, m_osName);
        ExtractToken(L"OSVersion",  lines, m_osVersion);
        ExtractToken(L"OSFullName", lines, m_linuxDistroCaption);
        ExtractToken(L"OSAlias",    lines, m_osAlias);
        ExtractToken(L"OSManufacturer", lines, m_osManufacturer);
    }
    else
    {
        m_osAlias = L"Universal";
    }

    // Behavior for m_osCompatName (method GetOSName) should be as follows:
    //   PostInstall scripts will first look for SCX-RELEASE file (only on universal kits)
    //   If found, add "ORIGINAL_KIT_TYPE=Universal" to scxconfig.conf file,
    //      else   add "ORIGINAL_KIT_TYPE=!Universal" to scxconfig.conf file.
    //   After that is set up, the SCX-RELEASE file is created.
    //
    //   A RHEL system should of OSAlias of "RHEL, SLES system should have "SuSE" (in scx-release)
    //
    //   We need to mimic return values for RHEL and SLES on universal kits that did not
    //   have a universal kit installed previously, but only for RHEL and SLES kits.  In
    //   all other cases, continue to return "Linux Distribution".

    wstring configFilename(m_deps->getConfigPath());
    SCXConfigFile configFile(configFilename);

    try
    {
        configFile.LoadConfig();
    }
    catch(SCXFilePathNotFoundException &e)
    {
        // Something's whacky with postinstall, so we can't follow algorithm
        static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eError, SCXCoreLib::eTrace);
        wstring logMessage(L"Unable to load configuration file " + configFilename);
        SCX_LOG(m_log, suppressor.GetSeverity(logMessage), logMessage);

        m_osCompatName = L"Unknown Linux Distribution";
    }

    if ( m_osCompatName.empty() )
    {
        wstring kitType;
        if ( configFile.GetValue(L"ORIGINAL_KIT_TYPE", kitType) )
        {
            if ( L"!Universal" == kitType )
            {
                if ( L"RHEL" == m_osAlias )
                {
                    m_osCompatName = L"Red Hat Distribution";
                }
                else if ( L"SLES" == m_osAlias )
                {
                    m_osCompatName = L"SuSE Distribution";
                }
            }
        }

        if ( m_osCompatName.empty() )
        {
            m_osCompatName = L"Linux Distribution";
        }
    }
#else
#error "Linux Platform not supported";
#endif

#elif defined(macos)
    m_osAlias = L"MacOS";
    m_osManufacturer = L"Apple Inc.";
    if (m_unameIsValid)
    {
        // MacOS is called "Darwin" in uname info, so we hard-code here
        m_osName = L"Mac OS";

        // This value we could read dynamically from the xml file
        // /System/Library/CoreServices/SystemVersion.plist, but that
        // file may be named differently based on client/server, and
        // reading the plist file would require framework stuff.
        //
        // Rather than using the plist, we'll use Gestalt, which is an
        // API designed to figure out versions of anything and everything.
        // Note that use of Gestalt requires the use of framework stuff
        // as well, so the Makefiles for MacOS are modified for that.

        SInt32 major, minor, bugfix;
        if (0 != Gestalt(gestaltSystemVersionMajor, &major)
                || 0 != Gestalt(gestaltSystemVersionMinor, &minor)
                || 0 != Gestalt(gestaltSystemVersionBugFix, &bugfix))
        {
            throw SCXCoreLib::SCXErrnoException(L"Gestalt", errno, SCXSRCLOCATION);
        }

        wostringstream sout;
        sout << major << L"." << minor << L"." << bugfix;
        m_osVersion = sout.str();
    }

#else
#error "Platform not supported"
#endif
}