TinyMUSH 3.3
TinyMUSH Server
|
Command evaluation and cracking. More...
#include "config.h"
#include "constants.h"
#include "typedefs.h"
#include "macros.h"
#include "externs.h"
#include "prototypes.h"
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
Classes | |
struct | tcache_ent |
Typedefs | |
typedef struct tcache_ent | TCENT |
Functions | |
char * | parse_to_cleanup (int eval, bool first, char *cstr, char *rstr, char *zstr) |
Helper for parse_to. More... | |
char * | parse_to (char **dstr, char delim, int eval) |
Split a line at a character, obeying nesting. More... | |
char * | parse_arglist (dbref player, dbref caller, dbref cause, char *dstr, char delim, dbref eval, char *fargs[], dbref nfargs, char *cargs[], dbref ncargs) |
Parse a line into an argument list contained in lbufs. More... | |
int | get_gender (dbref player) |
Process a command line, evaluating function calls and %-substitutions. More... | |
void | tcache_init (void) |
Initialize trace cache. More... | |
int | tcache_empty (void) |
Empty trace cache. More... | |
void | tcache_add (char *orig, char *result) |
Add to the trace cache. More... | |
void | tcache_finish (dbref player) |
Terminate trace cache. More... | |
bool | special_char (unsigned char ch) |
Check if character is a special char. More... | |
bool | token_char (int ch) |
Check if a character is a token. More... | |
char * | get_subj (int subj) |
Get subject pronoun. More... | |
char * | get_poss (int poss) |
Get Possessive Adjective pronoun. More... | |
char * | get_obj (int obj) |
Get Object pronoun. More... | |
char * | get_absp (int absp) |
Get Absolute Possessive pronoun. More... | |
void | exec (char *buff, char **bufc, dbref player, dbref caller, dbref cause, int eval, char **dstr, char *cargs[], int ncargs) |
Execute commands. More... | |
GDATA * | save_global_regs (const char *funcname) |
Save the global registers to protect them from various sorts of munging. More... | |
void | restore_global_regs (const char *funcname, GDATA *preserve) |
Restore the global registers to protect them from various sorts of munging. More... | |
Variables | |
struct tcache_ent * | tcache_head |
int | tcache_top |
int | tcache_count |
Command evaluation and cracking.
void exec | ( | char * | buff, |
char ** | bufc, | ||
dbref | player, | ||
dbref | caller, | ||
dbref | cause, | ||
int | eval, | ||
char ** | dstr, | ||
char * | cargs[], | ||
int | ncargs | ||
) |
Execute commands.
buff | Output buffer |
bufc | Output buffer tracker |
player | DBref of player |
caller | DBref of caller |
cause | DBref of cause |
eval | Evaluation flags |
dstr | Destination Buffer |
cargs | Command arguments |
ncargs | Number of command arguments |
Extend the buffer if we need to.
If we are tracing, save a copy of the starting buffer
Mundane characters are the most common. There are usually a bunch in a row. We should just copy them.
We must have a special character at this point.
A space. Add a space if not compressing or if previous char was not a space
General escape. Add the following char without special processing
Function start. Evaluate the contents of the square brackets as a function. If no closing bracket, insert the [ and continue.
Literal start. Insert everything up to the terminating } without parsing. If no closing brace, insert the { and continue.
Preserve leading spaces (Felan)
Percent-replace start. Evaluate the chars following and perform the appropriate substitution.
Null - all done
Command argument number N
Carriage return
Tab
Blank
c is last command executed
c is color
ANSI color
just skip over the characters
Xterm colors
We are dealing with background
We are dealing with foreground
Ok we got a color to process
Ran off the end. Back up.
Now we have the color string... Time to handle it
Shall we continue?
Equivalent of generic v() attr get
Ran off the end. Back up.
x-variable
Check for _<varname>
Copy. No interpretation.
We ran off the end of the string without finding a termination condition. Go back.
Variable attribute
Local registers
We know there's no result, so we just advance past.
Whoops, no end. Go back.
Ran off the end. Back up.
Objective pronoun
Personal pronoun
Subjective pronoun
Absolute possessive - idea from Empedocles
Invoker DB number
Executor DB number
Invoker name
Invoker location db#
Caller dbref
Enactor's objID
itext() equivalent
itext2() equivalent
use absolute level number
use number as delta back from current
Arguments to function
Piped command output
Percent - a literal %
Just copy
Arglist start. See if what precedes is a function. If so, execute it if we should.
Load an sbuf with an uppercase version of the func name, and see if the func exists. Trim trailing spaces from the name if configured.
If not a builtin func, check for global func
Do the right thing if it doesn't exist
If no closing delim, just insert the '(' and continue normally
Count number of args returned
We've got function(args) now, so back up over function name in output buffer.
If it's a user-defined function, perform it now.
Return the space allocated for the args
If the number of args is right, perform the func. Otherwise return an error message. Note that parse_arglist returns zero args as one null arg, so we have to handle that case specially.
Check recursion limit
Deal with the peculiar case of the calling object being destroyed mid-function sequence, such as with a command()/@destroy combo...
Return the space allocated for the arguments
We should never reach this point unless we're in a loop or switch, thanks to the table lookup.
Nesting level of loop takes precedence over switch nesting level.
If we're eating spaces, and the last thing was a space, eat it up. Complicated by the fact that at_space is initially true. So check to see if we actually put something in the buffer, too.
The ansi() function knows how to take care of itself. However, if the player used a x sub in the string, and hasn't yet terminated the color with a xn yet, we'll have to do it for them.
Report trace information
char * get_absp | ( | int | absp | ) |
Get Absolute Possessive pronoun.
subj | id of the pronoun |
int get_gender | ( | dbref | player | ) |
Process a command line, evaluating function calls and %-substitutions.
player | DBref of player |
char * get_obj | ( | int | obj | ) |
Get Object pronoun.
subj | id of the pronoun |
char * get_poss | ( | int | poss | ) |
Get Possessive Adjective pronoun.
subj | id of the pronoun |
char * get_subj | ( | int | subj | ) |
Get subject pronoun.
subj | id of the pronoun |
char * parse_arglist | ( | dbref | player, |
dbref | caller, | ||
dbref | cause, | ||
char * | dstr, | ||
char | delim, | ||
dbref | eval, | ||
char * | fargs[], | ||
dbref | nfargs, | ||
char * | cargs[], | ||
dbref | ncargs | ||
) |
Parse a line into an argument list contained in lbufs.
A pointer is returned to whatever follows the final delimiter. If the arglist is unterminated, a NULL is returned. The original arglist is destructively modified.
player | DBref of player |
caller | DBref of caller |
cause | DBref of cause |
dstr | Destination buffer |
delim | Delimiter |
eval | DBref of victim |
fargs | Function arguments |
nfargs | Number of function arguments |
cargs | Command arguments |
ncargs | Niimber of command arguments |
char * parse_to | ( | char ** | dstr, |
char | delim, | ||
int | eval | ||
) |
Split a line at a character, obeying nesting.
The line is destructively modified (a null is inserted where the delimiter was found) dstr is modified to point to the char after the delimiter, and the function return value points to the found string (space compressed if specified). If we ran off the end of the string without finding the delimiter, dstr is returned as NULL.
dstr | String to parse |
delim | Delimiter |
eval | Evaluation flags |
general escape
also escapes chars
If we hit something on the stack, unwind to it Otherwise (it's not on stack), if it's our delim we are done, and we convert the delim to a null and return a ptr to the char after the null. If it's not our delimiter, skip over it normally
space
char * parse_to_cleanup | ( | int | eval, |
bool | first, | ||
char * | cstr, | ||
char * | rstr, | ||
char * | zstr | ||
) |
Helper for parse_to.
eval | Evaluation flags |
first | Is this the first pass? |
cstr | String buffer |
rstr | String buffer |
zstr | String buffer |
void restore_global_regs | ( | const char * | funcname, |
GDATA * | preserve | ||
) |
Restore the global registers to protect them from various sorts of munging.
funcname | Function name |
preserve | Buffer where globals have been saved to. |
No change in the values. Move along.
Rather than doing a big free-and-copy thing, we could just handle changes in the data structure size. Place for future optimization.
GDATA * save_global_regs | ( | const char * | funcname | ) |
Save the global registers to protect them from various sorts of munging.
funcname | Function name |
bool special_char | ( | unsigned char | ch | ) |
Check if character is a special char.
ASCII table for reference
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI 1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US 2 SPC ! " # $ % & ' ( ) * + , - . / 3 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 4 @ A B C D E F G H I J K L M N O 5 P Q R S T U V W X Y Z [ \ ] ^ _ 6 ` a b c d e f g h i j k l m n o 7 p q r s t u v w x y z { | } ~ DEL
We want '', ESC, ' ', '\', '[', '{', '(', '', and '#'.
ch | Character to check |
We adjust the return value in order to avoid always treating '#' like a special character, as it gets used a whole heck of a lot.
void tcache_add | ( | char * | orig, |
char * | result | ||
) |
Add to the trace cache.
orig | Origin buffer |
result | Result buffer |
int tcache_empty | ( | void | ) |
Empty trace cache.
void tcache_finish | ( | dbref | player | ) |
Terminate trace cache.
player | DBref of player |
Ick. If we have no pointer, we should have no flag.
void tcache_init | ( | void | ) |
Initialize trace cache.
bool token_char | ( | int | ch | ) |
Check if a character is a token.
ch | Character to check |