Browse Source

More porting

master
J. King 2 years ago
parent
commit
b3602a8e98
  1. 68
      lib/Docopt.php

68
lib/Docopt.php

@ -38,32 +38,33 @@ class Docopt {
* --options, <positional-argument>, commands, which could be
* [optional], (required), (mutually | exclusive) or repeated...
*
* Example
* -------
* Example:
*
* > use MensBeam\Docopt\Docopt;
* > $doc = <<<DOCSTRING
* <<< Usage:
* <<< my_program tcp <host> <port> [--timeout=<seconds>]
* <<< my_program serial <port> [--baud=<n>] [--timeout=<seconds>]
* <<< my_program (-h | --help | --version)
* <<<
* <<< Options:
* <<< -h, --help Show this screen and exit.
* <<< --baud=<n> Baudrate [default: 9600]
* <<< DOCSTRING;
* > $argv = ['tcp', '127.0.0.1', '80', '--timeout', '30'];
* > echo json_encode(Docopt::docopt($doc, $argv), \JSON_PRETTY_PRINT);
* {
* "--baud": "9600",
* "--help": false,
* "--timeout": "30",
* "--version": false,
* "<host>": "127.0.0.1",
* "<port>": "80",
* "serial": false,
* "tcp": true
* }
* ```
* use MensBeam\Docopt\Docopt;
* $doc = <<<DOCSTRING
* Usage:
* my_program tcp <host> <port> [--timeout=<seconds>]
* my_program serial <port> [--baud=<n>] [--timeout=<seconds>]
* my_program (-h | --help | --version)
*
* Options:
* -h, --help Show this screen and exit.
* --baud=<n> Baudrate [default: 9600]
* DOCSTRING;
* $argv = ['tcp', '127.0.0.1', '80', '--timeout', '30'];
* echo json_encode(Docopt::docopt($doc, $argv), \JSON_PRETTY_PRINT);
* //{
* // "--baud": "9600",
* // "--help": false,
* // "--timeout": "30",
* // "--version": false,
* // "<host>": "127.0.0.1",
* // "<port>": "80",
* // "serial": false,
* // "tcp": true
* //}
* ```
*
* @param string $docstring Description of your command-line interface
* @param string[]|string|null $argv Argument list to be parsed. $_SERVER['argv'] is used if null is provided
@ -81,6 +82,7 @@ class Docopt {
bool $more_magic = false
): ParsedOptions {
# argv = sys.argv[1:] if argv is None else argv
$argv = $argv ?? array_slice($_SERVER['argv'] ?? [], 1);
# maybe_frame = inspect.currentframe()
# if maybe_frame:
# parent_frame = doc_parent_frame = magic_parent_frame = maybe_frame.f_back
@ -91,6 +93,8 @@ class Docopt {
# more_magic = True
# else:
# magic_parent_frame = magic_parent_frame.f_back
// DEVIATION: All these lines are to do with automatic invocation of the "magic" variant of docopt()
// We cannot do this in PHP
# if not docstring: # go look for one, if none exists, raise Exception
# while not docstring and doc_parent_frame:
# docstring = doc_parent_frame.f_locals.get("__doc__")
@ -98,6 +102,7 @@ class Docopt {
# doc_parent_frame = doc_parent_frame.f_back
# if not docstring:
# raise DocoptLanguageError("Either __doc__ must be defined in the scope of a parent or passed as the first argument.")
// DEVIATION: All these lines look for a docstring in the parent context. We simply require one as input
# output_value_assigned = False
# if more_magic and parent_frame:
# import dis
@ -110,14 +115,27 @@ class Docopt {
# MAYBE_STORE = next(instrs)
# if MAYBE_STORE and (MAYBE_STORE.opname.startswith("STORE") or MAYBE_STORE.opname.startswith("RETURN")):
# output_value_assigned = True
// DEVIATION: This is all for magic which is not possible in PHP
# usage_sections = parse_section("usage:", docstring)
# if len(usage_sections) == 0:
# raise DocoptLanguageError('"usage:" section (case-insensitive) not found. Perhaps missing indentation?')
# if len(usage_sections) > 1:
# raise DocoptLanguageError('More than one "usage:" (case-insensitive).')
$usage_sections = Util::parse_section("usage:", $docstring);
if (sizeof($usage_sections) === 0) {
throw new DocoptLanguageError('"usage:" section (case-insensitive) not found. Perhaps missing indentation?');
}
if (sizeof($usage_sections) > 1) {
throw new DocoptLanguageError('More than one "usage:" (case-insensitive).');
}
# options_pattern = re.compile(r"\n\s*?options:", re.IGNORECASE)
# if options_pattern.search(usage_sections[0]):
# raise DocoptExit("Warning: options (case-insensitive) was found in usage." "Use a blank line between each section..")
$options_pattern = '/\n\s*?options:/si';
if (preg_match($options_pattern, $usage_sections[0])) {
throw new DocoptExit("Warning: options (case-insensitive) was found in usage."."Use a blank line between each section..");
}
# DocoptExit.usage = usage_sections[0]
# options = parse_defaults(docstring)
# pattern = parse_pattern(formal_usage(DocoptExit.usage), options)

Loading…
Cancel
Save