cfad47cfa3/tads2/suprun.c
Commiter: Nikos Chantziaras
Author: Nikos Chantziaras
Revision: cfad47cfa3
File Size: 12.1 KB
(June 01, 2009 20:54 UTC) Almost 3 years ago
Initial commit.
#ifdef RCSID
static char RCSid[] =
"$Header: d:/cvsroot/tads/TADS2/SUPRUN.C,v 1.3 1999/07/11 00:46:30 MJRoberts Exp $";
#endif
/*
* Copyright (c) 1992, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
suprun.c - setup functions for run-time
Function
This module implements the set-up functions needed at run-time
Notes
Separated from sup.c to avoid having to link functions needed only
in the compiler into the runtime.
Modified
12/16/92 MJRoberts - add TADS/Graphic extensions
04/11/92 MJRoberts - creation
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "os.h"
#include "std.h"
#include "obj.h"
#include "prp.h"
#include "dat.h"
#include "tok.h"
#include "mcm.h"
#include "mch.h"
#include "sup.h"
#include "bif.h"
supbidef osfar_t supbitab[] =
{
{ "say", bifsay },
{ "car", bifcar },
{ "cdr", bifcdr },
{ "length", biflen },
{ "randomize", bifsrn },
{ "rand", bifrnd },
{ "substr", bifsub },
{ "cvtstr", bifcvs },
{ "cvtnum", bifcvn },
{ "upper", bifupr },
{ "lower", biflwr },
{ "caps", bifcap },
{ "find", biffnd },
{ "getarg", bifarg },
{ "datatype", biftyp },
{ "setdaemon", bifsdm },
{ "setfuse", bifsfs },
{ "setversion", bifsvn },
{ "notify", bifnfy },
{ "unnotify", bifunn },
{ "yorn", bifyon },
{ "remfuse", bifrfs },
{ "remdaemon", bifrdm },
{ "incturn", bifinc },
{ "quit", bifqui },
{ "save", bifsav },
{ "restore", bifrso },
{ "logging", biflog },
{ "input", bifinp },
{ "setit", bifsit },
{ "askfile", bifask },
{ "setscore", bifssc },
{ "firstobj", biffob },
{ "nextobj", bifnob },
{ "isclass", bifisc },
{ "restart", bifres },
{ "debugTrace", biftrc },
{ "undo", bifund },
{ "defined", bifdef },
{ "proptype", bifpty },
{ "outhide", bifoph },
{ "runfuses", bifruf },
{ "rundaemons", bifrud },
{ "gettime", biftim },
{ "getfuse", bifgfu },
{ "intersect", bifsct },
{ "inputkey", bifink },
{ "objwords", bifwrd },
{ "addword", bifadw },
{ "delword", bifdlw },
{ "getwords", bifgtw },
{ "nocaps", bifnoc },
{ "skipturn", bifskt },
{ "clearscreen", bifcls },
{ "firstsc", bif1sc },
{ "verbinfo", bifvin },
{ "fopen", biffopen },
{ "fclose", biffclose },
{ "fwrite", biffwrite },
{ "fread", biffread },
{ "fseek", biffseek },
{ "fseekeof", biffseekeof },
{ "ftell", bifftell },
{ "outcapture", bifcapture },
{ "systemInfo", bifsysinfo },
{ "morePrompt", bifmore },
{ "parserSetMe", bifsetme },
{ "parserGetMe", bifgetme },
{ "reSearch", bifresearch },
{ "reGetGroup", bifregroup },
{ "inputevent", bifinpevt },
{ "timeDelay", bifdelay },
{ "setOutputFilter", bifsetoutfilter },
{ "execCommand", bifexec },
{ "parserGetObj", bifgetobj },
{ "parseNounList", bifparsenl },
{ "parserTokenize", bifprstok },
{ "parserGetTokTypes", bifprstoktyp },
{ "parserDictLookup", bifprsdict },
{ "parserResolveObjects", bifprsrslv },
{ "parserReplaceCommand", bifprsrplcmd },
{ "exitobj", bifexitobj },
{ "inputdialog", bifinpdlg },
{ "resourceExists", bifresexists },
/*
* To accommodate systemInfo, we've removed g_readpic. This has been
* present for a while and didn't do anything, since tads/g was never
* released. We can therefore use its function slot without requiring
* a format change.
*/
/* { "g_readpic", bifgrp }, */
/* likewise these */
/* { "g_showpic", bifgsp }, */
/* { "g_sethot", bifgsh }, */
/* { "g_inventory", bifgin }, */
/*
* more tads/g functions - these are kept around mostly as
* placeholders in case we want to use these slots in the future
*/
/* { "g_compass", bifgco }, - removed for reSearch */
/* { "g_overlay", bifgov }, - removed for reGetGroup */
/* { "g_mode", bifgmd }, - removed for inputevent */
/* { "g_music", bifgmu }, - removed for timeDelay */
/* { "g_pause", bifgpa }, - removed for setOutputFilter */
/* { "g_effect", bifgef }, - removed for execCommand */
/* { "g_sound", bifgsn }, - removed for parserGetObj */
/* a few more placeholder slots for future expansion */
/* { "__reserved_func_0", bifgsn }, - removed for parseNounList */
/* { "__reserved_func_2", bifgsn }, - removed for parserTokenize */
/* { "__reserved_func_3", bifgsn }, - removed for parserGetTokTypes */
/* { "__reserved_func_4", bifgsn }, - removed for parserDictLookup */
/* { "__reserved_func_5", bifgsn }, - removed for parserResolveObjects */
/* { "__reserved_func_6", bifgsn }, - removed for parserReplaceCommand */
/* { "__reserved_func_7", bifgsn }, - removed for exitobj */
/* { "__reserved_func_8", bifgsn }, - removed for inputdialog */
/* { "__reserved_func_9", bifgsn }, - removed for resourceExists */
/* more slots added in 2.3.1 */
{ "__reserved_func_10", bifgsn },
{ "__reserved_func_11", bifgsn },
{ "__reserved_func_12", bifgsn },
{ "__reserved_func_13", bifgsn },
{ "__reserved_func_14", bifgsn },
{ "__reserved_func_15", bifgsn },
{ "__reserved_func_16", bifgsn },
{ "__reserved_func_17", bifgsn },
{ "__reserved_func_18", bifgsn },
{ "__reserved_func_19", bifgsn },
{ 0, 0 }
};
/* set up built-in functions array without symbol table (for run-time) */
void supbif(supcxdef *sup, void (*bif[])(bifcxdef*, int), int bifsiz)
{
supbidef *p;
int i;
for (p = supbitab, i = 0 ; p->supbinam ; ++i, ++p)
{
if (i >= bifsiz) errsig(sup->supcxerr, ERR_MANYBIF);
bif[i] = p->supbifn;
}
}
/* set up contents property for load-on-demand */
void supcont(void *ctx0, objnum obj, prpnum prp)
{
supcxdef *ctx = (supcxdef *)ctx0;
vocidef ***vpg;
vocidef **v;
voccxdef *voc = ctx->supcxvoc;
int i;
int j;
int len = 2;
objnum chi;
objnum loc;
/* be sure the buffer is allocated */
if (!ctx->supcxbuf)
{
ctx->supcxlen = 512;
ctx->supcxbuf = mchalo(ctx->supcxerr, (ushort)ctx->supcxlen,
"supcont");
}
assert(prp == PRP_CONTENTS); /* the only thing that makes sense */
for (vpg = voc->voccxinh, i = 0 ; i < VOCINHMAX ; ++vpg, ++i)
{
if (!*vpg) continue; /* no entries on this page */
for (v = *vpg, chi = (i << 8), j = 0 ; j < 256 ; ++v, ++chi, ++j)
{
/* if there's no record at this location, skip it */
if (!*v) continue;
/* inherit the location if it hasn't been set to any value */
if ((*v)->vociloc == MCMONINV
&& !((*v)->vociflg & VOCIFLOCNIL))
loc = (*v)->vociilc;
else
loc = (*v)->vociloc;
/* if this object is in the indicated location, add it */
if (loc == obj && !((*v)->vociflg & VOCIFCLASS))
{
/* see if we have room in list buffer; expand buffer if not */
if (len + 3 > ctx->supcxlen)
{
uchar *newbuf;
/* allocate a new buffer */
newbuf = mchalo(ctx->supcxerr,
(ushort)(len + 512), "supcont");
/* copy the old buffer's contents into the new buffer */
memcpy(newbuf, ctx->supcxbuf, ctx->supcxlen);
/* remember the new buffer length */
ctx->supcxlen = len + 512;
/* free the old buffer */
mchfre(ctx->supcxbuf);
/* remember the new buffer */
ctx->supcxbuf = newbuf;
/* sanity check for integer overflow */
if (len + 3 > ctx->supcxlen)
errsig(ctx->supcxmem->mcmcxgl->mcmcxerr, ERR_SUPOVF);
}
ctx->supcxbuf[len] = DAT_OBJECT;
oswp2(ctx->supcxbuf + len + 1, chi);
len += 3;
}
}
}
oswp2(ctx->supcxbuf, len);
objsetp(ctx->supcxmem, obj, prp, DAT_LIST, ctx->supcxbuf,
ctx->supcxrun->runcxundo);
}
static void supiwrds(voccxdef *ctx, objnum sc, objnum target, int flags)
{
int i;
vocdef *v;
vocdef **vp;
vocwdef *vw;
/* go through each hash value looking for superclass object */
for (i = VOCHASHSIZ, vp = ctx->voccxhsh ; i != 0 ; ++vp, --i)
{
/* go through all words in this hash chain */
for (v = *vp ; v != 0 ; v = v->vocnxt)
{
/* go through all vocwdef's defined for this word */
for (vw = vocwget(ctx, v->vocwlst) ; vw ;
vw = vocwget(ctx, vw->vocwnxt))
{
/* add word to target if it's defined for this superclass */
if (vw->vocwobj == sc)
vocadd2(ctx, vw->vocwtyp, target, VOCFINH + flags,
v->voctxt, v->voclen,
(v->vocln2 ? v->voctxt + v->voclen : (uchar *)0),
v->vocln2);
}
}
}
}
/* set up inherited vocabulary for a particular object */
void supivoc1(supcxdef *sup, voccxdef *ctx, vocidef *v, objnum target,
int inh_from_obj, int flags)
{
objnum *sc;
int numsc;
vocidef *scv;
for (numsc = v->vocinsc, sc = v->vocisc ; numsc ; ++sc, --numsc)
{
scv = vocinh(ctx, *sc);
if (scv)
{
/* inherit from its superclasses first */
supivoc1(sup, ctx, scv, target, FALSE, flags);
/* if it's a class object, we can inherit from it */
if (scv->vociflg & VOCIFCLASS)
{
/* inherit location, if we haven't already done so */
if (v->vociilc == MCMONINV)
{
if (scv->vociloc == MCMONINV)
v->vociilc = scv->vociilc;
else
v->vociilc = scv->vociloc;
}
}
/*
* inherit from superclass if it's a class, or if we're
* supposed to inherit from any object
*/
if (inh_from_obj || (scv->vociflg & VOCIFCLASS))
{
/* inherit vocabulary if this superclass has any words */
if (scv->vociflg & VOCIFVOC)
supiwrds(ctx, *sc, target, flags);
}
}
else
{
char buf[TOKNAMMAX + 1];
/* get the symbol's name */
supgnam(buf, sup->supcxtab, *sc);
/* log an error with the symbol's name and location of first use */
sup_log_undefobj(ctx->voccxmem, ctx->voccxerr, ERR_UNDFOBJ,
buf, (int)strlen(buf), *sc);
}
}
}
void sup_log_undefobj(mcmcxdef *mctx, errcxdef *ec, int err,
char *nm, int nmlen, objnum objn)
{
uchar *p;
size_t len;
/*
* if the object has any superclasses defined, what must have
* happened is that we encountered an error in the course of
* defining the object; the object is partially defined, hence it
* won't show up in our records of defined objects, yet it really
* shouldn't count as an undefined object; simply suppress the
* message in this case
*/
if (objget1sc(mctx, objn) != MCMONINV)
return;
/* get the object - it contains the location where it was defined */
p = mcmlck(mctx, (mcmon)objn);
/* skip the object header */
p += OBJDEFSIZ;
/* get the length of the name */
len = strlen((char *)p);
#ifdef OS_ERRLINE
len += strlen((char *)p + len + 1);
#endif
/* log the error */
errlog2(ec, err, ERRTSTR, errstr(ec, nm, nmlen),
ERRTSTR, errstr(ec, (char *)p, len));
/* done with the object */
mcmunlck(mctx, (mcmon)objn);
}
|