1 /* 2 * The Regina Rexx Interpreter 3 * Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public 16 * License along with this library; if not, write to the Free 17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 #ifndef REGINA_TYPES_H_INCLUDED 20 #define REGINA_TYPES_H_INCLUDED 21 22 typedef struct varbox *variableptr ; 23 typedef const struct varbox *cvariableptr ; 24 25 /* 26 * var_hashtable is a table with size entries. The entries are added according 27 * to their hash value. 28 * r is the number of read accesses. 29 * w is the number of write accesses. 30 * c is the number of collisions on access or while creating/copying the table. 31 * e is the number of true elements in the tbl, hashed to size buckets. 32 * Note that tbl contains one more hidden element used for variable 33 * maintenance if size > 0. 34 */ 35 typedef struct { 36 variableptr *tbl; 37 unsigned reads; 38 unsigned writes; 39 unsigned collisions; 40 unsigned elements; 41 unsigned size; 42 } var_hashtable; 43 44 typedef struct varbox { 45 var_hashtable *index; 46 variableptr next, prev, realbox ; 47 struct strengtype *name, *value ; 48 int guard ; 49 num_descr *num ; 50 int flag ; 51 unsigned hash ; 52 long hwired, valid ; /* FGC: at least valid may be too small for many 53 recursions with short instead of long. 54 27.09.98 (09/27/98). */ 55 variableptr stem ; 56 } variable ; 57 58 /* typedef int bool ; */ 59 60 typedef struct { 61 unsigned int lnum:1 ; /* left side of comparison is a number or string constant */ 62 unsigned int rnum:1 ; /* right side of comparison is a number or string constant */ 63 unsigned int lsvar:1 ; /* left side of comparison is a simple variable */ 64 unsigned int rsvar:1 ; /* right side of comparison is a simple variable */ 65 unsigned int lcvar:1 ; /* left side of comparison is a compound variable */ 66 unsigned int rcvar:1 ; /* right side of comparison is a compound variable */ 67 } compflags ; 68 69 typedef enum { 70 awtUNKNOWN = 0, 71 awtSTREAM = 1, 72 awtSTEM = 2, 73 awtLIFO = 3, 74 awtFIFO = 4 75 } AddressWithType; 76 77 typedef enum { 78 antUNKNOWN = 0, 79 antSTRING = 1, 80 antSIMSYMBOL = 2 81 } AddressNameType; 82 83 typedef enum { 84 fpdRETAIN = 0, 85 fpdCLEAR = 1 86 } FilePtrDisposition; 87 88 typedef struct { 89 unsigned int append:1; 90 unsigned int isinput:1; 91 unsigned int iserror:1; 92 unsigned int awt:3; /* overlay with AddressWithType */ 93 unsigned int ant:2; /* overlay with AddressNameType */ 94 unsigned int noeol:1; /* for INPUT NOEOL */ 95 } outputflags; /* used by ADDRESS WITH resourceo */ 96 97 typedef enum { 98 PROTECTED_DelayedScriptExit, 99 PROTECTED_DelayedInterpreterExit, 100 PROTECTED_DelayedRexxSignal 101 } delayed_error_type_t; 102 103 typedef enum { 104 QisUnused, 105 QisSESSION, 106 QisInternal, 107 QisExternal, 108 QisTemp 109 } queue_type_t ; 110 111 typedef struct { 112 time_t sec ; 113 time_t usec ; 114 } rexx_time; 115 116 struct _tsd_t; /* If this won't work change "struct _tsd_t *" to "void *" 117 * below. This will require more changes. Let your compiler 118 * choose the places. 119 */ 120 121 typedef struct pparambox *paramboxptr ; 122 typedef const struct pparambox *cparamboxptr ; 123 typedef struct pparambox { 124 paramboxptr next ; 125 int dealloc ; 126 struct strengtype *value ; 127 } parambox ; 128 129 typedef struct tnode { 130 unsigned int type ; 131 int charnr, lineno ; 132 union { /* saves memory which is really needed */ 133 int called; /* used during execution *and* don't need init */ 134 struct tnode *last; /* used during parsing */ 135 } o ; 136 struct strengtype *name ; 137 rexx_time *now ; 138 struct tnode *p[4] ; 139 union { 140 /* 141 * WARNING: When changing check whether to modify dumptree and the 142 * whole instore stuff. Seek for X_CEXPRLIST. 143 */ 144 streng *(*func)(struct _tsd_t *,cparamboxptr) ; 145 streng *strng ; 146 struct tnode *node ; 147 num_descr *number ; 148 compflags flags ; 149 variable *varbx ; 150 outputflags of ; 151 int parseflags ; 152 int nonansi ; 153 int trace_only ; /* For labels */ 154 } u ; 155 struct tnode *next ; 156 unsigned long nodeindex ; /* for an effectiv relocation, never change! */ 157 } treenode ; 158 typedef struct tnode *nodeptr ; 159 typedef const struct tnode *cnodeptr ; 160 161 typedef struct lineboxx *lineboxptr ; 162 typedef const struct lineboxx *clineboxptr ; 163 typedef struct lineboxx { 164 lineboxptr next, prev ; 165 struct strengtype *line ; 166 int lineno ; 167 } linebox ; 168 169 typedef struct labelboxx *labelboxptr ; 170 typedef const struct labelboxx *clabelboxptr ; 171 typedef struct labelboxx { 172 labelboxptr next ; 173 unsigned long hash ; 174 nodeptr entry ; 175 } labelbox ; 176 177 typedef struct trap_type /* index is type of signal */ 178 { 179 unsigned int on_off:1 ; /* true if trap is active/on */ 180 /* unsigned int trapped:1 ; */ /* true if condition has been raised */ 181 unsigned int def_act:1 ; /* true if default action is to ignore */ 182 unsigned int delayed:1 ; /* true if trap is in delay mode */ 183 unsigned int ignored:1 ; /* true if ignored when in delayed mode */ 184 unsigned int invoked:1 ; /* true if invoked by SIGNAL */ 185 streng *name ; /* label to transfer control to */ 186 } trap ; 187 188 typedef struct sig_type 189 { 190 int type ; 191 streng *info ; 192 streng *descr ; 193 int invoke ; /* is true if invoked with SIGNAL */ 194 int rc, subrc, lineno ; 195 } sigtype ; 196 197 typedef void (*signal_handler)(int); 198 199 typedef struct __regina_option 200 { 201 char *name ; 202 int offset ; 203 char *contains ; 204 } option_type ; 205 206 typedef struct _StackLine { 207 /* A stack line is a double linked list element of a streng. The streng 208 * never contains a line end and is never NULL. 209 * A read operations will happen at the top end, as well as a LIFO 210 * operation. 211 * A FIFO operation will happen at the bottom end. 212 */ 213 struct _StackLine *higher ; 214 struct _StackLine *lower ; 215 streng *contents ; 216 } StackLine ; 217 218 typedef struct _Buffer { 219 /* A buffer is a double linked list of stack line bundles. 220 * MAKEBUF() adds a new buffer at the newest end. 221 */ 222 struct _Buffer *higher ; 223 struct _Buffer *lower ; 224 225 /* The "content" of the buffer. See StackLine for a description. 226 * For a faster response of QUEUED(), we count the elements of lines. 227 */ 228 StackLine *top ; 229 StackLine *bottom ; 230 unsigned elements ; 231 } Buffer ; 232 233 typedef struct { 234 /* A queue is one of different implementations of queue types. 235 * See the picture and the description at the beginning of stack.c. 236 */ 237 queue_type_t type; 238 union { 239 struct { /* internal or SESSION: i */ 240 /* name is the uppercased name of the queue. In rare cases this 241 * may be NULL for QisSESSION after initialisation. 242 */ 243 streng *name ; 244 /* 245 * Indicates if the queue is a "real" queue 246 * or a false queue as a result of a rxqueue('set', 'qname') 247 * on a queue that doesn't exist. This is crap behaviour! 248 * but that's how Object Rexx works :-( 249 */ 250 int isReal ; 251 /* 252 * Content: We have a double linked list of buffers. See Buffer 253 * for a description. 254 */ 255 Buffer *top ; 256 Buffer *bottom ; 257 258 /* This is the count of buffers including the zeroth buffer */ 259 unsigned buffers ; 260 261 /* This is the overall count of elements in all buffers */ 262 unsigned elements ; 263 } i ; 264 struct { /* external: e */ 265 /* 266 * The port number for the current connection to an external rxstack 267 * Valid values: 1..0xFFFF, unused: 0 268 */ 269 int portno; 270 /* 271 * The socket fd for the current connection to an external rxstack 272 * Valid values: not -1, unused/error: -1 273 */ 274 int socket; 275 /* 276 * The server address of the current connection. Used to determine if 277 * we need to disconnect from one rxstack server and connect to 278 * another. 279 * The true data type is a 32 bit system depending type. 280 * Valid values: not 0, unused: 0 281 */ 282 int address; 283 /* 284 * A boolean value which indicates if the external queue has had a timeout 285 * set on it via RXQUEUE( 'Timeout' ) 286 * Valid values: 0 or 1 287 */ 288 int timeoutSet; 289 streng *name; 290 } e ; 291 Buffer t ; /* temp: t */ 292 } u ; 293 } Queue ; 294 295 typedef struct { /* one for each redirection in environment */ 296 streng *name; /* name if any, but not expanded */ 297 outputflags flags; 298 streng *base; /* "number" if name is a stem */ 299 streng *currname; /* expanded name + ".number" if name */ 300 /* is a stem */ 301 int currnamelen; /* len(currname) without ".number"*/ 302 int currnum; /* current number for a stem position */ 303 /* or -1 if unknown */ 304 int maxnum; /* maximum number for a stem position */ 305 /* or -1 if unknown */ 306 void *file; /* fileboxptr of the file with the */ 307 /* above name or NULL. */ 308 Queue *queue; /* queue with the above name or NULL. */ 309 Queue *tmp_queue;/* temporary queue for the redirection*/ 310 /* or NULL without this helper. */ 311 unsigned int SameAsOutput:2; /* locally used in shell.c */ 312 unsigned int FileRedirected:1; /* locally used in shell.c */ 313 char *tempname; /* locally used filename in shell.c */ 314 int type; /* locally used source in shell.c */ 315 int hdls[3]; /* locally used connection in shell.c */ 316 } environpart; 317 318 typedef struct { 319 struct strengtype *name; /* stemname or streamname if any */ 320 int subtype; /* SUBENVIR_... */ 321 int subcomed; /* has this environment been redirected to an API program via RexxRegistreSubcom???() */ 322 environpart input; 323 environpart output; 324 environpart error; 325 } environment; 326 327 typedef struct proclevelbox *proclevel ; 328 typedef const struct proclevelbox *cproclevel ; 329 typedef struct proclevelbox { 330 int numfuzz, currnumsize, numform ; 331 int mathtype ; 332 rexx_time rx_time ; 333 proclevel prev, next ; 334 var_hashtable *vars ; 335 paramboxptr args ; 336 struct strengtype *environment, *prev_env ; 337 char tracestat, traceint, varflag ; /* MDW 30012002 */ 338 sigtype *sig ; 339 trap *traps ; 340 jmp_buf *signal_continue; /* see jump_rexx_signal() */ 341 unsigned long options; 342 int pool; 343 } proclevbox ; 344 345 typedef struct _ttree { /* bucket list of treenodes which allows ultra fast 346 * loading of instore macros. 347 */ 348 struct _ttree *next; 349 unsigned long max; /* maximum number of elements in the bucket */ 350 unsigned long num; /* current number of elements in the bucket */ 351 unsigned long sum; /* sum of indices until element 0 */ 352 treenode * elems; 353 } ttree; /* treenode type */ 354 355 typedef struct { /* offsrcline: offset based source lines */ 356 unsigned long length; 357 unsigned long offset; 358 /* That's all. You need the source string of the incore macro to create 359 * a real sourceline using this information. 360 */ 361 } offsrcline; 362 363 typedef struct _otree { /* bucket list of offscrlines which allows ultra fast 364 * loading of instore macros. 365 */ 366 struct _otree *next; 367 unsigned long max; /* maximum number of elements in the bucket */ 368 unsigned long num; /* current number of elements in the bucket */ 369 unsigned long sum; /* sum of indices until element 0 */ 370 offsrcline * elems; 371 } otree; /* offsrcline type */ 372 373 typedef struct { /* internal_parser_type is a structure containing data from a 374 * parsing operation. 375 */ 376 lineboxptr first_source_line; /* Either this two values */ 377 lineboxptr last_source_line ; /* exist or srclines below */ 378 int tline; /* line number where error occured */ 379 int tstart; /* column number where error occured */ 380 int if_linenr; /* line number of last IF keyword */ 381 int when_linenr; /* line number of last WHEN keyword */ 382 int select_linenr; /* line number of last SELECT keyword */ 383 labelboxptr first_label; 384 labelboxptr last_label; 385 unsigned long numlabels; 386 labelboxptr sort_labels ; 387 int result; 388 nodeptr root; 389 ttree * nodes; 390 otree * srclines; /* Either this two values exist */ 391 const char * incore_source; /* or the two values above */ 392 streng * kill; /* Probably the true source of incore_source in case 393 * of an "INTERPRET" instruction or other not user 394 * generated but interpreted strings; else NULL. 395 */ 396 struct _tsd_t *TSD; /* needed during the parsing step */ 397 } internal_parser_type; 398 399 typedef struct { /* extstring: external (instore) string */ 400 unsigned long length; 401 /* and directly following the string's content */ 402 } extstring; 403 404 typedef struct { /* external_parser_type: the instore macro in user space */ 405 /* Never change from here until source including since it allows the 406 * reconstruction of the source if the machine type or Regina version 407 * doesn't match. 408 */ 409 char Magic[32]; /* "Regina's Internal Format\r\n" filled with 0 */ 410 #define MAGIC "Regina's Internal Format\r\n" 411 char ReginaVersion[64]; /* PARSE_VERSION_STRING */ 412 413 /* The following structure allows the detection of different 414 * architectures. We don't want to try to decode something from 415 * a 64 bit big endian encoded parsing tree on an i586 for 416 * example. 417 */ 418 union { 419 char ignore[4 * 256/8]; /* Allow 256 bit machines */ 420 struct { 421 unsigned long one; /* value one */ 422 unsigned long two; /* value two */ 423 void * ptr3; /* value (void*)3, size may be different to unsigned */ 424 void * ptr4; /* value (void*)4 */ 425 } s; 426 } arch_detector; 427 428 unsigned long OverallSize; /* in byte of this structure and all dependencies */ 429 430 unsigned long version; /* INSTORE_VERSION */ 431 432 /* We describe the sourcelines first */ 433 unsigned long NumberOfSourceLines; 434 unsigned long source; 435 /* Offset to table of source lines. Imagine a value of 1000 and 436 * 5 source lines (previous value). This structure has an address 437 * of 500 in the memory (what you get from malloc or something else). 438 * Then: The table has 5 entries at position 1500 in memory. 439 * Each table entry is an offsrcline structure. The source string is the 440 * instore[0] string of RexxStart or another source string. 441 */ 442 443 unsigned long NumberOfTreeElements; 444 unsigned long TreeStart; /* Within 0 .. (NumberOfTreeElements-1) */ 445 unsigned long tree; 446 /* Offset to table of nodes. Imagine a value of 2000 and 447 * 6 elements (NumberIfTreeElements). This structure has an address 448 * of 500 in the memory (what you get from malloc or something else). 449 * Then: The table has 6 treenodes at position 2500 in memory. 450 * Each table entry (treenode) must be relocated. Every nodeptr within a 451 * element is just an index within this table. If node->p[2] of one picked 452 * table entry is ((nodeptr) 4) then the address is calculated as follows: 453 * 500 + tree + (4*sizeof(treenode)) 454 * This value should be assigned to node->p[2] to use the value in its 455 * normal manner. 456 * A NULL value is represented by (nodeptr) (unsigned) -1. 457 * Every string within a treenode is relocated by adding 500. Imagine a 458 * value of 3000 for node->name. Then an extstring structure is located 459 * at 3500 in memory which represents the string's content. 460 */ 461 } external_parser_type; 462 463 typedef struct systeminfobox *sysinfo ; 464 typedef const struct systeminfobox *csysinfo ; 465 typedef struct systeminfobox { 466 struct strengtype *input_file ; /* must be 0-terminated without counting of the '\0' */ 467 streng *environment ; 468 FILE *input_fp; 469 int tracing ; 470 int interactive ; 471 jmp_buf *script_exit; /* see jump_script_exit() */ 472 streng *result ; 473 proclevbox *currlevel0 ; 474 struct systeminfobox *previous ; 475 nodeptr *callstack ; 476 int cstackcnt, cstackmax ; 477 int hooks ; 478 int invoked ; 479 int trace_override; 480 internal_parser_type tree; 481 int ctrlcounter; 482 } sysinfobox ; 483 484 #ifndef DONT_TYPEDEF_PFN 485 typedef unsigned long (*PFN)() ; 486 #endif 487 488 489 struct library { 490 streng *name; 491 void *handle; 492 unsigned long used; 493 494 struct library *next, *prev; 495 }; 496 497 498 struct entry_point { 499 streng *name; 500 PFN addr; 501 union { 502 void *gci_info; /* for function handlers */ 503 unsigned char user_area[8]; /* for suncommand and exit handlers */ 504 } special; 505 506 unsigned long hash; 507 struct library *lib; 508 struct entry_point *next, *prev; 509 }; 510 511 /* 512 * Every major OS has some functionality that isn't shared with others. 513 * Most functions relate to the command execution/redirection stuff. 514 * The global function collection *OS_Dep will point to this structure. 515 * Some systems, Win9x and OS/2-EMX, even use the DOS entry table because 516 * they can't take advantage of the performance functions the system 517 * usually provides. 518 * init() may map some "stupid" function on advanced function, as for 519 * instance Win9x doesn't support redirection correctly. 520 */ 521 struct _tsd_t; 522 struct regina_utsname; 523 typedef struct _OS_Dep_funcs { 524 void (*init) (void); 525 int (*setenv) (const char *name, const char *value); 526 int (*fork_exec) (struct _tsd_t *TSD, environment *env, const char *cmdline, int *rc); 527 int (*wait) (int process); 528 int (*open_subprocess_connection) (const struct _tsd_t *TSD, environpart *ep); 529 void (*unblock_handle) (int *handle, void *async_info); 530 void (*restart_file) (int hdl); 531 int (*close) (int handle, void *async_info); 532 void (*close_special) (int handle); 533 int (*read) (int hdl, void *buf, unsigned size, void *async_info) ; 534 int (*write) (int hdl, const void *buf, unsigned size, void *async_info); 535 void* (*create_async_info) (const struct _tsd_t *TSD); 536 void (*delete_async_info) (void *async_info); 537 void (*reset_async_info) (void *async_info); 538 void (*add_async_waiter) (void *async_info, int handle, int add_as_read_handle); 539 void (*wait_async_info) (void *async_info); 540 int (*uname) (struct regina_utsname *name); 541 } OS_Dep_funcs; 542 543 #include "regina64.h" 544 545 546 #endif /* REGINA_TYPES_H_INCLUDED */ 547