/* parse.h - parser declarations and macros
* Written by T. Alexander Popiel, 13 May 1995
* Last modified by T. Alexander Popiel, 26 May 1995
*
* Copyright (c) 1995 by T. Alexander Popiel
* See copyrite.h for details.
*/
#ifndef _PARSE_H_
#define _PARSE_H_
#include "copyrite.h"
#include "config.h"
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include "confmagic.h"
/* This is the type to be used for numbers which may be non-integral. */
#define HUGE_NVAL HUGE_DOUBLE
/* These are some common error messages. */
extern char e_int[]; /* #-1 ARGUMENT MUST BE INTEGER */
extern char e_ints[]; /* #-1 ARGUMENTS MUST BE INTEGERS */
extern char e_uint[]; /* #-1 ARGUMENT MUST BE POSITIVE INTEGER */
extern char e_uints[]; /* #-1 ARGUMENTS MUST BE POSITIVE INTEGERS */
extern char e_num[]; /* #-1 ARGUMENT MUST BE NUMBER */
extern char e_nums[]; /* #-1 ARGUMENTS MUST BE NUMBERS */
extern char e_perm[]; /* #-1 PERMISSION DENIED */
extern char e_atrperm[]; /* #-1 NO PERMISSION TO GET ATTRIBUTE */
extern char e_match[]; /* #-1 NO MATCH */
extern char e_notvis[]; /* #-1 NO SUCH OBJECT VISIBLE */
extern char e_disabled[]; /* #-1 FUNCTION DISABLED */
extern char e_range[]; /* #-1 OUT OF RANGE */
/* The following routines all take strings as arguments, and return
* data of the appropriate types.
*/
extern int parse_boolean(char const *str);
extern dbref parse_dbref(char const *str);
extern dbref qparse_dbref(char const *str);
extern dbref parse_objid(char const *str);
#define parse_integer(str) strtol(str, NULL, 10)
#define parse_uinteger(str) strtoul(str, NULL, 10)
#define parse_number(str) strtod(str, NULL)
/* The following routines all take varoius arguments, and return
* string representations of same. The string representations
* are stored in static buffers, so the next call to each function
* will destroy any old string that was there.
*/
#define unparse_boolean(x) ((x) ? "1" : "0")
char *unparse_dbref(dbref num);
char *unparse_integer(int num);
char *unparse_uinteger(unsigned int num);
char *unparse_number(NVAL num);
char *unparse_types(int type);
/* The following routines all take strings as arguments, and return
* true iff the string is a valid representation of the appropriate type.
*/
int is_dbref(char const *str);
int is_objid(char const *str);
int is_integer(char const *str);
int is_uinteger(char const *str);
int is_boolean(char const *str);
/* Split a sep-delimited string into individual elements */
extern int list2arr(char *r[], int max, char *list, char sep);
/* The reverse */
extern void arr2list(char *r[], int max, char *list, char **lp, char *sep);
/* All function declarations follow the format: */
#ifndef HAVE_FUN_DEFINED
typedef struct fun FUN;
#define HAVE_FUN_DEFINED
#endif
/** Common declaration for softcode function implementations */
#define FUNCTION(fun_name) \
/* ARGSUSED */ /* try to keep lint happy */ \
void fun_name (FUN *fun, char *buff, char **bp, int nargs, char *args[], \
int arglens[], dbref executor, dbref caller, dbref enactor, \
char const *called_as, PE_Info *pe_info); \
void fun_name(FUN *fun __attribute__ ((__unused__)), \
char *buff __attribute__ ((__unused__)), \
char **bp __attribute__ ((__unused__)), \
int nargs __attribute__ ((__unused__)), \
char *args[] __attribute__ ((__unused__)), \
int arglens[] __attribute__ ((__unused__)), \
dbref executor __attribute__ ((__unused__)), \
dbref caller __attribute__ ((__unused__)), \
dbref enactor __attribute__ ((__unused__)), \
char const *called_as __attribute__ ((__unused__)), \
PE_Info *pe_info __attribute__ ((__unused__)))
/* All results are returned in buff, at the point *bp. *bp is likely
* not equal to buff, so make no assumptions about writing at the
* start of the buffer. *bp must be updated to point at the next
* place to be filled (ala safe_str() and safe_chr()). Be very
* careful about not overflowing buff; use of safe_str() and safe_chr()
* for all writes into buff is highly recommended.
*
* nargs is the count of the number of arguments passed to the function,
* and args is an array of pointers to them. args will have at least
* nargs elements, or 10 elements, whichever is greater. The first ten
* elements are initialized to NULL for ease of porting functions from
* the old style, but relying on such is considered bad form.
* The argument strings are stored in BUFFER_LEN buffers, but reliance
* on that size is also considered bad form. The argument strings may
* be modified, but modifying the pointers to the argument strings will
* cause crashes.
*
* executor corresponds to %!, the object invoking the function.
* caller corresponds to %@, the last object to do a U() or similar.
* enactor corresponds to %#, the object that started the whole mess.
* Note that fun_ufun() and similar must swap around these parameters
* in calling process_expression(); no checks are made in the parser
* itself to maintain these values.
*
* called_as contains a pointer to the name of the function called
* (taken from the function table). This may be used to distinguish
* multiple functions which use the same C function for implementation.
*
* pe_info holds context information used by the parser. It should
* be passed untouched to process_expression(), if it is called.
* pe_info should be treated as a black box; its structure and contents
* may change without notice.
*
* Normally, p_e() returns 0. It returns 1 upon hitting the CPU time limit.
*/
/* process_expression() evaluates expressions. What a concept. */
int process_expression(char *buff, char **bp, char const **str,
dbref executor, dbref caller, dbref enactor,
int eflags, int tflags, PE_Info * pe_info);
/* buff is a pointer to a BUFFER_LEN string to contain the expression
* result. *bp is the point in buff at which the result should be written.
* *bp will be updated to point one past the result of the expression,
* and the result will _NOT_ be null-terminated.
* For top-level calls to process_expression(), *bp should probably equal
* buff. For calls to process_expression() inside function implementations,
* buff and bp should probably be the values passed into the implementation.
*
* *str is a pointer to a string containing the expression to evaluate.
* *str will be updated to point at the terminator which caused return
* from process_expression(). The string pointed to by *str will not
* be modified.
*
* executor, caller, and enactor represent %!, %@, and %#, respectively.
* No validity checking of any sort is done on these parameters, so please
* be careful with them.
*
* eflags consists of one or more of the following evaluation flags:
*/
#define PE_NOTHING 0
#define PE_COMPRESS_SPACES 0x00000001
#define PE_STRIP_BRACES 0x00000002
#define PE_COMMAND_BRACES 0x00000004
#define PE_EVALUATE 0x00000010
#define PE_FUNCTION_CHECK 0x00000020
#define PE_FUNCTION_MANDATORY 0x00000040
#define PE_LITERAL 0x00000100
#define PE_DOLLAR 0x00000200
#define PE_DEBUG 0x00000400
#define PE_DEFAULT (PE_COMPRESS_SPACES | PE_STRIP_BRACES | \
PE_EVALUATE | PE_FUNCTION_CHECK)
/* PE_COMPRESS_SPACES strips leading and trailing spaces, and reduces sets
* of internal spaces to one space.
*
* PE_STRIP_BRACES strips off top-level braces.
*
* PE_COMMAND_BRACES strips off only completely enclosing braces,
* suitable for trimming command lists given to noparse commands like
* @switch or @break.
*
* PE_EVALUATE allows %-substitutions, []-evaluation, function evaluation,
* and \-stripping.
*
* PE_FUNCTION_CHECK allows function evaluation. Note that both PE_EVALUATE
* and PE_FUNCTION_CHECK must be active for function evaluation to occur.
*
* PE_FUNCTION_MANDATORY causes an error to be reported if a function call
* is attempted for a non-existant function. Otherwise, the function call
* is not evaluated, but rather treated as normal text.
*
* PE_LITERAL prevents { and [ from being recognized and causing recursion.
*
* PE_DEFAULT is the most commonly used set of flags, normally sufficient
* for calls to process_expression().
*
*
* tflags consists of one or more of the following termination flags:
*/
#define PT_NOTHING 0
#define PT_BRACE 0x00000001
#define PT_BRACKET 0x00000002
#define PT_PAREN 0x00000004
#define PT_COMMA 0x00000008
#define PT_SEMI 0x00000010
#define PT_EQUALS 0x00000020
#define PT_SPACE 0x00000040
/* These represent '\0', '}', ']', ')', ',', ';', '=', and ' ', respectively.
* If the character corresponding to a set flag is encountered, then
* process_expression() will exit, with *str pointing at the terminating
* charater. '\0' is always a terminating character.
*
* PT_DEFAULT, below, is provided as syntactic sugar.
*/
#define PT_DEFAULT PT_NOTHING
/* pe_info is a pointer to a structure of internal state information
* for process_expression(). Top-level calls to process_expression()
* should pass a NULL as pe_info. Calls to process_expression() from
* function implementations should pass their pe_info as pe_info.
* In no case should any other pe_info be passed to process_expression().
*/
/* For the cpu time limiting. From timer.c */
extern void start_cpu_timer(void);
extern void reset_cpu_timer(void);
#endif /* !_PARSE_H_ */