From 3ba83d478069314337d6c45c3397a00ccd3f557f Mon Sep 17 00:00:00 2001 From: Louis-Guillaume Gagnon Date: Fri, 13 Dec 2013 22:19:49 -0500 Subject: [PATCH] main: parse argv and init config in 1 pass --- main.c | 548 +++++++++++++++-------------------------------------------------- 1 file changed, 124 insertions(+), 424 deletions(-) diff --git a/main.c b/main.c index 4ea307c..834b186 100644 --- a/main.c +++ b/main.c @@ -16,67 +16,29 @@ const char *progname = "sh"; static char *callname; -typedef enum { - F_ALLEXPORT, // -a or -o allexport - F_ERREXIT, // -e or -o errexit - F_IGNOREEOF, // -o ignoreeof - F_MONITOR, // -m or -o monitor - F_NOCLOBBER, // -C or -o noclobb - F_NOGLOB, // -f or -o noglob - F_REMEMBER, // -h - F_NOEXEC, // -n or -o noexec - F_NOLOG, // -o nolog - F_NOTIFY, // -b or -o notify - F_NOUNSET, // -u or -o nounset - F_VERBOSE, // -v or -o verbose - F_VI, // -o vi - F_XTRACE, // -x or -o xtrace - - F_D_ALLEXPORT, // +a or +o allexport - F_D_ERREXIT, // +e or +o errexit - F_D_IGNOREEOF, // +o ignoreeof - F_D_MONITOR, // +m or +o monitor - F_D_NOCLOBBER, // +C or +o noclobber - F_D_NOGLOB, // +f or +o noglob - F_D_REMEMBER, // +h - F_D_NOEXEC, // +n or +o noexec - F_D_NOLOG, // +o nolog - F_D_NOTIFY, // +b or +o notify - F_D_NOUNSET, // +u or +o nounset - F_D_VERBOSE, // +v or +o verbose - F_D_VI, // +o vi - F_D_XTRACE, // +x or +o xtrace - - F_CMDSTR, // -c - F_CMDSTDIN, // -s - - F_INTERACTIVE // -i - -} Flag; - /* we use this enum in the global config so we can know if a particular option has been initialized */ typedef enum {Ctrue = 1, Cfalse = 0, Cunset = -1} Cbool; typedef struct { - Cbool allexport; - Cbool errexit; - Cbool ignoreeof; - Cbool monitor; - Cbool noclobber; - Cbool noglob; - Cbool remember; - Cbool noexec; - Cbool nolog; - Cbool notify; - Cbool nounset; - Cbool verbose; - Cbool vi; - Cbool xtrace; - Cbool cmdstr; - Cbool cmdstdin; - Cbool interactive; -} Config; + Cbool allexport; // -a or -o allexport + Cbool errexit; // -e or -o errexit + Cbool ignoreeof; // -o ignoreeof + Cbool monitor; // -m or -o monitor + Cbool noclobber; // -C or -o noclobber + Cbool noglob; // -f or -o noglob + Cbool remember; // -h + Cbool noexec; // -n or -o noexec + Cbool nolog; // -o nolog + Cbool notify; // -b or -o notify + Cbool nounset; // -u or -o nounset + Cbool verbose; // -v or -o verbose + Cbool vi; // -o vi + Cbool xtrace; // -x or -o xtrace + Cbool cmdstr; // -c + Cbool cmdstdin; // -s; + Cbool interactive; // -i +} Config; /* not pretty, but i think it's the less ugly way to do this. we could require Cunset to be 0, but then Cfalse wouldnt be @@ -85,157 +47,22 @@ static Config gConfig = {Cunset,Cunset,Cunset,Cunset,Cunset,Cunset, Cunset,Cunset,Cunset,Cunset,Cunset,Cunset, Cunset,Cunset,Cunset,Cunset,Cunset}; -struct FlagList_ { - Flag flag; - struct FlagList_ *next; -}; - -typedef struct FlagList_ FlagList; - -static bool contains_flag(Flag f, FlagList *l); -static FlagList *cons_flag(Flag f, FlagList *l); -static FlagList *parse_argv(); +static void parse_argv(int *argc, char *argv[]); static void dump_config(void); -static void init_config(FlagList *l, bool operands); static void usage(void); -bool contains_flag(Flag f, FlagList *l) -{ - FlagList *p = l; - while(p != NULL) { - if(p->flag == f) - return true; - p = p->next; - } - return false; -} - -/* used to build flag list */ -FlagList *cons_flag(Flag f, FlagList *l) -{ - FlagList *node = malloc(sizeof(FlagList)); - if(node != NULL) { - node->flag = f; - node->next = l; - } - return node; -} - -/* mostly for debugging at this point */ -void print_flaglist(FlagList *l) -{ - while(l != NULL) { - switch(l->flag) { - case F_ALLEXPORT: - printf("allexport\n"); - break; - case F_ERREXIT: - printf("errexit\n"); - break; - case F_IGNOREEOF: - printf("ignoreeof\n"); - break; - case F_MONITOR: - printf("monitor\n"); - break; - case F_NOCLOBBER: - printf("noclobber\n"); - break; - case F_NOGLOB: - printf("noglob\n"); - break; - case F_REMEMBER: - printf("remember\n"); - break; - case F_NOEXEC: - printf("noexec\n"); - break; - case F_NOLOG: - printf("nolog\n"); - break; - case F_NOTIFY: - printf("notify\n"); - break; - case F_NOUNSET: - printf("nounset\n"); - break; - case F_VERBOSE: - printf("verbose\n"); - break; - case F_VI: - printf("vi\n"); - break; - case F_XTRACE: - printf("xtrace\n"); - break; - case F_D_ALLEXPORT: - printf("d_allexport\n"); - break; - case F_D_ERREXIT: - printf("d_errexit\n"); - break; - case F_D_IGNOREEOF: - printf("d_ignoreeof\n"); - break; - case F_D_MONITOR: - printf("d_monitor\n"); - break; - case F_D_NOCLOBBER: - printf("d_noclobber\n"); - break; - case F_D_NOGLOB: - printf("d_noglob\n"); - break; - case F_D_REMEMBER: - printf("d_remember\n"); - break; - case F_D_NOEXEC: - printf("d_noexec\n"); - break; - case F_D_NOLOG: - printf("d_nolog\n"); - break; - case F_D_NOTIFY: - printf("d_notify\n"); - break; - case F_D_NOUNSET: - printf("d_nounset\n"); - break; - case F_D_VERBOSE: - printf("d_verbose\n"); - break; - case F_D_VI: - printf("d_vi\n"); - break; - case F_D_XTRACE: - printf("d_xtrace\n"); - break; - case F_CMDSTR: - printf("cmdstr\n"); - break; - case F_CMDSTDIN: - printf("cmdstdin\n"); - break; - case F_INTERACTIVE: - printf("interactive\n"); - break; - } - l = l->next; - } -} - -/* this function modifies the argc and argv so that when +/* parse the argv, init global config + * *** this function modifies the argc and argv so that when * it returns, argv points to the 1st non-option and * argc is the _actual_ count. We also assume that the * caller decremented the argc and pointed argv to its * second field before calling */ -FlagList *parse_argv(int *argc, char *argv[]) +void parse_argv(int *argc, char *argv[]) { int j,len; char *str; - bool enable; - Flag flag; - FlagList *list = NULL; + Cbool enable; + bool operands; while(*argc != 0) { @@ -248,15 +75,16 @@ FlagList *parse_argv(int *argc, char *argv[]) /* if its a single '-', discard and stop parsing */ if(str[0] == '-' && len == 1) { - argv += 1; + argv++; (*argc)--; break; } /* if we get to this point, we can start analyzing the string. First, we want to know if we enable - or disable: */ - enable = str[0] == '-'; + or disable. Also, keep in mind that disable opts + have precedence over enable opts */ + enable = (Cbool) str[0] == '-'; /* the -o