summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakuji Tanaka <ttk@t-lab.opal.ne.jp>2021-09-18 08:20:21 +0000
committerTakuji Tanaka <ttk@t-lab.opal.ne.jp>2021-09-18 08:20:21 +0000
commit29fc9a6f30ccb4c3d350b9a95845c77dc964311c (patch)
tree7aded0f955dfd60497d155eeb4510870e834a662
parent84e590b99d5041cc1928eb3baebd009825c785e8 (diff)
upmendex: improve multi-levels of page numbers
git-svn-id: svn://tug.org/texlive/trunk@60535 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/README2
-rw-r--r--Build/source/texk/upmendex/ChangeLog14
-rw-r--r--Build/source/texk/upmendex/exvar.h2
-rw-r--r--Build/source/texk/upmendex/fread.c65
-rw-r--r--Build/source/texk/upmendex/fwrite.c58
-rw-r--r--Build/source/texk/upmendex/mendex.h4
-rw-r--r--Build/source/texk/upmendex/sort.c82
-rw-r--r--Build/source/texk/upmendex/tests/range.idx126
-rw-r--r--Build/source/texk/upmendex/tests/range1.ind25
-rw-r--r--Build/source/texk/upmendex/tests/range1.ist3
-rw-r--r--Build/source/texk/upmendex/tests/range2.ind26
-rw-r--r--Build/source/texk/upmendex/tests/range2.ist4
-rw-r--r--Build/source/texk/upmendex/tests/range3.ind25
-rw-r--r--Build/source/texk/upmendex/tests/range3.ist4
-rw-r--r--Build/source/texk/upmendex/tests/rangetwo.idx2
-rw-r--r--Build/source/texk/upmendex/tests/rangetwo.ind5
-rw-r--r--Build/source/texk/upmendex/tests/rangetwo.ist2
-rwxr-xr-xBuild/source/texk/upmendex/tests/upmendex.test18
-rw-r--r--Build/source/texk/upmendex/var.h2
19 files changed, 380 insertions, 89 deletions
diff --git a/Build/source/texk/README b/Build/source/texk/README
index 8b23d7d757e..497b871809d 100644
--- a/Build/source/texk/README
+++ b/Build/source/texk/README
@@ -108,7 +108,7 @@ ttf2pk2 - maintained here, by us
ttfdump - maintained here, by us, since Taiwan upstream apparently gone.
-upmendex 0.58 - by Takuji Tanaka
+upmendex 0.59 - by Takuji Tanaka
http://www.ctan.org/pkg/upmendex
https://github.com/t-tk/upmendex-package
diff --git a/Build/source/texk/upmendex/ChangeLog b/Build/source/texk/upmendex/ChangeLog
index 5745343f5ff..045305ef8c9 100644
--- a/Build/source/texk/upmendex/ChangeLog
+++ b/Build/source/texk/upmendex/ChangeLog
@@ -1,3 +1,17 @@
+2021-09-18 TANAKA Takuji <ttk@t-lab.opal.ne.jp>
+
+ * fread.c, fwrite.c, sort.c, mendex.h, {,ex}var.h:
+ Extend levels of page numbers from 3 to 10
+ for compatibility with makeindex.
+ Fix a bug of page ranges with multi-level page numbers.
+ * fread.c:
+ Strict check for "page_precedence" and "page_compositor" in style file.
+ * fwrite.c:
+ Do not break lines before "delim_n".
+ * tests/upmendex.test, tests/range.idx, tests/range[123].{ist,ind},
+ removed tests/rangetwo.*:
+ Update tests.
+
2021-09-05 TANAKA Takuji <ttk@t-lab.opal.ne.jp>
* fwrite.c:
diff --git a/Build/source/texk/upmendex/exvar.h b/Build/source/texk/upmendex/exvar.h
index dd650721e30..1b7a8d9bd63 100644
--- a/Build/source/texk/upmendex/exvar.h
+++ b/Build/source/texk/upmendex/exvar.h
@@ -2,7 +2,7 @@ extern FILE *efp;
extern int lines,idxcount,acc,reject;
extern int prange,fsti,lorder,bcomp,force,fpage,gflg,verb,debug;
-extern int warn,scount,pattr[3];
+extern int warn,scount,pattr[];
extern struct index *ind;
diff --git a/Build/source/texk/upmendex/fread.c b/Build/source/texk/upmendex/fread.c
index a336022e11b..ba1d3514856 100644
--- a/Build/source/texk/upmendex/fread.c
+++ b/Build/source/texk/upmendex/fread.c
@@ -493,25 +493,54 @@ int widechar_to_multibyte(char *mbstr, int32_t size, UChar *wcstr)
static void chkpageattr(struct page *p)
{
- int i,j,cc=0;
+ int i,j,cc=0,cnt,pplen,pclen;
+ char buff[16],*pcpos,*page0;
+ pplen=strlen(page_precedence);
+ pclen=strlen(page_compositor);
for (i=0;i<strlen(p->page);i++) {
- if (strncmp(page_compositor,&p->page[i],strlen(page_compositor))==0) {
+ page0=&p->page[i];
+ if (strncmp(page_compositor,page0,pclen)==0) {
p->attr[cc]=pattr[cc];
cc++;
- i+=strlen(page_compositor)-1;
+ i+=pclen-1;
+ if (cc>=PAGE_COMPOSIT_DEPTH) {
+ if (pclen>0)
+ verb_printf(efp, "\nToo many fields of page number \"%s\".\n", p->page);
+ else
+ verb_printf(efp, "\nIllegular page_comositor specification.\n");
+ exit(253);
+ }
}
else {
-ATTRLOOP:
- if (!((p->page[i]>='0' && p->page[i]<='9') || (p->page[i]>='A' && p->page[i]<='Z') || (p->page[i]>='a' && p->page[i]<='z'))) {
+ cnt=0;
+ if (!((*page0>='0' && *page0<='9') || (*page0>='A' && *page0<='Z') || (*page0>='a' && *page0<='z'))) {
p->attr[cc]= -1;
if (cc<2) p->attr[++cc]= -1;
return;
}
+ pcpos=strstr(page0,page_compositor);
+ j=pcpos ? pcpos-page0 : strlen(page0);
+ if (j>15) {
+ verb_printf(efp, "\nToo long page number string \"%s\".\n", page0);
+ exit(253);
+ }
+ strncpy(buff,page0,j);
+ buff[j]='\0';
+ATTRLOOP:
+ cnt++;
+ if (cnt>pplen) {
+ verb_printf(efp, "\nFailed to find page type for page \"%s\" in page_precedence specification (%s).\n",
+ page0, page_precedence);
+ exit(253);
+ }
+
switch(page_precedence[pattr[cc]]) {
case 'r':
- if (strchr("ivxlcdm",p->page[i])==NULL) {
- if (pattr[cc]<strlen(page_precedence)-1)
+ if (strchr("ivxlcdm",*page0)==NULL ||
+ (strchr("lcdm",*page0) && strchr(page_precedence,'a') && strlen(buff)==1 && pcpos)) {
+ /* heuristic detection as alphabet since L=50, C=100, D=100, M=1000 are quite large */
+ if (pattr[cc]<pplen-1)
pattr[cc]++;
else pattr[cc]=0;
for (j=cc+1;j<3;j++) pattr[j]=0;
@@ -519,8 +548,10 @@ ATTRLOOP:
}
break;
case 'R':
- if (strchr("IVXLCDM",p->page[i])==NULL) {
- if (pattr[cc]<strlen(page_precedence)-1)
+ if (strchr("IVXLCDM",*page0)==NULL ||
+ (strchr("LCDM",*page0) && strchr(page_precedence,'A') && strlen(buff)==1 && pcpos)) {
+ /* heuristic detection as alphabet since L=50, C=100, D=100, M=1000 are quite large */
+ if (pattr[cc]<pplen-1)
pattr[cc]++;
else pattr[cc]=0;
for (j=cc+1;j<3;j++) pattr[j]=0;
@@ -528,8 +559,8 @@ ATTRLOOP:
}
break;
case 'n':
- if (p->page[i]<'0' || p->page[i]>'9') {
- if (pattr[cc]<strlen(page_precedence)-1)
+ if (*page0<'0' || *page0>'9') {
+ if (pattr[cc]<pplen-1)
pattr[cc]++;
else pattr[cc]=0;
for (j=cc+1;j<3;j++) pattr[j]=0;
@@ -537,8 +568,8 @@ ATTRLOOP:
}
break;
case 'a':
- if (p->page[i]<'a' || p->page[i]>'z') {
- if (pattr[cc]<strlen(page_precedence)-1)
+ if (*page0<'a' || *page0>'z' || strlen(buff)>1) {
+ if (pattr[cc]<pplen-1)
pattr[cc]++;
else pattr[cc]=0;
for (j=cc+1;j<3;j++) pattr[j]=0;
@@ -546,8 +577,8 @@ ATTRLOOP:
}
break;
case 'A':
- if (p->page[i]<'A' || p->page[i]>'Z') {
- if (pattr[cc]<strlen(page_precedence)-1)
+ if (*page0<'A' || *page0>'Z' || strlen(buff)>1) {
+ if (pattr[cc]<pplen-1)
pattr[cc]++;
else pattr[cc]=0;
for (j=cc+1;j<3;j++) pattr[j]=0;
@@ -555,7 +586,9 @@ ATTRLOOP:
}
break;
default:
- break;
+ verb_printf(efp, "\nUnknown page type '%c' in page_precedence specification (%s).\n",
+ page_precedence[pattr[cc]], page_precedence);
+ exit(253);
}
}
}
diff --git a/Build/source/texk/upmendex/fwrite.c b/Build/source/texk/upmendex/fwrite.c
index a23ccec545c..a5b6aa60362 100644
--- a/Build/source/texk/upmendex/fwrite.c
+++ b/Build/source/texk/upmendex/fwrite.c
@@ -13,7 +13,7 @@ int line_length=0;
static void printpage(struct index *ind, FILE *fp, int num, char *lbuff);
static int range_check(struct index ind, int count, char *lbuff);
-static void linecheck(char *lbuff, char *tmpbuff);
+static void linecheck(char *lbuff, char *tmpbuff, int force);
static void crcheck(char *lbuff, FILE *fp);
static void index_normalize(UChar *istr, UChar *ini, int *chset);
static int initial_cmp_char(UChar *ini, UChar ch);
@@ -128,7 +128,7 @@ void warn_printf(FILE *fp, const char *format, ...)
vsnprintf(print_buff, sizeof print_buff, format, argptr);
va_end(argptr);
- warn++;
+ warn++;
fputs(print_buff, stderr);
if (fp!=stderr) fputs(print_buff, fp);
}
@@ -146,6 +146,22 @@ void verb_printf(FILE *fp, const char *format, ...)
if (fp!=stderr) fputs(print_buff, fp);
}
+static int pnumconv2(struct page *p)
+{
+ int j,k,cc,pclen;
+
+ pclen=strlen(page_compositor);
+ for (j=k=cc=0;j<strlen(p->page);j++) {
+ if (strncmp(p->page+j,page_compositor,pclen)==0) {
+ j+=pclen;
+ k=j;
+ cc++;
+ continue;
+ }
+ }
+ return pnumconv(p->page+k,p->attr[cc]);
+}
+
/* write ind file */
void indwrite(char *filename, struct index *ind, int pagenum)
@@ -507,7 +523,9 @@ static void printpage(struct index *ind, FILE *fp, int num, char *lbuff)
for(j=0;j<ind[num].num;j++) {
cc=range_check(ind[num],j,lbuff);
if (cc>j) {
- if (pnumconv(ind[num].p[j].page,ind[num].p[j].attr[0])==pnumconv(ind[num].p[cc].page,ind[num].p[cc].attr[0])) {
+ int epage = pnumconv2(&ind[num].p[cc]);
+ int bpage = pnumconv2(&ind[num].p[j]);
+ if (epage==bpage) {
j=cc-1;
continue;
}
@@ -518,20 +536,18 @@ static void printpage(struct index *ind, FILE *fp, int num, char *lbuff)
if (strlen(ind[num].p[j].enc)>0) {
SPRINTF(buff,"%s%s%s",encap_prefix,ind[num].p[j].enc,encap_infix);
}
- if (strlen(suffix_3p)>0 && (pnumconv(ind[num].p[cc].page,ind[num].p[cc].attr[0])-pnumconv(ind[num].p[j].page,ind[num].p[j].attr[0]))==2) {
- SAPPENDF(buff,"%s",ind[num].p[j].page);
+ /* print beginning of range */
+ SAPPENDF(buff,"%s",ind[num].p[j].page);
+ if (strlen(suffix_3p)>0 && epage-bpage==2) {
SAPPENDF(buff,"%s",suffix_3p);
}
- else if (strlen(suffix_mp)>0 && (pnumconv(ind[num].p[cc].page,ind[num].p[cc].attr[0])-pnumconv(ind[num].p[j].page,ind[num].p[j].attr[0]))>=2) {
- SAPPENDF(buff,"%s",ind[num].p[j].page);
+ else if (strlen(suffix_mp)>0 && epage-bpage>=2) {
SAPPENDF(buff,"%s",suffix_mp);
}
- else if (strlen(suffix_2p)>0 && (pnumconv(ind[num].p[cc].page,ind[num].p[cc].attr[0])-pnumconv(ind[num].p[j].page,ind[num].p[j].attr[0]))==1) {
- SAPPENDF(buff,"%s",ind[num].p[j].page);
+ else if (strlen(suffix_2p)>0 && epage-bpage==1) {
SAPPENDF(buff,"%s",suffix_2p);
}
else {
- SAPPENDF(buff,"%s",ind[num].p[j].page);
SAPPENDF(buff,"%s",delim_r);
SAPPENDF(buff,"%s",ind[num].p[cc].page);
}
@@ -540,14 +556,14 @@ static void printpage(struct index *ind, FILE *fp, int num, char *lbuff)
if (strlen(ind[num].p[j].enc)>0) {
SAPPENDF(tmpbuff,"%s",encap_suffix);
}
- linecheck(lbuff,tmpbuff);
+ linecheck(lbuff,tmpbuff, FALSE);
j=cc;
if (j==ind[num].num) {
goto PRINT;
}
else {
SAPPENDF(tmpbuff,"%s",delim_n);
- linecheck(lbuff,tmpbuff);
+ linecheck(lbuff,tmpbuff, TRUE);
}
}
else if (strlen(ind[num].p[j].enc)>0) {
@@ -569,19 +585,19 @@ static void printpage(struct index *ind, FILE *fp, int num, char *lbuff)
SAPPENDF(tmpbuff,"%s",ind[num].p[j].page);
SAPPENDF(tmpbuff,"%s",encap_suffix);
SAPPENDF(tmpbuff,"%s",delim_n);
- linecheck(lbuff,tmpbuff);
+ linecheck(lbuff,tmpbuff, FALSE);
}
else {
SAPPENDF(tmpbuff,"%s",ind[num].p[j].page);
SAPPENDF(tmpbuff,"%s",delim_n);
- linecheck(lbuff,tmpbuff);
+ linecheck(lbuff,tmpbuff, FALSE);
}
}
else {
/* no encap */
SAPPENDF(tmpbuff,"%s",ind[num].p[j].page);
SAPPENDF(tmpbuff,"%s",delim_n);
- linecheck(lbuff,tmpbuff);
+ linecheck(lbuff,tmpbuff, FALSE);
}
}
@@ -615,7 +631,7 @@ static void printpage(struct index *ind, FILE *fp, int num, char *lbuff)
else {
SAPPENDF(tmpbuff,"%s",ind[num].p[j].page);
}
- linecheck(lbuff,tmpbuff);
+ linecheck(lbuff,tmpbuff, FALSE);
PRINT:
fputs(lbuff,fp);
@@ -661,7 +677,7 @@ static int range_check(struct index ind, int count, char *lbuff)
if (strlen(ind.p[j].enc)>0) {
SPRINTF(tmpbuff,"%s%s%s%s%s%s",encap_prefix,ind.p[j].enc,encap_infix
,ind.p[j].page,encap_suffix,delim_n);
- linecheck(lbuff,tmpbuff);
+ linecheck(lbuff,tmpbuff, FALSE);
}
}
}
@@ -691,8 +707,8 @@ static int range_check(struct index ind, int count, char *lbuff)
break;
}
}
- cc1=pnumconv(ind.p[i-1].page,ind.p[i-1].attr[0]);
- cc2=pnumconv(ind.p[count].page,ind.p[count].attr[0]);
+ cc1=pnumconv2(&ind.p[i-1]);
+ cc2=pnumconv2(&ind.p[count]);
if (cc1>=cc2+2 || (cc1>=cc2+1 && strlen(suffix_2p)) || force) {
return i-1;
}
@@ -700,9 +716,9 @@ static int range_check(struct index ind, int count, char *lbuff)
}
/* check line length */
-static void linecheck(char *lbuff, char *tmpbuff)
+static void linecheck(char *lbuff, char *tmpbuff, int force)
{
- if (line_length+strlen(tmpbuff)>line_max) {
+ if (line_length+strlen(tmpbuff)>line_max && !force) {
SAPPENDF(lbuff,"\n");
SAPPENDF(lbuff,"%s",indent_space);
SAPPENDF(lbuff,"%s",tmpbuff);
diff --git a/Build/source/texk/upmendex/mendex.h b/Build/source/texk/upmendex/mendex.h
index c6703761fcc..d14e5c66753 100644
--- a/Build/source/texk/upmendex/mendex.h
+++ b/Build/source/texk/upmendex/mendex.h
@@ -11,10 +11,12 @@
#include <unicode/uchar.h>
#include <unicode/ucol.h>
+#define PAGE_COMPOSIT_DEPTH 10
+
struct page {
char *page;
char *enc;
- int attr[3];
+ int attr[PAGE_COMPOSIT_DEPTH];
};
struct index {
diff --git a/Build/source/texk/upmendex/sort.c b/Build/source/texk/upmendex/sort.c
index a3aedebae7f..26584e420aa 100644
--- a/Build/source/texk/upmendex/sort.c
+++ b/Build/source/texk/upmendex/sort.c
@@ -248,12 +248,12 @@ void pagesort(struct index *ind, int num)
static int pcomp(const void *p, const void *q)
{
int i,j,cc=0,num1,num2;
- char buff[16];
+ char buff[16],*p0,*p1;
const struct page *page1 = p, *page2 = q;
scount++;
- for (i=0;i<3;i++) {
+ for (i=0;i<PAGE_COMPOSIT_DEPTH;i++) {
if ((page1->attr[i]<0)&&(page2->attr[i]<0)) return 0;
else if ((page1->attr[i]<0)&&(page2->attr[i]>=0)) return -1;
else if ((page2->attr[i]<0)&&(page1->attr[i]>=0)) return 1;
@@ -261,18 +261,18 @@ static int pcomp(const void *p, const void *q)
if (page1->attr[i]>page2->attr[i]) return 1;
if (page1->attr[i]<page2->attr[i]) return -1;
- for (j=cc;j<strlen(page1->page);j++) {
- if (strncmp(&page1->page[j],page_compositor,strlen(page_compositor))==0) break;
- }
- strncpy(buff,&page1->page[cc],j-cc);
- buff[j-cc]='\0';
+ p0=&page1->page[cc];
+ p1=strstr(p0, page_compositor);
+ j=p1 ? p1-p0 : strlen(p0);
+ strncpy(buff,p0,j);
+ buff[j]='\0';
num1=pnumconv(buff,page1->attr[i]);
- for (j=cc;j<strlen(page2->page);j++) {
- if (strncmp(&page2->page[j],page_compositor,strlen(page_compositor))==0) break;
- }
- strncpy(buff,&page2->page[cc],j-cc);
- buff[j-cc]='\0';
+ p0=&page2->page[cc];
+ p1=strstr(p0, page_compositor);
+ j=p1 ? p1-p0 : strlen(p0);
+ strncpy(buff,p0,j);
+ buff[j]='\0';
num2=pnumconv(buff,page2->attr[i]);
if (num1>num2) return 1;
@@ -281,7 +281,8 @@ static int pcomp(const void *p, const void *q)
if (page1->enc[0]=='(' || page2->enc[0]==')') return -1;
if (page1->enc[0]==')' || page2->enc[0]=='(') return 1;
- cc=j+strlen(page_compositor);
+ if (p1) cc+=j+strlen(page_compositor);
+ else return 0;
}
return 0;
@@ -528,35 +529,48 @@ int is_comb_diacritical_mark(UChar *c)
int chkcontinue(struct page *p, int num)
{
- int i,j,cc=0,num1,num2;
- char buff[16];
+ int i,j,cc=0,num1,num2,k1,k2;
+ char buff1[16],buff2[16],*p0,*p1;
- for (i=0;i<3;i++) {
+ for (i=0;i<PAGE_COMPOSIT_DEPTH;i++) {
if ((p[num].attr[i]<0)&&(p[num+1].attr[i]<0)) return 1;
else if (p[num].attr[i]!=p[num+1].attr[i]) return 0;
- for (j=cc;j<strlen(p[num].page);j++) {
- if (strncmp(&p[num].page[j],page_compositor,strlen(page_compositor))==0) break;
+ p0=&p[num].page[cc];
+ p1=strstr(p0, page_compositor);
+ if (p1) {
+ j=p1-p0;
+ k1=j;
+ } else {
+ j=strlen(p0);
+ k1=0;
}
- strncpy(buff,&p[num].page[cc],j);
- buff[j]='\0';
- num1=pnumconv(buff,p[num].attr[i]);
-
- for (j=cc;j<strlen(p[num+1].page);j++) {
- if (strncmp(&p[num+1].page[j],page_compositor,strlen(page_compositor))==0) break;
+ strncpy(buff1,p0,j);
+ buff1[j]='\0';
+ num1=pnumconv(buff1,p[num].attr[i]);
+
+ p0=&p[num+1].page[cc];
+ p1=strstr(p0, page_compositor);
+ if (p1) {
+ j=p1-p0;
+ k2=j;
+ } else {
+ j=strlen(p0);
+ k2=0;
}
- strncpy(buff,&p[num+1].page[cc],j);
- buff[j]='\0';
- num2=pnumconv(buff,p[num+1].attr[i]);
-
- if (num1==num2 || num1+1==num2) {
- if (i==2) return 1;
- if ((p[num].attr[i+1]<0)&&(p[num+1].attr[i+1]<0)) return 1;
- else return 0;
+ strncpy(buff2,p0,j);
+ buff2[j]='\0';
+ num2=pnumconv(buff2,p[num+1].attr[i]);
+
+ if (k1>0 || k2>0) {
+ if (k1!=k2) return 0;
+ if (strcmp(buff1,buff2)) return 0;
+ cc+=k1+strlen(page_compositor);
+ continue;
}
- else if (num1!=num2) return 0;
- cc=j+strlen(page_compositor);
+ if (num1==num2 || num1+1==num2) return 1;
+ else return 0;
}
return 1;
diff --git a/Build/source/texk/upmendex/tests/range.idx b/Build/source/texk/upmendex/tests/range.idx
new file mode 100644
index 00000000000..e77882010c6
--- /dev/null
+++ b/Build/source/texk/upmendex/tests/range.idx
@@ -0,0 +1,126 @@
+\indexentry{entryA}{1}
+\indexentry{entryA}{2}
+\indexentry{entryA}{iii}
+\indexentry{entryA}{iv}
+\indexentry{entryA}{IX}
+\indexentry{entryA}{X}
+
+\indexentry{entryB}{1}
+\indexentry{entryB}{2}
+\indexentry{entryB}{3}
+\indexentry{entryB}{iii}
+\indexentry{entryB}{iv}
+\indexentry{entryB}{v}
+\indexentry{entryB}{IX}
+\indexentry{entryB}{X}
+\indexentry{entryB}{XI}
+
+\indexentry{entryC}{1}
+\indexentry{entryC}{2}
+\indexentry{entryC}{3}
+\indexentry{entryC}{4}
+\indexentry{entryC|bold}{iii}
+\indexentry{entryC|bold}{iv}
+\indexentry{entryC|bold}{v}
+\indexentry{entryC|bold}{vi}
+\indexentry{entryC}{IX}
+\indexentry{entryC|bold}{X}
+\indexentry{entryC}{XI}
+\indexentry{entryC}{XII}
+
+\indexentry{entryD}{c-1}
+\indexentry{entryD}{c-2}
+\indexentry{entryD}{i-iii}
+\indexentry{entryD}{i-iv}
+\indexentry{entryD}{d-IX}
+\indexentry{entryD}{d-X}
+
+\indexentry{entryE}{c-1}
+\indexentry{entryE}{c-2}
+\indexentry{entryE}{c-3}
+\indexentry{entryE}{i-iii}
+\indexentry{entryE}{i-iv}
+\indexentry{entryE}{i-v}
+\indexentry{entryE}{d-IX}
+\indexentry{entryE}{d-X}
+\indexentry{entryE}{d-XI}
+
+\indexentry{entryF}{C-I}
+\indexentry{entryF}{C-II}
+\indexentry{entryF}{C-III}
+\indexentry{entryF}{C-IV}
+\indexentry{entryF}{V-LIII}
+\indexentry{entryF}{V-LIV}
+\indexentry{entryF}{V-LV}
+\indexentry{entryF}{V-LVI}
+\indexentry{entryF}{D-DI}
+\indexentry{entryF}{D-DII}
+\indexentry{entryF}{D-DIII}
+\indexentry{entryF}{D-DIV}
+
+\indexentry{entryP}{A-a-1-I-iii}
+\indexentry{entryP}{A-a-2-I-iii}
+\indexentry{entryP}{A-a-3-I-iii}
+\indexentry{entryP}{A-a-1-II-iii}
+\indexentry{entryP}{A-a-1-III-iii}
+\indexentry{entryP}{A-a-1-I-iv}
+\indexentry{entryP}{A-a-1-I-v}
+
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-10}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-11}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-14}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-15}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-16}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-22}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-23}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-24}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-25}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-i}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-ii}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-iii}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-iv}
+\indexentry{entryQ}{1-2-3-4-5-6-7-8-9-v}
+
+\indexentry{entryA1|(}{1}
+\indexentry{entryA1|)}{2}
+\indexentry{entryA1|(}{iii}
+\indexentry{entryA1|)}{iv}
+\indexentry{entryA1|(}{IX}
+\indexentry{entryA1|)}{X}
+
+\indexentry{entryB1|(}{1}
+\indexentry{entryB1|)}{3}
+\indexentry{entryB1|(}{iii}
+\indexentry{entryB1|)}{v}
+\indexentry{entryB1|(}{IX}
+\indexentry{entryB1|)}{XI}
+
+\indexentry{entryC1|(}{1}
+\indexentry{entryC1|)}{4}
+\indexentry{entryC1|(bold}{iii}
+\indexentry{entryC1|)}{vi}
+\indexentry{entryC1|(}{IX}
+\indexentry{entryC1|bold}{X}
+\indexentry{entryC1|)}{XII}
+
+\indexentry{entryD1|(}{c-1}
+\indexentry{entryD1|)}{c-2}
+\indexentry{entryD1|(}{i-iii}
+\indexentry{entryD1|)}{i-iv}
+\indexentry{entryD1|(}{d-IX}
+\indexentry{entryD1|)}{d-X}
+
+\indexentry{entryE1|(}{c-1}
+\indexentry{entryE1|)}{c-3}
+\indexentry{entryE1|(}{i-iii}
+\indexentry{entryE1|)}{i-v}
+\indexentry{entryE1|(}{d-IX}
+\indexentry{entryE1|)}{d-XI}
+
+\indexentry{entryF1|(}{C-I}
+\indexentry{entryF1|)}{C-IV}
+\indexentry{entryF1|(}{V-LIII}
+\indexentry{entryF1|)}{V-LVI}
+\indexentry{entryF1|(}{D-DI}
+\indexentry{entryF1|bold}{D-DII}
+\indexentry{entryF1|)}{D-DIV}
diff --git a/Build/source/texk/upmendex/tests/range1.ind b/Build/source/texk/upmendex/tests/range1.ind
new file mode 100644
index 00000000000..0dc1d842a9f
--- /dev/null
+++ b/Build/source/texk/upmendex/tests/range1.ind
@@ -0,0 +1,25 @@
+\begin{theindex}
+
+ \item entryA, 1[[sfx 2p]], iii[[sfx 2p]], IX[[sfx 2p]]
+ \item entryA1, 1[[sfx 2p]], iii[[sfx 2p]], IX[[sfx 2p]]
+ \item entryB, 1[[sfx mp]], iii[[sfx mp]], IX[[sfx mp]]
+ \item entryB1, 1[[sfx mp]], iii[[sfx mp]], IX[[sfx mp]]
+ \item entryC, 1[[sfx mp]], \bold{iii[[sfx mp]]}, IX, \bold{X},
+ XI[[sfx 2p]]
+ \item entryC1, 1[[sfx mp]], \bold{iii[[sfx mp]]}, \bold{X},
+ IX[[sfx mp]]
+ \item entryD, c-1[[sfx 2p]], d-IX[[sfx 2p]], i-iii[[sfx 2p]]
+ \item entryD1, c-1[[sfx 2p]], d-IX[[sfx 2p]], i-iii[[sfx 2p]]
+ \item entryE, c-1[[sfx mp]], d-IX[[sfx mp]], i-iii[[sfx mp]]
+ \item entryE1, c-1[[sfx mp]], d-IX[[sfx mp]], i-iii[[sfx mp]]
+ \item entryF, C-I[[sfx mp]], D-DI[[sfx mp]], V-LIII[[sfx mp]]
+ \item entryF1, C-I[[sfx mp]], \bold{D-DII}, D-DI[[sfx mp]],
+ V-LIII[[sfx mp]]
+ \item entryP, A-a-1-I-iii[[sfx mp]], A-a-1-II-iii, A-a-1-III-iii,
+ A-a-2-I-iii, A-a-3-I-iii
+ \item entryQ, 1-2-3-4-5-6-7-8-9-10[[sfx 2p]],
+ 1-2-3-4-5-6-7-8-9-14[[sfx mp]],
+ 1-2-3-4-5-6-7-8-9-22[[sfx mp]],
+ 1-2-3-4-5-6-7-8-9-i[[sfx mp]]
+
+\end{theindex}
diff --git a/Build/source/texk/upmendex/tests/range1.ist b/Build/source/texk/upmendex/tests/range1.ist
new file mode 100644
index 00000000000..116c2d8713b
--- /dev/null
+++ b/Build/source/texk/upmendex/tests/range1.ist
@@ -0,0 +1,3 @@
+page_precedence "nrRaA"
+suffix_2p "[[sfx 2p]]"
+suffix_mp "[[sfx mp]]"
diff --git a/Build/source/texk/upmendex/tests/range2.ind b/Build/source/texk/upmendex/tests/range2.ind
new file mode 100644
index 00000000000..9e0bd8ce5e3
--- /dev/null
+++ b/Build/source/texk/upmendex/tests/range2.ind
@@ -0,0 +1,26 @@
+\begin{theindex}
+
+ \item entryA, 1[[sfx 2p]], iii[[sfx 2p]], IX[[sfx 2p]]
+ \item entryA1, 1[[sfx 2p]], iii[[sfx 2p]], IX[[sfx 2p]]
+ \item entryB, 1[[sfx 3p]], iii[[sfx 3p]], IX[[sfx 3p]]
+ \item entryB1, 1[[sfx 3p]], iii[[sfx 3p]], IX[[sfx 3p]]
+ \item entryC, 1[[delim r]]4, \bold{iii[[delim r]]vi}, IX, \bold{X},
+ XI[[sfx 2p]]
+ \item entryC1, 1[[delim r]]4, \bold{iii[[delim r]]vi}, \bold{X},
+ IX[[delim r]]XII
+ \item entryD, c-1[[sfx 2p]], d-IX[[sfx 2p]], i-iii[[sfx 2p]]
+ \item entryD1, c-1[[sfx 2p]], d-IX[[sfx 2p]], i-iii[[sfx 2p]]
+ \item entryE, c-1[[sfx 3p]], d-IX[[sfx 3p]], i-iii[[sfx 3p]]
+ \item entryE1, c-1[[sfx 3p]], d-IX[[sfx 3p]], i-iii[[sfx 3p]]
+ \item entryF, C-I[[delim r]]C-IV, D-DI[[delim r]]D-DIV,
+ V-LIII[[delim r]]V-LVI
+ \item entryF1, C-I[[delim r]]C-IV, \bold{D-DII}, D-DI[[delim r]]D-DIV,
+ V-LIII[[delim r]]V-LVI
+ \item entryP, A-a-1-I-iii[[sfx 3p]], A-a-1-II-iii, A-a-1-III-iii,
+ A-a-2-I-iii, A-a-3-I-iii
+ \item entryQ, 1-2-3-4-5-6-7-8-9-10[[sfx 2p]],
+ 1-2-3-4-5-6-7-8-9-14[[sfx 3p]],
+ 1-2-3-4-5-6-7-8-9-22[[delim r]]1-2-3-4-5-6-7-8-9-25,
+ 1-2-3-4-5-6-7-8-9-i[[delim r]]1-2-3-4-5-6-7-8-9-v
+
+\end{theindex}
diff --git a/Build/source/texk/upmendex/tests/range2.ist b/Build/source/texk/upmendex/tests/range2.ist
new file mode 100644
index 00000000000..552e5fb6748
--- /dev/null
+++ b/Build/source/texk/upmendex/tests/range2.ist
@@ -0,0 +1,4 @@
+page_precedence "nrRaA"
+delim_r "[[delim r]]"
+suffix_2p "[[sfx 2p]]"
+suffix_3p "[[sfx 3p]]"
diff --git a/Build/source/texk/upmendex/tests/range3.ind b/Build/source/texk/upmendex/tests/range3.ind
new file mode 100644
index 00000000000..f5b5f5268ff
--- /dev/null
+++ b/Build/source/texk/upmendex/tests/range3.ind
@@ -0,0 +1,25 @@
+\begin{theindex}
+
+ \item entryA, 1[[sfx 2p]], iii[[sfx 2p]], IX[[sfx 2p]]
+ \item entryA1, 1[[sfx 2p]], iii[[sfx 2p]], IX[[sfx 2p]]
+ \item entryB, 1[[sfx 3p]], iii[[sfx 3p]], IX[[sfx 3p]]
+ \item entryB1, 1[[sfx 3p]], iii[[sfx 3p]], IX[[sfx 3p]]
+ \item entryC, 1[[sfx mp]], \bold{iii[[sfx mp]]}, IX, \bold{X},
+ XI[[sfx 2p]]
+ \item entryC1, 1[[sfx mp]], \bold{iii[[sfx mp]]}, \bold{X},
+ IX[[sfx mp]]
+ \item entryD, c-1[[sfx 2p]], d-IX[[sfx 2p]], i-iii[[sfx 2p]]
+ \item entryD1, c-1[[sfx 2p]], d-IX[[sfx 2p]], i-iii[[sfx 2p]]
+ \item entryE, c-1[[sfx 3p]], d-IX[[sfx 3p]], i-iii[[sfx 3p]]
+ \item entryE1, c-1[[sfx 3p]], d-IX[[sfx 3p]], i-iii[[sfx 3p]]
+ \item entryF, C-I[[sfx mp]], D-DI[[sfx mp]], V-LIII[[sfx mp]]
+ \item entryF1, C-I[[sfx mp]], \bold{D-DII}, D-DI[[sfx mp]],
+ V-LIII[[sfx mp]]
+ \item entryP, A-a-1-I-iii[[sfx 3p]], A-a-1-II-iii, A-a-1-III-iii,
+ A-a-2-I-iii, A-a-3-I-iii
+ \item entryQ, 1-2-3-4-5-6-7-8-9-10[[sfx 2p]],
+ 1-2-3-4-5-6-7-8-9-14[[sfx 3p]],
+ 1-2-3-4-5-6-7-8-9-22[[sfx mp]],
+ 1-2-3-4-5-6-7-8-9-i[[sfx mp]]
+
+\end{theindex}
diff --git a/Build/source/texk/upmendex/tests/range3.ist b/Build/source/texk/upmendex/tests/range3.ist
new file mode 100644
index 00000000000..b751471b432
--- /dev/null
+++ b/Build/source/texk/upmendex/tests/range3.ist
@@ -0,0 +1,4 @@
+page_precedence "nrRaA"
+suffix_2p "[[sfx 2p]]"
+suffix_3p "[[sfx 3p]]"
+suffix_mp "[[sfx mp]]"
diff --git a/Build/source/texk/upmendex/tests/rangetwo.idx b/Build/source/texk/upmendex/tests/rangetwo.idx
deleted file mode 100644
index d941f7e8315..00000000000
--- a/Build/source/texk/upmendex/tests/rangetwo.idx
+++ /dev/null
@@ -1,2 +0,0 @@
-\indexentry{entryA}{1}
-\indexentry{entryA}{2}
diff --git a/Build/source/texk/upmendex/tests/rangetwo.ind b/Build/source/texk/upmendex/tests/rangetwo.ind
deleted file mode 100644
index 1119d2fa8e9..00000000000
--- a/Build/source/texk/upmendex/tests/rangetwo.ind
+++ /dev/null
@@ -1,5 +0,0 @@
-\begin{theindex}
-
- \item entryA, 1[[sfx2p]]
-
-\end{theindex}
diff --git a/Build/source/texk/upmendex/tests/rangetwo.ist b/Build/source/texk/upmendex/tests/rangetwo.ist
deleted file mode 100644
index 3e986c8935d..00000000000
--- a/Build/source/texk/upmendex/tests/rangetwo.ist
+++ /dev/null
@@ -1,2 +0,0 @@
-suffix_2p "[[sfx2p]]"
-
diff --git a/Build/source/texk/upmendex/tests/upmendex.test b/Build/source/texk/upmendex/tests/upmendex.test
index a291c1dfc74..54152ca7a06 100755
--- a/Build/source/texk/upmendex/tests/upmendex.test
+++ b/Build/source/texk/upmendex/tests/upmendex.test
@@ -7,7 +7,7 @@
TEXMFCNF=$srcdir/../kpathsea
export TEXMFCNF
-rm -f foo.* uni.* pprec*.* rangetwo.* locale*.* attr*.* rule*.*
+rm -f foo.* uni.* pprec*.* range*.* locale*.* attr*.* rule*.*
./upmendex $srcdir/tests/foo.idx -o foo.ind1 -t foo.ilg1 \
&& diff $srcdir/tests/foo.ind foo.ind1 || exit 1
@@ -28,10 +28,18 @@ cat $srcdir/tests/uni.idx | \
$srcdir/tests/uni.idx -o uni.ind3 -t uni.ilg3 \
&& diff $srcdir/tests/uni.ind uni.ind3 || exit 1
-# test for two-element range suffix_2p
-./upmendex -s $srcdir/tests/rangetwo.ist $srcdir/tests/rangetwo.idx \
- -o rangetwo.ind1 -t rangetwo.ilg \
- && diff $srcdir/tests/rangetwo.ind rangetwo.ind1 || exit 1
+# test for range suffix_2p, suffix_3p, suffix_mp
+./upmendex -s $srcdir/tests/range1.ist $srcdir/tests/range.idx \
+ -o range1.ind1 -t range1.ilg \
+ && diff $srcdir/tests/range1.ind range1.ind1 || exit 1
+
+./upmendex -s $srcdir/tests/range2.ist $srcdir/tests/range.idx \
+ -o range2.ind1 -t range2.ilg \
+ && diff $srcdir/tests/range2.ind range2.ind1 || exit 1
+
+./upmendex -s $srcdir/tests/range3.ist $srcdir/tests/range.idx \
+ -o range3.ind1 -t range3.ilg \
+ && diff $srcdir/tests/range3.ind range3.ind1 || exit 1
# test for page_precedence and suffix_3p
./upmendex -s $srcdir/tests/pprec0.ist $srcdir/tests/pprecA.idx \
diff --git a/Build/source/texk/upmendex/var.h b/Build/source/texk/upmendex/var.h
index a7a66bfe0fa..b627d75eff6 100644
--- a/Build/source/texk/upmendex/var.h
+++ b/Build/source/texk/upmendex/var.h
@@ -4,7 +4,7 @@ FILE *efp;
int lines,idxcount,acc=0,reject=0;
int prange=1,fsti=0,lorder=0,bcomp=0,force=0,fpage=0,gflg=0,verb=1,debug=0;
-int warn=0,scount=0,pattr[3]={0,0,0};
+int warn=0,scount=0,pattr[PAGE_COMPOSIT_DEPTH]={0};
/* static char roman[]={"ivxlcdm"},Roman[]={"IVXLCDM"}; */
struct index *ind;