diff options
Diffstat (limited to 'server-tools/instance-manager/parse.cc')
-rw-r--r-- | server-tools/instance-manager/parse.cc | 207 |
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; +} + |