xref: /original-bsd/usr.bin/pascal/libpc/GETNAME.c (revision bac5051c)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)GETNAME.c 1.2 01/10/81";
4 
5 #include "h00vars.h"
6 #include "h01errs.h"
7 
8 /*
9  * GETNAME - activate a file
10  *
11  * takes a name, name length, element size, and variable
12  * level and returns a pointer to a file structure.
13  *
14  * a new file structure is initialized if necessary.
15  * temporary names are generated, and given
16  * names are blank trimmed.
17  */
18 
19 struct iorec *
20 GETNAME(filep, name, maxnamlen, datasize)
21 
22 	register struct iorec	*filep;
23 	char			*name;
24 	int			maxnamlen;
25 	int			datasize;
26 {
27 	struct iorec	*prev;
28 	struct iorec	*next;
29 	register int	cnt;
30 	struct iorec	locvar;
31 	extern char	*mktemp();
32 
33 	if (filep->fblk >= MAXFILES || _actfile[filep->fblk] != filep) {
34 		/*
35 		 * initialize a new filerecord
36 		 */
37 		filep->funit = 0;
38 		if (datasize == 0) {
39 			filep->funit |= FTEXT;
40 			datasize = 1;
41 		}
42 		filep->fsize = datasize;
43 		filep->fbuf = 0;
44 		filep->lcount = 0;
45 		filep->llimit = 0x7fffffff;
46 		filep->fileptr = &filep->window[0];
47 		/*
48 		 * check to see if file is global, or allocated in
49 		 * the stack by checking its address against the
50 		 * address of one of our routine's local variables.
51 		 */
52 		if (filep < &locvar)
53 			filep->flev = GLVL;
54 		else
55 			filep->flev = filep;
56 		do {
57 			if (++_filefre == MAXFILES)
58 				_filefre = PREDEF + 1;
59 		} while (_actfile[_filefre] != FILNIL);
60 		filep->fblk = _filefre;
61 		_actfile[_filefre] = filep;
62 		/*
63 		 * link the newrecord into the file chain
64 		 */
65 		prev = (struct iorec *)&_fchain;
66 		next = _fchain.fchain;
67 		while (filep->flev > next->flev) {
68 			prev = next;
69 			next = next->fchain;
70 		}
71 		filep->fchain = next;
72 		prev->fchain = filep;
73 	} else {
74 		if (filep->funit & FDEF) {
75 			filep->funit &= (TEMP | FTEXT);
76 		} else {
77 			/*
78 			 * have a previous buffer, close associated file
79 			 */
80 			if (filep->fblk > PREDEF) {
81 				fflush(filep->fbuf);
82 				setbuf(filep->fbuf, NULL);
83 			}
84 			fclose(filep->fbuf);
85 			if (ferror(filep->fbuf)) {
86 				ERROR(ECLOSE, filep->pfname);
87 				return;
88 			}
89 			/*
90 			 * renamed temporary files are discarded
91 			 */
92 			if ((filep->funit & TEMP) &&
93 			    (name != NULL) &&
94 			    (unlink(filep->pfname))) {
95 				ERROR(EREMOVE, filep->pfname);
96 				return;
97 			}
98 			filep->funit &= (TEMP | FTEXT);
99 		}
100 	}
101 	/*
102 	 * get the filename associated with the buffer
103 	 */
104 	if (name == NULL) {
105 		if (*filep->fname != NULL) {
106 			return(filep);
107 		}
108 		/*
109 		 * no name given and no previous name, so generate
110 		 * a new one of the form tmp.xxxxxx
111 		 */
112 		filep->funit |= TEMP;
113 		name = mktemp("tmp.XXXXXX");
114 		maxnamlen = 10;
115 	} else {
116 		/*
117 		 * trim trailing blanks, and insure that the name
118 		 * will fit into the file structure
119 		 */
120 		for (cnt = 0; cnt < maxnamlen; cnt++)
121 			if (name[cnt] == '\0' || name[cnt] == ' ')
122 				break;
123 		if (cnt >= NAMSIZ) {
124 			ERROR(ENAMESIZE, name);
125 			return;
126 		}
127 		maxnamlen = cnt;
128 		filep->funit &= ~TEMP;
129 	}
130 	/*
131 	 * put the new name into the structure
132 	 */
133 	for (cnt = 0; cnt < maxnamlen; cnt++)
134 		filep->fname[cnt] = name[cnt];
135 	filep->fname[cnt] = '\0';
136 	filep->pfname = &filep->fname[0];
137 	return(filep);
138 }
139