source: trunk/NewView/CmdLineParameterUnit.pas@ 65

Last change on this file since 65 was 65, checked in by RBRi, 19 years ago

more fixes for the link handling

  • Property svn:eol-style set to native
File size: 15.9 KB
RevLine 
[23]1Unit CmdLineParameterUnit;
2
3// NewView - a new OS/2 Help Viewer
4// Copyright 2006 Ronald Brill (rbri at rbri dot de)
[42]5// This software is released under the GNU Public License - see readme.txt
[23]6
7// Helper functions to address the command line parameters newview
8// is started with
9
10Interface
11
12uses
[32]13 Os2Def,
14 BseTib,
15 BseDos,
[23]16 SysUtils,
17 Classes,
18 PMWIN,
[42]19 StringUtilsUnit,
20 DebugUnit;
[23]21
22 CONST
23 SUCCESS = 0;
24 ERROR_UNMATCHED_QUOTE = -1;
25
[42]26 TYPE EParsingFailed=CLASS(Exception);
27
[23]28 TYPE
29 TWindowPosition = record
30 left: longint;
31 bottom: longint;
32 width: longint;
33 height: longint;
34 end;
35 TYPE
36 TCmdLineParameters = class
37 private
[42]38 commandLine : String;
[23]39 showUsageFlag : boolean;
[42]40 searchFlag : boolean;
41 globalSearchFlag : boolean;
[23]42 language : string;
43 helpManagerFlag : boolean;
44 helpManagerWindow : integer;
45 windowPositionFlag: boolean;
46 windowPosition: TWindowPosition;
47 ownerWindow : integer;
48 windowTitle : string;
[25]49 fileNames : string;
[45]50 fileNamesRaw : string;
[42]51 searchText : string;
[23]52
[42]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;
[63]57 PROCEDURE parseSwitch(aCmdLineString : String);
[65]58 PROPERTY getFileNames : string read fileNames;
59 PROPERTY getSearchText : string read searchText;
[42]60
[23]61 public
[42]62 PROPERTY getCommandLine : String read commandLine;
[32]63 PROPERTY getShowUsageFlag : boolean read showUsageFlag;
[42]64 PROPERTY getSearchFlag : boolean read searchFlag;
65 PROPERTY getGlobalSearchFlag : boolean read globalSearchFlag;
[32]66 PROPERTY getLanguage : string read language;
67 PROPERTY getHelpManagerFlag : boolean read helpManagerFlag;
[25]68 FUNCTION setHelpManagerFlag(aNewValue : boolean) : boolean;
[32]69 PROPERTY getHelpManagerWindow : integer read helpManagerWindow;
70 PROPERTY getWindowPositionFlag : boolean read windowPositionFlag;
71 PROPERTY getWindowPosition : TWindowPosition read windowPosition;
72 PROPERTY getOwnerWindow : integer read ownerWindow;
73 PROPERTY getWindowTitle : string read windowTitle;
[45]74 PROPERTY getFileNamesRaw : string read fileNamesRaw;
[42]75
[65]76 PROCEDURE writeDetailsTo(aStrings : TStrings);
[42]77 PROCEDURE parseCmdLine(aCmdLineString : String);
[54]78
79 FUNCTION getInterpretedFileNames: String;
80 FUNCTION getInterpretedSearchText: String;
[23]81 end;
82
[54]83 FUNCTION getOwnHelpFileName: String;
84
[42]85 // returns a string containing the whole
86 // command line parametes
[54]87 FUNCTION nativeOS2GetCmdLineParameter : String;
[23]88
89
90Implementation
[54]91uses
92 ACLFileUtility;
[23]93
[65]94 PROCEDURE TCmdLineParameters.writeDetailsTo(aStrings : TStrings);
95 var
96 tmpWindowPosition : TWindowPosition;
97 begin
98 aStrings.Add('parsed infos:');
99
100 aStrings.Add('getShowUsageFlag: ' + boolToStr(getShowUsageFlag));
101 aStrings.Add('getSearchFlag: ' + boolToStr(getSearchFlag));
102 aStrings.Add('getSearchText: ' + getSearchText);
103 aStrings.Add('getGlobalSearchFlag: ' + boolToStr(getGlobalSearchFlag));
104 aStrings.Add('getLanguage: ' + getLanguage);
105 aStrings.Add('getHelpManagerFlag: ' + boolToStr(getHelpManagerFlag));
106 aStrings.Add('getHelpManagerFlag: ' + boolToStr(getHelpManagerFlag));
107 aStrings.Add('getHelpManagerWindow: ' + intToStr(getHelpManagerWindow));
108 aStrings.Add('getWindowPositionFlag: ' + boolToStr(getWindowPositionFlag));
109 aStrings.Add('getFileNames: ' + getFileNames);
110 aStrings.Add('getInterpretedSearchText: ' + getInterpretedSearchText);
111 aStrings.Add('getInterpretedFileNames: ' + getInterpretedFileNames);
112
113 tmpWindowPosition := getWindowPosition;
114 aStrings.Add('getWindowPosition: '
115 + intToStr(tmpWindowPosition.left) + ', '
116 + intToStr(tmpWindowPosition.bottom) + ', '
117 + intToStr(tmpWindowPosition.width) + ', '
118 + intToStr(tmpWindowPosition.height)
119 );
120 aStrings.Add('getOwnerWindow: ' + intToStr(getOwnerWindow));
121 aStrings.Add('getWindowTitle: ' + getWindowTitle);
122 end;
123
124
[54]125 FUNCTION TCmdLineParameters.getInterpretedFileNames: String;
126 var
127 tmpOwnHelpFileName : String;
128 begin
129 result := getFileNames;
130
131 if getGlobalSearchFlag
132 AND (getSearchText = '')
133 then
134 begin
135 result := '';
136 exit;
137 end;
138
139
140 tmpOwnHelpFileName := FindDefaultLanguageHelpFile('NewView');
141 if (result = '') AND
142 FileExists(tmpOwnHelpFileName)
143 then
144 result := tmpOwnHelpFileName;
145 end;
146
147
148 FUNCTION TCmdLineParameters.getInterpretedSearchText: String;
149 begin
150 result := getSearchText;
151
152 if getGlobalSearchFlag
153 AND (result = '')
154 then
155 result := getFileNamesRaw;
[65]156
157 if not getGlobalSearchFlag
158 AND (not getSearchFlag)
159 then
160 begin
161 result := StrTrim(result);
162 result := StrTrimChars(result, ['"']);
163 end;
164
[54]165 end;
166
167
[25]168 FUNCTION TCmdLineParameters.setHelpManagerFlag(aNewValue : boolean) : boolean;
169 begin
170 helpManagerFlag := aNewValue;
171 result := helpManagerFlag;
172 end;
173
174
[42]175 procedure TCmdLineParameters.parseCmdLine(aCmdLineString : String);
[23]176 var
[42]177 tmpState : (SWITCH, FILENAME, FILENAME_QUOTE, TEXT);
178 tmpCurrentChar : char;
[23]179 begin
[42]180 LogEvent(LogStartup, 'ParseCommandLine: "' + aCmdLineString + '"');
[25]181
[42]182 // store the original string for debugging
183 commandLine := aCmdLineString;
[23]184
[42]185 // reset the whole object
186 showUsageFlag := false;
187 searchFlag := false;
188 globalSearchFlag := false;
189 language := '';
190 helpManagerFlag := false;
191 helpManagerWindow := 0;
192 windowPositionFlag := false;
193 ownerWindow := 0;
194 windowTitle := '';
195 searchText := '';
[45]196 fileNames := '';
197 fileNamesRaw := '';
[23]198
[42]199 try
200 // start parsing
201 tmpState := FILENAME;
202 currentParsePosition := 1;
203 while currentParsePosition <= length(aCmdLineString) do
204 begin
205 tmpCurrentChar := aCmdLineString[currentParsePosition];
[23]206
[42]207 Case tmpCurrentChar of
208 ' ' :
209 begin
210 Case tmpState of
211 SWITCH :
212 begin
213 tmpState := FILENAME;
214 inc(currentParsePosition);
215 end;
216 FILENAME :
217 begin
218 if length(fileNames) > 0 then
[23]219 begin
[42]220 tmpState := TEXT;
[23]221 end;
[42]222 inc(currentParsePosition);
223 end;
224 FILENAME_QUOTE :
225 begin
[45]226 fileNames := fileNames + tmpCurrentChar;
227 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]228 inc(currentParsePosition);
229 end;
230 TEXT :
231 begin
232 searchText := searchText + tmpCurrentChar;
233 inc(currentParsePosition);
234 end;
[23]235 end;
[42]236 end;
[25]237
[42]238 '/', '-' :
239 begin
[23]240 Case tmpState of
[42]241 SWITCH :
[23]242 begin
[42]243 tmpState := SWITCH;
244 parseSwitch(aCmdLineString);
[23]245 end;
[42]246 FILENAME :
[23]247 begin
[42]248 if length(fileNames) < 1 then
249 begin
250 tmpState := SWITCH;
251 parseSwitch(aCmdLineString);
252 end
253 else
254 begin
[45]255 fileNames := fileNames + tmpCurrentChar;
256 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]257 inc(currentParsePosition);
258 end;
[23]259 end;
[42]260 FILENAME_QUOTE :
[23]261 begin
[45]262 fileNames := fileNames + tmpCurrentChar;
263 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]264 inc(currentParsePosition);
[23]265 end;
[42]266 else
267 begin
268 searchText := searchText + tmpCurrentChar;
269 inc(currentParsePosition);
270 end;
[23]271 end;
[42]272 end;
[23]273
[42]274 '"' :
275 begin
[23]276 Case tmpState of
[42]277 SWITCH :
[23]278 begin
[42]279 // syntax error
280 raise EParsingFailed.Create('Unsupported switch');
[23]281 end;
[42]282 FILENAME :
[23]283 begin
[42]284 tmpState := FILENAME_QUOTE;
[45]285 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]286 inc(currentParsePosition);
[23]287 end;
[42]288 FILENAME_QUOTE :
[23]289 begin
[42]290 tmpState := FILENAME;
[45]291 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]292 inc(currentParsePosition);
[23]293 end;
[42]294 TEXT :
[23]295 begin
[42]296 searchText := searchText + tmpCurrentChar;
297 inc(currentParsePosition);
[23]298 end;
[42]299 end;
300 end;
301
302 else
303 begin
304 Case tmpState of
305 SWITCH :
[23]306 begin
[42]307 // syntax error
308 raise EParsingFailed.Create('Unsupported switch');
[23]309 end;
[42]310 FILENAME :
[23]311 begin
[42]312 fileNames := fileNames + tmpCurrentChar;
[45]313 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]314 inc(currentParsePosition);
[23]315 end;
[42]316 FILENAME_QUOTE :
[23]317 begin
[45]318 fileNames := fileNames + tmpCurrentChar;
319 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]320 inc(currentParsePosition);
[23]321 end;
[42]322 else
323 begin
324 searchText := searchText + tmpCurrentChar;
325 inc(currentParsePosition);
[23]326 end;
[42]327 end;
328 end;
329 end;
330 end;
[23]331
[42]332 except
333 on e:EParsingFailed do
334 begin
335 showUsageFlag := true;
336 end;
337 end;
338
339 // remove leading blanks from search text
340 searchText := StrTrim(searchText);
341
342 LogEvent(LogStartup, 'Parameters parsed');
343 LogEvent(LogStartup, ' Filename(s): "' + fileNames + '"');
344 LogEvent(LogStartup, ' Search Text: "' + searchText + '"');
345 end;
346
347
348 FUNCTION TCmdLineParameters.ReadNextPart(const aParseString : String; const aSetOfDelimiterChars : TSetOfChars): String;
349 VAR
350 i : integer;
351 tmpChar : char;
352 BEGIN
353 result := '';
354 for i:= currentParsePosition to length(aParseString) do
355 begin
356 tmpChar := aParseString[i];
357 if tmpChar in aSetOfDelimiterChars then
358 begin
359 i := length(aParseString); // stop parsing
360 end
361 else
362 begin
363 result := result + tmpChar;
364 end;
365 end;
[23]366 END;
367
368
369
[42]370 Function TCmdLineParameters.handleParamWithValue(const aCmdLineString : String; const aSwitch : String; var aValue : String) : Boolean;
371 var
372 tmpText : String;
373 tmpSwitchLength : integer;
374 begin
375 tmpSwitchLength := Length(aSwitch);
376 tmpText := copy(aCmdLineString, currentParsePosition + 1, tmpSwitchLength);
377 tmpText := lowercase(tmpText);
[23]378
[42]379 if (lowercase(aSwitch) = tmpText) then
380 begin
381 currentParsePosition := currentParsePosition + 1 + tmpSwitchLength;
382 if aCmdLineString[currentParsePosition] = ':' then
383 begin
384 inc(currentParsePosition);
385 end;
[23]386
[42]387 aValue := readNextPart(aCmdLineString, [' ', '-', '/']);
388 currentParsePosition := currentParsePosition + length(aValue);
389 result := true;
390 exit;
391 end;
392 result := false;
393 end;
[23]394
395
[42]396 Function ParseWindowPositionPart(const aPart: String; const aScreenDimension: longint): longint;
397 Var
398 tmpPart : String;
399 Begin
400 if aPart = '' then
401 raise EParsingFailed.Create('Missing position element');
[23]402
[42]403 if StrEndsWithIgnoringCase(aPart, 'P') then
404 begin
405 tmpPart := copy(aPart, 1, length(aPart)-1);
406 if tmpPart = '' then
407 raise EParsingFailed.Create('Missing position element');
[23]408
[42]409 Result := StrToInt(tmpPart);
410 if Result < 0 then
411 Result := 0;
412 if Result > 100 then
413 Result := 100;
414 Result := Round(Result / 100 * aScreenDimension);
415 end
416 else
417 begin
418 Result := StrToInt(aPart);
419 end;
420 end;
[23]421
[42]422 Function ParseWindowPosition(const aParamValue: String): TWindowPosition;
423 Var
424 tmpParts : TStringList;
425 Begin
426 tmpParts := TStringList.Create;
427 StrExtractStrings(tmpParts, aParamValue, [','], '\');
[23]428
[42]429 result.Left := ParseWindowPositionPart(tmpParts[0], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
430 result.Bottom := ParseWindowPositionPart(tmpParts[1], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
[23]431
[42]432 result.Width := ParseWindowPositionPart(tmpParts[2], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
433 if result.Width < 50 then
434 result.Width := 50;
[23]435
[42]436 result.Height := ParseWindowPositionPart(tmpParts[3], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
437 if result.Height < 50 then
438 result.Height := 50;
439
440 tmpParts.Destroy;
[23]441 end;
442
443
[42]444 Procedure TCmdLineParameters.parseSwitch(aCmdLineString : String);
445 var
446 tmpCurrentChar : char;
447 tmpText : String;
448 tmpValue : String;
449 begin
450 // lang
451 if handleParamWithValue(aCmdLineString, 'lang', tmpValue) then
452 begin
453 language := tmpValue;
454 exit;
455 end;
456
457 // title
458 if handleParamWithValue(aCmdLineString, 'title', tmpValue) then
459 begin
460 windowTitle := tmpValue;
461 exit;
462 end;
463
464 // HM
465 if handleParamWithValue(aCmdLineString, 'hm', tmpValue) then
466 begin
467 try
468 helpManagerWindow := StrToInt(tmpValue);
469 helpManagerFlag := true;
470 except
471 on e:Exception do
472 begin
473 showUsageFlag := true;
474 end;
475 end;
476 exit;
477 end;
478
479 // owner
480 if handleParamWithValue(aCmdLineString, 'owner', tmpValue) then
481 begin
482 try
483 ownerWindow := StrToInt(tmpValue);
484 except
485 on e:Exception do
486 begin
487 showUsageFlag := true;
488 end;
489 end;
490 exit;
491 end;
492
493 // pos
494 if handleParamWithValue(aCmdLineString, 'pos', tmpValue) then
495 begin
496 windowPosition := ParseWindowPosition(tmpValue);
497 windowPositionFlag := true;
498 exit;
499 end;
500
501 // check the next char
502 tmpCurrentChar := aCmdLineString[currentParsePosition + 1];
503 Case tmpCurrentChar of
504 'h', 'H', '?' :
505 begin
506 currentParsePosition := currentParsePosition + 2;
507 showUsageFlag := true;
508
509 // 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;
517 end;
518
519 's', 'S' :
520 begin
521 currentParsePosition := currentParsePosition + 2;
522 searchFlag := true;
523 end;
524
525 'g', 'G' :
526 begin
527 currentParsePosition := currentParsePosition + 2;
528 globalSearchFlag := true;
529 end;
530
531 else
532 begin
533 raise EParsingFailed.Create('Unsupported switch');
534 end;
535 end;
[23]536 end;
537
[25]538
[54]539 FUNCTION getOwnHelpFileName: String;
540 begin
541 result := FindDefaultLanguageHelpFile('NewView');
542 end;
543
544
[42]545 FUNCTION nativeOS2GetCmdLineParameter : STRING;
546 VAR
547 tmpPtib : PTIB; // thread information block
548 tmpPpib : PPIB; // process information block
549 tmpCmd : PCHAR;
550 tmpResult : PCHAR;
551
552 BEGIN
553 // ask the system
554 DosGetInfoBlocks(tmpPtib, tmpPpib);
555 tmpCmd := tmpPpib^.pib_pchcmd;
556 // the fist element (null terminated) is the
557 // called command itself
558 // skip to the next null terminated string
559 // these are the parameters
560 tmpResult := tmpCmd + StrLen(tmpCmd) + 1;
561 result := StrPas(tmpResult);
562 END;
[23]563END.
Note: See TracBrowser for help on using the repository browser.