Files
nethack/sys/msdos/genschem.l
2002-01-05 21:05:56 +00:00

327 lines
6.6 KiB
Plaintext

%{
#include "config.h"
#include <stdlib.h>
#include <ctype.h>
#define MALLOC(type) (type *)malloc(sizeof(type))
typedef unsigned char bool;
struct OvlNode {
char FileName[13];
char Comment[80];
int OvlNumber;
struct OvlNode *Next;
};
int linenumber = 1;
int OvlNum = -1;
FILE *outf = NULL;
char *ovldesc = NULL;
struct OvlNode *List = NULL;
char *CommentTemplate;
struct OvlNode * FDECL(AddNode, (struct OvlNode *, struct OvlNode *));
struct OvlNode * FDECL(DelNode, (struct OvlNode *));
struct OvlNode * FDECL(ReverseList, (struct OvlNode *));
struct OvlNode * FDECL(SortList, (struct OvlNode *));
int NDECL (yylex);
#ifndef yywrap
int NDECL (yywrap);
#endif
#ifdef exit
#undef exit
#endif
%}
FILECH [A-Za-z0-9_]
FILE {FILECH}{1,8}("."{FILECH}{0,3})?
SCCS [Ss][Cc][Cc][Ss].*\n
COPYR [Cc][Oo][Pp][Yy][Rr][Ii][Gg][Hh][Tt].*\n
%%
{SCCS} { linenumber ++; }
{COPYR} { linenumber ++; }
^#.*\n {
if (OvlNum < 0) {
yytext[yyleng - 1] = 0;
fprintf (outf, CommentTemplate, yytext+1);
}
linenumber ++;
}
\n { linenumber ++; }
[ \t]+ ; /* skip trailing tabs & spaces */
\[.*\] {
yytext[yyleng-1] = 0; /* Discard the trailing \] */
if (ovldesc) free (ovldesc);
ovldesc = (char *) malloc(strlen(yytext+1)+1);
strcpy(ovldesc, yytext+1); /* Discard the first \[ */
OvlNum++;
}
{FILE} {
struct OvlNode *Tmp;
Tmp = MALLOC (struct OvlNode);
strcpy (Tmp->FileName, yytext);
Tmp->OvlNumber = OvlNum;
strncpy (Tmp->Comment, ovldesc, 80);
List = AddNode (List, Tmp);
}
. {
printf ("Line %d: Received character '%c' (%02x)\n",
linenumber, *yytext, *yytext);
}
%%
#ifndef yywrap
int
yywrap()
{
return 1;
}
#endif
#if defined(UNIX) || defined(_MSC_VER)
char *
strlwr(s)
char *s;
{
char *p;
for (p = s; *p; p++)
if (isupper(*p)) *p = tolower(*p);
return s;
}
char *
strupr(s)
char *s;
{
char *p;
for (p = s; *p; p++)
if (islower(*p)) *p = toupper(*p);
return s;
}
#endif
struct OvlNode *
SortList (List)
struct OvlNode *List;
{
struct OvlNode *List1 = NULL;
struct OvlNode *List2 = NULL;
struct OvlNode *Tmp;
if (List == NULL) return NULL;
if (List->Next == NULL) return List;
while (List != NULL) {
if (List != NULL) {
Tmp = List->Next;
List1 = AddNode (List1, List);
List = Tmp;
}
if (List != NULL) {
Tmp = List->Next;
List2 = AddNode (List2, List);
List = Tmp;
}
}
List1 = SortList (List1);
List2 = SortList (List2);
while (List1 != NULL || List2 != NULL) {
while (List1 != NULL && List2 == NULL) {
Tmp = List1->Next;
List = AddNode (List, List1);
List1 = Tmp;
}
while (List1 != NULL &&
strcmp(List1->FileName, List2->FileName) <= 0) {
Tmp = List1->Next;
List = AddNode (List, List1);
List1 = Tmp;
}
while (List2 != NULL && List1 == NULL) {
Tmp = List2->Next;
List = AddNode (List, List2);
List2 = Tmp;
}
while (List2 != NULL &&
strcmp(List1->FileName, List2->FileName) >= 0) {
Tmp = List2->Next;
List = AddNode (List, List2);
List2 = Tmp;
}
}
return ReverseList (List);
}
struct OvlNode *
AddNode (List, ToAdd)
struct OvlNode *List;
struct OvlNode *ToAdd;
{
ToAdd->Next = List;
return ToAdd;
}
struct OvlNode *
DelNode (List)
struct OvlNode *List;
{
struct OvlNode *tmp;
tmp = List->Next;
free (List);
return tmp;
}
struct OvlNode *
DelOvlList (List)
struct OvlNode *List;
{
while (List != NULL)
List = DelNode (List);
return List;
}
struct OvlNode *
ReverseList (List)
struct OvlNode *List;
{
struct OvlNode *Temp, *Last;
Last = NULL; Temp = List;
while (Temp) {
Temp = List->Next;
List->Next = Last;
Last = List;
List = Temp;
}
return Last;
}
/*
* Deletes all nodes with filename equal to that of the first node, except
* for the first node, itself, which it keeps.
*/
void
DelFile (List)
struct OvlNode *List;
{
struct OvlNode *tmp;
tmp = List;
while (tmp->Next != NULL) {
if (!stricmp(List->FileName, tmp->Next->FileName))
tmp->Next = DelNode (tmp->Next);
else
tmp = tmp->Next;
};
}
int
InList (List, ToFind)
struct OvlNode *List;
struct OvlNode *ToFind;
{
while (List != NULL) {
if (!stricmp(List->FileName, ToFind->FileName))
return 1;
List = List->Next;
};
return 0;
}
int
main (argc, argv)
int argc;
char *argv[];
{
bool MSC, BC;
char *Header, *Header2, *Header3, *RootLine, *OvlLine;
char *c;
char FileName[9];
time_t timer;
struct tm *curtim;
if (argc < 3) {
printf ("Too few arguments. Correct usage is:\n");
printf ("\t%s {/MSC || /BC} schemafile deffile\n\n", "genschem");
printf ("\t{/MSC || /BC} indicate the compiler to use.\n");
printf ("\tschemafile is the schema file to process.\n");
printf ("\tdeffile is the definition file to produce.\n");
printf ("\t\tif deffile is missing, stdout is assumed.\n\n");
return 1;
};
if (!stricmp(argv[1], "/MSC") || !stricmp(argv[1], "-MSC")) {
MSC = TRUE;
BC = FALSE;
} else if (!stricmp(argv[1], "/BC") || !stricmp(argv[1], "-BC")) {
MSC = FALSE;
BC = TRUE;
} else {
fprintf (stderr, "Unknown compiler format: %s\n", argv[1]);
return 1;
};
Header = BC ? "/* SCCS Id: @(#)%s\t3.3\t %02d/%02d/%02d */\n" :
"; SCCS Id: @(#)%s\t3.3\t %02d/%02d/%02d\n";
Header2 = BC ? "/* Copyright (c) Yitzhak Sapir, %d */\n" :
"; Copyright (c) NetHack PC Development Team, %d\n";
Header3 = BC ? "\n\n" : ";\n\nSEGMENTS\n\n";
RootLine = BC ? "-zC%s\n" :
"\"%s\" OVL:0\n";
OvlLine = BC ?
"-zC%s -zAOVLY -zCOVL%d\n" :
"\"%s\" OVL:%d\n";
CommentTemplate = BC ? "/* %s */\n" : ";%s\n";
yyin = fopen (argv[2], "r");
if (yyin == NULL) {
fprintf (stderr, "Error: Input file incorrect\n");
exit (1);
}
outf = fopen (argv[3], "w");
if (outf == NULL)
if (argc == 4) {
fprintf (stderr, "Error: Output file incorrect\n");
exit (1);
} else outf = stdout;
time (&timer);
curtim = localtime(&timer);
fprintf (outf, Header, argv[3], curtim->tm_year, curtim->tm_mon + 1,
curtim->tm_mday);
fprintf (outf, Header2, curtim->tm_year +1900);
yylex();
fprintf (outf, Header3);
for (List = SortList (List); List != NULL; List = DelNode (List)) {
if (BC) {
for (c = strlwr(List->FileName); *c; c++)
if (*c == '.') *c = '_';
} else strupr(List->FileName);
if (List->OvlNumber)
fprintf (outf, OvlLine, List->FileName, List->OvlNumber);
else fprintf (outf, RootLine, List->FileName, List->FileName);
}
fclose (outf);
}