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