xref: /original-bsd/usr.bin/pascal/libpc/GETNAME.c (revision 6c57d260)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)GETNAME.c 1.4 05/07/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, namlim, datasize)
21 
22 	register struct iorec	*filep;
23 	char			*name;
24 	long			namlim;
25 	long			datasize;
26 {
27 	int		maxnamlen = namlim;
28 	struct iorec	*prev;
29 	struct iorec	*next;
30 	register int	cnt;
31 	struct iorec	locvar;
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) == 0) {
75 			/*
76 			 * have a previous buffer, close associated file
77 			 */
78 			if (filep->fblk > PREDEF) {
79 				fflush(filep->fbuf);
80 				setbuf(filep->fbuf, NULL);
81 			}
82 			fclose(filep->fbuf);
83 			if (ferror(filep->fbuf)) {
84 				ERROR(ECLOSE, filep->pfname);
85 				return;
86 			}
87 			/*
88 			 * renamed temporary files are discarded
89 			 */
90 			if ((filep->funit & TEMP) &&
91 			    (name != NULL) &&
92 			    (unlink(filep->pfname))) {
93 				ERROR(EREMOVE, filep->pfname);
94 				return;
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(ENAMESIZE, 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