[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