/[emacs]/emacs/src/ccl.c
ViewVC logotype

Diff of /emacs/src/ccl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.82 by handa, Fri May 30 07:56:08 2003 UTC revision 1.82.4.1 by handa, Mon Sep 8 12:48:09 2003 UTC
# Line 1  Line 1 
1  /* CCL (Code Conversion Language) interpreter.  /* CCL (Code Conversion Language) interpreter.
2     Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN.     Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN.
3         Licensed to the Free Software Foundation.
4     Copyright (C) 2001, 2002 Free Software Foundation, Inc.     Copyright (C) 2001, 2002 Free Software Foundation, Inc.
5     Licensed to the Free Software Foundation.     Copyright (C) 2003
6         National Institute of Advanced Industrial Science and Technology (AIST)
7         Registration Number H13PRO009
8    
9  This file is part of GNU Emacs.  This file is part of GNU Emacs.
10    
# Line 25  Boston, MA 02111-1307, USA.  */ Line 28  Boston, MA 02111-1307, USA.  */
28  #include <stdio.h>  #include <stdio.h>
29    
30  #include "lisp.h"  #include "lisp.h"
31    #include "character.h"
32  #include "charset.h"  #include "charset.h"
33  #include "ccl.h"  #include "ccl.h"
34  #include "coding.h"  #include "coding.h"
35    
36    Lisp_Object Qccl, Qcclp;
37    
38  /* This contains all code conversion map available to CCL.  */  /* This contains all code conversion map available to CCL.  */
39  Lisp_Object Vcode_conversion_map_vector;  Lisp_Object Vcode_conversion_map_vector;
40    
# Line 62  Lisp_Object Vtranslation_hash_table_vect Line 68  Lisp_Object Vtranslation_hash_table_vect
68  #define GET_HASH_TABLE(id) \  #define GET_HASH_TABLE(id) \
69    (XHASH_TABLE (XCDR(XVECTOR(Vtranslation_hash_table_vector)->contents[(id)])))    (XHASH_TABLE (XCDR(XVECTOR(Vtranslation_hash_table_vector)->contents[(id)])))
70    
71    extern int charset_unicode;
72    
73  /* CCL (Code Conversion Language) is a simple language which has  /* CCL (Code Conversion Language) is a simple language which has
74     operations on one input buffer, one output buffer, and 7 registers.     operations on one input buffer, one output buffer, and 7 registers.
75     The syntax of CCL is described in `ccl.el'.  Emacs Lisp function     The syntax of CCL is described in `ccl.el'.  Emacs Lisp function
# Line 720  while(0) Line 728  while(0)
728    
729  /* Encode one character CH to multibyte form and write to the current  /* Encode one character CH to multibyte form and write to the current
730     output buffer.  If CH is less than 256, CH is written as is.  */     output buffer.  If CH is less than 256, CH is written as is.  */
731  #define CCL_WRITE_CHAR(ch)                                              \  #define CCL_WRITE_CHAR(ch)                      \
732    do {                                                                  \    do {                                          \
733      int bytes = SINGLE_BYTE_CHAR_P (ch) ? 1: CHAR_BYTES (ch);           \      if (! dst)                                  \
734      if (!dst)                                                           \        CCL_INVALID_CMD;                          \
735        CCL_INVALID_CMD;                                                  \      else if (dst < dst_end)                     \
736      else if (dst + bytes + extra_bytes < (dst_bytes ? dst_end : src))   \        *dst++ = (ch);                            \
737        {                                                                 \      else                                        \
738          if (bytes == 1)                                                 \        CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);    \
           {                                                             \  
             *dst++ = (ch);                                              \  
             if (extra_bytes && (ch) >= 0x80 && (ch) < 0xA0)             \  
               /* We may have to convert this eight-bit char to          \  
                  multibyte form later.  */                              \  
               extra_bytes++;                                            \  
           }                                                             \  
         else if (CHAR_VALID_P (ch, 0))                                  \  
           dst += CHAR_STRING (ch, dst);                                 \  
         else                                                            \  
           CCL_INVALID_CMD;                                              \  
       }                                                                 \  
     else                                                                \  
       CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);                            \  
   } while (0)  
   
 /* Encode one character CH to multibyte form and write to the current  
    output buffer.  The output bytes always forms a valid multibyte  
    sequence.  */  
 #define CCL_WRITE_MULTIBYTE_CHAR(ch)                                    \  
   do {                                                                  \  
     int bytes = CHAR_BYTES (ch);                                        \  
     if (!dst)                                                           \  
       CCL_INVALID_CMD;                                                  \  
     else if (dst + bytes + extra_bytes < (dst_bytes ? dst_end : src))   \  
       {                                                                 \  
         if (CHAR_VALID_P ((ch), 0))                                     \  
           dst += CHAR_STRING ((ch), dst);                               \  
         else                                                            \  
           CCL_INVALID_CMD;                                              \  
       }                                                                 \  
     else                                                                \  
       CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);                            \  
739    } while (0)    } while (0)
740    
741  /* Write a string at ccl_prog[IC] of length LEN to the current output  /* Write a string at ccl_prog[IC] of length LEN to the current output
742     buffer.  */     buffer.  */
743  #define CCL_WRITE_STRING(len)                           \  #define CCL_WRITE_STRING(len)                           \
744    do {                                                  \    do {                                                  \
745        int i;                                              \
746      if (!dst)                                           \      if (!dst)                                           \
747        CCL_INVALID_CMD;                                  \        CCL_INVALID_CMD;                                  \
748      else if (dst + len <= (dst_bytes ? dst_end : src))  \      else if (dst + len <= dst_end)                      \
749        for (i = 0; i < len; i++)                         \        for (i = 0; i < len; i++)                         \
750          *dst++ = ((XFASTINT (ccl_prog[ic + (i / 3)]))   \          *dst++ = ((XFASTINT (ccl_prog[ic + (i / 3)]))   \
751                    >> ((2 - (i % 3)) * 8)) & 0xFF;       \                    >> ((2 - (i % 3)) * 8)) & 0xFF;       \
# Line 777  while(0) Line 753  while(0)
753        CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);            \        CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);            \
754    } while (0)    } while (0)
755    
756  /* Read one byte from the current input buffer into REGth register.  */  /* Read one byte from the current input buffer into Rth register.  */
757  #define CCL_READ_CHAR(REG)                              \  #define CCL_READ_CHAR(r)                        \
758    do {                                                  \    do {                                          \
759      if (!src)                                           \      if (! src)                                  \
760        CCL_INVALID_CMD;                                  \        CCL_INVALID_CMD;                          \
761      else if (src < src_end)                             \      else if (src < src_end)                     \
762        {                                                 \        r = *src++;                               \
763          REG = *src++;                                   \      else if (ccl->last_block)                   \
764          if (REG == '\n'                                 \        {                                         \
765              && ccl->eol_type != CODING_EOL_LF)          \          ic = ccl->eof_ic;                       \
766            {                                             \          goto ccl_repeat;                        \
767              /* We are encoding.  */                     \        }                                         \
768              if (ccl->eol_type == CODING_EOL_CRLF)       \      else                                        \
769                {                                         \        CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);    \
770                  if (ccl->cr_consumed)                   \      } while (0)
771                    ccl->cr_consumed = 0;                 \  
772                  else                                    \  /* Decode CODE by a charset whose id is ID.  If ID is 0, return CODE
773                    {                                     \     as is for backward compatibility.  Assume that we can use the
774                      ccl->cr_consumed = 1;               \     variable `charset'.  */
775                      REG = '\r';                         \  
776                      src--;                              \  #define CCL_DECODE_CHAR(id, code)       \
777                    }                                     \    ((id) == 0 ? (code)                   \
778                }                                         \     : (charset = CHARSET_FROM_ID ((id)), DECODE_CHAR (charset, (code))))
779              else                                        \  
780                REG = '\r';                               \  /* Encode character C by some of charsets in CHARSET_LIST.  Set ID to
781            }                                             \     the id of the used charset, ENCODED to the resulf of encoding.
782          if (REG == LEADING_CODE_8_BIT_CONTROL           \     Assume that we can use the variable `charset'.  */
             && ccl->multibyte)                          \  
           REG = *src++ - 0x20;                          \  
       }                                                 \  
     else if (ccl->last_block)                           \  
       {                                                 \  
         ic = ccl->eof_ic;                               \  
         goto ccl_repeat;                                \  
       }                                                 \  
     else                                                \  
       CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);            \  
   } while (0)  
   
   
 /* Set C to the character code made from CHARSET and CODE.  This is  
    like MAKE_CHAR but check the validity of CHARSET and CODE.  If they  
    are not valid, set C to (CODE & 0xFF) because that is usually the  
    case that CCL_ReadMultibyteChar2 read an invalid code and it set  
    CODE to that invalid byte.  */  
783    
784  #define CCL_MAKE_CHAR(charset, code, c)                         \  #define CCL_ENCODE_CHAR(c, charset_list, id, encoded)           \
785    do {                                                          \    do {                                                          \
786      if (charset == CHARSET_ASCII)                               \      unsigned code;                                              \
       c = code & 0xFF;                                          \  
     else if (CHARSET_DEFINED_P (charset)                        \  
              && (code & 0x7F) >= 32                             \  
              && (code < 256 || ((code >> 7) & 0x7F) >= 32))     \  
       {                                                         \  
         int c1 = code & 0x7F, c2 = 0;                           \  
787                                                                  \                                                                  \
788          if (code >= 256)                                        \      charset = char_charset ((c), (charset_list), &code);        \
789            c2 = c1, c1 = (code >> 7) & 0x7F;                     \      if (! charset && ! NILP (charset_list))                     \
790          c = MAKE_CHAR (charset, c1, c2);                        \        charset = char_charset ((c), Qnil, &code);                \
791        if (charset)                                                \
792          {                                                         \
793            (id) = CHARSET_ID (charset);                            \
794            (encoded) = code;                                       \
795        }                                                         \        }                                                         \
796      else                                                        \     } while (0)
       c = code & 0xFF;                                          \  
   } while (0)  
797    
798    /* Execute CCL code on characters at SOURCE (length SRC_SIZE).  The
799  /* Execute CCL code on SRC_BYTES length text at SOURCE.  The resulting     resulting text goes to a place pointed by DESTINATION, the length
800     text goes to a place pointed by DESTINATION, the length of which     of which should not exceed DST_SIZE.  As a side effect, how many
801     should not exceed DST_BYTES.  The bytes actually processed is     characters are consumed and produced are recorded in CCL->consumed
802     returned as *CONSUMED.  The return value is the length of the     and CCL->produced, and the contents of CCL registers are updated.
803     resulting text.  As a side effect, the contents of CCL registers     If SOURCE or DESTINATION is NULL, only operations on registers are
804     are updated.  If SOURCE or DESTINATION is NULL, only operations on     permitted.  */
    registers are permitted.  */  
805    
806  #ifdef CCL_DEBUG  #ifdef CCL_DEBUG
807  #define CCL_DEBUG_BACKTRACE_LEN 256  #define CCL_DEBUG_BACKTRACE_LEN 256
# Line 865  struct ccl_prog_stack Line 818  struct ccl_prog_stack
818  /* For the moment, we only support depth 256 of stack.  */  /* For the moment, we only support depth 256 of stack.  */
819  static struct ccl_prog_stack ccl_prog_stack_struct[256];  static struct ccl_prog_stack ccl_prog_stack_struct[256];
820    
821  int  void
822  ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)  ccl_driver (ccl, source, destination, src_size, dst_size, charset_list)
823       struct ccl_program *ccl;       struct ccl_program *ccl;
824       unsigned char *source, *destination;       int *source, *destination;
825       int src_bytes, dst_bytes;       int src_size, dst_size;
826       int *consumed;       Lisp_Object charset_list;
827  {  {
828    register int *reg = ccl->reg;    register int *reg = ccl->reg;
829    register int ic = ccl->ic;    register int ic = ccl->ic;
830    register int code = 0, field1, field2;    register int code = 0, field1, field2;
831    register Lisp_Object *ccl_prog = ccl->prog;    register Lisp_Object *ccl_prog = ccl->prog;
832    unsigned char *src = source, *src_end = src + src_bytes;    int *src = source, *src_end = src + src_size;
833    unsigned char *dst = destination, *dst_end = dst + dst_bytes;    int *dst = destination, *dst_end = dst + dst_size;
834    int jump_address;    int jump_address;
835    int i = 0, j, op;    int i = 0, j, op;
836    int stack_idx = ccl->stack_idx;    int stack_idx = ccl->stack_idx;
837    /* Instruction counter of the current CCL code. */    /* Instruction counter of the current CCL code. */
838    int this_ic = 0;    int this_ic = 0;
839    /* CCL_WRITE_CHAR will produce 8-bit code of range 0x80..0x9F.  But,    struct charset *charset;
      each of them will be converted to multibyte form of 2-byte  
      sequence.  For that conversion, we remember how many more bytes  
      we must keep in DESTINATION in this variable.  */  
   int extra_bytes = ccl->eight_bit_control;  
840    
841    if (ic >= ccl->eof_ic)    if (ic >= ccl->eof_ic)
842      ic = CCL_HEADER_MAIN;      ic = CCL_HEADER_MAIN;
843    
844    if (ccl->buf_magnification == 0) /* We can't produce any bytes.  */    if (ccl->buf_magnification == 0) /* We can't read/produce any bytes.  */
845      dst = NULL;      dst = NULL;
846    
847    /* Set mapping stack pointer. */    /* Set mapping stack pointer. */
# Line 917  ccl_driver (ccl, source, destination, sr Line 866  ccl_driver (ccl, source, destination, sr
866            /* We can't just signal Qquit, instead break the loop as if            /* We can't just signal Qquit, instead break the loop as if
867               the whole data is processed.  Don't reset Vquit_flag, it               the whole data is processed.  Don't reset Vquit_flag, it
868               must be handled later at a safer place.  */               must be handled later at a safer place.  */
869            if (consumed)            if (src)
870              src = source + src_bytes;              src = source + src_size;
871            ccl->status = CCL_STAT_QUIT;            ccl->status = CCL_STAT_QUIT;
872            break;            break;
873          }          }
# Line 1233  ccl_driver (ccl, source, destination, sr Line 1182  ccl_driver (ccl, source, destination, sr
1182              case CCL_LE: reg[rrr] = i <= j; break;              case CCL_LE: reg[rrr] = i <= j; break;
1183              case CCL_GE: reg[rrr] = i >= j; break;              case CCL_GE: reg[rrr] = i >= j; break;
1184              case CCL_NE: reg[rrr] = i != j; break;              case CCL_NE: reg[rrr] = i != j; break;
1185              case CCL_DECODE_SJIS: DECODE_SJIS (i, j, reg[rrr], reg[7]); break;              case CCL_DECODE_SJIS:
1186              case CCL_ENCODE_SJIS: ENCODE_SJIS (i, j, reg[rrr], reg[7]); break;                {
1187                    i = (i << 8) | j;
1188                    SJIS_TO_JIS (i);
1189                    reg[rrr] = i >> 8;
1190                    reg[7] = i & 0xFF;
1191                    break;
1192                  }
1193                case CCL_ENCODE_SJIS:
1194                  {
1195                    i = (i << 8) | j;
1196                    JIS_TO_SJIS (i);
1197                    reg[rrr] = i >> 8;
1198                    reg[7] = i & 0xFF;
1199                    break;
1200                  }
1201              default: CCL_INVALID_CMD;              default: CCL_INVALID_CMD;
1202              }              }
1203            code &= 0x1F;            code &= 0x1F;
# Line 1254  ccl_driver (ccl, source, destination, sr Line 1217  ccl_driver (ccl, source, destination, sr
1217              case CCL_ReadMultibyteChar2:              case CCL_ReadMultibyteChar2:
1218                if (!src)                if (!src)
1219                  CCL_INVALID_CMD;                  CCL_INVALID_CMD;
1220                  CCL_READ_CHAR (i);
1221                if (src >= src_end)                CCL_ENCODE_CHAR (i, charset_list, reg[RRR], reg[rrr]);
                 {  
                   src++;  
                   goto ccl_read_multibyte_character_suspend;  
                 }  
   
               if (!ccl->multibyte)  
                 {  
                   int bytes;  
                   if (!UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes))  
                     {  
                       reg[RRR] = CHARSET_8_BIT_CONTROL;  
                       reg[rrr] = *src++;  
                       break;  
                     }  
                 }  
               i = *src++;  
               if (i == '\n' && ccl->eol_type != CODING_EOL_LF)  
                 {  
                   /* We are encoding.  */  
                   if (ccl->eol_type == CODING_EOL_CRLF)  
                     {  
                       if (ccl->cr_consumed)  
                         ccl->cr_consumed = 0;  
                       else  
                         {  
                           ccl->cr_consumed = 1;  
                           i = '\r';  
                           src--;  
                         }  
                     }  
                   else  
                     i = '\r';  
                   reg[rrr] = i;  
                   reg[RRR] = CHARSET_ASCII;  
                 }  
               else if (i < 0x80)  
                 {  
                   /* ASCII */  
                   reg[rrr] = i;  
                   reg[RRR] = CHARSET_ASCII;  
                 }  
               else if (i <= MAX_CHARSET_OFFICIAL_DIMENSION2)  
                 {  
                   int dimension = BYTES_BY_CHAR_HEAD (i) - 1;  
   
                   if (dimension == 0)  
                     {  
                       /* `i' is a leading code for an undefined charset.  */  
                       reg[RRR] = CHARSET_8_BIT_GRAPHIC;  
                       reg[rrr] = i;  
                     }  
                   else if (src + dimension > src_end)  
                     goto ccl_read_multibyte_character_suspend;  
                   else  
                     {  
                       reg[RRR] = i;  
                       i = (*src++ & 0x7F);  
                       if (dimension == 1)  
                         reg[rrr] = i;  
                       else  
                         reg[rrr] = ((i << 7) | (*src++ & 0x7F));  
                     }  
                 }  
               else if ((i == LEADING_CODE_PRIVATE_11)  
                        || (i == LEADING_CODE_PRIVATE_12))  
                 {  
                   if ((src + 1) >= src_end)  
                     goto ccl_read_multibyte_character_suspend;  
                   reg[RRR] = *src++;  
                   reg[rrr] = (*src++ & 0x7F);  
                 }  
               else if ((i == LEADING_CODE_PRIVATE_21)  
                        || (i == LEADING_CODE_PRIVATE_22))  
                 {  
                   if ((src + 2) >= src_end)  
                     goto ccl_read_multibyte_character_suspend;  
                   reg[RRR] = *src++;  
                   i = (*src++ & 0x7F);  
                   reg[rrr] = ((i << 7) | (*src & 0x7F));  
                   src++;  
                 }  
               else if (i == LEADING_CODE_8_BIT_CONTROL)  
                 {  
                   if (src >= src_end)  
                     goto ccl_read_multibyte_character_suspend;  
                   reg[RRR] = CHARSET_8_BIT_CONTROL;  
                   reg[rrr] = (*src++ - 0x20);  
                 }  
               else if (i >= 0xA0)  
                 {  
                   reg[RRR] = CHARSET_8_BIT_GRAPHIC;  
                   reg[rrr] = i;  
                 }  
               else  
                 {  
                   /* INVALID CODE.  Return a single byte character.  */  
                   reg[RRR] = CHARSET_ASCII;  
                   reg[rrr] = i;  
                 }  
               break;  
   
             ccl_read_multibyte_character_suspend:  
               if (src <= src_end && !ccl->multibyte && ccl->last_block)  
                 {  
                   reg[RRR] = CHARSET_8_BIT_CONTROL;  
                   reg[rrr] = i;  
                   break;  
                 }  
               src--;  
               if (ccl->last_block)  
                 {  
                   ic = ccl->eof_ic;  
                   goto ccl_repeat;  
                 }  
               else  
                 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);  
   
1222                break;                break;
1223    
1224              case CCL_WriteMultibyteChar2:              case CCL_WriteMultibyteChar2:
1225                i = reg[RRR]; /* charset */                if (! dst)
1226                if (i == CHARSET_ASCII                  CCL_INVALID_CMD;
1227                    || i == CHARSET_8_BIT_CONTROL                i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1228                    || i == CHARSET_8_BIT_GRAPHIC)                CCL_WRITE_CHAR (i);
                 i = reg[rrr] & 0xFF;  
               else if (CHARSET_DIMENSION (i) == 1)  
                 i = ((i - 0x70) << 7) | (reg[rrr] & 0x7F);  
               else if (i < MIN_CHARSET_PRIVATE_DIMENSION2)  
                 i = ((i - 0x8F) << 14) | reg[rrr];  
               else  
                 i = ((i - 0xE0) << 14) | reg[rrr];  
   
               CCL_WRITE_MULTIBYTE_CHAR (i);  
   
1229                break;                break;
1230    
1231              case CCL_TranslateCharacter:              case CCL_TranslateCharacter:
1232                CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);                i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1233                op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]),                op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]), i);
1234                                     i, -1, 0, 0);                CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]);
               SPLIT_CHAR (op, reg[RRR], i, j);  
               if (j != -1)  
                 i = (i << 7) | j;  
   
               reg[rrr] = i;  
1235                break;                break;
1236    
1237              case CCL_TranslateCharacterConstTbl:              case CCL_TranslateCharacterConstTbl:
1238                op = XINT (ccl_prog[ic]); /* table */                op = XINT (ccl_prog[ic]); /* table */
1239                ic++;                ic++;
1240                CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);                i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1241                op = translate_char (GET_TRANSLATION_TABLE (op), i, -1, 0, 0);                op = translate_char (GET_TRANSLATION_TABLE (op), i);
1242                SPLIT_CHAR (op, reg[RRR], i, j);                CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]);
               if (j != -1)  
                 i = (i << 7) | j;  
   
               reg[rrr] = i;  
1243                break;                break;
1244    
1245              case CCL_LookupIntConstTbl:              case CCL_LookupIntConstTbl:
# Line 1426  ccl_driver (ccl, source, destination, sr Line 1253  ccl_driver (ccl, source, destination, sr
1253                    {                    {
1254                      Lisp_Object opl;                      Lisp_Object opl;
1255                      opl = HASH_VALUE (h, op);                      opl = HASH_VALUE (h, op);
1256                      if (!CHAR_VALID_P (XINT (opl), 0))                      if (! CHARACTERP (XINT (opl)))
1257                        CCL_INVALID_CMD;                        CCL_INVALID_CMD;
1258                      SPLIT_CHAR (XINT (opl), reg[RRR], i, j);                      reg[RRR] = charset_unicode;
1259                      if (j != -1)                      reg[rrr] = op;
                       i = (i << 7) | j;  
                     reg[rrr] = i;  
1260                      reg[7] = 1; /* r7 true for success */                      reg[7] = 1; /* r7 true for success */
1261                    }                    }
1262                  else                  else
# Line 1442  ccl_driver (ccl, source, destination, sr Line 1267  ccl_driver (ccl, source, destination, sr
1267              case CCL_LookupCharConstTbl:              case CCL_LookupCharConstTbl:
1268                op = XINT (ccl_prog[ic]); /* table */                op = XINT (ccl_prog[ic]); /* table */
1269                ic++;                ic++;
1270                CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);                i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1271                {                {
1272                  struct Lisp_Hash_Table *h = GET_HASH_TABLE (op);                  struct Lisp_Hash_Table *h = GET_HASH_TABLE (op);
1273    
# Line 1876  ccl_driver (ccl, source, destination, sr Line 1701  ccl_driver (ccl, source, destination, sr
1701          }          }
1702    
1703        msglen = strlen (msg);        msglen = strlen (msg);
1704        if (dst + msglen <= (dst_bytes ? dst_end : src))        if (dst + msglen <= dst_end)
1705          {          {
1706            bcopy (msg, dst, msglen);            for (i = 0; i < msglen; i++)
1707            dst += msglen;              *dst++ = msg[i];
1708          }          }
1709    
1710        if (ccl->status == CCL_STAT_INVALID_CMD)        if (ccl->status == CCL_STAT_INVALID_CMD)
# Line 1905  ccl_driver (ccl, source, destination, sr Line 1730  ccl_driver (ccl, source, destination, sr
1730    ccl->ic = ic;    ccl->ic = ic;
1731    ccl->stack_idx = stack_idx;    ccl->stack_idx = stack_idx;
1732    ccl->prog = ccl_prog;    ccl->prog = ccl_prog;
1733    ccl->eight_bit_control = (extra_bytes > 1);    ccl->consumed = src - source;
1734    if (consumed)    ccl->produced = dst - destination;
     *consumed = src - source;  
   return (dst ? dst - destination : 0);  
1735  }  }
1736    
1737  /* Resolve symbols in the specified CCL code (Lisp vector).  This  /* Resolve symbols in the specified CCL code (Lisp vector).  This
# Line 2058  setup_ccl_program (ccl, ccl_prog) Line 1881  setup_ccl_program (ccl, ccl_prog)
1881    ccl->private_state = 0;    ccl->private_state = 0;
1882    ccl->status = 0;    ccl->status = 0;
1883    ccl->stack_idx = 0;    ccl->stack_idx = 0;
   ccl->eol_type = CODING_EOL_LF;  
1884    ccl->suppress_error = 0;    ccl->suppress_error = 0;
1885    ccl->eight_bit_control = 0;    ccl->eight_bit_control = 0;
1886    return 0;    return 0;
# Line 2120  programs.  */) Line 1942  programs.  */)
1942                    ? XINT (AREF (reg, i))                    ? XINT (AREF (reg, i))
1943                    : 0);                    : 0);
1944    
1945    ccl_driver (&ccl, (unsigned char *)0, (unsigned char *)0, 0, 0, (int *)0);    ccl_driver (&ccl, NULL, NULL, 0, 0, Qnil);
1946    QUIT;    QUIT;
1947    if (ccl.status != CCL_STAT_SUCCESS)    if (ccl.status != CCL_STAT_SUCCESS)
1948      error ("Error in CCL program at %dth code", ccl.ic);      error ("Error in CCL program at %dth code", ccl.ic);
# Line 2161  See the documentation of `define-ccl-pro Line 1983  See the documentation of `define-ccl-pro
1983  {  {
1984    Lisp_Object val;    Lisp_Object val;
1985    struct ccl_program ccl;    struct ccl_program ccl;
1986    int i, produced;    int i;
1987    int outbufsize;    int outbufsize;
1988    char *outbuf;    unsigned char *outbuf, *outp;
1989    struct gcpro gcpro1, gcpro2;    int str_chars, str_bytes;
1990    #define CCL_EXECUTE_BUF_SIZE 1024
1991      int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE];
1992      int consumed_chars, consumed_bytes, produced_chars;
1993    
1994    if (setup_ccl_program (&ccl, ccl_prog) < 0)    if (setup_ccl_program (&ccl, ccl_prog) < 0)
1995      error ("Invalid CCL program");      error ("Invalid CCL program");
# Line 2174  See the documentation of `define-ccl-pro Line 1999  See the documentation of `define-ccl-pro
1999      error ("Length of vector STATUS is not 9");      error ("Length of vector STATUS is not 9");
2000    CHECK_STRING (str);    CHECK_STRING (str);
2001    
2002    GCPRO2 (status, str);    str_chars = SCHARS (str);
2003      str_bytes = SBYTES (str);
2004    
2005    for (i = 0; i < 8; i++)    for (i = 0; i < 8; i++)
2006      {      {
# Line 2189  See the documentation of `define-ccl-pro Line 2015  See the documentation of `define-ccl-pro
2015        if (ccl.ic < i && i < ccl.size)        if (ccl.ic < i && i < ccl.size)
2016          ccl.ic = i;          ccl.ic = i;
2017      }      }
   outbufsize = SBYTES (str) * ccl.buf_magnification + 256;  
   outbuf = (char *) xmalloc (outbufsize);  
   ccl.last_block = NILP (contin);  
   ccl.multibyte = STRING_MULTIBYTE (str);  
   produced = ccl_driver (&ccl, SDATA (str), outbuf,  
                          SBYTES (str), outbufsize, (int *) 0);  
   for (i = 0; i < 8; i++)  
     XSET (AREF (status, i), Lisp_Int, ccl.reg[i]);  
   XSETINT (AREF (status, 8), ccl.ic);  
   UNGCPRO;  
2018    
2019    if (NILP (unibyte_p))    outbufsize = (ccl.buf_magnification
2020                    ? str_bytes * ccl.buf_magnification + 256
2021                    : str_bytes + 256);
2022      outp = outbuf = (unsigned char *) xmalloc (outbufsize);
2023    
2024      consumed_chars = consumed_bytes = 0;
2025      produced_chars = 0;
2026      while (consumed_bytes < str_bytes)
2027      {      {
2028        int nchars;        const unsigned char *p = SDATA (str) + consumed_bytes;
2029          const unsigned char *endp = SDATA (str) + str_bytes;
2030          int i = 0;
2031          int *src, src_size;
2032    
2033          if (endp - p == str_chars - consumed_chars)
2034            while (i < CCL_EXECUTE_BUF_SIZE && p < endp)
2035              source[i++] = *p++;
2036          else
2037            while (i < CCL_EXECUTE_BUF_SIZE && p < endp)
2038              source[i++] = STRING_CHAR_ADVANCE (p);
2039          consumed_chars += i;
2040          consumed_bytes = p - SDATA (str);
2041    
2042          if (consumed_bytes == str_bytes)
2043            ccl.last_block = NILP (contin);
2044          src = source;
2045          src_size = i;
2046          while (1)
2047            {
2048              ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE,
2049                          Qnil);
2050              if (ccl.status != CCL_STAT_SUSPEND_BY_DST)
2051                break;
2052              produced_chars += ccl.produced;
2053              if (NILP (unibyte_p))
2054                {
2055                  if (outp - outbuf + MAX_MULTIBYTE_LENGTH * ccl.produced
2056                      > outbufsize)
2057                    {
2058                      int offset = outp - outbuf;
2059                      outbufsize += MAX_MULTIBYTE_LENGTH * ccl.produced;
2060                      outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
2061                      outp = outbuf + offset;
2062                    }
2063                  for (i = 0; i < ccl.produced; i++)
2064                    CHAR_STRING_ADVANCE (destination[i], outp);
2065                }
2066              else
2067                {
2068                  if (outp - outbuf + ccl.produced > outbufsize)
2069                    {
2070                      int offset = outp - outbuf;
2071                      outbufsize += ccl.produced;
2072                      outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
2073                      outp = outbuf + offset;
2074                    }
2075                  for (i = 0; i < ccl.produced; i++)
2076                    *outp++ = destination[i];
2077                }
2078              src += ccl.consumed;
2079              src_size -= ccl.consumed;
2080            }
2081    
2082        produced = str_as_multibyte (outbuf, outbufsize, produced, &nchars);        if (ccl.status != CCL_STAT_SUSPEND_BY_SRC)
2083        val = make_multibyte_string (outbuf, nchars, produced);          break;
2084      }      }
2085    else  
     val = make_unibyte_string (outbuf, produced);  
   xfree (outbuf);  
   QUIT;  
   if (ccl.status == CCL_STAT_SUSPEND_BY_DST)  
     error ("Output buffer for the CCL programs overflow");  
2086    if (ccl.status != CCL_STAT_SUCCESS    if (ccl.status != CCL_STAT_SUCCESS
2087        && ccl.status != CCL_STAT_SUSPEND_BY_SRC)        && ccl.status != CCL_STAT_SUSPEND_BY_SRC)
2088      error ("Error in CCL program at %dth code", ccl.ic);      error ("Error in CCL program at %dth code", ccl.ic);
2089    
2090      for (i = 0; i < 8; i++)
2091        XSET (XVECTOR (status)->contents[i], Lisp_Int, ccl.reg[i]);
2092      XSETINT (XVECTOR (status)->contents[8], ccl.ic);
2093    
2094      if (NILP (unibyte_p))
2095        val = make_multibyte_string ((char *) outbuf, produced_chars,
2096                                     outp - outbuf);
2097      else
2098        val = make_unibyte_string ((char *) outbuf, produced_chars);
2099      xfree (outbuf);
2100    
2101    return val;    return val;
2102  }  }
2103    
# Line 2361  syms_of_ccl () Line 2242  syms_of_ccl ()
2242    staticpro (&Vccl_program_table);    staticpro (&Vccl_program_table);
2243    Vccl_program_table = Fmake_vector (make_number (32), Qnil);    Vccl_program_table = Fmake_vector (make_number (32), Qnil);
2244    
2245      Qccl = intern ("ccl");
2246      staticpro (&Qccl);
2247    
2248      Qcclp = intern ("cclp");
2249      staticpro (&Qcclp);
2250    
2251    Qccl_program = intern ("ccl-program");    Qccl_program = intern ("ccl-program");
2252    staticpro (&Qccl_program);    staticpro (&Qccl_program);
2253    

Legend:
Removed from v.1.82  
changed lines
  Added in v.1.82.4.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26