#ifndef PARSE_H #define PARSE_H //***************************************************************************** // // parse.h // // Player commands usually each take their own strict format. For instance, // the give command takes the format give <player> <object>. However, having to // parse out these arguments by hand in each command is a bit of a hassle and // something we can probably cut out most of the legwork for. That's what the // functions in this header are designed to do. // //***************************************************************************** // // format is a space-separated list of arguments to be parsed out. The following // argument types are valid: // ch someone the looker can see, with the specified keyword. // obj something the looker can see, with the specified keyword // room a room in the game with the specified key // exit an exit/dir the looker can see, with the specified keyword // word any single word (ends at whitespace or \0) // int any integer value // double any double value // bool any boolean value (true, false, yes, no, 0, 1) // string all text left to be parsed, up until the \0 delimeter // // Any arguments following a | are optional. They are things that will be parsed // if args has enough arguments in it, but which will be left null otherwise. // // If multiple types can plausibly be returned (e.g. trying to close a door or // an exit), the types can be enclosed in { and } and separated by spaces. If // the { } syntax is supplied, an additional integer pointer must be supplied // to parse_args. It will contain the type of thing parsed, as represented by // one of these definitions: #define PARSE_NONE -1 #define PARSE_EXIT 0 #define PARSE_CHAR 1 #define PARSE_OBJ 2 #define PARSE_ROOM 3 #define PARSE_STRING 4 #define PARSE_DOUBLE 5 #define PARSE_INT 6 #define PARSE_BOOL 7 // Types will be checked by the order they are provided in. So, for instance // {room ch obj} would check for a room first, then a ch, and otherwise an obj. // NOTE: Using double, integer, and boolean values in the { } syntax is frowned // upon, as assigning non-pointer values to points (which the other types must // be) can result in wacky and random errors. Stick to using exit, char, obj, // room, and word within the { } notation. // // Optional or mandatory 'flavor' syntax can be provided as well. For instance, // if you would like people to be able to put "the" in front of object names. // Mandatory 'flavor' syntax must be surrounded by < and >. Optional 'flavor' // syntax must be surrounded by [ and ]. // // .room can be tagged to the end of chs and objs to specify that other // chs/objs in the room are looked for. // // .world can be tagged to the end of chs and objs to specify that other // chs/objs in the world are looked for. // // .inv can be tagged to the end of objs to specify that objects in the person's // inventory are looked for. // // .eq can be tagged to the end of objs to specify that objects worn by the // character are looked for. // // .multiple can be tagged to the end of a ch, obj, or exit lookup. It // signifies that multiple items might be returned. If the .multiple syntax is // supplied, an additional boolean pointer argument must be supplied to // parse_args after the pointer to the thing to be assigned a value. After // parse_args finishes, this boolean value will have true/false if a list was // returned, or a single item. This argument must be supplied after any multi // type arguments (use of { and }) in the argument list. // // .noself can be tagged to the end of any ch lookup. It signifies that the // character cannot specify themselves as an argument. If it is used in // conjunction with .multiple, the looker will be taken out of any list // returned. // // .invis_ok can be tagged to the end of any ch, obj, or exit lookup. It // signifies that the normal constraint of being able to see the target is // nullified. // // both ch and obj markers require at least ONE argument tagged to the end of // them, to specify where the are looked for (e.g. ch.room, obj.inv). A ch or // an obj by itself will not suffice. // // parse_args returns true/false if it succeeded or failed. If show_errors is // true, syntax and type errors and failures to find targets are reported to // the looker in a player-friendly format. such as "could not find person, // 'bob'" or "the room 'city_square@midgaard' does not exist!" // // ********************************* IMPORTANT ********************************* // // IT IS THE DUTY OF THE USER TO FREE ANY LISTS RETURNED BY PARSE_ARGS. ALSO, // IF ANY WORDS OR STRINGS ARE QUERIED FOR, THE MEMORY PASSED IN AS args *WILL* // BE MANGLED BEYOND RECOGNITION TO PREVENT PEOPLE FROM ALSO HAVING TO FREE ANY // STRING VALUES RETURNED. // // ********************************* IMPORTANT ********************************* // // examples: // tell ch.world.noself string // close [the] {exit obj.room.inv} // goto {room ch.world obj.world} // remove [the] obj.eq.multiple.invis_ok // put [the] obj.inv.multiple [in the] obj.room.inv // give [the] obj.inv.multiple [to] ch.room // set ch.world.multiple word string // transfer ch.world.multiple.noself | [to] room bool parse_args(CHAR_DATA *looker, bool show_errors, const char *cmd, char *args, const char *syntax, ...); // // the same as above, but returns a Python list version of the arguments void *Py_parse_args(CHAR_DATA *looker, bool show_errors, const char *cmd, char *args, const char *syntax); #endif // PARSE_H