-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathJet.CommandLine.pas
More file actions
129 lines (106 loc) · 3.37 KB
/
Jet.CommandLine.pas
File metadata and controls
129 lines (106 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
unit Jet.CommandLine;
{
Command line parsing home.
}
interface
uses SysUtils, StringUtils;
type
EUsage = class(Exception);
procedure BadUsage(msg: UniString='');
procedure Redefined(term: string; old, new: UniString);
procedure Define(var Term: UniString; TermName: string; Value: UniString);
type
{
Command line parsing context. For now its a record because it's easier to track its lifetime.
We may later make this a virtual class and overrides will pull params from different sources:
string, TStringList, ParamStr()
As far as this module is concerned:
argument == any continuous element in the command line
option == argument starting with - or --
param == any element in the command line which serves as a parameter for the preceding argument
}
TParsingContext = record
i: integer;
procedure Reset;
function TryNextArg(out value: UniString): boolean;
function NextParam(key, param: UniString): UniString;
function TryNextParam(key, param: UniString; out value: UniString): boolean;
end;
PParsingContext = ^TParsingContext;
TCommandLineParser = class
public
procedure PrintUsage; virtual;
procedure Reset; virtual;
function HandleOption(ctx: PParsingContext; const s: UniString): boolean; virtual;
procedure Finalize; virtual;
end;
implementation
procedure BadUsage(msg: UniString='');
begin
raise EUsage.Create(msg);
end;
procedure Redefined(term: string; old, new: UniString);
begin
raise EUsage.Create(term+' already specified: '+old+'. Cannot process command "'+new+'".');
end;
procedure Define(var Term: UniString; TermName: string; Value: UniString);
begin
if Term <> '' then
Redefined(TermName, Term, Value);
Term := Value;
end;
procedure TParsingContext.Reset;
begin
i := 0;
end;
//Tries to consume one more argument from the command line or returns false
function TParsingContext.TryNextArg(out value: UniString): boolean;
begin
Result := (i < ParamCount);
if Result then begin
Inc(i);
value := ParamStr(i);
end;
end;
//Tries to consume one more _parameter_ for the current _argument_ from the command line.
//Parameters can't start with - or --, this is considered the beginning of the next option.
//If you need this format, use TryNextArg.
function TParsingContext.TryNextParam(key, param: UniString; out value: UniString): boolean;
begin
if i >= ParamCount then begin
Result := false;
exit;
end;
value := ParamStr(i+1);
Result := not value.StartsWith('-');
if Result then
Inc(i)
else
value := '';
end;
function TParsingContext.NextParam(key, param: UniString): UniString;
begin
Inc(i);
if i > ParamCount then
BadUsage(Key+' requires specifying the '+param);
Result := ParamStr(i);
end;
procedure TCommandLineParser.PrintUsage;
begin
//Override to output help for the options covered
end;
procedure TCommandLineParser.Reset;
begin
//Override to reset any configurable values to their default state
end;
function TCommandLineParser.HandleOption(ctx: PParsingContext; const s: string): boolean;
begin
//Override to handle some options and return true
Result := false;
end;
procedure TCommandLineParser.Finalize;
begin
//Override to perform any post-processing and consistency checks after parsing
//the available parameters.
end;
end.