diff options
author | Werner Koch <wk@gnupg.org> | 2020-02-25 19:43:49 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2020-02-25 19:53:13 +0100 |
commit | ca79d5edee8c6d93575708643ec825f81107e624 (patch) | |
tree | 62bf546053fae083bae93c1daed18ab7bc13a96d /src/argparse.c | |
parent | 8c185e719860aaa93cc37c0ec91c7bd5e3c2a5ce (diff) | |
download | libgpg-error-ca79d5edee8c6d93575708643ec825f81107e624.tar.gz |
core: Fold duplicated code from _gpgrt_argparse.
* src/argparse.c (_gpgrt_argparse): Fold common code.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'src/argparse.c')
-rw-r--r-- | src/argparse.c | 168 |
1 files changed, 86 insertions, 82 deletions
diff --git a/src/argparse.c b/src/argparse.c index 8ec1717..6f6431d 100644 --- a/src/argparse.c +++ b/src/argparse.c @@ -587,10 +587,12 @@ int _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig) { enum { Ainit, - Acomment, /* In a comment line. */ - Acopykeyword, /* Collecting a keyword. */ - Awaitarg, /* Wait for an argument. */ - Acopyarg, /* Copy the argument. */ + Acomment, /* In a comment line. */ + Acopykeyword, /* Collecting a keyword. */ + Awaitarg, /* Wait for an argument. */ + Acopyarg, /* Copy the argument. */ + Akeyword_eol, /* Got keyword at end of line. */ + Akeyword_spc, /* Got keyword at space. */ Askipandleave /* Skip the rest of the line and then leave. */ } state; gpgrt_opt_t **opts; @@ -638,60 +640,102 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig) for (;;) { nextstate: - if (unread_buf_count) - c = unread_buf[3 - unread_buf_count--]; - else - c = _gpgrt_fgetc (fp); - if (c == '\n' || c== EOF ) + /* Before scanning the next char handle the keyword seen states. */ + if (state == Akeyword_eol || state == Akeyword_spc) { - if ( c != EOF ) - arg->lineno++; - if (state == Askipandleave) - goto leave; - else if (state == Acopykeyword) + /* Check the keyword. */ + for (i=0; opts[i]->short_opt; i++ ) { - keyword[i] = 0; - for (i=0; opts[i]->short_opt; i++ ) + if (opts[i]->long_opt && !strcmp (opts[i]->long_opt, keyword)) + break; + } + idx = i; + arg->r_opt = opts[idx]->short_opt; + if ((opts[idx]->flags & ARGPARSE_OPT_IGNORE)) + { + /* Option is configured to be ignored. Start from + * scratch (new line) or process like a comment. */ + state = state == Akeyword_eol? Ainit : Acomment; + i = 0; + } + else if (!opts[idx]->short_opt ) + { + /* The option is not known - check for internal keywords. */ + if (state == Akeyword_spc && !strcmp (keyword, "alias")) { - if (opts[i]->long_opt && !strcmp (opts[i]->long_opt, keyword)) - break; + in_alias = 1; + state = Awaitarg; } - idx = i; - arg->r_opt = opts[idx]->short_opt; - if ((opts[idx]->flags & ARGPARSE_OPT_IGNORE)) + else if (!strcmp (keyword, "ignore-invalid-option")) { + /* We might have keywords as argument - add them to + * the list of ignored keywords. Note that we + * ignore empty argument lists and thus do not to + * call the function in the Akeyword_eol stae. */ + if (state == Akeyword_spc) + { + if (ignore_invalid_option_add (arg, fp)) + { + arg->r_opt = ARGPARSE_OUT_OF_CORE; + goto leave; + } + arg->lineno++; + } state = Ainit; i = 0; - goto nextstate; } - else if (!opts[idx]->short_opt ) + else if (ignore_invalid_option_p (arg, keyword)) + { + /* This invalid option is already in the iio list. */ + state = state == Akeyword_eol? Ainit : Acomment; + i = 0; + } + else { - if (!strcmp (keyword, "ignore-invalid-option")) - { - /* No argument - ignore this meta option. */ - state = Ainit; - i = 0; - goto nextstate; - } - else if (ignore_invalid_option_p (arg, keyword)) - { - /* This invalid option is in the iio list. */ - state = Ainit; - i = 0; - goto nextstate; - } arg->r_opt = ((opts[idx]->flags & ARGPARSE_OPT_COMMAND) ? ARGPARSE_INVALID_COMMAND : ARGPARSE_INVALID_OPTION); + if (state == Akeyword_spc) + { + state = Askipandleave; + } } - else if (!(opts[idx]->flags & ARGPARSE_TYPE_MASK)) + } + else if (state == Akeyword_spc) + { + /* Known option but need to scan for args. */ + state = Awaitarg; + } + else + { + /* Known option and at end of line - return option. */ + if (!(opts[idx]->flags & ARGPARSE_TYPE_MASK)) arg->r_type = 0; /* Does not take an arg. */ else if ((opts[idx]->flags & ARGPARSE_OPT_OPTIONAL) ) arg->r_type = 0; /* Arg is optional. */ else arg->r_opt = ARGPARSE_MISSING_ARG; - goto leave; + } + } /* (end state Akeyword_eol/Akeyword_spc) */ + + /* Get the next character from the line. */ + if (unread_buf_count) + c = unread_buf[3 - unread_buf_count--]; + else + c = _gpgrt_fgetc (fp); + + if (c == '\n' || c== EOF ) + { /* Handle end of line. */ + if ( c != EOF ) + arg->lineno++; + if (state == Askipandleave) + goto leave; + else if (state == Acopykeyword) + { + keyword[i] = 0; + state = Akeyword_eol; + goto nextstate; } else if (state == Awaitarg) { @@ -782,7 +826,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig) } state = Ainit; i = 0; - } + } /* (end handle end of line) */ else if (state == Askipandleave) ; /* Skip. */ else if (state == Ainit && isascii (c) && isspace(c)) @@ -793,49 +837,9 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig) ; /* Skip comments. */ else if (state == Acopykeyword && isascii (c) && isspace(c)) { - /* Check keyword. */ keyword[i] = 0; - for (i=0; opts[i]->short_opt; i++ ) - if (opts[i]->long_opt && !strcmp (opts[i]->long_opt, keyword)) - break; - idx = i; - arg->r_opt = opts[idx]->short_opt; - if ((opts[idx]->flags & ARGPARSE_OPT_IGNORE)) - { - /* Option is configured to be ignored. */ - state = Acomment; /* Process like a comment. */ - } - else if (!opts[idx]->short_opt) - { - /* The option is not known - check for other keywords. */ - if (!strcmp (keyword, "alias")) - { - in_alias = 1; - state = Awaitarg; - } - else if (!strcmp (keyword, "ignore-invalid-option")) - { - if (ignore_invalid_option_add (arg, fp)) - { - arg->r_opt = ARGPARSE_OUT_OF_CORE; - goto leave; - } - state = Ainit; - i = 0; - arg->lineno++; - } - else if (ignore_invalid_option_p (arg, keyword)) - state = Acomment; /* Process like a comment. */ - else - { - arg->r_opt = ((opts[idx]->flags & ARGPARSE_OPT_COMMAND) - ? ARGPARSE_INVALID_COMMAND - : ARGPARSE_INVALID_OPTION); - state = Askipandleave; /* Skip rest of line and leave. */ - } - } - else /* Known option. */ - state = Awaitarg; + state = Akeyword_spc; + goto nextstate; } else if (state == Awaitarg) { |