Exemplo n.º 1
0
static int CALLBACK PathWordBreakProc(LPCWSTR lpch, int ichCurrent, int cch, int code)
{
    if (code == WB_ISDELIMITER)
        return IsDelimiter(lpch[ichCurrent]);
    else
    {
        int dir = (code == WB_LEFT) ? -1 : 1;
        for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
            if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
    }
    return ichCurrent;
}
Exemplo n.º 2
0
void StringTokenizer::GetNextToken()
{
    // skip till end of token
    while( !AtEnd() && IsWhitespace(*mCurrentPos) )
        mCurrentPos++;

    // this is the start of the token
    mCurToken = (char*)mCurrentPos;

    // skip till end of token
    for(; !AtEnd(); ++mCurrentPos)
    {
        if( IsWhitespace(*mCurrentPos) )
            break;

        if( IsDelimiter(*mCurrentPos) )
        {
            if( mCurrentPos == (Byte*)mCurToken )
                ++mCurrentPos;
            break;
        }
    }

    // end of search condition
    if( mCurrentPos == (Byte*)mCurToken )
    {
        mCurToken = 0;
        mCurTokenLength = 0;
    }
    else
    {
        mCurTokenLength = mCurrentPos - (Byte*)mCurToken;
    }
}
Exemplo n.º 3
0
char *ReadWord_by_value(char *text,int curLoc,char specificDelimiter)
{
	char *tempItem=NULL,*tempText=NULL;
	enum Boolean delimiterFound=FALSE,inQuotes=FALSE;
	int i;
/*	if(specificDelimiter==NULL)
		specificDelimiter=' ';*/
	tempText = StringTrim(text+curLoc);
		if(strlen(tempText)==0)
			return NULL;

		for(i=0;delimiterFound==FALSE;i++)
		{
			if(tempText[i]=='\"')
				if(inQuotes==TRUE)
					inQuotes=FALSE;
				else		
					inQuotes=TRUE;
			else
				if(IsDelimiter(tempText[i],specificDelimiter)==TRUE)
						{
							delimiterFound=TRUE;
							if(i==0)
							{
								delimiterFound=FALSE;
								break;
							}							
							if(tempText[i]==':')
							{

									tempItem=(char*)realloc(tempItem,(i+1)*sizeof(char));
									tempItem[i]=tempText[i];
									i++;
							}
							else if(tempText[i]==' ' && inQuotes==TRUE)
							{
							delimiterFound=FALSE;
							tempItem=(char*)realloc(tempItem,(i+1)*sizeof(char));
							tempItem[i]=tempText[i];
								continue;
							}
							tempItem=(char*)realloc(tempItem,(i+1)*sizeof(char));
							tempItem[i]='\0';	
							break;
						
						}
				
			if(delimiterFound==FALSE)
			{
				tempItem=(char*)realloc(tempItem,(i+1)*sizeof(char));
				tempItem[i]=tempText[i];
			}
		}
		return tempItem;


}
Exemplo n.º 4
0
int CubeLexer::SortText(char *SourceText)
{
	unsigned long Offset=0;
	if (m_Sources)
	{
		free(m_Sources);
		m_SourceOffset=0;
		m_SortStatus=SORT_STATUS_NORMAL;
	}
	if ((m_Sources=(char *)malloc(strlen(SourceText)+1))==NULL)
	{
		return FALSE;
	}

	m_SortStatus=SORT_STATUS_NEWLINE;

	while(*SourceText)
	{
		if (NextChar(*SourceText))
		{
			if(IsNewLine(*SourceText)&&IsSpacer(m_Sources[Offset-1]))
				Offset--;
			if(IsCommentStart(*SourceText)&&IsSpacer(m_Sources[Offset-1]))
				Offset--;
			if(IsDelimiter(*SourceText)&&IsSpacer(m_Sources[Offset-1]))
				Offset--;
			if(IsSpacer(*SourceText)&&IsDelimiter(m_Sources[Offset-1]))
			{
				SourceText++;
				continue;
			}

			m_Sources[Offset++]=*(SourceText);
		}
		SourceText++;
	}
	m_Sources[Offset]='\0';
	return TRUE;
}
Exemplo n.º 5
0
bool WLex::GetValue(String *pStr)
{
    if(m_bEOF)
    {
	return false;
    }
    m_bEOL = false;
    pStr->resize(0);

    int ch;

    for(;;)
    {
	ch = getc(m_File);
	if(ch == EOF)
	{
	    m_bEOL = m_bEOF = true;
	    break;
	}
	if(ch == '\n')
	{
	    m_bEOL = true;
	    break;
	}

	if(IsEscape(ch))
	{
	    int chx = getc(m_File);

	    if(chx == EOF)
	    {
		m_bEOF = true;
		break;
	    }
	    pStr->append(1, char(ch));
	    continue;
	}
	if(IsDelimiter(ch))
	{
	    break;
	}
	pStr->append(1, char(ch));
    }

    return pStr->length() > 0;
}
Exemplo n.º 6
0
void CmdUart_t::IProcessByte(uint8_t b) {
    uint8_t d=0;
    if(b == '#') RxState = rsCmdCode1; // If # is received anywhere, start again
    else switch(RxState) {
        case rsCmdCode1:
            if(TryConvertToDigit(b, &d)) {
                CmdCode = d << 4;
                RxState = rsCmdCode2;
            }
            else IResetCmd();
            break;

        case rsCmdCode2:
            if(TryConvertToDigit(b, &d)) {
                CmdCode |= d;
                RxState = rsData1;
            }
            else IResetCmd();
            break;

        case rsData1:
            if(TryConvertToDigit(b, &d)) {
                *PCmdWrite = d << 4;
                RxState = rsData2;
            }
            else if(IsDelimiter(b)) return; // skip delimiters
            else if(IsEnd(b)) {
                UartCmdCallback(CmdCode, CmdData, (PCmdWrite - CmdData));
                IResetCmd();
            }
            else IResetCmd();
            break;

        case rsData2:
            if(TryConvertToDigit(b, &d)) {
                *PCmdWrite |= d;
                RxState = rsData1;  // Prepare to rx next byte
                if(PCmdWrite < (CmdData + (UART_CMDDATA_SZ-1))) PCmdWrite++;
            }
            else IResetCmd(); // Delimiters and End symbols are not allowed in the middle of byte
            break;

        default: break;
    } // switch
}
Exemplo n.º 7
0
void StringTokenizer::GetPreviousToken()
{
    Byte* pEndOfToken;

    // move to end of string if we are out of it.
    if( *mCurrentPos == 0 )
        --mCurrentPos;

    // skip till end of previous token
    while( mCurrentPos > mStartPos && IsWhitespace(*mCurrentPos) )
        mCurrentPos--;

    pEndOfToken = mCurrentPos;

    // skip till start of previous token
    for( ; mCurrentPos > mStartPos; --mCurrentPos )
    {
        if( IsWhitespace(*mCurrentPos) )
            break;

        if( IsDelimiter(*mCurrentPos) )
        {
            if( pEndOfToken == mCurrentPos )
                --mCurrentPos;
            break;
        }
    }


    if( pEndOfToken == mCurrentPos )
    {
        mCurToken = 0;
        mCurTokenLength = 0;
    }
    else
    {
        mCurToken = (char*)mCurrentPos+1;
        mCurTokenLength = pEndOfToken - mCurrentPos;
    }
}
Exemplo n.º 8
0
        OdbcExpected<bool> SqlLexer::Shift()
        {
            if (IsEod())
            {
                SetEod();

                return false;
            }

            TokenType::Type tokenType = TokenType::EOD;

            while (!IsEod())
            {
                int32_t tokenBegin = pos;

                switch (sql[pos])
                {
                    case '-':
                    {
                        // Full-line comment.
                        if (HaveData(1) && sql[pos + 1] == '-')
                        {
                            pos += 2;

                            while (!IsEod() && sql[pos] != '\n' && sql[pos] != '\r')
                                ++pos;

                            continue;
                        }

                        // Minus.
                        tokenType = TokenType::MINUS;

                        break;
                    }

                    case '"':
                    {
                        // Quoted string.
                        while (true)
                        {
                            ++pos;

                            if (IsEod())
                                return OdbcError(SqlState::SHY000_GENERAL_ERROR, "Unclosed quoted identifier.");

                            if (sql[pos] == '"')
                            {
                                if (!HaveData(2) || sql[pos + 1] != '"')
                                    break;

                                ++pos;
                            }
                        }

                        tokenType = TokenType::QUOTED;

                        break;
                    }

                    case '\'':
                    {
                        // String literal.
                        while (true)
                        {
                            ++pos;

                            if (IsEod())
                                return OdbcError(SqlState::SHY000_GENERAL_ERROR, "Unclosed string literal.");

                            if (sql[pos] == '\'')
                            {
                                if (!HaveData(2) || sql[pos + 1] != '\'')
                                    break;

                                ++pos;
                            }
                        }

                        tokenType = TokenType::STRING;

                        break;
                    }

                    case '.':
                    {
                        tokenType = TokenType::DOT;

                        break;
                    }

                    case ',':
                    {
                        tokenType = TokenType::COMMA;

                        break;
                    }

                    case ';':
                    {
                        tokenType = TokenType::SEMICOLON;

                        break;
                    }

                    case '(':
                    {
                        tokenType = TokenType::PARENTHESIS_LEFT;

                        break;
                    }

                    case ')':
                    {
                        tokenType = TokenType::PARENTHESIS_RIGHT;

                        break;
                    }

                    default:
                    {
                        // Skipping spaces.
                        if (iscntrl(sql[pos]) || isspace(sql[pos]))
                        {
                            do
                            {
                                ++pos;
                            }
                            while (!IsEod() && (iscntrl(sql[pos]) || isspace(sql[pos])));

                            continue;
                        }

                        // Word.
                        while (!IsEod() && !IsDelimiter(sql[pos]))
                            ++pos;

                        --pos;

                        tokenType = TokenType::WORD;

                        break;
                    }
                }

                ++pos;

                if (tokenType != TokenType::EOD)
                {
                    currentToken = SqlToken(&sql[tokenBegin], pos - tokenBegin, tokenType);

                    return true;
                }
            }

            SetEod();

            return false;
        }
Exemplo n.º 9
0
bool
wxPdfTokenizer::IsDelimiterOrWhitespace(int ch)
{
  return IsWhitespace(ch) || IsDelimiter(ch) || (ch == -1);
}
Exemplo n.º 10
0
static void MoveNextWord( LPCLASSDATA lpcd )
{
	/*
	 *	Obtain current caret column and a
	 *	pointer to the line.
	 */
	int	nPos = lpcd->ptCaretPos.x;
	LPLINE	lpLine = GETLINE( lpcd );

	/*
	 *	Are we at the end of the line?
	 */
	if ( nPos == lpLine->nLength )
	{
		/*
		 *	Yes go down one line and to the
		 *	first word on that line.
		 */
		if ( lpcd->ptCaretPos.y < ArrayGetSize( lpcd->lpLines ) - 1 )
		{
			/*
			 *	Start at 0
			 */
			nPos = 0;

			/*
			 *	Go down.
			 */
			lpcd->ptCaretPos.y++;

			/*
			 *	Skip spaces.
			 */
			lpLine = GETLINE( lpcd );

			if ( lpLine->pcText )
			{
				while ( _istspace( lpLine->pcText[ nPos ] ) && nPos < GETLINE( lpcd )->nLength )
					nPos++;
			}

			/*
			 *	Store new column position.
			 */
			lpcd->ptCaretPos.x = nPos;
		}
	}
	else
	{
		BOOL	bBreakOnNonSpace = FALSE;

		/*
		 *	Are we on a white space?
		 */
		if ( _istspace( lpLine->pcText[ nPos ] ))
		{
			/*
			 *	Skip spaces...
			 */
			while ( _istspace( lpLine->pcText[ nPos ] ) && nPos < lpLine->nLength )
				nPos++;
		}
		else if ( IsDelimiter( lpcd, lpLine->pcText [ nPos ] )) /* A delimiter? */
		{
			/*
			 *	Skip all delimiters and white spaces.
			 */
			while (( IsDelimiter( lpcd, lpLine->pcText[ nPos ] ) || _istspace( lpLine->pcText[ nPos ] )) && nPos < lpLine->nLength )
			{
				/*
				 *	White space?
				 */
				if ( _istspace( lpLine->pcText[ nPos ] ))
					/*
					 *	Yes. Break on the next non-white space.
					 */
					bBreakOnNonSpace = TRUE;
				else if ( bBreakOnNonSpace )
					/*
					 *	Stop at this non-white space.
					 */
					break;
				nPos++;
			}
		}
		else
		{
			/*
			 *	Skip all non delimiters and white spaces.
			 */
			while (( IsDelimiter( lpcd, lpLine->pcText[ nPos ] ) == FALSE || _istspace( lpLine->pcText[ nPos ] )) && nPos < lpLine->nLength )
			{
				/*
				 *	White space?
				 */
				if ( _istspace( lpLine->pcText[ nPos ] ))
					/*
					 *	Yes. Break on the next non-white space.
					 */
					bBreakOnNonSpace = TRUE;
				else if ( bBreakOnNonSpace )
					/*
					 *	Stop at this non-white space.
					 */
					break;
				nPos++;
			}
		}

		/*
		 *	Store position.
		 */
		lpcd->ptCaretPos.x = nPos;
	}

	/*
	 *	Save this position.
	 */
	lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x );

	/*
	 *	Make sure the caret is in the view.
	 */
	MakeCaretVisible( lpcd );

	/*
	 *	Update caret position.
	 */
	UpdateCaret( lpcd );
}
Exemplo n.º 11
0
void HandleCommand(char *line,int* curPos,opcode thisOpcode,char* label)
{
	BinaryMachineCode bmc;
	int decimal;
	char *binaryValue=NULL,*base12code=NULL,*param1=NULL,*param2=NULL;
	int addressingType1=NULL,addressingType2=NULL;
	enum Boolean errorFound=FALSE;
	Cmd tempCommand;
		char* errmsg=NULL;


	switch(thisOpcode.operand_count)
	{
	case 0:
		param1=ReadWord(line,curPos,' ');
		if(param1==NULL)
			FIX_NULL_STRING(param1);
		param1=StringTrim(param1);

		if(strlen(param1)>0 && IsDelimiter(param1[0],' ')==FALSE)
		{
			ALLOCATE_STRING(errmsg,50);
			strcpy(errmsg,thisOpcode.op);

			strcat(errmsg," - too many arguments for command ");
			ErrorHandler(CompilingError,errmsg);
			printf("b");
			return;
		}
		decimal=OctalToDecimal(thisOpcode.value_8);
		FIX_NULL_STRING(binaryValue);

		strcpy(binaryValue,ConvertIntToCharByBase(0,ConversionToBmcType,2));
		bmc = CreateBmcCode(binaryValue);

		bmc=AlterBmcValue(BmcOperationCode,OctalToDecimal(thisOpcode.value_8),bmc);
		/*strcpy(,convertBinaryMachineCodeToString(bmc,PrintStyle));

		strcpy(binaryValue,ConvertIntToCharByBase(decimal,ConversionToBmcType,2));
		ALLOCATE_STRING(bmcString,BMC_LENGTH+2);
		strcpy(bmcString,binaryValue);
		for(i=strlen(binaryValue);i<BMC_LENGTH;i++)
			bmcString[i]='0';
		bmcString[i]='\0';
		*/
		FIX_NULL_STRING(label);
		/*bmc=CreateBmcCode(bmcString);*/
		FIX_NULL_STRING(base12code);
		strcpy(base12code,ConvertBinaryStringToBase12(convertBinaryMachineCodeToString(bmc,BmcStyle)));
		tempCommand=CreateCmdObject(label,ConvertIntToCharByBase(IC,ConversionToAddress,10),ConvertIntToCharByBase(IC,ConversionToAddress,12),thisOpcode.op,"",bmc,base12code,'a');
		IC++;
		CmdQueue_AddRecord(tempCommand,computerLanguage);
		break;
	case 1:
		param2=ReadWord(line,curPos,' ');
		if(param2==NULL)
		{
			ALLOCATE_STRING(errmsg,50);
			strcpy(errmsg,thisOpcode.op);
			strcat(errmsg," - too few arguments for command ");
			ErrorHandler(CompilingError,errmsg);
			return;
		}
		addressingType2=IdentifyAddressing(param2);
		if(IsAddressingAllowedForCommand(addressingType2, thisOpcode.adddressing_type_dst)==FALSE)
		{
			ErrorHandler(CompilingError,"operand is not allowed for this command");
			errorFound=TRUE;
			return;
		}
		param1=ReadWord(line,curPos,' ');
		if(param1!=NULL && strlen(param1)>0)
		{
			ALLOCATE_STRING(errmsg,50);
			strcpy(errmsg,thisOpcode.op);
			strcat(errmsg," - too many arguments for command ");
			ErrorHandler(CompilingError,errmsg);
			return;
		}
		CreateBmcForCommand(line,label,thisOpcode,param1,param2,NULL,addressingType2);
		break;
	case 2:
		param1=ReadWord(line,curPos,' ');
		param2=ReadWord(line,curPos,' ');
		if(param1==NULL || param2==NULL)
		{
			ALLOCATE_STRING(errmsg,50);
			strcpy(errmsg,thisOpcode.op);
			strcat(errmsg," - too few arguments for command: ");
			ErrorHandler(CompilingError,errmsg);
			return;
		}
		if(ReadWord(line,curPos,' ') !=NULL)
		{
			ALLOCATE_STRING(errmsg,50);
			strcpy(errmsg,thisOpcode.op);
			strcat(errmsg," - too many arguments for command: ");
			ErrorHandler(CompilingError,errmsg);
			return;
		}
		addressingType1=IdentifyAddressing(param1);/* source */ 
		addressingType2=IdentifyAddressing(param2);/* destination */



		if(IsAddressingAllowedForCommand(addressingType1, thisOpcode.adddressing_type_src)==FALSE)
		{
			ErrorHandler(CompilingError,"operand is not allowed for this command");
			errorFound=TRUE;
		}
		if(IsAddressingAllowedForCommand(addressingType2, thisOpcode.adddressing_type_dst)==FALSE)
		{
			errorFound=TRUE;
			ErrorHandler(CompilingError,"operand is not allowed for this command");
		}
			
		if(errorFound==TRUE)
			return;
		
		CreateBmcForCommand(line,label,thisOpcode,param1,param2,addressingType1,addressingType2);
		
		break;
	default:
		break;
	
	}
}
Exemplo n.º 12
0
char *ReadWord(char *text,int* curLoc,char specificDelimiter) /* white space fix (bug fix: input changed to "by reference") */
{
	char *tempItem=NULL,*tempText=NULL;
	enum Boolean delimiterFound=FALSE,inQuotes=FALSE;
	int i,newstr_index=0,t;
	/*if(specificDelimiter==NULL)
		specificDelimiter=' ';*/
	if(text==NULL || strlen(text)==0)
		return NULL;
	tempText = StringTrim(text+(*curLoc));
		if(strlen(tempText)==0 || *curLoc>strlen(text))
			return NULL;
		t=strlen(tempText);
		for(i=0;IsDelimiter(tempText[i],' ')==TRUE && i<strlen(tempText);i++,(*curLoc)++)
		{
			continue;
		}
		tempText+=i;
		for(i=0;delimiterFound==FALSE;i++)
		{
			if(tempText[i]=='\"')
				if(inQuotes==TRUE)
					inQuotes=FALSE;
				else		
					inQuotes=TRUE;
			else
					if(IsDelimiter(tempText[i],specificDelimiter)==TRUE)
						{
							delimiterFound=TRUE;
							if(i==0)
							{
								delimiterFound=FALSE;
								continue;
							}							
							if(tempText[i]==':')
							{
								ALLOCATE_STRING(tempItem,++newstr_index);
									tempItem[newstr_index-1]=tempText[i];
									i++;
							}
							else if(tempText[i]==' ' && inQuotes==TRUE)
							{
							delimiterFound=FALSE;
								ALLOCATE_STRING(tempItem,++newstr_index);
									tempItem[newstr_index-1]=tempText[i];
								continue;
							}
							ALLOCATE_STRING(tempItem,++newstr_index);
							tempItem[newstr_index-1]='\0';	
							break;
						
						}
				
			if(delimiterFound==FALSE)
			{
								ALLOCATE_STRING(tempItem,++newstr_index);
									tempItem[newstr_index-1]=tempText[i];
			}
		}
	
		if(tempText[i-1]!=':')
			(*curLoc)+=++i;
		else
			(*curLoc)+=i++; /* include the ':' in the return string to identify it as a label */

		return tempItem;


}
Exemplo n.º 13
0
// native sscanf(const data[], const format[], (Float,_}:...);
static cell AMX_NATIVE_CALL
	n_sscanf(AMX * amx, cell * params)
{
	if (g_iTrueMax == 0)
	{
		logprintf("sscanf error: System not initialised.");
		return SSCANF_FAIL_RETURN;
	}
	// Friendly note, the most complex set of specifier additions is:
	// 
	//  A<i>(10, 11)[5]
	// 
	// In that exact order - type, default, size.  It's very opposite to how
	// it's done in code, where you would do the eqivalent to:
	// 
	//  <i>[5] = {10, 11}
	// 
	// But this method is vastly simpler to parse in this context!  Technically
	// you can, due to legacy support for 'p', do:
	// 
	//  Ai(10, 11)[5]
	// 
	// But you will get an sscanf warning, and I may remove that ability from
	// the start - that will mean a new function, but an easy to write one.
	// In fact the most complex will probably be something like:
	// 
	//  E<ifs[32]s[8]d>(10, 12.3, Hello there, Hi, 42)
	// 
	// Get the number of parameters passed.  We add one as the indexes are out
	// by one (OBOE - Out By One Error) due to params[0] being the parameter
	// count, not an actual parameter.
	const int
		paramCount = ((int)params[0] / 4) + 1;
	// Could add a check for only 3 parameters here - I can't think of a time
	// when you would not want any return values at all, but that doesn't mean
	// they don't exist - you could just want to check but not save the format.
	// Update - that is now a possibility with the '{...}' specifiers.
	if (paramCount < (2 + 1))
	{
		logprintf("sscanf error: Missing required parameters.");
		return SSCANF_FAIL_RETURN;
	}
	//else if (paramCount == (2 + 1))
	//{
		// Only have an input and a specifier - better hope the whole specifier
		// is quite (i.e. enclosed in '{...}').
	//}
	// Set up function wide values.
	// Get and check the main data.
	// Pointer to the current input data.
	char *
		string;
	STR_PARAM(amx, params[1], string);
	// Pointer to the current format specifier.
	char *
		format;
	STR_PARAM(amx, params[2], format);
	// Check for CallRemoteFunction style null strings and correct.
	if (string[0] == '\1' && string[1] == '\0')
	{
		string[0] = '\0';
	}
	// Current parameter to save data to.
	int
		paramPos = 3;
	cell *
		cptr;
	InitialiseDelimiter();
	// Skip leading space.
	SkipWhitespace(&string);
	bool
		doSave;
	// Code for the rare cases where the WHOLE format is quiet.
	if (*format == '{')
	{
		++format;
		doSave = false;
	}
	else
	{
		doSave = true;
	}
	// Now do the main loop as long as there are variables to store the data in
	// and input string remaining to get the data from.
	while (*string && (paramPos < paramCount || !doSave))
	{
		if (!*format)
		{
			// End of the format string - if we're here we've got all the
			// parameters but there is extra string or variables, which may
			// indicate their code needs fixing, for example:
			// sscanf(data, "ii", var0, var1, var3, var4);
			// There is only two format specifiers, but four returns.  This may
			// also be reached if there is too much input data, but that is
			// considered OK as that is likely a user's fault.
			if (paramPos < paramCount)
			{
				logprintf("sscanf warning: Format specifier does not match parameter count.");
			}
			if (!doSave)
			{
				// Started a quiet section but never explicitly ended it.
				logprintf("sscanf warning: Unclosed quiet section.");
			}
			return SSCANF_TRUE_RETURN;
		}
		else if (IsWhitespace(*format))
		{
			++format;
		}
		else
		{
			switch (*format++)
			{
				case 'L':
					DX(bool, L)
					// FALLTHROUGH
				case 'l':
					DOV(bool, L)
					break;
				case 'B':
					DX(int, B)
					// FALLTHROUGH
				case 'b':
					DO(int, B)
				case 'N':
					DX(int, N)
					// FALLTHROUGH
				case 'n':
					DO(int, N)
				case 'C':
					DX(char, C)
					// FALLTHROUGH
				case 'c':
					DO(char, C)
				case 'I':
				case 'D':
					DX(int, I)
					// FALLTHROUGH
				case 'i':
				case 'd':
					DO(int, I)
				case 'H':
				case 'X':
					DX(int, H)
					// FALLTHROUGH
				case 'h':
				case 'x':
					DO(int, H)
				case 'O':
					DX(int, O)
					// FALLTHROUGH
				case 'o':
					DO(int, O)
				case 'F':
					DXF(double, F)
					// FALLTHROUGH
				case 'f':
					DOF(double, F)
				case 'G':
					DXF(double, G)
					// FALLTHROUGH
				case 'g':
					DOF(double, G)
				case '{':
					if (doSave)
					{
						doSave = false;
					}
					else
					{
						// Already in a quiet section.
						logprintf("sscanf warning: Can't have nestled quiet sections.");
					}
					continue;
				case '}':
					if (doSave)
					{
						logprintf("sscanf warning: Not in a quiet section.");
					}
					else
					{
						doSave = true;
					}
					continue;
				case 'P':
					logprintf("sscanf warning: You can't have an optional delimiter.");
					// FALLTHROUGH
				case 'p':
					// 'P' doesn't exist.
					// Theoretically, for compatibility, this should be:
					// p<delimiter>, but that will break backwards
					// compatibility with anyone doing "p<" to use '<' as a
					// delimiter (doesn't matter how rare that may be).  Also,
					// writing deprecation code and both the new and old code
					// is more trouble than it's worth, and it's slow.
					// UPDATE: I wrote the "GetSingleType" code for 'a' and
					// figured out a way to support legacy and new code, while
					// still maintaining support for the legacy "p<" separator,
					// so here it is:
					ResetDelimiter();
					AddDelimiter(GetSingleType(&format));
					continue;
				case 'Z':
					logprintf("sscanf warning: 'Z' doesn't exist - that would be an optional, deprecated optional string!.");
					// FALLTHROUGH
				case 'z':
					logprintf("sscanf warning: 'z' is deprecated, consider using 'S' instead.");
					// FALLTHROUGH
				case 'S':
					if (IsDelimiter(*string))
					{
						char *
							dest;
						int
							length;
						if (DoSD(&format, &dest, &length))
						{
							// Send the string to PAWN.
							if (doSave)
							{
								amx_GetAddr(amx, params[paramPos++], &cptr);
								amx_SetString(cptr, dest, 0, 0, length);
							}
						}
						break;
					}
					// Implicit "else".
					SkipDefaultEx(&format);
					// FALLTHROUGH
				case 's':
					{
						// Get the length.
						int
							length = GetLength(&format, false);
						char *
							dest;
						DoS(&string, &dest, length, IsEnd(*format));
						// Send the string to PAWN.
						if (doSave)
						{
							amx_GetAddr(amx, params[paramPos++], &cptr);
							amx_SetString(cptr, dest, 0, 0, length);
						}
					}
					break;
				case 'U':
					DX(int, U)
					// FALLTHROUGH
				case 'u':
					DOV(int, U)
					break;
				case 'Q':
					DX(int, Q)
					// FALLTHROUGH
				case 'q':
					DOV(int, Q)
					break;
				case 'R':
					DX(int, R)
					// FALLTHROUGH
				case 'r':
					DOV(int, R)
					break;
				case 'A':
					// We need the default values here.
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoA(&format, &string, cptr, true))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						if (DoA(&format, &string, NULL, true))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case 'a':
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoA(&format, &string, cptr, false))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						if (DoA(&format, &string, NULL, false))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case 'E':
					// We need the default values here.
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoE(&format, &string, cptr, true))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						if (DoE(&format, &string, NULL, true))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case 'e':
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoE(&format, &string, cptr, false))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						if (DoE(&format, &string, NULL, false))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case 'K':
					// We need the default values here.
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoK(amx, &format, &string, cptr, true))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						if (DoK(amx, &format, &string, NULL, true))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case 'k':
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoK(amx, &format, &string, cptr, false))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						if (DoK(amx, &format, &string, NULL, false))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case '\'':
					// Find the end of the literal.
					{
						char
							* str = format,
							* write = format;
						bool
							escape = false;
						while (!IsEnd(*str) && (escape || *str != '\''))
						{
							if (*str == '\\')
							{
								if (escape)
								{
									// "\\" - Go back a step to write this
									// character over the last character (which
									// just happens to be the same character).
									--write;
								}
								escape = !escape;
							}
							else
							{
								if (*str == '\'')
								{
									// Overwrite the escape character with the
									// quote character.  Must have been
									// preceeded by a slash or it wouldn't have
									// got to here in the loop.
									--write;
								}
								escape = false;
							}
							// Copy the string over itself to get rid of excess
							// escape characters.
							// Not sure if it's faster in the average case to
							// always do the copy or check if it's needed.
							// This write is always safe as it makes the string
							// shorter, so we'll never run out of space.  It
							// will also not overwrite the original string.
							*write++ = *str++;
						}
						if (*str == '\'')
						{
							// Correct end.  Make a shorter string to search
							// for.
							*write = '\0';
							// Find the current section of format in string.
							char *
								find = strstr(string, format);
							if (!find)
							{
								// Didn't find the string
								return SSCANF_FAIL_RETURN;
							}
							// Found the string.  Update the current string
							// position to the length of the search term
							// further along from the start of the term.  Use
							// "write" here as we want the escaped string
							// length.
							string = find + (write - format);
							// Move to after the end of the search string.  Use
							// "str" here as we want the unescaped string
							// length.
							format = str + 1;
						}
						else
						{
							logprintf("sscanf warning: Unclosed string literal.");
							char *
								find = strstr(string, format);
							if (!find)
							{
								return SSCANF_FAIL_RETURN;
							}
							string = find + (write - format);
							format = str;
						}
					}
					break;
				case '%':
					logprintf("sscanf warning: sscanf specifiers do not require '%' before them.");
					continue;
				default:
					logprintf("sscanf warning: Unknown format specifier '%c', skipping.", *(format - 1));
					continue;
			}
			// Loop cleanup - only skip one spacer so that we can detect
			// multiple explicit delimiters in a row, for example:
			// 
			// hi     there
			// 
			// is NOT multiple explicit delimiters in a row (they're
			// whitespace).  This however is:
			// 
			// hi , , , there
			// 
			SkipOneSpacer(&string);
		}
	}
	// Temporary to the end of the code.
	ResetDelimiter();
	AddDelimiter(')');
	// We don't need code here to handle the case where paramPos was reached,
	// but the end of the string wasn't - if that's the case there's no
	// problem as we just ignore excess string data.
	while (paramPos < paramCount || !doSave)
	{
		// Loop through if there's still parameters remaining.
		if (!*format)
		{
			logprintf("sscanf warning: Format specifier does not match parameter count.");
			if (!doSave)
			{
				// Started a quiet section but never explicitly ended it.
				logprintf("sscanf warning: Unclosed quiet section.");
			}
			return SSCANF_TRUE_RETURN;
		}
		else if (IsWhitespace(*format))
		{
			++format;
		}
		else
		{
			// Do the main switch again.
			switch (*format++)
			{
				case 'L':
					DE(bool, L)
				case 'B':
					DE(int, B)
				case 'N':
					DE(int, N)
				case 'C':
					DE(char, C)
				case 'I':
				case 'D':
					DE(int, I)
				case 'H':
				case 'X':
					DE(int, H)
				case 'O':
					DE(int, O)
				case 'F':
					DEF(double, F)
				case 'G':
					DEF(double, G)
				case 'U':
					DE(int, U)
				case 'Q':
					DE(int, Q)
				case 'R':
					DE(int, R)
				case 'A':
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoA(&format, NULL, cptr, true))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						// Also pass NULL data so it knows to only collect the
						// default values.
						if (DoA(&format, NULL, NULL, true))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case 'E':
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoE(&format, NULL, cptr, true))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						// Also pass NULL data so it knows to only collect the
						// default values.
						if (DoE(&format, NULL, NULL, true))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case 'K':
					if (doSave)
					{
						amx_GetAddr(amx, params[paramPos++], &cptr);
						if (DoK(amx, &format, NULL, cptr, true))
						{
							break;
						}
					}
					else
					{
						// Pass a NULL pointer so data isn't saved anywhere.
						// Also pass NULL data so it knows to only collect the
						// default values.
						if (DoK(amx, &format, NULL, NULL, true))
						{
							break;
						}
					}
					return SSCANF_FAIL_RETURN;
				case '{':
					if (doSave)
					{
						doSave = false;
					}
					else
					{
						// Already in a quiet section.
						logprintf("sscanf warning: Can't have nestled quiet sections.");
					}
					break;
				case '}':
					if (doSave)
					{
						logprintf("sscanf warning: Not in a quiet section.");
					}
					else
					{
						doSave = true;
					}
					break;
				case 'Z':
					logprintf("sscanf warning: 'Z' doesn't exist - that would be an optional, deprecated optional string!.");
					// FALLTHROUGH
				case 'z':
					logprintf("sscanf warning: 'z' is deprecated, consider using 'S' instead.");
					// FALLTHROUGH
				case 'S':
					{
						char *
							dest;
						int
							length;
						if (DoSD(&format, &dest, &length))
						{
							// Send the string to PAWN.
							if (doSave)
							{
								amx_GetAddr(amx, params[paramPos++], &cptr);
								amx_SetString(cptr, dest, 0, 0, length);
							}
						}
					}
					break;
				case 'P':
					logprintf("sscanf warning: You can't have an optional delimiter.");
					// FALLTHROUGH
				case 'p':
					// Discard delimiter.  This only matters when they have
					// real inputs, not the default ones used here.
					GetSingleType(&format);
					continue;
				case '\'':
					// Implicitly optional if the specifiers after it are
					// optional.
					{
						bool
							escape = false;
						while (!IsEnd(*format) && (escape || *format != '\''))
						{
							if (*format == '\\')
							{
								escape = !escape;
							}
							else
							{
								escape = false;
							}
							++format;
						}
						if (*format == '\'')
						{
							++format;
						}
						else
						{
							logprintf("sscanf warning: Unclosed string literal.");
						}
					}
					break;
					// Large block of specifiers all together.
				case 'a':
				case 'b':
				case 'c':
				case 'd':
				case 'e':
				case 'f':
				case 'g':
				case 'h':
				case 'i':
				case 'k':
				case 'l':
				case 'n':
				case 'o':
				case 'q':
				case 'r':
				case 's':
				case 'u':
				case 'x':
					// These are non optional items, but the input string
					// didn't include them, so we fail - this is in fact the
					// most basic definition of a fail (the original)!  We
					// don't need any text warnings here - admittedly we don't
					// know if the format specifier is well formed (there may
					// not be enough return variables for example), but it
					// doesn't matter - the coder should have tested for those
					// things, and the more important thing is that the user
					// didn't enter the correct data.
					return SSCANF_FAIL_RETURN;
				case '%':
					logprintf("sscanf warning: sscanf specifiers do not require '%' before them.");
					break;
				default:
					logprintf("sscanf warning: Unknown format specifier '%c', skipping.", *(format - 1));
					break;
			}
			// Don't need any cleanup here.
		}
	}
	if (*format)
	{
		do
		{
			if (!IsWhitespace(*format))
			{
				// Only print this warning if the remaining characters are not
				// spaces - spaces are allowed, and sometimes required, on the
				// ends of formats (e.g. to stop the final 's' specifier
				// collecting all remaining characters and only get one word).
				// We could check that the remaining specifier is a valid one,
				// but this is only a guide - they shouldn't even have other
				// characters IN the specifier so it doesn't matter - it will
				// point to a bug, which is the important thing.
				if (doSave)
				{
					if (*format == '}')
					{
						logprintf("sscanf warning: Not in a quiet section.");
					}
					else if (*format != '{')
					{
						// Fix the bad display bug.
						logprintf("sscanf warning: Format specifier does not match parameter count.");
					}
					// Only display it once.
					break;
				}
				else
				{
					if (*format == '}')
					{
						doSave = true;
					}
					else
					{
						logprintf("sscanf warning: Format specifier does not match parameter count.");
						break;
					}
				}
			}
			++format;
		}
		while (*format);
	}
	if (!doSave)
	{
		// Started a quiet section but never explicitly ended it.
		logprintf("sscanf warning: Unclosed quiet section.");
	}
	// No more parameters and no more format specifiers which could be read
	// from - this is a valid return!
	return SSCANF_TRUE_RETURN;
}
Exemplo n.º 14
0
/*
 *	Is this the end of a block?
 */
static BOOL BlockEnd( LPCLASSDATA lpcd, LPBLOCK lpb, TCHAR *pcText, int nIndex, int nLength )
{
	/*
	 *	End String valid?
	 */
	if ( lpb->nEnd || lpb->pszEnd == END_OF_LINE )
	{
		/*
		 *	Block terminator at eol?
		 */
		if ( lpb->pszEnd == END_OF_LINE )
		{
			if ( nIndex == nLength )
			{
				/*
				 *	Match. Is it preceeded by an
				 *	escape character?
				 */
				if ( nIndex > 0 && Parser->cEscape && pcText[ nIndex - 1 ] == Parser->cEscape )
				{
					/*
					 *	Escape character escaped?
					 */
					if ( nIndex > 1 && Parser->cEscape && pcText[ nIndex - 2 ] == Parser->cEscape )
						/*
						 *	Still a match.
						 */
						 return TRUE;
					/*
					 *	This means no match.
					 */
					return FALSE;
				}

				/*
				 *	OK.
				 */
				return TRUE;
			}
		}
		/*
		 *	Is this the block terminator?
		 */
		else if ( ! ( Parser->bCaseOn ? _tcsncmp : _tcsnicmp )( lpb->pszEnd, &pcText[ nIndex ], lpb->nEnd ))
		{
			/*
			 *	Match. Is it preceeded by an
			 *	escape character?
			 */
			if ( nIndex > 0 && Parser->cEscape && pcText[ nIndex - 1 ] == Parser->cEscape )
			{
				/*
				 *	Escape character escaped?
				 */
				if ( nIndex > 1 && Parser->cEscape && pcText[ nIndex - 2 ] == Parser->cEscape )
					/*
					 *	Still a match.
					 */
					 return TRUE;

				/*
				 *	This means no match.
				 */
				return FALSE;
			}

			/*
			 *	Match!
			 */
			return TRUE;
		}
	}
	/*
	 *	If we do not have a block terminator we
	 *	terminate the block at the first white
	 *	space/delimiter or at the end of the line.
	 */
	else if ( nIndex == nLength )
		/*
		 *	End the block.
		 */
		return TRUE;
	else if ( nIndex < nLength && ( _istspace( pcText[ nIndex ] ) || IsDelimiter( lpcd, pcText[ nIndex ] )))
		/*
		 *	End the block.
		 */
		return TRUE;

	return FALSE;
}
Exemplo n.º 15
0
unsigned int CubeLexer::GetNextLexeme()
{
	int iLem=0;
	char chBegin;
		if (m_Sources[m_SourceOffset]=='\0')
		{
			//printf("<End>\n");
			m_Symbol='0';
			m_CurLexeme[0]='\0';
			return CUBE_LEXER_LEXEME_TYPE_END;
		}
		if (IsSpacer(m_Sources[m_SourceOffset]))
		{
			m_Symbol=m_Sources[m_SourceOffset];
			m_CurLexeme[0]=m_Sources[m_SourceOffset];
			m_CurLexeme[1]='\0';
			m_SourceOffset++;
			//printf("<Spacer>\n");
			return CUBE_LEXER_LEXEME_TYPE_SPACER;
		}

		if (IsNewLine(m_Sources[m_SourceOffset]))
		{
			m_Symbol=m_Sources[m_SourceOffset];
			m_CurLexeme[0]=m_Sources[m_SourceOffset];
			m_CurLexeme[1]='\0';
			m_SourceOffset++;
			//printf("<New line>\n");
			return CUBE_LEXER_LEXEME_TYPE_NEWLINE;
		}
		if (IsContainerStart((chBegin=m_Sources[m_SourceOffset])))
		{
			iLem=0;
			m_CurLexeme[iLem++]=m_Sources[m_SourceOffset];
			m_SourceOffset++;
			while (!IsSourcsEnd()&&!IsContainerEnd(chBegin,m_Sources[m_SourceOffset]))
			{
				m_CurLexeme[iLem++]=m_Sources[m_SourceOffset++];
			}
			m_CurLexeme[iLem++]=m_Sources[m_SourceOffset];
			m_CurLexeme[iLem]='\0';
			m_SourceOffset++;

			//printf("<Container> %s\n",m_CurLexeme);
			return CUBE_LEXER_LEXEME_TYPE_CONATINER;
		}

		if (IsDelimiter(m_Sources[m_SourceOffset]))
		{
			m_Symbol=m_Sources[m_SourceOffset];
			m_CurLexeme[0]=m_Sources[m_SourceOffset];
			m_CurLexeme[1]='\0';
			//printf("<Delimiter> %c\n",m_Sources[m_SourceOffset]);
			m_SourceOffset++;
			return CUBE_LEXER_LEXEME_TYPE_DELIMITER;
		}
		iLem=0;
		m_Symbol='\0';
		while (!IsSourcsEnd()&&!IsDelimiter(m_Sources[m_SourceOffset])&&!IsSpacer(m_Sources[m_SourceOffset])&&!IsNewLine(m_Sources[m_SourceOffset])&&!IsContainerStart(m_Sources[m_SourceOffset]))
		{
			m_CurLexeme[iLem++]=m_Sources[m_SourceOffset++];
		}
		m_CurLexeme[iLem]='\0';
		//printf("<Token> %s\n",m_CurLexeme);
	return CUBE_LEXER_LEXEME_TYPE_TOKEN;
}
Exemplo n.º 16
0
static void MovePrevWord( LPCLASSDATA lpcd )
{
	/*
	 *	Obtain current caret column and
	 *	the line were on.
	 */
	int	nPos = lpcd->ptCaretPos.x;
	LPLINE	lpLine = GETLINE( lpcd );

	/*
	 *	Are we at the start of the line?
	 */
	if ( nPos == 0 )
	{
		/*
		 *	Yes go down one line and to the
		 *	end of that line.
		 */
		if ( lpcd->ptCaretPos.y > 0 )
		{
			/*
			 *	Go up.
			 */
			lpcd->ptCaretPos.y--;

			/*
			 *	Put the caret at the end.
			 */
			lpcd->ptCaretPos.x = GETLINE( lpcd )->nLength;

			if ( lpcd->ptCaretPos.x )
				/*
				 *	Recursivly call ourselves.
				 */
				MovePrevWord( lpcd );
		}
	}
	else
	{
		/*
		 *	Previous character.
		 */
		nPos--;

		/*
		 *	Are we on a white space?
		 */
		if ( _istspace( lpLine->pcText[ nPos ] ))
		{
			/*
			 *	Skip spaces...
			 */
			while ( _istspace( lpLine->pcText[ nPos ] ) && nPos )
				nPos--;
		}

		/*
		 *	Start of the line?
		 */
		if ( nPos )
		{
			/*
			 *	Did we reach a delimiter?
			 */
			if ( IsDelimiter( lpcd, lpLine->pcText[ nPos ] )) /* A delimiter? */
			{
				/*
				 *	Skip all delimiters.
				 */
				while ( IsDelimiter( lpcd, lpLine->pcText[ nPos ] ))
				{
					/*
					 *	White space?
					 */
					if ( _istspace( lpLine->pcText[ nPos ] ))
						break;

					/*
					 *	Start of the line?
					 */
					if ( nPos == 0 )
					{
						/*
						 *	Will force the caret at position 0
						 */
						nPos = -1;
						break;
					}
					nPos--;
				}
				nPos++;
			}
			else
			{
				/*
				 *	Skip all non delimiters.
				 */
				while ( IsDelimiter( lpcd, lpLine->pcText[ nPos ] ) == FALSE )
				{
					/*
					 *	White space?
					 */
					if ( _istspace( lpLine->pcText[ nPos ] ))
						break;

					/*
					 *	Start of the line
					 */
					if ( nPos == 0 )
					{
						/*
						 *	Will force the caret at position 0
						 */
						nPos = -1;
						break;
					}
					nPos--;
				}
				nPos++;
			}
		}

		/*
		 *	Store position.
		 */
		lpcd->ptCaretPos.x = nPos;
	}

	/*
	 *	Save this position.
	 */
	lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x );

	/*
	 *	Make sure the care is in the view.
	 */
	MakeCaretVisible( lpcd );

	/*
	 *	Update caret position.
	 */
	UpdateCaret( lpcd );
}
Exemplo n.º 17
0
static
VOID
DoCommand(
    PCONSOLE_STATE State,
    LPSTR line)
{
    CHAR com[MAX_PATH]; /* the first word in the command */
    LPSTR cp = com;
//    LPSTR cstart;
    LPSTR rest = line; /* pointer to the rest of the command line */
//    INT cl;
    LPCOMMAND cmdptr;

    DPRINT1("DoCommand: (\'%s\')\n", line);

    /* Skip over initial white space */
    while (isspace(*rest))
        rest++;

//    cstart = rest;

    /* Anything to do ? */
    if (*rest)
    {
        /* Copy over 1st word as lower case */
        while (!IsDelimiter(*rest))
            *cp++ = tolower(*rest++);

        /* Terminate first word */
        *cp = '\0';

        /* Skip over whitespace to rest of line */
        while (isspace (*rest))
            rest++;

        /* Scan internal command table */
        for (cmdptr = Commands; ; cmdptr++)
        {
            /* If end of table execute ext cmd */
            if (cmdptr->name == NULL)
            {
                CONSOLE_ConOutPuts("Unknown command. Enter HELP to get a list of commands.");
                break;
            }

            if (stricmp(com, cmdptr->name) == 0)
            {
                cmdptr->func(State, rest);
                break;
            }

#if 0
            /* The following code handles the case of commands like CD which
             * are recognised even when the command name and parameter are
             * not space separated.
             *
             * e.g dir..
             * cd\freda
             */

            /* Get length of command name */
            cl = strlen(cmdptr->name);

            if ((cmdptr->flags & CMD_SPECIAL) &&
                (!strncmp (cmdptr->name, com, cl)) &&
                (strchr("\\.-", *(com + cl))))
            {
                /* OK its one of the specials...*/

                /* Call with new rest */
                cmdptr->func(State, cstart + cl);
                break;
            }
#endif
        }
    }
}
Exemplo n.º 18
0
int ParseLine( LPCLASSDATA lpcd, int nInBlock, TCHAR *pcText, int nLength, SYNTAX_COLOR *scColors, int *lpnBlocks, int nNumBlocks, int nLine )
{
	LPPARSER	lpp = Parser;
	LPKEYHASH	lpHash;
	LPBLOCK		lpBlock;
	COLORREF	crText = Parser->crColors[ CARR_TEXT ];
	int		nIndex = 0, nBlock = 0, nSize, i, nMatchX1 = 0, nMatchX2 = 0;
	BOOL		bContinue = FALSE, bStartOfLine = TRUE, bHasInit = FALSE;
  int nHyperLength;   // Modified by Stephan (2005-06-12)
                      // To allow unquoted paths with space like c:\program files
	
	/*
	 *	Compute match columns.
	 */
	if ( lpcd->ptBracket1.y >= 0 ) nMatchX1 = CaretOffsetLine( lpcd, lpcd->ptBracket1.y, lpcd->ptBracket1.x );
	if ( lpcd->ptBracket2.y >= 0 ) nMatchX2 = CaretOffsetLine( lpcd, lpcd->ptBracket2.y, lpcd->ptBracket2.x );

	/*
	 *	Any text to parse?
	 */
	if ( nLength == 0 )
		/*
		 *	Return the block we are in.
		 */
		 return nInBlock;

	/*
	 *	Start with a normal text
	 *	color block...
	 */
	if ( scColors )
	{
		/*
		 *	Enough text blocks?
		 */
		CHECK_BLOCKS;
		scColors[ nBlock ].nColumn   = nLength;
		scColors[ nBlock ].crColor   = crText;
		scColors[ nBlock ].crBgColor = CLR_DEFAULT;
		scColors[ nBlock ].pHash     = NULL;
		scColors[ nBlock ].wFlags    = 0;
	}

	/*
	 *	Parser active?
	 */
	if ( lpp == NULL )
	{
		/*
		 *	A single text color block.
		 */
		*lpnBlocks = 1;
		return -1;
	}

	/*
	 *	Are we in a block?
	 */
	if ( nInBlock != -1 )
	{
		/*
		 *	Get the block.
		 */
		lpBlock = ArrayGetAt( lpp->lpaBlocks, nInBlock );
		
		/*
		 *	Setup the color.
		 */
		if ( scColors )
		{
			/*
			 *	Enough text blocks?
			 */
			CHECK_BLOCKS;
			scColors[ nBlock ].nColumn   = nLength;
			scColors[ nBlock ].crColor   = lpBlock->crColor;
			scColors[ nBlock ].crBgColor = lpBlock->crBgColor;
			scColors[ nBlock ].pHash     = NULL;
			scColors[ nBlock ].wFlags    = 0;
		}

		/*
		 *	End the block with a string?
		 */
		if ( lpBlock->nEnd )
		{
			/*
			 *	See if the terminator string occures
			 *	on the line.
			 */
			LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( pcText, lpBlock->pszEnd );

			/*
			 *	Terminator found?
			 */
			if( pszStr == NULL )
			{
				/*
				 *	Are we parsing hyperlinks?
				 */
				if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
				{
					/*
					 *	Find all hyperlinks in the line starting
					 *	at offset 'nIndex'.
					 */
					*lpnBlocks = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, 0, nNumBlocks, lpnBlocks, scColors ) + 1;
					scColors[ *lpnBlocks - 1 ].nColumn = nLength;
				}
				else if ( lpnBlocks )
					/*
					 *	Uses a single block.
					 */
					*lpnBlocks = 1;

				/*
				 *	Remain in the text block.
				 */
				return nInBlock;
			}
			else if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
				/*
				 *	Find all hyperlinks from offset 'nIndex'
				 *	up to the block end marker.
				 */
				nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, ( int )( pszStr - pcText ), 0, nNumBlocks, lpnBlocks, scColors );

			/*
			 *	Skip to the index at which
			 *	the terminator was found.
			 */
			nIndex = ( int )( pszStr - pcText );
		}
	}
	else
	{
		/*
		 *	If we are not yet inside a block we determine
		 *	if any of the block initiators occure in this
		 *	line and, if so, at which offset.
		 */
		for ( i = 0; ; i++ )
		{
			/*
			 *	Get the block.
			 */
			lpBlock = ArrayGetAt( lpp->lpaBlocks, i );
			
			/*
			 *	Done?
			 */
			if ( lpBlock == NULL ) 
				break;

			/*
			 *	By default this block initiator is not on
			 *	this line.
			 */
			lpBlock->bInLine = FALSE;

			/*
			 *	Will the initiator fit at all?
			 */
			if ( lpBlock->nStart && lpBlock->nStart <= nLength )
			{
				/*
				 *	Look up the block initiator on the line.
				 */
				LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( pcText, lpBlock->pszStart );

				/*
				 *	Found?
				 */
				if ( pszStr != NULL )
				{
					/*
					 *	We have a block initializer.
					 */
					bHasInit = TRUE;

					/*
					 *	This block initiator is located 
					 *	on this line.
					 */
					lpBlock->bInLine = TRUE;
				}
			}
		}
	}
	
	/*
	 *	First we skip the leading blanks...
	 */
	while ( _istspace( pcText[ nIndex ] ) && nIndex <= nLength ) nIndex++;

	/*
	 *	Iterate text.
	 */
	for ( /*nIndex = 0*/; nIndex <= nLength; nIndex++ )
	{
		/*
		 *	Clear continue flag.
		 */
		bContinue = FALSE;

		/*
		 *	In a block?
		 */
		if ( nInBlock != -1 )
		{
			/*
			 *	Get block.
			 */
			lpBlock = ArrayGetAt( lpp->lpaBlocks, nInBlock );

			/*
			 *	Does the block terminate with a string?
			 */
			if ( lpBlock->nEnd )
			{
				/*
				 *	Does the terminator occure in the text?
				 */
				LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( &pcText[ nIndex ], lpBlock->pszEnd );
				
				/*
				 *	No. Return the block number.
				 */
				if ( pszStr == NULL )
				{
					/*
					 *	Are we parsing hyperlinks?
					 */
					if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
					{
						/*
						 *	Find the hyperlinks starting at offset 'nIndex'.
						 */
						*lpnBlocks = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, nBlock, nNumBlocks, lpnBlocks, scColors ) + 1;
						scColors[ *lpnBlocks - 1 ].nColumn = nLength;
					}
					else if ( lpnBlocks )
						/*
						 *	Store the block number. 
						 */
						*lpnBlocks = nBlock + 1;

					return nInBlock;
				}
				else if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
					/*
					 *	Find all hyperlinks from offset 'nIndex'
					 *	up to the block end marker.
					 */
					nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, ( int )( pszStr - pcText ), nBlock, nNumBlocks, lpnBlocks, scColors );

				/*
				 *	Skip through to the index at which the
				 *	terminator was found.
				 */
				nIndex = ( int )( pszStr - pcText );
			}

			/*
			 *	Will the terminator fit?
			 */
			if ( nLength - nIndex >= lpBlock->nEnd || lpBlock->pszEnd == END_OF_LINE )
			{
				/*
				 *	End a block?
				 */
				if ( BlockEnd( lpcd, lpBlock, pcText, nIndex, nLength ))
				{
					/*
					 *	Color array present?
					 */
					if ( scColors )
					{
						/*
						 *	Enough room?
						 */
						CHECK_BLOCKS;

						/*
						 *	Yes. Terminate current color.
						 */
						scColors[ nBlock++ ].nColumn = nIndex + lpBlock->nEnd;

						/*
						 *	Start a new color.
						 */
						scColors[ nBlock ].nColumn   = nLength;
						scColors[ nBlock ].crColor   = crText;
						scColors[ nBlock ].crBgColor = CLR_DEFAULT;
						scColors[ nBlock ].pHash     = NULL;
						scColors[ nBlock ].wFlags    = 0;
					}

					/*
					 *	Skip the block terminator.
					 */
					if ( lpBlock->pszEnd != END_OF_LINE ) nIndex += lpBlock->nEnd - 1;
					else				      nIndex = nLength;

					/*
					 *	No longer in the block.
					 */
					nInBlock = -1;
					
					/*
					 *	Continue parse...
					 */
					continue;
				}
			}
		}
		
		/*
		 *	Keep looking for the terminator if
		 *	we are still inside a block.
		 */
		if ( nInBlock != -1 )
		{
			if ( scColors && nIndex >= nLength )
				scColors[ nBlock ].nColumn = nIndex;
			continue;
		}

		/*
		 *	Do we have an initiator?
		 */
		if ( bHasInit )
		{
			/*
			 *	Look up the block
			 *	initiators.
			 */	
			for ( i = 0; ; i++ )
			{
				/*
				 *	Valid block?
				 */
				if (( lpBlock = ArrayGetAt( lpp->lpaBlocks, i )) == NULL )
					break;

				/*
				 *	Block initiator in this
				 *	line?
				 */
				if ( ! lpBlock->bInLine )
					continue;

				/*
				 *	Block found?
				 */
				if ( ! BlockStart( lpcd, lpBlock, pcText, nIndex, nLength, bStartOfLine ))
					continue;

				/*
				 *	Colors present?
				 */
				if ( scColors )
				{
					/*
					 *	Enough room?
					 */
					CHECK_BLOCKS;

					/*
					 *	Yes. Terminate current color.
					 */
					scColors[ nBlock++ ].nColumn = nIndex;

					/*
					 *	Start a new color.
					 */
					scColors[ nBlock ].nColumn   = nLength;
					scColors[ nBlock ].crColor   = lpBlock->crColor;
					scColors[ nBlock ].crBgColor = lpBlock->crBgColor;
					scColors[ nBlock ].pHash     = NULL;
					scColors[ nBlock ].wFlags    = 0;
				}

				/*
				 *	Mark us as being in the block.
				 */
				nInBlock = i;

				/*
				 *	Does this block terminate at eol?
				 */
				if ( lpBlock->pszEnd == END_OF_LINE )
				{
					/*
					 *	Look at the rest of the line
					 *	for hyperlinks.
					 */
					if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
						nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, nBlock, nNumBlocks, lpnBlocks, scColors );

					/*
					 *	Skip everything except
					 *	the last terminator length 
					 *	plus the escape character.
					 */
					nIndex = max( 0, nLength - 2 );
				}
				else
					/*
					 *	Skip the block initiator.
					 */
					nIndex += lpBlock->nStart - 1;

				/*
				 *	Break the loop and
				 *	continue parsing.
				 */
				bContinue = TRUE;
				break;
			}
		}

		/*
		 *	No longer at the start
		 *	of the line...
		 */
		bStartOfLine = FALSE;

		/*
		 *	Continue?
		 */
		if ( bContinue || scColors == NULL )
			continue;

		/*
		 *	Skip spaces.
		 */
		if ( _istspace( pcText[ nIndex ] ))
		{
			/*
			 *	Make a new block.
			 */
			if ( scColors[ nBlock ].crBgColor != CLR_DEFAULT ||
			     scColors[ nBlock ].crColor   != crText ||
			     scColors[ nBlock ].wFlags )
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup new color.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = CLR_DEFAULT;
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}
			continue;
		}
	
		if ( Parser->bParseHyperLinks && scColors )
		{
      nHyperLength = IsHyperlink( pcText, nIndex, nLength );    // Modified by Stephan (2005-06-12)

      if (nHyperLength)
      {
			  /*
			  *	Enough room?
			  */
			  CHECK_BLOCKS;

			  /*
			  *	Yes. Terminate current color.
			  */
			  scColors[ nBlock++ ].nColumn = nIndex;

			  /*
			  *	Start a new color.
			  */
			  scColors[ nBlock ].nColumn   = nLength;
			  scColors[ nBlock ].crColor   = Parser->crColors[ CARR_HYPERLINK ];
			  scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_HYPERLINK ];
			  scColors[ nBlock ].pHash     = NULL;
			  scColors[ nBlock ].wFlags    = SCF_HYPERLINK;

			  /*
			  *	Is it a quoted hyperlink?
			  */
			  if ( nIndex && (pcText[ nIndex - 1 ] == _T( '"' ) || pcText[ nIndex - 1 ] == _T( '\'' )))   // Modified by Stephan (2005-05-30)
			  {
				  /*
				  *	Look up the next quote.
				  */
				  while ( nIndex < nLength && pcText[ nIndex ] != _T( '"' ) && pcText[ nIndex ] != _T( '\'' ))   // Modified by Stephan (2005-05-30)
            nIndex++;
				  if ( pcText[ nIndex ] == _T( '"' ) || pcText[ nIndex ] == _T( '\'' ))   // Modified by Stephan (2005-05-30)
            nIndex--;
			  }
			  else
			  {
				  /*
				  *	Look up the next white space.
				  */
          nIndex += nHyperLength;   // Modified by Stephan
				  while ( nIndex < nLength && ! _istspace( pcText[ nIndex ] ) &&
                  pcText[ nIndex ] != _T('(') && pcText[ nIndex ] != _T(',') &&
                  pcText[ nIndex ] != _T(';') && pcText[ nIndex ] != _T(')') &&
                  pcText[ nIndex ] != _T('\''))   // Modified by Stephan (2005-05-28)
            nIndex++;
				  if ( _istspace( pcText[ nIndex ] ) ||
              pcText[ nIndex ] == _T('(') || pcText[ nIndex ] == _T(',') ||
              pcText[ nIndex ] == _T(';') || pcText[ nIndex ] == _T(')') ||
              pcText[ nIndex ] == _T('\''))   // Modified by Stephan (2005-05-28)
            nIndex--;
			  }
			  continue;
      }
		}

		/*
		 *	Delimiter?
		 */
		if ( IsDelimiter( lpcd, pcText[ nIndex ] ))
		{
			/*
			 *	Any change in color?
			 */
			if (( scColors[ nBlock ].crColor   != Parser->crColors[ CARR_DELIMITER ] ) ||
			    ( scColors[ nBlock ].crBgColor != Parser->crColors[ CARR_BACKGROUND_DELIMITER ] ) ||
			    ( scColors[ nBlock ].wFlags ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup delimiter color.
				 */
				scColors[ nBlock ].crColor   = Parser->crColors[ CARR_DELIMITER ];
				scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_DELIMITER ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}

			/*
			 *	Do we have matched brackets?
			 */
			if (( nLine == lpcd->ptBracket1.y && nIndex == nMatchX1 ) ||
			    ( nLine == lpcd->ptBracket2.y && nIndex == nMatchX2 ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup match color.
				 */
				scColors[ nBlock ].crColor   = scColors[ nBlock - 1 ].crColor;
				scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}

			/*
			 *	Continue parsing.
			 */
			continue;
		} 
		else
		/*
		 *	Is it a number? This check is a bit
		 *	to simple but it should not pose
		 *	any problems...
		 */
		if ( _istdigit( pcText[ nIndex ] ))
		{
			/*
			 *	Color changes?
			 */
			if (( scColors[ nBlock ].crColor   != Parser->crColors[ CARR_NUMBER ] ) ||
			    ( scColors[ nBlock ].crBgColor != Parser->crColors[ CARR_BACKGROUND_NUMBER ] ) ||
			    ( scColors[ nBlock ].wFlags ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate the current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup the number colors.
				 */
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].crColor   = Parser->crColors[ CARR_NUMBER ];
				scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_NUMBER ];
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}
		}
		else
		{
			/*
			 *	Do we have bracket matches?
			 */
			if (( nLine == lpcd->ptBracket1.y && nIndex == nMatchX1 ) ||
			    ( nLine == lpcd->ptBracket2.y && nIndex == nMatchX2 ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup match color.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;

				/*
				 *	Continue parsing.
				 */
				continue;
			}
			else if ( scColors[ nBlock ].crColor   != crText ||
				  scColors[ nBlock ].crBgColor != CLR_DEFAULT ||
				  scColors[ nBlock ].wFlags )
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;
		
				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup text color.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = CLR_DEFAULT;
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}
		}

		/*
		 *	Count the characters up until
		 *	the next space or delimiter.
		 */
		nSize = nIndex;
		while ( nSize < nLength && ! _istspace( pcText[ nSize ] ) && ! IsDelimiter( lpcd, pcText[ nSize ] ))
		{
			/*
			 *	Do we have bracket matches?
			 */
			if (( nLine == lpcd->ptBracket1.y && nSize == nMatchX1 ) ||
			    ( nLine == lpcd->ptBracket2.y && nSize == nMatchX2 ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nSize;

				/*
				 *	Setup match colors.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;

				/*
				 *	Continue parsing.
				 */
				break;
			}
			nSize++;
		}

		/*
		 *	Is the previous character a space/delimiter or are
		 *	we at the start of the line?
		 */
		if ( nIndex == 0 || _istspace( pcText[ nIndex - 1 ] ) || IsDelimiter( lpcd, pcText[ nIndex - 1 ] ))
		{
			/*
			 *	Is it a keyword
			 */
			if (( lpHash = IsKeyword( lpcd, &pcText[ nIndex ], nSize - nIndex )) != NULL )
			{
				/*
				 *	Color changes?
				 *	NOTE: Removed to accomodate case-fixing.
				 */
				/*if ( scColors[ nBlock ].crColor != lpHash->crColor )*/
				{
					/*
					 *	Enough room?
					 */
					CHECK_BLOCKS;

					/*
					 *	Terminate the current color.
					 */
					scColors[ nBlock++ ].nColumn = nIndex;

					/*
					 *	Setup the keyword color and the hash. We use the hash
					 *	when a text line is edited to fix the casing when 
					 *	case-fixing is turned on.
					 */
					scColors[ nBlock ].nColumn   = nLength;
					scColors[ nBlock ].crColor   = lpHash->crColor;
					scColors[ nBlock ].crBgColor = lpHash->crBkColor;
					scColors[ nBlock ].pHash     = lpHash;
					scColors[ nBlock ].wFlags    = 0;
				}
			}
		}

		/*
		 *	Are we at the end?
		 */
		if ( nSize >= nLength )
			break;

		/*
		 *	Adjust the index.
		 */
		nIndex = nSize - 1;
	}

	/*
	 *	Store the number of syntax
	 *	color block that are valid.
	 */
	if ( lpnBlocks )
		*lpnBlocks = nBlock + 1;

	return nInBlock;
}
Exemplo n.º 19
0
bool WLex::IsSpecial(int ch) const
{
    return IsDelimiter(ch) || IsEscape(ch) || ch == '\n';
}