/* Do not remove the headers from this file! see /USAGE for more info. */ // Command line processing #include <mudlib.h> private int classify( int opt, string options ){ int i; i = member_array(opt, options); if(i == -1){ printf("option -%c not recognized\n", opt); return 0; } if( ++i != strlen(options) ) return options[i] == ':'; } //:FUNCTION getopt //Takes an array and parses flags from it. Returns an array, the first //element being a mapping of flag : value, the second element being an //array of the remaining args, all flag information removed. The second //argument should be a string of single character flags that the command //accepts, followed by a colon (:) if the flag can take an argument. mixed getopt( mixed args, string options ) { mapping res; mixed optstring, opt, optarg; res = ([]); if(!options) options = ""; while (sizeof(args) && stringp(args[0]) && args[0][0] == '-' && args[0] != '-'){ if( args[0] == "--" ){ args = (sizeof(args)>1)? args[1..] : ({}); break; } optstring = strlen(args[0]) == 1 ? "" : args[0][1..]; args = sizeof(args) == 1 ? ({}) : args[1..]; while(optstring!=""){ opt = optstring[0]; optstring = strlen(optstring) == 1 ? "" : optstring[1..]; if(classify(opt,options)){ if(optstring == ""){ if(!sizeof(args)){ printf("option -%c requires an argument.\n", opt); return -1; } optstring = args[0]; args = sizeof(args)>1?args[1..]:({}); } optarg = optstring; optstring = ""; res[chr(opt)] = optarg; } else{ optarg = ""; res[chr(opt)] = optarg; } } } return ({ res, args }); } // Got the idea for this one from python, // but unlike getopt, didn't pirate the implimentation =) // //:FUNCTION argument_explode //assumes the arg passed is the argument to some unix-like //command where ares are space seperated unless enclosed in non-escaped //quotes. //Returns an array of the arguments. and an array of implode info mixed* argument_explode(string s) { string* result = ({}); string* implode_info = ({}); int i, l; int waiting_for; int end_of_last_word = -1; int beginning_of_word = 0; l = strlen(s); for(i=0; i < l; i++) { switch(s[i]) { case '\\': // This is because all \\'s aren't converted to \ here. if(i+1 != l && s[i+1] == '\\') break; i++; break; case '`': case '"': if(!waiting_for) { waiting_for = s[i]; if(beginning_of_word != i) { implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); end_of_last_word = i-1; result += ({s[beginning_of_word..end_of_last_word]}); } beginning_of_word = i; break; } if(waiting_for != s[i]) continue; result += ({s[beginning_of_word..i]}); implode_info += ({s[(end_of_last_word+1)..(beginning_of_word-1)]}); end_of_last_word = i; beginning_of_word = i+1; waiting_for = 0; break; case '|': if(waiting_for) break; if(beginning_of_word != i) { result += ({s[beginning_of_word..i-1],"|"}); implode_info +=({s[end_of_last_word+1..beginning_of_word-1],""}); end_of_last_word = i; beginning_of_word = i+1; break; } implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); result += ({"|"}); beginning_of_word = i+1; end_of_last_word = i; break; case '<': if(waiting_for) break; if(beginning_of_word != i) { result += ({s[beginning_of_word..i-1],"<"}); implode_info +=({s[end_of_last_word+1..beginning_of_word-1],""}); end_of_last_word = i; beginning_of_word = i+1; break; } result += ({"<"}); implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); end_of_last_word = i; beginning_of_word = i+1; break; case '>': if(waiting_for) break; if(beginning_of_word != i) { implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); result += ({s[beginning_of_word..i-1]}); beginning_of_word = i+1; end_of_last_word = i; } if(s[i+1] == '>') { // Skip the next > i++; implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); end_of_last_word = i; beginning_of_word = i+1; result += ({">>"}); break; } else { implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); end_of_last_word = i; beginning_of_word = i+1; result += ({">"}); break; } case ' ': if(waiting_for) break; if(beginning_of_word == i) { beginning_of_word = i+1; break; } implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); result += ({s[beginning_of_word..i-1]}); end_of_last_word = i-1; beginning_of_word = i+1; break; default: break; } } if(beginning_of_word < l) { implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); result += ({ s[beginning_of_word..] }); implode_info += ({""}); } else { implode_info += ({s[end_of_last_word+1..beginning_of_word-1]}); } return ({result,implode_info}); } //:FUNCTION parse_argument //calls argument_explode() and then getopt(), returning the //value of the getopt() call. mixed parse_argument( string input, string options ){ return getopt( argument_explode(input), options ); }