From the NannyMUD documentation
2000-12-16
NAME
basic_shell - A basic shell tool for mortals.DESCRIPTION
The basic shell provides the following: * aliases * nicknames * variables * automatic execution of command sequences * history list, including recalling of commands * page breaking of command output All defines mentioned herein can be found in the file. ALIASES The shell stores all aliases, up to MAX_ALIASES, in the mapping 'alias'. Aliases can contain the special characters %1 to %9, and %*. These will be replaced with argument 1-9 and all arguments, respectively. They can be used in any order and an arbitrary number of times. The $ char can be changed to whatever is preferred by changing ALIAS_ARG_MARKER. + Aliases are added like this: "alias x exa". + They are listed by simply typing "alias". + Typing "alias foo" show what the alias "foo" is set to. + Finally, "unalias foo" removes the alias "foo". The aliases are handled by the internal function 'apply_alias()'. Recursive or chained aliases are allowed, to a max nesting depth of MAX_RECURSION. NICKNAMES The shell stores all nicknames, up to MAX_NICKNAMES, in the mapping 'nickname'. Nickname substitution is only done on arguments, not query_verb(). All nickname processing is done in the function 'apply_nickname()'. Recursive or chained nicknames are allowed, just as for aliases. Adding, listing and removing nicknames work as for aliases above, with the commands "nickname" and "unnickname". VARIABLES The shell stores all variables, up to MAX_VARIABLES, in the mapping 'variable'. Variables work like a special kind of nickname, and are only evalutated when a player uses the "com" (can be changed by altering the defined CMD_COMMAND) command. Example: "set target orc" followed by "alias kk com kill $target", will expand "kk" to "kill orc". All variable processing is done in the function 'evaluate()'. The "$" character can be changed to whatever is preferred by changing CMD_VARIABLE_MARKER. Adding, listing and removing variables work as for aliases above, with the commands "variable" and "unvariable". AUTOMATIC EXECUTION OF COMMANDS The shell offers the commands "do", "dotimes" and "walk". The first two use the internal variable 'cmd_stack', which is a stack of queues of commands to be executed. Thus, nestled usage is allowed of these commands. The commands are executed in 'heart_beat()'. The number of commands that should be executed per hb can be changed by changing MAX_CMDS_PER_HB, currently set to 2. The commands are executed until 'cmd_stack' is empty. "walk" works slightly differently, since it allows a player to walk in a given direction until finding a word in the long description of a room. All walking functionality is handled in the function 'check_walk()', which is called from do_cmd(). It uses two separate variables, 'walk_dir_stack' and 'walk_to_stack', both arrays of strings. If 'check_walk()' discovers the player is walking in some direction, the topmost element of 'walk_dir_stack' is pushed onto the generic 'cmd_stack', to be executed in 'heart_beat()'. To control execution, the commands "break", "wait" and "cont" exist. "break" will halt execution. "break" twice in a row will clear the command stack completely, removing all suspended and not yet executed commands. If not cleared, execution can later be resumed with the "cont" command. The "wait" command suspends automatic executions for n nr of seconds. The resumed commands will be executed from the top of the command stack. All these commands can be changed by changing the defines CMD_DO, CMD_DOTIMES, CMD_WALK, CMD_BREAK, CMD_WAIT, CMD_CONTINUE. The starting and stopping of automatic command execution is handled by the private functions start() and stop(). HISTORY A history list of the last MAX_HISTORY_LEN commands is kept. It is normally updated whenever a player types a command, but on occasions when another object's add_action has gained precedence over the shell's, it might cease working until the slow_beat_hook moves the shell back on top of the player's inventory again. The data structure used is a circular array 'history', with two associated variables; 'history_ptr' which points one step ahead of the last command saved in the list, and 'history_nr', which keeps track of the total number of commands saved in the history list. The command "history" will display a list of the MAX_HISTORY_LEN last commands. & will recall command nr . "last " will repeat the last commands, using the automatic command functionality described above. These commands can be modified by changing the defines CMD_HISTORY and HISTORY_CHAR. PAGEBREAKING OF COMMAND OUTPUT The shell uses a shadow, whose location is given by PAGE_SHADOW, to buffer catch_tell to the player for one command. The shell then uses its own version of simplemore, 'shell_simplemore()' and 'shell_flush()', to pagebreak the output to the player. The reason for this is to avoid conflicts with other commands that already use the simplemore inherent in the player object, such as the "who" command. The buffered output is temporarily stored in the 'page_string' variable. OTHER FUNCTIONALITY Command overriding: Preceding a command by "\", for example typing "\out", will disable all shell parsing (aliases and nicknames, and it will not be added to the history list) for that command only. Modify by changing BYPASS_CHAR. Time command: "Time" shows the NannyMUD host computer's time, and Nanny game time (tm). Modify by changing CMD_TIME. Automatic execution of a command for everyone in the room: "many " executes once per living object in the room, appending the objects real_name/name/short to the string. Example: "many smile" in a room with an orc and a dwarf will cause the player to do "smile orc" and "smile dwarf". Modify by changing CMD_AUTO. .login alias: When 'restore()' is called in the shell (normally only at login), a call_out() of 2+random(5) seconds is made to the function 'login_alias()', which will execute the alias named ".login", if it exists. FUNCTIONS Normally you should not need to patch this object. These functions are public, ie, can be called from the outside, mostly for debugging purposes: void show_info() Prints a nicely formatted list of aliases, nicknames, variables and if the automatic command execution is running or not. mapping query_alias() Returns a copy of the 'alias' mapping. mapping query_nickname() Returns a copy of the 'nickname' mapping. mapping query_variable() Returns a copy of the 'variable' mapping. string *query_history() Returns a copy of the 'history' array. string *query_walk_dir_stack() Returns a copy of the 'walk_dir_stack' array. string *query_walk_to_stack() Returns a copy of the 'walk_to_stack' array. object query_owner() Returns the variable 'owner', the owner of the shell. Should always be the same as the shell's environment. int query_history_nr() Returns the total number of commands that have been saved in the 'history' list. int query_history_ptr() Returns the pointer to the current position in the 'history' array. void save() Saves the non-static shell variables, ie 'alias' and 'nickname' in SAVE_DIR. varargs void restore(object who) Restores the non-static shell variables, ie 'alias' and 'nickname' from SAVE_DIR. If no argument is given, the 'owner' variable is used. INTERNALS All commands are handled by the function 'parse()'. They are switched to the appropriate function. All shell commands can be redefined in shell.h. 'parse()' also handles adding commands to the history list. NOTE: If you inherit this shell for the purpose of adding new commands, you must override the 'parse()' function. The central functions are: private int execute(string cmd_string) Does command(cmd_string, owner), and moves the shell to the top of the owner's inventory afterwards. Returns the result from command(). protected mixed apply_alias(string cmd, string arg) Takes 'cmd' and 'arg' as the player typed in, and performs alias substitution. If no substitution was made, 0 is returned, otherwise the new command string is returned. Called by 'parse()'. protected mixed apply_nickname(string arg) Takes a string 'arg' as the player typed in, and performs nickname substitution. If no substitution was made, 0 is returned, otherwise the substituted string is returned. Called by 'parse()'. Note that nicknames are substituted before aliases. private status evaluate(string arg) Takes the arguments to the "cmd" command, and performs alias, nickname and variable substitution (in this order). Then calls 'execute()' to perform the command. Returns 1 unless arg is 0. private void check_walk() Checks if the player is walking using the "walk" command, if the destination is reached, if it is not possible to continue in the given direction, and if so, pops the direction and looked-for word from 'walk_dir_stack' and 'walk_to_stack' respectively. Otherwise, it pushes the walking direction on top of the 'cmd_stack'. public void heart_beat() Calls 'check_walk()' to see if any walk dirs gets pushed on the generic 'cmd_stack'. Then calls 'execute()' on commands from the 'cmd_stack', and removes them afterwards. Turns itself off if the 'cmd_stack' is empty.