summaryrefslogtreecommitdiff
path: root/server-tools/instance-manager/parse.cc
diff options
context:
space:
mode:
Diffstat (limited to 'server-tools/instance-manager/parse.cc')
-rw-r--r--server-tools/instance-manager/parse.cc207
1 files changed, 207 insertions, 0 deletions
diff --git a/server-tools/instance-manager/parse.cc b/server-tools/instance-manager/parse.cc
new file mode 100644
index 00000000000..38e10c7f2f5
--- /dev/null
+++ b/server-tools/instance-manager/parse.cc
@@ -0,0 +1,207 @@
+/* Copyright (C) 2004 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "parse.h"
+#include <string.h>
+
+enum Token
+{
+ TOK_FLUSH = 0,
+ TOK_INSTANCE,
+ TOK_INSTANCES,
+ TOK_OPTIONS,
+ TOK_START,
+ TOK_STATUS,
+ TOK_STOP,
+ TOK_SHOW,
+ TOK_NOT_FOUND, // must be after all tokens
+ TOK_END
+};
+
+struct tokens_st
+{
+ uint length;
+ const char *tok_name;
+};
+
+static struct tokens_st tokens[]= {
+ {5, "FLUSH"},
+ {8, "INSTANCE"},
+ {9, "INSTANCES"},
+ {7, "OPTIONS"},
+ {5, "START"},
+ {6, "STATUS"},
+ {4, "STOP"},
+ {4, "SHOW"}
+};
+
+
+/*
+ tries to find next word in the text
+ if found, returns the beginning and puts word length to word_len argument.
+ if not found returns pointer to first non-space or to '\0', word_len == 0
+*/
+
+inline void get_word(const char **text, uint *word_len)
+{
+ const char *word_end;
+
+ /* skip space */
+ while (my_isspace(default_charset_info, **text))
+ ++(*text);
+
+ word_end= *text;
+
+ while (my_isalnum(default_charset_info, *word_end))
+ ++word_end;
+
+ *word_len= word_end - *text;
+}
+
+
+/*
+ Returns token no if word corresponds to some token, otherwise returns
+ TOK_NOT_FOUND
+*/
+
+inline Token find_token(const char *word, uint word_len)
+{
+ int i= 0;
+ do
+ {
+ if (my_strnncoll(default_charset_info, (const uchar *) tokens[i].tok_name,
+ tokens[i].length, (const uchar *) word, word_len) == 0)
+ break;
+ }
+ while (++i < TOK_NOT_FOUND);
+ return (Token) i;
+}
+
+
+Token get_token(const char **text, uint *word_len)
+{
+ get_word(text, word_len);
+ if (*word_len)
+ return find_token(*text, *word_len);
+ return TOK_END;
+}
+
+
+Token shift_token(const char **text, uint *word_len)
+{
+ Token save= get_token(text, word_len);
+ (*text)+= *word_len;
+ return save;
+}
+
+
+void print_token(const char *token, uint tok_len)
+{
+ for (uint i= 0; i < tok_len; ++i)
+ printf("%c", token[i]);
+}
+
+
+int get_text_id(const char **text, uint *word_len, const char **id)
+{
+ get_word(text, word_len);
+ if (word_len == 0)
+ return 1;
+ *id= *text;
+ return 0;
+}
+
+
+Command *parse_command(Command_factory *factory, const char *text)
+{
+ uint word_len;
+ const char *instance_name;
+ uint instance_name_len;
+ Command *command;
+ const char *saved_text= text;
+
+ Token tok1= shift_token(&text, &word_len);
+
+ switch (tok1) {
+ case TOK_START: // fallthrough
+ case TOK_STOP:
+ if (shift_token(&text, &word_len) != TOK_INSTANCE)
+ goto syntax_error;
+ get_word(&text, &word_len);
+ if (word_len == 0)
+ goto syntax_error;
+ instance_name= text;
+ instance_name_len= word_len;
+ text+= word_len;
+ /* it should be the end of command */
+ get_word(&text, &word_len);
+ if (word_len)
+ goto syntax_error;
+
+ command= (tok1 == TOK_START) ? (Command *)
+ factory->new_Start_instance(instance_name, instance_name_len):
+ (Command *)
+ factory->new_Stop_instance(instance_name, instance_name_len);
+ break;
+ case TOK_FLUSH:
+ if (shift_token(&text, &word_len) != TOK_INSTANCES)
+ goto syntax_error;
+
+ get_word(&text, &word_len);
+ if (word_len)
+ goto syntax_error;
+
+ command= factory->new_Flush_instances();
+ break;
+ case TOK_SHOW:
+ switch (shift_token(&text, &word_len)) {
+ case TOK_INSTANCES:
+ get_word(&text, &word_len);
+ if (word_len)
+ goto syntax_error;
+ command= factory->new_Show_instances();
+ break;
+ case TOK_INSTANCE:
+ switch (Token tok2= shift_token(&text, &word_len)) {
+ case TOK_OPTIONS:
+ case TOK_STATUS:
+ get_text_id(&text, &instance_name_len, &instance_name);
+ text+= instance_name_len;
+ get_word(&text, &word_len);
+ if (word_len)
+ goto syntax_error;
+ command= (tok2 == TOK_STATUS) ? (Command *)
+ factory->new_Show_instance_status(instance_name,
+ instance_name_len):
+ (Command *)
+ factory->new_Show_instance_options(instance_name,
+ instance_name_len);
+ break;
+ default:
+ goto syntax_error;
+ }
+ break;
+ default:
+ goto syntax_error;
+ }
+ break;
+ default:
+syntax_error:
+ command= factory->new_Syntax_error();
+ }
+ return command;
+}
+