Ejemplo n.º 1
0
static JSBool
HandleData(JSContext *cx, JSONParser *jp, JSONDataType type, const jschar *buf, uint32 len)
{
  JSBool ok = JS_FALSE;
 
  switch (type) {
    case JSON_DATA_STRING:
      ok = HandleString(cx, jp, buf, len);
      break;
 
    case JSON_DATA_KEYSTRING:
      jp->objectKey = JS_NewUCStringCopyN(cx, buf, len);
      ok = JS_TRUE;
      break;
 
    case JSON_DATA_NUMBER:
      ok = HandleNumber(cx, jp, buf, len);
      break;
 
    case JSON_DATA_KEYWORD:
      ok = HandleKeyword(cx, jp, buf, len);
      break;
 
    default:
      JS_NOT_REACHED("Should have a JSON data type");
  }
 
  js_FinishStringBuffer(jp->buffer);
  js_InitStringBuffer(jp->buffer);
 
  return ok;
}
Ejemplo n.º 2
0
static JSBool
HandleData(JSContext *cx, JSONParser *jp, JSONDataType type)
{
  JSBool ok = JS_FALSE;

  if (!STRING_BUFFER_OK(jp->buffer))
      return JS_FALSE;

  switch (type) {
    case JSON_DATA_STRING:
      ok = HandleString(cx, jp, jp->buffer->base, STRING_BUFFER_OFFSET(jp->buffer));
      break;

    case JSON_DATA_KEYSTRING:
      js_AppendUCString(jp->objectKey, jp->buffer->base, STRING_BUFFER_OFFSET(jp->buffer));
      ok = STRING_BUFFER_OK(jp->objectKey);
      break;

    case JSON_DATA_NUMBER:
      ok = HandleNumber(cx, jp, jp->buffer->base, STRING_BUFFER_OFFSET(jp->buffer));
      break;

    case JSON_DATA_KEYWORD:
      ok = HandleKeyword(cx, jp, jp->buffer->base, STRING_BUFFER_OFFSET(jp->buffer));
      break;

    default:
      JS_NOT_REACHED("Should have a JSON data type");
  }

  js_FinishStringBuffer(jp->buffer);
  js_InitStringBuffer(jp->buffer);

  return ok;
}
Ejemplo n.º 3
0
int
main (int argc, char *argv[])
{
  char *ptr, *data = LoadInput();
  int i;

  /*
   * Handle CGI data
   */

  if (data) {
    ptr = strtok (data, "&");
    while (ptr) {
      HandleString (ptr);
      ptr = strtok (NULL, "&");
    }
    free (data);
  }

  /*
   * Add Path info
   */

  if (getenv ("PATH_INFO") != NULL) {
    data = FP_strdup (getenv ("PATH_INFO"));
    ptr = strtok (data, "/");
    while (ptr) {
      HandleString (ptr);
      ptr = strtok (NULL, "/");
    }
    free (data);
  }

  /*
   * Add args
   */

  for (i=1; i<argc; i++) {
    HandleString (argv[i]);
  }

  /*
   * done
   */

  return 0;
}
/* This function checks if the next word is Virtual instruction
 (like .string or .data) */
int CheckIfVirtualInstruction(char *line , int isLabel)
{
	int i;
	char *word;
	/* Set i position for case you have label and for case you don't have a label */
	i = isLabel ? isLabel+2 : 0;

	/* Ignore spaces */
	while(isspace(line[i]))
		i++;

	/* Check if */
	if(line[i++]=='.')
	{
		word=GetWord(&line[i],' ');
		if(strcmp(word,"data")==0)
		{
			if(isLabel>0)
			{
				SetLabel(line,(int)isLabel,DATA,0,0,(int)DC);
			}
			/* Step over .data word in line */
			i+=5;
			/* Ignore spaces */
			while(isspace(line[i]))
				i++;

			HandleData(&line[i]);
			return 1;

		}
		else if(strcmp(word,"string")==0)
		{
			if(isLabel>0)
			{
				SetLabel(line,(int)isLabel,DATA,0,0,(int)DC);
			}
			/* Step over .string word in line */
			i += 7;
			/* Step over space */
			while(isspace(line[i]))
				i++;

			HandleString(&line[i]);
			return 1;
		}
	}
	else
	{
		return 0;
	}
	return 0;
}
Ejemplo n.º 5
0
void ControlSocket::OnRead(void)
{
    if(!_ok)
        return;
    TcpSocket::OnRead();
    uint32 len = ibuf.GetLength();
    if(!len)
    {
        logdetail("ControlSocket: connection to %s:%u closed.",GetRemoteAddress().c_str(),GetRemotePort());
        return;
    }

    char *buf = new char[len];
    ibuf.Read(buf,len);

    if(buf[0]==0 && len > 1)
    {
        // reserved for future applications
    }
    else
    {
        uint32 i = 0;
        while(i < len)
        {
            if(buf[i] == 127) // ignore del key for now
                continue;
            if(buf[i] == 27) // escape sequence, drop whole buf (sent on direction key press for example)
                break;
            if(buf[i] == 8) // backspace
            {
                if(_str.length())
                    _str.erase(_str.length() - 1);
            }
            else if(buf[i] == 10 || buf[i] == 13 || buf[i] == 0) // newline or \0 char
            {
                if(_str.length() && _instance && _instance->GetScripts())
                {
                    HandleString(_str);
                }
                _str.clear();
            }
            else
            {
                _str += buf[i];
            }
            ++i;
        }
    }

    delete [] buf;
}
Ejemplo n.º 6
0
bool cPasTokenizer::Parse(const char* strLine, bool bSkipWhiteSpaces, bool bSkipComments)
{
    if (!GetTokenHandler())
        return false;

    IncLine();
    LogLine(strLine);

    if (m_bBlockComment)
    {
        strLine = AppendBlockComment(strLine, bSkipComments);
    }
    else if (GetLine() > 1)
    {
        if (!bSkipWhiteSpaces)
            PushToken(TOKEN_NEWLINE);
    }

    if (strLine == NULL)
        return false;

    while(char c = *strLine++)
    {
        tToken token;

        switch(c)
        {
        case ' ':
        case '\t':
            strLine = HandleWhiteSpace(strLine-1, bSkipWhiteSpaces);
            break;
        case '{':
            strLine = HandleBlockComment(strLine, bSkipComments);
            if (strLine == NULL)
            {
                return true;
            }
            break;
        case '+':
            PushToken(TOKEN_OPERATOR, PAS_OP_ADDITION);
            break;
        case '-':
            PushToken(TOKEN_OPERATOR, PAS_OP_SUBTRACTION);
            break;
        case '*':
            PushToken(TOKEN_OPERATOR, PAS_OP_MULTIPLICATION);
            break;
        case '/':
            switch(*strLine)
            {
            case '/':
                PushToken(TOKEN_LINECOMMENT, strLine+1);
                return true;
            default:
                PushToken(TOKEN_OPERATOR, PAS_OP_DIVISION);
                break;
            }
            break;
        case '=':
            PushToken(TOKEN_OPERATOR, PAS_OP_EQUAL);
            break;
        case '>':
            switch(*strLine)
            {
            case '=':
                PushToken(TOKEN_OPERATOR, PAS_OP_BIGGER_OR_EQUAL);
                strLine++;
                break;
            default:
                PushToken(TOKEN_OPERATOR, PAS_OP_BIGGER);
                break;
            };
            break;
        case '<':
            switch(*strLine)
            {
            case '=':
                PushToken(TOKEN_OPERATOR, PAS_OP_SMALLER_OR_EQUAL);
                strLine++;
                break;
            case '>':
                PushToken(TOKEN_OPERATOR, PAS_OP_NOT_EQUAL);
                strLine++;
                break;
            default:
                PushToken(TOKEN_OPERATOR, PAS_OP_SMALLER);
                break;
            };
            break;
        case ':':
            switch(*strLine)
            {
            case '=':
                PushToken(TOKEN_OPERATOR, PAS_OP_ASSIGNMENT);
                strLine++;
                break;
            default:
                PushToken(TOKEN_OPERATOR, PAS_OP_ISTYPE);
                break;
            };
            break;
        case '^':
            PushToken(TOKEN_OPERATOR, PAS_OP_DEREFERENCE);
            break;
        case '@':
            PushToken(TOKEN_OPERATOR, PAS_OP_ADDRESS);
            break;
        case '&':
            PushToken(TOKEN_OPERATOR, PAS_OP_AMPERSAND);
            break;
        case ',':
            PushToken(TOKEN_OPERATOR, PAS_OP_LIST);
            break;
        case ';':
            PushToken(TOKEN_OPERATOR, PAS_OP_COMMAND_SEPARATOR);
            break;
        case '#':
            strLine = ParseLiteral(strLine-1, TOKEN_CHAR);
            if (strLine == NULL)
                return false;
            break;
        case '$':
            strLine = ParseLiteral(strLine-1, TOKEN_LITERAL);
            if (strLine == NULL)
                return false;
            break;
        case '.':
            switch(*strLine)
            {
            case '$':
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                strLine = ParseLiteral(strLine-1, TOKEN_LITERAL);
                if (strLine == NULL)
                    return false;
                break;
            case '.':
                PushToken(TOKEN_OPERATOR, PAS_OP_RANGE);
                strLine++;
                break;
            case ')':
                PushToken(TOKEN_OPERATOR, PAS_OP_INDEX_CLOSE);
                strLine++;
                break;
            default:
                PushToken(TOKEN_OPERATOR, PAS_OP_MEMBER_ACCESS);
                break;
            }
            break;
        case '\'':
            strLine = HandleString(strLine-1);
            if (strLine == NULL)
                return true;
            break;
        case '(':
            switch(*strLine)
            {
            case '.':
                PushToken(TOKEN_OPERATOR, PAS_OP_INDEX_OPEN);
                strLine++;
                break;
            case '*':
                strLine = HandleBlockComment(strLine, bSkipComments);
                if (strLine == NULL)
                {
                    return true;
                }
                break;
            default:
                PushToken(TOKEN_OPERATOR, PAS_OP_BRACKET_OPEN);
                break;
            }
            break;
        case ')':
            PushToken(TOKEN_OPERATOR, PAS_OP_BRACKET_CLOSE);
            break;
        case '[':
            PushToken(TOKEN_OPERATOR, PAS_OP_INDEX_OPEN);
            break;
        case ']':
            PushToken(TOKEN_OPERATOR, PAS_OP_INDEX_CLOSE);
            break;

        default:
            if (isalpha(c) || c == '_')
            {
                strLine = ParseLabel(strLine-1);
            }
            else if (isdigit(c))
            {
                strLine = ParseLiteral(strLine-1, TOKEN_LITERAL);
            }
            else
            {
                std::stringstream strLog;
                strLog << "unknown character " << c;
                GetTokenHandler()->HandleError(strLog.str().c_str(), GetLine());
            }
            if (strLine == NULL)
                return false;
            break;
        }
    }

    return false;
}
Ejemplo n.º 7
0
    wxScopedCharTypeBuffer<CharType> Convert(const CharType *format)
    {
        // this is reset to NULL if we modify the format string
        m_fmtOrig = format;

        while ( *format )
        {
            if ( CopyFmtChar(*format++) == wxT('%') )
            {
                // skip any flags
                while ( IsFlagChar(*format) )
                    CopyFmtChar(*format++);

                // and possible width
                if ( *format == wxT('*') )
                    CopyFmtChar(*format++);
                else
                    SkipDigits(&format);

                // precision?
                if ( *format == wxT('.') )
                {
                    CopyFmtChar(*format++);
                    if ( *format == wxT('*') )
                        CopyFmtChar(*format++);
                    else
                        SkipDigits(&format);
                }

                // next we can have a size modifier
                SizeModifier size;

                switch ( *format )
                {
                    case 'h':
                        size = Size_Short;
                        format++;
                        break;

                    case 'l':
                        // "ll" has a different meaning!
                        if ( format[1] != 'l' )
                        {
                            size = Size_Long;
                            format++;
                            break;
                        }
                        //else: fall through

                    default:
                        size = Size_Default;
                }

                CharType outConv = *format;
                SizeModifier outSize = size;

                // and finally we should have the type
                switch ( *format )
                {
                    case wxT('S'):
                    case wxT('s'):
                        // all strings were converted into the same form by
                        // wxArgNormalizer<T>, this form depends on the context
                        // in which the value is used (scanf/printf/wprintf):
                        HandleString(*format, size, outConv, outSize);
                        break;

                    case wxT('C'):
                    case wxT('c'):
                        HandleChar(*format, size, outConv, outSize);
                        break;

                    default:
                        // nothing special to do
                        break;
                }

                if ( outConv == *format && outSize == size ) // no change
                {
                    if ( size != Size_Default )
                        CopyFmtChar(*(format - 1));
                    CopyFmtChar(*format);
                }
                else // something changed
                {
                    switch ( outSize )
                    {
                        case Size_Long:
                            InsertFmtChar(wxT('l'));
                            break;

                        case Size_Short:
                            InsertFmtChar(wxT('h'));
                            break;

                        case Size_Default:
                            // nothing to do
                            break;
                    }
                    InsertFmtChar(outConv);
                }

                format++;
            }
        }

        // notice that we only translated the string if m_fmtOrig == NULL (as
        // set by CopyAllBefore()), otherwise we should simply use the original
        // format
        if ( m_fmtOrig )
        {
            return wxScopedCharTypeBuffer<CharType>::CreateNonOwned(m_fmtOrig);
        }
        else
        {
            // shrink converted format string to actual size (instead of
            // over-sized allocation from CopyAllBefore()) and NUL-terminate
            // it:
            m_fmt.shrink(m_fmtLast - m_fmt.data());
            return m_fmt;
        }
    }
Ejemplo n.º 8
0
CToken* CTokenizer::FetchToken()
{
	if (m_nextToken != NULL)
	{
		CToken* curToken = m_nextToken;
		m_nextToken = curToken->GetNext();
		curToken->SetNext(NULL);
		return curToken;
	}
	byte theByte;
	CToken* theToken = NULL;

	while (true)
	{
		if (!NextChar(theByte))
		{
			return CToken::Create();
		}
		if (theByte <= ' ')
		{
			if ((theByte == '\n') && ((TKF_USES_EOL & m_flags) != 0))
			{
				return CUserToken::Create(TK_EOL, "-EOLN-");
			}
			continue;
		}
		switch(theByte)
		{
		case '#':
			if ((m_flags & TKF_IGNOREDIRECTIVES) == 0)
			{
				theToken = HandleDirective();
			}
			else
			{
				if ((m_flags & TKF_NODIRECTIVES) != 0)
				{
					return HandleSymbol('#');
				}
				SkipToLineEnd();
			}
			break;
		case '/':
			theToken = HandleSlash();
			break;
		case '"':
			theToken = HandleString();
			break;
		case '\'':
			theToken = HandleQuote();
			break;
		default:
			if (((theByte >= 'a') && (theByte <= 'z'))
				|| ((theByte >= 'A') && (theByte <= 'Z'))
				|| ((theByte == '_') && ((m_flags & TKF_NOUNDERSCOREINIDENTIFIER) == 0)))
			{
				theToken = HandleIdentifier(theByte);
			}
			else if (((m_flags & TKF_NUMERICIDENTIFIERSTART) != 0) && (theByte >= '0') && (theByte <= '9'))
			{
				theToken = HandleIdentifier(theByte);
			}
			else if (((theByte >= '0') && (theByte <= '9')) || (theByte == '-'))
			{
				theToken = HandleNumeric(theByte);
			}
			else if (theByte == '.')
			{
				theToken = HandleDecimal();
			}
			else if (theByte <= ' ')
			{
				break;
			}
			else
			{
				theToken = HandleSymbol(theByte);
			}
		}
		if (theToken != NULL)
		{
			return theToken;
		}
	}
}
Ejemplo n.º 9
0
    wxScopedCharTypeBuffer<CharType> Convert(const CharType *format)
    {
        // this is reset to NULL if we modify the format string
        m_fmtOrig = format;

#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
        while ( *format )
        {
            if ( CopyFmtChar(*format++) == wxT('%') )
            {
#if wxUSE_PRINTF_POS_PARAMS
                if ( *format >= '0' && *format <= '9' )
                {
                    SkipDigits(&format);
                    if ( *format == '$' )
                    {
                        // It was a positional argument specification.
                        CopyFmtChar(*format++);
                    }
                    //else: it was a width specification, nothing else to do.
                }
#endif // wxUSE_PRINTF_POS_PARAMS

                // skip any flags
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
                while ( IsFlagChar(*format) )
                    CopyFmtChar(*format++);

                // and possible width
                if ( *format == wxT('*') )
                    CopyFmtChar(*format++);
                else
                    SkipDigits(&format);

                // precision?
                if ( *format == wxT('.') )
                {
                    CopyFmtChar(*format++);
                    if ( *format == wxT('*') )
                        CopyFmtChar(*format++);
                    else
                        SkipDigits(&format);
                }

                // next we can have a size modifier
                SizeModifier size;

                switch ( *format )
                {
#ifdef __VISUALC__
                    case 'z':
                        // Used for size_t printing (e.g. %zu) and is in C99,
                        // but is not portable, MSVC uses 'I' with the same
                        // meaning.
                        ChangeFmtChar('I');
                        format++;
                        size = Size_Default;
                        break;
#endif // __VISUALC__

                    case 'h':
                        size = Size_Short;
                        format++;
                        break;

                    case 'l':
                        // "ll" has a different meaning!
                        if ( format[1] != 'l' )
                        {
                            size = Size_Long;
                            format++;
                            break;
                        }
                        wxFALLTHROUGH;

                    default:
                        size = Size_Default;
                }

                CharType outConv = *format;
                SizeModifier outSize = size;

                // and finally we should have the type
                switch ( *format )
                {
                    case wxT('S'):
                    case wxT('s'):
                        // all strings were converted into the same form by
                        // wxArgNormalizer<T>, this form depends on the context
                        // in which the value is used (scanf/printf/wprintf):
                        HandleString(*format, size, outConv, outSize);
                        break;

                    case wxT('C'):
                    case wxT('c'):
                        HandleChar(*format, size, outConv, outSize);
                        break;

                    default:
                        // nothing special to do
                        break;
                }

                if ( outConv == *format && outSize == size ) // no change
                {
                    if ( size != Size_Default )
                        CopyFmtChar(*(format - 1));
                    CopyFmtChar(*format);
                }
                else // something changed
                {
                    switch ( outSize )
                    {
                        case Size_Long:
                            InsertFmtChar(wxT('l'));
                            break;

                        case Size_Short:
                            InsertFmtChar(wxT('h'));
                            break;

                        case Size_Default:
                            // nothing to do
                            break;
                    }
                    InsertFmtChar(outConv);
                }

                format++;
            }
        }

        // notice that we only translated the string if m_fmtOrig == NULL (as
        // set by CopyAllBefore()), otherwise we should simply use the original
        // format
        if ( m_fmtOrig )
        {
            return wxScopedCharTypeBuffer<CharType>::CreateNonOwned(m_fmtOrig);
        }
        else
        {
            // shrink converted format string to actual size (instead of
            // over-sized allocation from CopyAllBefore()) and NUL-terminate
            // it:
            m_fmt.shrink(m_fmtLast - m_fmt.data());
            return m_fmt;
        }
    }
Ejemplo n.º 10
0
bool cPPTokenizer::Parse(const char* strLine, bool bSkipWhiteSpaces, bool bSkipComments)
{
  LOG("strLine: %s", strLine);
  LOG("Stop: %s", m_bStop ? "true" : "false");

  bool bSlashFound = false;
  char c;

  if (!GetTokenHandler())
    return false;

  IncLine();
  LogLine(strLine);

  if (m_bBlockComment)
  {
    strLine = AppendBlockComment(strLine);
    if (strLine == NULL)
      return true;
  }
  else if (m_bLineComment)
  {
    HandleLineComment(strLine);
    return true;
  }
  else if (m_bMultiLineString)
  {
    strLine = AppendString(strLine);
    if (strLine == NULL)
      return true;
  }
  else if (m_bMessage)
  {
    HandleMessage(strLine);
    return true;
  }
  else if (GetLine() > 1)
  {
    if (!bSkipWhiteSpaces)
      PushToken(TOKEN_NEWLINE);
  }

  if (m_bStop)
  {
    m_bStop = false;
    return false;
  }

  bool bLineStart = true;

  while(c = *strLine++)
  {
    tToken token;

    switch(c)
    {
      case ' ':
      case '\t':
        strLine = HandleWhiteSpace(strLine-1, bLineStart);
        break;

      case '#':
        if (m_bPreProcMode) 
        {
          switch(*strLine)
          {
            case '#': PushToken(TOKEN_OPERATOR, PP_OP_CONCATENATION); strLine++; break;
            default:
              PushToken(TOKEN_OPERATOR, PP_OP_STRINGIFICATION); 
              break;
          }
        }
        else
        {
          PushToken(TOKEN_OPERATOR, PP_OP_PREPROC);
          m_bPreProcMode = true;
          m_bExpectKeyword = true;
        }
        break;

      // ',', '(', ')' are needed to interpret parameter lists in macro calls

      case ',': PushToken(TOKEN_OPERATOR, PP_OP_COMMA); break;
      case '(': PushToken(TOKEN_OPERATOR, PP_OP_BRACKET_OPEN); break;
      case ')': PushToken(TOKEN_OPERATOR, PP_OP_BRACKET_CLOSE); break;
      case '+': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_ADDITION, "+"); break;
      case '-': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_SUBTRACTION, "-"); break;
      case '*': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_MULTIPLICATION, "*"); break;
      case '%':
        switch(*strLine)
        {
          case '>': PushToken(TOKEN_CHAR, '}'); strLine++; break;
          case ':': PushToken(TOKEN_CHAR, '#'); strLine++; break;
          default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_MODULUS, "%"); break;
        }
        break;
      case '~': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_BITWISE_NOT, "~"); break;
      case '^': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_BITWISE_XOR, "^"); break;
      case '!':
        switch(*strLine)
        {
          case '=': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_NOT_EQUAL, "!="); strLine++; break;
          default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_LOGICAL_NOT, "!"); break;
        }
        break;
      case '&':
        switch(*strLine)
        {
          case '&': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_LOGICAL_AND, "&&"); strLine++; break;
          default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_BITWISE_AND, "&"); break;
        }
        break;
      case '|':
        switch(*strLine)
        {
          case '|': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_LOGICAL_OR, "||"); strLine++; break;
          default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_BITWISE_OR, "|"); break;
        }
        break;
      case '=': 
        switch(*strLine)
        {
          case '=': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_EQUAL, "=="); strLine++; break;
          default: PushToken(TOKEN_CHAR, '='); break;
        }
        break;
      case '.':
        if (strLine[0] == '.' && strLine[1] == '.')
        {
          strLine += 2;
          PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_ELLIPSIS, "...");
        }
        else
        {
          switch(*strLine)
          {
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
              strLine = ParseLiteral(strLine-1);
              if (strLine == NULL)
                return PushPreProcEnd();
              break;
            default:
              PushToken(TOKEN_CHAR, '.');
              break;
          }
        }
        break;
      case ':':
        switch(*strLine)
        {
          case '>': PushToken(TOKEN_CHAR, ']'); strLine++; break;
          default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_CONDITIONAL_ELSE, ":"); break;
        }
        break;
      case '/':
        switch(*strLine)
        {
          case '/':
            // line comments are removed
            HandleLineComment(strLine);
            return PushPreProcEnd();
          case '*':
            strLine = HandleBlockComment(strLine-2);
            if (strLine == NULL)
              return PushPreProcEnd();
            break;

          default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_DIVISION, "/"); break;
        }
        break;
        case '\'':
          strLine = HandleString(strLine-1, '\'', TOKEN_STRING);
          if (strLine == NULL)
            return PushPreProcEnd();
          break;
        case '\"':
          strLine = HandleString(strLine-1, '\"', TOKEN_STRING);
          if (strLine == NULL)
            return PushPreProcEnd();
          break;
        case '>':
          switch(*strLine)
          {
            case '>': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_SHR, ">>"); strLine++; break;
            case '=': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_BIGGER_OR_EQUAL, ">="); strLine++; break;
            default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_BIGGER, ">"); break;
          }
          break;
        case '<':
          if (m_bInclude)
          {
            strLine = HandleString(strLine-1, '>', TOKEN_STRING);
            m_bInclude = false;
            if (strLine == NULL)
              return PushPreProcEnd();
          }
          else
          {
            switch(*strLine)
            {
              case '<': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_SHL, "<<"); strLine++; break;
              case '=': PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_SMALLER_OR_EQUAL, "<="); strLine++; break;
              case '%': PushToken(TOKEN_CHAR, '{'); strLine++; break;
              case ':': PushToken(TOKEN_CHAR, '['); strLine++; break;
              default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_SMALLER, "<"); break;
            }
            break;
          }
          break;

        case '\\':
          // check whether a line concatenation takes place
          if(*strLine == '\0')
          {
            return true;
          }
          break;

      case '?':
        switch(*strLine)
        {
          case '?':
            strLine++;
            switch(*strLine)
            {
              case '<': PushToken(TOKEN_CHAR, '{'); strLine++; break;
              case '>': PushToken(TOKEN_CHAR, '}'); strLine++; break;
              case '(': PushToken(TOKEN_CHAR, '['); strLine++; break;
              case ')': PushToken(TOKEN_CHAR, ']'); strLine++; break;
              case '\'': PushToken(TOKEN_CHAR, '^'); strLine++; break;
              case '!':  PushToken(TOKEN_CHAR, '|'); strLine++; break;
              case '-': PushToken(TOKEN_CHAR, '~'); strLine++; break;
              case '=': PushToken(TOKEN_CHAR, '#'); strLine++; break;
              case '/': PushToken(TOKEN_CHAR, '\\'); strLine++; break;
              default: PushToken(TOKEN_TEXT, "??"); break;
            }
            break;
          default: PushTokenIfPreProcMode(TOKEN_OPERATOR, PP_OP_CONDITIONAL, "?"); break;
        }
        break;

      default:
        if (isalpha(c) || c == '_')
        {
          strLine = ParseLabel(strLine-1);
          if (m_bMessage)
          {
            HandleMessage(strLine);
            m_bInclude = false;
            return true;
          }
        }
        else if (isdigit(c))
        {
          strLine = ParseLiteral(strLine-1);
        }
        else
        {
          PushToken(TOKEN_CHAR, c);
        }
        break;
    }
    bLineStart = false;
  }

  return PushPreProcEnd();
}