ArchWizard

DGD/

source navigation ]
diff markup ]
identifier search ]
file search ]
Version: [ 1.0.a0 ] [ 1.1 ] [ 1.2 ] [ 1.2p1 ] [ 1.2p2 ] [ 1.2p3 ] [ 1.2p4 ] [ 1.2.151 ]

  1 # define INCLUDE_FILE_IO
  2 # include "dgd.h"
  3 # include "str.h"
  4 # include "array.h"
  5 # include "object.h"
  6 # include "xfloat.h"
  7 # include "interpret.h"
  8 # include "data.h"
  9 # include "path.h"
 10 # include "editor.h"
 11 # include "call_out.h"
 12 # include "comm.h"
 13 # include "version.h"
 14 # include "macro.h"
 15 # include "token.h"
 16 # include "ppcontrol.h"
 17 # include "node.h"
 18 # include "parser.h"
 19 # include "compile.h"
 20 # include "csupport.h"
 21 # include "table.h"
 22 
 23 typedef struct {
 24     char *name;         /* name of the option */
 25     short type;         /* option type */
 26     bool resolv;        /* TRUE if path name must be resolved */
 27     bool set;           /* TRUE if option is set */
 28     Uint low, high;     /* lower and higher bound, for numeric values */
 29     union {
 30         long num;       /* numeric value */
 31         char *str;      /* string value */
 32     } u;
 33 } config;
 34 
 35 static config conf[] = {
 36 # define ARRAY_SIZE     0
 37                                 { "array_size",         INT_CONST, FALSE, FALSE,
 38                                                         1, USHRT_MAX / 2 },
 39 # define AUTO_OBJECT    1
 40                                 { "auto_object",        STRING_CONST, TRUE },
 41 # define BINARY_PORT    2
 42                                 { "binary_port",        INT_CONST, FALSE, FALSE,
 43                                                         0, USHRT_MAX },
 44 # define CACHE_SIZE     3
 45                                 { "cache_size",         INT_CONST, FALSE, FALSE,
 46                                                         2, UINDEX_MAX },
 47 # define CALL_OUTS      4
 48                                 { "call_outs",          INT_CONST, FALSE, FALSE,
 49                                                         0, UINDEX_MAX - 1 },
 50 # define CREATE         5
 51                                 { "create",             STRING_CONST, FALSE },
 52 # define DIRECTORY      6
 53                                 { "directory",          STRING_CONST, FALSE },
 54 # define DRIVER_OBJECT  7
 55                                 { "driver_object",      STRING_CONST, TRUE },
 56 # define DUMP_FILE      8
 57                                 { "dump_file",          STRING_CONST, FALSE },
 58 # define DYNAMIC_CHUNK  9
 59                                 { "dynamic_chunk",      INT_CONST, FALSE },
 60 # define ED_TMPFILE     10
 61                                 { "ed_tmpfile",         STRING_CONST, FALSE },
 62 # define EDITORS        11
 63                                 { "editors",            INT_CONST, FALSE, FALSE,
 64                                                         0, EINDEX_MAX },
 65 # define INCLUDE_DIRS   12
 66                                 { "include_dirs",       '(', FALSE },
 67 # define INCLUDE_FILE   13
 68                                 { "include_file",       STRING_CONST, TRUE },
 69 # define OBJECTS        14
 70                                 { "objects",            INT_CONST, FALSE, FALSE,
 71                                                         2, UINDEX_MAX },
 72 # define SECTOR_SIZE    15
 73                                 { "sector_size",        INT_CONST, FALSE, FALSE,
 74                                                         512, 8192 },
 75 # define STATIC_CHUNK   16
 76                                 { "static_chunk",       INT_CONST, FALSE },
 77 # define SWAP_FILE      17
 78                                 { "swap_file",          STRING_CONST, FALSE },
 79 # define SWAP_FRAGMENT  18
 80                                 { "swap_fragment",      INT_CONST, FALSE, FALSE,
 81                                                         0, SW_UNUSED },
 82 # define SWAP_SIZE      19
 83                                 { "swap_size",          INT_CONST, FALSE, FALSE,
 84                                                         1024, SW_UNUSED },
 85 # define TELNET_PORT    20
 86                                 { "telnet_port",        INT_CONST, FALSE, FALSE,
 87                                                         0, USHRT_MAX },
 88 # define TYPECHECKING   21
 89                                 { "typechecking",       INT_CONST, FALSE, FALSE,
 90                                                         0, 2 },
 91 # define USERS          22
 92                                 { "users",              INT_CONST, FALSE, FALSE,
 93                                                         1, EINDEX_MAX },
 94 # define NR_OPTIONS     23
 95 };
 96 
 97 
 98 typedef struct { char fill; char c;     } alignc;
 99 typedef struct { char fill; short s;    } aligns;
100 typedef struct { char fill; Int i;      } aligni;
101 typedef struct { char fill; char *p;    } alignp;
102 typedef struct { char c;                } alignz;
103 
104 typedef char dumpinfo[28];
105 
106 # define FORMAT_VERSION 2
107 
108 # define DUMP_VALID     0       /* valud dump flag */
109 # define DUMP_VERSION   1       /* dump file version number */
110 # define DUMP_DRIVER    2       /* 0: vanilla DGD, 1: iChat DGD */
111 # define DUMP_TYPECHECK 3       /* global typechecking */
112 # define DUMP_SECSIZE   4       /* sector size */
113 # define DUMP_TYPE      4       /* first XX bytes, dump type */
114 # define DUMP_STARTTIME 20      /* start time */
115 # define DUMP_ELAPSED   24      /* elapsed time */
116 
117 static dumpinfo header;         /* dumpfile header */
118 # define s0     (header[ 6])    /* short, msb */
119 # define s1     (header[ 7])    /* short, lsb */
120 # define i0     (header[ 8])    /* Int, msb */
121 # define i1     (header[ 9])
122 # define i2     (header[10])
123 # define i3     (header[11])    /* Int, lsb */
124 # define utsize (header[12])    /* sizeof(uindex) + sizeof(ssizet) */
125 # define desize (header[13])    /* sizeof(sector) + sizeof(eindex) */
126 # define psize  (header[14])    /* sizeof(char*) */
127 # define calign (header[15])    /* align(char) */
128 # define salign (header[16])    /* align(short) */
129 # define ialign (header[17])    /* align(Int) */
130 # define palign (header[18])    /* align(char*) */
131 # define zalign (header[19])    /* align(struct) */
132 static int ualign;              /* align(uindex) */
133 static int talign;              /* align(ssizet) */
134 static int dalign;              /* align(sector) */
135 static int ealign;              /* align(eindex) */
136 static dumpinfo rheader;        /* restored header */
137 # define rs0    (rheader[ 6])   /* short, msb */
138 # define rs1    (rheader[ 7])   /* short, lsb */
139 # define ri0    (rheader[ 8])   /* Int, msb */
140 # define ri1    (rheader[ 9])
141 # define ri2    (rheader[10])
142 # define ri3    (rheader[11])   /* Int, lsb */
143 # define rutsize (rheader[12])  /* sizeof(uindex) + sizeof(ssizet) */
144 # define rdesize (rheader[13])  /* sizeof(sector) + sizeof(eindex) */
145 # define rpsize (rheader[14])   /* sizeof(char*) */
146 # define rcalign (rheader[15])  /* align(char) */
147 # define rsalign (rheader[16])  /* align(short) */
148 # define rialign (rheader[17])  /* align(Int) */
149 # define rpalign (rheader[18])  /* align(char*) */
150 # define rzalign (rheader[19])  /* align(struct) */
151 static int rusize;              /* sizeof(uindex) */
152 static int rtsize;              /* sizeof(ssizet) */
153 static int rdsize;              /* sizeof(sector) */
154 static int resize;              /* sizeof(eindex) */
155 static int rualign;             /* align(uindex) */
156 static int rtalign;             /* align(ssizet) */
157 static int rdalign;             /* align(sector) */
158 static int realign;             /* align(eindex) */
159 static Uint starttime;          /* start time */
160 static Uint elapsed;            /* elapsed time */
161 static Uint boottime;           /* boot time */
162 
163 /*
164  * NAME:        conf->dumpinit()
165  * DESCRIPTION: initialize dump file information
166  */
167 static void conf_dumpinit()
168 {
169     short s;
170     Int i;
171     alignc cdummy;
172     aligns sdummy;
173     aligni idummy;
174     alignp pdummy;
175 
176     header[DUMP_VALID] = TRUE;                  /* valid dump flag */
177     header[DUMP_VERSION] = FORMAT_VERSION;      /* dump file version number */
178     header[DUMP_DRIVER] = 0;                    /* vanilla DGD */
179     header[DUMP_TYPECHECK] = conf[TYPECHECKING].u.num;
180     header[DUMP_SECSIZE + 0] = conf[SECTOR_SIZE].u.num >> 8;
181     header[DUMP_SECSIZE + 1] = conf[SECTOR_SIZE].u.num;
182 
183     starttime = boottime = P_time();
184 
185     s = 0x1234;
186     i = 0x12345678L;
187     s0 = strchr((char *) &s, 0x12) - (char *) &s;
188     s1 = strchr((char *) &s, 0x34) - (char *) &s;
189     i0 = strchr((char *) &i, 0x12) - (char *) &i;
190     i1 = strchr((char *) &i, 0x34) - (char *) &i;
191     i2 = strchr((char *) &i, 0x56) - (char *) &i;
192     i3 = strchr((char *) &i, 0x78) - (char *) &i;
193     utsize = sizeof(uindex) | (sizeof(ssizet) << 4);
194     desize = sizeof(sector) | (sizeof(eindex) << 4);
195     psize = sizeof(char*);
196     calign = (char *) &cdummy.c - (char *) &cdummy.fill;
197     salign = (char *) &sdummy.s - (char *) &sdummy.fill;
198     ialign = (char *) &idummy.i - (char *) &idummy.fill;
199     palign = (char *) &pdummy.p - (char *) &pdummy.fill;
200     zalign = sizeof(alignz);
201 
202     ualign = (sizeof(uindex) == sizeof(short)) ? salign : ialign;
203     talign = (sizeof(ssizet) == sizeof(short)) ? salign : ialign;
204     dalign = (sizeof(sector) == sizeof(short)) ? salign : ialign;
205     switch (sizeof(eindex)) {
206     case sizeof(char):  ealign = calign; break;
207     case sizeof(short): ealign = salign; break;
208     case sizeof(Int):   ealign = ialign; break;
209     }
210 }
211 
212 /*
213  * NAME:        conf->dump()
214  * DESCRIPTION: dump system state on file
215  */
216 void conf_dump()
217 {
218     int fd;
219     Uint etime;
220 
221     header[DUMP_TYPECHECK] = conf[TYPECHECKING].u.num;
222     header[DUMP_STARTTIME + 0] = starttime >> 24;
223     header[DUMP_STARTTIME + 1] = starttime >> 16;
224     header[DUMP_STARTTIME + 2] = starttime >> 8;
225     header[DUMP_STARTTIME + 3] = starttime;
226     etime = elapsed + P_time() - boottime;
227     header[DUMP_ELAPSED + 0] = etime >> 24;
228     header[DUMP_ELAPSED + 1] = etime >> 16;
229     header[DUMP_ELAPSED + 2] = etime >> 8;
230     header[DUMP_ELAPSED + 3] = etime;
231 
232     fd = sw_dump(conf[DUMP_FILE].u.str);
233     if (!kf_dump(fd)) {
234         fatal("failed to dump kfun table");
235     }
236     if (!o_dump(fd)) {
237         fatal("failed to dump object table");
238     }
239     if (!pc_dump(fd)) {
240         fatal("failed to dump precompiled objects");
241     }
242     if (!co_dump(fd)) {
243         fatal("failed to dump callout table");
244     }
245 
246     P_lseek(fd, 0L, SEEK_SET);
247     P_write(fd, header, sizeof(dumpinfo));
248 }
249 
250 /*
251  * NAME:        conf->restore()
252  * DESCRIPTION: restore system state from file
253  */
254 static void conf_restore(fd)
255 int fd;
256 {
257     unsigned int secsize;
258     long posn;
259 
260     if (P_read(fd, rheader, sizeof(dumpinfo)) != sizeof(dumpinfo) ||
261         memcmp(header, rheader, DUMP_TYPE) != 0) {
262         error("Bad or incompatible restore file header");
263     }
264 
265     starttime = (UCHAR(rheader[DUMP_STARTTIME + 0]) << 24) |
266                 (UCHAR(rheader[DUMP_STARTTIME + 1]) << 16) |
267                 (UCHAR(rheader[DUMP_STARTTIME + 2]) << 8) |
268                  UCHAR(rheader[DUMP_STARTTIME + 3]);
269     elapsed =  (UCHAR(rheader[DUMP_ELAPSED + 0]) << 24) |
270                (UCHAR(rheader[DUMP_ELAPSED + 1]) << 16) |
271                (UCHAR(rheader[DUMP_ELAPSED + 2]) << 8) |
272                 UCHAR(rheader[DUMP_ELAPSED + 3]);
273     rusize = rutsize & 0xf;
274     rtsize = rutsize >> 4;
275     if (rtsize == 0) {
276         rtsize = sizeof(unsigned short);        /* backward compat */
277     }
278     rdsize = rdesize & 0xf;
279     resize = rdesize >> 4;
280     if (resize == 0) {
281         resize = sizeof(char);                  /* backward compat */
282     }
283     rualign = (rusize == sizeof(short)) ? rsalign : rialign;
284     rtalign = (rtsize == sizeof(short)) ? rsalign : rialign;
285     rdalign = (rdsize == sizeof(short)) ? rsalign : rialign;
286     switch (resize) {
287     case sizeof(char):  realign = rcalign; break;
288     case sizeof(short): realign = rsalign; break;
289     case sizeof(Int):   realign = rialign; break;
290     }
291     if (sizeof(uindex) < rusize || sizeof(ssizet) < rtsize ||
292         sizeof(sector) < rdsize) {
293         error("Cannot restore uindex, ssizet or sector of greater width");
294     }
295     secsize = (UCHAR(rheader[DUMP_SECSIZE + 0]) << 8) |
296                UCHAR(rheader[DUMP_SECSIZE + 1]);
297     if (secsize > conf[SECTOR_SIZE].u.num) {
298         error("Cannot restore bigger sector size");
299     }
300 
301     sw_restore(fd, secsize);
302     kf_restore(fd);
303     o_restore(fd);
304 
305     posn = P_lseek(fd, 0L, SEEK_CUR);   /* preserve current file position */
306     o_conv();                           /* convert all objects */
307     P_lseek(fd, posn, SEEK_SET);        /* restore file position */
308 
309     pc_restore(fd);
310     boottime = P_time();
311     co_restore(fd, boottime);
312 }
313 
314 /*
315  * NAME:        conf->dsize()
316  * DESCRIPTION: compute the size and alignment of a struct
317  *              0x000000ff size in dump file
318  *              0x0000ff00 alignment in dump file
319  *              0x00ff0000 size
320  *              0xff000000 alignment
321  */
322 Uint conf_dsize(layout)
323 char *layout;
324 {
325     register char *p;
326     register Uint sz, rsz, al, ral;
327     register Uint size, rsize, align, ralign;
328 
329     p = layout;
330     size = rsize = 0;
331     align = ralign = 1;
332 
333     for (;;) {
334         switch (*p++) {
335         case 'c':       /* character */
336             sz = rsz = sizeof(char);
337             al = calign;
338             ral = rcalign;
339             break;
340 
341         case 's':       /* short */
342             sz = rsz = sizeof(short);
343             al = salign;
344             ral = rsalign;
345             break;
346 
347         case 'u':       /* uindex */
348             sz = sizeof(uindex);
349             rsz = rusize;
350             al = ualign;
351             ral = rualign;
352             break;
353 
354         case 'i':       /* Int */
355             sz = rsz = sizeof(Int);
356             al = ialign;
357             ral = rialign;
358             break;
359 
360         case 't':       /* ssizet */
361             sz = sizeof(ssizet);
362             rsz = rtsize;
363             al = talign;
364             ral = rtalign;
365             break;
366 
367         case 'd':       /* sector */
368             sz = sizeof(sector);
369             rsz = rdsize;
370             al = dalign;
371             ral = rdalign;
372             break;
373 
374         case 'e':       /* eindex */
375             sz = sizeof(eindex);
376             rsz = resize;
377             al = ealign;
378             ral = realign;
379             break;
380 
381         case 'p':       /* pointer */
382             sz = sizeof(char*);
383             rsz = rpsize;
384             al = palign;
385             ral = rpalign;
386             break;
387 
388         case 'x':       /* hte */
389             size = ALGN(size, zalign);
390             size = ALGN(size, palign);
391             size += sizeof(char*);
392             size = ALGN(size, palign);
393             size += sizeof(char*);
394             size = ALGN(size, zalign);
395             rsize = ALGN(rsize, rzalign);
396             rsize = ALGN(rsize, rpalign);
397             rsize += rpsize;
398             rsize = ALGN(rsize, rpalign);
399             rsize += rpsize;
400             rsize = ALGN(rsize, rzalign);
401             align = ALGN(align, palign);
402             ralign = ALGN(ralign, rpalign);
403             continue;
404 
405         case '[':       /* struct */
406             sz = conf_dsize(p);
407             al = (sz >> 8) & 0xff;
408             rsz = (sz >> 16) & 0xff;
409             ral = sz >> 24;
410             sz &= 0xff;
411             p = strchr(p, ']') + 1;
412             break;
413 
414         case ']':
415         case '\0':      /* end of layout */
416             if (p != layout + 2) {
417                 /* a stuct and not an array element */
418                 align = ALGN(align, zalign);
419                 ralign = ALGN(ralign, rzalign);
420             }
421             return ALGN(rsize, ralign) |
422                    (ralign << 8) |
423                    (ALGN(size, align) << 16) |
424                    (align << 24);
425         }
426 
427         size = ALGN(size, al) + sz;
428         rsize = ALGN(rsize, ral) + rsz;
429         align = ALGN(align, al);
430         ralign = ALGN(ralign, ral);
431     }
432 }
433 
434 /*
435  * NAME:        conf_dconv()
436  * DESCRIPTION: convert structs from dumpfile format
437  */
438 Uint conf_dconv(buf, rbuf, layout, n)
439 register char *buf, *rbuf;
440 char *layout;
441 Uint n;
442 {
443     register Uint i, ri, j, size, rsize;
444     register char *p;
445 
446     rsize = conf_dsize(layout);
447     size = (rsize >> 16) & 0xff;
448     rsize &= 0xff;
449     while (n > 0) {
450         i = ri = 0;
451         for (p = layout; *p != '\0' && *p != ']'; p++) {
452             switch (*p) {
453             case 'c':
454                 i = ALGN(i, calign);
455                 ri = ALGN(ri, rcalign);
456                 buf[i] = rbuf[ri];
457                 i += sizeof(char);
458                 ri += sizeof(char);
459                 break;
460 
461             case 's':
462                 i = ALGN(i, salign);
463                 ri = ALGN(ri, rsalign);
464                 buf[i + s0] = rbuf[ri + rs0];
465                 buf[i + s1] = rbuf[ri + rs1];
466                 i += sizeof(short);
467                 ri += sizeof(short);
468                 break;
469 
470             case 'u':
471                 i = ALGN(i, ualign);
472                 ri = ALGN(ri, rualign);
473                 if (sizeof(uindex) == rusize) {
474                     if (sizeof(uindex) == sizeof(short)) {
475                         buf[i + s0] = rbuf[ri + rs0];
476                         buf[i + s1] = rbuf[ri + rs1];
477                     } else {
478                         buf[i + i0] = rbuf[ri + ri0];
479                         buf[i + i1] = rbuf[ri + ri1];
480                         buf[i + i2] = rbuf[ri + ri2];
481                         buf[i + i3] = rbuf[ri + ri3];
482                     }
483                 } else {
484                     j = (UCHAR(rbuf[ri + rs0] & rbuf[ri + rs1]) == 0xff) ?
485                          -1 : 0;
486                     buf[i + i0] = j;
487                     buf[i + i1] = j;
488                     buf[i + i2] = rbuf[ri + rs0];
489                     buf[i + i3] = rbuf[ri + rs1];
490                 }
491                 i += sizeof(uindex);
492                 ri += rusize;
493                 break;
494 
495             case 'i':
496                 i = ALGN(i, ialign);
497                 ri = ALGN(ri, rialign);
498                 buf[i + i0] = rbuf[ri + ri0];
499                 buf[i + i1] = rbuf[ri + ri1];
500                 buf[i + i2] = rbuf[ri + ri2];
501                 buf[i + i3] = rbuf[ri + ri3];
502                 i += sizeof(Int);
503                 ri += sizeof(Int);
504                 break;
505 
506             case 't':
507                 i = ALGN(i, talign);
508                 ri = ALGN(ri, rtalign);
509                 if (sizeof(ssizet) == rtsize) {
510                     if (sizeof(ssizet) == sizeof(short)) {
511                         buf[i + s0] = rbuf[ri + rs0];
512                         buf[i + s1] = rbuf[ri + rs1];
513                     } else {
514                         buf[i + i0] = rbuf[ri + ri0];
515                         buf[i + i1] = rbuf[ri + ri1];
516                         buf[i + i2] = rbuf[ri + ri2];
517                         buf[i + i3] = rbuf[ri + ri3];
518                     }
519                 } else {
520                     buf[i + i0] = 0;
521                     buf[i + i1] = 0;
522                     buf[i + i2] = rbuf[ri + rs0];
523                     buf[i + i3] = rbuf[ri + rs1];
524                 }
525                 i += sizeof(ssizet);
526                 ri += rtsize;
527                 break;
528 
529             case 'd':
530                 i = ALGN(i, dalign);
531                 ri = ALGN(ri, rdalign);
532                 if (sizeof(sector) == rdsize) {
533                     if (sizeof(sector) == sizeof(short)) {
534                         buf[i + s0] = rbuf[ri + rs0];
535                         buf[i + s1] = rbuf[ri + rs1];
536                     } else {
537                         buf[i + i0] = rbuf[ri + ri0];
538                         buf[i + i1] = rbuf[ri + ri1];
539                         buf[i + i2] = rbuf[ri + ri2];
540                         buf[i + i3] = rbuf[ri + ri3];
541                     }
542                 } else {
543                     j = (UCHAR(rbuf[ri + rs0] & rbuf[ri + rs1]) == 0xff) ?
544                          -1 : 0;
545                     buf[i + i0] = j;
546                     buf[i + i1] = j;
547                     buf[i + i2] = rbuf[ri + rs0];
548                     buf[i + i3] = rbuf[ri + rs1];
549                 }
550                 i += sizeof(sector);
551                 ri += rdsize;
552                 break;
553 
554             case 'e':
555                 i = ALGN(i, ealign);
556                 ri = ALGN(ri, realign);
557                 i += sizeof(eindex);
558                 ri += resize;
559                 break;
560 
561             case 'p':
562                 i = ALGN(i, palign);
563                 ri = ALGN(ri, rpalign);
564                 for (j = sizeof(char*); j > 0; --j) {
565                     buf[i++] = 0;
566                 }
567                 ri += rpsize;
568                 break;
569 
570             case '[':
571                 j = conf_dsize(++p);
572                 i = ALGN(i, j >> 24);
573                 ri = ALGN(ri, (j >> 8) & 0xff);
574                 j = conf_dconv(buf + i, rbuf + ri, p, (Uint) 1);
575                 i += (j >> 16) & 0xff;
576                 ri += j & 0xff;
577                 p = strchr(p, ']');
578                 break;
579 
580             case 'x':
581                 i = ALGN(i, zalign);
582                 i = ALGN(i, palign);
583                 for (j = sizeof(char*); j > 0; --j) {
584                     buf[i++] = 0;
585                 }
586                 i = ALGN(i, palign);
587                 for (j = sizeof(char*); j > 0; --j) {
588                     buf[i++] = 0;
589                 }
590                 ri = ALGN(ri, rzalign);
591                 ri = ALGN(ri, rpalign);
592                 ri += rpsize;
593                 ri = ALGN(ri, rpalign);
594                 for (j = rpsize; j > 0; --j) {
595                     if (rbuf[ri] != 0) {
596                         buf[i - 1] = 1;
597                         break;
598                     }
599                     ri++;
600                 }
601                 ri += j;
602                 i = ALGN(i, zalign);
603                 ri = ALGN(ri, rzalign);
604                 break;
605             }
606         }
607 
608         buf += size;
609         rbuf += rsize;
610         --n;
611     }
612 
613     return (size << 16) | rsize;
614 }
615 
616 /*
617  * NAME:        conf->dread()
618  * DESCRIPTION: read from dumpfile
619  */
620 void conf_dread(fd, buf, layout, n)
621 int fd;
622 char *buf, *layout;
623 register Uint n;
624 {
625     char buffer[16384];
626     register unsigned int i, size, rsize;
627     Uint tmp;
628 
629     tmp = conf_dsize(layout);
630     size = (tmp >> 16) & 0xff;
631     rsize = tmp & 0xff;
632     while (n != 0) {
633         i = sizeof(buffer) / rsize;
634         if (i > n) {
635             i = n;
636         }
637         if (P_read(fd, buffer, i * rsize) != i * rsize) {
638             fatal("cannot read from dump file");
639         }
640         conf_dconv(buf, buffer, layout, (Uint) i);
641         buf += size * i;
642         n -= i;
643     }
644 }
645 
646 
647 # define MAX_DIRS       32
648 
649 static char *dirs[MAX_DIRS];
650 
651 /*
652  * NAME:        conferr()
653  * DESCRIPTION: error during the configuration phase
654  */
655 static void conferr(err)
656 char *err;
657 {
658     message("Config error, line %u: %s\012", tk_line(), err);   /* LF */
659 }
660 
661 /*
662  * NAME:        config->config()
663  * DESCRIPTION: read config file
664  */
665 static bool conf_config()
666 {
667     char buf[STRINGSZ];
668     register char *p;
669     register int h, l, m, c;
670 
671     for (h = NR_OPTIONS; h > 0; ) {
672         conf[--h].set = FALSE;
673     }
674     memset(dirs, '\0', sizeof(dirs));
675 
676     while ((c=pp_gettok()) != EOF) {
677         if (c != IDENTIFIER) {
678             conferr("option expected");
679             return FALSE;
680         }
681 
682         l = 0;
683         h = NR_OPTIONS;
684         for (;;) {
685             c = strcmp(yytext, conf[m = (l + h) >> 1].name);
686             if (c == 0) {
687                 break;  /* found */
688             } else if (c < 0) {
689                 h = m;  /* search in lower half */
690             } else {
691                 l = m + 1;      /* search in upper half */
692             }
693             if (l >= h) {
694                 conferr("unknown option");
695                 return FALSE;
696             }
697         }
698 
699         if (pp_gettok() != '=') {
700             conferr("'=' expected");
701             return FALSE;
702         }
703 
704         if ((c=pp_gettok()) != conf[m].type) {
705             if (c != INT_CONST && c != STRING_CONST && c != '(') {
706                 conferr("syntax error");
707                 return FALSE;
708             } else {
709                 conferr("bad value type");
710                 return FALSE;
711             }
712         }
713 
714         switch (c) {
715         case INT_CONST:
716             if (yylval.number < conf[m].low ||
717                 (conf[m].high != 0 && yylval.number > conf[m].high)) {
718                 conferr("int value out of range");
719                 return FALSE;
720             }
721             conf[m].u.num = yylval.number;
722             break;
723 
724         case STRING_CONST:
725             p = (conf[m].resolv) ? path_resolve(buf, yytext) : yytext;
726             l = strlen(p);
727             if (l >= STRINGSZ) {
728                 l = STRINGSZ - 1;
729                 p[l] = '\0';
730             }
731             m_static();
732             conf[m].u.str = strcpy(ALLOC(char, l + 1), p);
733             m_dynamic();
734             break;
735 
736         case '(':
737             if (pp_gettok() != '{') {
738                 conferr("'{' expected");
739                 return FALSE;
740             }
741             l = 0;
742             for (;;) {
743                 if (pp_gettok() != STRING_CONST) {
744                     conferr("string expected");
745                     return FALSE;
746                 }
747                 if (l == MAX_DIRS - 1) {
748                     conferr("too many include directories");
749                     return FALSE;
750                 }
751                 m_static();
752                 dirs[l] = strcpy(ALLOC(char, strlen(yytext) + 1), yytext);
753                 l++;
754                 m_dynamic();
755                 if ((c=pp_gettok()) == '}') {
756                     break;
757                 }
758                 if (c != ',') {
759                     conferr("',' expected");
760                     return FALSE;
761                 }
762             }
763             if (pp_gettok() != ')') {
764                 conferr("')' expected");
765                 return FALSE;
766             }
767             dirs[l] = (char *) NULL;
768             break;
769         }
770         conf[m].set = TRUE;
771         if (pp_gettok() != ';') {
772             conferr("';' expected");
773             return FALSE;
774         }
775     }
776 
777     for (l = 0; l < NR_OPTIONS; l++) {
778         if (!conf[l].set) {
779             char buffer[64];
780 
781             sprintf(buffer, "unspecified option %s", conf[l].name);
782             conferr(buffer);
783             return FALSE;
784         }
785     }
786 
787     return TRUE;
788 }
789 
790 static char *fname;             /* file name */
791 static int fd;                  /* file descriptor */
792 static char *obuf;              /* output buffer */
793 static unsigned int bufsz;      /* buffer size */
794 
795 /*
796  * NAME:        config->open()
797  * DESCRIPTION: create a new file
798  */
799 static bool copen(file)
800 char *file;
801 {
802     char fname[STRINGSZ];
803 
804     path_resolve(fname, file);
805     if ((fd=P_open(fname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644)) < 0) {
806         message("Config error: cannot create \"/%s\"\012", fname);      /* LF */
807         return FALSE;
808     }
809     bufsz = 0;
810 
811     return TRUE;
812 }
813 
814 /*
815  * NAME:        config->put()
816  * DESCRIPTION: write a string to a file
817  */
818 static void cputs(str)
819 register char *str;
820 {
821     register unsigned int len, chunk;
822 
823     len = strlen(str);
824     while (bufsz + len > BUF_SIZE) {
825         chunk = BUF_SIZE - bufsz;
826         memcpy(obuf + bufsz, str, chunk);
827         P_write(fd, obuf, BUF_SIZE);
828         str += chunk;
829         len -= chunk;
830         bufsz = 0;
831     }
832     if (len > 0) {
833         memcpy(obuf + bufsz, str, len);
834         bufsz += len;
835     }
836 }
837 
838 /*
839  * NAME:        config->close()
840  * DESCRIPTION: close a file
841  */
842 static bool cclose()
843 {
844     if (bufsz > 0 && P_write(fd, obuf, bufsz) != bufsz) {
845         message("Config error: cannot write \"/%s\"\012", fname);       /* LF */
846         P_close(fd);
847         return FALSE;
848     }
849     P_close(fd);
850 
851     return TRUE;
852 }
853 
854 /*
855  * NAME:        config->includes()
856  * DESCRIPTION: create include files
857  */
858 static bool conf_includes()
859 {
860     char buf[BUF_SIZE], buffer[STRINGSZ];
861 
862     /* create status.h file */
863     obuf = buf;
864     sprintf(buffer, "%s/status.h", dirs[0]);
865     if (!copen(buffer)) {
866         return FALSE;
867     }
868     cputs("/*\012 * This file defines the fields of the array returned ");
869     cputs("by the\012 * status() kfun.  It is automatically generated ");
870     cputs("by DGD on startup.\012 */\012\012");
871     cputs("# define ST_VERSION\t\t/* driver version */\012");
872     cputs("# define ST_STARTTIME\t1\t/* system start time */\012");
873     cputs("# define ST_BOOTTIME\t2\t/* system reboot time */\012");
874     cputs("# define ST_UPTIME\t3\t/* system virtual uptime */\012");
875     cputs("# define ST_SWAPSIZE\t4\t/* # sectors on swap device */\012");
876     cputs("# define ST_SWAPUSED\t5\t/* # sectors in use */\012");
877     cputs("# define ST_SECTORSIZE\t6\t/* size of swap sector */\012");
878     cputs("# define ST_SWAPRATE1\t7\t/* # objects swapped out last minute */\012");
879     cputs("# define ST_SWAPRATE5\t8\t/* # objects swapped out last five minutes */\012");
880     cputs("# define ST_SMEMSIZE\t9\t/* static memory allocated */\012");
881     cputs("# define ST_SMEMUSED\t10\t/* static memory in use */\012");
882     cputs("# define ST_DMEMSIZE\t11\t/* dynamic memory allocated */\012");
883     cputs("# define ST_DMEMUSED\t12\t/* dynamic memory in use */\012");
884     cputs("# define ST_OTABSIZE\t13\t/* object table size */\012");
885     cputs("# define ST_NOBJECTS\t14\t/* # objects in use */\012");
886     cputs("# define ST_COTABSIZE\t15\t/* callouts table size */\012");
887     cputs("# define ST_NCOSHORT\t16\t/* # short-term callouts */\012");
888     cputs("# define ST_NCOLONG\t17\t/* # long-term & millisecond callouts */\012");
889     cputs("# define ST_UTABSIZE\t18\t/* user table size */\012");
890     cputs("# define ST_ETABSIZE\t19\t/* editor table size */\012");
891     cputs("# define ST_STRSIZE\t20\t/* max string size */\012");
892     cputs("# define ST_ARRAYSIZE\t21\t/* max array/mapping size */\012");
893     cputs("# define ST_STACKDEPTH\t22\t/* remaining stack depth */\012");
894     cputs("# define ST_TICKS\t23\t/* remaining ticks */\012");
895     cputs("# define ST_PRECOMPILED\t24\t/* precompiled objects */\012");
896 
897     cputs("\012# define O_COMPILETIME\t\t/* time of compilation */\012");
898     cputs("# define O_PROGSIZE\t1\t/* program size of object */\012");
899     cputs("# define O_DATASIZE\t2\t/* # variables in object */\012");
900     cputs("# define O_NSECTORS\t3\t/* # sectors used by object */\012");
901     cputs("# define O_CALLOUTS\t4\t/* callouts in object */\012");
902     cputs("# define O_INDEX\t5\t/* unique ID for master object */\012");
903 
904     cputs("\012# define CO_HANDLE\t\t/* callout handle */\012");
905     cputs("# define CO_FUNCTION\t1\t/* function name */\012");
906     cputs("# define CO_DELAY\t2\t/* delay */\012");
907     cputs("# define CO_FIRSTXARG\t3\t/* first extra argument */\012");
908     if (!cclose()) {
909         return FALSE;
910     }
911 
912     /* create type.h file */
913     sprintf(buffer, "%s/type.h", dirs[0]);
914     if (!copen(buffer)) {
915         return FALSE;
916     }
917     cputs("/*\012 * This file gives definitions for the value returned ");
918     cputs("by the\012 * typeof() kfun.  It is automatically generated ");
919     cputs("by DGD on startup.\012 */\012\012");
920     sprintf(buffer, "# define T_NIL\t\t%d\012", T_NIL);
921     cputs(buffer);
922     sprintf(buffer, "# define T_INT\t\t%d\012", T_INT);
923     cputs(buffer);
924     sprintf(buffer, "# define T_FLOAT\t%d\012", T_FLOAT);
925     cputs(buffer);
926     sprintf(buffer, "# define T_STRING\t%d\012", T_STRING);
927     cputs(buffer);
928     sprintf(buffer, "# define T_OBJECT\t%d\012", T_OBJECT);
929     cputs(buffer);
930     sprintf(buffer, "# define T_ARRAY\t%d\012", T_ARRAY);
931     cputs(buffer);
932     sprintf(buffer, "# define T_MAPPING\t%d\012", T_MAPPING);
933     cputs(buffer);
934     if (!cclose()) {
935         return FALSE;
936     }
937 
938     /* create limits.h file */
939     sprintf(buffer, "%s/limits.h", dirs[0]);
940     if (!copen(buffer)) {
941         return FALSE;
942     }
943     cputs("/*\012 * This file defines some basic sizes of datatypes and ");
944     cputs("resources.\012 * It is automatically generated by DGD on ");
945     cputs("startup.\012 */\012\012");
946     cputs("# define CHAR_BIT\t\t8\t\t/* # bits in character */\012");
947     cputs("# define CHAR_MIN\t\t\t\t/* min character value */\012");
948     cputs("# define CHAR_MAX\t\t255\t\t/* max character value */\012\012");
949     cputs("# define INT_MIN\t\t0x80000000\t/* -2147483648 */\012");
950     cputs("# define INT_MAX\t\t2147483647\t/* max integer value */\012\012");
951     sprintf(buffer, "# define MAX_STRING_SIZE\t%u\t\t/* max string size (obsolete) */\012",
952             MAX_STRLEN);
953     cputs(buffer);
954     if (!cclose()) {
955         return FALSE;
956     }
957 
958     /* create float.h file */
959     sprintf(buffer, "%s/float.h", dirs[0]);
960     if (!copen(buffer)) {
961         return FALSE;
962     }
963     cputs("/*\012 * This file describes the floating point type. It is ");
964     cputs("automatically\012 * generated by DGD on startup.\012 */\012\012");
965     cputs("# define FLT_RADIX\t2\t\t\t/* binary */\012");
966     cputs("# define FLT_ROUNDS\t1\t\t\t/* round to nearest */\012");
967     cputs("# define FLT_EPSILON\t7.2759576142E-12\t/* smallest x: 1.0 + x != 1.0 */\012");
968     cputs("# define FLT_DIG\t10\t\t\t/* decimal digits of precision*/\012");
969     cputs("# define FLT_MANT_DIG\t36\t\t\t/* binary digits of precision */\012");
970     cputs("# define FLT_MIN\t2.22507385851E-308\t/* positive minimum */\012");
971     cputs("# define FLT_MIN_EXP\t(-1021)\t\t\t/* minimum binary exponent */\012");
972     cputs("# define FLT_MIN_10_EXP\t(-307)\t\t\t/* minimum decimal exponent */\012");
973     cputs("# define FLT_MAX\t1.79769313485E+308\t/* positive maximum */\012");
974     cputs("# define FLT_MAX_EXP\t1024\t\t\t/* maximum binary exponent */\012");
975     cputs("# define FLT_MAX_10_EXP\t308\t\t\t/* maximum decimal exponent */\012");
976     if (!cclose()) {
977         return FALSE;
978     }
979 
980     /* create trace.h file */
981     sprintf(buffer, "%s/trace.h", dirs[0]);
982     if (!copen(buffer)) {
983         return FALSE;
984     }
985     cputs("/*\012 * This file describes the fields of the array returned for ");
986     cputs("every stack\012 * frame by the call_trace() function.  It is ");
987     cputs("automatically generated by DGD\012 * on startup.\012 */\012\012");
988     cputs("# define TRACE_OBJNAME\t\t/* name of the object */\012");
989     cputs("# define TRACE_PROGNAME\t1\t/* name of the object the function is in */\012");
990     cputs("# define TRACE_FUNCTION\t2\t/* function name */\012");
991     cputs("# define TRACE_LINE\t3\t/* line number */\012");
992     cputs("# define TRACE_EXTERNAL\t4\t/* external call flag */\012");
993     cputs("# define TRACE_FIRSTARG\t5\t/* first argument to function */\012");
994     return cclose();
995 }
996 
997 
998 # ifdef DGD_EXTENSION
999 extern void extension_init      P((void));
1000 # endif
1001 
1002 void (*ext_restore)     P((object*));
1003 void (*ext_swapout)     P((object*));
1004 void (*ext_destruct)    P((object*));
1005 bool (*ext_funcall)     P((frame*, int, value*, char*));
1006 void (*ext_cleanup)     P((void));
1007 void (*ext_finish)      P((void));
1008 
1009 /*
1010  * NAME:        config->init()
1011  * DESCRIPTION: initialize the driver
1012  */
1013 bool conf_init(configfile, dumpfile, fragment)
1014 char *configfile, *dumpfile;
1015 sector *fragment;
1016 {
1017     char buf[STRINGSZ];
1018     int fd;
1019     bool init;
1020 
1021     /*
1022      * process config file
1023      */
1024     if (!pp_init(path_native(buf, configfile), (char **) NULL, 0)) {
1025         message("Config error: cannot open config file\012");   /* LF */
1026         m_finish();
1027         return FALSE;
1028     }
1029     init = conf_config();
1030     pp_clear();
1031     if (!init) {
1032         m_finish();
1033         return FALSE;
1034     }
1035     if (dumpfile != (char *) NULL) {
1036         fd = P_open(path_native(buf, dumpfile), O_RDONLY | O_BINARY, 0);
1037         if (fd < 0) {
1038             P_message("Config error: cannot open restore file\012");    /* LF */
1039             return FALSE;
1040         }
1041     }
1042 
1043     /* change directory */
1044     if (P_chdir(path_native(buf, conf[DIRECTORY].u.str)) < 0) {
1045         message("Config error: bad base directory \"%s\"\012",  /* LF */
1046                 conf[DIRECTORY].u.str);
1047         if (dumpfile != (char *) NULL) {
1048             P_close(fd);
1049         }
1050         m_finish();
1051         return FALSE;
1052     }
1053 
1054     m_static();
1055 
1056     /* initialize communications */
1057     if (!comm_init((int) conf[USERS].u.num,
1058                    (unsigned int) conf[TELNET_PORT].u.num,
1059                    (unsigned int) conf[BINARY_PORT].u.num)) {
1060         comm_finish();
1061         if (dumpfile != (char *) NULL) {
1062             P_close(fd);
1063         }
1064         m_finish();
1065         return FALSE;
1066     }
1067 
1068     /* initialize strings */
1069     str_init();
1070 
1071     /* initialize arrays */
1072     arr_init((int) conf[ARRAY_SIZE].u.num);
1073 
1074     /* initialize objects */
1075     o_init((uindex) conf[OBJECTS].u.num);
1076 
1077     /* initialize swap device */
1078     sw_init(conf[SWAP_FILE].u.str,
1079             (sector) conf[SWAP_SIZE].u.num,
1080             (sector) conf[CACHE_SIZE].u.num,
1081             (unsigned int) conf[SECTOR_SIZE].u.num);
1082 
1083     /* initialize swapped data handler */
1084     d_init(conf[TYPECHECKING].u.num == 2);
1085     *fragment = conf[SWAP_FRAGMENT].u.num;
1086 
1087     /* initalize editor */
1088     ed_init(conf[ED_TMPFILE].u.str,
1089             (int) conf[EDITORS].u.num);
1090 
1091     /* initialize call_outs */
1092     if (!co_init((uindex) conf[CALL_OUTS].u.num)) {
1093         comm_finish();
1094         if (dumpfile != (char *) NULL) {
1095             P_close(fd);
1096         }
1097         m_finish();
1098         return FALSE;
1099     }
1100 
1101     ext_restore =  (void (*) P((object*))) NULL;
1102     ext_swapout =  (void (*) P((object*))) NULL;
1103     ext_destruct = (void (*) P((object*))) NULL;
1104     ext_funcall =  (bool (*) P((frame*, int, value*, char*))) NULL;
1105     ext_cleanup =  (void (*) P((void))) NULL;
1106     ext_finish =   (void (*) P((void))) NULL;
1107 
1108     /* remove previously added kfuns */
1109     kf_clear();
1110 
1111 # ifdef DGD_EXTENSION
1112     extension_init();
1113 # endif
1114 
1115     /* initialize kfuns */
1116     kf_init();
1117 
1118     /* initialize interpreter */
1119     i_init(conf[CREATE].u.str, conf[TYPECHECKING].u.num == 2);
1120 
1121     /* initialize compiler */
1122     c_init(conf[AUTO_OBJECT].u.str,
1123            conf[DRIVER_OBJECT].u.str,
1124            conf[INCLUDE_FILE].u.str,
1125            dirs,
1126            (int) conf[TYPECHECKING].u.num);
1127 
1128     m_dynamic();
1129 
1130     /* initialize memory manager */
1131     m_init((size_t) conf[STATIC_CHUNK].u.num,
1132            (size_t) conf[DYNAMIC_CHUNK].u.num);
1133 
1134     /*
1135      * create include files
1136      */
1137     if (!conf_includes()) {
1138         comm_finish();
1139         if (dumpfile != (char *) NULL) {
1140             P_close(fd);
1141         }
1142         m_finish();
1143         return FALSE;
1144     }
1145 
1146     /* load precompiled objects */
1147     if (!pc_preload(conf[AUTO_OBJECT].u.str, conf[DRIVER_OBJECT].u.str)) {
1148         comm_finish();
1149         if (dumpfile != (char *) NULL) {
1150             P_close(fd);
1151         }
1152         m_finish();
1153         return FALSE;
1154     }
1155 
1156     /* initialize dumpfile header */
1157     conf_dumpinit();
1158 
1159     m_static();                         /* allocate error context statically */
1160     ec_push((ec_ftn) NULL);             /* guard error context */
1161     if (ec_push((ec_ftn) NULL)) {
1162         message((char *) NULL);
1163         endthread();
1164         message("Config error: initialization failed\012");     /* LF */
1165         ec_pop();                       /* remove guard */
1166 
1167         comm_finish();
1168         ed_finish();
1169         if (dumpfile != (char *) NULL) {
1170             P_close(fd);
1171         }
1172         m_finish();
1173         return FALSE;
1174     }
1175     m_dynamic();
1176     if (dumpfile == (char *) NULL) {
1177         /* initialize mudlib */
1178         if (ec_push((ec_ftn) errhandler)) {
1179             error((char *) NULL);
1180         }
1181         call_driver_object(cframe, "initialize", 0);
1182         ec_pop();
1183     } else {
1184         /* restore dump file */
1185         conf_restore(fd);
1186         P_close(fd);
1187 
1188         /* notify mudlib */
1189         if (ec_push((ec_ftn) errhandler)) {
1190             error((char *) NULL);
1191         }
1192         call_driver_object(cframe, "restored", 0);
1193         ec_pop();
1194     }
1195     ec_pop();
1196     i_del_value(cframe->sp++);
1197     endthread();
1198     ec_pop();                           /* remove guard */
1199 
1200     /* start accepting connections */
1201     comm_listen();
1202 
1203     return TRUE;
1204 }
1205 
1206 /*
1207  * NAME:        config->ext_callback()
1208  * DESCRIPTION: initialize callbacks for extension interface
1209  */
1210 void conf_ext_callback(restore, swapout, destruct, funcall, cleanup, finish)
1211 void (*restore) P((object*));
1212 void (*swapout) P((object*));
1213 void (*destruct) P((object*));
1214 bool (*funcall) P((frame*, int, value*, char*));
1215 void (*cleanup) P((void));
1216 void (*finish) P((void));
1217 {
1218     ext_restore =  restore;
1219     ext_swapout =  swapout;
1220     ext_destruct = destruct;
1221     ext_funcall =  funcall;
1222     ext_cleanup =  cleanup;
1223     ext_finish =   finish;
1224 }
1225 
1226 /*
1227  * NAME:        config->base_dir()
1228  * DESCRIPTION: return the driver base directory
1229  */
1230 char *conf_base_dir()
1231 {
1232     return conf[DIRECTORY].u.str;
1233 }
1234 
1235 /*
1236  * NAME:        config->driver()
1237  * DESCRIPTION: return the driver object name
1238  */
1239 char *conf_driver()
1240 {
1241     return conf[DRIVER_OBJECT].u.str;
1242 }
1243 
1244 /*
1245  * NAME:        config->typechecking()
1246  * DESCRIPTION: return the global typechecking flag
1247  */
1248 int conf_typechecking()
1249 {
1250     return conf[TYPECHECKING].u.num;
1251 }
1252 
1253 /*
1254  * NAME:        config->array_size()
1255  * DESCRIPTION: return the maximum array size
1256  */
1257 unsigned short conf_array_size()
1258 {
1259     return conf[ARRAY_SIZE].u.num;
1260 }
1261 
1262 /*
1263  * NAME:        config->statusi()
1264  * DESCRIPTION: return resource usage information
1265  */
1266 bool conf_statusi(f, idx, v)
1267 frame *f;
1268 Int idx;
1269 register value *v;
1270 {
1271     char *version;
1272     uindex ncoshort, ncolong;
1273 
1274     switch (idx) {
1275     case 0:     /* ST_VERSION */
1276         version = VERSION;
1277         PUT_STRVAL(v, str_new(version, (long) strlen(version)));
1278         break;
1279 
1280     case 1:     /* ST_STARTTIME */
1281         PUT_INTVAL(v, starttime);
1282         break;
1283 
1284     case 2:     /* ST_BOOTTIME */
1285         PUT_INTVAL(v, boottime);
1286         break;
1287 
1288     case 3:     /* ST_UPTIME */
1289         PUT_INTVAL(v, elapsed + P_time() - boottime);
1290         break;
1291 
1292     case 4:     /* ST_SWAPSIZE */
1293         PUT_INTVAL(v, conf[SWAP_SIZE].u.num);
1294         break;
1295 
1296     case 5:     /* ST_SWAPUSED */
1297         PUT_INTVAL(v, sw_count());
1298         break;
1299 
1300     case 6:     /* ST_SECTORSIZE */
1301         PUT_INTVAL(v, conf[SECTOR_SIZE].u.num);
1302         break;
1303 
1304     case 7:     /* ST_SWAPRATE1 */
1305         PUT_INTVAL(v, co_swaprate1());
1306         break;
1307 
1308     case 8:     /* ST_SWAPRATE5 */
1309         PUT_INTVAL(v, co_swaprate5());
1310         break;
1311 
1312     case 9:     /* ST_SMEMSIZE */
1313         PUT_INTVAL(v, m_info()->smemsize);
1314         break;
1315 
1316     case 10:    /* ST_SMEMUSED */
1317         PUT_INTVAL(v, m_info()->smemused);
1318         break;
1319 
1320     case 11:    /* ST_DMEMSIZE */
1321         PUT_INTVAL(v, m_info()->dmemsize);
1322         break;
1323 
1324     case 12:    /* ST_DMEMUSED */
1325         PUT_INTVAL(v, m_info()->dmemused);
1326         break;
1327 
1328     case 13:    /* ST_OTABSIZE */
1329         PUT_INTVAL(v, conf[OBJECTS].u.num);
1330         break;
1331 
1332     case 14:    /* ST_NOBJECTS */
1333         PUT_INTVAL(v, o_count());
1334         break;
1335 
1336     case 15:    /* ST_COTABSIZE */
1337         PUT_INTVAL(v, conf[CALL_OUTS].u.num);
1338         break;
1339 
1340     case 16:    /* ST_NCOSHORT */
1341         co_info(&ncoshort, &ncolong);
1342         PUT_INTVAL(v, ncoshort);
1343         break;
1344 
1345     case 17:    /* ST_NCOLONG */
1346         co_info(&ncoshort, &ncolong);
1347         PUT_INTVAL(v, ncolong);
1348         break;
1349 
1350     case 18:    /* ST_UTABSIZE */
1351         PUT_INTVAL(v, conf[USERS].u.num);
1352         break;
1353 
1354     case 19:    /* ST_ETABSIZE */
1355         PUT_INTVAL(v, conf[EDITORS].u.num);
1356         break;
1357 
1358     case 20:    /* ST_STRSIZE */
1359         PUT_INTVAL(v, MAX_STRLEN);
1360         break;
1361 
1362     case 21:    /* ST_ARRAYSIZE */
1363         PUT_INTVAL(v, conf[ARRAY_SIZE].u.num);
1364         break;
1365 
1366     case 22:    /* ST_STACKDEPTH */
1367         PUT_INTVAL(v, i_get_depth(f));
1368         break;
1369 
1370     case 23:    /* ST_TICKS */
1371         PUT_INTVAL(v, i_get_ticks(f));
1372         break;
1373 
1374     case 24:    /* ST_PRECOMPILED */
1375         PUT_ARRVAL(v, pc_list(f->data));
1376         break;
1377 
1378     default:
1379         return FALSE;
1380     }
1381 
1382     return TRUE;
1383 }
1384 
1385 /*
1386  * NAME:        config->status()
1387  * DESCRIPTION: return an array with information about resource usage
1388  */
1389 array *conf_status(f)
1390 register frame *f;
1391 {
1392     register value *v;
1393     register Int i;
1394     array *a;
1395 
1396     a = arr_new(f->data, 25L);
1397     for (i = 0, v = a->elts; i < 25; i++, v++) {
1398         conf_statusi(f, i, v);
1399     }
1400     return a;
1401 }
1402 
1403 /*
1404  * NAME:        config->objecti()
1405  * DESCRIPTION: return object resource usage information
1406  */
1407 bool conf_objecti(data, obj, idx, v)
1408 dataspace *data;
1409 register object *obj;
1410 Int idx;
1411 register value *v;
1412 {
1413     register control *ctrl;
1414     object *prog;
1415 
1416     prog = (obj->flags & O_MASTER) ? obj : OBJR(obj->u_master);
1417     ctrl = (O_UPGRADING(prog)) ? OBJR(prog->prev)->ctrl : o_control(prog);
1418 
1419     switch (idx) {
1420     case 0:     /* O_COMPILETIME */
1421         PUT_INTVAL(v, ctrl->compiled);
1422         break;
1423 
1424     case 1:     /* O_PROGSIZE */
1425         PUT_INTVAL(v, d_get_progsize(ctrl));
1426         break;
1427 
1428     case 2:     /* O_DATASIZE */
1429         PUT_INTVAL(v, ctrl->nvariables);
1430         break;
1431 
1432     case 3:     /* O_NSECTORS */
1433         PUT_INTVAL(v, (obj->flags & O_CREATED) ?
1434                        o_dataspace(obj)->nsectors : 0);
1435         if (obj->flags & O_MASTER) {
1436             v->u.number += ctrl->nsectors;
1437         }
1438         break;
1439 
1440     case 4:     /* O_CALLOUTS */
1441         PUT_ARRVAL(v, (obj->flags & O_CREATED) ?
1442                        d_list_callouts(data, o_dataspace(obj)) :
1443                        arr_new(data, 0L));
1444         break;
1445 
1446     case 5:     /* O_INDEX */
1447         PUT_INTVAL(v, (obj->flags & O_MASTER) ?
1448                        (Uint) obj->index : obj->u_master);
1449         break;
1450 
1451 
1452     default:
1453         return FALSE;
1454     }
1455 
1456     return TRUE;
1457 }
1458 
1459 /*
1460  * NAME:        config->object()
1461  * DESCRIPTION: return resource usage of an object
1462  */
1463 array *conf_object(data, obj)
1464 register dataspace *data;
1465 register object *obj;
1466 {
1467     register value *v;
1468     register Int i;
1469     array *a;
1470 
1471     a = arr_new(data, 6L);
1472     for (i = 0, v = a->elts; i < 6; i++, v++) {
1473         conf_objecti(data, obj, i, v);
1474     }
1475     return a;
1476 }
1477 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.