From d11327de0a4a727cc0d79dfeef46327765e6d7fd Mon Sep 17 00:00:00 2001 From: Louis-Guillaume Gagnon Date: Thu, 12 Dec 2013 15:06:58 -0500 Subject: [PATCH] main: add parse_argv() --- main.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 344 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index dfe8c24..de43967 100644 --- a/main.c +++ b/main.c @@ -1,10 +1,340 @@ +#include #include #include +#include + +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; + +struct FlagList_ { + Flag flag; + struct FlagList_ *next; +}; + +typedef struct FlagList_ FlagList; const char *progname = "sh"; +static FlagList *cons_flag(Flag f, FlagList *l); +static FlagList *parse_argv(); static void usage(void); +/* 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 + * 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[]) +{ + int j,len; + char *str; + bool enable; + Flag flag; + FlagList *list = NULL; + + while(*argc != 0) + { + str = argv[0]; + len = strlen(str); + + /* if not a flag, stop parsing flags */ + if(str[0] != '-' && str[0] != '+') + break; + + /* if its a single '-', discard and stop parsing */ + if(str[0] == '-' && len == 1) { + argv += 1; + (*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] == '-'; + + /* the -o