20
20
use Toolkit \Stdlib \Str ;
21
21
use function array_merge ;
22
22
use function array_shift ;
23
+ use function array_values ;
23
24
use function basename ;
24
25
use function count ;
25
26
use function explode ;
34
35
use function trim ;
35
36
36
37
/**
37
- * class AbstractParser
38
+ * class AbstractFlags
39
+ * abstract parser
38
40
*/
39
- abstract class AbstractParser implements ParserInterface
41
+ abstract class AbstractFlags implements ParserInterface
40
42
{
41
43
use QuickInitTrait;
42
44
use NameAliasTrait;
43
45
44
- protected const TRIM_CHARS = "; \t\n\r\0\x0B" ;
46
+ protected const TRIM_CHARS = "; \t\n\r\0\x0B" ;
45
47
protected const OPT_MAX_WIDTH = 16 ;
46
48
47
49
public const RULE_SEP = '; ' ;
@@ -50,7 +52,9 @@ abstract class AbstractParser implements ParserInterface
50
52
51
53
public const STATUS_ERR = 1 ;
52
54
53
- public const STATUS_HELP = 2 ; // found `-h|--help` flag
55
+ public const STATUS_ARG = 2 ;
56
+
57
+ public const STATUS_HELP = 3 ; // found `-h|--help` flag
54
58
55
59
public const SHORT_STYLE_GUN = 'gnu ' ;
56
60
@@ -148,7 +152,8 @@ abstract class AbstractParser implements ParserInterface
148
152
protected $ shortStyle = 'posix ' ;
149
153
150
154
/**
151
- * Whether stop parse option on first argument
155
+ * Stop parse option on found first argument.
156
+ * - useful for support multi commands. eg: `top --opt ... sub --opt ...`
152
157
*
153
158
* @var bool
154
159
*/
@@ -198,6 +203,39 @@ public function __construct(array $config = [])
198
203
Obj::init ($ this , $ config );
199
204
}
200
205
206
+ /**
207
+ * @param array|null $flags
208
+ *
209
+ * @return bool
210
+ */
211
+ public function parse (?array $ flags = null ): bool
212
+ {
213
+ if ($ this ->parsed ) {
214
+ return true ;
215
+ }
216
+
217
+ $ this ->parsed = true ;
218
+ $ this ->rawArgs = [];
219
+
220
+ if ($ flags === null ) {
221
+ $ flags = $ _SERVER ['argv ' ];
222
+ $ sFile = array_shift ($ flags );
223
+ $ this ->setScriptFile ($ sFile );
224
+ } else {
225
+ $ flags = array_values ($ flags );
226
+ }
227
+
228
+ $ this ->flags = $ flags ;
229
+ return $ this ->doParse ($ flags );
230
+ }
231
+
232
+ /**
233
+ * @param array $flags
234
+ *
235
+ * @return bool
236
+ */
237
+ abstract protected function doParse (array $ flags ): bool ;
238
+
201
239
/**
202
240
* @param array $rawArgs
203
241
*
@@ -227,6 +265,13 @@ protected function parseRawArgs(array $rawArgs): array
227
265
return $ args ;
228
266
}
229
267
268
+ public function resetResults (): void
269
+ {
270
+ // clear match results
271
+ $ this ->parsed = false ;
272
+ $ this ->rawArgs = $ this ->flags = [];
273
+ }
274
+
230
275
/****************************************************************
231
276
* build and render help
232
277
***************************************************************/
@@ -346,10 +391,10 @@ protected function doBuildHelp(array $argDefines, array $optDefines, bool $withC
346
391
}
347
392
348
393
/**
349
- * @see DEFINE_ITEM for array $define
350
394
* @param array|Option|Argument $define
351
395
*
352
396
* @return array
397
+ * @see DEFINE_ITEM for array $define
353
398
*/
354
399
protected function formatDesc ($ define ): array
355
400
{
@@ -403,7 +448,7 @@ protected function buildArgsForHelp(array $argDefines): array
403
448
}
404
449
405
450
// ensure desc is not empty
406
- $ arg ['desc ' ] = $ desc ? Str::ucfirst ($ desc ): "Argument $ helpName " ;
451
+ $ arg ['desc ' ] = $ desc ? Str::ucfirst ($ desc ) : "Argument $ helpName " ;
407
452
408
453
$ type = $ arg ['type ' ];
409
454
if (FlagType::isArray ($ type )) {
@@ -455,7 +500,7 @@ protected function buildOptsForHelp(array $optDefines): array
455
500
}
456
501
457
502
// ensure desc is not empty
458
- $ opt ['desc ' ] = $ desc ? Str::ucfirst ($ desc ): "Option $ name " ;
503
+ $ opt ['desc ' ] = $ desc ? Str::ucfirst ($ desc ) : "Option $ name " ;
459
504
460
505
$ helpName = FlagUtil::buildOptHelpName ($ names );
461
506
if ($ this ->showTypeOnHelp ) {
0 commit comments