[BusyBox] calling getopt() centrally

Vladimir N. Oleynik dzo at simtreas.ru
Wed Dec 18 05:12:03 UTC 2002


Bob,

> [test-patch attached]
> 
> I hope the attached patch to current development CVS is
> self-explanatory. The core idea is to optionally allow applets to make
> use of a central getopt() function rather than including very similar
> code for each one. This patch only updates a few fileutils applets (to
> keep it simple at first) but already seems to shave a few bytes off the
> default config.

Very interesting.

> * It's a looong time since I've looked at busybox (a couple of years or
> more) and a few months since I've written any C so there may be bugs.
> Sorry.

Please change
applet_opts[opt] = (void *) ~0; 
to
applet_opts[opt] = NULL;
for next correct compare.
Also, may be changing void * to char * for applet_opts.
You can apply your idea without rewrote optind -> argn, 
your algorithm equivalent set optind ;)
Also, may be creating two new macros for applets.h 
with and without your global getopt (NULL and not null arg)?


My idea:
All applet use small count options. 'ls' applet have many
options, but original GNU 'ls' use ~45 options.
So... We can using 64 bit flags.
For each applet making macros:
example mkdir getopt(m:p")


applets.h:

const char **applet_opts;	/* opts args */
long long opts_setted;		/* 64 bits flags */

static inline tst_opt_setted(int n_opt) { return opts_setted & (1 << n_opt); }


applets.c:

static int applet_getopts(int argc, char * const argv[], const char *optstring)
{
       const char *t;
	int nopt = 0;

	for(t = optstring; *t; t++) {
		if(*t != ':') {
			nopt++;
		}
	}
       applet_opts = xcalloc(nopt, sizeof(char *));
	nopt = 0;
       while ((opt = getopt(argc, argv, optstring)) > 0) {
               t = strchr(optstring, opt);
               if (t == NULL) {
                       show_usage();
               }
		opts_setted |= 1 << nopt;
               if (*(t + 1) == ':') {
                       applet_opts[nopt] = optarg;
               } 
		nopt++;
       }
       return optind;
}



mkdir.c:

/* glogal getopt "m:p" */
#define MKDIR_OPT_m 0
#define MKDIR_OPT_p 1

extern int mkdir_main (int argc, char **argv)
{
       if (tst_opt_setted(MKDIR_OPT_m)) {
               mode = 0777;
               if (!parse_mode (applet_opts[MKDIR_OPT_m], &mode)) {
                       error_msg_and_die ("invalid mode `%s'",
applet_opts[MKDIR_OPT_m]);
                }
               umask(0);
        }
       if (tst_opt_setted(MKDIR_OPT_p))
               flags |= FILEUTILS_RECUR;



This algorithm can set privileged option: if option 'a' can drop option 'b',
we can use optstring "ba", not "ab", and check first 'b' and twice 'a'.



--w
vodz



More information about the busybox mailing list