parent $libraries object $parse var $root child_index 0 var $root owners [$parse] var $root fertile 0 var $root inited 1 var $root owned [$parse] var $parse boolean_strs [["yes", "true", "1", "on"], ["no", "false", "0", "off"]] var $root manager $parse var $root writable [$parse] var $root readable ['parameters, 'methods, 'code] var $root dbref 'parse method reference arg string, [sep]; var middle, ref; // receives: "<object><seperator><method/param>" // returns ["<object>", "<method/param>"] // seperator defaults to a period. sep = [@sep, "."][1]; middle = sep in string; if (!middle) ref = [string, ""]; else if (middle == 1) ref = [sender().namef(['dbref]), substr(string, 2)]; else ref = [substr(string, 1, middle - 1), substr(string, middle + 1)]; // assumes "()" will appear at the end of the reference if at all, // and strips it off if present if ("()" in (ref[2])) ref = [ref[1], substr(ref[2], 1, ("()" in (ref[2])) - 1)]; return ref; . method object_match arg name, [who]; var msg; // .object_match("name"[, who]) // -> 0 name was the empty string // -> ~objnf nothing matched name // -> ~ambig more than one object matched name // Attempt to match an object name with who.match_environment(). If one is found, return it. Else, print a message and return one of the above false values. // 'who' defaults to sender(). who = who ? who[1] | sender(); if (!name) { (| who.tell("You must give the name of something.") |); return 0; } catch ~objnf, ~ambig { return who.match_environment(name); } with handler { switch (error()) { case ~objnf: msg = ("I don't see any \"" + name) + "\" here."; case ~ambig: msg = ("I don't know which \"" + name) + "\" you mean."; } (| who.tell(msg) |); return error(); } . method tell_error arg problem, [args]; var who, syntax, line, sprefix, prefix; // arg 1 == error // arg 2 (opt) == syntax // arg 3 (opt) == who // arg 4 (opt) == subbing object (in place of 'Object') -- string. syntax = [@args, 0][1]; who = [@args, sender(), sender()][2]; sprefix = (| sender().setting("error-syntax-prefix") |) || "=> "; prefix = (| sender().setting("error-prefix") |) || "! "; if (syntax) who.tell(((sprefix + "Syntax: `") + syntax) + "`"); if (problem) { if (type(problem) == 'string) { problem = $string.wrap_line(problem, (| who.linelen() |) || 79, prefix, 1); } else { for line in [1 .. listlen(problem)] problem = replace(problem, line, prefix + (problem[line])); } who.tell(problem); } throw(~stop, "", 'no_traceback); . method usage arg method, [dbref]; var code, extracted; // .usage(method[, dbref]) // Extract initial comments from the given method, returning them as a list of strings. // Throw ~methodnf if dbref does not define method. // dbref defaults to sender. dbref = dbref ? dbref[1] | sender(); dbref = dbref.find_method(method); code = dbref.list_method(method); extracted = []; if ((code[1]) == "disallow_overrides;") code = delete(code, 1); if (("arg " in (code[1])) == 1) code = delete(code, 1); if (("var " in (code[1])) == 1) code = delete(code, 1); while (!(code[1])) code = delete(code, 1); while (("//" in (code[1])) == 1) { extracted = [@extracted, strsub(code[1], "//", "")]; code = delete(code, 1); } return extracted; . method match arg string; var loc, obj; // called by $user.match_* methods, simply parses up the basic me/here/$* if (string == "me") return sender(); if (string == "here") return sender().location(); if (string && ((string[1]) == "$")) { obj = toobj(substr(string, 2)); if (!valid(obj)) throw(~objnf, "No such object " + string); return obj; } else { return 0; } . method boolean arg str; if (str in (boolean_strs[1])) return 1; else if (str in (boolean_strs[2])) return 0; else throw(~unknown, "Boolean flag not recognized."); . method full_reference arg str, [args]; var sep, defobj, middle, ref, type, match; defobj = [@args, sender()][1]; match = [@args, [$object, 'to_dbref], [$object, 'to_dbref]][2]; if ("()" in str) str = substr(str, 1, ("()" in str) - 1); if ("." in str) { type = 'method; sep = "."; } else if ("," in str) { type = 'parameter; sep = ","; } else { type = 'unknown; sep = "."; } middle = sep in str; if (!middle) ref = [(> (match[1]).(match[2])(str) <), ""]; else if (middle == 1) ref = [defobj, substr(str, 2)]; else ref = [(> (match[1]).(match[2])(substr(str, 1, middle - 1)) <), substr(str, middle + 1)]; return [type, ref[1], (ref[2]) ? tosym(ref[2]) | 0]; . method traceback arg traceback, [args]; var line, out, pre, lines, cur, x, error; // $parse.traceback(traceback(), lines, pre); // -1 lines represents the full error // pre is set to "! " unless otherwise specified. lines = [@args, -1][1]; pre = [@args, "! ", "! "][2]; error = [@args, 0, 0, 0][3]; // out = [(pre + "=> ") + ((traceback[1])[2])]; pre = pre + " "; // if (error == 0) out = [@out, (pre + "Thrown by ") + (._traceback(@sublist(traceback[2], 2)))]; else out = [@out, (((pre + "Error ") + toliteral(error)) + " thrown by ") + (._traceback(@sublist(traceback[2], 2)))]; // for x in [1 .. listlen(traceback) - 2] { if ((x <= lines) || (lines == (-1))) { line = ($data.unparse((traceback[x + 2])[1])) + ": "; line = line + (._traceback(@sublist(traceback[x + 2], 2))); out = [@out, pre + line]; } } return out; . method _traceback arg what, [more]; var line; if (more) return (((((($data.unparse(more[1])) + ".") + tostr(what)) + "() (") + ($data.unparse(more[2]))) + ") line ") + tostr(more[3]); else return tostr(what); . method options arg line, [defaults]; var loc, opt, x, out, defs; // this will not pay attention to groupings with quotes, should add // the functionality in later. // templates: #[["opt", [0/1, 0/1]]]; / #[['opt, [bool, value]]]; defaults = [@defaults, #[]][1]; if (!(("-" in line) || ("+" in line))) return [explode(line), defaults]; line = explode(line); out = line; for x in [1 .. listlen(line)] { if (((line[x])[1]) in ["-", "+"]) { out = setremove(out, line[x]); opt = substr(line[x], 2); defs = (| defaults[opt] |) || [0, ""]; defs = [((line[x])[1]) in ["+"], defs[2]]; if (defs[2]) { if (listlen(line) >= (x + 1)) { defs = [defs[1], line[x + 1]]; out = setremove(out, line[x + 1]); } } defaults = dict_add(defaults, opt, defs); } } return [out, defaults]; . method my_options arg line, options; var args, word, c, pos, key, p, p2; word = ""; args = ""; while (line) { c = line[1]; switch (c) { case "+": pos = " " in line; if (!pos) { key = substr(line, 2); line = ""; } else { key = substr(line, 2, pos); line = substr(line, pos); } key = tosym(key); catch ~keynf { if (((options[key])[1]) == 'bool) options = dict_add(options, key, ['bool, 1]); else throw(~opttype, ("Option " + tostr(key)) + " is not boolean."); } with handler { throw(~badopt, ("Option " + tostr(key)) + " is not a valid option."); } case "-": pos = " " in line; if (!pos) { key = substr(line, 2); line = ""; } else { key = substr(line, 2, pos); line = substr(line, pos); } key = tosym(key); catch ~keynf { if (((options[key])[1]) == 'bool) options = dict_add(options, key, ['bool, 0]); else throw(~opttype, ("Option " + tostr(key)) + " is not boolean."); } with handler { throw(~badopt, ("Option " + tostr(key)) + " is not a valid option."); } case "=": key = word; word = ""; pos = " " in line; if (!pos) pos = strlen(line); key = tosym(key); catch ~keynf { if (((options[key])[1]) == 'value) options = dict_add(options, key, ['value, substr(line, 2, pos - 1)]); else throw(~opttype, ("Option " + tostr(key)) + " is not a value."); } with handler { throw(~badopt, ("Option " + tostr(key)) + " is not a valid option."); } line = substr(line, pos + 1); case " ": args = args + word; word = ""; line = substr(line, 2); default: pos = " " in line; if (!pos) pos = strlen(line); p = "=" in line; if ((p > 0) && (p < pos)) { word = word + substr(line, 1, p - 1); line = substr(line, p); } else { p = "-" in line; p2 = "+" in line; if (p2 < p) p = p2; if ((p > 0) && (p < pos)) { args = args + substr(line, 1, p - 1); line = substr(line, p); } else { args = args + substr(line, 1, pos); line = substr(line, pos + 1); } } } } args = args + word; for key in (dict_keys(options)) { word = (options[key])[2]; if (type(word) == 'string) word = $string.trim(word); options = dict_add(options, key, word); } return [args, options]; . method xreference arg str, [args]; var out, p, tmp, defobj, match; defobj = [@args, sender()][1]; match = [@args, [$object, 'to_dbref], [$object, 'to_dbref]][2]; p = "<" in str; if (p) { out = [substr(str, 1, p - 1)]; tmp = substr(str, p + 1); p = ">" in tmp; if (!p) throw(~parse, ("Unable to parse reference \"" + str) + "\"."); out = [out[1], substr(tmp, 1, p - 1)]; tmp = (> .split_reference(substr(tmp, p + 1)) <); out = [tmp[1], @out, tmp[3]]; } else { out = (> .split_reference(str) <); out = [out[1], out[2], out[2], out[3]]; } if (!(out[2])) out = replace(out, 2, defobj); else out = replace(out, 2, (> (match[1]).(match[2])(out[2]) <)); if (!(out[3])) out = replace(out, 3, defobj); else out = replace(out, 3, (> (match[1]).(match[2])(out[3]) <)); return out; . method split_reference arg str; var sep, type, mid; if ("." in str) { type = 'method; sep = "."; } else if (":" in str) { type = 'variable; sep = ":"; } else if (";" in str) { type = 'anc_variable; sep = ";"; } else { throw(~parse, ("Invalid reference \"" + str) + "\""); } if (type == 'method) { if ("()" in str) str = substr(str, 1, ("()" in str) - 1); } mid = sep in str; if (!mid) return [type, str, 0]; else if (mid == 1) return [type, "", tosym(substr(str, 2))]; else return [type, substr(str, 1, mid - 1), tosym(substr(str, mid + 1))]; . method range arg str; var out; out = str.explode("-"); if (listlen(out) == 1) { out = [(> ._range(str) <), 'single]; } else if (listlen(out) == 2) { out = out.replace(1, (> ._range(out[1]) <)); out = out.replace(2, (> ._range(out[2]) <)); } else { throw(~range, "Invalid range reference."); } return out; . method _range arg str; if (str.is_numeric()) { return toint(str); } else { switch (str[1]) { case "$": return 'end; case ".": return 'current; case "^": return 'start; default: throw(~range, "Invalid range reference."); } } .