Add note about reboot before 'make upgrade' step.
[dragonfly.git] / contrib / tcsh-6 / gethost.c
blob1102445857f5d8de1f96383c2c59977dd0531c50
1 /* $Header: /p/tcsh/cvsroot/tcsh/gethost.c,v 1.15 2012/01/15 17:14:54 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.
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.
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.
33 #include "sh.h"
35 RCSID("$tcsh: gethost.c,v 1.15 2012/01/15 17:14:54 christos Exp $")
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
51 #include <ctype.h>
53 #define ISSPACE(p) (isspace((unsigned char) (p)) && (p) != '\n')
55 /*
56 * We cannot do that, because some compilers like #line and others
57 * like # <lineno>
58 * #define LINEDIRECTIVE
61 static const char *keyword[] =
63 "vendor",
64 #define T_VENDOR 0
65 "hosttype",
66 #define T_HOSTTYPE 1
67 "machtype",
68 #define T_MACHTYPE 2
69 "ostype",
70 #define T_OSTYPE 3
71 "newdef",
72 #define T_NEWDEF 4
73 "enddef",
74 #define T_ENDDEF 5
75 "newcode",
76 #define T_NEWCODE 6
77 "endcode",
78 #define T_ENDCODE 7
79 "comment",
80 #define T_COMMENT 8
81 "macro",
82 #define T_MACRO 9
83 NULL
84 #define T_NONE 10
87 #define S_DISCARD 0
88 #define S_COMMENT 1
89 #define S_CODE 2
90 #define S_KEYWORD 3
92 static int findtoken (char *);
93 static char *gettoken (char **, char *);
94 static char *pname;
96 int main (int, char *[]);
98 /* findtoken():
99 * Return the token number of the given token
101 static int
102 findtoken(char *ptr)
104 int i;
106 if (ptr == NULL || *ptr == '\0')
107 return T_NONE;
109 for (i = 0; keyword[i] != NULL; i++)
110 if (strcmp(keyword[i], ptr) == 0)
111 return i;
113 return T_NONE;
117 /* gettoken():
118 * Get : delimited token and remove leading/trailing blanks/newlines
120 static char *
121 gettoken(char **pptr, char *token)
123 char *ptr = *pptr;
124 char *tok = token;
126 for (; *ptr && ISSPACE(*ptr); ptr++)
127 continue;
129 for (; *ptr && *ptr != ':'; *tok++ = *ptr++)
130 continue;
132 if (*ptr == ':')
133 ptr++;
134 else
135 tok--;
137 for (tok--; tok >= token && *tok && ISSPACE(*tok); tok--)
138 continue;
140 *++tok = '\0';
142 *pptr = ptr;
143 return token;
146 static char *
147 cat(const char *a, const char *b, size_t len)
149 size_t l;
150 char *r;
152 if (len == 0)
153 len = strlen(b);
154 l = strlen(a) + len + 1;
155 if ((r = malloc(l)) == NULL)
156 abort();
157 snprintf(r, l, "%s%.*s", a, (int)len, b);
158 return r;
161 static const char *
162 explode(const char *defs)
164 static const char def[] = "defined("; /* ) */
165 static char *buf;
166 size_t len;
167 const char *ptr, *bptr, *eptr = NULL, *name;
169 if (strstr(defs, "#machine(" /* ) */))
170 return defs;
172 free(buf);
173 buf = strdup("("); /* ) */
174 for (ptr = defs; (bptr = strstr(ptr, def)) != NULL; ptr = eptr + 1) {
175 if (ptr != bptr)
176 buf = cat(buf, ptr, bptr - ptr);
177 if ((eptr = strchr(ptr + sizeof(def) - 1, ')')) == NULL) {
178 (void) fprintf(stderr, "%s: missing close paren `%s'\n",
179 pname, defs);
180 return defs;
182 buf = cat(buf, bptr, eptr - bptr + 1);
183 name = bptr + sizeof(def) - 1;
184 len = eptr - name;
185 if (len < 1) {
186 (void) fprintf(stderr, "%s: empty define `%s'\n",
187 pname, defs);
188 return defs;
190 if (*name != '_') {
191 char *undername = malloc(len + 10);
192 buf = cat(buf, " || defined(", 0);
193 snprintf(undername, len + 10, "__%.*s__)", (int)len,
194 name);
195 buf = cat(buf, undername, len + 5);
196 buf = cat(buf, " || defined(", 0);
197 snprintf(undername, len + 10, "__%.*s)", (int)len,
198 name);
199 buf = cat(buf, undername, len + 3);
202 if (!eptr) {
203 (void) fprintf(stderr, "%s: invalid input `%s'\n", pname, defs);
204 return defs;
206 buf = cat(buf, eptr + 1, 0);
207 buf = cat(buf, ")", 0);
208 return buf;
213 main(int argc, char *argv[])
215 char line[INBUFSIZE];
216 const char *fname = "stdin";
217 char *ptr, *tok;
218 char defs[INBUFSIZE];
219 char stmt[INBUFSIZE];
220 FILE *fp = stdin;
221 int lineno = 0;
222 int inprocess = 0;
223 int token, state;
224 int errs = 0;
226 if ((pname = strrchr(argv[0], '/')) == NULL)
227 pname = argv[0];
228 else
229 pname++;
231 if (argc > 2) {
232 (void) fprintf(stderr, "Usage: %s [<filename>]\n", pname);
233 return 1;
236 if (argc == 2)
237 if ((fp = fopen(fname = argv[1], "r")) == NULL) {
238 (void) fprintf(stderr, "%s: Cannot open `%s'\n", pname, fname);
239 return 1;
242 state = S_DISCARD;
244 while ((ptr = fgets(line, sizeof(line), fp)) != NULL) {
245 lineno++;
246 switch (token = findtoken(gettoken(&ptr, defs))) {
247 case T_NEWCODE:
248 state = S_CODE;
249 break;
251 case T_ENDCODE:
252 state = S_DISCARD;
253 break;
255 case T_COMMENT:
256 state = S_COMMENT;
257 break;
259 case T_NEWDEF:
260 state = S_KEYWORD;
261 break;
263 case T_ENDDEF:
264 state = S_DISCARD;
265 break;
267 case T_VENDOR:
268 state = S_KEYWORD;
269 break;
271 case T_HOSTTYPE:
272 state = S_KEYWORD;
273 break;
275 case T_MACHTYPE:
276 state = S_KEYWORD;
277 break;
279 case T_OSTYPE:
280 state = S_KEYWORD;
281 break;
283 case T_MACRO:
284 if (gettoken(&ptr, defs) == NULL) {
285 (void) fprintf(stderr, "%s: \"%s\", %d: Missing macro name\n",
286 pname, fname, lineno);
287 break;
289 if (gettoken(&ptr, stmt) == NULL) {
290 (void) fprintf(stderr, "%s: \"%s\", %d: Missing macro body\n",
291 pname, fname, lineno);
292 break;
294 (void) fprintf(stdout, "\n#if %s\n# define %s\n#endif\n\n", stmt,
295 defs);
296 break;
298 case T_NONE:
299 if (state != S_CODE && *defs != '\0') {
300 (void) fprintf(stderr, "%s: \"%s\", %d: Discarded\n",
301 pname, fname, lineno);
302 if (++errs == 30) {
303 (void) fprintf(stderr, "%s: Too many errors\n", pname);
304 return 1;
306 break;
308 (void) fprintf(stdout, "%s", line);
309 break;
311 default:
312 (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected token\n",
313 pname, fname, lineno);
314 return 1;
317 switch (state) {
318 case S_DISCARD:
319 if (inprocess) {
320 inprocess = 0;
321 (void) fprintf(stdout, "#endif\n");
323 break;
325 case S_KEYWORD:
326 tok = gettoken(&ptr, defs);
327 if (token == T_NEWDEF) {
328 if (inprocess) {
329 (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
330 pname, fname, lineno);
331 return 1;
333 if (tok == NULL) {
334 (void) fprintf(stderr, "%s: \"%s\", %d: No defs\n",
335 pname, fname, lineno);
336 return 1;
338 (void) fprintf(stdout, "\n\n");
339 #ifdef LINEDIRECTIVE
340 (void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
341 #endif /* LINEDIRECTIVE */
342 (void) fprintf(stdout, "#if %s\n", defs);
343 inprocess = 1;
345 else {
346 if (tok && *tok)
347 (void) fprintf(stdout, "# if (%s) && !defined(_%s_)\n",
348 explode(defs), keyword[token]);
349 else
350 (void) fprintf(stdout, "# if !defined(_%s_)\n",
351 keyword[token]);
353 if (gettoken(&ptr, stmt) == NULL) {
354 (void) fprintf(stderr, "%s: \"%s\", %d: No statement\n",
355 pname, fname, lineno);
356 return 1;
358 (void) fprintf(stdout, "# define _%s_\n", keyword[token]);
359 (void) fprintf(stdout, " %s = %s;\n", keyword[token], stmt);
360 (void) fprintf(stdout, "# endif\n");
362 break;
364 case S_COMMENT:
365 if (gettoken(&ptr, defs))
366 (void) fprintf(stdout, " /* %s */\n", defs);
367 break;
369 case S_CODE:
370 if (token == T_NEWCODE) {
371 #ifdef LINEDIRECTIVE
372 (void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
373 #endif /* LINEDIRECTIVE */
375 break;
377 default:
378 (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected state\n",
379 pname, fname, lineno);
380 return 1;
384 if (inprocess) {
385 (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
386 pname, fname, lineno);
387 return 1;
390 if (fp != stdin)
391 (void) fclose(fp);
393 return 0;