abermud/DATA/
/*
**  Utility program to build the data files.
*/
#include "kernel.h"

/* #define	DEBUG */
#ifdef	DEBUG
#define	Db(x)	x
#else
#define	Db(x)
#endif

#ifdef	RCSID
static char RCS[] =
	"$Header: generate.c,v 1.1 89/03/13 09:36:24 rsalz Exp $";
#endif	/* RCSID */

crapup(p) char *p; {
    perror(p);
    exit(1);
}

/*
**  Parse a flags line, a line like:
**	int1:int2:bits
**  and turn it into a four-byte int like:
**	bits:int1:int2
*/
static int
flags(buff)
    char		*buff;
{
    register char	*p,c;
    register int	 i;
    register int	 b;
    char		 save[120];

    (void)strcpy(save, buff);
    if (p = strchr(buff, ':')) {
	*p++ = '\0';
	i = atoi(buff) << 8;
	buff = p;
	if (p = strchr(buff, ':')) {
	    *p++ = '\0';
	    i |= atoi(buff);
	    for (b = 0; (c=*p) && (c=='0' || c=='1'); p++)
		b = (b << 1) | (c=='1' ? 1 : 0);
	    return i | (b << 16);
	}
    }
    (void)fprintf(stderr, "Badly-formed input line:\n%s\n", save);
    exit(1);
    /* NOTREACHED */
}


/*
**  Open file for read/write or die trying
*/
static FILE *
Do_fopen(name,mode)
char *name,*mode;	{
    FILE *file;

    if(*name=='-' && !name[1])
	return *mode=='w'?stdout:stdin;
    if(!(file=fopen(name,mode)))	{
	perror(name);
	(void)fprintf(stderr, "Unable to open file for %s\n",
	    *mode=='w'?"write":"read");
	exit(1);
    }
    return file;
}


/*
**  Create world file.
*/
static void
make_world(argc, argv)
    int		 argc;
    char	*argv[];
{
    register FILE	*F;
    register int	 b;
    int			 x[64];

    F = Do_fopen(argc == 2 ? argv[1] : UNIVERSE,"w");
    x[0] = 1;
    x[1] = 1;
    sec_write(F, x, 0, sizeof x / sizeof x[0]);
    for (b = 0; b < sizeof x / sizeof x[0]; )
	x[b++] = 0;

    for (b = 1; b < 600; b++, x[0] = 0)
	sec_write(F, x, b, sizeof x / sizeof x[0]);
    (void)fclose(F);
    exit(0);
}


/*
**  Create the user activity file.
*/
static void
make_uaf(argc, argv)
    int		 argc;
    char	*argv[];
{
    FILE	*F;
    PERSONA	 P;

    F = Do_fopen(argc==2? argv[1]: UAF_RAND,"w");

    P.p_sex = 0;
    P.p_level = 10001;
    P.p_score = 0;
    P.p_strength = 100;
    (void)strcpy(P.p_name, "Root");
    (void)fwrite((char *)&P, 1, sizeof P, F);

    /* Not legal name as endmark ie 2 in it */
    (void)strcpy(P.p_name, "Debugger");
    (void)fwrite((char *)&P, 1, sizeof P, F);
    (void)fclose(F);

    exit(0);
}


/*
**  Make the data file that shows what starts where, and their states.
*/
static void
make_reset(argc, argv)
    int			 argc;
    char		*argv[];
{
    register FILE	*In;
    register FILE	*Out;
    register int	*ip;
    register int	 i;
    char		buff[128];
    int			blob[10000];

    if(argc<3) {
	(void)fprintf(stderr, "Usage error\n");
	exit(1);
    }
    In = Do_fopen(argv[1],"r");
    Out = Do_fopen(argv[2],"w");

	/* Read thru object file, ignoring nonnumeric lines and collecting
	** others into blob[] for write to output file... */
    for (ip = blob, i = 0; fgets(buff, sizeof(buff), In);)	{
	Db( printf("%d-%s",i&3,buff); )
	if(*buff=='-' || isdigit(*buff))
	    *ip++ = ((i++ & 0x03) == 2) ? flags(buff) : (int)atoi(buff);
    }

    sec_write(Out, blob, 0, ip - blob);
    (void)fclose(In);
    (void)fclose(Out);
    exit(0);
}


/*
**  Make the user file.
*/
static void
make_user(argc, argv)
    int		 argc;
    char	*argv[];
{
    (void)fclose(Do_fopen(argc == 2 ? argv[1] : PASSWORDFILE,"w"));
    exit(0);
}


/*
**  Convert a string to lowercase.
*/
char *
uppercase(str)
    register char *str;
{
    register char *p;

    for (p = str; *p; p++)
	if (islower(*p))
	    *p = toupper(*p);
    return str;
}


/*
**	Search for word in internal storage, return zero if was already
**	there; else, return true and add to to the storage.
*/

int
used(word)
char *word;	{
	register int p;
	/* Maximum number of objects is 1000 here... feel free to make it
         * larger..
         */
	static char *storage[1000];
	static int  xused[1000];
	static int store_index;

	for(p=0; p < store_index; p++)
	  if(EQ(storage[p],word))
	    return(++xused[p]);
        storage[p] = (char *) malloc(35); /* 35 bytes for object name */
	(void)strcpy(storage[p],word);
	store_index++;
	return(0);
}


/*
**  Make header file objects.h
*/
static void
make_objects(argc,argv)
int argc;
char *argv[];	{
    register FILE	*In,*Out;
    register char	*p,*q;
    register int	 i;
    int			 j, nr;
    char		 buff[128],objname[2][30];

    if(argc<3) {
	(void)fprintf(stderr, "Usage error\n");
	exit(1);
    }
    In = Do_fopen(argv[1],"r");
    Out = Do_fopen(argv[2],"w");

	/* Print out header */
    (void)fprintf(Out,"\
/*\n\
**\tObject file header generated from %s\n\
**\tDON'T MAKE CHANGES HERE -- THEY WILL GO AWAY !\n\
*/\n\n",argv[1]);

        (void)fgets(buff, sizeof(buff), In);

	/* Read thru object file, creating #define:s for each object */
    for (i = 0; fgets(buff, sizeof(buff), In); i++)	{
	if(sscanf(buff,"%s%s%d",objname[0],objname[1],&j)!=3)	{
	    (void)fprintf(stderr, "Badly-formed input line:\n%s\n", buff);
	    exit(1);
	    /* NOTREACHED */
	}

	for(j=0; j<2; j++)	{
	    if(!*(p=uppercase(objname[j]))) continue;
	    for(q=p; *q; q++)
		if(!isalpha(*q) && *q!='$' && *q!='_')	{
		    *p='\0';
		    continue;
		}
	}
	for(j=0; *objname[j] && j<2; j++)	{
	    *buff='\0';
	    (void)strcpy(buff,objname[j]);
	    if(j==1)	{
		(void)strcat(buff,"_");
		(void)strcat(buff,objname[0]);
	    }
	    Db( printf("[%s|%s]->%s\n",objname[0],objname[1],buff);)
            if(!(nr = used(buff)))  {
		Db( printf("unused <%s>\n",buff);)
		(void)fprintf(Out,"#define\tOBJ_%s\t%d\n",buff,i);
		break;
	    } else {
                Db( printf("used <%s>\n",buff);)
                (void)fprintf(Out,"#define\tOBJ_%s_%d\t%d\n", buff, nr, i);
                break;
            }
	}

	for(j=0; j<4; j++)
		while(fgetc(In)!='^');
	while(fgetc(In)!='\n');
    }

    (void)fclose(In);
    (void)fclose(Out);
    exit(0);
}


/*
**  Make header file verbs.h
*/
static void
make_verbs(argc,argv)
int argc;
char *argv[];	{
    register FILE	*In,*Out;
    register char	*p,*q;
    register int	 i;
    int			 j;
    char		 buff[128],verb[30];
    int			 verb_numbers[1000],verbs_used=0;

    if(argc<3) {
	(void)fprintf(stderr, "Usage error\n");
	exit(1);
    }
    In = Do_fopen(argv[1],"r");
    Out = Do_fopen(argv[2],"w");

	/* Print out header */
    (void)fprintf(Out,"\
/*\n\
**\tVerb file header generated from %s\n\
**\tDON'T MAKE CHANGES HERE -- THEY WILL GO AWAY !\n\
*/\n\n",argv[1]);
    (void)fgets(buff, sizeof(buff), In);

	/* Read thru verb file, creating #define:s for each verb */

    while(fgets(buff, sizeof(buff), In))	{
	if(sscanf(buff,"%s%d",verb,&j)!=2)	{
	    (void)fprintf(stderr, "Badly-formed input line:\n%s\n", buff);
	    exit(1);
	    /* NOTREACHED */
	}

	if(!*(p=uppercase(verb))) continue;
	for(q=p; *q; q++)
	    if(!isalpha(*q) && *q!='$' && *q!='_') continue;
        (void)fprintf(Out,"#define\tVERB_%s\t%d\n",p,j);
    }

    (void)fclose(In);
    (void)fclose(Out);
    exit(0);
}


main(argc, argv)
    int		 argc;
    char	*argv[];
{
    argc--;
    argv++;

    if (argc)
    if (EQ(*argv, "world"))
	make_world(argc, argv);
    else if (EQ(*argv, "uaf"))
	make_uaf(argc, argv);
    else if (EQ(*argv, "reset"))
	make_reset(argc, argv);
    else if (EQ(*argv, "userfile"))
	make_user(argc, argv);
    else if (EQ(*argv, "objects"))
	make_objects(argc, argv);
    else if (EQ(*argv, "verbs"))
	make_verbs(argc, argv);

    (void)fprintf(stderr, "Usage error.\n");
    exit(1);
}