Ignore:
Timestamp:
Feb 4, 2007, 8:09:00 PM (19 years ago)
Author:
RBRi
Message:

again significant changes for the command line parser
TODO: write many more unit tests

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/NewView/CmdLineParameterUnit.pas

    r65 r67  
    5151       searchText : string;
    5252
    53        currentParsePosition : integer;
    54 
    55        FUNCTION ReadNextPart(const aParseString : String; const aSetOfDelimiterChars : TSetOfChars): String;
    56        FUNCTION handleParamWithValue(const aCmdLineString : String; const aSwitch : String; var aValue : String) : Boolean;
    57        PROCEDURE parseSwitch(aCmdLineString : String);
     53//       FUNCTION ReadNextPart(const aParseString : String; const aSetOfDelimiterChars : TSetOfChars): String;
     54       FUNCTION handleSwitchWithValue(const aSwitchString : String; const aSwitch : String; var aValue : String) : Boolean;
     55       PROCEDURE parseSwitch(aSwitchString : String);
    5856       PROPERTY getFileNames : string read fileNames;
    5957       PROPERTY getSearchText : string read searchText;
     
    9694    tmpWindowPosition : TWindowPosition;
    9795  begin
     96    aStrings.Add('''' + getCommandLine + '''');
    9897    aStrings.Add('parsed infos:');
    9998
     
    123122
    124123
    125   FUNCTION TCmdLineParameters.getInterpretedFileNames: String;
     124  Function TCmdLineParameters.getInterpretedFileNames: String;
    126125  var
    127126    tmpOwnHelpFileName : String;
     
    146145
    147146
    148   FUNCTION TCmdLineParameters.getInterpretedSearchText: String;
     147  Function TCmdLineParameters.getInterpretedSearchText: String;
    149148  begin
    150149    result := getSearchText;
     
    166165
    167166
    168   FUNCTION TCmdLineParameters.setHelpManagerFlag(aNewValue : boolean) : boolean;
     167  Function TCmdLineParameters.setHelpManagerFlag(aNewValue : boolean) : boolean;
    169168  begin
    170169       helpManagerFlag := aNewValue;
     
    173172
    174173
    175   procedure TCmdLineParameters.parseCmdLine(aCmdLineString : String);
     174  Procedure TCmdLineParameters.parseCmdLine(aCmdLineString : String);
    176175  var
    177     tmpState : (SWITCH, FILENAME, FILENAME_QUOTE, TEXT);
     176    tmpState : (WHITESPACE, QUOTE, SWITCH, FILENAME, TEXT);
     177    tmpCurrentParsePosition : integer;
     178    tmpQuoted : boolean;
    178179    tmpCurrentChar : char;
     180    tmpWhitespace : String;
     181    tmpQuote : String;
     182    tmpSwitch : String;
    179183  begin
    180184     LogEvent(LogStartup, 'ParseCommandLine: "' + aCmdLineString + '"');
     
    199203     try
    200204       // start parsing
    201        tmpState := FILENAME;
    202        currentParsePosition := 1;
    203        while currentParsePosition <= length(aCmdLineString) do
     205       tmpState := WHITESPACE;
     206       tmpWhitespace := '';
     207       tmpSwitch := '';
     208       tmpQuote := '';
     209       tmpQuoted := false;
     210       tmpCurrentParsePosition := 1;
     211       while tmpCurrentParsePosition <= length(aCmdLineString) do
    204212       begin
    205          tmpCurrentChar := aCmdLineString[currentParsePosition];
     213         tmpCurrentChar := aCmdLineString[tmpCurrentParsePosition];
    206214
    207215         Case tmpCurrentChar of
    208216           ' ' :
     217           begin
     218             Case tmpState of
     219
     220               WHITESPACE :
     221               begin
     222                 tmpWhitespace := tmpWhitespace + tmpCurrentChar;
     223               end;
     224
     225               QUOTE :
     226               begin
     227                 tmpQuote := tmpQuote + tmpCurrentChar;
     228               end;
     229
     230               SWITCH :
     231               begin
     232                 if tmpQuoted then
     233                 begin
     234                   tmpSwitch := tmpSwitch + tmpCurrentChar;
     235                 end
     236                 else
     237                 begin
     238                   parseSwitch(tmpSwitch);
     239                   tmpState := WHITESPACE;
     240                   tmpWhitespace := tmpCurrentChar;
     241                 end
     242               end;
     243
     244               FILENAME :
     245               begin
     246                 if tmpQuoted then
     247                 begin
     248                   fileNames := fileNames + tmpCurrentChar;
     249                   fileNamesRaw := fileNamesRaw + tmpCurrentChar;
     250                 end
     251                 else
     252                 begin
     253                   tmpState := WHITESPACE;
     254                   tmpWhitespace := tmpCurrentChar;
     255                 end
     256               end;
     257
     258               TEXT :
     259               begin
     260                 if tmpQuoted then
     261                 begin
     262                   searchText := searchText + tmpCurrentChar;
     263                 end
     264                 else
     265                 begin
     266                   tmpState := WHITESPACE;
     267                   tmpWhitespace := tmpCurrentChar;
     268                 end
     269               end;
     270             end;
     271           end;
     272
     273           '/', '-' :
     274           begin
     275             Case tmpState of
     276               WHITESPACE :
     277               begin
     278                 tmpState := SWITCH;
     279                 tmpSwitch := '';
     280               end;
     281
     282               QUOTE :
     283               begin
     284                 tmpState := SWITCH;
     285                 tmpSwitch := '';
     286               end;
     287
     288               SWITCH :
     289               begin
     290                 parseSwitch(tmpSwitch);
     291                 tmpSwitch := '';
     292               end;
     293
     294               FILENAME :
     295               begin
     296                 fileNames := fileNames + tmpCurrentChar;
     297                 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
     298               end;
     299
     300               TEXT :
     301               begin
     302                 searchText := searchText + tmpCurrentChar;
     303               end;
     304             end;
     305           end;
     306
     307           '"' :
     308           begin
     309             if tmpQuoted then
     310             begin
     311               tmpQuoted := false;
     312               Case tmpState of
     313                 FILENAME :
     314                 begin
     315                   fileNamesRaw := fileNamesRaw + tmpCurrentChar;
     316                 end;
     317               end;
     318             end
     319             else
    209320             begin
    210321               Case tmpState of
    211                  SWITCH :
    212                  begin
    213                    tmpState := FILENAME;
    214                    inc(currentParsePosition);
     322                 WHITESPACE :
     323                 begin
     324                   tmpState := QUOTE;
     325                   tmpQuote := tmpCurrentChar;
    215326                 end;
    216327                 FILENAME :
    217328                 begin
    218                    if length(fileNames) > 0 then
    219                    begin
    220                      tmpState := TEXT;
    221                    end;
    222                    inc(currentParsePosition);
     329                   fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    223330                 end;
    224                  FILENAME_QUOTE :
    225                  begin
     331               end;
     332               tmpQuoted := true;
     333             end;
     334           end;
     335
     336           // any other char
     337           else
     338           begin
     339             Case tmpState of
     340
     341               WHITESPACE :
     342               begin
     343                 if length(fileNames) > 0 then
     344                 begin
     345                   tmpState := TEXT;
     346                   searchText := searchText + tmpWhitespace + tmpCurrentChar;
     347                 end
     348                 else
     349                 begin
     350                   tmpState := FILENAME;
    226351                   fileNames := fileNames + tmpCurrentChar;
    227352                   fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    228                    inc(currentParsePosition);
    229353                 end;
    230                  TEXT :
    231                  begin
    232                    searchText := searchText + tmpCurrentChar;
    233                    inc(currentParsePosition);
     354               end;
     355
     356               QUOTE :
     357               begin
     358                 if length(fileNames) > 0 then
     359                 begin
     360                   tmpState := TEXT;
     361                   searchText := searchText + tmpWhitespace + tmpCurrentChar;
     362                 end
     363                 else
     364                 begin
     365                   tmpState := FILENAME;
     366                   fileNames := fileNames + tmpCurrentChar;
     367                   fileNamesRaw := fileNamesRaw + tmpQuote + tmpCurrentChar;
    234368                 end;
    235369               end;
    236              end;
    237 
    238            '/', '-' :
    239              begin
    240                Case tmpState of
    241                  SWITCH :
    242                  begin
    243                    tmpState := SWITCH;
    244                    parseSwitch(aCmdLineString);
    245                  end;
    246                  FILENAME :
    247                  begin
    248                    if length(fileNames) < 1 then
    249                    begin
    250                      tmpState := SWITCH;
    251                      parseSwitch(aCmdLineString);
    252                    end
    253                    else
    254                    begin
    255                      fileNames := fileNames + tmpCurrentChar;
    256                      fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    257                      inc(currentParsePosition);
    258                    end;
    259                  end;
    260                  FILENAME_QUOTE :
    261                  begin
    262                    fileNames := fileNames + tmpCurrentChar;
    263                    fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    264                    inc(currentParsePosition);
    265                  end;
    266                else
    267                  begin
    268                    searchText := searchText + tmpCurrentChar;
    269                    inc(currentParsePosition);
    270                  end;
    271                end;
    272              end;
    273 
    274            '"' :
    275              begin
    276                Case tmpState of
    277                  SWITCH :
    278                  begin
    279                    // syntax error
    280                    raise EParsingFailed.Create('Unsupported switch');
    281                  end;
    282                  FILENAME :
    283                  begin
    284                    tmpState := FILENAME_QUOTE;
    285                    fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    286                    inc(currentParsePosition);
    287                  end;
    288                  FILENAME_QUOTE :
    289                  begin
    290                    tmpState := FILENAME;
    291                    fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    292                    inc(currentParsePosition);
    293                  end;
    294                  TEXT :
    295                  begin
    296                    searchText := searchText + tmpCurrentChar;
    297                    inc(currentParsePosition);
    298                  end;
    299                end;
    300              end;
    301 
    302            else
    303              begin
    304                Case tmpState of
    305                  SWITCH :
    306                  begin
    307                    // syntax error
    308                    raise EParsingFailed.Create('Unsupported switch');
    309                  end;
    310                  FILENAME :
    311                  begin
    312                    fileNames := fileNames + tmpCurrentChar;
    313                    fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    314                    inc(currentParsePosition);
    315                  end;
    316                  FILENAME_QUOTE :
    317                  begin
    318                    fileNames := fileNames + tmpCurrentChar;
    319                    fileNamesRaw := fileNamesRaw + tmpCurrentChar;
    320                    inc(currentParsePosition);
    321                  end;
    322                else
     370
     371               SWITCH :
     372               begin
     373                 tmpSwitch := tmpSwitch + tmpCurrentChar;
     374               end;
     375
     376               FILENAME :
     377               begin
     378                 fileNames := fileNames + tmpCurrentChar;
     379                 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
     380               end;
     381
     382               TEXT :
    323383               begin
    324384                 searchText := searchText + tmpCurrentChar;
    325                  inc(currentParsePosition);
    326385               end;
    327386             end;
    328387           end;
    329388        end;
     389        inc(tmpCurrentParsePosition);
    330390      end;
     391
     392      // ok all chars are processed, but maybe we have something to do
     393      Case tmpState of
     394        SWITCH :
     395        begin
     396          parseSwitch(tmpSwitch);
     397        end;
     398     end;
     399
     400
     401     // TODO remove interpreted
    331402
    332403    except
     
    346417
    347418
     419{
    348420  FUNCTION TCmdLineParameters.ReadNextPart(const aParseString : String; const aSetOfDelimiterChars : TSetOfChars): String;
    349421  VAR
     
    365437    end;
    366438  END;
    367 
    368 
    369 
    370   Function TCmdLineParameters.handleParamWithValue(const aCmdLineString : String; const aSwitch : String; var aValue : String) : Boolean;
     439}
     440
     441
     442  Function TCmdLineParameters.handleSwitchWithValue(const aSwitchString : String; const aSwitch : String; var aValue : String) : Boolean;
    371443  var
    372444    tmpText : String;
     445    tmpValueStartPos : integer;
    373446    tmpSwitchLength : integer;
    374447  begin
    375448    tmpSwitchLength := Length(aSwitch);
    376     tmpText := copy(aCmdLineString, currentParsePosition + 1, tmpSwitchLength);
     449    tmpText := copy(aSwitchString, 1, tmpSwitchLength);
    377450    tmpText := lowercase(tmpText);
    378451
    379452    if (lowercase(aSwitch) = tmpText) then
    380453    begin
    381       currentParsePosition := currentParsePosition + 1 + tmpSwitchLength;
    382       if aCmdLineString[currentParsePosition] = ':' then
     454      tmpValueStartPos := tmpSwitchLength;
     455      inc(tmpValueStartPos);
     456      if aSwitchString[tmpValueStartPos] = ':' then
    383457      begin
    384         inc(currentParsePosition);
     458        inc(tmpValueStartPos);
    385459      end;
    386460
    387       aValue := readNextPart(aCmdLineString, [' ', '-', '/']);
    388       currentParsePosition := currentParsePosition + length(aValue);
     461      aValue := copy(aSwitchString, tmpValueStartPos, Length(aSwitchString) - tmpValueStartPos+ 1);
    389462      result := true;
    390463      exit;
     
    442515
    443516
    444   Procedure TCmdLineParameters.parseSwitch(aCmdLineString : String);
     517  Procedure TCmdLineParameters.parseSwitch(aSwitchString : String);
    445518  var
    446519    tmpCurrentChar : char;
     
    449522  begin
    450523    // lang
    451     if handleParamWithValue(aCmdLineString, 'lang', tmpValue) then
     524    if handleSwitchWithValue(aSwitchString, 'lang', tmpValue) then
    452525    begin
    453526      language := tmpValue;
     
    456529
    457530    // title
    458     if handleParamWithValue(aCmdLineString, 'title', tmpValue) then
     531    if handleSwitchWithValue(aSwitchString, 'title', tmpValue) then
    459532    begin
    460533      windowTitle := tmpValue;
     
    463536
    464537    // HM
    465     if handleParamWithValue(aCmdLineString, 'hm', tmpValue) then
     538    if handleSwitchWithValue(aSwitchString, 'hm', tmpValue) then
    466539    begin
    467540      try
     
    478551
    479552    // owner
    480     if handleParamWithValue(aCmdLineString, 'owner', tmpValue) then
     553    if handleSwitchWithValue(aSwitchString, 'owner', tmpValue) then
    481554    begin
    482555      try
     
    492565
    493566    // pos
    494     if handleParamWithValue(aCmdLineString, 'pos', tmpValue) then
     567    if handleSwitchWithValue(aSwitchString, 'pos', tmpValue) then
    495568    begin
    496569      windowPosition := ParseWindowPosition(tmpValue);
     
    500573
    501574    // check the next char
    502     tmpCurrentChar := aCmdLineString[currentParsePosition + 1];
     575    // TODO check for other invalid chars
     576    tmpCurrentChar := aSwitchString[1];
    503577    Case tmpCurrentChar of
    504578      'h', 'H', '?' :
    505579        begin
    506           currentParsePosition := currentParsePosition + 2;
    507580          showUsageFlag := true;
    508581
    509582          // check for 'help'
    510           tmpText := copy(aCmdLineString, currentParsePosition, 3);
    511           tmpText := lowercase(tmpText);
    512 
    513           if ('elp' = tmpText) then
    514           begin
    515             currentParsePosition := currentParsePosition + 3;
    516           end;
     583//          tmpText := copy(aCmdLineString, 2, 3);
     584//          tmpText := lowercase(tmpText);
     585
     586//          if ('elp' = tmpText) then
     587//          begin
     588//          end;
    517589        end;
    518590
    519591      's', 'S' :
    520592        begin
    521           currentParsePosition := currentParsePosition + 2;
    522593          searchFlag := true;
    523594        end;
     
    525596      'g', 'G' :
    526597        begin
    527           currentParsePosition := currentParsePosition + 2;
    528598          globalSearchFlag := true;
    529599        end;
Note: See TracChangeset for help on using the changeset viewer.