source: trunk/NewView/CmdLineParameterUnit.pas@ 63

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

formating fix

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