xref: /csrg-svn/usr.bin/pascal/src/savenl.c (revision 36536)
122189Sdist /*
222189Sdist  * Copyright (c) 1980 Regents of the University of California.
322189Sdist  * All rights reserved.  The Berkeley software License Agreement
422189Sdist  * specifies the terms and conditions for redistribution.
522189Sdist  */
65446Slinton 
714742Sthien #ifndef lint
8*36536Smckusick static char sccsid[] = "@(#)savenl.c	5.2 (Berkeley) 01/09/89";
922189Sdist #endif not lint
105446Slinton 
115446Slinton /*
125446Slinton  * savenl - routines for saving namelist and line number information
135446Slinton  *
145446Slinton  * This module contains the routines that make pi dump a namelist
155446Slinton  * at the end of the object file.  We do this by first creating
165446Slinton  * four temporary files in "startnlfile".  One temp file contains
175446Slinton  * the string table, one the symbol table, one the file name
185446Slinton  * information and one the line number information.
195446Slinton  *
205446Slinton  * Prior to generation of the code for a statement the "lineno"
215446Slinton  * routine is called to dump the line number and current object
225446Slinton  * address.  At the end of each block "savenl" is called to dump
235446Slinton  * the strings and symbol structures.
245446Slinton  *
255446Slinton  * At the end of execution "copynlfile" is called and it copies
265446Slinton  * the temp files onto the end of the obj file.
275446Slinton  *
285446Slinton  * In case of error, "removenlfile" is called to destroy the temp files.
295446Slinton  *
305446Slinton  * The only other changes to pi are in calling these routines from
315446Slinton  *
325446Slinton  * 	"main"		(main.c)
335446Slinton  *	"yymain"	(yymain.c)
345446Slinton  *	"funcend"	(fend.c)
355446Slinton  *	"yyget"		(yyget.c)
365446Slinton  *	"putline"	(stat.c)
375446Slinton  */
385446Slinton 
395446Slinton #include "whoami.h"
406427Speter #ifdef OBJ
416427Speter         /*
426427Speter 	 *	and the rest of the file
436427Speter 	 */
445446Slinton #include "0.h"
455655Slinton #include "objfmt.h"
465446Slinton 
475446Slinton #undef NIL
485446Slinton 
495446Slinton /*
505446Slinton  * pdx header files
515446Slinton  */
525446Slinton 
536427Speter #include "../pdx/defs.h"
546427Speter #include "../pdx/object.h"
556427Speter #include "../pdx/object/objsym.rep"
566427Speter #include "../pdx/mappings.h"
576427Speter #include "../pdx/mappings/filetab.h"
585446Slinton 
59*36536Smckusick LOCAL char symname[] = "/tmp/obj.symXXXXXX";
60*36536Smckusick LOCAL char strname[] = "/tmp/obj.strXXXXXX";
61*36536Smckusick LOCAL char filesname[] = "/tmp/obj.filesXXXXXX";
62*36536Smckusick LOCAL char linesname[] = "/tmp/obj.linesXXXXXX";
635446Slinton 
645446Slinton LOCAL FILE *symfp;
655446Slinton LOCAL FILE *strfp;
665446Slinton LOCAL FILE *filesfp;
675446Slinton LOCAL FILE *linesfp;
685446Slinton 
695655Slinton LOCAL long nlsize;
705655Slinton 
7114742Sthien extern FILE *fopen();
7214742Sthien 
73*36536Smckusick LOCAL putblock();
74*36536Smckusick LOCAL putstring();
75*36536Smckusick 
765446Slinton /*
775446Slinton  * create temporary files for the namelist info
785446Slinton  */
795446Slinton 
805446Slinton startnlfile()
815446Slinton {
825655Slinton 	nlsize = 0;
8314742Sthien 	(void) mktemp(symname);
8414742Sthien 	(void) mktemp(strname);
8514742Sthien 	(void) mktemp(filesname);
8614742Sthien 	(void) mktemp(linesname);
875446Slinton 	symfp = fopen(symname, "w");
885446Slinton 	strfp = fopen(strname, "w");
895446Slinton 	filesfp = fopen(filesname, "w");
905446Slinton 	linesfp = fopen(linesname, "w");
915446Slinton 	if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) {
925446Slinton 		fprintf(stderr, "can't create /tmp/obj");
935446Slinton 		pexit(NOSTART);
945446Slinton 	}
955446Slinton 	newfile(filename, 1);
965446Slinton }
975446Slinton 
985446Slinton /*
995446Slinton  * now copy the temp files back to obj; strings, symbols, file names, and lines
1005446Slinton  *
1015446Slinton  * There's some efficiency garbage here that uses straight system
1025446Slinton  * calls rather than standard I/O library calls.
1035446Slinton  */
1045446Slinton 
1055446Slinton copynlfile()
1065446Slinton {
1075446Slinton 	register int n;
10814742Sthien 	extern long lseek();
1095446Slinton 	int symfd, strfd, filesfd, linesfd;
1105446Slinton 	char buff[BUFSIZ];
1115446Slinton 
11214742Sthien 	(void) fclose((FILE *) symfp);
11314742Sthien 	(void) fclose((FILE *) strfp);
11414742Sthien 	(void) fclose((FILE *) filesfp);
11514742Sthien 	(void) fclose((FILE *) linesfp);
1165655Slinton 	if (!opt('g')) {
1175655Slinton 		removenlfile();
1185655Slinton 		return;
1195655Slinton 	}
1205446Slinton 	symfd = open(symname, 0);
1215446Slinton 	strfd = open(strname, 0);
1225446Slinton 	filesfd = open(filesname, 0);
1235446Slinton 	linesfd = open(linesname, 0);
1245446Slinton 	if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) {
1255446Slinton 		fprintf(stderr, "sync error on /tmp/obj");
1265446Slinton 		pexit(ERRS);
1275446Slinton 	}
12814742Sthien 	(void) lseek(ofil, 0L, 2);
12914742Sthien 	write(ofil, (char *) (&nlhdr), sizeof(nlhdr));
1305446Slinton 	n = read(strfd, buff, BUFSIZ - sizeof(nlhdr));
1315446Slinton 	write(ofil, buff, n);
1325446Slinton 	cat(strfd);
1335446Slinton 	cat(symfd);
1345446Slinton 	cat(filesfd);
1355446Slinton 	cat(linesfd);
1365446Slinton 	removenlfile();
1375446Slinton }
1385446Slinton 
1395446Slinton cat(fd)
1405446Slinton int fd;
1415446Slinton {
1425446Slinton 	register int n;
1435446Slinton 	char buff[BUFSIZ];
1445446Slinton 
1455446Slinton 	while ((n = read(fd, buff, BUFSIZ)) > 0) {
1465446Slinton 		write(ofil, buff, n);
1475446Slinton 	}
14814742Sthien 	(void) close(fd);
1495446Slinton }
1505446Slinton 
1515446Slinton removenlfile()
1525446Slinton {
1535446Slinton 	unlink(symname);
1545446Slinton 	unlink(strname);
1555446Slinton 	unlink(filesname);
1565446Slinton 	unlink(linesname);
1575446Slinton }
1585446Slinton 
1595655Slinton nlhdrsize()
1605655Slinton {
1615655Slinton 	int r;
1625655Slinton 
1635655Slinton 	if (!opt('g')) {
1645655Slinton 		r = 0;
1655655Slinton 	} else {
1665655Slinton 		r = nlsize + sizeof(nlhdr);
1675655Slinton 	}
1685655Slinton 	return r;
1695655Slinton }
1705655Slinton 
1715446Slinton #define isblock(s)	(s->class == FUNC || s->class == PROC)
1725446Slinton #define isbuiltin(s)	((s->nl_block&037) == 0 && isblock(s))
1735446Slinton #define symno(p)	(p==NULL ? 0 : nloff(p))
1745446Slinton 
1755446Slinton struct nls {
1765446Slinton 	struct nl *nls_low;
1775446Slinton 	struct nl *nls_high;
1785446Slinton };
1795446Slinton 
1805446Slinton struct nl nl[], *nlp, ntab[], *nlact;
1815446Slinton 
18214742Sthien /*VARARGS*/
1835446Slinton savenl(to, rout)
1845446Slinton struct nl *to;
1855446Slinton {
1865446Slinton 	register struct nl *p;
1875446Slinton 	register OBJSYM *s;
1885446Slinton 	OBJSYM tmpsym;
1895446Slinton 	struct nls *nlsp;
1905446Slinton 
1915446Slinton 	if (to != NIL) {
19214742Sthien 		putblock((char *) rout);
1935446Slinton 	} else {
1945446Slinton 		putblock("main program");
1955446Slinton 	}
19614742Sthien 	nlsp = (struct nls *) nlact;
1975446Slinton 	s = &tmpsym;
1985446Slinton 	for (p = nlp; p != to;) {
1995446Slinton 		if (p == nlsp->nls_low) {
20014742Sthien 			if (nlsp == ((struct nls *) &ntab[0]))
2015446Slinton 				break;
2025446Slinton 			nlsp--;
2035446Slinton 			p = nlsp->nls_high;
2045446Slinton 		}
2055446Slinton 		p--;
2065446Slinton 		if (isbuiltin(p) || symno(p) == 0) {
2075446Slinton 			continue;
2085446Slinton 		}
2095446Slinton 		nlhdr.nsyms++;
2105655Slinton 		nlsize += sizeof(OBJSYM) + sizeof(int);
21114742Sthien 		(void) putw(symno(p), symfp);
2125446Slinton 		if (p->symbol != NULL) {
2135446Slinton 			s->strindex = nlhdr.stringsize;
2145446Slinton 			putstring(p->symbol);
2155446Slinton 		} else {
2165446Slinton 			s->strindex = 0;
2175446Slinton 		}
2185446Slinton 		s->oclass = p->class;
2195446Slinton 		s->oblkno = (p->nl_block&037);
2205446Slinton 		s->typno = symno(p->type);
2215446Slinton 		s->chno = symno(p->chain);
2225446Slinton 		s->osymvalue.orangev.lower = p->range[0];
2235446Slinton 		s->osymvalue.orangev.upper = p->range[1];
2245446Slinton 		if (isblock(p)) {
2257919Smckusick 			s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC];
2265446Slinton 		} else if (p->class == RECORD || p->class == VARNT) {
2275446Slinton 			s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]);
2285446Slinton 			s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]);
2295446Slinton 		}
23014742Sthien 		fwrite((char *) s, sizeof(*s), 1, symfp);
2315446Slinton 	}
2325446Slinton }
2335446Slinton 
2345446Slinton /*
2355446Slinton  * Dump a line number and the current object location counter.
2365446Slinton  *
2375446Slinton  * To save space the difference from the previous line number and offset
2385446Slinton  * (one byte each) is dumped.
2395446Slinton  */
2405446Slinton 
2415446Slinton LOCAL int oline = 0;
2425655Slinton LOCAL int olc = HEADER_BYTES;
2435446Slinton 
2445446Slinton lineno(line)
2455446Slinton int line;
2465446Slinton {
2475755Slinton 	OBJLINE info;
2485755Slinton 
2495446Slinton 	if (line != oline) {
2505446Slinton 		nlhdr.nlines++;
2515755Slinton 		nlsize += sizeof(OBJLINE);
2525755Slinton 		info.separate.lineincr = line - oline;
25314742Sthien 		info.separate.addrincr = ((unsigned short) (lc - olc));
25414742Sthien 		(void) putw((int) info.together, linesfp);
2555446Slinton 		oline = line;
25614742Sthien 		olc = (int) lc;
2575446Slinton 	}
2585446Slinton }
2595446Slinton 
2605446Slinton /*
2615446Slinton  * put out a file name entry, including:
2625446Slinton  *
2635446Slinton  *	the current line number for the new file
2645446Slinton  *	the current location counter
2655446Slinton  *	the string table address of the file name
2665446Slinton  *	an index into the current line number information
2675446Slinton  */
2685446Slinton 
2695446Slinton newfile(s, line)
2705446Slinton char *s;
2715446Slinton int line;
2725446Slinton {
2735446Slinton 	FILETAB ft;
2745446Slinton 
2755446Slinton 	nlhdr.nfiles++;
2765655Slinton 	nlsize += sizeof(FILETAB);
2775446Slinton 	ft.line = line;
2785446Slinton 	oline = line;
2795446Slinton 	if (lc == 0) {
2805446Slinton 		ft.addr = 0;
2815446Slinton 	} else {
28214742Sthien 		ft.addr = ((LINENO) lc - HEADER_BYTES );
2835446Slinton 	}
2845446Slinton 	ft.filename = (char *) nlhdr.stringsize;
2855446Slinton 	putstring(s);
2865446Slinton 	ft.lineindex = nlhdr.nlines;
28714742Sthien 	fwrite((char *) (&ft), sizeof(ft), 1, filesfp);
2885446Slinton }
2895446Slinton 
2905446Slinton /*
2915446Slinton  * put out a dummy symbol at the beginning of a block
2925446Slinton  */
2935446Slinton 
2945446Slinton LOCAL putblock(s)
2955446Slinton char *s;
2965446Slinton {
2975446Slinton 	static OBJSYM zerosym;
2985446Slinton 
2995446Slinton 	nlhdr.nsyms++;
3005655Slinton 	nlsize += sizeof(OBJSYM) + sizeof(int);
30114742Sthien 	(void) putw(0, symfp);
3025446Slinton 	zerosym.strindex = nlhdr.stringsize;
3035446Slinton 	putstring(s);
30414742Sthien 	fwrite((char *) (&zerosym), sizeof(zerosym), 1, symfp);
3055446Slinton }
3065446Slinton 
3075446Slinton /*
3085446Slinton  * put out a string to the string table file
3095446Slinton  */
3105446Slinton 
3115446Slinton LOCAL putstring(s)
3125446Slinton char *s;
3135446Slinton {
3145446Slinton 	register char *p;
3155446Slinton 
3165655Slinton 	for (p = s; *p != '\0'; p++) {
3175446Slinton 		putc(*p, strfp);
3185655Slinton 	}
3195446Slinton 	nlhdr.stringsize += (p - s + 1);
3205655Slinton 	nlsize += (p - s + 1);
3215446Slinton 	putc('\0', strfp);
3225446Slinton }
3236427Speter #endif OBJ
324