#include <string.h>
#include "once.h"
#include "sgs.h"
#include <locale.h>
#include <limits.h>
static wchar_t L_INITIAL[] = {'I', 'N', 'I', 'T', 'I', 'A', 'L', 0};
static void get1core(void);
static void free1core(void);
static void get2core(void);
static void free2core(void);
static void get3core(void);
#ifdef DEBUG
static void free3core(void);
#endif
static FILE *
lex_open_driver(const char *fname, const char *dir)
{
FILE *fp;
char path[PATH_MAX];
if (dir == NULL)
dir = NBASE;
(void) snprintf(path, PATH_MAX, "%s/%s", dir, fname);
fp = fopen(path, "r");
if (fp == NULL)
error("Lex driver missing, file %s", path);
return (fp);
}
int
main(int argc, char **argv)
{
int i;
int c;
char *apath = NULL;
char *ypath;
Boolean eoption = 0, woption = 0;
sargv = argv;
sargc = argc;
(void) setlocale(LC_ALL, "");
#ifdef DEBUG
while ((c = getopt(argc, argv, "dyctvnewVQ:Y:")) != EOF) {
#else
while ((c = getopt(argc, argv, "ctvnewVQ:Y:")) != EOF) {
#endif
switch (c) {
#ifdef DEBUG
case 'd':
debug++;
break;
case 'y':
yydebug = TRUE;
break;
#endif
case 'V':
(void) fprintf(stderr, "lex: %s %s\n",
(const char *)SGU_PKG,
(const char *)SGU_REL);
break;
case 'Q':
v_stmp = optarg;
if (*v_stmp != 'y' && *v_stmp != 'n')
error(
"lex: -Q should be followed by [y/n]");
break;
case 'Y':
apath = optarg;
break;
case 'c':
ratfor = FALSE;
break;
case 't':
fout = stdout;
break;
case 'v':
report = 1;
break;
case 'n':
report = 0;
break;
case 'w':
case 'W':
woption = 1;
handleeuc = 1;
widecio = 1;
break;
case 'e':
case 'E':
eoption = 1;
handleeuc = 1;
widecio = 0;
break;
default:
(void) fprintf(stderr,
"Usage: lex [-ewctvnV] [-Y directory] "
"[-Q(y/n)] [file]\n");
exit(1);
}
}
if (woption && eoption) {
error(
"You may not specify both -w and -e simultaneously.");
}
no_input = argc - optind;
if (no_input) {
if (strcmp(argv[optind], "-") == 0)
fin = stdin;
else {
fin = fopen(argv[optind], "r");
if (fin == NULL)
error(
"Can't open input file -- %s", argv[optind]);
}
} else
fin = stdin;
(void) gch();
get1core();
scopy(L_INITIAL, sp);
sname[0] = sp;
sp += slength(L_INITIAL) + 1;
sname[1] = 0;
exclusive[0] = 0;
if (!handleeuc) {
ZCH = ncg = NCH;
}
if (yyparse())
exit(1);
if (handleeuc) {
ncg = ncgidtbl * 2;
ZCH = ncg;
if (ncg >= MAXNCG)
error(
"Too complex rules -- requires too many char groups.");
sortcgidtbl();
}
repbycgid();
free1core();
get2core();
ptail();
mkmatch();
#ifdef DEBUG
if (debug)
pccl();
#endif
sect = ENDSECTION;
if (tptr > 0)
cfoll(tptr-1);
#ifdef DEBUG
if (debug)
pfoll();
#endif
cgoto();
#ifdef DEBUG
if (debug) {
(void) printf("Print %d states:\n", stnum + 1);
for (i = 0; i <= stnum; i++)
stprt(i);
}
#endif
free2core();
get3core();
layout();
#ifdef DEBUG
free3core();
#endif
if (handleeuc) {
if (ratfor)
error("Ratfor is not supported by -w or -e option.");
ypath = EUCNAME;
}
else
ypath = ratfor ? RATNAME : CNAME;
fother = lex_open_driver(ypath, apath);
while ((i = getc(fother)) != EOF)
(void) putc((char)i, fout);
(void) fclose(fother);
(void) fclose(fout);
if (report == 1)
statistics();
(void) fclose(stdout);
(void) fclose(stderr);
return (0);
}
static void
get1core(void)
{
ccptr = ccl = (CHR *)myalloc(CCLSIZE, sizeof (*ccl));
pcptr = pchar = (CHR *)myalloc(pchlen, sizeof (*pchar));
def = (CHR **)myalloc(DEFSIZE, sizeof (*def));
subs = (CHR **)myalloc(DEFSIZE, sizeof (*subs));
dp = dchar = (CHR *)myalloc(DEFCHAR, sizeof (*dchar));
sname = (CHR **)myalloc(STARTSIZE, sizeof (*sname));
exclusive = (int *)myalloc(STARTSIZE, sizeof (*exclusive));
sp = schar = (CHR *)myalloc(STARTCHAR, sizeof (*schar));
if (ccl == 0 || def == 0 ||
pchar == 0 || subs == 0 || dchar == 0 ||
sname == 0 || exclusive == 0 || schar == 0)
error("Too little core to begin");
}
static void
free1core(void)
{
free(def);
free(subs);
free(dchar);
}
static void
get2core(void)
{
int i;
gotof = (int *)myalloc(nstates, sizeof (*gotof));
nexts = (int *)myalloc(ntrans, sizeof (*nexts));
nchar = (CHR *)myalloc(ntrans, sizeof (*nchar));
state = (int **)myalloc(nstates, sizeof (*state));
atable = (int *)myalloc(nstates, sizeof (*atable));
sfall = (int *)myalloc(nstates, sizeof (*sfall));
cpackflg = (Boolean *)myalloc(nstates, sizeof (*cpackflg));
tmpstat = (CHR *)myalloc(tptr+1, sizeof (*tmpstat));
foll = (int **)myalloc(tptr+1, sizeof (*foll));
nxtpos = positions = (int *)myalloc(maxpos, sizeof (*positions));
if (tmpstat == 0 || foll == 0 || positions == 0 ||
gotof == 0 || nexts == 0 || nchar == 0 ||
state == 0 || atable == 0 || sfall == 0 || cpackflg == 0)
error("Too little core for state generation");
for (i = 0; i <= tptr; i++)
foll[i] = 0;
}
static void
free2core(void)
{
free(positions);
free(tmpstat);
free(foll);
free(name);
free(left);
free(right);
free(parent);
free(nullstr);
free(state);
free(sname);
free(exclusive);
free(schar);
free(ccl);
}
static void
get3core(void)
{
verify = (int *)myalloc(outsize, sizeof (*verify));
advance = (int *)myalloc(outsize, sizeof (*advance));
stoff = (int *)myalloc(stnum+2, sizeof (*stoff));
if (verify == 0 || advance == 0 || stoff == 0)
error("Too little core for final packing");
}
#ifdef DEBUG
static void
free3core(void)
{
free(advance);
free(verify);
free(stoff);
free(gotof);
free(nexts);
free(nchar);
free(atable);
free(sfall);
free(cpackflg);
}
#endif
BYTE *
myalloc(int a, int b)
{
BYTE *i;
i = calloc(a, b);
if (i == 0)
warning("calloc returns a 0");
return (i);
}
void
yyerror(char *s)
{
(void) fprintf(stderr,
"\"%s\":line %d: Error: %s\n", sargv[optind], yyline, s);
}