|
|
1.1 root 1: %{
2: static char ID[] = "@(#) ld.lex: 1.10 12/1/83";
3: #include "system.h"
4: #include <stdio.h>
5: #include <signal.h>
6: #include "bool.h"
7: #include "paths.h"
8: #include "sgs.h"
9: #include "structs.h" /* global structure definitions */
10: #include "extrns.h" /* external function definitions */
11: #include "y.tab.h" /* tokens generated by yacc */
12:
13: #if !ONEPROC || TRVEC
14: #include "tv.h"
15: #include "ldtv.h"
16: #endif
17:
18: #include "aouthdr.h"
19: #if ONEPROC
20: #include "instr.h"
21: #endif
22:
23: extern char version[]; /* ld version information */
24:
25: /*
26: * There are four start states for the lex parse:
27: *
28: * A : look for initial keyword of a ld directive
29: * MEMoREG : scan a ld directive
30: * COMA : skip a stand-alone comment
31: * COMoMR : skip a comment at the end of a directive
32: */
33:
34: #define RET1(a) {yylval.ivalue=a;moveit(1,a);return(a);}
35: #define RET2(a,b) {yylval.sptr=a;moveit(2,yylval.sptr);return(b);}
36: #define RET3(a,b) {yylval.lptr=a;moveit(3,yylval.lptr);return(b);}
37:
38:
39:
40: #define LSAVSIZE 6
41: static long lsavarea[LSAVSIZE]; /* local save area for integer tokens */
42: static int lsavndx = 0;
43: extern long *savelng();
44:
45: #define CSAVSIZE 1024
46: static char csavarea[CSAVSIZE]; /* local save area for string tokens */
47: static char *csavptr = &csavarea[0];
48: extern char *savestr();
49:
50: char inline[256]; /* global save area for the current input line */
51: char *inptr = &inline[0];
52:
53: char **argptr; /* main procedure argument list */
54: int argcnt; /* and count */
55:
56:
57: extern int in_y_exp; /* in_y_exp :
58: * TRUE : yacc is parsing assignment
59: * FALSE : yacc is not in assignment
60: *
61: * See explanation is ld.yac.
62: */
63:
64: int assigncnt; /* number of assignment slots */
65:
66:
67: #if FLEXNAMES
68: # define STRBASE 6144
69: #else
70: # define STRBASE 3072
71: #endif
72: /*eject*/
73: %}
74: %start A MEMoREG COMA COMoMR
75: %%
76: %{
77: long longint; /* local variables used in processing */
78: char *p; /* numbers and strings */
79: %}
80:
81: <A>"/*" BEGIN COMA;
82: <MEMoREG>"/*" BEGIN COMoMR;
83: <COMA>"*/" BEGIN A;
84: <COMoMR>"*/" BEGIN MEMoREG;
85: <COMA,COMoMR>. ;
86:
87: <A>MEMORY { BEGIN MEMoREG; RET1(MEMORY); }
88: <A>REGIONS { BEGIN MEMoREG; RET1(REGIONS); }
89: <A>TV { BEGIN MEMoREG; RET1(TV); }
90:
91: <A>SECTIONS RET1(SECTIONS);
92: <A>DSECT RET1(DSECT);
93: <A>NOLOAD RET1(NOLOAD);
94: <A>COPY RET1(COPY);
95: <A>INFO RET1(INFO);
96:
97: <MEMoREG>"}" { BEGIN A; RET1(RBRACE); }
98: <MEMoREG>ORIGIN|origin|org|o RET1(ORG);
99: <MEMoREG>LENGTH|length|len|l RET1(LEN);
100: <MEMoREG>SPARE|spare|s RET1(SPARE);
101: <MEMoREG>RANGE|range RET1(RANGE);
102: <MEMoREG>ASSIGN|assign RET1(ASSIGN);
103:
104: <A,MEMoREG>"." RET1(DOT);
105: <A,MEMoREG>"}" RET1(RBRACE);
106: <A,MEMoREG>"{" RET1(LBRACE);
107: <A,MEMoREG>")" RET1(RPAREN);
108: <A,MEMoREG>"(" RET1(LPAREN);
109: <A,MEMoREG>":" RET1(COLON);
110: <A,MEMoREG>";" RET1(SEMICOL);
111: <A,MEMoREG>"-" RET1(MINUS);
112: <A,MEMoREG>"=" RET1(EQ);
113: <A,MEMoREG>">" RET1(GT);
114: <A,MEMoREG>"," RET1(COMMA);
115: <A,MEMoREG>"&" RET1(AND);
116: <A,MEMoREG>"&&" RET1(ANDAND);
117: <A,MEMoREG>"|" RET1(OR);
118: <A,MEMoREG>"||" RET1(OROR);
119: <A,MEMoREG>"==" RET1(EQEQ);
120: <A,MEMoREG>"!=" RET1(NE);
121: <A,MEMoREG>"~" RET1(BNOT);
122: <A,MEMoREG>"!" RET1(NOT);
123: <A,MEMoREG>"/" RET1(DIV);
124: <A,MEMoREG>"*" RET1(MULT);
125: <A,MEMoREG>"%" RET1(PC);
126: <A,MEMoREG>"<" RET1(LT);
127: <A,MEMoREG>">=" RET1(GE);
128: <A,MEMoREG>"<=" RET1(LE);
129: <A,MEMoREG>"<<" RET1(LSHIFT);
130: <A,MEMoREG>">>" RET1(RSHIFT);
131: <A,MEMoREG>"+" RET1(PLUS);
132: <A,MEMoREG>"+=" RET1(PLUSEQ);
133: <A,MEMoREG>"-=" RET1(MINUSEQ);
134: <A,MEMoREG>"*=" RET1(MULTEQ);
135: <A,MEMoREG>"/=" RET1(DIVEQ);
136: <A,MEMoREG>ALIGN|align RET1(ALIGN);
137: <A,MEMoREG>BLOCK|block RET1(BLOCK);
138: <A,MEMoREG>GROUP|group RET1(GROUP);
139: <A,MEMoREG>PHY|phy RET1(PHY);
140:
141:
142: "\n" {
143: lineno++;
144: inptr = &inline[0];
145: }
146: [ \t]+ {
147: *inptr++ = ' ';
148: *inptr = '\0';
149: }
150:
151:
152: <A,MEMoREG>[0][0-7]* {
153: longint = 0L;
154: for(p=yytext+1; *p != '\0'; p++) {
155: longint = longint * 8 + (*p-'0');
156: }
157: RET3(savelng(longint), LONGINT);
158: }
159: <A,MEMoREG>[0-9]+ {
160: longint = 0L;
161: for(p=yytext; *p != '\0'; p++) {
162: longint = longint * 10 + (*p-'0');
163: }
164: RET3(savelng(longint), LONGINT);
165: }
166: <A,MEMoREG>0[Xx][0-9a-fA-F]+ {
167: longint = 0L;
168: for(p=yytext+2; *p != '\0'; p++) {
169: longint = longint << 4;
170: if (*p >= '0' && *p <= '9')
171: longint += *p-'0';
172: else if (*p >= 'a' && *p <= 'f')
173: longint += *p-'a'+10;
174: else longint += *p-'A'+10;
175: }
176: RET3(savelng(longint), LONGINT);
177: }
178:
179: <A,MEMoREG>[a-zA-Z0-9$._]+"/"("*"|"=") {
180: yyless(yyleng-2);
181: RET2(savestr(yytext), NAME);
182: }
183:
184: <A,MEMoREG>[a-zA-Z0-9$._/]+"/"("*"|"=") {
185: if ( in_y_exp )
186: REJECT;
187: yyless(yyleng-2);
188: RET2(savestr(yytext), FILENAME);
189: }
190:
191: <A,MEMoREG>[a-zA-Z0-9$._]+ {
192: RET2(savestr(yytext), NAME);
193: }
194:
195: <A,MEMoREG>[a-zA-Z0-9$._/]+ {
196: if ( in_y_exp )
197: REJECT;
198: RET2(savestr(yytext), FILENAME);
199: }
200: %%
201: /*eject*/
202: main(argc,argv)
203: int argc;
204: char *argv[];
205: {
206:
207: /*
208: * This is the MAIN procdure for PASS 1 of ld
209: *
210: * PASS 1 is the parsing pass:
211: * 1. The ld command line, and any specified ifiles, are
212: * scanned for good syntax.
213: * 2. Control blocks are constructed, containing the information
214: * extracted from the input.
215: * 3. If there are no errors, the control blocks are written out
216: * to a "transfer file", for reading by PASS 2.
217: * 4. If there are no errors, PASS 2 is called via a system
218: * "execl" call.
219: */
220:
221: /*
222: * Initialize PASS 1
223: */
224:
225: initpass1();
226: argptr = argv;
227: argcnt = argc;
228: if ( argcnt <= 1 )
229: {
230: fprintf( stderr, "Usage: %sld [ options ] file ...\n", SGS );
231: exit(1);
232: }
233:
234: /*
235: * Process the command-line arguments to ld
236: */
237:
238: lineno = 0;
239: curfilnm = savefn("*command line*");
240:
241: while( --argcnt )
242: if( **++argptr == '-' )
243: /*
244: * The argument is a flag
245: */
246: pflags( ++(*argptr), FALSE );
247: else {
248: /*
249: * The argument is a file name
250: */
251: BEGIN A;
252: filespec(*argptr);
253: }
254:
255: /*
256: * Perform a consistency check among the ld flags:
257: * 1. "-h" and "-X" flags
258: * 2. "-ild", "-r", and "-a" flags
259: * 3. "-r" and "-s" flags
260: * 4. "-p" and "-B" flags
261: *
262: * Assign default values to the ld flags
263: * 1. "-h" flag
264: * 2. "-a" flag
265: * 3. "-p" flag
266: */
267:
268: if( Xflag )
269: if( hflag > 0 ) {
270: if( hflag < sizeof(AOUTHDR) )
271: lderror(1, 0,NULL, "optional header size (%d bytes) is too small to contain the UNIX a.out header (%d bytes)",
272: hflag, sizeof(AOUTHDR) );
273: }
274: else
275: hflag = sizeof(AOUTHDR);
276: #if ILDOPT
277: if (ildflag) {
278: rflag = 1;
279: if (sflag) {
280: lderror (0, 0, NULL, "both -ild and -s flags are set. -s flag turned off");
281: sflag = 0;
282: }
283: }
284: #endif
285: if( rflag && sflag ) {
286: lderror(0, 0,NULL, "both -r and -s flags are set. -s flag turned off" );
287: sflag = 0;
288: }
289: if ( Bflag && (pflag > 0) && (pflag < Bflag)) {
290: lderror(0, 0, NULL, "pflag(%d) less than Bflag, set to value of Bflag(%d)\n",
291: pflag, Bflag);
292: pflag = Bflag;
293: }
294: if( ! rflag )
295: aflag = 1;
296:
297: /*
298: * Supply version information
299: */
300:
301: if( Vflag ) {
302: fprintf( stderr, "\n%sld : %s : Version %s",
303: SGSNAME, RELEASE, version );
304: if( Vflag == 2 ) {
305: #if AR16WR
306: fprintf( stderr, " : PDP 11/70-45 : " );
307: #endif
308: #if AR32WR
309: fprintf( stderr, " : VAX 11/780 : " );
310: #endif
311: #if ! AR16WR && ! AR32WR
312: #ifdef u3b
313: fprintf( stderr, " : 3B-20 : " );
314: #else
315: fprintf( stderr, " : non-DEC : ");
316: #endif
317: #endif
318: #if TS
319: fprintf( stderr, "UN*X TS" );
320: #else
321: fprintf( stderr, "UN*X" );
322: #endif
323: }
324: fprintf( stderr, "\n" );
325: }
326:
327: /*
328: * Exit if any errors were found, or if this is a "parse only"
329: * run
330: */
331:
332: if( (errlev != 0) || (cflag == 1) ) {
333: #if !ONEPROC
334: unlink( trnname );
335: #endif
336: exit(errlev);
337: }
338:
339: /*
340: * Call PASS 2
341: */
342:
343: #if ONEPROC
344: pass2();
345: }
346: #else
347: callpass2();
348:
349: unlink( trnname );
350: lderror(2, 0,NULL, "failure to load pass 2 of %sld", SGS);
351: }
352: /*eject*/
353: ldexit()
354: {
355:
356: /*
357: * PASS 1: clean up and exit after a fatal error
358: */
359:
360: signal(SIGINT, SIG_IGN);
361: signal(SIGQUIT, SIG_DFL);
362: signal(SIGTERM, SIG_IGN);
363: signal(SIGHUP, SIG_DFL);
364:
365: exit(13); /* unlucky break */
366: }
367: /*eject*/
368: #endif
369: long *
370: savelng(l)
371: long l;
372: {
373:
374: /*
375: * Copy a long token into local save area and return a pointer to it.
376: *
377: * The save area is used as a circular buffer
378: */
379:
380: lsavndx++;
381: lsavndx %= LSAVSIZE;
382: lsavarea[lsavndx] = l;
383:
384: return( &lsavarea[lsavndx] );
385: }
386:
387:
388:
389:
390: char *
391: savestr(p)
392: char *p;
393: {
394:
395: /*
396: * Copy a string into local save area and return a pointer to it
397: *
398: * The save area is used as a circular buffer
399: */
400:
401: register char *saveptr;
402:
403: if( csavptr > (csavarea + CSAVSIZE - 256) )
404: csavptr = csavarea;
405: saveptr = csavptr;
406:
407: while( *csavptr++ = *p++ );
408:
409: return( saveptr );
410: }
411:
412:
413:
414:
415: moveit(type, value)
416: int type, value;
417: {
418: register char *p;
419:
420: p = &yytext[0];
421:
422: while( *inptr++ = *p++ );
423: inptr--;
424:
425: #if DEBUG
426: if( dflag > 3 ) {
427: fprintf(stderr, "line: <%s> return: <", inline);
428: switch( type ) {
429: case 1:
430: fprintf(stderr, "%d>\n", value);
431: break;
432: case 2:
433: fprintf(stderr, "%s>\n", (char *) value);
434: break;
435: case 3:
436: fprintf(stderr, "%08lx>\n", * (long *) value);
437: break;
438: }
439: }
440: #endif
441: }
442: /*eject*/
443: initpass1()
444: {
445: register int oldmode;
446: int ldexit();
447: #if ONEPROC
448: long times();
449: #endif
450:
451: /*
452: * Set the following signals to be caught, unless ld is running in the
453: * background. In this case, leave them set at "ignore"
454: */
455:
456: if( signal(SIGINT, ldexit) == SIG_IGN )
457: signal(SIGINT, SIG_IGN);
458: if( signal(SIGHUP, ldexit) == SIG_IGN )
459: signal(SIGHUP, SIG_IGN);
460: if( signal(SIGQUIT, ldexit) == SIG_IGN )
461: signal(SIGQUIT, SIG_IGN);
462:
463:
464: #if ONEPROC
465: ttime = times(&ptimes);
466: #else
467: /*
468: * Create the "transfer file" used to pass information to PASS 2
469: */
470:
471: sprintf(trnname, "%s/%s", TMPDIR, "ldXXXXX");
472: mktemp(trnname);
473:
474: oldmode = umask( 0 );
475: if( close( creat(trnname,0644) ) == -1 ) {
476: umask( oldmode );
477: lderror(2, 0,NULL, "can't create intermediate %sld file %s",
478: SGS, trnname);
479: }
480: umask( oldmode );
481: #endif
482:
483: /*
484: * Allocate the global file name save area
485: */
486:
487: strbase = myalloc(STRBASE);
488: strnext = strbase;
489: strlimit = strbase + STRBASE;
490:
491: #if ONEPROC && (!NOSDP)
492: /*
493: * Initialize the Software Demand Paging System
494: */
495: syminit();
496: #endif
497: }
498: /*eject*/
499: #if !ONEPROC
500: callpass2()
501: {
502:
503: /*
504: * Output PASS 1 information to the "transfer file"
505: *
506: * 1. reserve space for flags and list headers
507: * 2. output lists
508: * 3. output flags and list headers
509: */
510:
511: trnfdes = fopen(trnname, "w");
512: skp_tf_hdr();
513: wrt_tf();
514: wrt_tf_hdr();
515: fclose( trnfdes );
516:
517: /*
518: * Exit, if this is a "generate transfer file run" only
519: */
520:
521: if( cflag == 2 ) {
522: fprintf( stderr, "ld transfer file name: %s\n", trnname );
523: exit(0);
524: }
525: #if DEBUG
526: if( dflag > 2 )
527: fprintf( stderr, "ld transfer file name: %s\n", trnname );
528: #endif
529:
530: /*
531: * Execute PASS 2
532: */
533:
534: execl(LD2, LD2, trnname, 0);
535:
536: }
537: /*eject*/
538: skp_tf_hdr()
539: {
540:
541: /*
542: * Reserve space for control and descriptor information collected during
543: * PASS 1
544: *
545: * This information is of fixed length, and comes at the very beginning
546: * of the transfer file
547: */
548:
549: register long length;
550:
551: length =
552: 7 * sizeof(int) + /* list sizes */
553: 13 * sizeof(char) + /* flags */
554: #if UNIX || XL
555: 1 * sizeof(char) + /* xflag */
556: #endif
557: #if ILDOPT
558: 1 * sizeof(char) + /* ildflag */
559: #endif
560: #if PAGING
561: 1 * sizeof(char) + /* Fflag */
562: #endif
563: #if PAGING
564: 1 * sizeof(char) + /* zflag */
565: #endif
566: #if COMMON
567: 2 * sizeof(char) + /* tflag and Mflag */
568: #endif
569: 3 * sizeof(int) + /* control values */
570: 3 * sizeof(short) + /* VStamp, fill and magic */
571: 128 + /* output file name */
572: 8 + /* program entry pt */
573: sizeof(TVINFO) + /* tv information */
574: 1 * sizeof(int); /* flags + counts */
575:
576: fseek( trnfdes, length, 0 );
577: }
578: /*eject*/
579: wrt_tf()
580: {
581:
582: /*
583: * Output the bulk of the information extracted from PASS 1:
584: *
585: * 1. The names of input ifiles, input *.o and archive files, and
586: * output sections
587: * 2. The data structures describing the ld directives
588: */
589:
590: MEMTYPE *outds1();
591: REGION *outds2();
592: ACTITEM *outds3(), *outds4(), *outds6();
593: TVASSIGN *outds8();
594:
595: /*
596: * 1. Output saved strings
597: */
598:
599: fwrite( strbase, 1, (strnext - strbase), trnfdes );
600:
601:
602: /*
603: * 2a. Output DEFSYM data structures
604: */
605:
606: symcnt = 0;
607: if( symlist.head ) {
608: register ACTITEM *a;
609: a = (ACTITEM *) symlist.head;
610: while( a ) {
611: a = outds3(a);
612: symcnt++;
613: }
614: }
615:
616: /*
617: * 2b. Output MEMTYPE data structures
618: */
619:
620: memcnt = 0;
621: if( memlist.head ) {
622: register MEMTYPE *m;
623: m = (MEMTYPE *) memlist.head;
624: while( m ) {
625: m = outds1(m);
626: memcnt++;
627: }
628: }
629:
630: /*
631: * 2c. Output REGION data structures
632: */
633:
634: regcnt = 0;
635: if( reglist.head ) {
636: register REGION *r;
637: r = (REGION *) reglist.head;
638: while( r ) {
639: r = outds2(r);
640: regcnt++;
641: }
642: }
643:
644: /*
645: * 2d. Output information on input *.o and archive library files
646: */
647:
648: ldfcnt = 0;
649: if( ldfilist.head ) {
650: register ACTITEM *a;
651: a = (ACTITEM *) ldfilist.head;
652: while( a ) {
653: a = outds3(a);
654: ldfcnt++;
655: }
656: }
657:
658:
659: /*
660: * 2e. Output information on output sections
661: */
662:
663: bldcnt = 0;
664: if( bldoutsc.head ) {
665: register ACTITEM *a;
666: a = (ACTITEM *) bldoutsc.head;
667: while( a ) {
668: a = outds4(a);
669: bldcnt++;
670: }
671: }
672:
673:
674: /*
675: * 2f. Output information on assignments
676: */
677:
678: expcnt = 0;
679: if( explist.head ) {
680: register ACTITEM *a;
681: a = (ACTITEM *) explist.head;
682: while( a ) {
683: a = outds6(a);
684: expcnt++;
685: }
686: }
687:
688: /*
689: * 2g. Output information on slot assignments
690: */
691:
692: tvslotcnt = 0;
693: if (tvslot1 != NULL) {
694: register TVASSIGN *s;
695: s = tvslot1;
696: while (s != NULL) {
697: s = outds8(s);
698: ++tvslotcnt;
699: }
700: }
701: }
702: /*eject*/
703: wrt_tf_hdr()
704: {
705:
706: /*
707: * Output control and descriptor information obtained during PASS 1
708: *
709: * This information is of fixed length, and comes at the very beginning
710: * of the transfer file
711: */
712:
713: int length;
714:
715: fseek( trnfdes, 0L, 0 );
716:
717: /*
718: * Output the sizes of the lists built during PASS 1
719: *
720: * 1. symbol definition/undefinition
721: * 2. MEMORY directives
722: * 3. REGIONS directives
723: * 4. input *.o and archive library files
724: * 5. output sections
725: * 6. assignment directives
726: * 7. tv slot assignment directives
727: */
728:
729: fwrite( &symcnt, sizeof(int), 1, trnfdes );
730: fwrite( &memcnt, sizeof(int), 1, trnfdes );
731: fwrite( ®cnt, sizeof(int), 1, trnfdes );
732: fwrite( &ldfcnt, sizeof(int), 1, trnfdes );
733: fwrite( &bldcnt, sizeof(int), 1, trnfdes );
734: fwrite( &expcnt, sizeof(int), 1, trnfdes );
735: fwrite(&tvslotcnt, sizeof(int), 1, trnfdes);
736:
737: /*
738: * Output the ld control flags
739: */
740:
741: fwrite( &aflag, sizeof(char), 1, trnfdes );
742: fwrite( &cflag, sizeof(char), 1, trnfdes );
743: fwrite( &dflag, sizeof(char), 1, trnfdes );
744: fwrite( &iflag, sizeof(char), 1, trnfdes );
745: fwrite( &mflag, sizeof(char), 1, trnfdes );
746: fwrite( &rflag, sizeof(char), 1, trnfdes );
747: fwrite( &sflag, sizeof(char), 1, trnfdes );
748: fwrite( &tvflag, sizeof(char), 1, trnfdes );
749: fwrite( &Hflag, sizeof(char), 1, trnfdes );
750: fwrite( &Nflag, sizeof(char), 1, trnfdes );
751: fwrite( &Sflag, sizeof(char), 1, trnfdes );
752: fwrite( &Vflag, sizeof(char), 1, trnfdes );
753: fwrite( &Xflag, sizeof(char), 1, trnfdes );
754: fwrite( &hflag, sizeof(int), 1, trnfdes );
755: fwrite( &pflag, sizeof(int), 1, trnfdes );
756: fwrite( &Bflag, sizeof(int), 1, trnfdes );
757: fwrite( &VSflag, sizeof(short), 1, trnfdes);
758: #if UNIX || XL
759: fwrite( &xflag, sizeof(char), 1, trnfdes );
760: #endif
761: #if COMMON
762: fwrite( &tflag, sizeof(char), 1, trnfdes );
763: fwrite( &Mflag, sizeof(char), 1, trnfdes );
764: #endif
765: #if PAGING
766: fwrite( &Fflag, sizeof(char), 1, trnfdes );
767: #endif
768: #if PAGING
769: fwrite( &zflag, sizeof(char), 1, trnfdes );
770: #endif
771: #if ILDOPT
772: fwrite( &ildflag, sizeof(char), 1, trnfdes );
773: #endif
774:
775: /*
776: * Output various values extracted from the parse
777: */
778:
779: fwrite( &globfill, sizeof(short), 1, trnfdes );
780: fwrite( &magic, sizeof(unsigned short), 1, trnfdes );
781:
782: fwrite( outfilnm, 128, 1, trnfdes );
783: fwrite( epsymbol, 8, 1, trnfdes );
784:
785: /* convert filename from ptr to index */
786: if (tvspec.tvinflnm != NULL)
787: tvspec.tvinflnm = (char *) ((int) tvspec.tvinflnm - (int) strbase);
788: fwrite( &tvspec, sizeof(TVINFO), 1, trnfdes );
789:
790: /*
791: * Output the size of the saved strings
792: */
793:
794: length = strnext - strbase;
795: fwrite( &length, sizeof(int), 1, trnfdes );
796: }
797: /*eject*/
798: MEMTYPE *
799: outds1(m)
800: MEMTYPE *m;
801: {
802:
803: /*
804: * Output one MEMTYPE data structure
805: */
806:
807: fwrite( m, 1, sizeof(MEMTYPE), trnfdes );
808:
809: return( m->mtnext );
810: }
811:
812:
813:
814: REGION *
815: outds2(r)
816: REGION *r;
817: {
818:
819: /*
820: * Output one REGION data structure
821: */
822:
823: fwrite( r, 1, sizeof(REGION), trnfdes );
824:
825: return( r->rgnext );
826: }
827: /*eject*/
828: ACTITEM *
829: outds3(a)
830: ACTITEM *a;
831: {
832:
833: /*
834: * Output one AILDFILE, AILDLBRY, AIADFILE, or AIDFNSYM data structure
835: *
836: * Convert a "pointer to a string" to a "index to a string"
837: */
838:
839: a->ldlbry.aiinflnm = (char *) ((int) a->ldlbry.aiinflnm - (int) strbase);
840: a->ldlbry.aifilnam = (char *) ((int) a->ldlbry.aifilnam - (int) strbase);
841:
842: fwrite( a, 1, sizeof(ACTITEM), trnfdes );
843:
844: return( a->ldlbry.ainext );
845: }
846:
847:
848:
849: ACTITEM *
850: outds4(a)
851: ACTITEM *a;
852: {
853:
854: /*
855: * Output one AIDFNSCN or AIDFNGRP data structure
856: *
857: * Convert a "pointer to a string" to a "index to a string"
858: */
859:
860: register ACTITEM *anext, *b;
861: ACTITEM *outds5();
862:
863: anext = a->dfnscn.ainext;
864: a->dfnscn.aiinflnm = (char *) ((int) a->dfnscn.aiinflnm - (int) strbase);
865:
866: fwrite( a, 1, sizeof(ACTITEM), trnfdes );
867:
868: b = (ACTITEM *) a->dfnscn.sectspec.head;
869: switch( a->dfnscn.aitype ) {
870: case AIDFNSCN:
871: while( b )
872: switch( b->addscn.aitype ) {
873: case AIADDSCN:
874: b = outds5(b);
875: break;
876: case AIADFILE:
877: b = outds3(b);
878: break;
879: case AIEVEXPR:
880: b = outds6(b);
881: break;
882: }
883: break;
884: case AIDFNGRP:
885: while( b )
886: b = outds4(b);
887: break;
888: default:
889: lderror(2,0,NULL,"failure dumping an AIDFNxxx data structure\n");
890: }
891:
892: return( a->dfnscn.ainext );
893: }
894:
895:
896:
897: ACTITEM *
898: outds5(a)
899: ACTITEM *a;
900: {
901:
902: /*
903: * Output one AIADDSCN data structure
904: *
905: * Convert a "pointer to a string" to a "index to a string"
906: */
907:
908: a->addscn.aiinflnm = (char *) ((int) a->addscn.aiinflnm - (int) strbase);
909: a->addscn.aiscfile = (char *) ((int) a->addscn.aiscfile - (int) strbase);
910:
911: fwrite( a, 1, sizeof(ACTITEM), trnfdes );
912:
913: return( a->addscn.ainext );
914: }
915:
916:
917:
918: ACTITEM *
919: outds6(a)
920: ACTITEM *a;
921: {
922:
923: /*
924: * Output one AIEVEXPR data structure
925: *
926: * Convert a "pointer to a string" to a "index to a string"
927: */
928:
929: a->evexpr.aiinflnm = (char *) ((int) a->evexpr.aiinflnm - (int) strbase);
930:
931: fwrite( a, 1, sizeof(ACTITEM), trnfdes );
932:
933: outds7( a->evexpr.aiexptr );
934:
935: return( a->evexpr.ainext );
936: }
937:
938:
939:
940: outds7(e)
941: ENODE *e;
942: {
943:
944: /*
945: * Output one ENODE data structure
946: */
947:
948: switch( (unsigned) e->gnode.exop ) {
949: case INT:
950: case DOT:
951: fwrite( e, 1, sizeof(ENODE), trnfdes );
952: break;
953: case NAME:
954: fwrite( e, 1, sizeof(ENODE), trnfdes );
955: break;
956: default:
957: fwrite( e, 1, sizeof(ENODE), trnfdes );
958: if( e->gnode.exleft )
959: outds7(e->gnode.exleft);
960: if( e->gnode.exright )
961: outds7(e->gnode.exright);
962: }
963:
964: }
965:
966:
967:
968: TVASSIGN *
969: outds8(s)
970: TVASSIGN *s;
971: {
972:
973: /*
974: * Output one tv slot assignment (TVASSIGN) structure
975: */
976:
977: fwrite( s, sizeof(TVASSIGN), 1, trnfdes);
978: return( s->nxtslot );
979: }
980: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.