//***************************************************************************************** // Copyright (c) 2000 Michael Kurz // All rights reserved. // If you want to use this source in your applications conatct: // // $FileName : cLineParser.pkg // $ProjectName : General shared classes // $Author : Michael Kurz // $Created : 12-31-2000 @ 09:00 // // Contents: // Separates a string to its parts which need to be seperated by a special character. // // $Rev History // 11/09/2005 **WvA Added the possibility to skip parts in the parsing. This allows // us to parse UNC paths correctly while the sep character is set to "\" // //***************************************************************************************** // This Class separates a string into his parts. Which need to be // seperated by a seperating character (psSepCharacter) // As the class is based on an array the parts can be retrieved by // "get value item iItem to sPart" and the number of items with a call // of "get Item_Count to iCount". Define CLINEPARSER_COMMAND For 0 Define CLINEPARSER_KEYWORD For 1 Define CLINEPARSER_COMMENT For 2 Define CLINEPARSER_STRING For 3 Define CLINEPARSER_EXPRESSION For 4 Define CLINEPARSER_INDICATOR For 5 Class cLineParser Is a Array // Adding properties and setting default values Procedure Construct_Object Forward Send Construct_Object Property String psSepCharacter Public "," // Seperating character Property String psSkipSequence Public "" // Sometimes we want the parser to skip parsing parts, eg. the unc prefix "\\" when the character is set to "\" Property String psSwapOutSequence Public "$x$" // (Private) This is used along with psSkipSequence to temporarily swap out parts you want to skip parsing, you would normally not need to change this. Property String psInputLine Public "" // Stores the whole last given string. (only for convenience) Property Integer piSkipEmptyParts Public 0 // Skips empty parts // Follow the language tokens, ie (Expr), comments, strings etc. recognize as token, Property Integer piLanguageTokens Public False Object oType Is an Array End_Object End_Procedure // Parses a line in its parts which are seperated by "psSepCharacter". Procedure ParseLine String sLine If (piLanguageTokens(Self)) Begin Set psSepCharacter To " " Send ParseLineTkn sLine End Else Send ParseLineStd sLine End_Procedure Procedure Add_Token Integer iType String sToken Set value Item (Item_Count(Self)) To (Trim(sToken)) If ((Item_Count(Self)=1)And(iType<>CLINEPARSER_COMMENT)And(iType<>CLINEPARSER_INDICATOR)) Set value Of (oType(Self)) Item (Item_Count(Self)-1) To CLINEPARSER_COMMAND Else Set value Of (oType(Self)) Item (Item_Count(Self)-1) To iType End_Procedure Function ProcessStrToken String sChar String sLine Integer iCount Returns Integer String sToken sChr Move "" To sToken Move sChar To sChr Move (sToken+sChr) To sToken Move "" To sChr While ((sChr<>sChar)And(iCount<=(Length(sLine)))) Increment iCount Move (Mid(sLine,1,iCount)) To sChr Move (sToken+sChr) To sToken Loop If (Trim(sToken)<>"") Send Add_Token CLINEPARSER_STRING (Trim(sToken)) Function_Return iCount End_Function Function ProcessBrToken String sCharSt String sCharEn String sLine Integer iCount Returns Integer Integer iBr iStr iChr String sToken sChr Increment iBr // Start Move sCharSt To sToken While ((iBr<>0)And(iCount<=(Length(sLine)))) Increment iCount Move (Mid(sLine,1,iCount)) To sChr If (sChr='"') Begin If (iStr) Decrement iStr Else Begin If (Not(iChr)) Increment iStr End End If (sChr="'") Begin If (iChr) Decrement iChr Else Begin If (Not(iStr)) Increment iChr End End If ((Not(iStr))And(Not(iChr))) Begin If (sChr=sCharSt) Increment iBr If (sChr=sCharEn) Decrement iBr End Move (sToken+sChr) To sToken Loop If (Trim(sToken)<>"") Begin If (sCharSt="[") Send Add_Token CLINEPARSER_INDICATOR (Trim(sToken)) Else Send Add_Token CLINEPARSER_EXPRESSION (Trim(sToken)) End Function_Return iCount End_Function Procedure ParseLineTkn String sLine Integer iPos iC iBlank iSepL iCount String sPart sToken sChar sSep sCom sNext sComLine Move ('/'+'/') To sCom Move (psSepCharacter(Self)) To sSep Move (Length(sSep)) To iSepL Send Delete_Data If (sSep=" ") Move 1 To iBlank If (Left(sLine,2)=sCom) Begin Send Add_Token CLINEPARSER_COMMENT (Trim(sLine)) Procedure_Return End If sCom In sLine Begin Move (Left(sLine, (Pos(sCom, sLine)-1))) To sToken Move (Replace(sToken, sLine, "")) To sLine Move (Trim(sLine)) To sComLine Move sToken To sLine Move "" To sToken End While (iCount<=(Length(sLine))) Increment iCount Move (Mid(sLine,1,iCount)) To sChar If (sChar='"' Or sChar="'") Begin Get ProcessStrToken sChar sLine iCount To iCount Move "" To sChar End Else If (sChar="(") Begin Get ProcessBrToken sChar ")" sLine iCount To iCount Move "" To sChar End Else If (sChar="[") Begin Get ProcessBrToken sChar "]" sLine iCount To iCount Move "" To sChar End Else If (sChar="/") Begin Increment iCount Move (Mid(sLine,1,iCount)) To sNext If (sNext="/") Begin Move (sChar+sNext+Right(sLine, iCount+1)) To sToken If (Trim(sToken)<>"") Send Add_Token CLINEPARSER_COMMENT (Trim(sToken)) Move (Length(sLine)+100) To iCount // Cancels parsing End Move "" To sChar End If (sChar=sSep) Begin If (Trim(sToken)<>"") Send Add_Token CLINEPARSER_KEYWORD (Trim(sToken)) Move "" To sToken End If (sChar<>"") Move (sToken+sChar) To sToken Loop If (sComLine<>"") Send Add_Token CLINEPARSER_COMMENT (Trim(sComLine)) End_Procedure Procedure ParseLineStd String sLine Integer iPos iC iBlank iSepL iCount String sPart sSkip sSwap sOld Boolean bSwapped Move (Length(psSepCharacter(Self))) To iSepL Send Delete_Data // *WvA: 11/09/2005 Added logic to skip parsing of specific parts. Move (false) To bSwapped Get psSkipSequence To sSkip Get psSwapOutSequence To sSwap If (sSkip<>"") Begin // temporarily replace our skip sequence with the swapvalue Move sLine To sOld Move (Replaces(sSkip,sLine,sSwap)) To sLine Move (sOld<>sLine) To bSwapped End If (psSepCharacter(Self)) Eq " " Move 1 To iBlank Repeat Increment iCount Move (Pos(psSepCharacter(Self),sLine)) To iPos If iPos Eq 0 Move (Length(sLine)) To iPos Move (Left(sLine,iPos+iSepL-1)) To sPart Move (Replace(sPart,sLine,"")) To sLine If (Right(sPart,iSepL)) Eq (psSepCharacter(Self)) ; Move (Left(sPart,length(sPart)-iSepL)) To sPart //move (Right(sLine,Length(sLine)-iPos)) to sLine If iBlank Move (LTrim(sLine)) To sLine // *WvA: 11/09/2005 Added logic to skip parsing of specific parts. If ((bSwapped) And (Pos(sSwap,sPart)>0)) Begin // Move our skip sequence back in the part just before storing it. Move (Replaces(sSwap,sPart,sSkip)) To sPart End If (Not(piSkipEmptyParts(Self))) Set value Item (Item_Count(Self)) To sPart Else If (Trim(sPart)) Ne "" Set value Item (Item_Count(Self)) To sPart If iCount Gt 200 Begin // Send Info_Box "Failure!" Procedure_Return End Until (sLine Eq "") End_Procedure // An easy procedure to init the LineParser. Procedure Init String sSepCharacter Integer iSkipEmptyParts Set psSepCharacter To sSepCharacter Set piSkipEmptyParts To iSkipEmptyParts End_Procedure End_Class // cLineParser