/* Adapted from delatex.lex */
%{
#include <assert.h>
int depth = 0; 
%}
L [A-Za-z]
SA "begin"|"bibitem"|"bibliography"|"bibstyle"
SB "cite"|"end"|"include"|"includeonly"|"input"
SC "pageref"|"label"|"ref"|"cite"|"index"
S ({SA}|{SB}|{SC})
%Start Display Math Normal Tag
%%
\\%			ECHO; /* Escaped comment */ 
"\\{"		ECHO; /* Escaped "{" */
"\\}"		ECHO; /* Escaped "}" */
"\\$"		ECHO; /* Escaped $ */
"%".*		ECHO; /* Comments */
<Normal>{L}+ {    /* A word */	
			ECHO;
			AddIndex(yytext);
		} 
<Normal>{L}+"\\index{" {
				ECHO;
				BEGIN Tag;
				assert(depth == 0);
				depth = 1 ;
		}
<Normal>"\\"{S}"{"	{ 
				ECHO; 
				BEGIN Tag;
				assert(depth == 0);
				depth = 1;
		} 
\\{L}+		ECHO; /* Other controls */
<Tag>"{"	{
				ECHO;
				assert(depth > 0);
				depth++;
			}
<Tag>"}"	{
				ECHO; 
				assert(depth > 0);
				if (--depth	== 0)
					BEGIN Normal;
			}
<Tag>[^{}]		ECHO; /* up to next "}" */
<Normal>"\\("	{  /* begin latex math mode */
			ECHO; 
			BEGIN Math;
		}
<Math>"\\)"	{  /* end latex math mode */
			ECHO;
		  	BEGIN Normal;
		}
<Math>.|\\[^)]|\n	ECHO; /* in latex math mode */
<Normal,Display>\$([^$]|\\\$)+\$	ECHO;  /*  in math mode */
<Normal>"\\["		{/* now in Latex display mode */
				ECHO; 
				BEGIN Display;
			} 
<Normal>"$$"		{
				ECHO; 
				BEGIN Display; /* now in Display math mode */
			}
<Display>[^$]|\\[^\]]	ECHO; /* most things in display math mode */
<Display>"\\]"	{	
			ECHO;
			BEGIN Normal; /* get out of Display math mode */
		 }
<Display>"$$"	{
			ECHO;
			BEGIN Normal; /* get out of Display math mode */
		}
<Normal>\\.	ECHO; /* other single character control sequences */
<Normal>\\\n	ECHO; /* more of the same */
<Normal>\n|.	ECHO; /*  anything else, a character at a time */
%%
digest(fin,fout)
FILE *fin;
FILE *fout;
{
	yyin = fin;
	yyout = fout;
	yylex();
	return 0;
}
char *ProgName;
main(argc,argv)
	char **argv;
{
	int i;
	int nerrs = 0;
	
	ProgName = argv[0];
	
	if (init() != 0)
		return nerrs;
	BEGIN Normal; /* Starts yylex off in the right state */

	if (argc == 1) 
		return nerrs + digest(stdin,stdout);
	for (i = 1; i < argc; i++) {
		fprintf(stderr,"%s:\n",argv[i]);
		nerrs += ProcessFile(argv[i],digest);
	}
	return nerrs;
}

#include <stdio.h>
#include <search.h>

#define  NUM_KEY    10000	/* # of elements in search table */


ENTRY *hsearch();

FILE *GetFp()
{
	char *fname;
	FILE *fp;
	{
		char *DataBase = "names.bib";
		extern char *scanpath();
		extern char *getenv();

		if (getenv("INDEXDB"))
			DataBase = getenv("INDEXDB");
		if ((fname = scanpath(".",DataBase)) == (char *)0)
			if ((fname = scanpath("INDEXINPUTS",DataBase)) == (char *)0)
				if ((fname = scanpath("BIBINPUTS",DataBase)) == (char *)0)
					if ((fname = scanpath("TEXINPUTS",DataBase)) == (char *)0)
						if ((fname = scanpath("PATH",DataBase)) == (char *)0) {
							(void) fprintf(stderr,
								"%s: Cannot find \"%s\"\n",
								ProgName,DataBase
							);
							return (FILE *)0;
						}
	}
	fp = fopen(fname,"r");
	if (fp == (FILE *)0) 
		perror(fname);
	fprintf(stderr,"Reading database %s:\n",fname);
	free(fname);
	return fp;
}	

int init()
{
/* space to store strings */
static char string_space[NUM_KEY * 50];

/* next avail space in string_space */
register char *str_ptr = string_space;

	char *fmt = "@string{%s = \"%[^\"]\"}\n";
	struct entry e;
	FILE *fp;

	char s1[100];
	char s2[200];
	char *last = (char *)0;
	int i = 0;

	if ((fp = GetFp()) == (FILE *)0)
		return 1;

	(void) hcreate(NUM_KEY);
	
	while (fscanf(fp,fmt, s1, s2) == 2) {
		e.key = str_ptr;
		strcpy(str_ptr, s1);
		str_ptr += strlen(str_ptr) + 1;
		if (i == 0)
			fprintf(stderr,"First entry is %s\n",e.key);

		e.data = str_ptr;
		strcpy(str_ptr, s2);
		str_ptr += strlen(str_ptr) + 1;
		i++;

		(void) hsearch(e, ENTER);
	}
	fprintf(stderr,"Last entry is %s\n",e.key);
	fprintf(stderr,"Total of %d entries\n",i); 
	(void) fclose(fp);
	return 0;
}

AddIndex(s)
char *s;
{
	struct entry *p;
	if ((p = hsearch(&s,FIND)) != NULL) {
		fprintf(yyout,"\\index{%s@%s}",p->key,p->data);
	}
}





