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
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
22 CONST
23 SUCCESS = 0;
24 ERROR_UNMATCHED_QUOTE = -1;
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;
44 helpManagerWindow : integer;
45 windowPositionFlag: boolean;
46 windowPosition: TWindowPosition;
47 ownerWindow : integer;
48 windowTitle : string;
[25]49 fileNames : string;
[45]50 fileNamesRaw : string;
[42]51 searchText : string;
[23]52
[42]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;
[63]57 PROCEDURE parseSwitch(aCmdLineString : String);
[42]58
[23]59 public
[42]60 PROPERTY getCommandLine : String read commandLine;
[32]61 PROPERTY getShowUsageFlag : boolean read showUsageFlag;
[42]62 PROPERTY getSearchFlag : boolean read searchFlag;
63 PROPERTY getGlobalSearchFlag : boolean read globalSearchFlag;
[32]64 PROPERTY getLanguage : string read language;
65 PROPERTY getHelpManagerFlag : boolean read helpManagerFlag;
[25]66 FUNCTION setHelpManagerFlag(aNewValue : boolean) : boolean;
[32]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;
[45]73 PROPERTY getFileNamesRaw : string read fileNamesRaw;
[42]74 PROPERTY getSearchText : string read searchText;
75
76 PROCEDURE parseCmdLine(aCmdLineString : String);
[54]77
78 FUNCTION getInterpretedFileNames: String;
79 FUNCTION getInterpretedSearchText: 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
91 ACLFileUtility;
[23]92
[54]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
[25]127 FUNCTION TCmdLineParameters.setHelpManagerFlag(aNewValue : boolean) : boolean;
128 begin
129 helpManagerFlag := aNewValue;
130 result := helpManagerFlag;
131 end;
132
133
[42]134 procedure TCmdLineParameters.parseCmdLine(aCmdLineString : String);
[23]135 var
[42]136 tmpState : (SWITCH, FILENAME, FILENAME_QUOTE, TEXT);
137 tmpCurrentChar : char;
[23]138 begin
[42]139 LogEvent(LogStartup, 'ParseCommandLine: "' + aCmdLineString + '"');
[25]140
[42]141 // store the original string for debugging
142 commandLine := aCmdLineString;
[23]143
[42]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 := '';
[45]155 fileNames := '';
156 fileNamesRaw := '';
[23]157
[42]158 try
159 // start parsing
160 tmpState := FILENAME;
161 currentParsePosition := 1;
162 while currentParsePosition <= length(aCmdLineString) do
163 begin
164 tmpCurrentChar := aCmdLineString[currentParsePosition];
[23]165
[42]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
[23]178 begin
[42]179 tmpState := TEXT;
[23]180 end;
[42]181 inc(currentParsePosition);
182 end;
183 FILENAME_QUOTE :
184 begin
[45]185 fileNames := fileNames + tmpCurrentChar;
186 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]187 inc(currentParsePosition);
188 end;
189 TEXT :
190 begin
191 searchText := searchText + tmpCurrentChar;
192 inc(currentParsePosition);
193 end;
[23]194 end;
[42]195 end;
[25]196
[42]197 '/', '-' :
198 begin
[23]199 Case tmpState of
[42]200 SWITCH :
[23]201 begin
[42]202 tmpState := SWITCH;
203 parseSwitch(aCmdLineString);
[23]204 end;
[42]205 FILENAME :
[23]206 begin
[42]207 if length(fileNames) < 1 then
208 begin
209 tmpState := SWITCH;
210 parseSwitch(aCmdLineString);
211 end
212 else
213 begin
[45]214 fileNames := fileNames + tmpCurrentChar;
215 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]216 inc(currentParsePosition);
217 end;
[23]218 end;
[42]219 FILENAME_QUOTE :
[23]220 begin
[45]221 fileNames := fileNames + tmpCurrentChar;
222 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]223 inc(currentParsePosition);
[23]224 end;
[42]225 else
226 begin
227 searchText := searchText + tmpCurrentChar;
228 inc(currentParsePosition);
229 end;
[23]230 end;
[42]231 end;
[23]232
[42]233 '"' :
234 begin
[23]235 Case tmpState of
[42]236 SWITCH :
[23]237 begin
[42]238 // syntax error
239 raise EParsingFailed.Create('Unsupported switch');
[23]240 end;
[42]241 FILENAME :
[23]242 begin
[42]243 tmpState := FILENAME_QUOTE;
[45]244 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]245 inc(currentParsePosition);
[23]246 end;
[42]247 FILENAME_QUOTE :
[23]248 begin
[42]249 tmpState := FILENAME;
[45]250 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]251 inc(currentParsePosition);
[23]252 end;
[42]253 TEXT :
[23]254 begin
[42]255 searchText := searchText + tmpCurrentChar;
256 inc(currentParsePosition);
[23]257 end;
[42]258 end;
259 end;
260
261 else
262 begin
263 Case tmpState of
264 SWITCH :
[23]265 begin
[42]266 // syntax error
267 raise EParsingFailed.Create('Unsupported switch');
[23]268 end;
[42]269 FILENAME :
[23]270 begin
[42]271 fileNames := fileNames + tmpCurrentChar;
[45]272 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]273 inc(currentParsePosition);
[23]274 end;
[42]275 FILENAME_QUOTE :
[23]276 begin
[45]277 fileNames := fileNames + tmpCurrentChar;
278 fileNamesRaw := fileNamesRaw + tmpCurrentChar;
[42]279 inc(currentParsePosition);
[23]280 end;
[42]281 else
282 begin
283 searchText := searchText + tmpCurrentChar;
284 inc(currentParsePosition);
[23]285 end;
[42]286 end;
287 end;
288 end;
289 end;
[23]290
[42]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;
[23]325 END;
326
327
328
[42]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);
[23]337
[42]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;
[23]345
[42]346 aValue := readNextPart(aCmdLineString, [' ', '-', '/']);
347 currentParsePosition := currentParsePosition + length(aValue);
348 result := true;
349 exit;
350 end;
351 result := false;
352 end;
[23]353
354
[42]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');
[23]361
[42]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');
[23]367
[42]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;
[23]380
[42]381 Function ParseWindowPosition(const aParamValue: String): TWindowPosition;
382 Var
383 tmpParts : TStringList;
384 Begin
385 tmpParts := TStringList.Create;
386 StrExtractStrings(tmpParts, aParamValue, [','], '\');
[23]387
[42]388 result.Left := ParseWindowPositionPart(tmpParts[0], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
389 result.Bottom := ParseWindowPositionPart(tmpParts[1], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
[23]390
[42]391 result.Width := ParseWindowPositionPart(tmpParts[2], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
392 if result.Width < 50 then
393 result.Width := 50;
[23]394
[42]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;
[23]400 end;
401
402
[42]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;
[23]495 end;
496
[25]497
[54]498 FUNCTION getOwnHelpFileName: String;
499 begin
500 result := FindDefaultLanguageHelpFile('NewView');
501 end;
502
503
[42]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;
[23]522END.
Note: See TracBrowser for help on using the repository browser.