source: trunk/NewView/CmdLineParameterUnit.pas@ 76

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

improved debug switch 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
[76]23 ENV_DEBUG = 'NEWVIEW_DEBUG';
[23]24
[76]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;
[69]44 helpManagerWindow : HWND;
[23]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
[67]53 FUNCTION handleSwitchWithValue(const aSwitchString : String; const aSwitch : String; var aValue : String) : Boolean;
54 PROCEDURE parseSwitch(aSwitchString : String);
[65]55 PROPERTY getFileNames : string read fileNames;
56 PROPERTY getSearchText : string read searchText;
[42]57
[23]58 public
[42]59 PROPERTY getCommandLine : String read commandLine;
[32]60 PROPERTY getShowUsageFlag : boolean read showUsageFlag;
[42]61 PROPERTY getSearchFlag : boolean read searchFlag;
62 PROPERTY getGlobalSearchFlag : boolean read globalSearchFlag;
[32]63 PROPERTY getLanguage : string read language;
64 PROPERTY getHelpManagerFlag : boolean read helpManagerFlag;
[25]65 FUNCTION setHelpManagerFlag(aNewValue : boolean) : boolean;
[69]66 PROPERTY getHelpManagerWindow : HWND read helpManagerWindow;
[32]67 PROPERTY getWindowPositionFlag : boolean read windowPositionFlag;
68 PROPERTY getWindowPosition : TWindowPosition read windowPosition;
69 PROPERTY getOwnerWindow : integer read ownerWindow;
70 PROPERTY getWindowTitle : string read windowTitle;
[45]71 PROPERTY getFileNamesRaw : string read fileNamesRaw;
[42]72
[65]73 PROCEDURE writeDetailsTo(aStrings : TStrings);
[42]74 PROCEDURE parseCmdLine(aCmdLineString : String);
[54]75
76 FUNCTION getInterpretedFileNames: String;
77 FUNCTION getInterpretedSearchText: String;
[23]78 end;
79
[54]80 FUNCTION getOwnHelpFileName: String;
81
[42]82 // returns a string containing the whole
83 // command line parametes
[54]84 FUNCTION nativeOS2GetCmdLineParameter : String;
[23]85
86
87Implementation
[54]88uses
[76]89 DOS,
[54]90 ACLFileUtility;
[23]91
[65]92 PROCEDURE TCmdLineParameters.writeDetailsTo(aStrings : TStrings);
93 var
94 tmpWindowPosition : TWindowPosition;
95 begin
[67]96 aStrings.Add('''' + getCommandLine + '''');
[65]97 aStrings.Add('parsed infos:');
98
99 aStrings.Add('getShowUsageFlag: ' + boolToStr(getShowUsageFlag));
100 aStrings.Add('getSearchFlag: ' + boolToStr(getSearchFlag));
101 aStrings.Add('getSearchText: ' + getSearchText);
102 aStrings.Add('getGlobalSearchFlag: ' + boolToStr(getGlobalSearchFlag));
103 aStrings.Add('getLanguage: ' + getLanguage);
104 aStrings.Add('getHelpManagerFlag: ' + boolToStr(getHelpManagerFlag));
[69]105 aStrings.Add('getHelpManagerWindow: ' + LongWordToStr(getHelpManagerWindow));
[65]106 aStrings.Add('getWindowPositionFlag: ' + boolToStr(getWindowPositionFlag));
107 aStrings.Add('getFileNames: ' + getFileNames);
108 aStrings.Add('getInterpretedSearchText: ' + getInterpretedSearchText);
109 aStrings.Add('getInterpretedFileNames: ' + getInterpretedFileNames);
110
111 tmpWindowPosition := getWindowPosition;
112 aStrings.Add('getWindowPosition: '
113 + intToStr(tmpWindowPosition.left) + ', '
114 + intToStr(tmpWindowPosition.bottom) + ', '
115 + intToStr(tmpWindowPosition.width) + ', '
116 + intToStr(tmpWindowPosition.height)
117 );
118 aStrings.Add('getOwnerWindow: ' + intToStr(getOwnerWindow));
119 aStrings.Add('getWindowTitle: ' + getWindowTitle);
120 end;
121
122
[67]123 Function TCmdLineParameters.getInterpretedFileNames: String;
[54]124 var
125 tmpOwnHelpFileName : String;
126 begin
127 result := getFileNames;
128
129 if getGlobalSearchFlag
130 AND (getSearchText = '')
131 then
132 begin
133 result := '';
134 exit;
135 end;
136
137
138 tmpOwnHelpFileName := FindDefaultLanguageHelpFile('NewView');
139 if (result = '') AND
140 FileExists(tmpOwnHelpFileName)
141 then
142 result := tmpOwnHelpFileName;
143 end;
144
145
[67]146 Function TCmdLineParameters.getInterpretedSearchText: String;
[54]147 begin
148 result := getSearchText;
149
150 if getGlobalSearchFlag
151 AND (result = '')
152 then
153 result := getFileNamesRaw;
[65]154
155 if not getGlobalSearchFlag
156 AND (not getSearchFlag)
157 then
158 begin
159 result := StrTrim(result);
160 result := StrTrimChars(result, ['"']);
161 end;
[54]162 end;
163
164
[67]165 Function TCmdLineParameters.setHelpManagerFlag(aNewValue : boolean) : boolean;
[25]166 begin
167 helpManagerFlag := aNewValue;
168 result := helpManagerFlag;
169 end;
170
171
[67]172 Procedure TCmdLineParameters.parseCmdLine(aCmdLineString : String);
[23]173 var
[67]174 tmpState : (WHITESPACE, QUOTE, SWITCH, FILENAME, TEXT);
175 tmpCurrentParsePosition : integer;
176 tmpQuoted : boolean;
[42]177 tmpCurrentChar : char;
[67]178 tmpWhitespace : String;
179 tmpQuote : String;
180 tmpSwitch : String;
[23]181 begin
[76]182 // first adjust logging
183 if GetEnv(ENV_DEBUG) = '' then
184 begin
185 // TODO set boolean
186 end
187 else
188 begin
189 SetLogAspects(GetEnv(ENV_DEBUG));
190 end;
[25]191
[76]192 LogEvent(LogStartup, 'ParseCommandLine: "' + aCmdLineString + '"');
[23]193
[76]194 // store the original string for debugging
195 commandLine := aCmdLineString;
[23]196
[76]197 // reset the whole object
198 showUsageFlag := false;
199 searchFlag := false;
200 globalSearchFlag := false;
201 language := '';
202 helpManagerFlag := false;
203 helpManagerWindow := 0;
204 windowPositionFlag := false;
205 ownerWindow := 0;
206 windowTitle := '';
207 searchText := '';
208 fileNames := '';
209 fileNamesRaw := '';
[23]210
[76]211 try
212 // start parsing
213 tmpState := WHITESPACE;
214 tmpWhitespace := '';
215 tmpSwitch := '';
216 tmpQuote := '';
217 tmpQuoted := false;
218 tmpCurrentParsePosition := 1;
219 while tmpCurrentParsePosition <= length(aCmdLineString) do
220 begin
221 tmpCurrentChar := aCmdLineString[tmpCurrentParsePosition];
[67]222
[76]223 Case tmpCurrentChar of
224 ' ' :
225 begin
226 Case tmpState of
[67]227
[76]228 WHITESPACE :
229 begin
230 tmpWhitespace := tmpWhitespace + tmpCurrentChar;
231 end;
[67]232
[76]233 QUOTE :
234 begin
235 tmpQuote := tmpQuote + tmpCurrentChar;
236 end;
[67]237
[76]238 SWITCH :
239 begin
240 if tmpQuoted then
241 begin
242 tmpSwitch := tmpSwitch + tmpCurrentChar;
243 end
244 else
245 begin
246 parseSwitch(tmpSwitch);
247 tmpState := WHITESPACE;
248 tmpWhitespace := tmpCurrentChar;
249 end
250 end;
[67]251
[76]252 FILENAME :
253 begin
254 if tmpQuoted then
255 begin
256 fileNames := fileNames + tmpCurrentChar;
257 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
258 end
259 else
260 begin
261 tmpState := WHITESPACE;
262 tmpWhitespace := tmpCurrentChar;
263 end
264 end;
[25]265
[76]266 TEXT :
267 begin
268 if tmpQuoted then
269 begin
270 searchText := searchText + tmpCurrentChar;
271 end
272 else
273 begin
274 tmpState := WHITESPACE;
275 tmpWhitespace := tmpCurrentChar;
276 end
277 end;
278 end;
279 end;
[67]280
[76]281 '/', '-' :
282 begin
283 Case tmpState of
284 WHITESPACE :
285 begin
286 tmpState := SWITCH;
287 tmpSwitch := '';
288 end;
[67]289
[76]290 QUOTE :
291 begin
292 tmpState := SWITCH;
293 tmpSwitch := '';
294 end;
[67]295
[76]296 SWITCH :
297 begin
298 parseSwitch(tmpSwitch);
299 tmpSwitch := '';
300 end;
[67]301
[76]302 FILENAME :
303 begin
304 fileNames := fileNames + tmpCurrentChar;
305 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
306 end;
[67]307
[76]308 TEXT :
309 begin
310 searchText := searchText + tmpCurrentChar;
311 end;
312 end;
313 end;
[42]314
[76]315 '"' :
316 begin
317 if tmpQuoted then
318 begin
319 tmpQuoted := false;
320 Case tmpState of
321 FILENAME :
322 begin
323 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
324 end;
325 end;
326 end
327 else
328 begin
329 Case tmpState of
330 WHITESPACE :
331 begin
332 tmpState := QUOTE;
333 tmpQuote := tmpCurrentChar;
334 end;
335 FILENAME :
336 begin
337 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
338 end;
339 end;
340 tmpQuoted := true;
341 end;
342 end;
[67]343
[76]344 // any other char
345 else
346 begin
347 Case tmpState of
[67]348
[76]349 WHITESPACE :
350 begin
351 if length(fileNames) > 0 then
352 begin
353 tmpState := TEXT;
354 searchText := searchText + tmpWhitespace + tmpCurrentChar;
355 end
356 else
357 begin
358 tmpState := FILENAME;
359 fileNames := fileNames + tmpCurrentChar;
360 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
361 end;
362 end;
[67]363
[76]364 QUOTE :
365 begin
366 if length(fileNames) > 0 then
367 begin
368 tmpState := TEXT;
369 searchText := searchText + tmpWhitespace + tmpCurrentChar;
370 end
371 else
372 begin
373 tmpState := FILENAME;
374 fileNames := fileNames + tmpCurrentChar;
375 fileNamesRaw := fileNamesRaw + tmpQuote + tmpCurrentChar;
376 end;
377 end;
[67]378
[76]379 SWITCH :
380 begin
381 tmpSwitch := tmpSwitch + tmpCurrentChar;
382 end;
[67]383
[76]384 FILENAME :
385 begin
386 fileNames := fileNames + tmpCurrentChar;
387 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
388 end;
389
390 TEXT :
391 begin
392 searchText := searchText + tmpCurrentChar;
393 end;
394 end;
395 end;
[42]396 end;
[67]397 inc(tmpCurrentParsePosition);
[42]398 end;
[23]399
[67]400 // ok all chars are processed, but maybe we have something to do
401 Case tmpState of
402 SWITCH :
403 begin
404 parseSwitch(tmpSwitch);
405 end;
[76]406 end;
407 // TODO remove interpreted
[42]408 except
409 on e:EParsingFailed do
410 begin
411 showUsageFlag := true;
412 end;
413 end;
414
415 // remove leading blanks from search text
416 searchText := StrTrim(searchText);
417
418 LogEvent(LogStartup, 'Parameters parsed');
419 LogEvent(LogStartup, ' Filename(s): "' + fileNames + '"');
420 LogEvent(LogStartup, ' Search Text: "' + searchText + '"');
421 end;
422
423
[67]424 Function TCmdLineParameters.handleSwitchWithValue(const aSwitchString : String; const aSwitch : String; var aValue : String) : Boolean;
[42]425 var
426 tmpText : String;
[67]427 tmpValueStartPos : integer;
[42]428 tmpSwitchLength : integer;
429 begin
430 tmpSwitchLength := Length(aSwitch);
[67]431 tmpText := copy(aSwitchString, 1, tmpSwitchLength);
[42]432 tmpText := lowercase(tmpText);
[23]433
[42]434 if (lowercase(aSwitch) = tmpText) then
435 begin
[67]436 tmpValueStartPos := tmpSwitchLength;
437 inc(tmpValueStartPos);
438 if aSwitchString[tmpValueStartPos] = ':' then
[42]439 begin
[67]440 inc(tmpValueStartPos);
[42]441 end;
[23]442
[67]443 aValue := copy(aSwitchString, tmpValueStartPos, Length(aSwitchString) - tmpValueStartPos+ 1);
[42]444 result := true;
445 exit;
446 end;
447 result := false;
448 end;
[23]449
450
[42]451 Function ParseWindowPositionPart(const aPart: String; const aScreenDimension: longint): longint;
452 Var
453 tmpPart : String;
454 Begin
455 if aPart = '' then
456 raise EParsingFailed.Create('Missing position element');
[23]457
[42]458 if StrEndsWithIgnoringCase(aPart, 'P') then
459 begin
460 tmpPart := copy(aPart, 1, length(aPart)-1);
461 if tmpPart = '' then
462 raise EParsingFailed.Create('Missing position element');
[23]463
[42]464 Result := StrToInt(tmpPart);
465 if Result < 0 then
466 Result := 0;
467 if Result > 100 then
468 Result := 100;
469 Result := Round(Result / 100 * aScreenDimension);
470 end
471 else
472 begin
473 Result := StrToInt(aPart);
474 end;
475 end;
[23]476
[42]477 Function ParseWindowPosition(const aParamValue: String): TWindowPosition;
478 Var
479 tmpParts : TStringList;
480 Begin
481 tmpParts := TStringList.Create;
482 StrExtractStrings(tmpParts, aParamValue, [','], '\');
[23]483
[42]484 result.Left := ParseWindowPositionPart(tmpParts[0], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
485 result.Bottom := ParseWindowPositionPart(tmpParts[1], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
[23]486
[42]487 result.Width := ParseWindowPositionPart(tmpParts[2], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
488 if result.Width < 50 then
489 result.Width := 50;
[23]490
[42]491 result.Height := ParseWindowPositionPart(tmpParts[3], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
492 if result.Height < 50 then
493 result.Height := 50;
494
495 tmpParts.Destroy;
[23]496 end;
497
498
[67]499 Procedure TCmdLineParameters.parseSwitch(aSwitchString : String);
[42]500 var
501 tmpCurrentChar : char;
502 tmpValue : String;
503 begin
504 // lang
[67]505 if handleSwitchWithValue(aSwitchString, 'lang', tmpValue) then
[42]506 begin
507 language := tmpValue;
508 exit;
509 end;
510
511 // title
[67]512 if handleSwitchWithValue(aSwitchString, 'title', tmpValue) then
[42]513 begin
514 windowTitle := tmpValue;
515 exit;
516 end;
517
518 // HM
[67]519 if handleSwitchWithValue(aSwitchString, 'hm', tmpValue) then
[42]520 begin
521 try
522 helpManagerWindow := StrToInt(tmpValue);
523 helpManagerFlag := true;
524 except
525 on e:Exception do
526 begin
527 showUsageFlag := true;
528 end;
529 end;
530 exit;
531 end;
532
533 // owner
[67]534 if handleSwitchWithValue(aSwitchString, 'owner', tmpValue) then
[42]535 begin
536 try
537 ownerWindow := StrToInt(tmpValue);
538 except
539 on e:Exception do
540 begin
541 showUsageFlag := true;
542 end;
543 end;
544 exit;
545 end;
546
547 // pos
[67]548 if handleSwitchWithValue(aSwitchString, 'pos', tmpValue) then
[42]549 begin
550 windowPosition := ParseWindowPosition(tmpValue);
551 windowPositionFlag := true;
552 exit;
553 end;
554
555 // check the next char
[67]556 // TODO check for other invalid chars
557 tmpCurrentChar := aSwitchString[1];
[42]558 Case tmpCurrentChar of
559 'h', 'H', '?' :
560 begin
561 showUsageFlag := true;
562 end;
563
564 's', 'S' :
565 begin
566 searchFlag := true;
567 end;
568
569 'g', 'G' :
570 begin
571 globalSearchFlag := true;
572 end;
573
574 else
575 begin
576 raise EParsingFailed.Create('Unsupported switch');
577 end;
578 end;
[23]579 end;
580
[25]581
[54]582 FUNCTION getOwnHelpFileName: String;
583 begin
584 result := FindDefaultLanguageHelpFile('NewView');
585 end;
586
587
[42]588 FUNCTION nativeOS2GetCmdLineParameter : STRING;
589 VAR
590 tmpPtib : PTIB; // thread information block
591 tmpPpib : PPIB; // process information block
592 tmpCmd : PCHAR;
593 tmpResult : PCHAR;
594
595 BEGIN
596 // ask the system
597 DosGetInfoBlocks(tmpPtib, tmpPpib);
598 tmpCmd := tmpPpib^.pib_pchcmd;
599 // the fist element (null terminated) is the
600 // called command itself
601 // skip to the next null terminated string
602 // these are the parameters
603 tmpResult := tmpCmd + StrLen(tmpCmd) + 1;
604 result := StrPas(tmpResult);
605 END;
[23]606END.
Note: See TracBrowser for help on using the repository browser.