/* * Auxilliary routines for BibTeX in C. * * Tim Morgan 2/15/88 * Eduardo Krell 4/21/88 */ /* * JBibTeX Version by Shouichi Matsui * matsui@denken.or.jp (matsui%denken.or.jp@uunet.uu.net) * 1989-05-02 * Last updated: 1990-12-29 * many codes are from ../cjtex/extra.c by T. Sakurai */ /* * Modified for pTeX 2.1 by Kazunori Aasayama * asayama@kuis.kyoto-u.ac.jp Sep. 4, 1995 * Modified for pTeX 2.1.5 by Kazunori Aasayama * asayama@vsp.cpg.sony.co.jp March. 14, 1997 */ /* Change DEFAULT_FILE_CODE, DEFAULT_TERM_CODE definition for your site code 1 JIS; Kanji-in ESC$@, Kanji-out ESC(J 2 JIS; Kanji-in ESC$@, Kanji-out ESC(H 3 JIS; Kanji-in ESC$@, Kanji-out ESC(B 4 JIS; Kanji-in ESC$B, Kanji-out ESC(J 5 JIS; Kanji-in ESC$B, Kanji-out ESC(H 6 JIS; Kanji-in ESC$B, Kanji-out ESC(B 10 Shift JIS 20 EUC */ /* #define KANJI */ #define KANJI_C #include "kanji.h" #include "jbibd.h" #include /* const_string based_prog_name="BibTeX"; const_string based_prog_version="0.99c"; */ #ifdef OUTJIS # define DEFAULT_FILE_CODE 6 /* JIS */ # define DEFAULT_TERM_CODE 6 /* JIS */ #else # ifdef OUTSJIS # define DEFAULT_FILE_CODE 10 /* SJIS */ # define DEFAULT_TERM_CODE 10 /* SJIS */ # else /* EUC */ # ifdef OUTEUC # define DEFAULT_FILE_CODE 20 /* EUC */ # define DEFAULT_TERM_CODE 20 /* EUC */ # else # error /* unexpected. */ # endif # endif #endif /* END OF SITE DEPENDENT DEFINITIONS */ typedef ASCIIcode textchar; typedef struct kaninfo_s kaninfo; struct kaninfo_s{ char ktype, kstat; textchar kpend; int (*in_ln)(); int (*out_ch)(); kaninfo *next; }; static kaninfo kanjiinfo_table[NOFILE]; static int kanji_file_code, kanji_term_code; /* kanji code same as NTT-JTeX */ static get_kanji_code(); static set_kanji_type(); boolean jbibtex_open_input (f, path_index, fopen_mode) FILE **f; int path_index; const_string fopen_mode; { boolean result; result = open_input(f,path_index,fopen_mode); if (result == false) return false; set_kanji_type(*f, kanji_file_code); return result; } boolean jbibtex_open_output (f, fopen_mode) FILE **f; const_string fopen_mode; { boolean result; result = open_output(f,fopen_mode); if (result == false) return false; set_kanji_type(*f, kanji_file_code); return result; } boolean inputline(f) FILE *f; { int in; register kaninfo *ki; last = 0; ki = &kanjiinfo_table[fileno(f)]; in = (*(ki->in_ln))(f,ki); if (in == EOF && last == 0) return false; if (in != EOF && in != '\n' && in != '\r') return false; /* Don't bother using xord if we don't need to. */ #ifdef NONASCII /* for (in = 0; in <= last; in++) buffer[in] = xord[buffer[in]]; */ #endif return true; } jbibtex_printstr(s, c) char *s, c; { static unsigned char temp_buff[4096]; /* maybe too long */ sprintf(temp_buff, "%s%c", s, c); jbibtex_Fputs(logfile, temp_buff); jbibtex_Fputs(stdout, temp_buff); } jbibtex_putc(c, f) textchar c; FILE *f; { register kaninfo *ki; ki = &kanjiinfo_table[fileno(f)]; (*(ki->out_ch))(c, f, ki); } jbibtex_Fputs(f, s) register FILE *f; register textchar *s; { register kaninfo *ki; ki = &kanjiinfo_table[fileno(f)]; for (; *s; s++) (*(ki->out_ch))(*s, f, ki); } initkanji() { get_kanji_code(); } /*** internal routines ***/ /* kanji state */ #define KAN_ASCII 0 #define KAN_JIS_FIRST 1 #define KAN_JIS_SECOND 2 #define KAN_ASCII_KAN 3 #define ESC '\033' #define KANJIBIT 0x80 #define isTeXkanji(c) ((c)&KANJIBIT) #define deTeXkanji(c) ((c)&~KANJIBIT) static int in_ln_gen(); static int in_ln_ascii(); static int in_ln_jis(); static int in_ln_sjis(); static int out_ch_ascii(); static int out_ch_jis(); static int out_ch_sjis(); static int out_ch_euc(); static integer check_euc_kanji(); static integer check_sj_kanji(); static integer fix_kanji_range(); static int (*in_ln_tab[])() = { in_ln_ascii, in_ln_jis, in_ln_jis, in_ln_jis, in_ln_jis, in_ln_jis, in_ln_jis, 0, 0, 0, in_ln_sjis, 0, 0, 0, 0, 0, 0, 0, 0, 0, in_ln_jis }; static int (*out_ch_tab[])() = { out_ch_ascii, out_ch_jis, out_ch_jis, out_ch_jis, out_ch_jis, out_ch_jis, out_ch_jis, 0, 0, 0, out_ch_sjis, 0, 0, 0, 0, 0, 0, 0, 0, 0, out_ch_euc }; struct { char esc_in, esc_out; } jis_esc_tab[] = { {'\0', '\0'}, /* dummy */ {'@', 'J'}, {'@', 'H'}, {'@', 'B'}, {'B', 'J'}, {'B', 'H'}, {'B', 'B'} }; static get_kanji_code() { extern int atoi(); register char *p; if (prockanjicode == JIS) kanji_file_code = 6; else if (prockanjicode == EUC) kanji_file_code = 20; else if (prockanjicode == SJIS) kanji_file_code = 10; else kanji_file_code = DEFAULT_FILE_CODE; kanji_term_code = DEFAULT_TERM_CODE; if( p=kpse_var_value("BIBFILECODE") ) kanji_file_code = atoi(p); if( (kanji_file_code<1)||(kanji_file_code>20)|| (in_ln_tab[kanji_file_code] == 0) ) { fprintf(stderr,"Kanji File Code:%d is illegal. I'll use system default\n", kanji_file_code); kanji_file_code = DEFAULT_FILE_CODE; } if( p=kpse_var_value("BIBTERMCODE") ) kanji_term_code = atoi(p); if( (kanji_term_code<1)||(kanji_term_code>20)|| (in_ln_tab[kanji_term_code] == 0 ) ) { fprintf(stderr,"Kanji Term Code:%d is illegal. I'll use system default\n", kanji_term_code); kanji_term_code = DEFAULT_TERM_CODE; } set_kanji_type(stdout,kanji_term_code); set_kanji_type(stderr,kanji_term_code); } static set_kanji_type(f, ktype) FILE *f; int ktype; { kaninfo *ki; ki = &kanjiinfo_table[fileno(f)]; ki->ktype = ktype; ki->kstat = KAN_ASCII; ki->in_ln = in_ln_tab[ktype]; ki->out_ch = out_ch_tab[ktype]; } static int in_ln_ascii(f, ki) register FILE *f; kaninfo *ki; { register int i; while ( last < bufsize && ((i = getc(f)) != EOF) && i != '\n' && i != '\r') { #ifdef NONASCII buffer[last++] = i; #else buffer[last++] = (i > 127 || i < 0)?' ':i; #endif } return (i); } static int in_ln_jis(f, ki) FILE *f; kaninfo *ki; { return (in_ln_gen(f, ki, check_euc_kanji, fix_kanji_range)); } static int in_ln_sjis(f, ki) FILE *f; kaninfo *ki; { return (in_ln_gen(f, ki, check_sj_kanji, SJIStoEUC)); } static integer check_euc_kanji(c, ki) textchar c; kaninfo *ki; { /* An illegal kanji should be detected, but ... */ if (isTeXkanji(c)) { ki->kpend = c; ki->kstat = KAN_ASCII_KAN; } else buffer[last++] = c; } static integer check_sj_kanji(c, ki) textchar c; kaninfo *ki; { if (c >= 0xe0 || c >= 0x80 && c < 0xa0) { ki->kpend = c; ki->kstat = KAN_ASCII_KAN; } else if (c < 0x80) buffer[last++] = c; else { /* Web procedure should be called for a better error handling. */ fprintf(stderr, "\n1-byte kana (shift-jis) ignored.\n"); buffer[last++] = '?'; } } static int in_ln_gen(f, ki, checkkanji, makekanji) register FILE *f; register kaninfo *ki; int (*checkkanji)(), (*makekanji)(); { register int i; while ( last < bufsize && ((i = getc(f)) != EOF) && i != '\n' && i !='\r') { if (ki->kstat == KAN_ASCII) { if (i == ESC) { if ((i = getc(f)) == '$') { getc(f); ki->kstat = KAN_JIS_SECOND; } else if (i == '(') { getc(f); /* ki->kstat = KAN_ASCII; */ } else { /* Web procedure should be called for a better error handling. */ fprintf(stderr,"\nText line contains an invalid escape sequence\n"); exit(1); } } else (*checkkanji)(i, ki); } else if (ki->kstat == KAN_JIS_FIRST) { integer c; if (last >= bufsize-1) return(i); c = fix_kanji_range(JIStoEUC(((integer)ki->kpend << 8) | i)); buffer[last++] = c >> 8; buffer[last++] = c & 0xff; ki->kstat = KAN_JIS_SECOND; } else if (ki->kstat == KAN_JIS_SECOND) { if (i == ESC) { if ((i = getc(f)) == '$') { getc(f); /* ki->kstat = KAN_JIS_SECOND; */ } else if (i == '(') { getc(f); ki->kstat = KAN_ASCII; } else { /* Web procedure should be called for a better error handling. */ fprintf(stderr,"\nText line contains an invalid escape sequence\n"); exit(1); } } else if (i < ' ') { buffer[last++] = i; } else { ki->kpend = i; ki->kstat = KAN_JIS_FIRST; } } else /*if (ki->kstat == KAN_ASCII_KAN)*/ { integer c; if (last >= bufsize-1) return(i); c = fix_kanji_range((*makekanji)(((integer)ki->kpend << 8) | i)); buffer[last++] = c >> 8; buffer[last++] = c & 0xff; ki->kstat = KAN_ASCII; } } return (i); } static out_ch_ascii(c, f, ki) textchar c; FILE *f; kaninfo *ki; { putc(deTeXkanji(c), f); } static out_ch_jis(c, f, ki) textchar c; FILE *f; register kaninfo *ki; { int cj; if (ki->kstat == KAN_JIS_FIRST) { cj = EUCtoJIS(((integer)ki->kpend << 8) | c); putc(cj >> 8, f); putc(cj & 0xff, f); ki->kstat = KAN_JIS_SECOND; } else if (isTeXkanji(c)) { if (ki->kstat == KAN_ASCII) { putc(ESC, f); putc('$', f); putc(jis_esc_tab[ki->ktype].esc_in, f); } ki->kpend = c; ki->kstat = KAN_JIS_FIRST; } else { if (ki->kstat == KAN_JIS_SECOND) { putc(ESC, f); putc('(', f); putc(jis_esc_tab[ki->ktype].esc_out, f); } putc(c, f); ki->kstat = KAN_ASCII; } } static out_ch_sjis(c, f, ki) textchar c; FILE *f; register kaninfo *ki; { textchar c1, c2; if (ki->kstat == KAN_ASCII_KAN) { integer csj; csj = EUCtoSJIS(((integer)ki->kpend << 8) | c); putc(csj >> 8, f); putc(csj & 0xff, f); ki->kstat = KAN_ASCII; } else if (isTeXkanji(c)) { ki->kpend = c; ki->kstat = KAN_ASCII_KAN; } else putc(c, f); } static out_ch_euc(c, f, ki) textchar c; FILE *f; kaninfo *ki; { putc(c, f); } /* * Kanji conversion functions */ static integer fix_kanji_range(c) integer c; { return (c < 0xa100 || (c >= 0xa900 && c <= 0xafff) || c >= 0xf500) ? 0xa2a3 : c; }