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