summaryrefslogtreecommitdiff
path: root/indexing/lamstex-index
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /indexing/lamstex-index
Initial commit
Diffstat (limited to 'indexing/lamstex-index')
-rw-r--r--indexing/lamstex-index/DOS-EXE/INDEX.EXEbin0 -> 107149 bytes
-rw-r--r--indexing/lamstex-index/Makefile26
-rw-r--r--indexing/lamstex-index/config.MS.h6
-rw-r--r--indexing/lamstex-index/config.sun-gcc.h14
-rw-r--r--indexing/lamstex-index/index.c2689
5 files changed, 2735 insertions, 0 deletions
diff --git a/indexing/lamstex-index/DOS-EXE/INDEX.EXE b/indexing/lamstex-index/DOS-EXE/INDEX.EXE
new file mode 100644
index 0000000000..ead87eca98
--- /dev/null
+++ b/indexing/lamstex-index/DOS-EXE/INDEX.EXE
Binary files differ
diff --git a/indexing/lamstex-index/Makefile b/indexing/lamstex-index/Makefile
new file mode 100644
index 0000000000..43d97ee4d5
--- /dev/null
+++ b/indexing/lamstex-index/Makefile
@@ -0,0 +1,26 @@
+# Makefile for TeXplorators index
+#
+# config.sun-gcc.h is supplied as a model.
+# UnixTeX would like to hear of any interesting
+# configuration files for other systems.
+# Copy the appropriate config.*.h to config.h
+# then make
+#
+# This Makefile may not work for MSDOS. Make your
+# own one, or compile by hand.
+#
+CFLAGS = -g
+CC = gcc
+
+all: index
+
+index: index.o
+ cc -o index index.o
+
+index.o: index.c config.h
+
+clean:
+ rm -f *.o *~ \#* core
+
+veryclean: clean
+ rm -f config.h index
diff --git a/indexing/lamstex-index/config.MS.h b/indexing/lamstex-index/config.MS.h
new file mode 100644
index 0000000000..28244eca43
--- /dev/null
+++ b/indexing/lamstex-index/config.MS.h
@@ -0,0 +1,6 @@
+/* default environment */
+#define MICROSOFTC
+#define LITTLENDIAN
+#define ANSI
+#define READ_BINARY "rb"
+#define WRITE_BINARY "wb"
diff --git a/indexing/lamstex-index/config.sun-gcc.h b/indexing/lamstex-index/config.sun-gcc.h
new file mode 100644
index 0000000000..5d9442863b
--- /dev/null
+++ b/indexing/lamstex-index/config.sun-gcc.h
@@ -0,0 +1,14 @@
+#define int short
+#undef ANSI /* To use old-style K&R functions */
+#undef MICROSOFTC
+#undef LITTLENDIAN
+
+#ifdef ANSI
+/* Other things in ANSI C are good, but this is a crock */
+#define READ_BINARY "rb"
+#define WRITE_BINARY "wb"
+#else
+/* The good old simple and logical K&R I/O */
+#define READ_BINARY "r"
+#define WRITE_BINARY "w"
+#endif
diff --git a/indexing/lamstex-index/index.c b/indexing/lamstex-index/index.c
new file mode 100644
index 0000000000..b2d5bcd647
--- /dev/null
+++ b/indexing/lamstex-index/index.c
@@ -0,0 +1,2689 @@
+/************************************************************************/
+/* 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 <stdio.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <string.h>
+#ifdef ANSI
+#include <stdlib.h>
+#endif
+#include <memory.h>
+
+/*------------------------------*/
+/* 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; i<MAX_DEFINES; i++)
+ if ( define[i]!=NULL )
+ free( define[i] );
+ for (i=0; i<MAX_ABBREVS; i++)
+ if ( abbrev[i]!=NULL )
+ {
+ if ( abbrev[i]->astr != NULL ) free( abbrev[i]->astr );
+ if ( abbrev[i]->xstr != NULL ) free( abbrev[i]->xstr );
+ free( abbrev[i] );
+ }
+
+ for (i=0; i<MAX_PAGEORDER; i++)
+ if ( PO[i]!=NULL )
+ {
+ if ( PO[i]->style !=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; i<MAX_ENTRIES; i++)
+ Entry[i].item = NULL;
+ for (i=0; i<MAX_DEFINES; i++)
+ define[i] = NULL;
+ for (i=0; i<MAX_ABBREVS; i++)
+ abbrev[i] = NULL;
+ for (i=0; i<MAX_PAGEORDER; i++)
+ PO[i] = NULL;
+ FirstEntry = TRUE;
+ NULLPTR = &nullstr[0];
+ PageType = 0;
+ PageIndex = 0;
+ PageSpan = FALSE;
+ Tindex = 0;
+
+ SortingOrder[1] =E1;
+ SortingOrder[2] =E1_ALIAS;
+ SortingOrder[3] =E1_PRE;
+ SortingOrder[4] =E1_POST;
+
+ SortingOrder[5] =E2;
+ SortingOrder[6] =E2_ALIAS;
+ SortingOrder[7] =E2_PRE;
+ SortingOrder[8] =E2_POST;
+
+ SortingOrder[9] =E3;
+ SortingOrder[10]=E3_ALIAS;
+ SortingOrder[11]=E3_PRE;
+ SortingOrder[12]=E3_POST;
+
+ SortingOrder[13]=E4;
+ SortingOrder[14]=E4_ALIAS;
+ SortingOrder[15]=E4_PRE;
+ SortingOrder[16]=E4_POST;
+
+ SortingOrder[17]=E5;
+ SortingOrder[18]=E5_ALIAS;
+ SortingOrder[19]=E5_PRE;
+ SortingOrder[20]=E5_POST;
+ SortingOrder[21]=CROSS_REF;
+
+ FirstOrder = 1;
+ LastOrder = 21;
+
+ PageOrder[0] = CSNAME;
+ PageOrder[1] = PREFIX;
+ PageOrder[2] = NUMBER;
+ PageOrder[3] = POSTFIX;
+
+ PageOrderFirst = 0;
+ PageOrderLast = 3;
+
+ return;
+}
+
+void ReduceSpaces(str)
+char *str;
+{
+ char *p;
+ char *q;
+
+ p = str; q = str;
+ while ( *p != 0 )
+ {
+ if ( (*p == SPACE) && (*(p+1) == SPACE) ) p++;
+ else
+ *q++ = *p++;
+ }
+ *q = *p;
+ return;
+}
+
+
+void BuildString(idx)
+int idx;
+{
+ int i;
+ char cbuf[300];
+ char str[300];
+
+ string[0] = 0;
+ for (i=E1; i<NUMBER; i++)
+ {
+ switch( i )
+ {
+ case 2: case 5: case 8: case 11: case 14:
+ case 3: case 6: case 9: case 12: case 15:
+ 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);
+ 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<j )
+ {
+ switch ( *p )
+ {
+ case DQUOTE:
+ if ( *(p-1)==RSLASH )
+ *q++ = *p;
+ else
+ done = TRUE;
+ break;
+ case NL:
+ done = TRUE;
+ break;
+ case STAR:
+ *q++ = 0;
+ if ( cur!=0 )
+ {
+ SkipSpacesReverse(j,q);
+ copyString(idx,cur,string);
+ cur = 0;
+ }
+ q = r;
+ p++; i++;
+ switch ( *p )
+ {
+ case ONE: case TWO: case THREE: case FOUR: case FIVE:
+ cur = GetSubLevel( (*p)-ZERO,*(p+1) ); p++; i++;
+ q = r;
+ break;
+ case 'a':
+ p++; i++; q = r;
+ curEntry = ALIAS_TYPE;
+ alias = TRUE;
+ cur = E1_ALIAS;
+ break;
+ case MINUS:
+ p++; i++; q = r;
+ curEntry = PRE_TYPE;
+ cur = E1_PRE;
+ break;
+ case PLUS:
+ p++; i++; q = r;
+ curEntry = POST_TYPE;
+ cur = E1_POST;
+ break;
+ case 'e':
+ q = r;
+ curEntry = ENTRY_TYPE;
+ cur = E1_CS;
+ break;
+ case 'p':
+ q = r;
+ cur = CTRLSEQ;
+ break;
+ case 'f':
+ case 'F':
+ case 't':
+ q = r;
+ *q++ = *p; *q++ = 0;
+ copyString(idx,PAGE_SPAN,string);
+ q = r;
+ break;
+ case 'x':
+ if ( crossref )
+ {
+ sprintf(msgbuf,"%s\n *x and *X can't occur together\n",
+ str);
+ syntax_error(msgbuf);
+ }
+ strcpy(string,"x"); copyString(idx,XREF,string);
+ strcpy(string,"99999"); copyString(idx,NUMBER,string);
+ curEntry = XREF_TYPE; xref = TRUE;
+ q = r;
+ cur = CROSS_REF;
+ break;
+ case 'X':
+ if ( xref )
+ {
+ sprintf(msgbuf,"%s\n *x and *X can't occur together\n",
+ str);
+ syntax_error(msgbuf);
+ }
+ strcpy(string,"X"); copyString(idx,XREF,string);
+ crossref = TRUE;
+ cur = CROSS_REF; curEntry = XREF_TYPE;
+ q = r;
+ break;
+ case RSLASH:
+ cur = 0; break;
+ default:
+ syntax_error(str);
+ cur = 0;
+ break;
+ }
+ break;
+ case COMMA:
+ p++; i++; *q++ = 0;
+ copyString(idx,cur,string);
+ q = r;
+ e++; cur = e*3 - 2;
+ break;
+ case LBRACE:
+ switch ( curEntry )
+ {
+ case ALIAS_TYPE:
+ case PRE_TYPE:
+ case POST_TYPE:
+ case ENTRY_TYPE:
+ case XREF_TYPE:
+ case CROSS_TYPE:
+ break;
+ default:
+ *q++ = *p; break;
+ }
+ break;
+ case RBRACE:
+ switch ( curEntry )
+ {
+ case ALIAS_TYPE:
+ alias = FALSE;
+ case PRE_TYPE:
+ case POST_TYPE:
+ case ENTRY_TYPE:
+ case XREF_TYPE:
+ case CROSS_TYPE:
+ *q++ = 0;
+ ReduceSpaces(string);
+ copyString(idx,cur,string);
+ q = r;
+ curEntry = OTHER_TYPE; cur = 0;
+ break;
+ default:
+ *q++ = *p; break;
+ }
+ break;
+ case RSLASH:
+ if ( *(p+1) == COMMA)
+ {
+ p++; i++; *q++ = *p;
+ }
+ else
+ *q++ = *p;
+ break;
+ default:
+ *q++ = *p;
+ break;
+ }
+ p++; i++;
+ }
+
+ *q++ = 0;
+ if ( cur!=0 )
+ {
+ SkipSpacesReverse(j,q);
+ copyString(idx,cur,string);
+ cur = 0;
+ }
+
+ /* post processing of ndxfile */
+ /* largest j with <entry_j> */
+ 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<j )
+ {
+ num[i++] = *p++;
+ }
+ num[i] = 0;
+ strcpy(outstr,"0000");
+ for (k=i; k>=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 ( i<j && *p != NL )
+ {
+ switch ( *p )
+ {
+ case LBRACE:
+ if ( *(p+1) != RBRACE )
+ q = r;
+ else { p++; i++; cur++; }
+ break;
+ case RBRACE:
+ *q++ = 0;
+ copyString(idx,cur,string);
+ cur++;
+ break;
+ default:
+ *q++ = *p;
+ break;
+ }
+ p++; i++;
+ }
+ return;
+}
+
+char * CheckAbbrev(s,q)
+char s[];
+char *q;
+{
+ int i,j,len;
+ BYTE found;
+ char *p;
+
+ for (i=0, found=FALSE; i<nabb && !found; i++)
+ {
+ if ( stricmp(s,abbrev[i]->astr)==0 )
+ {
+ found = TRUE; p = abbrev[i]->xstr; len = strlen(abbrev[i]->xstr);
+ j = 0;
+ while ( *p!=0 && j<len)
+ {
+ *q++ = *p++; j++;
+ }
+ }
+ }
+ if ( !found )
+ { sprintf(string,"syntax error! '%s' - not an \\abbrev",s); error(string); }
+ return ( q );
+}
+
+
+
+/* preprocess NDX file for defines, abbrevs, page orders */
+void PreProc()
+{
+ char buf[300],str[300];
+ int i,j,len;
+ char *p, *q, *r;
+ BYTE done, status;
+
+ printMSG("preprocessing...");
+ ndef = nabb = npo = 0 ;
+ fgets(buf,300,ndxfile);
+ while ( !feof(ndxfile) )
+ {
+ len = strlen(buf);
+ p = &buf[0];
+ if ( strnicmp(p,"\\define",7)==0 )
+ {
+ buf[len-1]=0;
+ if ( ndef >= 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 && i<len )
+ { p++; i++; }
+
+ while ( *(p+j)!=LBRACE && *(p+j)!=SPACE && (p+j)<q ) j++;
+ *(p+j) = 0;
+ abbrev[nabb]->astr = GetStringSpace(p);
+ strcpy(abbrev[nabb]->astr,p);
+
+ p += j+1; j = len-1;
+ i=0; /* remove spaces */
+ while ( *p==SPACE && i<len )
+ { p++; i++; }
+
+ if ( *p==LBRACE ) p++;
+
+ while ( *q!=RBRACE && q>p ) q--;
+ *q = 0;
+ abbrev[nabb]->xstr = GetStringSpace(p);
+ strcpy(abbrev[nabb]->xstr,p);
+ nabb++;
+ }
+ else
+ {
+ i=0; /* remove spaces */
+ while ( *p==SPACE && i<len )
+ { p++; i++; }
+
+ if ( strnicmp(p,"\\pageorder",10)==0 )
+ {
+ buf[len-1]=0;
+ p+=10;
+ RemoveSpaces(p);
+ GetPageOrderSpace(npo);
+ /* get style */
+ j=0; q = &buf[len-1];
+ while ( *(p+j)!=LBRACE && (p+j)<q )
+ { j++; }
+ if ( (p+j) >= 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 ) j++;
+ if ( (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 ) j++;
+ if ( (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<len )
+ {
+ switch ( *p )
+ {
+ case STAR:
+ if ( *(p+1)==RSLASH )
+ {
+ r = &str[0]; done = FALSE;
+ *r++ = *p++; *r++ = *p++;
+ while ( !done )
+ {
+ switch ( *p )
+ {
+ case SPACE: case DQUOTE: case COMMA: case LBRACE:
+ case RBRACE: case LBRACKET: case RBRACKET:
+ case LPAREN: case RPAREN: case QUOTE: case DOLLAR:
+ case TILDE: case EXCLAIM: case CARET:
+ case MINUS: case USCORE: case PLUS: case EQUAL:
+ case COLON: case SEMI: case LQUOTE: case GREATER:
+ case LESS: case QUESTION: case SLASH: case BAR:
+ case STAR: case RSLASH: case PERIOD:
+ *r++=0;
+ done = TRUE;
+ break;
+ default:
+ *r++ = *p++; i++;
+ break;
+ } /* switch */
+ } /* while */
+ q=CheckAbbrev(str,q);
+ } /* if */
+ else
+ { *q++ = *p++; i++; }
+ break;
+ default:
+ *q++ = *p++; i++;
+ break;
+ } /* switch */
+ } /* while */
+ *q++ = 0;
+ PutString( string, xxxfile );
+ } /* not NL or SPACE */
+ } /* others */
+ } /* else pageorders */
+ } /* else abbrevs */
+ fgets(buf,300,ndxfile);
+ } /* while */
+ return;
+}
+
+
+
+
+/**********************************************************************/
+/* BuildProc: read in contents of .ndx file into internal data buffers*/
+/* Inputs : .ndx file handle */
+/* Output : Entries */
+/**********************************************************************/
+#ifndef SEEK_END
+#define SEEK_END 2
+#define SEEK_CUR 1
+#define SEEK_SET 0
+#endif
+void BuildProc( void )
+{
+ char abuf[300];
+ char bbuf[300];
+ int i;
+
+ fseek(xxxfile, 0L, SEEK_SET);
+ nitems = 0;
+ fgets(abuf,300,xxxfile);
+ while( !feof(xxxfile) )
+ {
+ nitems++;
+ fgets( abuf,300,xxxfile );
+ }
+
+ nitems/=2;
+ fseek(xxxfile, 0L, SEEK_SET);
+ GetFieldSpace(0);
+
+ for (i=1; i<=nitems; i++ )
+ {
+ fgets(abuf,300,xxxfile);
+ fgets(bbuf,300,xxxfile);
+
+ if ( bbuf[0]!='{' )
+ {
+ sprintf( msgbuf,"\n! Entry ->\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; i<npo && !done; i++)
+ {
+ if ( strncmp(Entry[idx].item->fields[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; i<n; i++ )
+ {
+ for ( j=i-gap; j>0 && 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; i<end; i++)
+ {
+ if ( *(Entry[i].item->fields[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; i<n && change; i++)
+ {
+ change = FALSE;
+ for (j=0;j<n-1;j++)
+ {
+ status = CompareStringsPO(SubPageOrder[j],SubPageOrder[j+1]);
+ if ( status>0 )
+ {
+ 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; i<idx; i++)
+ {
+ stat=0;
+
+ for (k=E1; k<=CROSS_REF && stat==0; k++)
+ {
+ stat=stricmp(Entry[i].item->fields[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; i<cur; i++)
+ {
+ if ( stricmp( Entry[i].item->fields[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; i<idx+nxt; i++)
+ {
+ xtype = (char) *(Entry[i].item->fields[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; i<idx+nxt; i++)
+ {
+ level = GetD2(i,idx);
+ xtype = (char) *(Entry[i].item->fields[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; i<idx+nxt; i++ )
+ {
+ level = GetD2(i,idx);
+ xtype = (char) *(Entry[i].item->fields[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; i<idx+nxt; i++ )
+ {
+ level = GetD2(i,idx);
+ xtype = (char) *(Entry[i].item->fields[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; i<idx+nxt; i++)
+ {
+ xtype = (char) *(Entry[i].item->fields[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; i<idx+nxt; i++)
+ {
+ level = GetD2(i,idx);
+ xtype = (char) *(Entry[i].item->fields[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; i<ndef; i++)
+ {
+ sprintf(msgbuf,"%s\n",define[i]);
+ PutString( msgbuf, xdxfile );
+ } /* for */
+
+ curIndex = 1;
+ while ( curIndex <= nitems )
+ {
+ TeXPut( curIndex );
+ }
+ return;
+} /* end - TexOut */
+
+
+/**********************************************************************/
+/* Move Entries */
+/* Inputs: from, to */
+/* Output: none */
+/**********************************************************************/
+void MoveEntry(from,to)
+ int from,to;
+{
+int k;
+
+ /* return if both are the same entry */
+ if ( from == to )
+ return;
+
+ for (k=E1; k<=CROSS_REF; k++)
+ {
+ Entry[to].item->fields[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 ########################### */