source: trunk/NewView/CmdLineParameterUnit.pas@ 80

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

improved log handling

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