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