xref: /freebsd/contrib/tcsh/gethost.c (revision f0adf7f5cdd241db2f2c817683191a6ef64a4e95)
1 /* $Header: /src/pub/tcsh/gethost.c,v 1.9 2002/12/04 12:30:55 christos Exp $ */
2 /*
3  * gethost.c: Create version file from prototype
4  */
5 /*-
6  * Copyright (c) 1980, 1991 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 #include "sh.h"
34 
35 RCSID("$Id: gethost.c,v 1.9 2002/12/04 12:30:55 christos Exp $")
36 
37 #ifdef SCO
38 # define perror __perror
39 # define rename __rename
40 # define getopt __getopt
41 # define system __system
42 #endif
43 #include <stdio.h>
44 #ifdef SCO
45 # undef perror
46 # undef rename
47 # undef getopt
48 # undef system
49 #endif
50 
51 #include <ctype.h>
52 
53 /* Some people don't bother to declare these */
54 #if defined(SUNOS4) || defined(ibm032)
55 extern int fprintf();
56 extern int fclose();
57 #endif /* SUNOS4 || ibm032 */
58 
59 #define ISSPACE(p)	(isspace((unsigned char) (p)) && (p) != '\n')
60 
61 /*
62  * We cannot do that, because some compilers like #line and others
63  * like # <lineno>
64  * #define LINEDIRECTIVE
65  */
66 
67 static const char *keyword[] =
68 {
69     "vendor",
70 #define T_VENDOR	0
71     "hosttype",
72 #define T_HOSTTYPE	1
73     "machtype",
74 #define T_MACHTYPE	2
75     "ostype",
76 #define T_OSTYPE	3
77     "newdef",
78 #define T_NEWDEF	4
79     "enddef",
80 #define T_ENDDEF	5
81     "newcode",
82 #define T_NEWCODE	6
83     "endcode",
84 #define T_ENDCODE	7
85     "comment",
86 #define T_COMMENT	8
87     "macro",
88 #define T_MACRO		9
89     NULL
90 #define T_NONE		10
91 };
92 
93 #define S_DISCARD	0
94 #define S_COMMENT	1
95 #define S_CODE		2
96 #define S_KEYWORD	3
97 
98 static int findtoken __P((char *));
99 static char *gettoken __P((char **, char  *));
100 
101 int main __P((int, char *[]));
102 
103 /* findtoken():
104  *	Return the token number of the given token
105  */
106 static int
107 findtoken(ptr)
108     char *ptr;
109 {
110     int i;
111 
112     if (ptr == NULL || *ptr == '\0')
113 	return T_NONE;
114 
115     for (i = 0; keyword[i] != NULL; i++)
116 	if (strcmp(keyword[i], ptr) == 0)
117 	    return i;
118 
119     return T_NONE;
120 }
121 
122 
123 /* gettoken():
124  *	Get : delimited token and remove leading/trailing blanks/newlines
125  */
126 static char *
127 gettoken(pptr, token)
128     char **pptr;
129     char  *token;
130 {
131     char *ptr = *pptr;
132     char *tok = token;
133 
134     for (; *ptr && ISSPACE(*ptr); ptr++)
135 	continue;
136 
137     for (; *ptr && *ptr != ':'; *tok++ = *ptr++)
138 	continue;
139 
140     if (*ptr == ':')
141 	ptr++;
142     else
143 	tok--;
144 
145     for (tok--; tok >= token && *tok && ISSPACE(*tok); tok--)
146 	continue;
147 
148     *++tok = '\0';
149 
150     *pptr = ptr;
151     return token;
152 }
153 
154 
155 int
156 main(argc, argv)
157     int argc;
158     char *argv[];
159 {
160     char line[INBUFSIZE];
161     char *pname;
162     const char *fname = "stdin";
163     char *ptr, *tok;
164     char defs[INBUFSIZE];
165     char stmt[INBUFSIZE];
166     FILE *fp = stdin;
167     int lineno = 0;
168     int inprocess = 0;
169     int token, state;
170     int errs = 0;
171 
172     if ((pname = strrchr(argv[0], '/')) == NULL)
173 	pname = argv[0];
174     else
175 	pname++;
176 
177     if (argc > 2) {
178 	(void) fprintf(stderr, "Usage: %s [<filename>]\n", pname);
179 	return 1;
180     }
181 
182     if (argc == 2)
183 	if ((fp = fopen(fname = argv[1], "r")) == NULL) {
184 	    (void) fprintf(stderr, "%s: Cannot open `%s'\n", pname, fname);
185 	    return 1;
186 	}
187 
188     state = S_DISCARD;
189 
190     while ((ptr = fgets(line, sizeof(line), fp)) != NULL) {
191 	lineno++;
192 	switch (token = findtoken(gettoken(&ptr, defs))) {
193 	case T_NEWCODE:
194 	    state = S_CODE;
195 	    break;
196 
197 	case T_ENDCODE:
198 	    state = S_DISCARD;
199 	    break;
200 
201 	case T_COMMENT:
202 	    state = S_COMMENT;
203 	    break;
204 
205 	case T_NEWDEF:
206 	    state = S_KEYWORD;
207 	    break;
208 
209 	case T_ENDDEF:
210 	    state = S_DISCARD;
211 	    break;
212 
213 	case T_VENDOR:
214 	    state = S_KEYWORD;
215 	    break;
216 
217 	case T_HOSTTYPE:
218 	    state = S_KEYWORD;
219 	    break;
220 
221 	case T_MACHTYPE:
222 	    state = S_KEYWORD;
223 	    break;
224 
225 	case T_OSTYPE:
226 	    state = S_KEYWORD;
227 	    break;
228 
229 	case T_MACRO:
230 	    if (gettoken(&ptr, defs) == NULL) {
231 		(void) fprintf(stderr, "%s: \"%s\", %d: Missing macro name\n",
232 			       pname, fname, lineno);
233 		break;
234 	    }
235 	    if (gettoken(&ptr, stmt) == NULL) {
236 		(void) fprintf(stderr, "%s: \"%s\", %d: Missing macro body\n",
237 			       pname, fname, lineno);
238 		break;
239 	    }
240 	    (void) fprintf(stdout, "\n#if %s\n# define %s\n#endif\n\n", stmt,
241 			   defs);
242 	    break;
243 
244 	case T_NONE:
245 	    if (state != S_CODE && defs && *defs != '\0') {
246 		(void) fprintf(stderr, "%s: \"%s\", %d: Discarded\n",
247 			       pname, fname, lineno);
248 		if (++errs == 30) {
249 		    (void) fprintf(stderr, "%s: Too many errors\n", pname);
250 		    return 1;
251 		}
252 		break;
253 	    }
254 	    (void) fprintf(stdout, "%s", line);
255 	    break;
256 
257 	default:
258 	    (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected token\n",
259 			   pname, fname, lineno);
260 	    return 1;
261 	}
262 
263 	switch (state) {
264 	case S_DISCARD:
265 	    if (inprocess) {
266 		inprocess = 0;
267 		(void) fprintf(stdout, "#endif\n");
268 	    }
269 	    break;
270 
271 	case S_KEYWORD:
272 	    tok = gettoken(&ptr, defs);
273 	    if (token == T_NEWDEF) {
274 		if (inprocess) {
275 		    (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
276 				   pname, fname, lineno);
277 		    return 1;
278 		}
279 		if (tok == NULL) {
280 		    (void) fprintf(stderr, "%s: \"%s\", %d: No defs\n",
281 				   pname, fname, lineno);
282 		    return 1;
283 		}
284 		(void) fprintf(stdout, "\n\n");
285 #ifdef LINEDIRECTIVE
286 		(void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
287 #endif /* LINEDIRECTIVE */
288 		(void) fprintf(stdout, "#if %s\n", defs);
289 		inprocess = 1;
290 	    }
291 	    else {
292 		if (tok && *tok)
293 		    (void) fprintf(stdout, "# if (%s) && !defined(_%s_)\n",
294 				   defs, keyword[token]);
295 		else
296 		    (void) fprintf(stdout, "# if !defined(_%s_)\n",
297 				   keyword[token]);
298 
299 		if (gettoken(&ptr, stmt) == NULL) {
300 		    (void) fprintf(stderr, "%s: \"%s\", %d: No statement\n",
301 				   pname, fname, lineno);
302 		    return 1;
303 		}
304 		(void) fprintf(stdout, "# define _%s_\n", keyword[token]);
305 		(void) fprintf(stdout, "    %s = %s;\n", keyword[token], stmt);
306 		(void) fprintf(stdout, "# endif\n");
307 	    }
308 	    break;
309 
310 	case S_COMMENT:
311 	    if (gettoken(&ptr, defs))
312 		(void) fprintf(stdout, "    /* %s */\n", defs);
313 	    break;
314 
315 	case S_CODE:
316 	    if (token == T_NEWCODE) {
317 #ifdef LINEDIRECTIVE
318 		(void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
319 #endif /* LINEDIRECTIVE */
320 	    }
321 	    break;
322 
323 	default:
324 	    (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected state\n",
325 			   pname, fname, lineno);
326 	    return 1;
327 	}
328     }
329 
330     if (inprocess) {
331 	(void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
332 		       pname, fname, lineno);
333 	return 1;
334     }
335 
336     if (fp != stdin)
337 	(void) fclose(fp);
338 
339     return 0;
340 }
341