source: trunk/NewView/CmdLineParameterUnit.pas@ 109

Last change on this file since 109 was 109, checked in by RBRi, 18 years ago

updates for AnsiString usage

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