079bf616c69a57a91cfc14789097600104100a91
7 null
* = 0; opt
* = 1; char
* = 2; string
* = 3; ident
* = 4; eos
* = 5; eof
* = 6;
10 options
* = 0; strings
* = 1; identifiers
* = 2; chars
* = 3; terminators
* = 4;
11 emptystr
* = 5; emptyident
* = 6; invalid
* = 7;
14 ok
* = 0; unkopt
* = 1; missarg
* = 2;
17 String
* = POINTER TO ARRAY OF CHAR;
21 args
: POINTER TO ARRAY OF String
;
22 argn
-, argi
-: INTEGER;
27 PROCEDURE Skip (n
: INTEGER);
30 ASSERT(argn
< LEN(args
), 21);
31 ASSERT(argi
+ n
<= LEN(args
[argn
]$
), 22);
35 PROCEDURE IsOpt (ch
: CHAR): BOOLEAN;
37 RETURN (CAP(ch
) >= "A") & (CAP(ch
) <= "Z") OR (ch
>= "0") & (ch
<= "9") OR (ch
= "-")
40 PROCEDURE IsIdentStart (ch
: CHAR): BOOLEAN;
42 RETURN (CAP(ch
) >= "A") & (CAP(ch
) <= "Z") OR (ch
= "_")
45 PROCEDURE IsIdent (ch
: CHAR): BOOLEAN;
47 RETURN (CAP(ch
) >= "A") & (CAP(ch
) <= "Z") OR (ch
= "_") OR (ch
>= "0") & (ch
<= "9")
50 PROCEDURE Get
* (VAR x
: BYTE);
51 VAR i
, j
, len
: INTEGER; sym
: BYTE; c
: CHAR;
54 IF argn
>= LEN(args
) THEN
55 optMode
:= FALSE
; sym
:= eof
58 c
:= args
[argn
, argi
];
60 optMode
:= FALSE
; INC(argn
); argi
:= 0;
61 IF terminators
IN opts
THEN sym
:= eos
; (* !!! *)
62 ELSIF argn
>= LEN(args
) THEN sym
:= eof (* !!! *)
63 ELSE c
:= args
[argn
, argi
] (* continue parsing *)
67 IF (options
IN opts
) & (optMode
& IsOpt(c
) OR (c
= "-") & IsOpt(args
[argn
, argi
+ 1])) THEN
70 ch
:= c
; optMode
:= TRUE
; Skip(1)
72 ch
:= args
[argn
, argi
+ 1]; optMode
:= TRUE
; Skip(2)
74 ELSIF (identifiers
IN opts
) OR (strings
IN opts
) THEN
75 len
:= 0; i
:= argi
; sym
:= null
;
76 (* --- get length of identifier --- *)
77 IF (identifiers
IN opts
) & (IsIdentStart(args
[argn
, i
]) OR (emptyident
IN opts
)) THEN
78 WHILE IsIdent(args
[argn
, i
]) DO
84 (* --- get length of string --- *)
85 IF strings
IN opts
THEN
86 WHILE args
[argn
, i
] # 0X
DO
91 ELSIF (identifiers
IN opts
) & (args
[argn
, i
] # 0X
) & ~
(invalid
IN opts
) THEN
92 WHILE args
[argn
, i
] # 0X
DO INC(i
) END;
95 (* --- copy string --- *)
96 IF (sym
# null
) & ((len
> 0) OR (sym
= string
) & (emptystr
IN opts
) OR (sym
= ident
) & (emptyident
IN opts
)) THEN
98 FOR j
:= 0 TO len
- 1 DO
99 str
[j
] := args
[argn
, argi
+ j
]
105 ELSIF chars
IN opts
THEN
106 ch
:= c
; optMode
:= FALSE
; Skip(1)
108 optMode
:= FALSE
; sym
:= null
; Skip(1)
117 argn
:= 1; argi
:= 0; ch
:= 0X
; str
:= NIL; optMode
:= FALSE
;
118 opts
:= {options
, strings
, emptystr
}
121 PROCEDURE GetOpt
* (IN optstring
: ARRAY OF CHAR): CHAR;
122 VAR save
: SET; sym
: BYTE; c
: CHAR; i
, mode
: INTEGER;
124 save
:= opts
; opts
:= {options
, strings
, emptystr
}; c
:= 0X
;
128 WHILE (optstring
[i
] # 0X
) & (optstring
[i
] # c
) DO
130 WHILE optstring
[i
] = ":" DO
134 IF optstring
[i
] = c
THEN
135 opts
:= {strings
, emptystr
}; mode
:= 0; INC(i
);
136 WHILE optstring
[i
] = ":" DO
140 IF mode
# 0 THEN Get(sym
);
141 IF (sym
# string
) & (mode
= 1) THEN
142 NEW(str
, 2); str
[0] := c
; c
:= ":"
145 ELSE NEW(str
, 2); str
[0] := c
; c
:= "?"
147 ELSIF sym
= eof
THEN c
:= 0X (* eof *)
148 ELSE c
:= "$" (* string *)
157 NEW(args
, Kernel
.argc
);
158 FOR i
:= 0 TO Kernel
.argc
- 1 DO
159 NEW(args
[i
], LEN(Kernel
.argv
[i
]$
) + 1);
160 args
[i
]^
:= Kernel
.argv
[i
]$