I was trying to think of a newer way to parse arguments, in which you wouldn't have to do the argument parsing from within each command function. What I came up was an argument parser/interpreter. What it does is takes a string and depending upon what the function is expecting either splits it up into words or sends the string on (with or without leading spaces trimmed). Specifications: STRING : String with leading spaces removed STRING_SPACES : String with leading spaces intact WORDS : Split into words struct ArgType { int argc; char **argv; }; Argc is only zero when there is no arguments passed to the function. argv[0] always holds the string, even for WORDS. In the case of STRING and STRING_SPACES, argc equals 1 when a string was passed. Note that OneWord and SkipSpaces are from CircleMud, they are not the functions I use in my own mud, but I didn't want to include my functions (after all, I'm not releasing my mud's code). Here goes the code (note this in an individual program that demonstrates how the ArgInterpreter() works, you'll have to implement into CircleMud yourself): #include <stdio.h> #include <stdlib.h> #define STRING 0 // string w/o leading spaces #define STRING_SPACES 1 // string w/ leading spaces #define WORDS 2 // split string into words struct ArgType { int argc; char **argv; }; void SkipSpaces(char **argument) { for (; **argument && isspace(**argument); (*argument)++); } char *OneWord(char *argument, char *first) { SkipSpaces(&argument); while (*argument && !isspace(*argument)) { *(first++) = tolower(*argument); argument++; } *first = '\0'; return argument; } struct ArgType ArgInterpreter(char *str, int arg_data) { int was_space = 1, i = 0; struct ArgType ap; char word[256]; char *tmp; const char *arg_types[] = { "STRING", "STRING_SPACES", "WORDS", "\n" }; at.argc = 0; if (!str || !*str) return (at); if (arg_data != WORDS) { at.argc = 1; at.argv = (char **) calloc(1, sizeof(char *)); if (arg_data == STRING) SkipSpaces(&str); at.argv[0] = strdup(str); printf("%s:%s\n", arg_types[arg_data], at.argv[0]); return (at); } SkipSpaces(&str); for (tmp = str; *tmp; tmp++) if (isspace(*tmp)) was_space = 1; else if (was_space) { at.argc++; was_space = 0; } printf("%s: %d words\n", arg_types[arg_data], at.argc); at.argv = (char **) calloc(at.argc, sizeof(char *)); do { i++; str = OneWord(str, word); if (word && *word) at.argv[i] = strdup(word); printf("%s: argv[%d]=%s\n", arg_types[arg_data], i, argv[i]); } while (*word && *str); return (at); } void main(void) { char *msg = " Enter test string here."; struct ArgType argd; argd = ArgInterpreter(msg, STRING); argd = ArgInterpreter(msg, STRING_SPACES); argd = ArgInterpreter(msg, WORDS); } This might make a good snippet. If anyone gets it into CircleMud, then don't hesistate to inform me. Note, though, that it wouldn't be a small task, as you'd have to change all the ACMD functions to support it and the command table to include the arg_data thing (to specify if the function should get STRING/STRING_SPACES/WORDS). But, after those two things, changing the command_interpreter() to use ArgInterpreter() is trivial. -- Daniel Koepke dkoepke@california.com Forgive me father, for I am sin. char m[35]="Yano eu!r'!dr!\ne!! !!!!!";void main(){int i=0,p;for(;i<3;i++, p=0){for(;m[3*p+i]!='!';p++)printf("%c",m[3*p+i]);}} +-----------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://cspo.queensu.ca/~fletcher/Circle/list_faq.html | | Or send 'info circle' to majordomo@cspo.queensu.ca | +-----------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/18/00 PST