DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T t

⟦3daac1e69⟧ TextFile

    Length: 13000 (0x32c8)
    Types: TextFile
    Names: »tokprep.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/laser-setters/dvi-to-ps/TeXPS/sup/tokprep.c« 

TextFile

/* Copyright 1988 Stephan v. Bechtolsheim */

/* This file is part of the TeXPS Software Package.

The TeXPS Software Package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the TeXPS Software Package
General Public License for full details.

Everyone is granted permission to copy, modify and redistribute
the TeXPS Software Package, but only under the conditions described in the
TeXPS Software Package General Public License.   A copy of this license is
supposed to have been given to you along with TeXPS Software Package so you
can know your rights and responsibilities.  It should be in a
file named CopyrightLong.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */

#include <stdio.h>
#include <ctype.h>
#include "release.h"
#include "extfil.h"

/* This program reads in a token definition file (.tdef) to generate
   output which can be used as partial input to yacc and lex
   to recognize keywords. */

/* Externals. */
extern char * StrcpyAlloc();
extern char * StrncpyAlloc();
extern char * optarg;
extern int optind;
extern char * tmpdir_default;

/* Definitions. */
#define V_VERBOSE 2
#define V_REGULAR 1
#define V_QUIET   0

#define VERSION "1.2"
#define DATE "May 9, 1990"

#define TRUE 1
#define FALSE 0

/* Forward declarations. */
void Usage();

/* Global variables. */

/* Input token definintion file. */
EX_FILES Ex_TokensIn; 

/* Output of .h file goes here. */
EX_FILES Ex_HOut;

/* Output for building the lexical analyzer goes here. */
EX_FILES Ex_LOut;

/* Name of the function which is generated when the -C option is used.
   The name "PrintToken" specified here can be changed using the -N option. */
char *PrintTokenFunctionName = "PrintToken";

/* Output for building a C program which prints the tokens in
   a "symbolic" way. Use the -C option of this program. */
EX_FILES Ex_COut;

/* Output for the token definitions used in yacc. Use the -Y option of this
   program. */
EX_FILES Ex_YOut;

/* Output for my sgmllex.c program. */
EX_FILES Ex_Sgtok;

/* Verbose level is any number between 0 [quiet] and 2 [verbose] */
int Verbose = 1;

/* Program name */
char *ProgName;

/* TokenCounter. Start at 1, because token zero has a special meaning.
   It is used by lex to signal the end of the input. */
int TokenCounter = 1;

/* Keywords are only matched at the beginning of a line in lex? Default
   is no, see -b option though. */
int LexBeginningOfLineOnly = FALSE;

/* Keywords in angle brackets (SGML)? Default is no, see -a option. */
int LexKeywordsSgmlType = FALSE;

/* Keywords for lex are usually lower case. Use the -c option to preserve
   case sensitivity. */
int LexKeywordsLowerCase = TRUE;

/*
 * Main
 * ****
 */
main(argc, argv)
     int argc;
     char *argv[];
{
  char line[256];
  char word[256];
  char word2[256];
  char *token_string_org;
  char *token_string;
  char *token_string_l;
  char *token_string_yacc;
  char *token_string_yacc_1;
  char *token_string_yacc_2;
  int i;
  int c;
  int linenumber = 0;

  ProgName = argv[0];
  InitProgName (ProgName, tmpdir_default);

  FExInit();
  InitSignalHandling();

  /* Usage of the program is as follows */
  if (argc == 1) {
    Usage();
    exit(1);
  }

  /* Initialize all the file pointers. */
  FExOpen(&Ex_TokensIn, EFT_INIT, NULL, NULL, NULL);
  FExOpen(&Ex_HOut,  EFT_INIT, NULL, NULL, NULL);
  FExOpen(&Ex_LOut,  EFT_INIT, NULL, NULL, NULL);
  FExOpen(&Ex_COut,  EFT_INIT, NULL, NULL, NULL);
  FExOpen(&Ex_YOut,  EFT_INIT, NULL, NULL, NULL);
  FExOpen(&Ex_Sgtok, EFT_INIT, NULL, NULL, NULL);

  /* Option Processing. */
  while ((c=getopt(argc, argv, "abcqvC:H:L:N:S:Y:")) != EOF) {
    switch (c) {
      /* -a: The lexical analyzer will read in the keywords and enclose them
	 in angle brackets so they are recognized in an SGML like style. */
      case 'a':
        LexKeywordsSgmlType = TRUE;
        break;

      /* -b: Keywords are now only matched at the beginning of a line, not
	 anywhere else in the text. */
      case 'b':
        LexBeginningOfLineOnly = TRUE;
	break;

      /* -c: Keywords are case sensitive now. By default this program maps
	 all keywords to lower case (regardless of how they were entered.) */
      case 'c':
        LexKeywordsLowerCase = FALSE;
	break;

      /* -q: quiet. */
      case 'q':
        Verbose = V_QUIET;
	break;

      /* -v: verbose. */
      case 'v':
	Verbose = V_VERBOSE;
	break;

      /* -C file[.c]: generate a C program which given a token value prints the
	 token in a symbolic represenation. This C program must be compiled and
	 linked to the source which wants to print tokens. The name of the C
	 procedure generated here is by defailt PrintTokenFunctionName but can
	 be changed with the -N option, if necessary. */
      case 'C':
	FExOpen(&Ex_COut, EFT_WRITE, EFQ_NO_STDOUT, optarg, "c");
	fprintf(EX_FP(Ex_COut), "/* This file is generated by program \"%s\". */\n", ProgName);
	fprintf(EX_FP(Ex_COut), "/* DO NOT CHANGE, change the input file to \"%s\" instead. */\n\n", ProgName);
	fprintf(EX_FP(Ex_COut), "#include <stdio.h>\n");
	fprintf(EX_FP(Ex_COut), "void %s(fp, t)\nFILE *fp;\n int t;\n{\n", PrintTokenFunctionName);
	fprintf(EX_FP(Ex_COut), "switch(t) {\n");
	fprintf(EX_FP(Ex_COut), "\tcase  0: fprintf(fp, \"<<end of lex>>\"); break;\n");
	break;

      /* -H file[.h]: generate a .h file with all the definitions of
	 tokens in it. This file can be used by the lexical analyzer to return proper
	 values. */
      case 'H':
	FExOpen(&Ex_HOut, EFT_WRITE, EFQ_NO_STDOUT, optarg, "h");
	fprintf(EX_FP(Ex_HOut), "/* File generated by program \"%s\". */\n", ProgName);
	fprintf(EX_FP(Ex_HOut), "/* DO NOT CHANGE, change the input file to \"%s\" instead. */\n\n", ProgName);
	break;

      /* -L file[.lex]: generate a (partial) .lex file with all the definitions for
	 reading in the keywords. */
      case 'L':
	FExOpen(&Ex_LOut, EFT_WRITE, EFQ_NO_STDOUT, optarg, "lex");
	break;

      /* -N name: print token function name. This option is used to overwrite
	 the default used by '-C'. */
      case 'N':
	if (Ex_COut.ef_open)
	  Fatal ("main(): -N option: -C option must be used AFTER -N option.");
	PrintTokenFunctionName = StrcpyAlloc(optarg);
	break;

      /* -Y file[.y]: generate a .y file (for yacc) with "%token name number"
	 definitions. */
      case 'Y':
	FExOpen(&Ex_YOut, EFT_WRITE, EFQ_NO_STDOUT, optarg, "y");
	fprintf(EX_FP(Ex_YOut), "/* File generated by program \"%s\". */\n", ProgName);
	fprintf(EX_FP(Ex_YOut), "/* DO NOT CHANGE, change the input file to \"%s\" instead. */\n\n", ProgName);
	break;

      /* -S file[.sgtok]: generate a .sgtok file (for sgmllex). */
      case 'S':
	FExOpen(&Ex_Sgtok, EFT_WRITE, EFQ_NO_STDOUT, optarg, "sgtok");
	break;

      case '?':
	Fatal ("main(): Illegal option.");
	break;

      default:
	Fatal ("main(): defaults.");
      } /* switch */
  } /* while */

  /* If no output file is specified all we can do is parse the file. */
  if (!Ex_HOut.ef_open && !Ex_HOut.ef_open &&
      !Ex_LOut.ef_open && !Ex_COut.ef_open && !Ex_YOut.ef_open &&
      !Ex_Sgtok.ef_open)
    fprintf (stderr, "main(): no output file open, parse input file only\n.");

  /* Open token definitions file. The following also explains the
     structure of the input of this file. */
  FExOpen(&Ex_TokensIn, EFT_READ, NULL, argv[optind], "tdef");

  /* Now read in this file on a line by line basis */
  while (ReadLineIntoBuffer(EX_FP(Ex_TokensIn), line, 256) != EOF) {
    linenumber++;
    if (line[0] == '%') /* Skip comment lines. */
      continue;
    if (Strlen(line) == 0)
      continue; /* Skip empty lines. */

#ifdef DEBUG
    printf ("%s\n", line); /* Print the line for debugging purposes. */
#endif
    /* First in the line comes the token itself. Pick up this token. */
    for (i = 0; line[i] != ' ' && line[i] != '\t' && line[i] != '\0'; i++)
      ;
    token_string_org = StrncpyAlloc(line, i);

    if (Ex_HOut.ef_open) /* Write #defines into a .h file. */
      fprintf (EX_FP(Ex_HOut), "#define %-20s %d\n",
	       token_string_org, TokenCounter);

    if (Ex_COut.ef_open) /* Write the C program which prints the tokens. */
      fprintf(EX_FP(Ex_COut), "\tcase %2d: fprintf(fp, \"%s\"); break;\n",
	      TokenCounter, token_string_org);

    /* The second "field", if available, contains information which is used
       by yacc (type information). */
    if (Ex_YOut.ef_open) { /* Write the stuff for yacc. */
      token_string_yacc = StrcpyAlloc(line);
      RemoveLeadingWhiteSpace(token_string_yacc);
      RemoveTrailingWhiteSpace(token_string_yacc);
      for (i=0;
	   *(token_string_yacc+i) != ' ' &&
	   *(token_string_yacc+i) != '\t' &&
	   *(token_string_yacc+i) != '\0'; i++)
	word[i] = *(token_string_yacc+i);
      word[i] = '\0';
#ifdef DEBUG
      fprintf (stderr, "WORD: \"%s\", \"%s\" (%d)\n", word, token_string_yacc, Strlen(word));
#endif      
      RemoveInLine(token_string_yacc, Strlen(word));
#ifdef DEBUG
      fprintf (stderr, "NOW: %s\n", token_string_yacc);
#endif
      RemoveLeadingWhiteSpace(token_string_yacc);

      if (Strlen(token_string_yacc) == 0)
	fprintf (EX_FP(Ex_YOut), "%%token %-20s %2d\n",
		 word, TokenCounter);
      else
	fprintf (EX_FP(Ex_YOut), "%%token <%s> %-20s %2d\n",
		 token_string_yacc, word, TokenCounter);
    }

    /* Is it a keyword type of token? Yes, if it starts with K_ */
    if (IsBeginningOfLine(line, "K_")) {

      /* Pick up the keyword! */
      for (i=0; line[i] != ' ' && line[i] != '\t' && line[i] != '\0'; i++)
	;

      /* Generate the keyword, also in a lower case version only. */
      token_string =   StrncpyAlloc(line, i);
      token_string_l = StrncpyAlloc(line, i);
      for (i=0; token_string_l[i] != '\0'; i++)
	if (isupper(token_string_l[i]))
	  token_string_l[i] = tolower(token_string_l[i]);
#ifdef DEBUG
      printf ("K_ type of token: \"%s\" / \"%s\"\n", token_string, token_string_l);
#endif
      /* Write the keyword parsing stuff for lex. Take into account that if
	 the -b option is used then keywords are only matched at the
	 beginning of a line. Also take the <...> into consideration. */
      if (Ex_LOut.ef_open)
	fprintf (EX_FP(Ex_LOut), "%s\"%s%s%s\" {return(%d);}\n",
		 LexBeginningOfLineOnly ? "^":"",
		 LexKeywordsSgmlType ? "<":"",
		 LexKeywordsLowerCase? token_string_l:token_string,
		 LexKeywordsSgmlType ? ">":"",
		 TokenCounter);

      if (Ex_Sgtok.ef_open) { /* sgmlex token definitions. */
	if (Strcmp (token_string_l+Strlen(token_string_l)-2, "_e") == 0) {
	  token_string_l[Strlen(token_string_l)-2] = '\0';
	  fprintf(EX_FP(Ex_Sgtok), "/%-19s %2d\n", token_string_l, TokenCounter);
	} else
	  fprintf(EX_FP(Ex_Sgtok), "%-20s %2d\n", token_string_l, TokenCounter);
      }

      /* S_ type of token ? Special keyword token (already programmed). */
    } else if (IsBeginningOfLine(line, "S_")) {
    }

    /* T_ type of token ? Ordinary token. */
    else if (IsBeginningOfLine(line, "T_")) {
    }

    /* Any other is an error. */
    else
      Fatal3 ("main(): token does not start with\n\tK_, T_ or S_; token is \"%s\", line %d",
	      line, linenumber);
    TokenCounter ++;
  } /* while loop reading the token definitions file. */

  /* Close the C program which prints the tokens, that is close the switch
     statement and the procedure itself. */
  if (Ex_COut.ef_open) {
    fprintf(EX_FP(Ex_COut), "\tdefault: Fatal2 (\"%s(): illegal token, #%%d\", t);\n",
	    PrintTokenFunctionName);
    fprintf(EX_FP(Ex_COut), "}}\n");
  }

  FExClose(&Ex_TokensIn); /* Close all other files now. */
  FExClose(&Ex_HOut);
  FExClose(&Ex_LOut);
  FExClose(&Ex_COut);
  FExClose(&Ex_YOut);
  FExClose(&Ex_Sgtok);
  exit (0);
}

/* Usage text */
char *UsageText[] = {
  "\t-a (keywords enclosed in angle brackets <...>, SGML style)",
  "\t-b (keywords are matched at the begining of a line only by lex)",
  "\t-c (keywords are by default mapped to lower case, -c: preserve case sensitivity)",
  "\t[-N Function name] (define function name for printing token C program.)",
  "\t[-C file[.c]] (Output file for a C-program printing the tokens)",
  "\t[-L file[.lex]] (Output file for lex)",
  "\t[-H file[.h]] (.h file for all tokens)",
  "\t[-S file[.sgtok]] (.sgtok SGML token definitions / sgmllex)",
  "\t[-Y file[.y]] (Output file for yacc token definitions)",
  "\t[-q] (quiet)      [-v] (verbose)",
  "\tfile[.tdef]... (or '-' for stdin)",
  NULL};

/*
 * Usage
 * *****
 * Print usage message.
 */
void
Usage()
{
  char **ptr;

  fprintf (stderr, "%s:  Version %s of %s\n", ProgName, VERSION, DATE);
  fprintf (stderr, "%s: TeXPS version %s of %s\n", ProgName, RELEASE_VERSION, RELEASE_DATE);
  fprintf (stderr, "usage: %s\n", ProgName);
  ptr = &UsageText[0];
  while (*ptr != NULL)
    fprintf (stderr, "%s\n", *ptr++);
}