1 /* $Header: /src/pub/tcsh/gethost.c,v 1.10 2005/01/05 16:06:13 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.10 2005/01/05 16:06:13 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 #define ISSPACE(p) (isspace((unsigned char) (p)) && (p) != '\n') 54 55 /* 56 * We cannot do that, because some compilers like #line and others 57 * like # <lineno> 58 * #define LINEDIRECTIVE 59 */ 60 61 static const char *keyword[] = 62 { 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 85 }; 86 87 #define S_DISCARD 0 88 #define S_COMMENT 1 89 #define S_CODE 2 90 #define S_KEYWORD 3 91 92 static int findtoken __P((char *)); 93 static char *gettoken __P((char **, char *)); 94 95 int main __P((int, char *[])); 96 97 /* findtoken(): 98 * Return the token number of the given token 99 */ 100 static int 101 findtoken(ptr) 102 char *ptr; 103 { 104 int i; 105 106 if (ptr == NULL || *ptr == '\0') 107 return T_NONE; 108 109 for (i = 0; keyword[i] != NULL; i++) 110 if (strcmp(keyword[i], ptr) == 0) 111 return i; 112 113 return T_NONE; 114 } 115 116 117 /* gettoken(): 118 * Get : delimited token and remove leading/trailing blanks/newlines 119 */ 120 static char * 121 gettoken(pptr, token) 122 char **pptr; 123 char *token; 124 { 125 char *ptr = *pptr; 126 char *tok = token; 127 128 for (; *ptr && ISSPACE(*ptr); ptr++) 129 continue; 130 131 for (; *ptr && *ptr != ':'; *tok++ = *ptr++) 132 continue; 133 134 if (*ptr == ':') 135 ptr++; 136 else 137 tok--; 138 139 for (tok--; tok >= token && *tok && ISSPACE(*tok); tok--) 140 continue; 141 142 *++tok = '\0'; 143 144 *pptr = ptr; 145 return token; 146 } 147 148 149 int 150 main(argc, argv) 151 int argc; 152 char *argv[]; 153 { 154 char line[INBUFSIZE]; 155 char *pname; 156 const char *fname = "stdin"; 157 char *ptr, *tok; 158 char defs[INBUFSIZE]; 159 char stmt[INBUFSIZE]; 160 FILE *fp = stdin; 161 int lineno = 0; 162 int inprocess = 0; 163 int token, state; 164 int errs = 0; 165 166 if ((pname = strrchr(argv[0], '/')) == NULL) 167 pname = argv[0]; 168 else 169 pname++; 170 171 if (argc > 2) { 172 (void) fprintf(stderr, "Usage: %s [<filename>]\n", pname); 173 return 1; 174 } 175 176 if (argc == 2) 177 if ((fp = fopen(fname = argv[1], "r")) == NULL) { 178 (void) fprintf(stderr, "%s: Cannot open `%s'\n", pname, fname); 179 return 1; 180 } 181 182 state = S_DISCARD; 183 184 while ((ptr = fgets(line, sizeof(line), fp)) != NULL) { 185 lineno++; 186 switch (token = findtoken(gettoken(&ptr, defs))) { 187 case T_NEWCODE: 188 state = S_CODE; 189 break; 190 191 case T_ENDCODE: 192 state = S_DISCARD; 193 break; 194 195 case T_COMMENT: 196 state = S_COMMENT; 197 break; 198 199 case T_NEWDEF: 200 state = S_KEYWORD; 201 break; 202 203 case T_ENDDEF: 204 state = S_DISCARD; 205 break; 206 207 case T_VENDOR: 208 state = S_KEYWORD; 209 break; 210 211 case T_HOSTTYPE: 212 state = S_KEYWORD; 213 break; 214 215 case T_MACHTYPE: 216 state = S_KEYWORD; 217 break; 218 219 case T_OSTYPE: 220 state = S_KEYWORD; 221 break; 222 223 case T_MACRO: 224 if (gettoken(&ptr, defs) == NULL) { 225 (void) fprintf(stderr, "%s: \"%s\", %d: Missing macro name\n", 226 pname, fname, lineno); 227 break; 228 } 229 if (gettoken(&ptr, stmt) == NULL) { 230 (void) fprintf(stderr, "%s: \"%s\", %d: Missing macro body\n", 231 pname, fname, lineno); 232 break; 233 } 234 (void) fprintf(stdout, "\n#if %s\n# define %s\n#endif\n\n", stmt, 235 defs); 236 break; 237 238 case T_NONE: 239 if (state != S_CODE && defs && *defs != '\0') { 240 (void) fprintf(stderr, "%s: \"%s\", %d: Discarded\n", 241 pname, fname, lineno); 242 if (++errs == 30) { 243 (void) fprintf(stderr, "%s: Too many errors\n", pname); 244 return 1; 245 } 246 break; 247 } 248 (void) fprintf(stdout, "%s", line); 249 break; 250 251 default: 252 (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected token\n", 253 pname, fname, lineno); 254 return 1; 255 } 256 257 switch (state) { 258 case S_DISCARD: 259 if (inprocess) { 260 inprocess = 0; 261 (void) fprintf(stdout, "#endif\n"); 262 } 263 break; 264 265 case S_KEYWORD: 266 tok = gettoken(&ptr, defs); 267 if (token == T_NEWDEF) { 268 if (inprocess) { 269 (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n", 270 pname, fname, lineno); 271 return 1; 272 } 273 if (tok == NULL) { 274 (void) fprintf(stderr, "%s: \"%s\", %d: No defs\n", 275 pname, fname, lineno); 276 return 1; 277 } 278 (void) fprintf(stdout, "\n\n"); 279 #ifdef LINEDIRECTIVE 280 (void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname); 281 #endif /* LINEDIRECTIVE */ 282 (void) fprintf(stdout, "#if %s\n", defs); 283 inprocess = 1; 284 } 285 else { 286 if (tok && *tok) 287 (void) fprintf(stdout, "# if (%s) && !defined(_%s_)\n", 288 defs, keyword[token]); 289 else 290 (void) fprintf(stdout, "# if !defined(_%s_)\n", 291 keyword[token]); 292 293 if (gettoken(&ptr, stmt) == NULL) { 294 (void) fprintf(stderr, "%s: \"%s\", %d: No statement\n", 295 pname, fname, lineno); 296 return 1; 297 } 298 (void) fprintf(stdout, "# define _%s_\n", keyword[token]); 299 (void) fprintf(stdout, " %s = %s;\n", keyword[token], stmt); 300 (void) fprintf(stdout, "# endif\n"); 301 } 302 break; 303 304 case S_COMMENT: 305 if (gettoken(&ptr, defs)) 306 (void) fprintf(stdout, " /* %s */\n", defs); 307 break; 308 309 case S_CODE: 310 if (token == T_NEWCODE) { 311 #ifdef LINEDIRECTIVE 312 (void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname); 313 #endif /* LINEDIRECTIVE */ 314 } 315 break; 316 317 default: 318 (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected state\n", 319 pname, fname, lineno); 320 return 1; 321 } 322 } 323 324 if (inprocess) { 325 (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n", 326 pname, fname, lineno); 327 return 1; 328 } 329 330 if (fp != stdin) 331 (void) fclose(fp); 332 333 return 0; 334 } 335