Project: JDW argv
Description: argv[] processing support for PHP scripts.
Author: John Walsh
Maintainer: John Walsh
Copyright (C) 2021, John Walsh, all rights reserved.
Created: May 03 2021
https://sourceforge.net/projects/jdw-argv/
----
This is 'JDW argv'.
It is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
There should be a copy of the GNU General Public License
in the file 'COPYING'. If not, see <http://www.gnu.org/licenses/>.
----------------------------------------------------------------------
Change Log / Development History
================================
Version: 1.0.0 - 03/05/2021
First release.
----------------------------------------------------------------------
Description
===========
A support script to provide argv[] options processing for PHP scripts.
When I wrote 'gd_process.php':
https://sourceforge.net/projects/gd-process/
I needed a CLI argv[] options processor.
I search around for one, and found this:
https://gist.github.com/DenesKellner/29a696e4420a4f3e162a935e5cb9ab4f
by Dénes Kellner.
I decided to use it, and also expanded and devleoped it, enough to
create and release it as this new project.
So my thanks to Dénes Kellner for getting this started.
----------------------------------------------------------------------
Usage
=====
This documentation may seam quite complex for what the code is/does.
It may be easier to look over a project that has good example usage
code, like 'gd_process.php':
https://sourceforge.net/projects/gd-process/
Also, 'jdw_argv_test.php' is provided for running your own tests with.
As well as trying it with 'good/valid' option values, give it 'bad/
invalid' values to see how they are handled, and how they effect the
comsumption of argv[] values - especially if you use '=' or ' '
seperators.
'jdw_argv.php' will give you the ability to accept CLI argv option/value
pairs, with the option specified as a single 'char' and/or longer 'word'
name, and to be of a specified 'type'. They can take any of these forms:
-option=value
--option=value
-option value
--option value
--option
-o=value
--o=value
-o value
--o value
-o
-ovalue (for char name options only, with a single minus)
If 'value' is mising:
eg. --option1 --option2=value2
then it is taken as NULL.
'char' options (using a single -): -f=filename, -f filename, -ffilename
are all valid and equivalent.
'word' option names (multiple --) MUST use a '=' or ' ' for a seperator.
note:
If an options value is not explicitly specified,
ie. space seperated, then the next 'argv' is taken as the value.
This is known as a 'shifted' (ie. assumed) value.
If the 'shifted' value would be another option specifier (ie. begins
with a '-'), then it is put back (not consumed) and a value of NULL is
assumed.
A negative numeric value (eg. -90) would be treated as an option,
so you must use -o=-30 in this case.
If the value is not valid (ie. not formatted as per its required
'type'), then the argv may or may not be consumed,
see option: OPT_CONSUME_BAD_VALUES.
Can not have multiple short option names in one setting: -abc
because it will be interpreted as -a=bc
----------------------------------------------------------------------
Documentation
=============
The processing is setup by injesting schema(s).
They specify the option names and their types, that will be accepted.
Once the schema(s) are in place, the argv[] is then injested.
All options (that begin with a '-') are checked against the schema,
and stored if recognised and valid, or not stored if the runtime
processing options are set accordingly.
All argv[] values that are not an option (ie. just a parameter) are
stored and indexed by their non-option index. ie. the first parameter
will be at index 1 (0 is the script name) regardless of how many options
are in the argv[] before it.
Once all the argv[] processing is complete, the argv[] parameters and
options can be read by the script, by using the function jdw_argv_get().
Internal Data
-------------
The results of all the processing are stored in the global: $argv_info[]
Schema
------
Options to be accepted/processed are specified via a schema.
An options schema is a string, where each line can be a specifier of
options, or a comment.
A comment line is:
a blank line
begins with 4 or more spaces
does not have a '-' char as it's first non-space character
An option specifier line is of the format, 4 columns (space seperated):
-char --word type comment
-char, --word = option names, in single char and word format.
The 'char' name MUST have a leading '-', but it is optional for the
'word' name.
You can specify both a 'word' and a 'char' name, or just one of them
(use - for no setting), and they can be the same.
type = see below.
comment = has no effect, is present so that the schema can be used for
the 'help' option of the script.
eg:
$jdw_options_schema = "
-q --quiet-mode bool Suppress all error messages
-f --filename str Name of your input document
-m --max-lines int Maximum number of lines to read
-p -- float Value of PI
and no 'word' name option
-n --num num Any number value
- --z-mode bool no 'char' name option
-h --hex pcre./[0-9a-f]{2}/i a 2 digit hex value
";
Types
-----
type can be any of :-
str, bool, int, float, real, num, pcre
type can also have a 'modifier' part, '.' seperated
eg: pcre./regex/
'str'
will accept any value
'bool'
accepts: 0, 1, false, true
defaults to true if the value is not present, or invalid.
'int'
'float' and 'real'
'num'
all the above will accept all numeric formats, but will be cast to the
required type.
'pcre./regex/'
The 'regex' expression is forced to match the whole of value,
so you don't need to use ^ and $ in your regex.
Runtime Processing Options
--------------------------
The behavior of the processing can be tuned by the following options:
OPT_CHAR_ICASE - sets if 'char' option names are case insensitive
(internally forced to UPPER case).
OPT_WORD_ICASE - sets if 'word' option names are case insensitive
(internally forced to UPPER case).
OPT_CONSUME_BAD_VALUES - sets if 'shifted' values are consumed from
argv[], when they are invalid (according to its type).
OPT_IGNORE_INVALID_OPTIONS - sets if an unrecognised option name is
ignored (excluded from argv_info[]).
If ignored, then a 'shifted' value will not be consumed.
If not ignored, then a new entry is created for it of type 'str'.
OPT_IGNORE_INVALID_VALUES - sets if an option with an invalid value
(according to its type) will be ignored (excluded from argv_info[]).
extra detail
------------
booleans are special, in that they will ALWAYS produce a valid value.
Any bad/invalid values will be defaulted to TRUE,
but the actual argv[] value will also be processed according to the
option OPT_CONSUME_BAD_VALUES, and so may or may not be consume.
The idea behind this behavior is to allow usage such as:
script.php -b filename.ext
ie. if the '-b' is some boolean option, and with a filename following
it, the filename is not a valid value for the boolean option. So the
boolean option is defaulted to true, and the invalid value (the filename)
will not be consumed if OPT_CONSUME_BAD_VALUES is false.
This is more intuative to a human user, rather than following the strict
rules for argv procesing/consumption.
----------------------------------------------------------------------
functions
=========
function jdw_argv_reset()
clear all the internal data.
----
function jdw_argv_injest_schema($opt_schema)
multiple calls will merge all options/schemas together.
----
function jdw_argv_injest_argv($opt_argv)
parses argv[] according to the options schema injested.
----
function jdw_argv_get($opt_name, $opt_default=null)
jdw_argv_get() returns a list of values:
value = the value
index = the original argv[] index
valid = true or false
* parameters
to get an argv[] parameter, use a numeric 'opt_key':
list($opt_param_1, $opt_index, $opt_valid) = jdw_argv_get(1);
if you don't specify a default value, and the parameter was not set,
then a value of NULL is returned.
* options
to get an argv[] option, use the name of the option for the 'opt_key':
If both char and word names were specified, then use the 'word' name.
eg:
list($opt_number, $opt_index, $opt_valid) = jdw_argv_get("number");
for an option, the returned values are also arrays, that will hold
all the settings of the option.
if an option was not set, the default value is used with an index of -1.
in case of multiple settings of an option,
if you only want the last option value set, use jdw_end()
eg:
$opt_number = jdw_end($opt_number);
you can also count how many times an option was set, which can be useful
for boolean options.
eg:
list($opt_debug_bool, $opt_index, $opt_valid) = jdw_argv_get("d");
$opt_debug_level = count(array_keys($opt_debug_bool, true)) - count(array_keys($opt_debug_bool, false));
an input of: script.php -d -d0 -d
would produce a 'd' option value of 2.
----------------------------------------------------------------------
To Do
=====
----------------------------------------------------------------------