source: trunk/NewView/CmdLineParameterUnit.pas@ 30

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

comments removed

  • Property svn:eol-style set to native
File size: 14.6 KB
RevLine 
[23]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, BseTib, BseDos,
14 SysUtils,
15 Classes,
16
17 PMWIN,
18
19 ACLStringUtility,
20 ACLProfile,
21 ACLFileUtility;
22
23 CONST
24 SUCCESS = 0;
25 ERROR_UNMATCHED_QUOTE = -1;
26
27 TYPE
28 TWindowPosition = record
29 left: longint;
30 bottom: longint;
31 width: longint;
32 height: longint;
33 end;
34 TYPE
35 TCmdLineParameters = class
36 private
37 showUsageFlag : boolean;
38 searchTextFlag : boolean;
39 searchText : string;
40 globalSearchTextFlag : boolean;
41 globalSearchText : string;
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;
50 topics : string;
[23]51
52 public
53 FUNCTION getShowUsageFlag : boolean;
54 FUNCTION getSearchTextFlag : boolean;
55 FUNCTION getSearchText : string;
56 FUNCTION getGlobalSearchTextFlag : boolean;
57 FUNCTION getGlobalSearchText : string;
58 FUNCTION getLanguage : string;
59 FUNCTION getHelpManagerFlag : boolean;
[25]60 FUNCTION setHelpManagerFlag(aNewValue : boolean) : boolean;
[23]61 FUNCTION getHelpManagerWindow : integer;
62 FUNCTION getWindowPositionFlag : boolean;
63 FUNCTION getWindowPosition : TWindowPosition;
64 FUNCTION getOwnerWindow : integer;
65 FUNCTION getWindowTitle : string;
[25]66 FUNCTION getFileNames : string;
67 FUNCTION getTopics : string;
[23]68 PROCEDURE parseCmdLine(aSplittedCmdLine : TStringList);
69 end;
70
71 // returns a string containing the whole
72 // command line parametes
73 FUNCTION nativeOS2GetCmdLineParameter : STRING;
74
75 // returns a string containing the whole
76 // command line parametes
[25]77 FUNCTION splitCmdLineParameter(aCmdLineString : String; var aResult : TStringList) : integer;
[23]78
79 // Return true if param matches the form
80 // /Flag:value
81 // dash (-) can be used instead of slash (/)
82 // colon can be omitted
83 FUNCTION MatchValueParam( const aParam: string; const aFlag: string; var aValue: string): boolean;
84
85 // Return true if param matches the form
86 // /Flag
87 // dash (-) can be used instead of slash (/)
88 FUNCTION MatchFlagParam( const aParam: string; const aFlag: string): boolean;
89
90 // Extract a single element of a window position spec
91 // - take a value from comma-separated list
92 // - convert to numeric
93 // - if the number ends with P then take as
94 // a percentage of given dimension
95 FUNCTION ExtractPositionElement(Var aParamValue: string; aScreenDimension: longint) : longint;
96
97 // Extract a specified window position:
98 // X,Y,W,H
99 FUNCTION ExtractPositionSpec(aParamValue: string; Var aPosition: TWindowPosition ): boolean;
100Implementation
101
102 FUNCTION TCmdLineParameters.getShowUsageFlag : boolean;
103 begin
104 result := showUsageFlag;
105 end;
106
107
108 FUNCTION TCmdLineParameters.getSearchTextFlag : boolean;
109 begin
110 result := searchTextFlag;
111 end;
112
113
114 FUNCTION TCmdLineParameters.getSearchText : string;
115 begin
116 result := searchText;
117 end;
118
119
120 FUNCTION TCmdLineParameters.getGlobalSearchTextFlag : boolean;
121 begin
122 result := globalSearchTextFlag;
123 end;
124
125
126 FUNCTION TCmdLineParameters.getGlobalSearchText : string;
127 begin
128 result := globalSearchText;
129 end;
130
131
132 FUNCTION TCmdLineParameters.getLanguage : string;
133 begin
134 result := language;
135 end;
136
137
138 FUNCTION TCmdLineParameters.getHelpManagerFlag : boolean;
139 begin
140 result := helpManagerFlag;
141 end;
142
143
[25]144 FUNCTION TCmdLineParameters.setHelpManagerFlag(aNewValue : boolean) : boolean;
145 begin
146 helpManagerFlag := aNewValue;
147 result := helpManagerFlag;
148 end;
149
150
[23]151 FUNCTION TCmdLineParameters.getHelpManagerWindow : integer;
152 begin
153 result := helpManagerWindow;
154 end;
155
156
157 FUNCTION TCmdLineParameters.getWindowPositionFlag : boolean;
158 begin
159 result := windowPositionFlag;
160 end;
161
162
163 FUNCTION TCmdLineParameters.getWindowPosition : TWindowPosition;
164 begin
165 result := windowPosition;
166 end;
167
168
169 FUNCTION TCmdLineParameters.getOwnerWindow : integer;
170 begin
171 result := ownerWindow;
172 end;
173
174
175 FUNCTION TCmdLineParameters.getWindowTitle : string;
176 begin
177 result := windowTitle;
178 end;
179
180
[25]181 FUNCTION TCmdLineParameters.getFileNames : string;
[23]182 begin
[25]183 result := fileNames;
[23]184 end;
185
186
[25]187 FUNCTION TCmdLineParameters.getTopics : string;
[23]188 begin
[25]189 result := topics;
[23]190 end;
191
192
193 procedure TCmdLineParameters.parseCmdLine(aSplittedCmdLine : TStringList);
194 var
195 tmpParamIndex : integer;
196 tmpParameter : string;
197 tmpParameterValue : string;
198 begin
[25]199 ProfileEvent( 'ParseCommandLineParameters started' );
200
[23]201 // reset the whole object
202 showUsageFlag := false;
203 searchTextFlag := false;
204 searchText := '';
205 globalSearchTextFlag := false;
206 globalSearchText := '';
207 language := '';
208 helpManagerFlag := false;
209 helpManagerWindow := 0;
210 windowPositionFlag := false;
211 // windowPosition;
212 ownerWindow := 0;
213 windowTitle := '';
214
[25]215 filenames := '';
216 topics := '';
[23]217
218 // start parsing
219 for tmpParamIndex := 0 to aSplittedCmdLine.Count -1 do
220 begin
221 tmpParameter := aSplittedCmdLine[tmpParamIndex];
222
223 if MatchFlagParam(tmpParameter, '?')
224 or MatchFlagParam(tmpParameter, 'H')
225 or MatchFlagParam(tmpParameter, 'HELP') then
226 begin
227 showUsageFlag := true
228 end
229 else if MatchValueParam(tmpParameter, 'G', globalSearchText) then
230 begin
231 globalSearchTextFlag := true;
232 end
233 else if MatchValueParam(tmpParameter, 'S', searchText) then
234 begin
235 searchTextFlag := true;
236 end
237 else if MatchValueParam(tmpParameter, 'LANG', language) then
238 begin
239 // nothing to do
240 end
241 else if MatchValueParam(tmpParameter, 'HM', tmpParameterValue) then
242 begin
243 try
244 helpManagerWindow := StrToInt(tmpParameterValue);
245 helpManagerFlag := true;
246 except
247 // ignore invalid window value
248 end;
249 end
250 else if MatchValueParam(tmpParameter, 'OWNER', tmpParameterValue) then
251 begin
252 try
253 ownerWindow := StrToInt(tmpParameterValue);
254 except
255 // ignore invalid owner value
256 end;
257 end
258 else if MatchValueParam(tmpParameter, 'TITLE', windowTitle) then
259 begin
260 // nothing to do
261 end
262 else if MatchFlagParam(tmpParameter, 'PROFILE') then
263 begin
264 StartProfile(GetLogFilesDir + 'newview.prf' );
265 end
266 else if MatchValueParam(tmpParameter, 'POS', tmpParameterValue ) then
267 begin
268 // set window position/size
269 if ExtractPositionSpec(tmpParameterValue, windowPosition) then
270 begin
271 windowPositionFlag := true;
272 end
273 else
274 begin
275 // invalid...
276 showUsageFlag := true;
277 end;
278 end
279 else
280 begin
[25]281 if length(filenames) = 0 then
[23]282 begin
283 // filename
[25]284 fileNames := tmpParameter;
[23]285 end
286 else
287 begin
288 // search (topic) parameter... append all remaining thingies
[25]289 if topics <> '' then
[23]290 begin
[25]291 topics := topics + ' ';
[23]292 end;
[25]293 topics := topics + tmpParameter;
[23]294 end;
295 end;
296 end;
[25]297
298 ProfileEvent('Parameters parsed');
299 ProfileEvent(' Filename(s): ' + fileNames);
300 ProfileEvent(' Topic(s): ' + topics);
301 ProfileEvent( '...done' );
[23]302 end;
303
304
305FUNCTION nativeOS2GetCmdLineParameter : STRING;
306 VAR
307 tmpPtib : PTIB; /* thread information block */
308 tmpPpib : PPIB; /* process information block */
309 tmpCmd : PCHAR;
310 tmpResult : PCHAR;
311
312 BEGIN
313 DosGetInfoBlocks(tmpPtib, tmpPpib);
314 tmpCmd := tmpPpib^.pib_pchcmd;
315 tmpResult := tmpCmd + StrLen(tmpCmd) + 1;
316 nativeOS2GetCmdLineParameter := StrPas(tmpResult);
317 END;
318
319
[25]320FUNCTION splitCmdLineParameter(aCmdLineString : String; var aResult : TStringList) : integer;
[23]321 CONST
322 STATE_BEFORE = 0;
323 STATE_INSIDE = 1;
324 STATE_START_QUOTE = 2;
325 STATE_INSIDE_QUOTED = 3;
326 STATE_INSIDE_QUOTED_START_QUOTE = 4;
327 VAR
328 i : Integer;
329 tmpCurrentChar : char;
330 tmpState : INTEGER;
331 tmpCurrentCommand : String;
332
333 BEGIN
[25]334 result := SUCCESS;
335 aResult.Clear;
336
[28]337 tmpState := STATE_BEFORE;
[23]338 tmpCurrentCommand := '';
339 for i:=1 to length(aCmdLineString) do
340 begin
341 tmpCurrentChar := aCmdLineString[i];
342
343 Case tmpCurrentChar of
344 ' ' :
345 begin
346 Case tmpState of
347 STATE_BEFORE : {do nothing};
348 STATE_INSIDE :
349 begin
[25]350 aResult.add(tmpCurrentCommand);
[23]351 tmpCurrentCommand := '';
352 tmpState := STATE_BEFORE;
353 end;
354 STATE_INSIDE_QUOTED_START_QUOTE :
355 begin
[25]356 aResult.add(tmpCurrentCommand);
[23]357 tmpCurrentCommand := '';
358 tmpState := STATE_BEFORE;
359 end;
360 ELSE
361 begin
362 tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
363 end;
364 end;
365 end;
366
367 '"' :
368 begin
369 Case tmpState of
370 STATE_START_QUOTE :
371 begin
[28]372 tmpState := STATE_INSIDE_QUOTED_START_QUOTE;
[23]373 end;
374 STATE_INSIDE_QUOTED :
375 tmpState := STATE_INSIDE_QUOTED_START_QUOTE;
376 STATE_INSIDE_QUOTED_START_QUOTE :
377 begin
378 tmpState := STATE_INSIDE_QUOTED;
379 tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
380 end;
381 ELSE
382 tmpState := STATE_START_QUOTE;
383 end;
384 end;
385 ELSE
386 begin
387 Case tmpState of
388 STATE_BEFORE :
389 begin
390 tmpState := STATE_INSIDE;
391 tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
392 end;
393 STATE_INSIDE :
394 begin
395 tmpState := STATE_INSIDE;
396 tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
397 end;
398 STATE_START_QUOTE :
399 begin
400 tmpState := STATE_INSIDE_QUOTED;
401 tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
402 end;
403 STATE_INSIDE_QUOTED :
404 begin
405 tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
406 end;
407 STATE_INSIDE_QUOTED_START_QUOTE :
408 begin
409 tmpState := STATE_INSIDE;
410 tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
411 end;
412 end;
413 end;
414 end;
415 end;
416
417 Case tmpState of
418 STATE_BEFORE : { nothing to do};
419 STATE_INSIDE :
420 begin
[25]421 aResult.add(tmpCurrentCommand);
[23]422 end;
[29]423 STATE_START_QUOTE :
424 begin
425 result := ERROR_UNMATCHED_QUOTE;
426 end;
[23]427 STATE_INSIDE_QUOTED_START_QUOTE :
428 begin
[29]429 if (0 < length(tmpCurrentCommand)) then
430 begin
431 aResult.add(tmpCurrentCommand);
432 end;
[23]433 end;
[29]434 STATE_INSIDE_QUOTED :
435 begin
436 result := ERROR_UNMATCHED_QUOTE;
437 if (0 < length(tmpCurrentCommand)) then
438 begin
439 aResult.add(tmpCurrentCommand);
440 end;
441 end;
[23]442 ELSE
443 begin
[25]444 result := ERROR_UNMATCHED_QUOTE;
[29]445 if (0 < length(tmpCurrentCommand)) then
446 begin
447 aResult.add(tmpCurrentCommand);
448 end;
[23]449 end;
450 end;
451 END;
452
453
454FUNCTION MatchValueParam( const aParam: string; const aFlag: string; var aValue: string ): boolean;
455begin
456 Result := false;
457
458 if aParam = '' then
459 exit;
460
461 if ( aParam[ 1 ] <> '/' )
462 and ( aParam[ 1 ] <> '-' ) then
463 exit;
464
465 if CompareText(copy(aParam, 2, length(aFlag)), aFlag) <> 0 then
466 exit;
467
468 Result := true;
469
470 aValue := copy(aParam, 2 + length(aFlag), length(aParam));
471 if aValue <> '' then
472 if aValue[ 1 ] = ':' then
473 delete(aValue, 1, 1 );
474end;
475
476
477FUNCTION MatchFlagParam(const aParam: string; const aFlag: string ): boolean;
478begin
479 Result := false;
480
481 if aParam = '' then
482 exit;
483
484 if (aParam[ 1 ] <> '/' )
485 and (aParam[ 1 ] <> '-' ) then
486 exit;
487 Result := CompareText(copy(aParam, 2, length(aParam)-1), aFlag) = 0;
488end;
489
490
491FUNCTION ExtractPositionElement(Var aParamValue: string; aScreenDimension: longint ): longint;
492var
493 tmpElement: string;
494begin
495 tmpElement := ExtractNextValue(aParamValue, ',' );
496 if tmpElement = '' then
497 raise Exception.Create('Missing position element');
498 if StrEnds('P', tmpElement) then
499 begin
500 Delete(tmpElement, length(tmpElement), 1);
501 if tmpElement = '' then
502 raise Exception.Create('Missing position element');
503 Result := StrToInt(tmpElement);
504 if Result < 0 then
505 Result := 0;
506 if Result > 100 then
507 Result := 100;
508 Result := Round(Result / 100 * aScreenDimension);
509 end
510 else
511 begin
512 Result := StrToInt(tmpElement);
513 end;
514end;
515
516FUNCTION SystemMetrics(aSystemMetric : LONG) : LongInt;
517Begin
518 Result := WinQuerySysValue(HWND_DESKTOP, aSystemMetric);
519end;
520
521FUNCTION ExtractPositionSpec(aParamValue: string; Var aPosition: TWindowPosition ): boolean;
522begin
523 try
524 aPosition.Left := ExtractPositionElement(aParamValue, SystemMetrics(SV_CXSCREEN));
525 aPosition.Bottom := ExtractPositionElement(aParamValue, SystemMetrics(SV_CYSCREEN));
526 aPosition.Width := ExtractPositionElement(aParamValue, SystemMetrics(SV_CXSCREEN));
527 if aPosition.Width < 50 then
528 aPosition.Width := 50;
529 aPosition.Height := ExtractPositionElement(aParamValue, SystemMetrics(SV_CYSCREEN));
530 if aPosition.Height < 50 then
531 aPosition.Height := 50;
532 Result := true;
533 except
534 Result := false;
535 end;
536end;
537
[25]538
[23]539END.
Note: See TracBrowser for help on using the repository browser.