Logo Search packages:      
Sourcecode: tcsh version File versions  Download package

gethost.c

/* $Header: /p/tcsh/cvsroot/tcsh/gethost.c,v 1.12 2006/03/02 18:46:44 christos Exp $ */
/*
 * gethost.c: Create version file from prototype
 */
/*-
 * Copyright (c) 1980, 1991 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "sh.h"

RCSID("$tcsh: gethost.c,v 1.12 2006/03/02 18:46:44 christos Exp $")

#ifdef SCO
# define perror __perror
# define rename __rename
# define getopt __getopt
# define system __system
#endif
#include <stdio.h>
#ifdef SCO
# undef perror
# undef rename
# undef getopt
# undef system
#endif

#include <ctype.h>

#define ISSPACE(p)      (isspace((unsigned char) (p)) && (p) != '\n')

/* 
 * We cannot do that, because some compilers like #line and others
 * like # <lineno>
 * #define LINEDIRECTIVE 
 */

static const char *keyword[] =
{
    "vendor",
#define T_VENDOR  0
    "hosttype",
#define T_HOSTTYPE      1
    "machtype",
#define T_MACHTYPE      2
    "ostype",
#define T_OSTYPE  3
    "newdef",
#define T_NEWDEF  4
    "enddef",
#define T_ENDDEF  5
    "newcode",
#define T_NEWCODE 6
    "endcode",
#define T_ENDCODE 7
    "comment",
#define T_COMMENT 8
    "macro",
#define T_MACRO         9
    NULL
#define T_NONE          10
};

#define S_DISCARD 0
#define S_COMMENT 1
#define S_CODE          2
#define S_KEYWORD 3

static int findtoken (char *);
static char *gettoken (char **, char  *);

int main (int, char *[]);

/* findtoken():
 *    Return the token number of the given token
 */
static int
findtoken(char *ptr)
{
    int i;

    if (ptr == NULL || *ptr == '\0')
      return T_NONE;

    for (i = 0; keyword[i] != NULL; i++)
      if (strcmp(keyword[i], ptr) == 0)
          return i;

    return T_NONE;
}


/* gettoken():
 *    Get : delimited token and remove leading/trailing blanks/newlines
 */
static char *
gettoken(char **pptr, char *token)
{
    char *ptr = *pptr;
    char *tok = token;

    for (; *ptr && ISSPACE(*ptr); ptr++)
      continue;

    for (; *ptr && *ptr != ':'; *tok++ = *ptr++)
      continue;

    if (*ptr == ':')
      ptr++;
    else
      tok--;

    for (tok--; tok >= token && *tok && ISSPACE(*tok); tok--)
      continue;

    *++tok = '\0';

    *pptr = ptr;
    return token;
}
      

int
main(int argc, char *argv[])
{
    char line[INBUFSIZE];
    char *pname;
    const char *fname = "stdin";
    char *ptr, *tok;
    char defs[INBUFSIZE];
    char stmt[INBUFSIZE];
    FILE *fp = stdin;
    int lineno = 0;
    int inprocess = 0;
    int token, state;
    int errs = 0;

    if ((pname = strrchr(argv[0], '/')) == NULL)
      pname = argv[0];
    else
      pname++;

    if (argc > 2) {
      (void) fprintf(stderr, "Usage: %s [<filename>]\n", pname);
      return 1;
    }

    if (argc == 2)
      if ((fp = fopen(fname = argv[1], "r")) == NULL) {
          (void) fprintf(stderr, "%s: Cannot open `%s'\n", pname, fname);
          return 1;
      }

    state = S_DISCARD;

    while ((ptr = fgets(line, sizeof(line), fp)) != NULL) {
      lineno++;
      switch (token = findtoken(gettoken(&ptr, defs))) {
      case T_NEWCODE:
          state = S_CODE;
          break;

      case T_ENDCODE:
          state = S_DISCARD;
          break;

      case T_COMMENT:
          state = S_COMMENT;
          break;

      case T_NEWDEF:
          state = S_KEYWORD;
          break;

      case T_ENDDEF:
          state = S_DISCARD;
          break;

      case T_VENDOR:
          state = S_KEYWORD;
          break;

      case T_HOSTTYPE:
          state = S_KEYWORD;
          break;

      case T_MACHTYPE:
          state = S_KEYWORD;
          break;

      case T_OSTYPE:
          state = S_KEYWORD;
          break;

      case T_MACRO:
          if (gettoken(&ptr, defs) == NULL) {
            (void) fprintf(stderr, "%s: \"%s\", %d: Missing macro name\n",
                         pname, fname, lineno);
            break;
          }
          if (gettoken(&ptr, stmt) == NULL) {
            (void) fprintf(stderr, "%s: \"%s\", %d: Missing macro body\n",
                         pname, fname, lineno);
            break;
          }
          (void) fprintf(stdout, "\n#if %s\n# define %s\n#endif\n\n", stmt,
                     defs);
          break;

      case T_NONE:
          if (state != S_CODE && defs && *defs != '\0') {
            (void) fprintf(stderr, "%s: \"%s\", %d: Discarded\n",
                         pname, fname, lineno);
            if (++errs == 30) {
                (void) fprintf(stderr, "%s: Too many errors\n", pname);
                return 1;
            }
            break;
          }
          (void) fprintf(stdout, "%s", line);
          break;

      default:
          (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected token\n",
                     pname, fname, lineno);
          return 1;
      }

      switch (state) {
      case S_DISCARD:
          if (inprocess) {
            inprocess = 0;
            (void) fprintf(stdout, "#endif\n");
          }
          break;

      case S_KEYWORD:
          tok = gettoken(&ptr, defs);
          if (token == T_NEWDEF) {
            if (inprocess) {
                (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
                           pname, fname, lineno);
                return 1;
            }
            if (tok == NULL) {
                (void) fprintf(stderr, "%s: \"%s\", %d: No defs\n",
                           pname, fname, lineno);
                return 1;
            }
            (void) fprintf(stdout, "\n\n");
#ifdef LINEDIRECTIVE
            (void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
#endif /* LINEDIRECTIVE */
            (void) fprintf(stdout, "#if %s\n", defs);
            inprocess = 1;
          }
          else {
            if (tok && *tok)
                (void) fprintf(stdout, "# if (%s) && !defined(_%s_)\n",
                           defs, keyword[token]);
            else
                (void) fprintf(stdout, "# if !defined(_%s_)\n", 
                           keyword[token]);

            if (gettoken(&ptr, stmt) == NULL) {
                (void) fprintf(stderr, "%s: \"%s\", %d: No statement\n",
                           pname, fname, lineno);
                return 1;
            }
            (void) fprintf(stdout, "# define _%s_\n", keyword[token]);
            (void) fprintf(stdout, "    %s = %s;\n", keyword[token], stmt);
            (void) fprintf(stdout, "# endif\n");
          }
          break;

      case S_COMMENT:
          if (gettoken(&ptr, defs))
            (void) fprintf(stdout, "    /* %s */\n", defs);
          break;

      case S_CODE:
          if (token == T_NEWCODE) {
#ifdef LINEDIRECTIVE
            (void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
#endif /* LINEDIRECTIVE */
          }
          break;

      default:
          (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected state\n",
                     pname, fname, lineno);
          return 1;
      }
    }

    if (inprocess) {
      (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
                   pname, fname, lineno);
      return 1;
    }

    if (fp != stdin)
      (void) fclose(fp);

    return 0;
}

Generated by  Doxygen 1.6.0   Back to index