-
Notifications
You must be signed in to change notification settings - Fork 2
/
CPM.GetOptions.inc.xml
114 lines (103 loc) · 3.63 KB
/
CPM.GetOptions.inc.xml
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
<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25">
<Routine name="CPM.GetOptions" type="INC"><![CDATA[
/// given single command-line extract 1st verb as command and all the rest
/// as arguments array
ExtractArgs(&line,&command,&args) {
#dim pattern As %String = ##class(%Regex.Matcher).%New("\""([^\""]+)\""|[^ ]+")
set line = $zstrip(line,"<>WC")
set command = $piece(line," ")
set line = $piece(line," ",2,*)
kill args
set args = 0
set pattern.Text = line
while pattern.Locate() {
set argument = pattern.Group
set args($increment(args)) = $zstrip(argument, "<>", """")
}
}
#define OptionBoolean 1
#define OptionString 2
/// parse options from args array according format specifications from dmtDest
/// each option specification is preceeding destination variable (passed by reference)
///
/// GetOptions(.args,"-o",.option,"/verbose|/v",.verbose,"/include:",.include)
GetOptions(&args,&fmtDest...) public {
#dim known ; known options
// 1. scan options
for i=1:2:$get(fmtDest) {
#dim opts As %String = $get(fmtDest(i))
continue:opts=""
for j=1:1:$length(opts,"|") {
#dim opt As %String = $zstrip($piece(opts,"|",j), "<>", "-/")
#dim lastC As %String = $e(opt,*)
#dim optType As %Integer = $case(lastC, ":":$$$OptionString, :$$$OptionBoolean)
set opt = $zstrip(opt,"<>",":")
set known(opt) = $lb(optType, i + 1) ; remember option type and destination argument pointer
}
}
#dim argsN = "" ; new args without processed known options
// 2. process passed args while creating new modified args (without known /options)
for i=1:1:$get(args) {
#dim arg As %String = $get(args(i))
#dim isOption As %Boolean = $case($extract(arg,1),"/":1, "-":1, :0)
if isOption {
#dim option As %String = $zstrip(arg, "<>", "-/:")
#dim optInfo = $get(known(option))
if option = "help" {
// special case - processed separately
do ShowOptionsHelp(.fmtDest)
return 0
}
if $length(optInfo)>0 {
#dim type As %Integer = $li(optInfo,1)
#dim index As %Integer = $li(optInfo,2)
if type=$$$OptionBoolean {
set fmtDest(index) = 1
} else {
set fmtDest(index) = $get(args($i(i)))
}
} else {
return i ; unknown /option - bails out
}
} else {
set argsN($i(argsN)) = arg
}
}
// 3. save not consumed arguments back to args array
if $get(argsN)<$get(args) {
kill args merge args = argsN
}
quit $$$OK
}
ShowOptionsHelp(&fmtDest) {
for i=1:2:$get(fmtDest) {
#dim opts As %String = $get(fmtDest(i))
continue:opts=""
#if 0
for j=1:1:$length(opts,"|") {
#dim opt As %String = $zstrip($piece(opts,"|",j), "<>", "-/")
#dim lastC As %String = $e(opt,*)
#dim optType As %Integer = $case(lastC, ":":$$$OptionString, :$$$OptionBoolean)
set opt = $zstrip(opt,"<>",":")
//set known(opt) = $lb(optType, i + 1) ; remember option type and destination argument pointer
write opt, ?8,!
}
#else
write !,opts
#endif
}
}
PopArrValue(&args)
{
#dim value
#dim key As %String = $order(args(""),1,value)
quit:key=""
if $data(args(key)) {
kill args(key)
return value
}
return ""
}
]]></Routine>
</Export>