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
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
22 CONST
23 SUCCESS = 0;
24 ERROR_UNMATCHED_QUOTE = -1;
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 : integer;
45 windowPositionFlag: boolean;
46 windowPosition: TWindowPosition;
47 ownerWindow : integer;
48 windowTitle : string;
49 fileNames : string;
50 fileNamesRaw : string;
51 searchText : string;
52
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;
57 PROCEDURE parseSwitch(aCmdLineString : String);
58 PROPERTY getFileNames : string read fileNames;
59 PROPERTY getSearchText : string read searchText;
60
61 public
62 PROPERTY getCommandLine : String read commandLine;
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 : 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;
74 PROPERTY getFileNamesRaw : string read fileNamesRaw;
75
76 PROCEDURE writeDetailsTo(aStrings : TStrings);
77 PROCEDURE parseCmdLine(aCmdLineString : String);
78
79 FUNCTION getInterpretedFileNames: String;
80 FUNCTION getInterpretedSearchText: String;
81 end;
82
83 FUNCTION getOwnHelpFileName: String;
84
85 // returns a string containing the whole
86 // command line parametes
87 FUNCTION nativeOS2GetCmdLineParameter : String;
88
89
90Implementation
91uses
92 ACLFileUtility;
93
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
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;
156
157 if not getGlobalSearchFlag
158 AND (not getSearchFlag)
159 then
160 begin
161 result := StrTrim(result);
162 result := StrTrimChars(result, ['"']);
163 end;
164
165 end;
166
167
168 FUNCTION TCmdLineParameters.setHelpManagerFlag(aNewValue : boolean) : boolean;
169 begin
170 helpManagerFlag := aNewValue;
171 result := helpManagerFlag;
172 end;
173
174
175 procedure TCmdLineParameters.parseCmdLine(aCmdLineString : String);
176 var
177 tmpState : (SWITCH, FILENAME, FILENAME_QUOTE, TEXT);
178 tmpCurrentChar : char;
179 begin
180 LogEvent(LogStartup, 'ParseCommandLine: "' + aCmdLineString + '"');
181
182 // store the original string for debugging
183 commandLine := aCmdLineString;
184
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 := '';
196 fileNames := '';
197 fileNamesRaw := '';
198
199 try
200 // start parsing
201 tmpState := FILENAME;
202 currentParsePosition := 1;
203 while currentParsePosition <= length(aCmdLineString) do
204 begin
205 tmpCurrentChar := aCmdLineString[currentParsePosition];
206
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
219 begin
220 tmpState := TEXT;
221 end;
222 inc(currentParsePosition);
223 end;
224 FILENAME_QUOTE :
225 begin
226 fileNames := fileNames + tmpCurrentChar;
227 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
228 inc(currentParsePosition);
229 end;
230 TEXT :
231 begin
232 searchText := searchText + tmpCurrentChar;
233 inc(currentParsePosition);
234 end;
235 end;
236 end;
237
238 '/', '-' :
239 begin
240 Case tmpState of
241 SWITCH :
242 begin
243 tmpState := SWITCH;
244 parseSwitch(aCmdLineString);
245 end;
246 FILENAME :
247 begin
248 if length(fileNames) < 1 then
249 begin
250 tmpState := SWITCH;
251 parseSwitch(aCmdLineString);
252 end
253 else
254 begin
255 fileNames := fileNames + tmpCurrentChar;
256 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
257 inc(currentParsePosition);
258 end;
259 end;
260 FILENAME_QUOTE :
261 begin
262 fileNames := fileNames + tmpCurrentChar;
263 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
264 inc(currentParsePosition);
265 end;
266 else
267 begin
268 searchText := searchText + tmpCurrentChar;
269 inc(currentParsePosition);
270 end;
271 end;
272 end;
273
274 '"' :
275 begin
276 Case tmpState of
277 SWITCH :
278 begin
279 // syntax error
280 raise EParsingFailed.Create('Unsupported switch');
281 end;
282 FILENAME :
283 begin
284 tmpState := FILENAME_QUOTE;
285 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
286 inc(currentParsePosition);
287 end;
288 FILENAME_QUOTE :
289 begin
290 tmpState := FILENAME;
291 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
292 inc(currentParsePosition);
293 end;
294 TEXT :
295 begin
296 searchText := searchText + tmpCurrentChar;
297 inc(currentParsePosition);
298 end;
299 end;
300 end;
301
302 else
303 begin
304 Case tmpState of
305 SWITCH :
306 begin
307 // syntax error
308 raise EParsingFailed.Create('Unsupported switch');
309 end;
310 FILENAME :
311 begin
312 fileNames := fileNames + tmpCurrentChar;
313 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
314 inc(currentParsePosition);
315 end;
316 FILENAME_QUOTE :
317 begin
318 fileNames := fileNames + tmpCurrentChar;
319 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
320 inc(currentParsePosition);
321 end;
322 else
323 begin
324 searchText := searchText + tmpCurrentChar;
325 inc(currentParsePosition);
326 end;
327 end;
328 end;
329 end;
330 end;
331
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;
366 END;
367
368
369
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);
378
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;
386
387 aValue := readNextPart(aCmdLineString, [' ', '-', '/']);
388 currentParsePosition := currentParsePosition + length(aValue);
389 result := true;
390 exit;
391 end;
392 result := false;
393 end;
394
395
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');
402
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');
408
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;
421
422 Function ParseWindowPosition(const aParamValue: String): TWindowPosition;
423 Var
424 tmpParts : TStringList;
425 Begin
426 tmpParts := TStringList.Create;
427 StrExtractStrings(tmpParts, aParamValue, [','], '\');
428
429 result.Left := ParseWindowPositionPart(tmpParts[0], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
430 result.Bottom := ParseWindowPositionPart(tmpParts[1], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
431
432 result.Width := ParseWindowPositionPart(tmpParts[2], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
433 if result.Width < 50 then
434 result.Width := 50;
435
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;
441 end;
442
443
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;
536 end;
537
538
539 FUNCTION getOwnHelpFileName: String;
540 begin
541 result := FindDefaultLanguageHelpFile('NewView');
542 end;
543
544
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;
563END.
Note: See TracBrowser for help on using the repository browser.