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