/************************************************************************/ /* File: Index.c */ /************************************************************************/ /* Developer: TeXplorators Inc., Houston, Texas */ /* PRODUCT : Index: Sort TeX index entries alphabetically */ /* Module : index */ /* Notes : This source code is compiled with Microsoft C 5.1 */ /************************************************************************/ /* SOFTWARE LICENSE AGREEMENT 1. PURPOSE This agreement recites the terms and conditions under which The TeXplorators Corporation ("TEXPLORATORS") agrees to grant you a free, nonexclusive, transferable license to use the INDEX software. 2. UNDERTAKINGS BY TEXPLORATORS 2A. Ownership: Ownership of the INDEX software remains exclusively in TEXPLORATORS. 2B. License Fee: TEXPLORATORS makes the INDEX software available to you free of any license fee. 2C. Disclaimers: TEXPLORATORS DISCLAIMS ALL EXPRESS OR IMPLIED WARRANTIES OF INDEX'S MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. 2D. Liability: TEXPLORATORS' LIABILITY, IF ANY, IS LIMITED TO THE DISTRIBUTION FEE YOU PAID, AND DOES NOT INCLUDE SPECIAL AND/OR CONSEQUENTIAL DAMAGES ARISING OUT OF, OR IN CONNECTION WITH, THE USE OF INDEX. SINCE SOME STATES DISALLOW LIMITATION OR EXCLUSION OF LIABILITY, THIS LIMITATION OR EXCLUSION MAY NOT APPLY TO YOU. 3. UNDERTAKINGS BY YOU. 3A. Proper Use: You agree to use the INDEX software in compliance with the terms and conditions hereof. 3B. Notices on Authorized Copies: You agree to take reasonable precautions to preserve the propriety of the INDEX software by duplicating verbatim, on all copies thereof, the notices of TEXPLORATORS' interests recited thereon. You agree to note that source code is available upon request, if you do not distribute source code with the INDEX software. 3C. Distribution: You are encouraged to freely distribute the INDEX software, including source code, on or through any common media including diskettes and electronic bulletin board systems. You agree to distribute this license with each and every copy so distributed, and to either distribute source code therewith or make source code available upon request. You may charge a distribution fee to cover the cost of diskettes, handling and shipping. 3D. Modifications: You are authorized to make modifications to INDEX, but these modifications must be conspicuously noted and dated therewith. 3E. License Fee: You may not charge a license fee for the INDEX software, either in its original or modified form. However, you may charge a license fee for your software which is broader in scope than INDEX, whereby INDEX is not a primary functional unit thereof. 4. SCOPE This Software License Agreement constitutes the entire agreement between TEXPLORATORS and you regarding the INDEX software, and shall be construed under the laws of the State of TEXAS. The TeXplorators Corporation By: Michael Spivak, President Page*/ /* HISTORY: [03/07/1991] - Index now operates on a single .ndx file - there will be .npg file. An error message will be issued if a \Page{...}{...}{...} does not follow each entry. Each entry buffer size is expanded to 300 symbols. */ /* Configuration and defines for Unix 05/08/1991, P. A. MacKay */ /* System-dependent defines */ #include "config.h" /*------------------------------*/ /* includes */ /*------------------------------*/ #include #include #include #include #ifdef ANSI #include #endif #include /*------------------------------*/ /* defines */ /*------------------------------*/ #define TRUE 1 #define FALSE 0 #define MAX_STRING 5120 #define MAX_ENTRIES 15000 #define MAX_DEFINES 200 #define MAX_ABBREVS 200 #define MAX_PAGEORDER 200 #define MAX_PAGEENTRY 500 #define SPACE 32 #define COMMA ',' #define STAR '*' #define DQUOTE 34 #define BAR '|' #define LBRACE 123 #define RBRACE 125 #define RSLASH '\\' #define MINUS '-' #define PLUS '+' #define NL '\n' #define LBRACKET '[' #define RBRACKET ']' #define LPAREN '(' #define RPAREN ')' #define QUOTE 39 #define DOLLAR '$' #define ATSIGN '@' #define TILDE '~' #define EXCLAIM '!' #define CARET '^' #define USCORE '_' #define EQUAL '=' #define COLON ':' #define SEMI ';' #define LQUOTE '`' #define GREATER '>' #define LESS '<' #define QUESTION '?' #define SLASH '/' #define PERIOD '.' #define ZERO '0' #define ONE '1' #define TWO '2' #define THREE '3' #define FOUR '4' #define FIVE '5' #define ENTRY1 1 #define ENTRY2 4 #define ENTRY3 7 #define ENTRY4 10 #define ENTRY5 13 #define PRE_TYPE 0 #define POST_TYPE 1 #define ALIAS_TYPE 2 #define ENTRY_TYPE 3 #define XREF_TYPE 4 #define CROSS_TYPE 5 #define OTHER_TYPE 6 #define LEVEL0 0 #define LEVEL1 1 #define LEVEL2 2 #define LEVEL3 3 #define LEVEL4 4 #define LEVEL5 5 #define E1 1 #define E1_PRE 2 #define E1_POST 3 #define E1_ALIAS 23 #define E1_CS 28 #define E2 4 #define E2_PRE 5 #define E2_POST 6 #define E2_ALIAS 24 #define E2_CS 29 #define E3 7 #define E3_PRE 8 #define E3_POST 9 #define E3_ALIAS 25 #define E3_CS 30 #define E4 10 #define E4_PRE 11 #define E4_POST 12 #define E4_ALIAS 26 #define E4_CS 31 #define E5 13 #define E5_PRE 14 #define E5_POST 15 #define E5_ALIAS 27 #define E5_CS 32 #define XREF 16 #define NUMBER 17 #define CSNAME 18 #define PREFIX 19 #define POSTFIX 20 #define PAGE_SPAN 21 #define LARGEST 22 #define CTRLSEQ 33 #define CROSS_REF 34 /*------------------------------*/ /* typedefs */ /*------------------------------*/ #ifdef MICROSOFT_C typedef unsigned int WORD; #else typedef unsigned short WORD; #endif typedef unsigned char BYTE; typedef struct { char *fields[35]; } FieldType; typedef struct { FieldType *item; } EntryType; typedef struct { char *astr; char *xstr; } AbbrvType; typedef struct { char *style; char *pre; char *post; BYTE order; BYTE nstyle; BYTE npre; BYTE npost; } PageOrderType; /*------------------------------*/ /* data structures */ /*------------------------------*/ EntryType Entry[MAX_ENTRIES]; /* entries */ char *define[MAX_DEFINES]; /* defines */ AbbrvType *abbrev[MAX_ABBREVS]; /* abbrevs */ PageOrderType *PO[MAX_PAGEORDER];/*page orders */ int SubPageOrder[MAX_PAGEENTRY]; int SortingOrder[35]; /* sorting order indices */ int FirstOrder; /* First Sorting Order entry*/ int LastOrder; /* Last Sorting Order entry */ int PageOrder[10]; /* Page order indices */ int PageOrderFirst; /* Fist page order entry */ int PageOrderLast; /* Last page order entry */ char PageType; int PageIndex; int PageSpan; int Tindex; /* Topage Index */ char string[300]; /* working string buffer */ FILE *ndxfile; /* index file */ FILE *xdxfile; /* sorted file */ FILE *xxxfile; /* temporary file */ char ndxname[80]; /* .ndx file name */ char xdxname[80]; /* .xdx file name */ char tmpname[80]; /* .@d@ file name */ char idxname[80]; /* .idx file name */ BYTE alias; /* alias flag */ BYTE xref; /* xref flag */ BYTE crossref; /* crossref flag */ BYTE curEntry; /* type of entry appears */ WORD nitems; /* number of input lines */ WORD ndef; /* number of defs */ WORD nabb; /* number of abbrevs */ WORD npo; /* number of pageorders */ char curLetter; /* current letter */ char preLetter; /* previous letter */ BYTE FirstEntry; /* first entry flag */ char pagenum[80]; /* page number */ char prevnum[80]; /* previous page number */ BYTE skippage; /* skip page flag */ char *nullstr=""; /* NULL string */ char *NULLPTR; /* NULL pointer */ char *delstr="D"; /* Delete string */ char *DELPTR; /* DEL pointer */ BYTE idxfile; /* make idxfile */ char msgbuf[1024]; /* message buffer */ int curIndex; /* current index */ char arg1[300], arg2[300], arg3[300], arg4[300], arg5[300]; /*------------------------------*/ /* functions prototypes */ /*------------------------------*/ #ifdef ANSI /* Use ANSI C prototypes */ void beep(void); void BuildProc(void); void BuildString(int); char *CheckAbbrev(char s[], char *q); void CheckAlias(int); BYTE CheckLevel(int cur, int idx, BYTE level); int CompareStrings(int i,int j); int CompareStringsPO(int i,int j); void copyString(int,int,char *); void doNDX(int,char *); void doNPG(int,char *); void DoNormal(int idx,char arg[]); void DoVariant(int idx, char arg[]); int DupPageFormat(int idx, char arg[]); int DupEntry(int idx, int cur); int DupXref(int idx, int cur); void error(char *); void exit(int); int FindLastT( int idx ); void FreeEntry( int idx ); void FreeMem(void); void GetAbbrevSpace(int); void GetArg(int idx,char arg[],BYTE pre,BYTE cs,BYTE entry, BYTE post,BYTE alias); void GetArgs(int idx,char *arg1,char *arg2,char *arg3, char *arg4,char *arg5); BYTE GetD2(int cur,int idx); void GetFieldSpace(int); BYTE GetPageNum(int idx); int GetPageOrder(int); void GetPageOrderSpace(int); char *GetStringSpace(char *); int GetSubLevel(int, int); void InitProc(void); void OutputProc(int idx,char *arg1,char *arg2,char *arg3, char *arg4,char *arg5); int main(int argc, char *argv[]); void MoveEntry( int from, int to ); void PreProc(void); void printMSG(char *); void PrintErrorMSG(void); void PutPageNum(int idx); void PutByte( char c, FILE *f ); void PutString( char string[], FILE *f ); void ReduceSpaces(char *); void RemoveDuplicates( void ); void RemoveEmptySet(char *str); void RemoveSpaces(char *); void RemoveTrailingSpace(char *str); void ScanEntry( char line[] ); char *SkipSpaces(char *p); void SkipSpacesReverse(int len, char *p); void SortPageNumber( int beg, int end ); void SortProc(void); void strCopy(char *,char *,int); void SwapStrings(int cur, int nxt); void syntax_error(char *); void TeXOut(void); void TeXPut(int idx); void xref_proc(int idx); void xxref_proc(int idx); void other_proc(int idx); #else /* Use old-style K&R function declarations */ void beep(); void BuildProc(); void BuildString(); char *CheckAbbrev(); void CheckAlias(); BYTE CheckLevel(); int CompareStrings(); int CompareStringsPO(); void copyString(); void doNDX(); void doNPG(); void DoNormal(); void DoVariant(); int DupPageFormat(); int DupEntry(); int DupXref(); void error(); void exit(); int FindLastT(); void FreeEntry(); void FreeMem(); void GetAbbrevSpace(); void GetArg(); void GetArgs(); BYTE GetD2(); void GetFieldSpace(); BYTE GetPageNum(); int GetPageOrder(); void GetPageOrderSpace(); char *GetStringSpace(); int GetSubLevel(); void InitProc(); void OutputProc(); int main(); void MoveEntry(); void PreProc(); void printMSG(); void PrintErrorMSG(); void PutPageNum(); void PutByte(); void PutString(); void ReduceSpaces(); void RemoveDuplicates(); void RemoveEmptySet(); void RemoveSpaces(); void RemoveTrailingSpace(); void ScanEntry(); char *SkipSpaces(); void SkipSpacesReverse(); void SortPageNumber(); void SortProc(); void strCopy(); void SwapStrings(); void syntax_error(); void TeXOut(); void TeXPut(); void xref_proc(); void xxref_proc(); void other_proc(); #endif /*------------------------------*/ /* functions */ /*------------------------------*/ void beep() { printf("\007\b"); return; } void FreeMem() { int i,j; for (i=0; i<=nitems; i++) { if ( Entry[i].item!=NULL ) { for (j=E1; j<=CROSS_REF; j++) { if (Entry[i].item->fields[j]!=NULLPTR ) free( Entry[i].item->fields[j] ); } } } for (i=0; iastr != NULL ) free( abbrev[i]->astr ); if ( abbrev[i]->xstr != NULL ) free( abbrev[i]->xstr ); free( abbrev[i] ); } for (i=0; istyle !=NULL ) free( PO[i]->style ); if ( PO[i]->pre !=NULL ) free( PO[i]->pre ); if ( PO[i]->post !=NULL ) free( PO[i]->post ); free( PO[i] ); } return; } void error(s) char *s; { beep(); printf("\n%s\n",s); FreeMem(); exit(0); } void syntax_error(s) char *s; { sprintf(string,"syntax error! -> %s",s); error(string); } void printMSG(s) char *s; { int i; printf("\r"); for (i=0; i<78; i++) printf(" "); printf("\r"); printf("%s",s); return; } void PutByte(c,f) char c; FILE *f; { fputc( c, f ); if ( ferror(f) ) error("! File write error - out of disk space"); } /* end - PutByte */ void PutString(s,f) char *s; FILE *f; { fputs( s, f ); if ( ferror(f) ) error("! File write error - out of disk space"); } /* end - PutString */ /* Get Field Space */ void GetFieldSpace(idx) int idx; { int i; /* Check for boundary conditions */ if ( idx >= MAX_ENTRIES ) { sprintf(string,"! number of entries (%d) exceeded MAXIMUM allowed (%d)", idx,MAX_ENTRIES); error( string ); } Entry[idx].item = (FieldType *) malloc( sizeof(FieldType) ); if ( Entry[idx].item==NULL ) error("! out of fields space"); for (i=0; i<35; i++) Entry[idx].item->fields[i]=NULLPTR; return; } /* Get Abbrev Space */ void GetAbbrevSpace(idx) int idx; { /* Check for boundary conditions */ if ( idx >= MAX_ABBREVS ) { sprintf(string,"! number of abbrevs (%d) exceeded MAXIMUM allowed (%d)", idx,MAX_ABBREVS); error( string ); } abbrev[idx] = (AbbrvType *) malloc( sizeof(AbbrvType) ); if ( abbrev[idx]==NULL ) error("! out of space"); abbrev[idx]->astr = NULL; abbrev[idx]->xstr = NULL; return; } /* Get PageOrder Space */ void GetPageOrderSpace(idx) int idx; { /* Check for boundary conditions */ if ( idx >= MAX_PAGEORDER ) { sprintf(string, "! number of pageorders directives (%d) exceeded MAXIMUM allowed (%d)", idx,MAX_PAGEORDER); error( string ); } PO[idx] = (PageOrderType *) malloc( sizeof(PageOrderType) ); if ( PO[idx]==NULL ) error("! out of space"); PO[idx]->style = NULL; PO[idx]->pre = NULL; PO[idx]->post = NULL; PO[idx]->order = 0; PO[idx]->nstyle = 0; PO[idx]->npre = 0; PO[idx]->npost = 0; return; } /* Get String Space */ char * GetStringSpace(str) char *str; { char *p; int i; i = strlen(str); p = (char *) malloc( i+1 ); if ( p==NULL ) error("! out of strings space"); return(p); } void InitProc() { int i; for (i=0; ifields[i]!=NULLPTR ) { memcpy(cbuf,Entry[idx].item->fields[i], strlen(Entry[idx].item->fields[i])+1); } else cbuf[0]=0; sprintf(str,"%s %c",cbuf,BAR); strcat(string,str); break; default: if ( Entry[idx].item->fields[i]!=NULLPTR ) memcpy(cbuf,Entry[idx].item->fields[i], strlen(Entry[idx].item->fields[i])+1); else cbuf[0] = 0; sprintf(str,"%s %c",cbuf,BAR); ReduceSpaces(&str[0]); strcat(string,str); break; } } for (i=NUMBER; i<=CROSS_REF; i++) { if ( Entry[idx].item->fields[i]!=NULLPTR ) memcpy(cbuf,Entry[idx].item->fields[i], strlen(Entry[idx].item->fields[i])+1); else cbuf[0]=0; sprintf(str,"%s%c",cbuf,BAR); ReduceSpaces(&str[0]); strcat(string,str); } return; } int GetSubLevel(n,op) int n,op; { int cur; switch ( op ) { case 'a': cur = 22 + n; curEntry = ALIAS_TYPE; alias = TRUE; break; case MINUS: cur = n*3 -1; curEntry = PRE_TYPE; break; case PLUS: cur = n*3; curEntry = POST_TYPE; break; case 'e': cur = 27 + n; curEntry = ENTRY_TYPE; break; default: cur = 0; break; } return(cur); } void CheckAlias(idx) int idx; { char *p; if ( Entry[idx].item->fields[E1_ALIAS]!=NULLPTR ) { p = Entry[idx].item->fields[E1]; Entry[idx].item->fields[E1] = Entry[idx].item->fields[E1_ALIAS]; Entry[idx].item->fields[E1_ALIAS] = p; } if ( Entry[idx].item->fields[E2_ALIAS]!=NULLPTR ) { p = Entry[idx].item->fields[E2]; Entry[idx].item->fields[E2] = Entry[idx].item->fields[E2_ALIAS]; Entry[idx].item->fields[E2_ALIAS] = p; } if ( Entry[idx].item->fields[E3_ALIAS]!=NULLPTR ) { p = Entry[idx].item->fields[E3]; Entry[idx].item->fields[E3] = Entry[idx].item->fields[E3_ALIAS]; Entry[idx].item->fields[E3_ALIAS] = p; } if ( Entry[idx].item->fields[E4_ALIAS]!=NULLPTR ) { p = Entry[idx].item->fields[E4]; Entry[idx].item->fields[E4] = Entry[idx].item->fields[E4_ALIAS]; Entry[idx].item->fields[E4_ALIAS] = p; } if ( Entry[idx].item->fields[E5_ALIAS]!=NULLPTR ) { p = Entry[idx].item->fields[E5]; Entry[idx].item->fields[E5] = Entry[idx].item->fields[E5_ALIAS]; Entry[idx].item->fields[E5_ALIAS] = p; } return; } void strCopy(d,s,len) char *d, *s; int len; { int i; for (i=0; i<=len; i++) *(d+i) = *(s+i); return; } void copyString(idx,cur,str) int idx,cur; char *str; { if ( cur == 0 ) return; Entry[idx].item->fields[cur] = GetStringSpace( str ); strcpy(Entry[idx].item->fields[cur], str ); return; } char *SkipSpaces(p) char *p; { while ( *p==SPACE && *p!=0 ) p++; return(p); } void SkipSpacesReverse(len,q) int len; char *q; { char *r; r = q-2; while ( *r==SPACE && len>0 ) { r--; len--; } r++; *r = 0; return; } void RemoveSpaces(str) char *str; { char *p; char *q; p = q = str; while ( *p != 0 ) { if ( (*p == SPACE) ) p++; else *q++ = *p++; } *q = *p; return; } void RemoveEmptySet(str) char *str; { char *p; char *q; if ( strlen(str) <= 2 ) return; p = str; q = str; while ( *p != 0 ) { if ( (*p == LBRACE) && (*(p+1) == RBRACE) ) p+=2; else *q++ = *p++; } *q = *p; return; } void RemoveTrailingSpace(str) char *str; { char *p; char *q; p = str; q = str; while ( *p != 0 ) { if ( (*p == SPACE) && (*(p+1) == RBRACE) ) p++; else *q++ = *p++; } *q = *p; return; } void doNDX(idx,str) int idx; char str[]; { int i,j; char *p, *q, *r; int cur,e; BYTE done; j = strlen(str); p = &str[0]; p++; q = r = &string[0]; i = 0; e = 1; cur = E1; xref = FALSE; alias = FALSE; crossref = FALSE; done = FALSE; curEntry = OTHER_TYPE; while ( !done && i */ sprintf(string,"%d",e); copyString(idx,LARGEST,string); CheckAlias(idx); return; } void doNPG(idx,str) int idx; char str[]; { int i,j,k; char *p, *q, *r; int cur; char num[10],outstr[10]; j = strlen(str); p = &str[0]; p++; q = r = &string[0]; i = 0; while ( *p != RBRACE && i=0; k--) outstr[4-i+k] = num[k]; for (k=0; k<5; k++) outstr[k]; copyString(idx,NUMBER,outstr); p++; i++; cur = CSNAME; while ( iastr)==0 ) { found = TRUE; p = abbrev[i]->xstr; len = strlen(abbrev[i]->xstr); j = 0; while ( *p!=0 && j= MAX_DEFINES ) { sprintf(string, "! number of defines (%d) exceeded MAXIMUM allowed (%d)", ndef,MAX_DEFINES); error( string ); } define[ndef] = GetStringSpace(p); strcpy(define[ndef],p); ndef++; } else { if ( strnicmp(p,"\\abbrev",7)==0 ) { buf[len-1]=0; p+=7; GetAbbrevSpace(nabb); j=0; q = &buf[len-1]; i=0; /* remove spaces */ while ( *p==SPACE && iastr = GetStringSpace(p); strcpy(abbrev[nabb]->astr,p); p += j+1; j = len-1; i=0; /* remove spaces */ while ( *p==SPACE && ip ) q--; *q = 0; abbrev[nabb]->xstr = GetStringSpace(p); strcpy(abbrev[nabb]->xstr,p); nabb++; } else { i=0; /* remove spaces */ while ( *p==SPACE && i= q ) syntax_error(buf); *(p+j) = 0; PO[npo]->style = GetStringSpace(p); strcpy(PO[npo]->style,p); PO[npo]->nstyle = (BYTE) strlen(p); /* get pre page material */ p += j+1; j=0; while ( *(p+j)!=RBRACE && (p+j)= q ) syntax_error(buf); *(p+j) = 0; if ( j==0 ) { PO[npo]->pre = NULLPTR; } else { PO[npo]->pre = GetStringSpace(p); strcpy(PO[npo]->pre,p); } PO[npo]->npre = (BYTE) strlen(p); /* get post page material */ p += j+2; j=0; while ( *(p+j)!=RBRACE && (p+j)= q ) syntax_error(buf); *(p+j) = 0; if ( j==0 ) { PO[npo]->post = NULLPTR; } else { PO[npo]->post = GetStringSpace(p); strcpy(PO[npo]->post,p); } PO[npo]->npost = (BYTE) strlen(p); /* get page order */ p += j+1; if ( *p==LBRACE ) { p++; q--; *q=0; } PO[npo]->order =(BYTE) atoi(p); npo++; } /* endif page order */ else { if ( *p!=NL && *p!=SPACE ) { q = &string[0]; done = FALSE; status = FALSE; i = 0; *q++ = *p++; while ( i\n%s does not have a following \"{...}{...}{...}\" line.", abuf ); error( msgbuf ); } GetFieldSpace(i); ScanEntry( abuf ); doNDX(i,abuf); doNPG(i,bbuf); }; return; } /**********************************************************************/ /* ScanEntry: scan entry line and delete entry delimiters */ /* Inputs : line */ /* Output : line */ /**********************************************************************/ void ScanEntry( char line[] ) { int len,i; if ( line[0] == RSLASH ) { sprintf( msgbuf,"Entry ->\n%s begins with a '\\'.", line ); error( msgbuf ); } else line[0] = SPACE; len = strlen( line ); i = strlen(line) - 2; while( i>0 && line[i] == SPACE ) { i--; } line[i] = SPACE; line[i] = NL; return; } int PageOrderSort(i,j) int i, j; { int stat,n,k; int i_order, j_order; i_order=GetPageOrder(i); j_order=GetPageOrder(j); stat = 0; for (n=PageOrderFirst; n<=PageOrderLast && stat==0; n++) { k = PageOrder[n]; stat=strcmp(Entry[i].item->fields[k],Entry[j].item->fields[k]); switch ( k ) { case CSNAME: case PREFIX: if ( stat!= 0 ) { if ( i_order < j_order ) return( -1 ); if ( i_order > j_order ) return( 1 ); return ( stat ); } break; case NUMBER: if ( stat != 0 ) { if ( (i_order == j_order) && (i_order == MAX_PAGEORDER) ) return( stat ); if ( (i_order == MAX_PAGEORDER) && (j_order < i_order) ) return( 1 ); if ( (j_order == MAX_PAGEORDER) && (i_order < j_order) ) return( -1 ); return( stat ); } else { if ( i_order < j_order ) return( -1 ); if ( i_order > j_order ) return( 1 ); } break; case POSTFIX: if ( stat!= 0 ) { if ( i_order < j_order ) return( -1 ); if ( i_order > j_order ) return( 1 ); return ( stat ); } break; default: break; } /* switch */ } /* for */ return( stat ); } int CompareStrings(i,j) int i,j; { int n,k; int stat; stat=0; for (n=FirstOrder; n<=LastOrder && stat==0; n++) { k = SortingOrder[n]; stat=stricmp(Entry[i].item->fields[k],Entry[j].item->fields[k]); } if ( stat==0 ) { stat = PageOrderSort(i,j); } /* if */ return( stat ); } int GetPageOrder(idx) int idx; { int i,done; int order; order = MAX_PAGEORDER; for (i=0,done=FALSE; ifields[CSNAME],PO[i]->style, PO[i]->nstyle)==0 && strncmp(Entry[idx].item->fields[PREFIX],PO[i]->pre, PO[i]->npre)==0 && strncmp(Entry[idx].item->fields[POSTFIX],PO[i]->post, PO[i]->npost)==0 ) { order = PO[i]->order; done = TRUE; } } return(order); } void SwapStrings(cur,nxt) int cur,nxt; { int k; char *p; for (k=E1; k<=CROSS_REF; k++) { p = Entry[cur].item->fields[k]; Entry[cur].item->fields[k] = Entry[nxt].item->fields[k]; Entry[nxt].item->fields[k] = p; } return; } void SortProc() { int i,j,n; FILE *f; int gap; printMSG("sorting..."); /* Shell sort */ n = nitems+1; for ( gap=n/2; gap>0; gap/=2 ) { for ( i=gap; i0 && CompareStrings(j,j+gap) > 0; j-=gap ) { SwapStrings(j,j+gap); } } } /* write out sorted list - this is for debugging only */ if ( idxfile ) { f = fopen(idxname,"w"); if ( f==NULL ) { sprintf(string,"File write error %s",idxname); error(string); } for (i=1; i<=nitems; i++) { BuildString(i); PutString( string, f ); PutByte( NL, f); } fclose(f); } return; } int CompareStringsPO(i,j) int i,j; { int stat; stat = PageOrderSort(i,j); return( stat ); } /**********************************************************************/ /* Sort Page Numbers */ /* Inputs: beginning entry, ending entry */ /* Output: Sorted list of page numbers entries */ /**********************************************************************/ void SortPageNumber(beg,end) int beg, end; { int i,j,k,n; int change,status; /* Check for boundary conditions */ if ( ( end - beg ) >= MAX_PAGEENTRY ) { sprintf(string,"! page line entries (%d) exceeded MAXIMUM allowed (%d)", end-beg,MAX_PAGEENTRY ); error( string ); } n = 0; for (i=beg; ifields[XREF])!='x' ) { SubPageOrder[n] = i; n++; } } /* Refined Bubble sort - for simplicity Note: we only need to sort a subset of the entries. Sorting is done using an array of indices without physically swapping entries. */ change = TRUE; for (i=0; i0 ) { k = SubPageOrder[j+1]; SubPageOrder[j+1] = SubPageOrder[j]; SubPageOrder[j] = k; change=TRUE; } } } return; } BYTE CheckLevel(cur,idx,level) int cur,idx; BYTE level; { BYTE entry_i, pre_i, post_i, alias_i, cs_i; switch ( level ) { case LEVEL1: entry_i = E1; pre_i = E1_PRE; post_i = E1_POST; alias_i = E1_ALIAS; cs_i = E1_CS; break; case LEVEL2: entry_i = E2; pre_i = E2_PRE; post_i = E2_POST; alias_i = E2_ALIAS; cs_i = E2_CS; break; case LEVEL3: entry_i = E3; pre_i = E3_PRE; post_i = E3_POST; alias_i = E3_ALIAS; cs_i = E3_CS; break; case LEVEL4: entry_i = E4; pre_i = E4_PRE; post_i = E4_POST; alias_i = E4_ALIAS; cs_i = E4_CS; break; case LEVEL5: entry_i = E5; pre_i = E5_PRE; post_i = E5_POST; alias_i = E5_ALIAS; cs_i = E5_CS; break; } if ( strcmp(Entry[cur].item->fields[entry_i], Entry[idx].item->fields[entry_i])==0 && strcmp(Entry[cur].item->fields[pre_i], Entry[idx].item->fields[pre_i]) ==0 && strcmp(Entry[cur].item->fields[post_i], Entry[idx].item->fields[post_i]) ==0 && strcmp(Entry[cur].item->fields[alias_i], Entry[idx].item->fields[alias_i])==0 && strcmp(Entry[cur].item->fields[cs_i], Entry[idx].item->fields[cs_i]) ==0 ) return(TRUE); else return(FALSE); } BYTE GetD2(cur,idx) int cur; int idx; { if ( CheckLevel( cur,idx,LEVEL1 ) ) { if ( CheckLevel( cur,idx,LEVEL2 ) ) { if ( CheckLevel( cur,idx,LEVEL3) ) { if ( CheckLevel( cur,idx,LEVEL4 ) ) { if ( CheckLevel ( cur,idx,LEVEL5 ) ) return(LEVEL5); else return(LEVEL4); } else return(LEVEL3); } else return(LEVEL2); } else return(LEVEL1); } else return(LEVEL0); return(LEVEL0); } void GetArg(idx,arg,pre,cs,entry,post,alias) int idx; char arg[]; BYTE pre,cs,entry,post,alias; { if ( Entry[idx].item->fields[alias]!=NULLPTR ) entry = alias; if ( Entry[idx].item->fields[cs]==NULLPTR ) { if ( Entry[idx].item->fields[pre]==NULLPTR && Entry[idx].item->fields[post]==NULLPTR ) sprintf(arg,"{%s}",Entry[idx].item->fields[entry]); else sprintf(arg,"{{%s}{%s}{%s}}",Entry[idx].item->fields[pre], Entry[idx].item->fields[entry],Entry[idx].item->fields[post]); } else { sprintf(arg,"{{%s}{%s{%s}}{%s}}",Entry[idx].item->fields[pre], Entry[idx].item->fields[cs], Entry[idx].item->fields[entry],Entry[idx].item->fields[post]); } RemoveEmptySet(arg); return; } void DoNormal(idx,arg) int idx; char arg[]; { char *p; char str[80]; int pn; pn = atoi(Entry[idx].item->fields[NUMBER]); strcpy( str, Entry[idx].item->fields[CSNAME] ); p = &str[0]; if ( strncmp(p,"\\arabic",7)==0 ) *p=0; if ( Entry[idx].item->fields[CTRLSEQ]==NULLPTR ) { if ( Entry[idx].item->fields[PREFIX]==NULLPTR && Entry[idx].item->fields[POSTFIX]==NULLPTR ) { if ( *p==0 ) sprintf(arg,"{%d}",pn); else sprintf(arg,"{%s{%d}}",p,pn); } else { if ( *p==0 ) sprintf(arg,"{{%s}{%d}{%s}}", Entry[idx].item->fields[PREFIX],pn, Entry[idx].item->fields[POSTFIX]); else sprintf(arg,"{{%s}{%s{%d}}{%s}}", Entry[idx].item->fields[PREFIX],p,pn, Entry[idx].item->fields[POSTFIX]); } } else { if ( Entry[idx].item->fields[PREFIX]==NULLPTR && Entry[idx].item->fields[POSTFIX]==NULLPTR ) { if ( *p == 0 ) sprintf(arg,"{%s{%d}}",Entry[idx].item->fields[CTRLSEQ],pn); else sprintf(arg,"{%s{%s{%d}}}",Entry[idx].item->fields[CTRLSEQ], p,pn); } else { if ( *p == 0 ) sprintf(arg,"{%s{{%s}{%d}{%s}}}", Entry[idx].item->fields[CTRLSEQ], Entry[idx].item->fields[PREFIX],pn, Entry[idx].item->fields[POSTFIX]); else sprintf(arg,"{%s{{%s}{%s{%d}}{%s}}}", Entry[idx].item->fields[CTRLSEQ], Entry[idx].item->fields[PREFIX],p,pn, Entry[idx].item->fields[POSTFIX]); } } return; } void DoVariant(idx,arg) int idx; char arg[]; { char *p; int pn; char str[80]; pn = atoi(Entry[idx].item->fields[NUMBER]); strcpy(str,Entry[idx].item->fields[CSNAME]); p = &str[0]; if ( strncmp(p,"\\arabic",7)==0 ) *p=0; if ( Entry[idx].item->fields[PREFIX]==NULLPTR && Entry[idx].item->fields[POSTFIX]==NULLPTR ) { if ( *p==0 ) sprintf(arg,"{%s }{%d}",Entry[idx].item->fields[CTRLSEQ],pn); else sprintf(arg,"{%s }{%s{%d}}",Entry[idx].item->fields[CTRLSEQ],p,pn); } else { if ( *p==0 ) sprintf(arg,"{%s }{{%s}{%d}{%s}}", Entry[idx].item->fields[CTRLSEQ], Entry[idx].item->fields[PREFIX],pn, Entry[idx].item->fields[POSTFIX]); else sprintf(arg,"{%s }{{%s}{%s{%d}}{%s}}", Entry[idx].item->fields[CTRLSEQ], Entry[idx].item->fields[PREFIX], p,pn,Entry[idx].item->fields[POSTFIX]); } return; } void PrintErrorMSG() { int i; PutString( "%% ",xdxfile ); for (i=0; i<72; i++) PutByte('/',xdxfile); PutByte( NL, xdxfile ); PutString("%%\n",xdxfile); PutString( msgbuf,xdxfile ); PutString("%%\n",xdxfile); PutString("%% ",xdxfile); for (i=0; i<72; i++) PutByte('\\',xdxfile); PutByte( NL, xdxfile); return; } int DupPageFormat(idx,arg) int idx; char arg[]; { int i,level; BYTE done; char tmpbuf[300]; for (i=idx-1, done=FALSE; i>0 && !done; i--) { level = GetD2(i,idx); if ( level==LEVEL5 ) { if ( strcmp(Entry[idx].item->fields[NUMBER], Entry[i].item->fields[NUMBER])==0 && strcmp(Entry[idx].item->fields[CTRLSEQ], Entry[i].item->fields[CTRLSEQ])!=0 ) { RemoveEmptySet(arg); sprintf(msgbuf,"%% \\Page %s\n",arg); sprintf(tmpbuf, "%% Duplicate page number formatted differently\n"); strcat(msgbuf,tmpbuf); PrintErrorMSG(); done = TRUE; return( FALSE ); } /* if */ } /* if - level */ else done = TRUE; } /* for */ return(TRUE); } /**********************************************************************/ /* Find The Last matching t entry */ /* Inputs: index into current entry */ /* Output: TRUE if found, FALSE if not */ /**********************************************************************/ int FindLastT(idx) int idx; { int i,level,done; Tindex = 0; done = FALSE; level = GetD2(idx-1,idx); for ( i=idx-1; ( i>0 ) && ( level==LEVEL5 ) && !done ; i-- ) { done = TRUE; if ( strcmp(Entry[idx].item->fields[NUMBER], Entry[i].item->fields[NUMBER])==0 && strcmp(Entry[idx].item->fields[PAGE_SPAN], Entry[i].item->fields[PAGE_SPAN])==0 ) { Tindex = i; done = FALSE; } level = GetD2(i-1,idx); } if ( Tindex != 0 ) return( TRUE ); else return( FALSE ); } BYTE GetPageNum(idx) int idx; { char type; char arg[300]; int status; char tmpbuf[300]; type = *(Entry[idx].item->fields[PAGE_SPAN]); skippage = FALSE; switch ( type ) { case 'F': DoVariant(idx,arg); if ( PageType=='f' || PageType=='F' ) { sprintf(msgbuf,"%% \\Pagespan %s\n",arg); sprintf(tmpbuf, "%% Page span starting at %s within span starting at %d\n", arg,atoi(Entry[PageIndex].item->fields[NUMBER])); strcat(msgbuf,tmpbuf); PrintErrorMSG(); skippage = TRUE; return(FALSE); } PageType = type ; PageIndex = idx; PageSpan = TRUE; break; case 'f': DoNormal(idx,arg); if ( PageType=='f' || PageType=='F' ) { sprintf(msgbuf,"%% \\Pagespan %s\n",arg); sprintf(tmpbuf, "%% Page span starting at %s within span starting at %d\n", arg,atoi(Entry[PageIndex].item->fields[NUMBER])); strcat(msgbuf,tmpbuf); PrintErrorMSG(); skippage = TRUE; return(FALSE); } PageType = type ; PageIndex = idx; PageSpan = TRUE; break; case 't': switch ( PageType ) { case 'F': DoVariant(idx,arg); break; case 'f': DoNormal(idx,arg); break; default: DoNormal(idx,arg); if ( FindLastT(idx) ) { sprintf(msgbuf,"%% \\Topage %s\n",arg); sprintf(tmpbuf, "%% Span ending at %s also ending at {%s {%d}}\n", arg, Entry[Tindex].item->fields[CTRLSEQ], atoi(Entry[Tindex].item->fields[NUMBER])); strcat(msgbuf,tmpbuf); PrintErrorMSG(); skippage = TRUE; PageType = 0; PageIndex = 0; PageSpan = FALSE; return(FALSE); } sprintf(msgbuf,"%% \\Topage %s\n",arg); sprintf(tmpbuf, "%% Page span ending at %s has no starting page\n", arg); strcat(msgbuf,tmpbuf); PrintErrorMSG(); skippage = TRUE; PageType = 0; PageIndex = 0; PageSpan = FALSE; return(FALSE); break; } /* switch */ break; default: DoNormal(idx,arg); if ( PageSpan ) { /* Drop it if within page span */ status = stricmp(Entry[idx].item->fields[CTRLSEQ], Entry[PageIndex].item->fields[CTRLSEQ]); if ( status == 0 ) return( FALSE ); else { sprintf(msgbuf, "%% Page %s%s within span starting at {%s {%d}}\n", Entry[idx].item->fields[CTRLSEQ],arg, Entry[PageIndex].item->fields[CTRLSEQ], atoi(Entry[PageIndex].item->fields[NUMBER])); PrintErrorMSG(); skippage = TRUE; return( FALSE ); } /* else */ } /* if */ status = DupPageFormat(idx,arg); if ( !status ) return( FALSE ); break; } /* switch */ RemoveEmptySet(arg); strcpy(prevnum,pagenum); strcpy(pagenum,arg); return(TRUE); } void PutPageNum(idx) int idx; { char c; char str[80]; if ( skippage ) return; c = *(Entry[idx].item->fields[PAGE_SPAN]) ; switch ( c ) { case 'f': sprintf(str,"\\Pagespan %s\n",pagenum); PutString( str, xdxfile ); break; case 'F': sprintf(str,"\\PageSpan %s\n",pagenum); PutString( str, xdxfile ); break; case 't': sprintf(str,"\\Topage %s\n",pagenum); PutString( str, xdxfile ); if ( strcmp( Entry[idx].item->fields[CTRLSEQ], Entry[PageIndex].item->fields[CTRLSEQ] ) !=0 ) { sprintf(msgbuf,"%% \\Page span from {%s {%d}} to %s\n", Entry[PageIndex].item->fields[CTRLSEQ], atoi(Entry[PageIndex].item->fields[NUMBER]), pagenum); PrintErrorMSG(); } PageType = 0; PageIndex = 0; PageSpan = FALSE; break; default: sprintf(str,"\\Page %s\n",pagenum); PutString( str, xdxfile ); break; } return; } void GetArgs(idx,arg1,arg2,arg3,arg4,arg5) int idx; char *arg1, *arg2, *arg3, *arg4, *arg5; { GetArg(idx,arg1,E1_PRE,E1_CS,E1,E1_POST,E1_ALIAS); GetArg(idx,arg2,E2_PRE,E2_CS,E2,E2_POST,E2_ALIAS); GetArg(idx,arg3,E3_PRE,E3_CS,E3,E3_POST,E3_ALIAS); GetArg(idx,arg4,E4_PRE,E4_CS,E4,E4_POST,E4_ALIAS); GetArg(idx,arg5,E5_PRE,E5_CS,E5,E5_POST,E5_ALIAS); return; } int DupEntry( idx, cur ) int idx,cur; { int i,k,stat; for (i=cur; ifields[k],Entry[idx].item->fields[k]); } if ( stat == 0 ) return( TRUE ); } /* for */ if ( stat == 0 ) return( TRUE ); else return ( FALSE ); } /* end - DupEntry */ int DupXref( idx, cur ) int idx,cur; { int i; for (i=idx; ifields[CROSS_REF], Entry[cur].item->fields[CROSS_REF] ) == 0 ) return( TRUE ); } return ( FALSE ); } /* end - DupXref */ void xxref_proc(idx) int idx; { int i,d2,nxt,level,n; BYTE done; char xtype; int status; /* put out 1 cross reference */ GetArgs(idx,arg1,arg2,arg3,arg4,arg5); d2 = GetD2(idx,idx-1); sprintf(msgbuf,"\\Entry %s%d%s%s%s%s%s\n", Entry[idx].item->fields[LARGEST],d2,arg1,arg2,arg3,arg4,arg5); PutString( msgbuf, xdxfile ); sprintf(msgbuf,"\\Xref {\\See {%s}}\n", Entry[idx].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); /* Gather all the cross references */ nxt = 1; done = FALSE; while ( !done && (idx+nxt)<=nitems ) { level = GetD2(idx,idx+nxt); xtype = (char) *(Entry[idx+nxt].item->fields[XREF]); if ( level==LEVEL5 && ( xtype=='X' || xtype=='x' ) ) { if ( !DupXref(idx, idx+nxt) ) { sprintf(msgbuf,"\\Morexref {\\See {%s}}\n", Entry[idx+nxt].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); } nxt++; } else { done = TRUE; } } SortPageNumber(idx,idx+nxt); n = 0; for ( i=idx; ifields[XREF]); if ( xtype != 'x' ) { status = GetPageNum(SubPageOrder[n]); if ( status ) PutPageNum(SubPageOrder[n]); n++; } } /* put out cross references again */ sprintf(msgbuf,"\\Xref {\\See {%s}}\n", Entry[idx].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); for ( i=idx+1; ifields[XREF]); if ( level==LEVEL5 && ( xtype=='X' || xtype=='x' ) ) { if ( !DupXref(idx,i) ) { sprintf(msgbuf,"\\Morexref {\\See {%s}}\n", Entry[i].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); } } /* if */ } /* for */ curIndex = idx + nxt; return; } /* xxref_proc */ void xref_proc(idx) int idx; { int nxt,level,d2,i; BYTE done; char xtype; BYTE ctype; /* CASE I or CASE II */ nxt = 1; done = FALSE; ctype = 1; while ( !done && (idx+nxt)<=nitems ) { level = GetD2(idx+nxt,idx); xtype = (char) *(Entry[idx+nxt].item->fields[XREF]); if ( level==LEVEL5 && ( xtype=='X' || xtype =='x') ) { if ( xtype == 'X' ) ctype = 2; nxt++; } else { done = TRUE; } } /* while */ /* CASE I */ if ( ctype == 1 ) { /* put out 1 cross reference */ GetArgs(idx,arg1,arg2,arg3,arg4,arg5); d2 = GetD2(idx,idx-1); sprintf(msgbuf,"\\Entryxref %s%d%s%s%s%s%s{\\See {%s}}\n", Entry[idx].item->fields[LARGEST],d2,arg1,arg2,arg3,arg4,arg5, Entry[idx].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); /* Gather up all the cross references */ for ( i=idx+1; ifields[XREF]); if ( level==LEVEL5 && xtype=='x' ) { if ( !DupXref(idx,i) ) { sprintf(msgbuf,"\\Morexref {\\See {%s}}\n", Entry[i].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); } } else { done = TRUE; } } /* while */ curIndex = idx + nxt; } /* if */ /* CASE II */ else { xxref_proc( idx ); } return; } /* end - xref_proc */ void OutputProc(idx,arg1,arg2,arg3,arg4,arg5) int idx; char *arg1, *arg2, *arg3, *arg4, *arg5; { int d2, status; d2 = GetD2(idx,idx-1); if ( d2==LEVEL5 ) { if ( !DupEntry( idx, idx-1 ) ) { status = GetPageNum(idx); if ( status ) PutPageNum(idx); } } else { sprintf(msgbuf,"\\Entry %s%d%s%s%s%s%s\n", Entry[idx].item->fields[LARGEST],d2,arg1,arg2,arg3,arg4,arg5); PutString( msgbuf, xdxfile ); status = GetPageNum(idx); if ( status ) PutPageNum(idx); } return; } /* end - OutputProc */ void other_proc(idx) int idx; { int i,d2,nxt,level,n; BYTE done,first; char xtype,ctype; int status; /* this is the last line */ if ( idx+1 > nitems ) { /* finish up and exits */ GetArgs(idx,arg1,arg2,arg3,arg4,arg5); OutputProc(idx,arg1,arg2,arg3,arg4,arg5); curIndex++; return; } /* Get all the LEVEL5 entries */ nxt = 1; done = FALSE; ctype = FALSE; while ( !done && (idx+nxt)<=nitems ) { level = GetD2(idx+nxt,idx); xtype = (char) *(Entry[idx+nxt].item->fields[XREF]); if ( level==LEVEL5 ) { if ( xtype == 'X' || xtype == 'x' ) ctype = TRUE; nxt++; } else { done = TRUE; } } if ( !ctype ) { /* Not a cross reference, so we output line and return */ GetArgs(idx,arg1,arg2,arg3,arg4,arg5); OutputProc(idx,arg1,arg2,arg3,arg4,arg5); curIndex++; return; } /* put out entry first */ GetArgs(idx,arg1,arg2,arg3,arg4,arg5); d2 = GetD2(idx,idx-1); sprintf(msgbuf,"\\Entry %s%d%s%s%s%s%s\n", Entry[idx].item->fields[LARGEST],d2,arg1,arg2,arg3,arg4,arg5); PutString( msgbuf, xdxfile ); /* Gather all the cross references */ first = TRUE; for (i=idx+1; ifields[XREF]); if ( level==LEVEL5 && ( xtype=='X' || xtype=='x' ) ) { if ( !DupXref(idx,i) ) { if ( first ) { first = FALSE; sprintf(msgbuf,"\\Xref {\\See {%s}}\n", Entry[i].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); } /* if */ else { sprintf(msgbuf,"\\Morexref {\\See {%s}}\n", Entry[i].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); } /* else */ } /* if - dupXref */ } /* if - level */ } /* for */ /* We need to sort a subset of the entries base on page order, viz, entries with LEVEL5 */ SortPageNumber(idx,idx+nxt); n = 0; for ( i=idx; ifields[XREF]); switch ( xtype ) { case 'x': break; case 'X': default: status = GetPageNum(SubPageOrder[n]); if ( status ) PutPageNum(SubPageOrder[n]); n++; break; } /* switch */ } /* for */ /* put out cross references again */ first = TRUE; for ( i=idx+1; ifields[XREF]); if ( level==5 && ( xtype=='X' || xtype=='x' ) ) { if ( !DupXref(idx,i) ) { if ( first ) { sprintf(msgbuf,"\\Xref {\\See {%s}}\n", Entry[i].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); first = FALSE; } /* if */ else { sprintf(msgbuf,"\\Morexref {\\See {%s}}\n", Entry[i].item->fields[CROSS_REF]); PutString( msgbuf, xdxfile ); } /* else */ } /* if */ } /* if */ } /* for */ curIndex = idx + nxt; return; } /* end - other_proc */ void TeXPut(idx) int idx; { char xtype; curLetter = (char) toupper(*(Entry[idx].item->fields[E1])); if ( curLetter != preLetter ) { sprintf(msgbuf,"\n\\LETTER %c\n\n",curLetter); PutString( msgbuf, xdxfile ); preLetter = curLetter; } xtype = (char) *(Entry[idx].item->fields[XREF]); switch( xtype ) { case 'x': xref_proc(idx); break; case 'X': xxref_proc(idx); break; default: other_proc(idx); break; } return; } /* end - TeXPut */ void TeXOut() { int i; printMSG("writing output..."); preLetter = 0; for (i=0; ifields[k] = Entry[from].item->fields[k]; } return; } /* end - MoveEntry */ /**********************************************************************/ /* Free Entry */ /* Inputs: idx */ /* Output: none */ /**********************************************************************/ void FreeEntry(idx) int idx; { int j; if ( Entry[idx].item!=NULL ) { for ( j=E1; j<=CROSS_REF; j++ ) { if ( Entry[idx].item->fields[j]!=NULLPTR ) free( Entry[idx].item->fields[j] ); Entry[idx].item->fields[j] = NULLPTR; } } return; } /* end - FreeEntry */ /**********************************************************************/ /* Remove Duplicates Entries */ /* Inputs: none */ /* Output: modified nitems */ /**********************************************************************/ void RemoveDuplicates() { int i,j,cur,level; cur = 1; for ( i=2; i<=nitems; i++ ) { if ( DupEntry( i, cur ) ) { Entry[i].item->fields[0] = DELPTR; } level = GetD2(i,cur); if ( level!=LEVEL5 ) cur = i; } for ( i=1,j=1; i<=nitems; i++ ) { if ( Entry[i].item->fields[0]==DELPTR ) { FreeEntry(i); } else { MoveEntry(i,j); j++; } } nitems = --j; return; } /* end - RemoveDuplicates */ /* make main() an int so it returns something predictable to the OS */ int main(argc, argv) int argc; char *argv[]; { if ( argc<2 ) { printf("\n\tUsage: index filename\n"); exit(0); } printf("\n\tnewindex 1.10 All Rights Reserved."); printf("\n\tCopyright (c) 1989-91 The TeXplorators Corporation.\n"); strcpy(ndxname,argv[1]); strcat(ndxname,".ndx"); strcpy(tmpname,argv[1]); strcat(tmpname,".@d@"); strcpy(xdxname,argv[1]); strcat(xdxname,".xdx"); strcpy(idxname,argv[1]); strcat(idxname,".idx"); idxfile = FALSE; if ( argc > 2 ) { if ( strnicmp(argv[2],"-i",2)==0 ) idxfile = TRUE; } if ( ( ndxfile = fopen(ndxname,"r") )==NULL ) { printf("File %s not found\r\n",ndxname); beep(); exit(0); } if ( ( xxxfile = fopen(tmpname,"w+") )==NULL ) { printf("File %s cannot be opened\r\n",tmpname); beep(); exit(0); } if ( ( xdxfile = fopen(xdxname,"w") )==NULL ) { printf("File %s cannot be opened\r\n",xdxname); beep(); exit(0); } InitProc(); PreProc(); BuildProc(); fclose(ndxfile); SortProc(); RemoveDuplicates(); TeXOut(); fclose(xdxfile); fclose(xxxfile); #ifdef MICROSOFTC fcloseall(); #endif unlink(tmpname); FreeMem(); printMSG(""); printf("\r\n"); return(0); } /* ############################### END OF FILE ########################### */