1760Speter /* Copyright (c) 1979 Regents of the University of California */ 2760Speter 3*7927Smckusick static char sccsid[] = "@(#)nl.c 1.8 08/27/82"; 4760Speter 5760Speter #include "whoami.h" 6760Speter #include "0.h" 7760Speter #include "opcode.h" 8760Speter #include "objfmt.h" 9760Speter 10760Speter /* 11760Speter * NAMELIST SEGMENT DEFINITIONS 12760Speter */ 13760Speter struct nls { 14760Speter struct nl *nls_low; 15760Speter struct nl *nls_high; 16760Speter } ntab[MAXNL], *nlact; 17760Speter 18760Speter struct nl nl[INL]; 19760Speter struct nl *nlp = nl; 20760Speter struct nls *nlact = ntab; 21760Speter 22760Speter /* 23760Speter * all these strings must be places where people can find them 24760Speter * since lookup only looks at the string pointer, not the chars. 25760Speter * see, for example, pTreeInit. 26760Speter */ 27760Speter 28760Speter /* 29760Speter * built in constants 30760Speter */ 31760Speter char *in_consts[] = { 32760Speter "true" , 33760Speter "false" , 34760Speter "TRUE", 35760Speter "FALSE", 36760Speter "minint" , 37760Speter "maxint" , 38760Speter "minchar" , 39760Speter "maxchar" , 40760Speter "bell" , 41760Speter "tab" , 42760Speter 0 43760Speter }; 44760Speter 45760Speter /* 46760Speter * built in simple types 47760Speter */ 48760Speter char *in_types[] = 49760Speter { 50760Speter "boolean", 51760Speter "char", 52760Speter "integer", 53760Speter "real", 54760Speter "_nil", /* dummy name */ 55760Speter 0 56760Speter }; 57760Speter 58760Speter int in_rclasses[] = 59760Speter { 60760Speter TINT , 61760Speter TINT , 62760Speter TINT , 63760Speter TCHAR , 64760Speter TBOOL , 65760Speter TDOUBLE , 66760Speter 0 67760Speter }; 68760Speter 69760Speter long in_ranges[] = 70760Speter { 71760Speter -128L , 128L , 72760Speter -32768L , 32767L , 73760Speter -2147483648L , 2147483647L , 74760Speter 0L , 127L , 75760Speter 0L , 1L , 76760Speter 0L , 0L /* fake for reals */ 77760Speter }; 78760Speter 79760Speter /* 80760Speter * built in constructed types 81760Speter */ 82760Speter char *in_ctypes[] = { 83760Speter "Boolean" , 84760Speter "intset" , 85760Speter "alfa" , 86760Speter "text" , 87760Speter 0 88760Speter }; 89760Speter 90760Speter /* 91760Speter * built in variables 92760Speter */ 93760Speter char *in_vars[] = { 94760Speter "input" , 95760Speter "output" , 96760Speter 0 97760Speter }; 98760Speter 99760Speter /* 100760Speter * built in functions 101760Speter */ 102760Speter char *in_funcs[] = 103760Speter { 104760Speter "abs" , 105760Speter "arctan" , 106760Speter "card" , 107760Speter "chr" , 108760Speter "clock" , 109760Speter "cos" , 110760Speter "eof" , 111760Speter "eoln" , 112760Speter "eos" , 113760Speter "exp" , 114760Speter "expo" , 115760Speter "ln" , 116760Speter "odd" , 117760Speter "ord" , 118760Speter "pred" , 119760Speter "round" , 120760Speter "sin" , 121760Speter "sqr" , 122760Speter "sqrt" , 123760Speter "succ" , 124760Speter "trunc" , 125760Speter "undefined" , 126760Speter /* 127760Speter * Extensions 128760Speter */ 129760Speter "argc" , 130760Speter "random" , 131760Speter "seed" , 132760Speter "wallclock" , 133760Speter "sysclock" , 134760Speter 0 135760Speter }; 136760Speter 137760Speter /* 138760Speter * Built-in procedures 139760Speter */ 140760Speter char *in_procs[] = 141760Speter { 142*7927Smckusick "assert", 143760Speter "date" , 144760Speter "dispose" , 145760Speter "flush" , 146760Speter "get" , 147760Speter "getseg" , 148760Speter "halt" , 149760Speter "linelimit" , 150760Speter "message" , 151760Speter "new" , 152760Speter "pack" , 153760Speter "page" , 154760Speter "put" , 155760Speter "putseg" , 156760Speter "read" , 157760Speter "readln" , 158760Speter "remove" , 159760Speter "reset" , 160760Speter "rewrite" , 161760Speter "time" , 162760Speter "unpack" , 163760Speter "write" , 164760Speter "writeln" , 165760Speter /* 166760Speter * Extensions 167760Speter */ 168760Speter "argv" , 169760Speter "null" , 170760Speter "stlimit" , 171760Speter 0 172760Speter }; 173760Speter 174760Speter #ifndef PI0 175760Speter /* 176760Speter * and their opcodes 177760Speter */ 178760Speter int in_fops[] = 179760Speter { 180760Speter O_ABS2, 181760Speter O_ATAN, 182760Speter O_CARD|NSTAND, 183760Speter O_CHR2, 184760Speter O_CLCK|NSTAND, 185760Speter O_COS, 186760Speter O_EOF, 187760Speter O_EOLN, 188760Speter 0, 189760Speter O_EXP, 190760Speter O_EXPO|NSTAND, 191760Speter O_LN, 192760Speter O_ODD2, 193760Speter O_ORD2, 194760Speter O_PRED2, 195760Speter O_ROUND, 196760Speter O_SIN, 197760Speter O_SQR2, 198760Speter O_SQRT, 199760Speter O_SUCC2, 200760Speter O_TRUNC, 201760Speter O_UNDEF|NSTAND, 202760Speter /* 203760Speter * Extensions 204760Speter */ 205760Speter O_ARGC|NSTAND, 206760Speter O_RANDOM|NSTAND, 207760Speter O_SEED|NSTAND, 208760Speter O_WCLCK|NSTAND, 209760Speter O_SCLCK|NSTAND 210760Speter }; 211760Speter 212760Speter /* 213760Speter * Built-in procedures 214760Speter */ 215760Speter int in_pops[] = 216760Speter { 217*7927Smckusick O_ASRT|NSTAND, 218760Speter O_DATE|NSTAND, 2197914Smckusick O_DISPOSE, 220760Speter O_FLUSH|NSTAND, 221760Speter O_GET, 222760Speter 0, 223760Speter O_HALT|NSTAND, 224760Speter O_LLIMIT|NSTAND, 225760Speter O_MESSAGE|NSTAND, 226760Speter O_NEW, 227760Speter O_PACK, 228760Speter O_PAGE, 229760Speter O_PUT, 230760Speter 0, 231760Speter O_READ4, 232760Speter O_READLN, 233760Speter O_REMOVE|NSTAND, 234760Speter O_RESET, 235760Speter O_REWRITE, 236760Speter O_TIME|NSTAND, 237760Speter O_UNPACK, 238760Speter O_WRITEF, 239760Speter O_WRITLN, 240760Speter /* 241760Speter * Extensions 242760Speter */ 243760Speter O_ARGV|NSTAND, 244760Speter O_ABORT|NSTAND, 245760Speter O_STLIM|NSTAND 246760Speter }; 247760Speter #endif 248760Speter 249760Speter /* 250760Speter * Initnl initializes the first namelist segment and then 251760Speter * initializes the name list for block 0. 252760Speter */ 253760Speter initnl() 254760Speter { 255760Speter register char **cp; 256760Speter register struct nl *np; 257760Speter struct nl *fp; 258760Speter int *ip; 259760Speter long *lp; 260760Speter 261760Speter #ifdef DEBUG 262760Speter if ( hp21mx ) 263760Speter { 264760Speter MININT = -32768.; 265760Speter MAXINT = 32767.; 266760Speter #ifndef PI0 2676356Speter #ifdef OBJ 268760Speter genmx(); 2696356Speter #endif OBJ 270760Speter #endif 271760Speter } 272760Speter #endif 273760Speter ntab[0].nls_low = nl; 274760Speter ntab[0].nls_high = &nl[INL]; 275760Speter defnl ( 0 , 0 , 0 , 0 ); 276760Speter 277760Speter /* 278760Speter * Types 279760Speter */ 280760Speter for ( cp = in_types ; *cp != 0 ; cp ++ ) 281760Speter hdefnl ( *cp , TYPE , nlp , 0 ); 282760Speter 283760Speter /* 284760Speter * Ranges 285760Speter */ 286760Speter lp = in_ranges; 287760Speter for ( ip = in_rclasses ; *ip != 0 ; ip ++ ) 288760Speter { 289760Speter np = defnl ( 0 , RANGE , nl+(*ip) , 0 ); 290760Speter nl[*ip].type = np; 291760Speter np -> range[0] = *lp ++ ; 292760Speter np -> range[1] = *lp ++ ; 293760Speter 294760Speter }; 295760Speter 296760Speter /* 297760Speter * built in constructed types 298760Speter */ 299760Speter 300760Speter cp = in_ctypes; 301760Speter /* 302760Speter * Boolean = boolean; 303760Speter */ 304760Speter hdefnl ( *cp++ , TYPE , nl+T1BOOL , 0 ); 305760Speter 306760Speter /* 307760Speter * intset = set of 0 .. 127; 308760Speter */ 309760Speter intset = *cp++; 310760Speter hdefnl( intset , TYPE , nlp+1 , 0 ); 311760Speter defnl ( 0 , SET , nlp+1 , 0 ); 312760Speter np = defnl ( 0 , RANGE , nl+TINT , 0 ); 313760Speter np -> range[0] = 0L; 314760Speter np -> range[1] = 127L; 315760Speter 316760Speter /* 317760Speter * alfa = array [ 1 .. 10 ] of char; 318760Speter */ 319760Speter np = defnl ( 0 , RANGE , nl+TINT , 0 ); 320760Speter np -> range[0] = 1L; 321760Speter np -> range[1] = 10L; 322760Speter defnl ( 0 , ARRAY , nl+T1CHAR , 1 ) -> chain = np; 323760Speter hdefnl ( *cp++ , TYPE , nlp-1 , 0 ); 324760Speter 325760Speter /* 326760Speter * text = file of char; 327760Speter */ 328760Speter hdefnl ( *cp++ , TYPE , nlp+1 , 0 ); 329760Speter np = defnl ( 0 , FILET , nl+T1CHAR , 0 ); 330760Speter np -> nl_flags |= NFILES; 331760Speter 332760Speter /* 333760Speter * input,output : text; 334760Speter */ 335760Speter cp = in_vars; 336760Speter # ifndef PI0 337760Speter input = hdefnl ( *cp++ , VAR , np , INPUT_OFF ); 338760Speter output = hdefnl ( *cp++ , VAR , np , OUTPUT_OFF ); 339760Speter # else 340760Speter input = hdefnl ( *cp++ , VAR , np , 0 ); 341760Speter output = hdefnl ( *cp++ , VAR , np , 0 ); 342760Speter # endif 3433828Speter # ifdef PC 3443828Speter input -> extra_flags |= NGLOBAL; 3453828Speter output -> extra_flags |= NGLOBAL; 3463828Speter # endif PC 347760Speter 348760Speter /* 349760Speter * built in constants 350760Speter */ 351760Speter cp = in_consts; 352760Speter np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 ); 353760Speter fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 ); 354760Speter (nl + TBOOL)->chain = fp; 355760Speter fp->chain = np; 356760Speter np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 ); 357760Speter fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 ); 358760Speter fp->chain = np; 359760Speter if (opt('s')) 360760Speter (nl + TBOOL)->chain = fp; 361760Speter hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MININT; 362760Speter hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MAXINT; 363760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , 0 ); 364760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , 127 ); 365760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , '\007' ); 366760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , '\t' ); 367760Speter 368760Speter /* 369760Speter * Built-in functions and procedures 370760Speter */ 371760Speter #ifndef PI0 372760Speter ip = in_fops; 373760Speter for ( cp = in_funcs ; *cp != 0 ; cp ++ ) 374760Speter hdefnl ( *cp , FUNC , 0 , * ip ++ ); 375760Speter ip = in_pops; 376760Speter for ( cp = in_procs ; *cp != 0 ; cp ++ ) 377760Speter hdefnl ( *cp , PROC , 0 , * ip ++ ); 378760Speter #else 379760Speter for ( cp = in_funcs ; *cp != 0 ; cp ++ ) 380760Speter hdefnl ( *cp , FUNC , 0 , 0 ); 381760Speter for ( cp = in_procs ; *cp != 0 , cp ++ ) 382760Speter hdefnl ( *cp , PROC , 0 , 0 ); 383760Speter #endif 384760Speter # ifdef PTREE 385760Speter pTreeInit(); 386760Speter # endif 387760Speter } 388760Speter 389760Speter struct nl * 390760Speter hdefnl(sym, cls, typ, val) 391760Speter { 392760Speter register struct nl *p; 393760Speter 394760Speter #ifndef PI1 395760Speter if (sym) 396760Speter hash(sym, 0); 397760Speter #endif 398760Speter p = defnl(sym, cls, typ, val); 399760Speter if (sym) 400760Speter enter(p); 401760Speter return (p); 402760Speter } 403760Speter 404760Speter /* 405760Speter * Free up the name list segments 406760Speter * at the end of a statement/proc/func 407760Speter * All segments are freed down to the one in which 408760Speter * p points. 409760Speter */ 410760Speter nlfree(p) 411760Speter struct nl *p; 412760Speter { 413760Speter 414760Speter nlp = p; 415760Speter while (nlact->nls_low > nlp || nlact->nls_high < nlp) { 416760Speter free(nlact->nls_low); 417760Speter nlact->nls_low = NIL; 418760Speter nlact->nls_high = NIL; 419760Speter --nlact; 420760Speter if (nlact < &ntab[0]) 421760Speter panic("nlfree"); 422760Speter } 423760Speter } 424760Speter 425760Speter 426760Speter char *VARIABLE = "variable"; 427760Speter 428760Speter char *classes[ ] = { 429760Speter "undefined", 430760Speter "constant", 431760Speter "type", 432760Speter "variable", /* VARIABLE */ 433760Speter "array", 434760Speter "pointer or file", 435760Speter "record", 436760Speter "field", 437760Speter "procedure", 438760Speter "function", 439760Speter "variable", /* VARIABLE */ 440760Speter "variable", /* VARIABLE */ 441760Speter "pointer", 442760Speter "file", 443760Speter "set", 444760Speter "subrange", 445760Speter "label", 446760Speter "withptr", 447760Speter "scalar", 448760Speter "string", 449760Speter "program", 4501197Speter "improper", 4511197Speter "variant", 4521197Speter "formal procedure", 4531197Speter "formal function" 454760Speter }; 455760Speter 456760Speter char *snark = "SNARK"; 457760Speter 458760Speter #ifdef PI 459760Speter #ifdef DEBUG 460760Speter char *ctext[] = 461760Speter { 462760Speter "BADUSE", 463760Speter "CONST", 464760Speter "TYPE", 465760Speter "VAR", 466760Speter "ARRAY", 467760Speter "PTRFILE", 468760Speter "RECORD", 469760Speter "FIELD", 470760Speter "PROC", 471760Speter "FUNC", 472760Speter "FVAR", 473760Speter "REF", 474760Speter "PTR", 475760Speter "FILET", 476760Speter "SET", 477760Speter "RANGE", 478760Speter "LABEL", 479760Speter "WITHPTR", 480760Speter "SCAL", 481760Speter "STR", 482760Speter "PROG", 483760Speter "IMPROPER", 4841197Speter "VARNT", 4851197Speter "FPROC", 4861197Speter "FFUNC" 487760Speter }; 488760Speter 489760Speter char *stars = "\t***"; 490760Speter 491760Speter /* 492760Speter * Dump the namelist from the 493760Speter * current nlp down to 'to'. 494760Speter * All the namelist is dumped if 495760Speter * to is NIL. 496760Speter */ 497760Speter dumpnl(to, rout) 498760Speter struct nl *to; 499760Speter { 500760Speter register struct nl *p; 501760Speter register int j; 502760Speter struct nls *nlsp; 503760Speter int i, v, head; 504760Speter 505760Speter if (opt('y') == 0) 506760Speter return; 507760Speter if (to != NIL) 508760Speter printf("\n\"%s\" Block=%d\n", rout, cbn); 509760Speter nlsp = nlact; 510760Speter head = NIL; 511760Speter for (p = nlp; p != to;) { 512760Speter if (p == nlsp->nls_low) { 513760Speter if (nlsp == &ntab[0]) 514760Speter break; 515760Speter nlsp--; 516760Speter p = nlsp->nls_high; 517760Speter } 518760Speter p--; 519760Speter if (head == NIL) { 520760Speter printf("\tName\tClass Bn+Flags\tType\tVal\tChn\n"); 521760Speter head++; 522760Speter } 523760Speter printf("%3d:", nloff(p)); 524760Speter if (p->symbol) 525760Speter printf("\t%.7s", p->symbol); 526760Speter else 527760Speter printf(stars); 528760Speter if (p->class) 529760Speter printf("\t%s", ctext[p->class]); 530760Speter else 531760Speter printf(stars); 532760Speter if (p->nl_flags) { 533760Speter pchr('\t'); 534760Speter if (p->nl_flags & 037) 535760Speter printf("%d ", p->nl_flags & 037); 536760Speter #ifndef PI0 537760Speter if (p->nl_flags & NMOD) 538760Speter pchr('M'); 539760Speter if (p->nl_flags & NUSED) 540760Speter pchr('U'); 541760Speter #endif 542760Speter if (p->nl_flags & NFILES) 543760Speter pchr('F'); 544760Speter } else 545760Speter printf(stars); 546760Speter if (p->type) 547760Speter printf("\t[%d]", nloff(p->type)); 548760Speter else 549760Speter printf(stars); 550760Speter v = p->value[0]; 551760Speter switch (p->class) { 552760Speter case TYPE: 553760Speter break; 554760Speter case VARNT: 555760Speter goto con; 556760Speter case CONST: 557760Speter switch (nloff(p->type)) { 558760Speter default: 559760Speter printf("\t%d", v); 560760Speter break; 561760Speter case TDOUBLE: 562760Speter printf("\t%f", p->real); 563760Speter break; 564760Speter case TINT: 565760Speter case T4INT: 566760Speter con: 567760Speter printf("\t%ld", p->range[0]); 568760Speter break; 569760Speter case TSTR: 570760Speter printf("\t'%s'", p->ptr[0]); 571760Speter break; 572760Speter } 573760Speter break; 574760Speter case VAR: 575760Speter case REF: 576760Speter case WITHPTR: 5771197Speter case FFUNC: 5781197Speter case FPROC: 579760Speter printf("\t%d,%d", cbn, v); 580760Speter break; 581760Speter case SCAL: 582760Speter case RANGE: 583760Speter printf("\t%ld..%ld", p->range[0], p->range[1]); 584760Speter break; 585760Speter case RECORD: 586760Speter printf("\t%d(%d)", v, p->value[NL_FLDSZ]); 587760Speter break; 588760Speter case FIELD: 589760Speter printf("\t%d", v); 590760Speter break; 591760Speter case STR: 592760Speter printf("\t|%d|", p->value[0]); 593760Speter break; 594760Speter case FVAR: 595760Speter case FUNC: 596760Speter case PROC: 597760Speter case PROG: 598760Speter if (cbn == 0) { 599760Speter printf("\t<%o>", p->value[0] & 0377); 600760Speter #ifndef PI0 601760Speter if (p->value[0] & NSTAND) 602760Speter printf("\tNSTAND"); 603760Speter #endif 604760Speter break; 605760Speter } 606760Speter v = p->value[1]; 607760Speter default: 608760Speter casedef: 609760Speter if (v) 610760Speter printf("\t<%d>", v); 611760Speter else 612760Speter printf(stars); 613760Speter } 614760Speter if (p->chain) 615760Speter printf("\t[%d]", nloff(p->chain)); 616760Speter switch (p->class) { 617760Speter case RECORD: 618760Speter if (p->ptr[NL_VARNT]) 619760Speter printf("\tVARNT=[%d]", nloff(p->ptr[NL_VARNT])); 620760Speter if (p->ptr[NL_TAG]) 621760Speter printf(" TAG=[%d]", nloff(p->ptr[NL_TAG])); 622760Speter break; 623760Speter case VARNT: 624760Speter printf("\tVTOREC=[%d]", nloff(p->ptr[NL_VTOREC])); 625760Speter break; 626760Speter } 6273828Speter # ifdef PC 6283828Speter if ( p -> extra_flags != 0 ) { 6293828Speter pchr( '\t' ); 6303828Speter if ( p -> extra_flags & NEXTERN ) 6313828Speter printf( "NEXTERN " ); 6323828Speter if ( p -> extra_flags & NLOCAL ) 6333828Speter printf( "NLOCAL " ); 6343828Speter if ( p -> extra_flags & NPARAM ) 6353828Speter printf( "NPARAM " ); 6363828Speter if ( p -> extra_flags & NGLOBAL ) 6373828Speter printf( "NGLOBAL " ); 6383828Speter if ( p -> extra_flags & NREGVAR ) 6393828Speter printf( "NREGVAR " ); 6403828Speter } 6413828Speter # endif PC 642760Speter # ifdef PTREE 643760Speter pchr( '\t' ); 644760Speter pPrintPointer( stdout , "%s" , p -> inTree ); 645760Speter # endif 646760Speter pchr('\n'); 647760Speter } 648760Speter if (head == 0) 649760Speter printf("\tNo entries\n"); 650760Speter } 651760Speter #endif 652760Speter 653760Speter 654760Speter /* 655760Speter * Define a new name list entry 656760Speter * with initial symbol, class, type 657760Speter * and value[0] as given. A new name 658760Speter * list segment is allocated to hold 659760Speter * the next name list slot if necessary. 660760Speter */ 661760Speter struct nl * 662760Speter defnl(sym, cls, typ, val) 663760Speter char *sym; 664760Speter int cls; 665760Speter struct nl *typ; 666760Speter int val; 667760Speter { 668760Speter register struct nl *p; 669760Speter register int *q, i; 670760Speter char *cp; 671760Speter 672760Speter p = nlp; 673760Speter 674760Speter /* 675760Speter * Zero out this entry 676760Speter */ 677760Speter q = p; 678760Speter i = (sizeof *p)/(sizeof (int)); 679760Speter do 680760Speter *q++ = 0; 681760Speter while (--i); 682760Speter 683760Speter /* 684760Speter * Insert the values 685760Speter */ 686760Speter p->symbol = sym; 687760Speter p->class = cls; 688760Speter p->type = typ; 689760Speter p->nl_block = cbn; 690760Speter p->value[0] = val; 691760Speter 692760Speter /* 693760Speter * Insure that the next namelist 694760Speter * entry actually exists. This is 695760Speter * really not needed here, it would 696760Speter * suffice to do it at entry if we 697760Speter * need the slot. It is done this 698760Speter * way because, historically, nlp 699760Speter * always pointed at the next namelist 700760Speter * slot. 701760Speter */ 702760Speter nlp++; 703760Speter if (nlp >= nlact->nls_high) { 704760Speter i = NLINC; 705760Speter cp = malloc(NLINC * sizeof *nlp); 7061834Speter if (cp == 0) { 707760Speter i = NLINC / 2; 708760Speter cp = malloc((NLINC / 2) * sizeof *nlp); 709760Speter } 7101834Speter if (cp == 0) { 711760Speter error("Ran out of memory (defnl)"); 712760Speter pexit(DIED); 713760Speter } 714760Speter nlact++; 715760Speter if (nlact >= &ntab[MAXNL]) { 716760Speter error("Ran out of name list tables"); 717760Speter pexit(DIED); 718760Speter } 719760Speter nlp = cp; 720760Speter nlact->nls_low = nlp; 721760Speter nlact->nls_high = nlact->nls_low + i; 722760Speter } 723760Speter return (p); 724760Speter } 725760Speter 726760Speter /* 727760Speter * Make a duplicate of the argument 728760Speter * namelist entry for, e.g., type 729760Speter * declarations of the form 'type a = b' 730760Speter * and array indicies. 731760Speter */ 732760Speter struct nl * 733760Speter nlcopy(p) 734760Speter struct nl *p; 735760Speter { 736760Speter register int *p1, *p2, i; 737760Speter 738760Speter p1 = p; 739760Speter p = p2 = defnl(0, 0, 0, 0); 740760Speter i = (sizeof *p)/(sizeof (int)); 741760Speter do 742760Speter *p2++ = *p1++; 743760Speter while (--i); 744760Speter p->chain = NIL; 745760Speter return (p); 746760Speter } 747760Speter 748760Speter /* 749760Speter * Compute a namelist offset 750760Speter */ 751760Speter nloff(p) 752760Speter struct nl *p; 753760Speter { 754760Speter 755760Speter return (p - nl); 756760Speter } 757760Speter 758760Speter /* 759760Speter * Enter a symbol into the block 760760Speter * symbol table. Symbols are hashed 761760Speter * 64 ways based on low 6 bits of the 762760Speter * character pointer into the string 763760Speter * table. 764760Speter */ 765760Speter struct nl * 766760Speter enter(np) 767760Speter struct nl *np; 768760Speter { 769760Speter register struct nl *rp, *hp; 770760Speter register struct nl *p; 771760Speter int i; 772760Speter 773760Speter rp = np; 774760Speter if (rp == NIL) 775760Speter return (NIL); 776760Speter #ifndef PI1 777760Speter if (cbn > 0) 778760Speter if (rp->symbol == input->symbol || rp->symbol == output->symbol) 779760Speter error("Pre-defined files input and output must not be redefined"); 780760Speter #endif 781760Speter i = rp->symbol; 782760Speter i &= 077; 783760Speter hp = disptab[i]; 784760Speter if (rp->class != BADUSE && rp->class != FIELD) 785760Speter for (p = hp; p != NIL && (p->nl_block & 037) == cbn; p = p->nl_next) 786760Speter if (p->symbol == rp->symbol && p->class != BADUSE && p->class != FIELD) { 787760Speter #ifndef PI1 788760Speter error("%s is already defined in this block", rp->symbol); 789760Speter #endif 790760Speter break; 791760Speter 792760Speter } 793760Speter rp->nl_next = hp; 794760Speter disptab[i] = rp; 795760Speter return (rp); 796760Speter } 797760Speter #endif 798