bool TParser::GetToken() { curToken = _T(""); if(pos >= expr.GetLength()) { curToken = _T(""); typToken = PARSER_END; return true; } while(IsSpace()) pos++; if(IsDelim()) { curToken = expr[pos++]; switch(curToken[0]) { case _T('+'): typToken = PARSER_PLUS; return true; case _T('-'): typToken = PARSER_MINUS; return true; case _T('*'): typToken = PARSER_MULTIPLY; return true; case _T('/'): typToken = PARSER_DIVIDE; return true; case _T('%'): typToken = PARSER_PERCENT; return true; case _T('^'): typToken = PARSER_POWER; return true; case _T('['): case _T('('): typToken = PARSER_L_BRACKET; return true; case _T(']'): case _T(')'): typToken = PARSER_R_BRACKET; return true; } } else if(IsComma()) { curToken = expr[pos++]; typToken = PARSER_COMMA; return true; } else if(IsLetter()) { int i=0; curToken = _T(""); while(IsLetter() || IsDigit()) curToken += expr[pos++]; curToken.MakeLower(); if(curToken == _T("pi")) { typToken = PARSER_PI; return true; } else if(curToken == _T("e")) { typToken = PARSER_E; return true; } else if(curToken == _T("sin")) { typToken = PARSER_SIN; return true; } else if(curToken == _T("cos")) { typToken = PARSER_COS; return true; } else if(curToken == _T("tg")) { typToken = PARSER_TG; return true; } else if(curToken == _T("ctg")) { typToken = PARSER_CTG; return true; } else if(curToken == _T("arcsin")) { typToken = PARSER_ARCSIN; return true; } else if(curToken == _T("arccos")) { typToken = PARSER_ARCCOS; return true; } else if(curToken == _T("arctg")) { typToken = PARSER_ARCTG; return true; } else if(curToken == _T("arcctg")) { typToken = PARSER_ARCCTG; return true; } else if(curToken == _T("sh")) { typToken = PARSER_SH; return true; } else if(curToken == _T("ch")) { typToken = PARSER_CH; return true; } else if(curToken == _T("th")) { typToken = PARSER_TH; return true; } else if(curToken == _T("cth")) { typToken = PARSER_CTH; return true; } else if(curToken == _T("exp")) { typToken = PARSER_EXP; return true; } else if(curToken == _T("lg")) { typToken = PARSER_LG; return true; } else if(curToken == _T("ln")) { typToken = PARSER_LN; return true; } else if(curToken == _T("sqrt")) { typToken = PARSER_SQRT; return true; } else if(curToken == _T("abs")) { typToken = PARSER_ABS; return true; } else if(curToken == _T("min")) { typToken = PARSER_MIN; return true; } else if(curToken == _T("max")) { typToken = PARSER_MAX; return true; } else if(curToken == _T("atan2")) { typToken = PARSER_ATAN2; return true; } else if(curToken == _T("if")) { typToken = PARSER_IF; return true; } else if(curToken == _T("left")) { typToken = PARSER_GUIDE; return true; } else if(curToken == _T("right")) { typToken = PARSER_GUIDE; return true; } else if(curToken == _T("top")) { typToken = PARSER_GUIDE; return true; } else if(curToken == _T("bottom")) { typToken = PARSER_GUIDE; return true; } else if(curToken == _T("width")) { typToken = PARSER_GUIDE; return true; } else if(curToken == _T("height")) { typToken = PARSER_GUIDE; return true; } else SendError(0); } else if(IsAdjust()) { int i=0; curToken = _T(""); while((!IsSpace())&&(!IsDelim())) curToken += expr[pos++]; typToken = PARSER_ADJUST; return true; } else if(IsGuide()) { int i=0; curToken = _T(""); while((!IsSpace())&&(!IsDelim())) curToken += expr[pos++]; typToken = PARSER_GUIDE; return true; } else if(IsDigit() || IsPoint()) { int i=0; curToken = _T(""); while(IsDigit()) curToken += expr[pos++]; if(IsPoint()) { curToken += expr[pos++]; while(IsDigit()) curToken += expr[pos++]; } typToken = PARSER_NUMBER; return true; } else { curToken = expr[pos++]; SendError(1); } return false; }
static BOOLEAN Optional_Query_Parameters(LIST Tokens, pQueryStruct pQueryParameters, pSTRING pCommandLine) { Token CurrentToken; /* Used to hold the token being examined. */ CARDINAL Error = 0; /* Used to hold the error return code from LIST operations. */ BOOLEAN ReturnValue = FALSE; /* Used to hold the function return value. */ pSTRING pDriveName = NULL; pSTRING pFilesystemType = NULL; pSTRING pDriveNumber = NULL; pSTRING pNumber = NULL; unsigned int TokenPosition; /* Get the current token so that we can examine it. */ GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( !Error ) { if (CurrentToken.TokenType == All_CLI) { pQueryParameters->NameType = AllNameType; NextToken(Tokens, &Error); ReturnValue = TRUE; } else { /* If it is a drive number */ if ( Drive_Number(Tokens, &pDriveNumber) ) { pQueryParameters->NameType = DriveNumberType; pQueryParameters->pName = pDriveNumber; ReturnValue = TRUE; } else { if ( Drive_Name(Tokens, SemiColon, &pDriveName) ) { pQueryParameters->NameType = DriveNameType; pQueryParameters->pName = pDriveName; ReturnValue = TRUE; } else { ReportParseError(Expected_ALL_or_Drive_Number_or_Name, Tokens, pCommandLine); return ReturnValue; } /* endif */ } /* endif */ } /* endif */ /* If the next token is a comma, the following token */ /* must be a valid filesystem type. */ SkipOptionalWhitespace(Tokens); GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( !Error ) { if ( IsComma(Tokens) ) { SkipOptionalWhitespace(Tokens); GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( !Error) { /* The token following the comma must be filesystem type */ if ( Acceptable_Name(Tokens, SemiColon, &pFilesystemType) ) { pQueryParameters->pFileSystemType = pFilesystemType; ReturnValue = TRUE; } else { /* A number is also acceptable as a filesystem type */ if (CurrentToken.TokenType == Number) { pNumber = (pSTRING) malloc(strlen(CurrentToken.pTokenText)+1); if (pNumber != NULL) { pQueryParameters->pFileSystemType = pNumber; strcpy(pNumber, CurrentToken.pTokenText); NextToken(Tokens, &Error); ReturnValue = TRUE; } else { ReportError(Not_Enough_Memory); ReturnValue = FALSE; return ReturnValue; } /* endif */ } else { ReturnValue = FALSE; ReportParseError(Expected_File_System_Type, Tokens, pCommandLine); } /* endif */ } /* endif */ } /* endif */ } else { /* Since we wouldn't have reached this point if the required */ /* portion of the rule had not been satisfied above, then */ /* we have satisfied the optional query parameters rule even */ /* without the optional comma and filesytem type. */ ReturnValue = TRUE; } /* endif */ } /* endif */ } /* endif */ /* Report any errors accessing the token list as an internal error! */ if ( Error ) ReportError(Internal_Error); return ReturnValue; }
BOOLEAN Deletion_Parameters(LIST Tokens, pDeletionStruct pDeletionParameters, pSTRING pCommandLine) { Token CurrentToken; /* Used to hold the token being examined. */ CARDINAL Error = 0; /* Used to hold the error return code from LIST operations. */ BOOLEAN ReturnValue = FALSE; /* Used to hold the function return value. */ pSTRING pDriveName = NULL; pSTRING pPartitionName = NULL; pSTRING pDriveNumber = NULL; pSTRING pVolumeName = NULL; unsigned int TokenPosition; /* Get the current token so that we can examine it. */ GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( Error ) { /* Report any errors accessing the token list as an internal error! */ ReportError(Internal_Error); return ReturnValue; } /* endif */ /* The next token must be the keyword ALL, PARTITION, or VOLUME */ switch (CurrentToken.TokenType) { case All_CLI: pDeletionParameters->NameType = NoNameType; pDeletionParameters->DeletionOption = Deletion_None; /* All found, advance to next token */ NextToken(Tokens,&Error); SkipOptionalWhitespace(Tokens); /* The token following the ALL keyword must be a comma */ if ( IsComma(Tokens) ) { SkipOptionalWhitespace(Tokens); GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( Error) { /* Report any errors accessing the token list as an internal error! */ ReportError(Internal_Error); return ReturnValue; } /* endif */ switch (CurrentToken.TokenType) { case Compatibility: pDeletionParameters->DeletionOption = Deletion_All_Compatibility; NextToken(Tokens,&Error); ReturnValue = TRUE; break; case Logical: pDeletionParameters->DeletionOption = Deletion_All_Logical; NextToken(Tokens,&Error); ReturnValue = TRUE; break; case LVM: pDeletionParameters->DeletionOption = Deletion_All_LVM; NextToken(Tokens,&Error); ReturnValue = TRUE; break; case Primary: pDeletionParameters->DeletionOption = Deletion_All_Primary; NextToken(Tokens,&Error); ReturnValue = TRUE; break; case Unused: pDeletionParameters->DeletionOption = Deletion_All_Unused; NextToken(Tokens,&Error); ReturnValue = TRUE; break; case Volumes: pDeletionParameters->DeletionOption = Deletion_All_Volumes; NextToken(Tokens,&Error); ReturnValue = TRUE; break; case Eof: case SemiColon: ReportParseError(Expected_Deletion_Suboption, Tokens, pCommandLine); break; default: ReportParseError(Expected_Deletion_Suboption, Tokens, pCommandLine); } /* endswitch */ } else { ReportParseError(Expected_Comma, Tokens, pCommandLine); } /* endif */ break; case Partition: pDeletionParameters->DeletionOption = Deletion_Partition; /* Partition found, advance to next token */ NextToken(Tokens,&Error); SkipOptionalWhitespace(Tokens); /* The token following the PARTITION keyword must be a comma */ if ( IsComma(Tokens) ) { SkipOptionalWhitespace(Tokens); GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( Error) { /* Report any errors accessing the token list as an internal error! */ ReportError(Internal_Error); return ReturnValue; } /* endif */ /* The token following PARTITION must be a drive number or drive name */ /* If it is a drive number */ if ( Drive_Number(Tokens, &pDriveNumber) ) { pDeletionParameters->NameType = DriveNumberType; pDeletionParameters->pDrive = pDriveNumber; } else { /* If it is a drive name */ if ( Drive_Name(Tokens, Comma, &pDriveName) ) { pDeletionParameters->NameType = DriveNameType; pDeletionParameters->pDrive = pDriveName; } else { ReportParseError(Expected_Drive_Number_or_Name, Tokens, pCommandLine); return ReturnValue; } /* endif */ } /* endif */ SkipOptionalWhitespace(Tokens); /* The next token is a comma, the one following it must be a parition name */ if ( IsComma(Tokens) ) { SkipOptionalWhitespace(Tokens); GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( Error ) { /* Report any errors accessing the token list as an internal error! */ ReportError(Internal_Error); return ReturnValue; } /* endif */ pPartitionName = NULL; /* The next tokens, up to the next semicolon, must be a Partition name. */ if ( Partition_Name(Tokens, SemiColon, &pPartitionName) ) { pDeletionParameters->pPartitionName = pPartitionName; ReturnValue = TRUE; } else { ReportParseError(Expected_Partition_Name, Tokens, pCommandLine); } /* endif */ } else { /* Since the next token was not a comma, assume that the optional */ /* partition name was not specified. */ /* When the partition name is not specified, the parser indicates */ /* that all paritions on the specified drive are to be deleted. */ pDeletionParameters->DeletionOption = Deletion_Partitions; ReturnValue = TRUE; } /* endif */ } else { ReportParseError(Expected_Comma, Tokens, pCommandLine); } /* endif */ break; case Volume: pDeletionParameters->DeletionOption = Deletion_Volume; /* Volume found, advance to next token */ NextToken(Tokens,&Error); SkipOptionalWhitespace(Tokens); /* The next non-whitespace token must be a comma */ if ( IsComma(Tokens) ) { SkipOptionalWhitespace(Tokens); GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( Error ) { ReportError(Internal_Error); return ReturnValue; } /* endif */ pVolumeName = NULL; /* The next tokens, up to the next semicolon, must be a volume name. */ if ( Volume_Name(Tokens, SemiColon, &pVolumeName) ) { pDeletionParameters->pVolumeName = pVolumeName; ReturnValue = TRUE; } else { ReportParseError(Expected_Volume_Name, Tokens, pCommandLine); } /* endif */ } else { ReportParseError(Expected_Comma, Tokens, pCommandLine); } /* endif */ break; default: ReportParseError(Expected_Deletion_Option, Tokens, pCommandLine); break; } /* endswitch */ /* Report any errors accessing the token list as an internal error! */ if ( Error ) ReportError(Internal_Error); return ReturnValue; }
BOOLEAN Query_Parameters(LIST Tokens, pQueryStruct pQueryParameters, pSTRING pCommandLine) { Token CurrentToken; /* Used to hold the token being examined. */ CARDINAL Error = 0; /* Used to hold the error return code from LIST operations. */ BOOLEAN ReturnValue = FALSE; /* Used to hold the function return value. */ pSTRING pDriveName = NULL; pSTRING pDriveNumber = NULL; unsigned int TokenPosition; /* Get the current token so that we can examine it. */ GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( !Error ) { /* Set the OptionType field of the query structure */ switch (CurrentToken.TokenType) { case All_CLI: pQueryParameters->OptionType = Query_All; break; case Bootable: pQueryParameters->OptionType = Query_Bootable; break; case Compatibility: pQueryParameters->OptionType = Query_Compatibility; break; case Freespace: pQueryParameters->OptionType = Query_Freespace; break; case Logical: pQueryParameters->OptionType = Query_Logical; break; case LVM: pQueryParameters->OptionType = Query_LVM; break; case Primary: pQueryParameters->OptionType = Query_Primary; break; case Unusable: pQueryParameters->OptionType = Query_Unusable; break; case Volumes: pQueryParameters->OptionType = Query_Volumes; break; default: pQueryParameters->OptionType = Query_Error; ReportParseError(Expected_Query_Option, Tokens, pCommandLine); break; } /* endswitch */ /* Check for optional parameters */ switch (CurrentToken.TokenType) { case Primary: case Logical: case Volumes: case Compatibility: case LVM: case All_CLI: NextToken(Tokens, &Error); if ( !Error ) { SkipOptionalWhitespace(Tokens); /* If there is a comma following the option */ if ( IsComma(Tokens) ) { SkipOptionalWhitespace(Tokens); /* The token sequence following the comma must */ /* satisfy the Optional Query Parameters rule. */ if ( Optional_Query_Parameters(Tokens, pQueryParameters, pCommandLine) ) { ReturnValue = TRUE; } /* endif */ } else { pQueryParameters->NameType = NoNameType; ReturnValue = TRUE; } /* endif */ } /* endif */ break; case Freespace: case Unusable: case Bootable: NextToken(Tokens, &Error); if ( !Error ) { SkipOptionalWhitespace(Tokens); /* If there is a comma following the option */ if ( IsComma(Tokens) ) { SkipOptionalWhitespace(Tokens); GetToken(Tokens,sizeof(Token),&CurrentToken,&TokenPosition,&Error); if ( !Error ) { /* Any token following the comma must be the keword ALL */ /* or a drive number or a drive name. */ /* If it is ALL */ if (CurrentToken.TokenType == All_CLI) { pQueryParameters->NameType = AllNameType; NextToken(Tokens, &Error); ReturnValue = TRUE; } else { /* If it is a drive number */ if ( Drive_Number(Tokens, &pDriveNumber) ) { pQueryParameters->NameType = DriveNumberType; pQueryParameters->pName = pDriveNumber; ReturnValue = TRUE; } else { if ( Drive_Name(Tokens, SemiColon, &pDriveName) ) { pQueryParameters->NameType = DriveNameType; pQueryParameters->pName = pDriveName; ReturnValue = TRUE; } else { ReportParseError(Expected_ALL_or_Drive_Number_or_Name, Tokens, pCommandLine); } /* endif */ } /* endif */ } /* endif */ } /* endif */ } else { pQueryParameters->NameType = NoNameType; ReturnValue = TRUE; } /* endif */ } /* endif */ } /* endswitch */ } /* Report any errors accessing the token list as an internal error! */ if ( Error ) { ReportError(Internal_Error); } return ReturnValue; }