summaryrefslogtreecommitdiff
path: root/Build/source/texk/upmendex/fread.c
diff options
context:
space:
mode:
authorTakuji Tanaka <KXD02663@nifty.ne.jp>2016-02-09 11:02:48 +0000
committerTakuji Tanaka <KXD02663@nifty.ne.jp>2016-02-09 11:02:48 +0000
commitadec059e95b8e5728d8fb2d8420c5e928812c282 (patch)
tree28d38c44042fea2befbccbdd71063c801518d298 /Build/source/texk/upmendex/fread.c
parentb0bdd8cd0fed764f189d773b0b0f69d25415a8f5 (diff)
texk/upmendex: upmendex 0.50
git-svn-id: svn://tug.org/texlive/trunk@39638 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/upmendex/fread.c')
-rw-r--r--Build/source/texk/upmendex/fread.c554
1 files changed, 554 insertions, 0 deletions
diff --git a/Build/source/texk/upmendex/fread.c b/Build/source/texk/upmendex/fread.c
new file mode 100644
index 00000000000..22f50ef9eb8
--- /dev/null
+++ b/Build/source/texk/upmendex/fread.c
@@ -0,0 +1,554 @@
+#include "mendex.h"
+
+#include <kpathsea/tex-file.h>
+
+#include "exkana.h"
+#include "exvar.h"
+
+#define BUFSIZE 65535
+
+static int getestr(char *buff, char *estr);
+static void chkpageattr(struct page *p);
+static void copy_multibyte_char(char *buff1, char *buff2, int *i, int *j);
+
+/* read idx file */
+int idxread(char *filename, int start)
+{
+ int i,j,k,l,m,n,cc,indent,wflg,flg=0,bflg=0,nest,esc,quo,eflg=0,pacc,preject;
+ char buff[BUFSIZE],wbuff[BUFSIZE],estr[256],table[BUFSIZE];
+ UChar utable[BUFSIZE],ubuff[BUFSIZE],*tmp1,*tmp2;
+ FILE *fp;
+
+ pacc=acc;
+ preject=reject;
+
+ if (filename==NULL) {
+ fp=stdin;
+#ifdef WIN32
+ setmode(fileno(fp), _O_BINARY);
+#endif
+ verb_printf(efp, "Scanning input file stdin.");
+ }
+ else {
+ if(kpse_in_name_ok(filename))
+ fp=fopen(filename,"rb");
+ else
+ fp=NULL;
+ if (fp==NULL) {
+ sprintf(buff,"%s.idx",filename);
+ if(kpse_in_name_ok(buff))
+ fp=fopen(buff,"rb");
+ else
+ fp=NULL;
+ if (fp==NULL) {
+ warn_printf(efp,"Warning: Couldn't find input file %s.\n",filename);
+ return 1;
+ }
+ else strcpy(filename,buff);
+ }
+ verb_printf(efp,"Scanning input file %s.",filename);
+ }
+
+ for (i=start,n=1;;i++,n++) {
+ if (!(i%100))
+ ind=(struct index *)realloc(ind,sizeof(struct index)*(i+100));
+LOOP:
+ ind[i].lnum=n;
+ if (fgets(buff,sizeof(buff)-1,fp)==NULL) break;
+ for (j=bflg=cc=0;j<strlen(buff);j++) {
+ if (buff[j]!=' ' && buff[j]!='\n') cc=1;
+ if (bflg==0) {
+ if (strncmp(&buff[j],keyword,strlen(keyword))==0) {
+ j+=strlen(keyword);
+ bflg=1;
+ }
+ }
+ if (bflg==1) {
+ if (buff[j]==arg_open) {
+ j++;
+ break;
+ }
+ }
+ }
+ if (j==strlen(buff)) {
+ if (cc) reject++;
+ i--;
+ continue;
+ }
+ indent=wflg=k=nest=esc=quo=0;
+
+/* analize words */
+
+ for (;;j++,k++) {
+ if (buff[j]=='\n' || buff[j]=='\0') {
+ verb_printf(efp,"\nWarning: Incomplete first argument in %s, line %d.",filename,ind[i].lnum);
+ warn++;
+ n++;
+ goto LOOP;
+ }
+
+ if (buff[j]==quote && esc==0 && quo==0) {
+ k--;
+ quo=1;
+ continue;
+ }
+
+ if (quo==0 && buff[j]==escape) {
+ esc=1;
+ }
+
+ if (quo==0) {
+ if (esc==0 && buff[j]==arg_open) {
+ nest++;
+ wbuff[k]=buff[j];
+ continue;
+ }
+ else if (esc==0 && buff[j]==arg_close && nest>0) {
+ nest--;
+ wbuff[k]=buff[j];
+ continue;
+ }
+ if (nest==0) {
+ if (buff[j]==level) {
+ esc=0;
+ if (indent>=2) {
+ fprintf(efp,"\nError: Extra `%c\' in %s, line %d.",level,filename,ind[i].lnum);
+ if (efp!=stderr) fprintf(stderr,"\nError: Extra `%c\' in %s, line %d.",level,filename,ind[i].lnum);
+ eflg++;
+ reject++;
+ n++;
+ goto LOOP;
+ }
+ wbuff[k]='\0';
+ multibyte_to_widechar(utable,BUFSIZE,wbuff);
+ ind[i].idx[indent]=u_xstrdup(utable);
+ if (!wflg) ind[i].org[indent]=NULL;
+ indent++;
+ wflg=0;
+ k= -1;
+ continue;
+ }
+ else if (buff[j]==actual) {
+ esc=0;
+ if (wflg) {
+ fprintf(efp,"\nError: Extra `%c\' in %s, line %d.",actual,filename,ind[i].lnum);
+ if (efp!=stderr) fprintf(stderr,"\nError: Extra `%c\' in %s, line %d.",actual,filename,ind[i].lnum);
+ eflg++;
+ reject++;
+ n++;
+ goto LOOP;
+ }
+ wbuff[k]='\0';
+ multibyte_to_widechar(utable,BUFSIZE,wbuff);
+ ind[i].org[indent]=u_xstrdup(utable);
+ wflg=1;
+ k= -1;
+ continue;
+ }
+ else if ((esc==0 && buff[j]==arg_close) || buff[j]==encap) {
+ esc=0;
+ if (buff[j]==encap) {
+ j++;
+ cc=getestr(&buff[j],estr);
+ if (cc<0) {
+ fprintf(efp,"\nBad encap string in %s, line %d.",filename,ind[i].lnum);
+ if (efp!=stderr) fprintf(stderr,"\nBad encap string in %s, line %d.",filename,ind[i].lnum);
+ eflg++;
+ reject++;
+ n++;
+ goto LOOP;
+ }
+ j+=cc;
+ }
+ else estr[0]='\0';
+
+ wbuff[k]='\0';
+ multibyte_to_widechar(utable,BUFSIZE,wbuff);
+ ind[i].idx[indent]=u_xstrdup(utable);
+ if (u_strlen(ind[i].idx[indent])==0) {
+ if (wflg) {
+ u_strcpy(ind[i].idx[indent],ind[i].org[indent]);
+ }
+ else if (indent>0) {
+ indent--;
+ }
+ else {
+ verb_printf(efp,"\nWarning: Illegal null field in %s, line %d.",filename,ind[i].lnum);
+ warn++;
+ n++;
+ goto LOOP;
+ }
+ }
+ if (!wflg) {
+ ind[i].org[indent]=NULL;
+ }
+ break;
+ }
+ }
+ if (bcomp==1) {
+ if (buff[j]==' ' || buff[j]=='\t') {
+ esc=0;
+ if (k==0) {
+ k--;
+ continue;
+ }
+ else if (buff[j+1]==' ' || buff[j+1]=='\t' || buff[j+1]==encap || buff[j+1]==arg_close || buff[j+1]==actual || buff[j+1]==level) {
+ k--;
+ continue;
+ }
+ else if (buff[j]=='\t') {
+ wbuff[k]=' ';
+ continue;
+ }
+ }
+ }
+ }
+ else quo=0;
+
+ if (buff[j]!=escape) esc=0;
+ copy_multibyte_char(buff, wbuff, &j, &k);
+ }
+ ind[i].words=indent+1;
+
+/* kana-convert */
+
+ for (k=0;k<ind[i].words;k++) {
+ if (ind[i].org[k]==NULL) {
+ cc=convert(ind[i].idx[k],utable);
+ if (cc==-1) {
+ fprintf(efp,"in %s, line %d.",filename,ind[i].lnum);
+ if (efp!=stderr) fprintf(stderr,"in %s, line %d.",filename,ind[i].lnum);
+ eflg++;
+ reject++;
+ n++;
+ goto LOOP;
+ }
+ ind[i].dic[k]=u_xstrdup(utable);
+ }
+ else {
+ cc=convert(ind[i].org[k],utable);
+ if (cc==-1) {
+ fprintf(efp,"in %s, line %d.",filename,ind[i].lnum);
+ if (efp!=stderr) fprintf(stderr,"in %s, line %d.",filename,ind[i].lnum);
+ eflg++;
+ reject++;
+ n++;
+ goto LOOP;
+ }
+ ind[i].dic[k]=u_xstrdup(utable);
+ }
+ }
+ acc++;
+
+/* page edit */
+
+ if (i==0) {
+ ind[0].num=0;
+ ind[0].p=xmalloc(sizeof(struct page)*16);
+ for (;buff[j]!=arg_open && buff[j]!='\n' && buff[j]!='\0';j++);
+ if (buff[j]=='\n' || buff[j]=='\0') {
+ verb_printf(efp,"\nWarning: Missing second argument in %s, line %d.",filename,ind[i].lnum);
+ acc--;
+ reject++;
+ warn++;
+ n++;
+ goto LOOP;
+ }
+ j++;
+ for (k=nest=0;;j++,k++) {
+ if (buff[j]=='\n' || buff[j]=='\0') {
+ verb_printf(efp,"\nWarning: Incomplete second argument in %s, line %d.",filename,ind[i].lnum);
+ acc--;
+ reject++;
+ warn++;
+ n++;
+ goto LOOP;
+ }
+ if (buff[j]==arg_open)
+ nest++;
+ else if (buff[j]==arg_close) {
+ if (nest==0) {
+ table[k]='\0';
+ ind[0].p[0].page=xstrdup(table);
+ break;
+ }
+ else nest--;
+ }
+ copy_multibyte_char(buff, table, &j, &k);
+ }
+ ind[0].p[0].enc=xstrdup(estr);
+ chkpageattr(&ind[0].p[0]);
+ }
+ else {
+ for (l=0;l<i;l++) {
+ flg=0;
+ if (ind[i].words!=ind[l].words) continue;
+ for (flg=1,m=0;m<ind[i].words;m++) {
+ if (u_strcmp(ind[i].idx[m],ind[l].idx[m])!=0) {
+ flg=0;
+ break;
+ }
+ if (u_strcmp(ind[i].dic[m],ind[l].dic[m])!=0) {
+ if (ind[i].org[m]!=NULL) tmp1=ind[i].org[m];
+ else tmp1=ind[i].idx[m];
+
+ if (ind[l].org[m]!=NULL) tmp2=ind[l].org[m];
+ else tmp2=ind[i].idx[m];
+
+ widechar_to_multibyte(wbuff,BUFSIZE,tmp1);
+ verb_printf(efp,"\nWarning: Sort key \"%s\"",wbuff);
+ widechar_to_multibyte(wbuff,BUFSIZE,tmp2);
+ verb_printf(efp," is different from previous key \"%s\"",wbuff);
+ widechar_to_multibyte(wbuff,BUFSIZE,ind[i].idx[m]);
+ verb_printf(efp," for same index \"%s\" in %s, line %d.",wbuff,filename,ind[i].lnum);
+ warn++;
+ flg=0;
+ break;
+ }
+ }
+ if (flg==1) break;
+ }
+
+ if (flg==1) {
+ for (m=0;m<ind[i].words;m++) {
+ free(ind[i].idx[m]);
+ free(ind[i].dic[m]);
+ }
+
+ i--;
+ for (;buff[j]!=arg_open && buff[j]!='\n' && buff[j]!='\0';j++);
+ if (buff[j]=='\n' || buff[j]=='\0') {
+ verb_printf(efp,"\nWarning: Missing second argument in %s, line %d.",filename,ind[i].lnum);
+ acc--;
+ reject++;
+ warn++;
+ n++;
+ i++;
+ goto LOOP;
+ }
+ j++;
+ for (k=nest=0;;j++,k++) {
+ if (buff[j]=='\n' || buff[j]=='\0') {
+ verb_printf(efp,"\nWarning: Incomplete second argument in %s, line %d.",filename,ind[i].lnum);
+ warn++;
+ n++;
+ i++;
+ goto LOOP;
+ }
+ if (buff[j]==arg_open)
+ nest++;
+ else if (buff[j]==arg_close) {
+ if (nest==0) break;
+ else nest--;
+ }
+ copy_multibyte_char(buff, table, &j, &k);
+ }
+
+ table[k]='\0';
+
+ for (k=0;k<=ind[l].num;k++) {
+ if (strcmp(ind[l].p[k].page,table)==0) {
+ if (strcmp(ind[l].p[k].enc,estr)==0) break;
+ }
+ }
+
+ if (k>ind[l].num) {
+ ind[l].num++;
+ if (!((ind[l].num)%16)) ind[l].p=(struct page *)realloc(ind[l].p,sizeof(struct page)*((int)((ind[l].num)/16)+1)*16);
+
+ ind[l].p[ind[l].num].page=xstrdup(table);
+
+ ind[l].p[ind[l].num].enc=xstrdup(estr);
+ chkpageattr(&ind[l].p[ind[l].num]);
+ }
+ }
+ else {
+ ind[i].num=0;
+ ind[i].p=xmalloc(sizeof(struct page)*16);
+ for (;buff[j]!=arg_open && buff[j]!='\n' && buff[j]!='\0';j++);
+ if (buff[j]=='\n' || buff[j]=='\0') {
+ verb_printf(efp,"\nWarning: Missing second argument in %s, line %d.",filename,ind[i].lnum);
+ acc--;
+ reject++;
+ warn++;
+ n++;
+ goto LOOP;
+ }
+ j++;
+ for (k=nest=0;;j++,k++) {
+ if (buff[j]=='\n' || buff[j]=='\0') {
+ verb_printf(efp,"\nWarning: Incomplete second argument in %s, line %d.",filename,ind[i].lnum);
+ acc--;
+ reject++;
+ warn++;
+ n++;
+ goto LOOP;
+ }
+ if (buff[j]==arg_open)
+ nest++;
+ if (buff[j]==arg_close) {
+ if (nest==0) {
+ table[k]='\0';
+ ind[i].p[0].page=xstrdup(table);
+ break;
+ }
+ else nest--;
+ }
+ copy_multibyte_char(buff, table, &j, &k);
+ }
+ ind[l].p[0].enc=xstrdup(estr);
+ chkpageattr(&ind[i].p[0]);
+ }
+ }
+ }
+ lines=i;
+ if (filename != NULL) fclose(fp);
+
+ verb_printf(efp,"...done (%d entries accepted, %d rejected).\n",acc-pacc, reject-preject);
+ return eflg;
+}
+
+/* pic up encap string */
+static int getestr(char *buff, char *estr)
+{
+ int i,nest=0;
+
+ for (i=0;i<strlen(buff);i++) {
+ if (buff[i]==encap) {
+ if (i>0) {
+ if ((unsigned char)buff[i-1]<0x80) {
+ estr[i]=buff[i];
+ i++;
+ }
+ }
+ else {
+ estr[i]=buff[i];
+ i++;
+ }
+ }
+ if (nest==0 && buff[i]==arg_close) {
+ estr[i]='\0';
+ return i;
+ }
+ if (buff[i]==arg_open) nest++;
+ else if (buff[i]==arg_close) nest--;
+ copy_multibyte_char(buff, estr, &i, NULL);
+ }
+
+ return -1;
+}
+
+static void copy_multibyte_char(char *buff1, char *buff2, int *i, int *j)
+{
+ int len;
+
+ if ((unsigned char)buff1[*i]<0x80) {
+ buff2[j ? *j : *i] = buff1[*i];
+ return;
+ }
+ len = multibytelen((unsigned char)buff1[*i]);
+ if (len<0) {
+ verb_printf(efp,"\nWarning: Illegal input of lead byte 0x%x in UTF-8.",(unsigned char)buff1[*i]);
+ len=1; /* copy one byte when illegal lead byte */
+ }
+ while(len--) {
+ buff2[j ? (*j)++ : *i] = buff1[*i];
+ (*i)++;
+ }
+ if (j!=NULL) (*j)--;
+ (*i)--;
+}
+
+int multibyte_to_widechar(UChar *wcstr, int32_t size, char *mbstr)
+{
+ int32_t len, olen, nsub;
+ UErrorCode err;
+
+ len=strlen(mbstr)+1;
+ do {
+ err = U_ZERO_ERROR;
+ len--;
+ u_strFromUTF8WithSub(NULL, 0, &olen, mbstr, len, 0xFFFD, &nsub, &err);
+ } while (olen>=size);
+ err = U_ZERO_ERROR;
+ u_strFromUTF8WithSub(wcstr, size, &olen, mbstr, len, 0xFFFD, &nsub, &err);
+ return olen;
+}
+
+int widechar_to_multibyte(char *mbstr, int32_t size, UChar *wcstr)
+{
+ int32_t len, olen, nsub;
+ UErrorCode err;
+
+ len=u_strlen(wcstr)+1;
+ do {
+ err = U_ZERO_ERROR;
+ len--;
+ u_strToUTF8WithSub(NULL, 0, &olen, wcstr, len, 0xFFFD, &nsub, &err);
+ } while (olen>=size);
+ err = U_ZERO_ERROR;
+ u_strToUTF8WithSub(mbstr, size, &olen, wcstr, len, 0xFFFD, &nsub, &err);
+ return olen;
+}
+
+static void chkpageattr(struct page *p)
+{
+ int i,j,cc=0;
+
+ for (i=0;i<strlen(p->page);i++) {
+ if (strncmp(page_compositor,&p->page[i],strlen(page_compositor))==0) {
+ p->attr[cc]=pattr[cc];
+ cc++;
+ i+=strlen(page_compositor)-1;
+ }
+ 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'))) {
+ p->attr[cc]= -1;
+ if (cc<2) p->attr[++cc]= -1;
+ return;
+ }
+ switch(page_precedence[pattr[cc]]) {
+ case 'r':
+ if (strchr("ivxlcdm",p->page[i])==NULL) {
+ pattr[cc]++;
+ for (j=cc+1;j<3;j++) pattr[j]=0;
+ goto ATTRLOOP;
+ }
+ break;
+ case 'R':
+ if (strchr("IVXLCDM",p->page[i])==NULL) {
+ pattr[cc]++;
+ for (j=cc+1;j<3;j++) pattr[j]=0;
+ goto ATTRLOOP;
+ }
+ break;
+ case 'n':
+ if (p->page[i]<'0' || p->page[i]>'9') {
+ pattr[cc]++;
+ for (j=cc+1;j<3;j++) pattr[j]=0;
+ goto ATTRLOOP;
+ }
+ break;
+ case 'a':
+ if (p->page[i]<'a' || p->page[i]>'z') {
+ pattr[cc]++;
+ for (j=cc+1;j<3;j++) pattr[j]=0;
+ goto ATTRLOOP;
+ }
+ break;
+ case 'A':
+ if (p->page[i]<'A' || p->page[i]>'Z') {
+ pattr[cc]++;
+ for (j=cc+1;j<3;j++) pattr[j]=0;
+ goto ATTRLOOP;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ p->attr[cc]=pattr[cc];
+ if (cc<2) p->attr[++cc]= -1;
+}