int Reader(CommandBase* commands [], int num_commands, int argc, const char** argv) { std::vector<const char*> inputs; CommandBase* last_command = NULL; CommandHelp help_command(commands,num_commands); int command_count = 0; bool command_chosen = false; for(int i=1; i<argc; i++) { double tmp; if(argv[i][0] == '-' && !string_is_double(argv[i],tmp)) { //command if(string_is_double(argv[i],tmp)) command_chosen = false; //check for help queries first if(0 == strcmp("help",&argv[i][1])) { if(last_command != NULL) { int res = DoCommand(last_command,inputs); if(res <= 0) return res; } last_command = &help_command; command_count++; command_chosen = true; } //search through rest of commands for(int k=0; k<num_commands && !command_chosen; k++) { if(0 == strcmp(commands[k]->Name(),&argv[i][1])) { //we've found a command if(last_command != NULL) { int res = DoCommand(last_command,inputs); if(res <= 0) return res; } last_command = commands[k]; command_chosen = true; command_count++; } } if(!command_chosen) { printf("Unknown command %s\n", argv[i]); PrintCommands(commands, num_commands); return -1; } } else { //add an argument inputs.push_back(argv[i]); command_chosen = false; } } if(command_count == 0) { if(inputs.size() > 0) cout<<"Some stray elements were given on the command line"<<endl; PrintCommands(commands, num_commands); } else { assert(last_command != NULL); int res = DoCommand(last_command,inputs); if(res <= 0) return res; } return 0; }
// // tries to make a double parse var PARSE_VAR *use_one_parse_token_double(const char *buf) { PARSE_VAR *var = NULL; if(string_is_double(buf)) { var = newParseVar(PARSE_VAR_DOUBLE); var->dbl_val = atof(buf); } return var; }
bool CommandBase::SetArg(int arg, const char* val) { if(0 == strcmp(val,"#")) return true; //default arguments switch(args[arg].type) { case Bool: return string_is_bool(val,*(bool*)args[arg].data); case Int: return string_is_int(val,*(int*)args[arg].data); case Float: return string_is_float(val,*(float*)args[arg].data); case Double: return string_is_double(val,*(double*)args[arg].data); case String: *(const char**)args[arg].data = val; return true; } return false; }
// // Tries to apply a token to args, to parse something out. Returns a PARSE_VAR // if the token's usage resulted in the creation of a variable. If an error was // encountered, make this apparent by setting the value of the variable at error PARSE_VAR *use_one_parse_token(CHAR_DATA *looker, PARSE_TOKEN *tok, char **args, bool *error, char *err_buf) { char buf[SMALL_BUFFER]; PARSE_VAR *var = NULL; char *arg = *args; // skip over any leading spaces we might have while(isspace(*arg)) arg++; switch(tok->type) { case PARSE_TOKEN_MULTI: { // make a proxy error value and error buf so we don't accidentally fill // these up when it turns out we find something on a var past the first bool multi_err = FALSE; char multi_err_buf[SMALL_BUFFER] = ""; // go through all of our possible types until we find something LIST_ITERATOR *multi_i = newListIterator(tok->token_list); PARSE_TOKEN *mtok = NULL; bool multiple_possible = FALSE; ITERATE_LIST(mtok, multi_i) { if(mtok->all_ok) multiple_possible = TRUE; var = use_one_parse_token(looker, mtok, &arg, &multi_err, multi_err_buf); // reset our error value for the next pass at it... if(var == NULL) multi_err = FALSE; // found something! Disambiguate the type else { switch(mtok->type) { case PARSE_TOKEN_CHAR: var->disambiguated_type = PARSE_CHAR; break; case PARSE_TOKEN_ROOM: var->disambiguated_type = PARSE_ROOM; break; case PARSE_TOKEN_EXIT: var->disambiguated_type = PARSE_EXIT; break; case PARSE_TOKEN_OBJ: var->disambiguated_type = PARSE_OBJ; break; case PARSE_TOKEN_WORD: var->disambiguated_type = PARSE_STRING; break; case PARSE_TOKEN_STRING: var->disambiguated_type = PARSE_STRING; break; case PARSE_TOKEN_INT: var->disambiguated_type = PARSE_INT; break; case PARSE_TOKEN_DOUBLE: var->disambiguated_type = PARSE_DOUBLE; break; case PARSE_TOKEN_BOOL: var->disambiguated_type = PARSE_BOOL; break; } // break out of the loop... we found something break; } } deleteListIterator(multi_i); // did we manage not to find something? if(var != NULL) var->multiple_possible = multiple_possible; else { one_arg(arg, buf); // get the first arg, for reporting... sprintf(err_buf, "Your argument '%s' was invalid or could not be found.", buf); *error = TRUE; } break; } case PARSE_TOKEN_FLAVOR: { int len = strlen(tok->flavor); // have we found the flavor text? if(strncasecmp(tok->flavor, arg, len) == 0 && (arg[len] == '\0' || isspace(arg[len]))) arg = arg + len; // do we need to do something about it? else if(!tok->flavor_optional) *error = TRUE; break; } // parse out a char value case PARSE_TOKEN_CHAR: arg = one_arg(arg, buf); var = use_one_parse_token_char(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The person, %s, could not be found.", buf); *error = TRUE; } break; // parse out an obj value case PARSE_TOKEN_OBJ: arg = one_arg(arg, buf); var = use_one_parse_token_obj(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The object, %s, could not be found.", buf); *error = TRUE; } break; // parse out a room value case PARSE_TOKEN_ROOM: arg = one_arg(arg, buf); var = use_one_parse_token_room(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The room, %s, could not be found.", buf); *error = TRUE; } break; // parse out an exit value case PARSE_TOKEN_EXIT: arg = one_arg(arg, buf); var = use_one_parse_token_exit(looker, tok, buf); if(var == NULL) { sprintf(err_buf, "The direction, %s, could not be found.", buf); *error = TRUE; } break; // try to parse out a double value case PARSE_TOKEN_DOUBLE: arg = one_arg(arg, buf); var = use_one_parse_token_double(buf); if(var == NULL) { sprintf(err_buf, "'%s' is not a decimal value.", buf); *error = TRUE; } break; // try to parse out an integer value case PARSE_TOKEN_INT: arg = one_arg(arg, buf); var = use_one_parse_token_int(buf); if(var == NULL) { sprintf(err_buf, "'%s' is not a%s number.", buf, (string_is_double(buf) ? "n acceptable" : "")); *error = TRUE; } break; // try to parse out a boolean value case PARSE_TOKEN_BOOL: arg = one_arg(arg, buf); var = use_one_parse_token_bool(buf); if(var == NULL) { sprintf(err_buf, "'%s' is not a yes/no value.", buf); *error = TRUE; } break; // parse out a single word case PARSE_TOKEN_WORD: { var = newParseVar(PARSE_VAR_STRING); var->ptr_val = arg; bool multi_word = FALSE; char multi_mark = '"'; // are we using quotation marks to specify multiple words? if(*arg == '"' || *arg == '\'') { multi_word = TRUE; multi_mark = *arg; arg++; var->ptr_val = arg; } // go through arg to the next space, and delimit the word for(; *arg != '\0'; arg++) { if((multi_word && *arg == multi_mark) || (!multi_word && isspace(*arg))) { *arg = '\0'; arg++; break; } } break; } // copies whatever is left case PARSE_TOKEN_STRING: var = newParseVar(PARSE_VAR_STRING); var->ptr_val = arg; // skip up the place of the arg... while(*arg != '\0') arg++; break; // since this doesn't really parse a value... case PARSE_TOKEN_OPTIONAL: break; } // up the placement of our arg if we didn't encounter an error if(!*error) *args = arg; return var; }