cfad47cfa3/tads2/suprun.c

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
#ifdef RCSID
2
static char RCSid[] =
3
"$Header: d:/cvsroot/tads/TADS2/SUPRUN.C,v 1.3 1999/07/11 00:46:30 MJRoberts Exp $";
4
#endif
5
6
/* 
7
 *   Copyright (c) 1992, 2002 Michael J. Roberts.  All Rights Reserved.
8
 *   
9
 *   Please see the accompanying license file, LICENSE.TXT, for information
10
 *   on using and copying this software.  
11
 */
12
/*
13
Name
14
  suprun.c - setup functions for run-time
15
Function
16
  This module implements the set-up functions needed at run-time
17
Notes
18
  Separated from sup.c to avoid having to link functions needed only
19
  in the compiler into the runtime.
20
Modified
21
  12/16/92 MJRoberts     - add TADS/Graphic extensions
22
  04/11/92 MJRoberts     - creation
23
*/
24
25
#include <stdlib.h>
26
#include <string.h>
27
#include <assert.h>
28
29
#include "os.h"
30
#include "std.h"
31
#include "obj.h"
32
#include "prp.h"
33
#include "dat.h"
34
#include "tok.h"
35
#include "mcm.h"
36
#include "mch.h"
37
#include "sup.h"
38
#include "bif.h"
39
40
supbidef osfar_t supbitab[] =
41
{
42
    { "say", bifsay },
43
    { "car", bifcar },
44
    { "cdr", bifcdr },
45
    { "length", biflen },
46
    { "randomize", bifsrn },
47
    { "rand", bifrnd },
48
    { "substr", bifsub },
49
    { "cvtstr", bifcvs },
50
    { "cvtnum", bifcvn },
51
    { "upper", bifupr },
52
    { "lower", biflwr },
53
    { "caps", bifcap },
54
    { "find", biffnd },
55
    { "getarg", bifarg },
56
    { "datatype", biftyp },
57
    { "setdaemon", bifsdm },
58
    { "setfuse", bifsfs },
59
    { "setversion", bifsvn },
60
    { "notify", bifnfy },
61
    { "unnotify", bifunn },
62
    { "yorn", bifyon },
63
    { "remfuse", bifrfs },
64
    { "remdaemon", bifrdm },
65
    { "incturn", bifinc },
66
    { "quit", bifqui },
67
    { "save", bifsav },
68
    { "restore", bifrso },
69
    { "logging", biflog },
70
    { "input", bifinp },
71
    { "setit", bifsit },
72
    { "askfile", bifask },
73
    { "setscore", bifssc },
74
    { "firstobj", biffob },
75
    { "nextobj", bifnob },
76
    { "isclass", bifisc },
77
    { "restart", bifres },
78
    { "debugTrace", biftrc },
79
    { "undo", bifund },
80
    { "defined", bifdef },
81
    { "proptype", bifpty },
82
    { "outhide", bifoph },
83
    { "runfuses", bifruf },
84
    { "rundaemons", bifrud },
85
    { "gettime", biftim },
86
    { "getfuse", bifgfu },
87
    { "intersect", bifsct },
88
    { "inputkey", bifink },
89
    { "objwords", bifwrd },
90
    { "addword", bifadw },
91
    { "delword", bifdlw },
92
    { "getwords", bifgtw },
93
    { "nocaps", bifnoc },
94
    { "skipturn", bifskt },
95
    { "clearscreen", bifcls },
96
    { "firstsc", bif1sc },
97
    { "verbinfo", bifvin },
98
    { "fopen", biffopen },
99
    { "fclose", biffclose },
100
    { "fwrite", biffwrite },
101
    { "fread", biffread },
102
    { "fseek", biffseek },
103
    { "fseekeof", biffseekeof },
104
    { "ftell", bifftell },
105
    { "outcapture", bifcapture },
106
107
    { "systemInfo", bifsysinfo },
108
    { "morePrompt", bifmore },
109
    { "parserSetMe", bifsetme },
110
    { "parserGetMe", bifgetme },
111
112
    { "reSearch", bifresearch },
113
    { "reGetGroup", bifregroup },
114
    { "inputevent", bifinpevt },
115
    { "timeDelay", bifdelay },
116
    { "setOutputFilter", bifsetoutfilter },
117
    { "execCommand", bifexec },
118
    { "parserGetObj", bifgetobj },
119
    { "parseNounList", bifparsenl },
120
    { "parserTokenize", bifprstok },
121
    { "parserGetTokTypes", bifprstoktyp },
122
    { "parserDictLookup", bifprsdict },
123
    { "parserResolveObjects", bifprsrslv },
124
    { "parserReplaceCommand", bifprsrplcmd },
125
    { "exitobj", bifexitobj },
126
    { "inputdialog", bifinpdlg },
127
    { "resourceExists", bifresexists },
128
129
    /* 
130
     *   To accommodate systemInfo, we've removed g_readpic.  This has been
131
     *   present for a while and didn't do anything, since tads/g was never
132
     *   released.  We can therefore use its function slot without requiring
133
     *   a format change.  
134
     */
135
    /* { "g_readpic", bifgrp }, */
136
137
    /* likewise these */
138
    /* { "g_showpic", bifgsp }, */
139
    /* { "g_sethot", bifgsh }, */
140
    /* { "g_inventory", bifgin }, */
141
142
    /* 
143
     *   more tads/g functions - these are kept around mostly as
144
     *   placeholders in case we want to use these slots in the future 
145
     */
146
    /* { "g_compass", bifgco }, - removed for reSearch */
147
    /* { "g_overlay", bifgov }, - removed for reGetGroup */
148
    /* { "g_mode", bifgmd }, - removed for inputevent */
149
    /* { "g_music", bifgmu }, - removed for timeDelay */
150
    /* { "g_pause", bifgpa }, - removed for setOutputFilter */
151
    /* { "g_effect", bifgef }, - removed for execCommand */
152
    /* { "g_sound", bifgsn }, - removed for parserGetObj */
153
154
    /* a few more placeholder slots for future expansion */
155
    /* { "__reserved_func_0", bifgsn }, - removed for parseNounList */
156
    /* { "__reserved_func_2", bifgsn }, - removed for parserTokenize */
157
    /* { "__reserved_func_3", bifgsn }, - removed for parserGetTokTypes */
158
    /* { "__reserved_func_4", bifgsn }, - removed for parserDictLookup */
159
    /* { "__reserved_func_5", bifgsn }, - removed for parserResolveObjects */
160
    /* { "__reserved_func_6", bifgsn }, - removed for parserReplaceCommand */
161
    /* { "__reserved_func_7", bifgsn }, - removed for exitobj */
162
    /* { "__reserved_func_8", bifgsn }, - removed for inputdialog */
163
    /* { "__reserved_func_9", bifgsn }, - removed for resourceExists */
164
165
    /* more slots added in 2.3.1 */
166
    { "__reserved_func_10", bifgsn },
167
    { "__reserved_func_11", bifgsn },
168
    { "__reserved_func_12", bifgsn },
169
    { "__reserved_func_13", bifgsn },
170
    { "__reserved_func_14", bifgsn },
171
    { "__reserved_func_15", bifgsn },
172
    { "__reserved_func_16", bifgsn },
173
    { "__reserved_func_17", bifgsn },
174
    { "__reserved_func_18", bifgsn },
175
    { "__reserved_func_19", bifgsn },
176
    
177
178
    { 0, 0 }
179
};
180
181
/* set up built-in functions array without symbol table (for run-time) */
182
void supbif(supcxdef *sup, void (*bif[])(bifcxdef*, int), int bifsiz)
183
{
184
    supbidef *p;
185
    int       i;
186
187
    for (p = supbitab, i = 0 ; p->supbinam ; ++i, ++p)
188
    {
189
        if (i >= bifsiz) errsig(sup->supcxerr, ERR_MANYBIF);
190
        bif[i] = p->supbifn;
191
    }
192
}
193
194
/* set up contents property for load-on-demand */
195
void supcont(void *ctx0, objnum obj, prpnum prp)
196
{
197
    supcxdef  *ctx = (supcxdef *)ctx0;
198
    vocidef ***vpg;
199
    vocidef  **v;
200
    voccxdef  *voc = ctx->supcxvoc;
201
    int        i;
202
    int        j;
203
    int        len = 2;
204
    objnum     chi;
205
    objnum     loc;
206
207
    /* be sure the buffer is allocated */
208
    if (!ctx->supcxbuf)
209
    {
210
        ctx->supcxlen = 512;
211
        ctx->supcxbuf = mchalo(ctx->supcxerr, (ushort)ctx->supcxlen,
212
                               "supcont");
213
    }
214
215
    assert(prp == PRP_CONTENTS);         /* the only thing that makes sense */
216
    for (vpg = voc->voccxinh, i = 0 ; i < VOCINHMAX ; ++vpg, ++i)
217
    {
218
        if (!*vpg) continue;                     /* no entries on this page */
219
        for (v = *vpg, chi = (i << 8), j = 0 ; j < 256 ; ++v, ++chi, ++j)
220
        {
221
            /* if there's no record at this location, skip it */
222
            if (!*v) continue;
223
224
            /* inherit the location if it hasn't been set to any value */
225
            if ((*v)->vociloc == MCMONINV
226
                && !((*v)->vociflg & VOCIFLOCNIL))
227
                loc = (*v)->vociilc;
228
            else
229
                loc = (*v)->vociloc;
230
231
            /* if this object is in the indicated location, add it */
232
            if (loc == obj && !((*v)->vociflg & VOCIFCLASS))
233
            {
234
                /* see if we have room in list buffer; expand buffer if not */
235
                if (len + 3 > ctx->supcxlen)
236
                {
237
                    uchar *newbuf;
238
239
                    /* allocate a new buffer */
240
                    newbuf = mchalo(ctx->supcxerr,
241
                                    (ushort)(len + 512), "supcont");
242
243
                    /* copy the old buffer's contents into the new buffer */
244
                    memcpy(newbuf, ctx->supcxbuf, ctx->supcxlen);
245
246
                    /* remember the new buffer length */
247
                    ctx->supcxlen = len + 512;
248
249
                    /* free the old buffer */
250
                    mchfre(ctx->supcxbuf);
251
252
                    /* remember the new buffer */
253
                    ctx->supcxbuf = newbuf;
254
255
                    /* sanity check for integer overflow */
256
                    if (len + 3 > ctx->supcxlen)
257
                        errsig(ctx->supcxmem->mcmcxgl->mcmcxerr, ERR_SUPOVF);
258
                }
259
                ctx->supcxbuf[len] = DAT_OBJECT;
260
                oswp2(ctx->supcxbuf + len + 1, chi);
261
                len += 3;
262
            }
263
        }
264
    }
265
266
    oswp2(ctx->supcxbuf, len);
267
    objsetp(ctx->supcxmem, obj, prp, DAT_LIST, ctx->supcxbuf,
268
            ctx->supcxrun->runcxundo);
269
}
270
271
static void supiwrds(voccxdef *ctx, objnum sc, objnum target, int flags)
272
{
273
    int       i;
274
    vocdef   *v;
275
    vocdef  **vp;
276
    vocwdef  *vw;
277
    
278
    /* go through each hash value looking for superclass object */
279
    for (i = VOCHASHSIZ, vp = ctx->voccxhsh ; i != 0 ; ++vp, --i)
280
    {
281
        /* go through all words in this hash chain */
282
        for (v = *vp ; v != 0 ; v = v->vocnxt)
283
        {
284
            /* go through all vocwdef's defined for this word */
285
            for (vw = vocwget(ctx, v->vocwlst) ; vw ;
286
                 vw = vocwget(ctx, vw->vocwnxt))
287
            {
288
                /* add word to target if it's defined for this superclass */
289
                if (vw->vocwobj == sc)
290
                    vocadd2(ctx, vw->vocwtyp, target, VOCFINH + flags,
291
                            v->voctxt, v->voclen,
292
                            (v->vocln2 ? v->voctxt + v->voclen : (uchar *)0),
293
                            v->vocln2);
294
            }
295
        }
296
    }
297
}
298
299
/* set up inherited vocabulary for a particular object */
300
void supivoc1(supcxdef *sup, voccxdef *ctx, vocidef *v, objnum target,
301
              int inh_from_obj, int flags)
302
{
303
    objnum   *sc;
304
    int       numsc;
305
    vocidef  *scv;
306
    
307
    for (numsc = v->vocinsc, sc = v->vocisc ; numsc ; ++sc, --numsc)
308
    {
309
        scv = vocinh(ctx, *sc);
310
        if (scv)
311
        {
312
            /* inherit from its superclasses first */
313
            supivoc1(sup, ctx, scv, target, FALSE, flags);
314
            
315
            /* if it's a class object, we can inherit from it */
316
            if (scv->vociflg & VOCIFCLASS)
317
            {
318
                /* inherit location, if we haven't already done so */
319
                if (v->vociilc == MCMONINV)
320
                {
321
                    if (scv->vociloc == MCMONINV)
322
                        v->vociilc = scv->vociilc;
323
                    else
324
                        v->vociilc = scv->vociloc;
325
                }
326
            }
327
328
            /*
329
             *   inherit from superclass if it's a class, or if we're
330
             *   supposed to inherit from any object 
331
             */
332
            if (inh_from_obj || (scv->vociflg & VOCIFCLASS))
333
            {
334
                /* inherit vocabulary if this superclass has any words */
335
                if (scv->vociflg & VOCIFVOC)
336
                    supiwrds(ctx, *sc, target, flags);
337
            }
338
        }
339
        else
340
        {
341
            char  buf[TOKNAMMAX + 1];
342
343
            /* get the symbol's name */
344
            supgnam(buf, sup->supcxtab, *sc);
345
346
            /* log an error with the symbol's name and location of first use */
347
            sup_log_undefobj(ctx->voccxmem, ctx->voccxerr, ERR_UNDFOBJ,
348
                             buf, (int)strlen(buf), *sc);
349
        }
350
    }    
351
}
352
353
void sup_log_undefobj(mcmcxdef *mctx, errcxdef *ec, int err,
354
                      char *nm, int nmlen, objnum objn)
355
{
356
    uchar  *p;
357
    size_t  len;
358
359
    /* 
360
     *   if the object has any superclasses defined, what must have
361
     *   happened is that we encountered an error in the course of
362
     *   defining the object; the object is partially defined, hence it
363
     *   won't show up in our records of defined objects, yet it really
364
     *   shouldn't count as an undefined object; simply suppress the
365
     *   message in this case 
366
     */
367
    if (objget1sc(mctx, objn) != MCMONINV)
368
        return;
369
370
    /* get the object - it contains the location where it was defined */
371
    p = mcmlck(mctx, (mcmon)objn);
372
373
    /* skip the object header */
374
    p += OBJDEFSIZ;
375
376
    /* get the length of the name */
377
    len = strlen((char *)p);
378
379
#ifdef OS_ERRLINE
380
    len += strlen((char *)p + len + 1);
381
#endif
382
383
    /* log the error */
384
    errlog2(ec, err, ERRTSTR, errstr(ec, nm, nmlen),
385
            ERRTSTR, errstr(ec, (char *)p, len));
386
387
    /* done with the object */
388
    mcmunlck(mctx, (mcmon)objn);
389
}
390