/* Copyright (c) 1993 Stephen F. White */
#include <stdio.h>
#include <ctype.h>
#ifdef SYSV
#include <string.h>
#else
#include <strings.h>
#endif
#include <sys/time.h>
#include "config.h"
#include "cool.h"
#include "proto.h"
#include "sys_proto.h"
#include "execute.h"
#include "netio.h"
#include "x.tab.h"
/*
* builtins.c
*
* This file handles looking up and argument checking for the
* built-in functions, through bf_lookup(). The actual opcodes for
* the functions are contained in opcodes2.c.
*/
/*
* bf_table - Table of built-in functions
*
* "num" is the token which the parser should assign. "name" is
* the name of the function (case is irrelevant, as always).
* "minargs" is the minimum number of arguments the function will
* accept, "maxargs" is the maximum. If "maxargs" is negative, an
* unlimited number of arguments will be accepted.
*/
struct bf_entry {
int num;
const char *name;
int minargs;
int maxargs;
} bf_table[] = {
{ CLONE, "clone", 0, 0 }, /* functions which modify */
{ DESTROY, "destroy", 0, 0 }, /* the current object */
{ CHPARENTS, "chparents", 1, 1 },
{ LOCK, "lock", 1, 1 },
{ RMVERB, "rm_verb", 1, 1 },
{ RMMETHOD, "rm_method", 1, 1 },
{ RMVAR, "rm_var", 1, 1 },
{ UNLOCK, "unlock", 1, 1 },
{ VERB, "add_verb", 3, 3 },
{ ASGNGVAREXPR,"setvar", 2, 2 },
{ VERBS, "verbs", 0, 0 }, /* functions which get info */
{ VARS, "vars", 0, 0 }, /* about current object */
{ GETGVAREXPR, "getvar", 1, 1 },
{ METHODS, "methods", 0, 0 },
{ HASPARENT, "hasparent", 1, 1 },
{ OBJSIZE, "objsize", 0, 0 },
{ FIND_METHOD, "find_method", 1, 1 },
{ SPEW_METHOD,"spew_method", 1, 1 },
{ LIST_METHOD, "list_method", 1, 4 },
{ DECOMPILE, "decompile", 0, 0 },
{ PSUB, "psub", 1, 1 },
{ ECHO, "echo", 1, 1 }, /* player functions */
{ ECHO_FILE, "echo_file", 1, 1 },
{ QUIT, "quit", 0, 0 },
{ PROGRAM, "program", 0, 2 },
{ COMPILE, "compile", 1, 3 },
{ SETADD, "setadd", 2, 2 }, /* list functions */
{ SETREMOVE, "setremove", 2, 2 },
{ LISTINSERT, "listinsert", 2, 3 },
{ LISTAPPEND, "listappend", 2, 3 },
{ LISTDELETE, "listdelete", 2, 2 },
{ LISTASSIGN, "listassign", 3, 3 },
{ EXPLODE, "explode", 1, 2 }, /* string functions */
{ STRSUB, "strsub", 3, 4 },
{ PAD, "pad", 2, 3 },
{ MATCH, "match", 2, 3 },
{ MATCH_FULL, "match_full", 2, 3 },
{ CRYPT, "crypt", 1, 2 },
{ TONUM, "tonum", 1, 1 }, /* conversion functions */
{ TOOBJ, "toobj", 1, 1 },
{ TOSTR, "tostr", 1, 1 },
{ TOERR, "toerr", 1, 1 },
{ TYPEOF, "typeof", 1, 1 }, /* utility functions */
{ LENGTHOF, "lengthof", 1, 1 },
{ SERVEROF, "serverof", 1, 1 },
{ SERVERNAME, "servername", 1, 1 },
{ SERVERS, "servers", 0, 0 },
{ RANDOM, "random", 1, 1 },
{ TIME, "time", 0, 0 },
{ CTIME, "ctime", 0, 1 },
{ SLEEP, "sleep", 1, 1 },
{ KILL, "kill", 1, 1 },
{ PS, "ps", 0, 0 },
{ SHUTDOWN, "shutdown", 0, 0 }, /* wizard functions */
{ DUMP, "dump", 0, 0 },
{ WRITELOG, "writelog", 1, 1 },
{ CHECKMEM, "checkmem", 0, 0 },
{ CACHE_STATS, "cache_stats", 0, 0 },
};
/*
* bf_lookup() - Look up a built-in function by name
*
* "name" is the function to look up. "nargs" is the number of arguments
* passed to the function. The return value, if positive, is the token
* which the parser should assign. If the return value is negative,
* an error has occurred:
*
* -1: too few arguments
* -2: too many arguments
* -3: function not found
*/
int
bf_lookup(const char *name, int nargs)
{
int i;
for (i = 0; i < Arraysize(bf_table); i++) {
if (!cool_strcasecmp(bf_table[i].name, name)) {
if (nargs < bf_table[i].minargs) {
return -1;
} else if (bf_table[i].maxargs >= 0
&& nargs > bf_table[i].maxargs) {
return -2;
} else {
return bf_table[i].num;
}
}
}
return -3;
}
const char *
bf_id2name(int id)
{
int i;
for (i = 0; i < Arraysize(bf_table); i++) {
if (bf_table[i].num == id) {
return bf_table[i].name;
}
}
return 0;
}