|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 13000 (0x32c8)
Types: TextFile
Names: »tokprep.c«
└─⟦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«
/* 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++);
}