X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Ffile-coding.c;h=3068c896823dac45e334b378d4adf0bf92d709c6;hb=4082f470d7c6075a5c04c1bdf6e9e3f27c9700d5;hp=7a7eee3ad32196326ec51dce11096b75eb16d8ca;hpb=44e716ef11bd794a51f8c5b56c4f3f10a7dbf217;p=chise%2Fxemacs-chise.git- diff --git a/src/file-coding.c b/src/file-coding.c index 7a7eee3..3068c89 100644 --- a/src/file-coding.c +++ b/src/file-coding.c @@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" + #include "buffer.h" #include "elhash.h" #include "insdel.h" @@ -244,10 +245,46 @@ static Lisp_Object mark_coding_system (Lisp_Object, void (*) (Lisp_Object)); static void print_coding_system (Lisp_Object, Lisp_Object, int); static void finalize_coding_system (void *header, int for_disksave); +#ifdef MULE +static const struct lrecord_description ccs_description_1[] = { + { XD_LISP_OBJECT, offsetof(charset_conversion_spec, from_charset), 2 }, + { XD_END } +}; + +static const struct struct_description ccs_description = { + sizeof(charset_conversion_spec), + ccs_description_1 +}; + +static const struct lrecord_description ccsd_description_1[] = { + XD_DYNARR_DESC(charset_conversion_spec_dynarr, &ccs_description), + { XD_END } +}; + +static const struct struct_description ccsd_description = { + sizeof(charset_conversion_spec_dynarr), + ccsd_description_1 +}; +#endif + +static const struct lrecord_description coding_system_description[] = { + { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, name), 2 }, + { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, mnemonic), 3 }, + { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, eol_lf), 3 }, +#ifdef MULE + { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, iso2022.initial_charset), 4 }, + { XD_STRUCT_PTR, offsetof(struct Lisp_Coding_System, iso2022.input_conv), 1, &ccsd_description }, + { XD_STRUCT_PTR, offsetof(struct Lisp_Coding_System, iso2022.output_conv), 1, &ccsd_description }, + { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, ccl.decode), 2 }, +#endif + { XD_END } +}; + DEFINE_LRECORD_IMPLEMENTATION ("coding-system", coding_system, mark_coding_system, print_coding_system, finalize_coding_system, - 0, 0, struct Lisp_Coding_System); + 0, 0, coding_system_description, + struct Lisp_Coding_System); static Lisp_Object mark_coding_system (Lisp_Object obj, void (*markobj) (Lisp_Object)) @@ -1583,26 +1620,65 @@ determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out, if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT || *eol_type_in_out == EOL_AUTODETECT) { + unsigned char random_buffer[4096]; + int nread; + Lisp_Object coding_system = Qnil; - while (1) + nread = Lstream_read (stream, random_buffer, sizeof (random_buffer)); + if (nread) { - unsigned char random_buffer[4096]; - int nread; + unsigned char *cp = random_buffer; - nread = Lstream_read (stream, random_buffer, sizeof (random_buffer)); - if (!nread) - break; - if (detect_coding_type (&decst, random_buffer, nread, - XCODING_SYSTEM_TYPE (*codesys_in_out) != - CODESYS_AUTODETECT)) - break; - } + while (cp < random_buffer + nread) + { + if ((*cp++ == 'c') && (cp < random_buffer + nread) && + (*cp++ == 'o') && (cp < random_buffer + nread) && + (*cp++ == 'd') && (cp < random_buffer + nread) && + (*cp++ == 'i') && (cp < random_buffer + nread) && + (*cp++ == 'n') && (cp < random_buffer + nread) && + (*cp++ == 'g') && (cp < random_buffer + nread) && + (*cp++ == ':') && (cp < random_buffer + nread)) + { + unsigned char coding_system_name[4096 - 6]; + unsigned char *np = coding_system_name; + while ( (cp < random_buffer + nread) + && ((*cp == ' ') || (*cp == '\t')) ) + { + cp++; + } + while ( (cp < random_buffer + nread) && + (*cp != ' ') && (*cp != '\t') && (*cp != ';') ) + { + *np++ = *cp++; + } + *np = 0; + coding_system + = Ffind_coding_system (intern (coding_system_name)); + break; + } + } + if (EQ(coding_system, Qnil)) + do{ + if (detect_coding_type (&decst, random_buffer, nread, + XCODING_SYSTEM_TYPE (*codesys_in_out) + != CODESYS_AUTODETECT)) + break; + nread = Lstream_read (stream, + random_buffer, sizeof (random_buffer)); + if (!nread) + break; + } while(1); + } *eol_type_in_out = decst.eol_type; if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT) - *codesys_in_out = coding_system_from_mask (decst.mask); + { + if (EQ(coding_system, Qnil)) + *codesys_in_out = coding_system_from_mask (decst.mask); + else + *codesys_in_out = coding_system; + } } - /* If we absolutely can't determine the EOL type, just assume LF. */ if (*eol_type_in_out == EOL_AUTODETECT) *eol_type_in_out = EOL_LF; @@ -1725,6 +1801,62 @@ do { \ /* C should be a binary character in the range 0 - 255; convert to internal format and add to Dynarr DST. */ +#ifdef UTF2000 +#define DECODE_ADD_BINARY_CHAR(c, dst) \ +do { \ + if (BYTE_ASCII_P (c)) \ + Dynarr_add (dst, c); \ + else \ + { \ + Dynarr_add (dst, (c >> 6) | 0xc0); \ + Dynarr_add (dst, (c & 0x3f) | 0x80); \ + } \ +} while (0) + +INLINE void +DECODE_ADD_UCS_CHAR(Emchar c, unsigned_char_dynarr* dst) +{ + if ( c <= 0x7f ) + { + Dynarr_add (dst, c); + } + else if ( c <= 0x7ff ) + { + Dynarr_add (dst, (c >> 6) | 0xc0); + Dynarr_add (dst, (c & 0x3f) | 0x80); + } + else if ( c <= 0xffff ) + { + Dynarr_add (dst, (c >> 12) | 0xe0); + Dynarr_add (dst, ((c >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (c & 0x3f) | 0x80); + } + else if ( c <= 0x1fffff ) + { + Dynarr_add (dst, (c >> 18) | 0xf0); + Dynarr_add (dst, ((c >> 12) & 0x3f) | 0x80); + Dynarr_add (dst, ((c >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (c & 0x3f) | 0x80); + } + else if ( c <= 0x3ffffff ) + { + Dynarr_add (dst, (c >> 24) | 0xf8); + Dynarr_add (dst, ((c >> 18) & 0x3f) | 0x80); + Dynarr_add (dst, ((c >> 12) & 0x3f) | 0x80); + Dynarr_add (dst, ((c >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (c & 0x3f) | 0x80); + } + else + { + Dynarr_add (dst, (c >> 30) | 0xfc); + Dynarr_add (dst, ((c >> 24) & 0x3f) | 0x80); + Dynarr_add (dst, ((c >> 18) & 0x3f) | 0x80); + Dynarr_add (dst, ((c >> 12) & 0x3f) | 0x80); + Dynarr_add (dst, ((c >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (c & 0x3f) | 0x80); + } +} +#else #define DECODE_ADD_BINARY_CHAR(c, dst) \ do { \ if (BYTE_ASCII_P (c)) \ @@ -1740,6 +1872,7 @@ do { \ Dynarr_add (dst, c); \ } \ } while (0) +#endif #define DECODE_OUTPUT_PARTIAL_CHAR(ch) \ do { \ @@ -1799,6 +1932,9 @@ struct decoding_stream /* Additional information (the state of the running CCL program) used by the CCL decoder. */ struct ccl_program ccl; + + /* counter for UTF-8 or UCS-4 */ + unsigned char counter; #endif struct detection_state decst; }; @@ -1933,6 +2069,7 @@ reset_decoding_stream (struct decoding_stream *str) { setup_ccl_program (&str->ccl, CODING_SYSTEM_CCL_DECODE (str->codesys)); } + str->counter = 0; #endif /* MULE */ str->flags = str->ch = 0; } @@ -2116,6 +2253,7 @@ mule_decode (Lstream *decoding, CONST unsigned char *src, decode_coding_utf8 (decoding, src, dst, n); break; case CODESYS_CCL: + str->ccl.last_block = str->flags & CODING_STATE_END; ccl_driver (&str->ccl, src, dst, n, 0, CCL_MODE_DECODING); break; case CODESYS_ISO2022: @@ -2394,7 +2532,11 @@ reset_encoding_stream (struct encoding_stream *str) str->iso2022.register_right = 1; str->iso2022.current_charset = Qnil; str->iso2022.current_half = 0; +#ifdef UTF2000 + str->iso2022.current_char_boundary = 0; +#else str->iso2022.current_char_boundary = 1; +#endif break; } case CODESYS_CCL: @@ -2528,6 +2670,7 @@ mule_encode (Lstream *encoding, CONST unsigned char *src, encode_coding_utf8 (encoding, src, dst, n); break; case CODESYS_CCL: + str->ccl.last_block = str->flags & CODING_STATE_END; ccl_driver (&str->ccl, src, dst, n, 0, CCL_MODE_ENCODING); break; case CODESYS_ISO2022: @@ -2687,10 +2830,16 @@ decode_coding_sjis (Lstream *decoding, CONST unsigned char *src, { unsigned char e1, e2; - Dynarr_add (dst, LEADING_BYTE_JAPANESE_JISX0208); DECODE_SJIS (ch, c, e1, e2); +#ifdef UTF2000 + DECODE_ADD_UCS_CHAR(MAKE_CHAR(Vcharset_japanese_jisx0208, + e1 & 0x7F, + e2 & 0x7F), dst); +#else + Dynarr_add (dst, LEADING_BYTE_JAPANESE_JISX0208); Dynarr_add (dst, e1); Dynarr_add (dst, e2); +#endif } else { @@ -2706,8 +2855,13 @@ decode_coding_sjis (Lstream *decoding, CONST unsigned char *src, ch = c; else if (BYTE_SJIS_KATAKANA_P (c)) { +#ifdef UTF2000 + DECODE_ADD_UCS_CHAR(MAKE_CHAR(Vcharset_katakana_jisx0201, + c & 0x7F, 0), dst); +#else Dynarr_add (dst, LEADING_BYTE_KATAKANA_JISX0201); Dynarr_add (dst, c); +#endif } else DECODE_ADD_BINARY_CHAR (c, dst); @@ -2732,10 +2886,82 @@ encode_coding_sjis (Lstream *encoding, CONST unsigned char *src, unsigned int flags = str->flags; unsigned int ch = str->ch; eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys); +#ifdef UTF2000 + unsigned char char_boundary = str->iso2022.current_char_boundary; +#endif while (n--) { c = *src++; +#ifdef UTF2000 + switch (char_boundary) + { + case 0: + if ( c >= 0xfc ) + { + ch = c & 0x01; + char_boundary = 5; + } + else if ( c >= 0xf8 ) + { + ch = c & 0x03; + char_boundary = 4; + } + else if ( c >= 0xf0 ) + { + ch = c & 0x07; + char_boundary = 3; + } + else if ( c >= 0xe0 ) + { + ch = c & 0x0f; + char_boundary = 2; + } + else if ( c >= 0xc0 ) + { + ch = c & 0x1f; + char_boundary = 1; + } + else + { + ch = 0; + if (c == '\n') + { + if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) + Dynarr_add (dst, '\r'); + if (eol_type != EOL_CR) + Dynarr_add (dst, c); + } + else + Dynarr_add (dst, c); + char_boundary = 0; + } + break; + case 1: + ch = ( ch << 6 ) | ( c & 0x3f ); + { + Lisp_Object charset; + unsigned int c1, c2, s1, s2; + + BREAKUP_CHAR (ch, charset, c1, c2); + if (EQ(charset, Vcharset_katakana_jisx0201)) + { + Dynarr_add (dst, c1 | 0x80); + } + else if (EQ(charset, Vcharset_japanese_jisx0208)) + { + ENCODE_SJIS (c1 | 0x80, c2 | 0x80, s1, s2); + Dynarr_add (dst, s1); + Dynarr_add (dst, s2); + } + } + char_boundary = 0; + break; + default: + ch = ( ch << 6 ) | ( c & 0x3f ); + char_boundary--; + } +#else if (c == '\n') { if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) @@ -2772,10 +2998,14 @@ encode_coding_sjis (Lstream *encoding, CONST unsigned char *src, ch = 0; } } +#endif } str->flags = flags; str->ch = ch; +#ifdef UTF2000 + str->iso2022.current_char_boundary = char_boundary; +#endif } DEFUN ("decode-shift-jis-char", Fdecode_shift_jis_char, 1, 1, 0, /* @@ -3007,6 +3237,7 @@ static void encode_coding_big5 (Lstream *encoding, CONST unsigned char *src, unsigned_char_dynarr *dst, unsigned int n) { +#ifndef UTF2000 unsigned char c; struct encoding_stream *str = ENCODING_STREAM_DATA (encoding); unsigned int flags = str->flags; @@ -3061,6 +3292,7 @@ encode_coding_big5 (Lstream *encoding, CONST unsigned char *src, str->flags = flags; str->ch = ch; +#endif } @@ -3081,7 +3313,7 @@ Return the corresponding character. if (BYTE_BIG5_TWO_BYTE_1_P (b1) && BYTE_BIG5_TWO_BYTE_2_P (b2)) { - int leading_byte; + Charset_ID leading_byte; Lisp_Object charset; DECODE_BIG5 (b1, b2, leading_byte, c1, c2); charset = CHARSET_BY_LEADING_BYTE (leading_byte); @@ -3199,6 +3431,9 @@ Return the UCS code (a positive integer) corresponding to CHARACTER. return Fget_char_table (character, mule_to_ucs_table); } +#ifdef UTF2000 +#define decode_ucs4 DECODE_ADD_UCS_CHAR +#else /* Decode a UCS-4 character into a buffer. If the lookup fails, use (U+3013) of JIS X 0208, which means correct character is not found, instead. @@ -3227,6 +3462,7 @@ decode_ucs4 (unsigned long ch, unsigned_char_dynarr *dst) Dynarr_add (dst, 46 + 128); } } +#endif static unsigned long mule_char_to_ucs4 (Lisp_Object charset, @@ -3304,37 +3540,40 @@ decode_coding_ucs4 (Lstream *decoding, CONST unsigned char *src, struct decoding_stream *str = DECODING_STREAM_DATA (decoding); unsigned int flags = str->flags; unsigned int ch = str->ch; + unsigned char counter = str->counter; while (n--) { unsigned char c = *src++; - switch (flags) + switch (counter) { case 0: ch = c; - flags = 3; + counter = 3; break; case 1: decode_ucs4 ( ( ch << 8 ) | c, dst); ch = 0; - flags = 0; + counter = 0; break; default: ch = ( ch << 8 ) | c; - flags--; + counter--; } } - if (flags & CODING_STATE_END) + if (counter & CODING_STATE_END) DECODE_OUTPUT_PARTIAL_CHAR (ch); str->flags = flags; str->ch = ch; + str->counter = counter; } static void encode_coding_ucs4 (Lstream *encoding, CONST unsigned char *src, unsigned_char_dynarr *dst, unsigned int n) { +#ifndef UTF2000 struct encoding_stream *str = ENCODING_STREAM_DATA (encoding); unsigned int flags = str->flags; unsigned int ch = str->ch; @@ -3463,6 +3702,7 @@ encode_coding_ucs4 (Lstream *encoding, CONST unsigned char *src, str->iso2022.current_charset = charset; /* Verbum caro factum est! */ +#endif } @@ -3513,37 +3753,38 @@ decode_coding_utf8 (Lstream *decoding, CONST unsigned char *src, unsigned int flags = str->flags; unsigned int ch = str->ch; eol_type_t eol_type = str->eol_type; + unsigned char counter = str->counter; while (n--) { unsigned char c = *src++; - switch (flags) + switch (counter) { case 0: if ( c >= 0xfc ) { ch = c & 0x01; - flags = 5; + counter = 5; } else if ( c >= 0xf8 ) { ch = c & 0x03; - flags = 4; + counter = 4; } else if ( c >= 0xf0 ) { ch = c & 0x07; - flags = 3; + counter = 3; } else if ( c >= 0xe0 ) { ch = c & 0x0f; - flags = 2; + counter = 2; } else if ( c >= 0xc0 ) { ch = c & 0x1f; - flags = 1; + counter = 1; } else { @@ -3555,11 +3796,11 @@ decode_coding_utf8 (Lstream *decoding, CONST unsigned char *src, ch = ( ch << 6 ) | ( c & 0x3f ); decode_ucs4 (ch, dst); ch = 0; - flags = 0; + counter = 0; break; default: ch = ( ch << 6 ) | ( c & 0x3f ); - flags--; + counter--; } label_continue_loop:; } @@ -3569,8 +3810,10 @@ decode_coding_utf8 (Lstream *decoding, CONST unsigned char *src, str->flags = flags; str->ch = ch; + str->counter = counter; } +#ifndef UTF2000 static void encode_utf8 (Lisp_Object charset, unsigned char h, unsigned char l, unsigned_char_dynarr *dst) @@ -3616,6 +3859,7 @@ encode_utf8 (Lisp_Object charset, Dynarr_add (dst, (code & 0x3f) | 0x80); } } +#endif static void encode_coding_utf8 (Lstream *encoding, CONST unsigned char *src, @@ -3626,6 +3870,63 @@ encode_coding_utf8 (Lstream *encoding, CONST unsigned char *src, unsigned int ch = str->ch; eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys); unsigned char char_boundary = str->iso2022.current_char_boundary; +#ifdef UTF2000 + + while (n--) + { + unsigned char c = *src++; + switch (char_boundary) + { + case 0: + if ( c >= 0xfc ) + { + Dynarr_add (dst, c); + char_boundary = 5; + } + else if ( c >= 0xf8 ) + { + Dynarr_add (dst, c); + char_boundary = 4; + } + else if ( c >= 0xf0 ) + { + Dynarr_add (dst, c); + char_boundary = 3; + } + else if ( c >= 0xe0 ) + { + Dynarr_add (dst, c); + char_boundary = 2; + } + else if ( c >= 0xc0 ) + { + Dynarr_add (dst, c); + char_boundary = 1; + } + else + { + if (c == '\n') + { + if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) + Dynarr_add (dst, '\r'); + if (eol_type != EOL_CR) + Dynarr_add (dst, c); + } + else + Dynarr_add (dst, c); + char_boundary = 0; + } + break; + case 1: + Dynarr_add (dst, c); + char_boundary = 0; + break; + default: + Dynarr_add (dst, c); + char_boundary--; + } + } +#else /* not UTF2000 */ Lisp_Object charset = str->iso2022.current_charset; #ifdef ENABLE_COMPOSITE_CHARS @@ -3749,10 +4050,13 @@ encode_coding_utf8 (Lstream *encoding, CONST unsigned char *src, } #endif +#endif /* not UTF2000 */ str->flags = flags; str->ch = ch; str->iso2022.current_char_boundary = char_boundary; +#ifndef UTF2000 str->iso2022.current_charset = charset; +#endif /* Verbum caro factum est! */ } @@ -4652,7 +4956,9 @@ decode_coding_iso2022 (Lstream *decoding, CONST unsigned char *src, else { /* Graphic characters */ Lisp_Object charset; - int lb; +#ifndef UTF2000 + Charset_ID lb; +#endif int reg; DECODE_HANDLE_EOL_TYPE (eol_type, c, flags, dst); @@ -4695,6 +5001,22 @@ decode_coding_iso2022 (Lstream *decoding, CONST unsigned char *src, charset = new_charset; } +#ifdef UTF2000 + if (XCHARSET_DIMENSION (charset) == 1) + { + DECODE_OUTPUT_PARTIAL_CHAR (ch); + DECODE_ADD_UCS_CHAR + (MAKE_CHAR (charset, c & 0x7F, 0), dst); + } + else if (ch) + { + DECODE_ADD_UCS_CHAR + (MAKE_CHAR (charset, ch & 0x7F, c & 0x7F), dst); + ch = 0; + } + else + ch = c; +#else lb = XCHARSET_LEADING_BYTE (charset); switch (XCHARSET_REP_BYTES (charset)) { @@ -4743,6 +5065,7 @@ decode_coding_iso2022 (Lstream *decoding, CONST unsigned char *src, else ch = c; } +#endif } if (!ch) @@ -4860,12 +5183,15 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src, unsigned char char_boundary; struct encoding_stream *str = ENCODING_STREAM_DATA (encoding); unsigned int flags = str->flags; - unsigned int ch = str->ch; + Emchar ch = str->ch; Lisp_Coding_System *codesys = str->codesys; eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys); int i; Lisp_Object charset; int half; +#ifdef UTF2000 + unsigned int byte1, byte2; +#endif #ifdef ENABLE_COMPOSITE_CHARS /* flags for handling composite chars. We do a little switcharoo @@ -4882,6 +5208,216 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src, #ifdef ENABLE_COMPOSITE_CHARS back_to_square_n: #endif +#ifdef UTF2000 + while (n--) + { + c = *src++; + + switch (char_boundary) + { + case 0: + if ( c >= 0xfc ) + { + ch = c & 0x01; + char_boundary = 5; + } + else if ( c >= 0xf8 ) + { + ch = c & 0x03; + char_boundary = 4; + } + else if ( c >= 0xf0 ) + { + ch = c & 0x07; + char_boundary = 3; + } + else if ( c >= 0xe0 ) + { + ch = c & 0x0f; + char_boundary = 2; + } + else if ( c >= 0xc0 ) + { + ch = c & 0x1f; + char_boundary = 1; + } + else + { + ch = 0; + + restore_left_to_right_direction (codesys, dst, &flags, 0); + + /* Make sure G0 contains ASCII */ + if ((c > ' ' && c < ISO_CODE_DEL) || + !CODING_SYSTEM_ISO2022_NO_ASCII_CNTL (codesys)) + { + ensure_normal_shift (str, dst); + iso2022_designate (Vcharset_ascii, 0, str, dst); + } + + /* If necessary, restore everything to the default state + at end-of-line */ + if (c == '\n' && + !(CODING_SYSTEM_ISO2022_NO_ASCII_EOL (codesys))) + { + restore_left_to_right_direction (codesys, dst, &flags, 0); + + ensure_normal_shift (str, dst); + + for (i = 0; i < 4; i++) + { + Lisp_Object initial_charset = + CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i); + iso2022_designate (initial_charset, i, str, dst); + } + } + if (c == '\n') + { + if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) + Dynarr_add (dst, '\r'); + if (eol_type != EOL_CR) + Dynarr_add (dst, c); + } + else + { + if (CODING_SYSTEM_ISO2022_ESCAPE_QUOTED (codesys) + && fit_to_be_escape_quoted (c)) + Dynarr_add (dst, ISO_CODE_ESC); + Dynarr_add (dst, c); + } + char_boundary = 0; + } + break; + case 1: + ch = ( ch << 6 ) | ( c & 0x3f ); + + char_boundary = 0; + if ( (0x80 <= ch) && (ch <= 0x9f) ) + { + charmask = (half == 0 ? 0x00 : 0x80); + + if (CODING_SYSTEM_ISO2022_ESCAPE_QUOTED (codesys) + && fit_to_be_escape_quoted (ch)) + Dynarr_add (dst, ISO_CODE_ESC); + /* you asked for it ... */ + Dynarr_add (dst, ch); + } + else + { + int reg; + + BREAKUP_CHAR (ch, charset, byte1, byte2); + ensure_correct_direction (XCHARSET_DIRECTION (charset), + codesys, dst, &flags, 0); + + /* Now determine which register to use. */ + reg = -1; + for (i = 0; i < 4; i++) + { + if (EQ (charset, str->iso2022.charset[i]) || + EQ (charset, + CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i))) + { + reg = i; + break; + } + } + + if (reg == -1) + { + if (XCHARSET_GRAPHIC (charset) != 0) + { + if (!NILP (str->iso2022.charset[1]) && + (!CODING_SYSTEM_ISO2022_SEVEN (codesys) || + CODING_SYSTEM_ISO2022_LOCK_SHIFT (codesys))) + reg = 1; + else if (!NILP (str->iso2022.charset[2])) + reg = 2; + else if (!NILP (str->iso2022.charset[3])) + reg = 3; + else + reg = 0; + } + else + reg = 0; + } + + iso2022_designate (charset, reg, str, dst); + + /* Now invoke that register. */ + switch (reg) + { + case 0: + ensure_normal_shift (str, dst); + half = 0; + break; + + case 1: + if (CODING_SYSTEM_ISO2022_SEVEN (codesys)) + { + ensure_shift_out (str, dst); + half = 0; + } + else + half = 1; + break; + + case 2: + if (CODING_SYSTEM_ISO2022_SEVEN (str->codesys)) + { + Dynarr_add (dst, ISO_CODE_ESC); + Dynarr_add (dst, 'N'); + half = 0; + } + else + { + Dynarr_add (dst, ISO_CODE_SS2); + half = 1; + } + break; + + case 3: + if (CODING_SYSTEM_ISO2022_SEVEN (str->codesys)) + { + Dynarr_add (dst, ISO_CODE_ESC); + Dynarr_add (dst, 'O'); + half = 0; + } + else + { + Dynarr_add (dst, ISO_CODE_SS3); + half = 1; + } + break; + + default: + abort (); + } + + charmask = (half == 0 ? 0x00 : 0x80); + + switch (XCHARSET_DIMENSION (charset)) + { + case 1: + Dynarr_add (dst, byte1 | charmask); + break; + case 2: + Dynarr_add (dst, byte1 | charmask); + Dynarr_add (dst, byte2 | charmask); + break; + default: + abort (); + } + } + ch =0; + break; + default: + ch = ( ch << 6 ) | ( c & 0x3f ); + char_boundary--; + } + } +#else /* not UTF2000 */ + while (n--) { c = *src++; @@ -5119,6 +5655,7 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src, } } } +#endif /* not UTF2000 */ #ifdef ENABLE_COMPOSITE_CHARS if (in_composite) @@ -5132,7 +5669,11 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src, } #endif /* ENABLE_COMPOSITE_CHARS */ +#ifdef UTF2000 + if ( (char_boundary == 0) && flags & CODING_STATE_END) +#else if (char_boundary && flags & CODING_STATE_END) +#endif { restore_left_to_right_direction (codesys, dst, &flags, 0); ensure_normal_shift (str, dst); @@ -5195,10 +5736,68 @@ encode_coding_no_conversion (Lstream *encoding, CONST unsigned char *src, unsigned int flags = str->flags; unsigned int ch = str->ch; eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys); +#ifdef UTF2000 + unsigned char char_boundary = str->iso2022.current_char_boundary; +#endif while (n--) { - c = *src++; + c = *src++; +#ifdef UTF2000 + switch (char_boundary) + { + case 0: + if ( c >= 0xfc ) + { + ch = c & 0x01; + char_boundary = 5; + } + else if ( c >= 0xf8 ) + { + ch = c & 0x03; + char_boundary = 4; + } + else if ( c >= 0xf0 ) + { + ch = c & 0x07; + char_boundary = 3; + } + else if ( c >= 0xe0 ) + { + ch = c & 0x0f; + char_boundary = 2; + } + else if ( c >= 0xc0 ) + { + ch = c & 0x1f; + char_boundary = 1; + } + else + { + ch = 0; + + if (c == '\n') + { + if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) + Dynarr_add (dst, '\r'); + if (eol_type != EOL_CR) + Dynarr_add (dst, c); + } + else + Dynarr_add (dst, c); + char_boundary = 0; + } + break; + case 1: + ch = ( ch << 6 ) | ( c & 0x3f ); + Dynarr_add (dst, ch & 0xff); + char_boundary = 0; + break; + default: + ch = ( ch << 6 ) | ( c & 0x3f ); + char_boundary--; + } +#else /* not UTF2000 */ if (c == '\n') { if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) @@ -5234,10 +5833,14 @@ encode_coding_no_conversion (Lstream *encoding, CONST unsigned char *src, untranslatable character, so ignore it */ ch = 0; } +#endif /* not UTF2000 */ } str->flags = flags; str->ch = ch; +#ifdef UTF2000 + str->iso2022.current_char_boundary = char_boundary; +#endif } @@ -5291,12 +5894,17 @@ convert_to_external_format (CONST Bufbyte *ptr, for (; ptr < end;) { +#ifdef UTF2000 + Bufbyte c = + (*ptr < 0xc0) ? *ptr : + ((*ptr & 0x1f) << 6) | (*(ptr+1) & 0x3f); +#else Bufbyte c = (BYTE_ASCII_P (*ptr)) ? *ptr : (*ptr == LEADING_BYTE_CONTROL_1) ? (*(ptr+1) - 0x20) : (*ptr == LEADING_BYTE_LATIN_ISO8859_1) ? (*(ptr+1)) : '~'; - +#endif Dynarr_add (conversion_out_dynarr, (Extbyte) c); INC_CHARPTR (ptr); } @@ -5655,12 +6263,24 @@ complex_vars_of_file_coding (void) list4 (Qeol_type, Qlf, Qmnemonic, build_string ("Binary"))); +#ifdef UTF2000 + Fmake_coding_system + (Qutf8, Qutf8, + build_string ("Coding-system of ISO/IEC 10646 UTF-8."), + list2 (Qmnemonic, build_string ("UTF8"))); +#endif + Fdefine_coding_system_alias (Qno_conversion, Qraw_text); /* Need this for bootstrapping */ coding_category_system[CODING_CATEGORY_NO_CONVERSION] = Fget_coding_system (Qraw_text); +#ifdef UTF2000 + coding_category_system[CODING_CATEGORY_UTF8] + = Fget_coding_system (Qutf8); +#endif + #ifdef MULE { unsigned int i;