From 0fdb450a2c06b7b3707c7ea7cf04edd9d4e9fc9d Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 26 Feb 2015 21:07:33 -0600 Subject: More 'splaining. --- www/code.html | 78 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 27 deletions(-) (limited to 'www') diff --git a/www/code.html b/www/code.html index 7603c841..a458b52c 100644 --- a/www/code.html +++ b/www/code.html @@ -877,20 +877,21 @@ a double_list, dlist_add() your entries, and then break the circle with

lib/args.c

Toybox's main.c automatically parses command line options before calling the -command's main function. Option parsing starts in get_optflags(), which stores +command's main function. Option parsing starts in get_optflags(), which stores results in the global structures "toys" (optflags and optargs) and "this".

The option parsing infrastructure stores a bitfield in toys.optflags to -indicate which options the current command line contained. Arguments +indicate which options the current command line contained, and defines FLAG +macros code can use to check whether each argument's bit is set. Arguments attached to those options are saved into the command's global structure -("this"). Any remaining command line arguments are collected together into -the null-terminated array toys.optargs, with the length in toys.optc. (Note +("this"). Any remaining command line arguments are collected together into +the null-terminated array toys.optargs, with the length in toys.optc. (Note that toys.optargs does not contain the current command name at position zero, -use "toys.which->name" for that.) The raw command line arguments get_optflags() +use "toys.which->name" for that.) The raw command line arguments get_optflags() parsed are retained unmodified in toys.argv[].

Toybox's option parsing logic is controlled by an "optflags" string, using -a format reminiscent of getopt's optargs but has several important differences. +a format reminiscent of getopt's optargs but with several important differences. Toybox does not use the getopt() function out of the C library, get_optflags() is an independent implementation which doesn't permute the original arguments (and thus doesn't change how the @@ -904,14 +905,14 @@ command line arguments to look for, and what to do with them. If a command has no option definition string (I.E. the argument is NULL), option parsing is skipped for that command, which must look at the raw data in toys.argv to parse its -own arguments. (If no currently enabled command uses option parsing, +own arguments. (If no currently enabled command uses option parsing, get_optflags() is optimized out of the resulting binary by the compiler's --gc-sections option.)

You don't have to free the option strings, which point into the environment -space (I.E. the string data is not copied). A TOYFLAG_NOFORK command +space (I.E. the string data is not copied). A TOYFLAG_NOFORK command that uses the linked list type "*" should free the list objects but not -the data they point to, via "llist_free(TT.mylist, NULL);". (If it's not +the data they point to, via "llist_free(TT.mylist, NULL);". (If it's not NOFORK, exit() will free all the malloced data anyway unless you want to implement a CONFIG_TOYBOX_FREE cleanup for it.)

@@ -932,7 +933,7 @@ available to command_main(): -

A note about "." and CFG_TOYBOX_FLOAT: option parsing only understands <>= -after . when CFG_TOYBOX_FLOAT -is enabled. (Otherwise the code to determine where floating point constants -end drops out; it requires floating point). When disabled, it can reserve a -global data slot for the argument (so offsets won't change in your -GLOBALS[] block), but will never fill it out. You can handle -this by using the USE_BLAH() macros with C string concatenation, ala: -"abc." USE_TOYBOX_FLOAT("<1.23>4.56=7.89") "def"

-

GLOBALS

Options which have an argument fill in the corresponding slot in the global @@ -1033,7 +1046,7 @@ in the same order they're declared, and that padding won't be inserted between consecutive variables of register size. Thus the first few entries can be longs or pointers corresponding to the saved arguments.

-

See toys/other/hello.c for a longer example of parsing options into the +

See toys/example/*.c for longer examples of parsing options into the GLOBALS block.

char *toys.optargs[]

@@ -1087,7 +1100,7 @@ optflag, but letters are never control characters.)

Option parsing only understands <>= after . when CFG_TOYBOX_FLOAT is enabled. (Otherwise the code to determine where floating point constants end drops out. When disabled, it can reserve a global data slot for the -argument so offsets won't change, but will never fill it out.). You can handle +argument so offsets won't change, but will never fill it out.) You can handle this by using the USE_BLAH() macros with C string concatenation, ala:

"abc." USE_TOYBOX_FLOAT("<1.23>4.56=7.89") "def"
@@ -1095,13 +1108,13 @@ this by using the USE_BLAH() macros with C string concatenation, ala:

--longopts

The optflags string can contain long options, which are enclosed in -parentheses. They may be appended to an existing option character, in +parentheses. They may be appended to an existing option character, in which case the --longopt is a synonym for that option, ala "a:(--fred)" which understands "-a blah" or "--fred blah" as synonyms.

Longopts may also appear before any other options in the optflags string, in which case they have no corresponding short argument, but instead set -their own bit based on position. So for "(walrus)#(blah)xy:z" "command +their own bit based on position. So for "(walrus)#(blah)xy:z", "command --walrus 42" would set toys.optflags = 16 (-z = 1, -y = 2, -x = 4, --blah = 8) and would assign this[1] = 42;

@@ -1109,6 +1122,17 @@ and would assign this[1] = 42;

each "bare longopt" (ala "(one)(two)abc" before any option characters) always sets its own bit (although you can group them with +X).

+

Only bare longopts have a FLAG_ macro with the longopt name +(ala --fred would #define FLAG_fred). Other longopts use the short +option's FLAG macro to test the toys.optflags bit.

+ +

Options with a semicolon ";" after their data type can only set their +corresponding GLOBALS() entry via "--longopt=value". For example, option +string "x(boing): y" would set TT.x if it saw "--boing=value", but would +treat "--boing value" as setting FLAG_x in toys.optargs, leaving TT.x NULL, +and keeping "value" in toys.optargs[]. (This lets "ls --color" and +"ls --color=auto" both work.)

+

[groups]

At the end of the option string, square bracket groups can define -- cgit v1.2.3