xref: /csrg-svn/usr.bin/pascal/src/savenl.c (revision 6427)
15446Slinton /* Copyright (c) 1982 Regents of the University of California */
25446Slinton 
3*6427Speter static char sccsid[] = "@(#)savenl.c 1.4 04/01/82";
45446Slinton 
55446Slinton /*
65446Slinton  * savenl - routines for saving namelist and line number information
75446Slinton  *
85446Slinton  * This module contains the routines that make pi dump a namelist
95446Slinton  * at the end of the object file.  We do this by first creating
105446Slinton  * four temporary files in "startnlfile".  One temp file contains
115446Slinton  * the string table, one the symbol table, one the file name
125446Slinton  * information and one the line number information.
135446Slinton  *
145446Slinton  * Prior to generation of the code for a statement the "lineno"
155446Slinton  * routine is called to dump the line number and current object
165446Slinton  * address.  At the end of each block "savenl" is called to dump
175446Slinton  * the strings and symbol structures.
185446Slinton  *
195446Slinton  * At the end of execution "copynlfile" is called and it copies
205446Slinton  * the temp files onto the end of the obj file.
215446Slinton  *
225446Slinton  * In case of error, "removenlfile" is called to destroy the temp files.
235446Slinton  *
245446Slinton  * The only other changes to pi are in calling these routines from
255446Slinton  *
265446Slinton  * 	"main"		(main.c)
275446Slinton  *	"yymain"	(yymain.c)
285446Slinton  *	"funcend"	(fend.c)
295446Slinton  *	"yyget"		(yyget.c)
305446Slinton  *	"putline"	(stat.c)
315446Slinton  */
325446Slinton 
335446Slinton #include "whoami.h"
34*6427Speter #ifdef OBJ
35*6427Speter         /*
36*6427Speter 	 *	and the rest of the file
37*6427Speter 	 */
385446Slinton #include "0.h"
395655Slinton #include "objfmt.h"
405446Slinton 
415446Slinton #undef NIL
425446Slinton 
435446Slinton /*
445446Slinton  * pdx header files
455446Slinton  */
465446Slinton 
47*6427Speter #include "../pdx/defs.h"
48*6427Speter #include "../pdx/object.h"
49*6427Speter #include "../pdx/object/objsym.rep"
50*6427Speter #include "../pdx/mappings.h"
51*6427Speter #include "../pdx/mappings/filetab.h"
525446Slinton 
535446Slinton LOCAL char *symname = "/tmp/obj.symXXXX";
545446Slinton LOCAL char *strname = "/tmp/obj.strXXXX";
555446Slinton LOCAL char *filesname = "/tmp/obj.filesXXXX";
565446Slinton LOCAL char *linesname = "/tmp/obj.linesXXXX";
575446Slinton 
585446Slinton LOCAL FILE *symfp;
595446Slinton LOCAL FILE *strfp;
605446Slinton LOCAL FILE *filesfp;
615446Slinton LOCAL FILE *linesfp;
625446Slinton 
635655Slinton LOCAL long nlsize;
645655Slinton 
655446Slinton /*
665446Slinton  * create temporary files for the namelist info
675446Slinton  */
685446Slinton 
695446Slinton startnlfile()
705446Slinton {
715655Slinton 	nlsize = 0;
725446Slinton 	mktemp(symname);
735446Slinton 	mktemp(strname);
745446Slinton 	mktemp(filesname);
755446Slinton 	mktemp(linesname);
765446Slinton 	symfp = fopen(symname, "w");
775446Slinton 	strfp = fopen(strname, "w");
785446Slinton 	filesfp = fopen(filesname, "w");
795446Slinton 	linesfp = fopen(linesname, "w");
805446Slinton 	if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) {
815446Slinton 		fprintf(stderr, "can't create /tmp/obj");
825446Slinton 		pexit(NOSTART);
835446Slinton 	}
845446Slinton 	newfile(filename, 1);
855446Slinton }
865446Slinton 
875446Slinton /*
885446Slinton  * now copy the temp files back to obj; strings, symbols, file names, and lines
895446Slinton  *
905446Slinton  * There's some efficiency garbage here that uses straight system
915446Slinton  * calls rather than standard I/O library calls.
925446Slinton  */
935446Slinton 
945446Slinton copynlfile()
955446Slinton {
965446Slinton 	register int n;
975446Slinton 	int symfd, strfd, filesfd, linesfd;
985446Slinton 	char buff[BUFSIZ];
995446Slinton 
1005446Slinton 	fclose(symfp);
1015446Slinton 	fclose(strfp);
1025446Slinton 	fclose(filesfp);
1035446Slinton 	fclose(linesfp);
1045655Slinton 	if (!opt('g')) {
1055655Slinton 		removenlfile();
1065655Slinton 		return;
1075655Slinton 	}
1085446Slinton 	symfd = open(symname, 0);
1095446Slinton 	strfd = open(strname, 0);
1105446Slinton 	filesfd = open(filesname, 0);
1115446Slinton 	linesfd = open(linesname, 0);
1125446Slinton 	if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) {
1135446Slinton 		fprintf(stderr, "sync error on /tmp/obj");
1145446Slinton 		pexit(ERRS);
1155446Slinton 	}
1165446Slinton 	lseek(ofil, 0L, 2);
1175446Slinton 	write(ofil, &nlhdr, sizeof(nlhdr));
1185446Slinton 	n = read(strfd, buff, BUFSIZ - sizeof(nlhdr));
1195446Slinton 	write(ofil, buff, n);
1205446Slinton 	cat(strfd);
1215446Slinton 	cat(symfd);
1225446Slinton 	cat(filesfd);
1235446Slinton 	cat(linesfd);
1245446Slinton 	removenlfile();
1255446Slinton }
1265446Slinton 
1275446Slinton cat(fd)
1285446Slinton int fd;
1295446Slinton {
1305446Slinton 	register int n;
1315446Slinton 	char buff[BUFSIZ];
1325446Slinton 
1335446Slinton 	while ((n = read(fd, buff, BUFSIZ)) > 0) {
1345446Slinton 		write(ofil, buff, n);
1355446Slinton 	}
1365446Slinton 	close(fd);
1375446Slinton }
1385446Slinton 
1395446Slinton removenlfile()
1405446Slinton {
1415446Slinton 	unlink(symname);
1425446Slinton 	unlink(strname);
1435446Slinton 	unlink(filesname);
1445446Slinton 	unlink(linesname);
1455446Slinton }
1465446Slinton 
1475655Slinton nlhdrsize()
1485655Slinton {
1495655Slinton 	int r;
1505655Slinton 
1515655Slinton 	if (!opt('g')) {
1525655Slinton 		r = 0;
1535655Slinton 	} else {
1545655Slinton 		r = nlsize + sizeof(nlhdr);
1555655Slinton 	}
1565655Slinton 	return r;
1575655Slinton }
1585655Slinton 
1595446Slinton #define isblock(s)	(s->class == FUNC || s->class == PROC)
1605446Slinton #define isbuiltin(s)	((s->nl_block&037) == 0 && isblock(s))
1615446Slinton #define symno(p)	(p==NULL ? 0 : nloff(p))
1625446Slinton 
1635446Slinton struct nls {
1645446Slinton 	struct nl *nls_low;
1655446Slinton 	struct nl *nls_high;
1665446Slinton };
1675446Slinton 
1685446Slinton struct nl nl[], *nlp, ntab[], *nlact;
1695446Slinton 
1705446Slinton savenl(to, rout)
1715446Slinton struct nl *to;
1725446Slinton {
1735446Slinton 	register struct nl *p;
1745446Slinton 	register OBJSYM *s;
1755446Slinton 	OBJSYM tmpsym;
1765446Slinton 	struct nls *nlsp;
1775446Slinton 	int v;
1785446Slinton 
1795446Slinton 	if (to != NIL) {
1805446Slinton 		putblock(rout);
1815446Slinton 	} else {
1825446Slinton 		putblock("main program");
1835446Slinton 	}
1845446Slinton 	nlsp = nlact;
1855446Slinton 	s = &tmpsym;
1865446Slinton 	for (p = nlp; p != to;) {
1875446Slinton 		if (p == nlsp->nls_low) {
1885446Slinton 			if (nlsp == &ntab[0])
1895446Slinton 				break;
1905446Slinton 			nlsp--;
1915446Slinton 			p = nlsp->nls_high;
1925446Slinton 		}
1935446Slinton 		p--;
1945446Slinton 		if (isbuiltin(p) || symno(p) == 0) {
1955446Slinton 			continue;
1965446Slinton 		}
1975446Slinton 		nlhdr.nsyms++;
1985655Slinton 		nlsize += sizeof(OBJSYM) + sizeof(int);
1995446Slinton 		putw(symno(p), symfp);
2005446Slinton 		if (p->symbol != NULL) {
2015446Slinton 			s->strindex = nlhdr.stringsize;
2025446Slinton 			putstring(p->symbol);
2035446Slinton 		} else {
2045446Slinton 			s->strindex = 0;
2055446Slinton 		}
2065446Slinton 		s->oclass = p->class;
2075446Slinton 		s->oblkno = (p->nl_block&037);
2085446Slinton 		s->typno = symno(p->type);
2095446Slinton 		s->chno = symno(p->chain);
2105446Slinton 		s->osymvalue.orangev.lower = p->range[0];
2115446Slinton 		s->osymvalue.orangev.upper = p->range[1];
2125446Slinton 		if (isblock(p)) {
2135446Slinton 			s->osymvalue.ofuncv.codeloc = p->entloc;
2145446Slinton 		} else if (p->class == RECORD || p->class == VARNT) {
2155446Slinton 			s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]);
2165446Slinton 			s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]);
2175446Slinton 		}
2185446Slinton 		fwrite(s, sizeof(*s), 1, symfp);
2195446Slinton 	}
2205446Slinton }
2215446Slinton 
2225446Slinton /*
2235446Slinton  * Dump a line number and the current object location counter.
2245446Slinton  *
2255446Slinton  * To save space the difference from the previous line number and offset
2265446Slinton  * (one byte each) is dumped.
2275446Slinton  */
2285446Slinton 
2295446Slinton LOCAL int oline = 0;
2305655Slinton LOCAL int olc = HEADER_BYTES;
2315446Slinton 
2325446Slinton lineno(line)
2335446Slinton int line;
2345446Slinton {
2355755Slinton 	OBJLINE info;
2365755Slinton 
2375446Slinton 	if (line != oline) {
2385446Slinton 		nlhdr.nlines++;
2395755Slinton 		nlsize += sizeof(OBJLINE);
2405755Slinton 		info.separate.lineincr = line - oline;
2415755Slinton 		info.separate.addrincr = lc - olc;
2425755Slinton 		putw(info.together, linesfp);
2435446Slinton 		oline = line;
2445446Slinton 		olc = lc;
2455446Slinton 	}
2465446Slinton }
2475446Slinton 
2485446Slinton /*
2495446Slinton  * put out a file name entry, including:
2505446Slinton  *
2515446Slinton  *	the current line number for the new file
2525446Slinton  *	the current location counter
2535446Slinton  *	the string table address of the file name
2545446Slinton  *	an index into the current line number information
2555446Slinton  */
2565446Slinton 
2575446Slinton newfile(s, line)
2585446Slinton char *s;
2595446Slinton int line;
2605446Slinton {
2615446Slinton 	FILETAB ft;
2625446Slinton 
2635446Slinton 	nlhdr.nfiles++;
2645655Slinton 	nlsize += sizeof(FILETAB);
2655446Slinton 	ft.line = line;
2665446Slinton 	oline = line;
2675446Slinton 	if (lc == 0) {
2685446Slinton 		ft.addr = 0;
2695446Slinton 	} else {
2705655Slinton 		ft.addr = lc - HEADER_BYTES;
2715446Slinton 	}
2725446Slinton 	ft.filename = (char *) nlhdr.stringsize;
2735446Slinton 	putstring(s);
2745446Slinton 	ft.lineindex = nlhdr.nlines;
2755446Slinton 	fwrite(&ft, sizeof(ft), 1, filesfp);
2765446Slinton }
2775446Slinton 
2785446Slinton /*
2795446Slinton  * put out a dummy symbol at the beginning of a block
2805446Slinton  */
2815446Slinton 
2825446Slinton LOCAL putblock(s)
2835446Slinton char *s;
2845446Slinton {
2855446Slinton 	register int i;
2865446Slinton 	static OBJSYM zerosym;
2875446Slinton 
2885446Slinton 	nlhdr.nsyms++;
2895655Slinton 	nlsize += sizeof(OBJSYM) + sizeof(int);
2905446Slinton 	putw(0, symfp);
2915446Slinton 	zerosym.strindex = nlhdr.stringsize;
2925446Slinton 	putstring(s);
2935446Slinton 	fwrite(&zerosym, sizeof(zerosym), 1, symfp);
2945446Slinton }
2955446Slinton 
2965446Slinton /*
2975446Slinton  * put out a string to the string table file
2985446Slinton  */
2995446Slinton 
3005446Slinton LOCAL putstring(s)
3015446Slinton char *s;
3025446Slinton {
3035446Slinton 	register char *p;
3045446Slinton 
3055655Slinton 	for (p = s; *p != '\0'; p++) {
3065446Slinton 		putc(*p, strfp);
3075655Slinton 	}
3085446Slinton 	nlhdr.stringsize += (p - s + 1);
3095655Slinton 	nlsize += (p - s + 1);
3105446Slinton 	putc('\0', strfp);
3115446Slinton }
312*6427Speter #endif OBJ
313