source: trunk/NewView/CmdLineParameterUnit.pas@ 78

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

method name refactoring

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