[libvirt] [PATCH 4/8] virsh: add vrshCommandParser abstraction
Eric Blake
eblake at redhat.com
Tue Oct 12 19:48:35 UTC 2010
On 10/12/2010 01:13 AM, Lai Jiangshan wrote:
>
> add vrshCommandParser and make vshCommandParse() accepts different
s/vrsh/vsh/; s/accepts/accept/
> parsers.
>
> the current code for parse command string is integrated as
> vshCommandStringParse().
>
> Signed-off-by: Lai Jiangshan<laijs at cn.fujitsu.com>
> ---
> virsh.c | 91 +++++++++++++++++++++++++++++++---------------------------------
> 1 file changed, 45 insertions(+), 46 deletions(-)
> diff --git a/tools/virsh.c b/tools/virsh.c
> index f97ee42..27321a5 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -10158,23 +10158,29 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd)
> return ret;
> }
>
> +#define VSH_TK_ERROR -1
> +#define VSH_TK_ARG 0
> +#define VSH_TK_SUBCMD_END 1
> +#define VSH_TK_END 2
Hmm, in addition to floating this earlier, you also lost _NONE and added
_SUBCMD_END. The enum I suggested in patch 3 is sounding more
appealing, so I'll squash it in now.
> +
> +typedef struct __vshCommandParser {
> + int (*getNextArg)(vshControl *, struct __vshCommandParser *, char **);
> + char *pos;
> +} vshCommandParser;
> +
> +static int vshCommandParse(vshControl *ctl, vshCommandParser *parser);
I'm a fan of avoiding forward static declarations if the file can be
rearranged topologically.
> +
> /* ---------------
> * Command string parsing
> * ---------------
> */
This logically belongs before enums related to command parsing.
> -#define VSH_TK_ERROR -1
> -#define VSH_TK_NONE 0
> -#define VSH_TK_DATA 1
> -#define VSH_TK_END 2
>
> static int
> -vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res)
> +vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res)
> {
> bool double_quote = false;
> int sz = 0;
> - char *p = str, *q;
> -
> - *end = NULL;
> + char *p = parser->pos, *q;
Rebasing this on top of my edits to patch 1 is getting interesting.
>
> while (p&& *p&& (*p == ' ' || *p == '\t'))
You no longer need to check if p is NULL,
> +static int vshCommandStringParse(vshControl *ctl, char *cmdstr)
> +{
> + vshCommandParser parser;
> +
> + if (cmdstr == NULL || *cmdstr == '\0')
> + return FALSE;
> +
> + parser.pos = cmdstr;
...since this guarantees it is non-NULL.
> + for (;;) {
$ git grep 'for.*;;' | wc -l
14
$ git grep 'while.*true' | wc -l
6
$ git grep 'while.*1' | wc -l
70
Guess which one I'm changing this to, for consistency :)
ACK, with those nits fixed. Here's what I squashed in:
diff --git i/tools/virsh.c w/tools/virsh.c
index 56985a4..d9f72f3 100644
--- i/tools/virsh.c
+++ w/tools/virsh.c
@@ -10174,38 +10174,40 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd)
return ret;
}
-#define VSH_TK_ERROR -1
-#define VSH_TK_ARG 0
-#define VSH_TK_SUBCMD_END 1
-#define VSH_TK_END 2
+/* ---------------
+ * Command string parsing
+ * ---------------
+ */
+
+typedef enum {
+ VSH_TK_ERROR, /* Failed to parse a token */
+ VSH_TK_ARG, /* Arbitrary argument, might be option or empty */
+ VSH_TK_SUBCMD_END, /* Separation between commands */
+ VSH_TK_END /* No more commands */
+} vshCommandToken;
typedef struct __vshCommandParser {
- int (*getNextArg)(vshControl *, struct __vshCommandParser *, char **);
+ vshCommandToken (*getNextArg)(vshControl *, struct
__vshCommandParser *,
+ char **);
char *pos;
} vshCommandParser;
static int vshCommandParse(vshControl *ctl, vshCommandParser *parser);
-/* ---------------
- * Command string parsing
- * ---------------
- */
-
-static int ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+static vshCommandToken ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char
**res)
{
bool double_quote = false;
int sz = 0;
char *p = parser->pos;
- char *q = vshStrdup(ctl, str);
+ char *q = vshStrdup(ctl, p);
- *end = NULL;
*res = q;
- while (p && *p && (*p == ' ' || *p == '\t'))
+ while (*p && (*p == ' ' || *p == '\t'))
p++;
- if (p == NULL || *p == '\0')
+ if (*p == '\0')
return VSH_TK_END;
if (*p == ';') {
parser->pos = ++p; /* = \0 or begin of next command */
@@ -10261,15 +10262,15 @@ vshCommandParse(vshControl *ctl,
vshCommandParser *parser)
ctl->cmd = NULL;
}
- for (;;) {
+ while (1) {
vshCmdOpt *last = NULL;
const vshCmdDef *cmd = NULL;
- int tk;
+ vshCommandToken tk;
int data_ct = 0;
first = NULL;
- for (;;) {
+ while (1) {
const vshCmdOptDef *opt = NULL;
tkdata = NULL;
--
Eric Blake eblake at redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
More information about the libvir-list
mailing list