aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2020-02-25 17:59:19 +0000
committerWerner Koch <[email protected]>2020-02-25 17:59:19 +0000
commit8c185e719860aaa93cc37c0ec91c7bd5e3c2a5ce (patch)
treec479417dc2f2ef0009bd35229456793fd0880bdb
parentcore: New flag ARGPARSE_FLAG_USERVERS to try versioned config files. (diff)
downloadlibgpg-error-8c185e719860aaa93cc37c0ec91c7bd5e3c2a5ce.tar.gz
libgpg-error-8c185e719860aaa93cc37c0ec91c7bd5e3c2a5ce.zip
core: Improve readability of _gpgrt_argparse.
* src/argparse.c (_gpgrt_argparse): Use enum for the states and replace continue and break. -- The use of continue and break in the endless loop if confusing due to the size of the loop's body and because there are also inner for loops with break. It is better to make things explicit by using goto. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--src/argparse.c98
1 files changed, 57 insertions, 41 deletions
diff --git a/src/argparse.c b/src/argparse.c
index d54ca66..8ec1717 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -586,8 +586,15 @@ ignore_invalid_option_clear (gpgrt_argparse_t *arg)
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. */
+ Askipandleave /* Skip the rest of the line and then leave. */
+ } state;
gpgrt_opt_t **opts;
- int state, i, c;
+ int i, c;
int idx = 0;
char keyword[100];
char *buffer = NULL;
@@ -626,9 +633,11 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
arg->internal->opt_flags = 0;
/* Find the next keyword. */
- state = i = 0;
+ state = Ainit;
+ i = 0;
for (;;)
{
+ nextstate:
if (unread_buf_count)
c = unread_buf[3 - unread_buf_count--];
else
@@ -637,9 +646,9 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
{
if ( c != EOF )
arg->lineno++;
- if (state == -1)
- break;
- else if (state == 2)
+ if (state == Askipandleave)
+ goto leave;
+ else if (state == Acopykeyword)
{
keyword[i] = 0;
for (i=0; opts[i]->short_opt; i++ )
@@ -651,22 +660,25 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
arg->r_opt = opts[idx]->short_opt;
if ((opts[idx]->flags & ARGPARSE_OPT_IGNORE))
{
- state = i = 0;
- continue;
+ state = Ainit;
+ i = 0;
+ goto nextstate;
}
else if (!opts[idx]->short_opt )
{
if (!strcmp (keyword, "ignore-invalid-option"))
{
/* No argument - ignore this meta option. */
- state = i = 0;
- continue;
+ state = Ainit;
+ i = 0;
+ goto nextstate;
}
else if (ignore_invalid_option_p (arg, keyword))
{
/* This invalid option is in the iio list. */
- state = i = 0;
- continue;
+ state = Ainit;
+ i = 0;
+ goto nextstate;
}
arg->r_opt = ((opts[idx]->flags & ARGPARSE_OPT_COMMAND)
? ARGPARSE_INVALID_COMMAND
@@ -679,11 +691,11 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
else
arg->r_opt = ARGPARSE_MISSING_ARG;
- break;
+ goto leave;
}
- else if (state == 3)
+ else if (state == Awaitarg)
{
- /* No argument found. */
+ /* No argument found at the end of the line. */
if (in_alias)
arg->r_opt = ARGPARSE_MISSING_ARG;
else if (!(opts[idx]->flags & ARGPARSE_TYPE_MASK))
@@ -693,11 +705,11 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
else
arg->r_opt = ARGPARSE_MISSING_ARG;
- break;
+ goto leave;
}
- else if (state == 4)
+ else if (state == Acopyarg)
{
- /* Has an argument. */
+ /* Has an argument at the end of a line. */
if (in_alias)
{
if (!buffer)
@@ -757,7 +769,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
gpgrt_annotate_leaked_object (buffer);
}
}
- break;
+ goto leave;
}
else if (c == EOF)
{
@@ -766,20 +778,20 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
arg->r_opt = ARGPARSE_READ_ERROR;
else
arg->r_opt = 0; /* EOF. */
- break;
+ goto leave;
}
- state = 0;
+ state = Ainit;
i = 0;
}
- else if (state == -1)
+ else if (state == Askipandleave)
; /* Skip. */
- else if (state == 0 && isascii (c) && isspace(c))
+ else if (state == Ainit && isascii (c) && isspace(c))
; /* Skip leading white space. */
- else if (state == 0 && c == '#' )
- state = 1; /* Start of a comment. */
- else if (state == 1)
+ else if (state == Ainit && c == '#' )
+ state = Acomment; /* Start of a comment. */
+ else if (state == Acomment)
; /* Skip comments. */
- else if (state == 2 && isascii (c) && isspace(c))
+ else if (state == Acopykeyword && isascii (c) && isspace(c))
{
/* Check keyword. */
keyword[i] = 0;
@@ -790,49 +802,52 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
arg->r_opt = opts[idx]->short_opt;
if ((opts[idx]->flags & ARGPARSE_OPT_IGNORE))
{
- state = 1; /* Process like a comment. */
+ /* 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 = 3;
+ state = Awaitarg;
}
else if (!strcmp (keyword, "ignore-invalid-option"))
{
if (ignore_invalid_option_add (arg, fp))
{
arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
+ goto leave;
}
- state = i = 0;
+ state = Ainit;
+ i = 0;
arg->lineno++;
}
else if (ignore_invalid_option_p (arg, keyword))
- state = 1; /* Process like a comment. */
+ state = Acomment; /* Process like a comment. */
else
{
arg->r_opt = ((opts[idx]->flags & ARGPARSE_OPT_COMMAND)
? ARGPARSE_INVALID_COMMAND
: ARGPARSE_INVALID_OPTION);
- state = -1; /* Skip rest of line and leave. */
+ state = Askipandleave; /* Skip rest of line and leave. */
}
}
- else
- state = 3;
+ else /* Known option. */
+ state = Awaitarg;
}
- else if (state == 3)
+ else if (state == Awaitarg)
{
/* Skip leading spaces of the argument. */
if (!isascii (c) || !isspace(c))
{
i = 0;
keyword[i++] = c;
- state = 4;
+ state = Acopyarg;
}
}
- else if (state == 4)
+ else if (state == Acopyarg)
{
/* Collect the argument. */
if (buffer)
@@ -855,7 +870,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
{
xfree (buffer);
arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
+ goto leave;
}
}
}
@@ -874,22 +889,23 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
else
{
arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
+ goto leave;
}
}
}
else if (i >= DIM(keyword)-1)
{
arg->r_opt = ARGPARSE_KEYWORD_TOO_LONG;
- state = -1; /* Skip rest of line and leave. */
+ state = Askipandleave; /* Skip rest of line and leave. */
}
else
{
keyword[i++] = c;
- state = 2;
+ state = Acopykeyword;
}
}
+ leave:
return arg->r_opt;
}