From 925701797f55f195682f3d147481f244e5050c90 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 27 Jul 2008 09:37:38 +0000 Subject: [PATCH] --- ase/cmd/awk/awk.c | 84 +++++++++----- ase/include/ase/utl/getopt.h | 21 ++-- ase/lib/utl/getopt.c | 213 ++++++++++++----------------------- 3 files changed, 140 insertions(+), 178 deletions(-) diff --git a/ase/cmd/awk/awk.c b/ase/cmd/awk/awk.c index ba60b440..5f1636ab 100644 --- a/ase/cmd/awk/awk.c +++ b/ase/cmd/awk/awk.c @@ -1035,27 +1035,28 @@ static int handle_args (int argc, ase_char_t* argv[], struct awk_src_io* src_io) ase_cint_t c; static ase_opt_lng_t lng[] = { - { ASE_T("implicit"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("explicit"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("bxor"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("shift"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("idiv"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("extio"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("newline"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("baseone"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("stripspaces"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("nextofile"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("crfl"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("argstomain"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("reset"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("maptovar"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, - { ASE_T("pablock"), ASE_OPT_OPTIONAL, ASE_NULL, 0 }, + { ASE_T("implicit"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("explicit"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("bxor"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("shift"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("idiv"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("extio"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("newline"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("baseone"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("stripspaces"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("nextofile"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("crlf"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("argstomain"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("reset"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("maptovar"), ASE_OPT_ARG_OPTIONAL, 0 }, + { ASE_T("pablock"), ASE_OPT_ARG_OPTIONAL, 0 }, - { ASE_T("help"), ASE_OPT_NONE, ASE_NULL, ASE_T('h')}, - { ASE_T("main"), ASE_OPT_REQUIRED, ASE_NULL, ASE_T('m') }, - { ASE_T("file"), ASE_OPT_REQUIRED, ASE_NULL, ASE_T('f') }, - { ASE_T("field-separator"), ASE_OPT_REQUIRED, ASE_NULL, ASE_T('F') }, - { ASE_T("assign"), ASE_OPT_REQUIRED, ASE_NULL, ASE_T('v') } + { ASE_T("main"), ASE_OPT_ARG_REQUIRED, ASE_T('m') }, + { ASE_T("file"), ASE_OPT_ARG_REQUIRED, ASE_T('f') }, + { ASE_T("field-separator"), ASE_OPT_ARG_REQUIRED, ASE_T('F') }, + { ASE_T("assign"), ASE_OPT_ARG_REQUIRED, ASE_T('v') }, + + { ASE_T("help"), ASE_OPT_ARG_NONE, ASE_T('h')} }; @@ -1071,30 +1072,46 @@ static int handle_args (int argc, ase_char_t* argv[], struct awk_src_io* src_io) switch (c) { case 0: - ase_printf (ASE_T("%d\n"), opt.lngind); + ase_printf (ASE_T(">>> [%s] [%s]\n"), opt.lngopt, opt.arg); break; case ASE_T('h'): print_usage (argv[0]); - return -1; - + return 1; case ASE_T('f'): - ase_printf (ASE_T("ffffffffffff\n")); src_io->input_file = opt.arg; + ase_printf (ASE_T("[file] = %s\n"), opt.arg); + break; + + case ASE_T('F'): + ase_printf (ASE_T("[field separator] = %s\n"), opt.arg); break; case ASE_T('?'): - ase_fprintf (ASE_STDERR, ASE_T("Error: illegal option - %c\n"), opt.opt); - print_usage (argv[0]); + if (opt.lngopt) + { + ase_printf (ASE_T("Error: illegal option - %s\n"), opt.lngopt); + } + else + { + ase_printf (ASE_T("Error: illegal option - %c\n"), opt.opt); + } return -1; case ASE_T(':'): - ase_fprintf (ASE_STDERR, ASE_T("Error: missing argument for %c\n"), opt.opt); - print_usage (argv[0]); + if (opt.lngopt) + { + ase_printf (ASE_T("Error: bad argument for %s\n"), opt.lngopt); + } + else + { + ase_printf (ASE_T("Error: bad argument for %c\n"), opt.opt); + } return -1; default: + ase_printf (ASE_T("DEFAULT....\n")); return -1; } } @@ -1108,12 +1125,19 @@ static int handle_args (int argc, ase_char_t* argv[], struct awk_src_io* src_io) /* the remainings are data file names */ } + + while (opt.ind < argc) + { + ase_printf (ASE_T("RA => [%s]\n"), argv[opt.ind++]); + } +/* if (opt.ind < argc) { ase_printf (ASE_T("Error: redundant argument - %s\n"), argv[opt.ind]); print_usage (argv[0]); return -1; } +*/ return 0; } @@ -1157,11 +1181,13 @@ static int awk_main (int argc, ase_char_t* argv[]) ASE_AWK_BASEONE | ASE_AWK_PABLOCK; - if (handle_args (argc, argv, &src_io) == -1) + i = handle_args (argc, argv, &src_io); + if (i == -1) { print_usage (argv[0]); return -1; } + if (i == 1) return 0; infiles[file_count] = ASE_NULL; runarg[runarg_count].ptr = NULL; diff --git a/ase/include/ase/utl/getopt.h b/ase/include/ase/utl/getopt.h index 8428b378..5c2ba13f 100644 --- a/ase/include/ase/utl/getopt.h +++ b/ase/include/ase/utl/getopt.h @@ -1,5 +1,5 @@ /* - * $Id: getopt.h 287 2008-07-24 14:08:37Z baconevi $ + * $Id: getopt.h 289 2008-07-26 15:37:38Z baconevi $ * * {License} */ @@ -10,9 +10,12 @@ #include #include -#define ASE_OPT_NONE 0 -#define ASE_OPT_REQUIRED 1 -#define ASE_OPT_OPTIONAL 2 +enum +{ + ASE_OPT_ARG_NONE = 0, + ASE_OPT_ARG_REQUIRED = 1, + ASE_OPT_ARG_OPTIONAL = 2 +}; typedef struct ase_opt_t ase_opt_t; typedef struct ase_opt_lng_t ase_opt_lng_t; @@ -21,7 +24,6 @@ struct ase_opt_lng_t { const ase_char_t* str; int has_arg; - int* flag; int val; }; @@ -34,15 +36,14 @@ struct ase_opt_t /* output */ ase_cint_t opt; /* character checked for validity */ ase_char_t* arg; /* argument associated with an option */ - int err; + + /* output */ + ase_char_t* lngopt; /* input + output */ int ind; /* index into parent argv vector */ - /* output */ - int lngind; - - /* internal */ + /* input + output - internal*/ ase_char_t* cur; }; diff --git a/ase/lib/utl/getopt.c b/ase/lib/utl/getopt.c index 36a1843b..9b69dbc0 100644 --- a/ase/lib/utl/getopt.c +++ b/ase/lib/utl/getopt.c @@ -1,5 +1,5 @@ /* - * $Id: getopt.c 288 2008-07-25 15:01:27Z baconevi $ + * $Id: getopt.c 289 2008-07-26 15:37:38Z baconevi $ * * {License} */ @@ -126,142 +126,12 @@ ase_cint_t ase_getopt (int argc, ase_char_t* const* argv, ase_opt_t* opt) } #endif -/* Code based on Unununium project (http://unununium.org/) */ - ase_cint_t ase_getopt (int argc, ase_char_t* const* argv, ase_opt_t* opt) { ase_char_t* oli; /* option letter list index */ + int dbldash = 0; - if (opt->ind == 0) opt->ind = 1; - -//again: - if (opt->ind >= argc /*|| !argv[opt->ind] */|| - argv[opt->ind][0] != ASE_T('-') || - argv[opt->ind][1] == ASE_T('\0')) return ASE_CHAR_EOF; - - if (argv[opt->ind][1] == ASE_T('-') && - argv[opt->ind][2] == ASE_T('\0')) - { - /* -- */ - ++opt->ind; - return ASE_CHAR_EOF; - } - - // TODO: how to handle when lng is off? is this correct? - if (opt->lng != ASE_NULL && argv[opt->ind][1] == ASE_T('-')) - { - /* a long option */ - - ase_char_t* arg = argv[opt->ind] + 2; - const ase_opt_lng_t* o; - - /* TODO: rewrite it.. */ - /*char* max=strchr(arg,'='); - if (max == ASE_NULL) max = arg + strlen(arg);*/ - ase_char_t* max = arg; - while (*max != ASE_T('\0') && *max != ASE_T('=')) max++; - - //for (o = longopts; o->name != ASE_NULL; o++) - for (o = opt->lng; o->str != ASE_NULL; o++) - { - //if (!strncmp (o->name, arg, max - arg)) - if (ase_strxcmp (arg, max-arg, o->str) != 0) continue; - - /* match */ - opt->lngind = o - opt->lng; - if (o->has_arg > 0) - { - if (*max == ASE_T('=')) - { - opt->arg = max + 1; - } - else - { - opt->arg = argv[opt->ind+1]; - if (!opt->arg && o->has_arg == 1) - { /* no argument there */ - if (*opt->str == ASE_T(':')) - return ASE_T(':'); - - /* - write(2,"argument required: `",20); - write(2,arg,(size_t)(max-arg)); - write(2,"'.\n",3); - */ - opt->ind++; - return ASE_T('?'); - } - opt->ind++; - } - } - - opt->ind++; - - if (o->flag) *(o->flag) = o->val; - else return o->val; - - return 0; - } - - if (*opt->str == ASE_T(':')) return ASE_T(':'); - - /* - write(2,"invalid option `",16); - write(2,arg,(size_t)(max-arg)); - write(2,"'.\n",3); - */ - - opt->ind++; - return ASE_T('?'); - } - -#if 0 - if (lastidx != opt->ind) - { - lastidx=opt->ind; lastofs=0; - } - - opt->opt=argv[opt->ind][lastofs+1]; - - tmp=ase_strchr(opt->str,opt->opt); - if (tmp != ASE_NULL) - { - if (tmp[0] == ASE_T('\0')) - { /* apparently, we looked for \0, i.e. end of argument */ - ++opt->ind; - goto again; - } - if (tmp[1] == ASE_T(':')) - { /* argument expected */ - if (tmp[2]==':' || argv[opt->ind][lastofs+2]) { /* "-foo", return "oo" as opt->arg */ - if (!*(opt->arg=argv[opt->ind]+lastofs+2)) opt->arg=0; - goto found; - } - opt->arg=argv[opt->ind+1]; - if (!opt->arg) { /* missing argument */ - ++opt->ind; - if (*opt->str==':') return ':'; - getopterror(1); - return ':'; - } - ++opt->ind; - } - else - { - ++lastofs; - return opt->opt; - } -found: - ++opt->ind; - return optopt; - } - else - { /* not found */ - getopterror(0); - ++opt->ind; - return '?'; - } -#endif + opt->lngopt = ASE_NULL; if (opt->cur == ASE_NULL) { @@ -274,18 +144,82 @@ found: /* update scanning pointer */ if (opt->ind >= argc || *(opt->cur = argv[opt->ind]) != ASE_T('-')) { + /* All arguments have been processed or the current + * argument doesn't start with a dash */ opt->cur = EMSG; return ASE_CHAR_EOF; } - if (opt->cur[1] != ASE_T('\0') && *++opt->cur == ASE_T('-')) - { - /* found "--" */ - ++opt->ind; + opt->cur++; + + #if 0 + if (*opt->cur == ASE_T('\0')) + { + /* - */ + opt->ind++; opt->cur = EMSG; return ASE_CHAR_EOF; } - } /* option letter okay? */ + #endif + + if (*opt->cur == ASE_T('-')) + { + if (*++opt->cur == ASE_T('\0')) + { + /* -- */ + opt->ind++; + opt->cur = EMSG; + return ASE_CHAR_EOF; + } + else + { + dbldash = 1; + } + } + } + + if (dbldash && opt->lng != ASE_NULL) + { + const ase_opt_lng_t* o; + ase_char_t* end = opt->cur; + + while (*end != ASE_T('\0') && *end != ASE_T('=')) end++; + + for (o = opt->lng; o->str != ASE_NULL; o++) + { + if (ase_strxcmp (opt->cur, end-opt->cur, o->str) != 0) continue; + + /* match */ + opt->cur = EMSG; + opt->lngopt = o->str; + opt->arg = ((*end == ASE_T('='))? (end + 1): ASE_NULL); + + if (o->has_arg == ASE_OPT_ARG_NONE) + { + if (opt->arg != ASE_NULL) + { + /* redundant argument */ + return BADARG; + } + } + else if (o->has_arg == ASE_OPT_ARG_REQUIRED && opt->arg == ASE_NULL) + { + if (argc > ++opt->ind) opt->arg = argv[opt->ind]; + else + { + /* missing argument */ + return BADARG; + } + } + + opt->ind++; + return o->val; + } + + if (*end == ASE_T('=')) *end = ASE_T('\0'); + opt->lngopt = opt->cur; + return BADCH; + } if ((opt->opt = *opt->cur++) == ASE_T(':') || (oli = ase_strchr(opt->str, opt->opt)) == ASE_NULL) @@ -318,6 +252,7 @@ found: { /* no arg */ opt->cur = EMSG; + opt->arg = ASE_NULL; /*if (*opt->str == ASE_T(':'))*/ return BADARG; /*return BADCH;*/ } @@ -328,7 +263,7 @@ found: } opt->cur = EMSG; - ++opt->ind; + opt->ind++; } return opt->opt; /* dump back option letter */