4.4BSD/usr/src/share/doc/index/index.4.3/src/unduphead.y

/* this program (modified from duphead.y)
should contract duplicate headwords (independent of case) into "
so we can run reduce again. */

%{
#include "reduce.h"
#include <strings.h>
#include <ctype.h>
#include "pagesizes.h"  /* contains last page information for each doc */
int npages;	/* current number of pages in group */
#define MAXPAGES 300
#define MAXHDLEN 200
#define MAXSTRING 255
Page pages[MAXPAGES];  /* contains an entire group's page references */
char text[MAXHDLEN]="";	/* headword text */
char oldtext[MAXHDLEN]="";	/* headword text for previous entry*/
int initial=1;
%}
%union {
	char *sptr;  /* pointer to string */
	Page *pptr;  /* pointer to page entry */
}
%token <sptr> HEADWORD
%token <sptr> WORD
%token <sptr> DUP
%token <pptr> PAGE
%token <sptr> WHITESPACE
%token <sptr> ELLIPSIS

%%
index:	
	| index group {
		debugpr("group\n",10);
		npages=0;
		}
	;

group: 	  hdsentence '\n' {
			debugpr("newhead\n",10);
		}
	| group dup '\n'
	;

dup: 	DUP PAGE 	{
		fprintf(stderr, "unduphead found a dup!");
		}
	;
hdsentence :
	| HEADWORD	{
			debugpr("head",10);
			sprintf(text,"%s",$1);
		}
	| hdsentence WORD {
			debugpr("addword",10);
			strcat(text,$2);
		}
	| hdsentence WHITESPACE {
			debugpr("addwhite",10);
			strcat(text,"\t");
		}
	| hdsentence ELLIPSIS {
			debugpr("ellipsis",10);
			strcat(text,$2);
		}
	| hdsentence PAGE {
			debugpr("headpage",10);
			outputhead();
			outputpage($2,npages);
		}
	;

%%
#include <stdio.h>
#include <setjmp.h>
extern int lineno;
#define YYDEBUG
char *progname;
jmp_buf reparse;
int debug=0;

main(argc,argv)
	char *argv[];
{
	progname = argv[0];
	debug=0;
	setjmp(reparse);
	yyparse();
}

outputpage(p,position)
	char *p;
	int position;
	{
	if (debug>8) fprintf(stderr, "\nppage %s position %d ", p, position);
	pages[position].filename[0]='\0';
	pages[position].percent[0]='\0';
	strcpy(pages[position].pageentry,"unknown");
	sscanf(p,"%s%s%s",pages[position].filename,
		pages[position].percent,
		pages[position].pageentry);
	parsepageentry(&pages[position]);
	if (debug>8)
	fprintf(stderr, 
		"\naddpage posn %d file %s %s page %s \nsort %d vol %s section %d docnum %d docname %s pagenum %d\n", 
		position,
		pages[position].filename,
		pages[position].percent,
		pages[position].pageentry,
		pages[position].sortkey,
		pages[position].volname,
		pages[position].section,
		pages[position].docnum,
		pages[position].docname,
		pages[position].pagenum);
		printf("%s",p);
	}

parsepageentry(p) 
	Page *p;
	{
	char *colon, *minus, *lparen, *rparen;
	char tmp[MAXSTRING];
	char *t;

	if (debug>8)
		fprintf(stderr, "parsepageentry %s", p->pageentry);
	if(strcmp(p->pageentry,"unknown")==0) {
		intuitpageentry(p);
	}
	strcpy(tmp,p->pageentry);  /* we work on it here */
	if (colon = index(tmp,':')) {
		/* found a supplementary docname */
		*colon='\0';
		strcpy(p->volname,tmp); t=colon+1;

		if(strcmp(p->volname,"USD")==0) {
			p->sortkey=4;
		}
		else if(strcmp(p->volname,"PS1")==0) {
			p->sortkey=9;
		}
		else if(strcmp(p->volname,"PS2")==0) {
			p->sortkey=10;
		}
		else if(strcmp(p->volname,"SMM")==0) {
			p->sortkey=12;
		}
		else parseerror("bad supp volume name",p);

		if(minus=index(t,'-')) {
			/* break out docnum and pagenum */
			*minus='\0';
			p->docnum=atoi(t); t=minus+1;
			p->pagenum=atoi(t);
			strcpy(p->docname,"");
		} else parseerror("bogus supp",p);

	} else 	if (lparen = index(tmp,'(')) {
		/* found a man page entry */
		*lparen='\0';
		strcpy(p->docname,tmp); t=lparen+1;
		p->section=atoi(t);
		p->docnum=0;
		switch(p->section) {
			case 1:
				p->sortkey = 1;
				strcpy(p->volname,"URM");
				break;
			case 2:
				p->sortkey = 5;
				strcpy(p->volname,"PRM");
				break;
			case 3:
				p->sortkey = 6;
				strcpy(p->volname,"PRM");
				break;
			case 4:
				p->sortkey = 7;
				strcpy(p->volname,"PRM");
				break;
			case 5:
				p->sortkey = 8;
				strcpy(p->volname,"PRM");
				break;
			case 6:
				p->sortkey = 2;
				strcpy(p->volname,"URM");
				break;
			case 7:
				p->sortkey = 3;
				strcpy(p->volname,"URM");
				break;
			case 8:
				p->sortkey = 11;
				strcpy(p->volname,"SMM");
				break;
			default:
				parseerror("bad section number",p);
			}
		if (rparen = index(t,')')) 
			if(minus=index(rparen,'-')) {
				t=minus+1;
				p->pagenum=atoi(t);
			}
		else p->pagenum=0;
	} else parseerror("neither man nor supp entry",p);
}
	
	
intuitpageentry(p)
	Page *p;
	{
	char *q;
	int docnum;

	if((q=index(p->filename,'.'))==0) parseerror("cant intuit",p);
	q++;
	docnum=atoi(q);
	if(strncmp(p->filename,"USD.",4)==0) {
		sprintf(p->pageentry,"USD:%d-0",docnum);
		return;
	}
	else if(strncmp(p->filename,"PS1.",4)==0) {
		sprintf(p->pageentry,"PS1:%d-0",docnum);
		return;
	}
	else if(strncmp(p->filename,"PS2.",4)==0) {
		sprintf(p->pageentry,"PS2:%d-0",docnum);
		return;
	}
	else if(strncmp(p->filename,"SMM.",4)==0) {
		sprintf(p->pageentry,"SMM:%d-0",docnum);
		return;
	} else  { /* must be a man page */
	sprintf(p->pageentry,"%s",p->filename);
	if((q=index(p->pageentry,'.'))==0) parseerror("cant intuit man",p);
	else {
		*q='(';
		if (*(++q)=='N') *q='1';	/* correct man(n) to man(1) */
	}

	if((q=index(p->pageentry,':'))==0) parseerror("cant intuit man",p);
	else *q=')';
	strcat(p->pageentry,"-0");
	}
}

int compar(p1, p2)
	Page *p1, *p2;
{
	int ret;

	if (p1->sortkey < p2->sortkey) return -1; 
	else if (p1->sortkey == p2->sortkey) {
		if (p1->docnum < p2->docnum) return -1;
		else if (p1->docnum == p2->docnum) {
			if ((ret=strcmp(p1->docname, p2->docname))==0) {
				return (p1->pagenum - p2->pagenum);
			} else return ret;
		} else return 1;
	} else return 1;
}

int samedoc(i, j)
	int i,j;
{
	if (pages[i].sortkey != pages[j].sortkey) return 0; 
	if (pages[i].docnum != pages[j].docnum) return 0;
	if ((strcmp(pages[i].docname, pages[j].docname)==0) &&
		(pages[i].docnum == pages[j].docnum))
		return 1;
	else return 0;
}

outputhead()
{
int i, equal;
char c, d;
	/* if head same as previously printed, put out " */
	if (strcmp(oldtext, text)==0)  {
		printf("\n  \"    ");
		return;
	}
	equal=1;  /* assume equal */
	for (i=0; i<strlen(oldtext); i++) {
	  if(isupper(c=oldtext[i]))  c=tolower(oldtext[i]);
	  if(isupper(d=text[i]))  d=tolower(text[i]);
	  if (c != d) {
		  equal=0; break;
	  }
	}
	if (equal && (strlen(oldtext) == strlen(text))) printf("\n  \"    ");
	else {
		printf("\n%s	",text);
		strcpy(oldtext, text);
	}
}

yyerror(s) /* syntax error routine */
	char *s;
{
	prerror(s, (char *) 0);
}

prerror(s1,s2)
	char *s1, *s2;
{
	fprintf(stderr, "%s", s1);	
	if (s2) fprintf(stderr, "%s", s2);	
	fprintf(stderr, " at line %d, token %d\n", lineno, yychar);
	
}

debugpr(s1,level)
	char *s1;
	int level;
{
	if (debug>level) fprintf(stderr, "%s", s1);	
}

parseerror(s1,p)
	char *s1;
	Page *p;
{
	fprintf(stderr, "%s:%s\n", s1, p->pageentry);	
}