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