]> code.delx.au - gnu-emacs/blobdiff - src/ccl.c
* window.c (Fwindow_live_p): Use WINDOW_LIVE_P.
[gnu-emacs] / src / ccl.c
index 7764476c17a7693a4665a729ac603ef7905441da..2b1e824933e89b2f29d5d31d3a06ef675423cfc7 100644 (file)
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -420,7 +420,7 @@ Lisp_Object Vccl_program_table;
                                          IC += 2;
                                        */
 
-#define CCL_Extention          0x1F /* Extended CCL code
+#define CCL_Extension          0x1F /* Extended CCL code
                                        1:ExtendedCOMMNDRrrRRRrrrXXXXX
                                        2:ARGUEMENT
                                        3:...
@@ -537,7 +537,10 @@ Lisp_Object Vccl_program_table;
    At first, VAL0 is set to reg[rrr], and it is translated by the
    first map to VAL1.  Then, VAL1 is translated by the next map to
    VAL2.  This mapping is iterated until the last map is used.  The
-   result of the mapping is the last value of VAL?.
+   result of the mapping is the last value of VAL?.  When the mapping
+   process reached to the end of the map set, it moves to the next
+   map set.  If the next does not exit, the mapping process terminates,
+   and regard the last value as a result.
 
    But, when VALm is mapped to VALn and VALn is not a number, the
    mapping proceed as below:
@@ -548,8 +551,12 @@ Lisp_Object Vccl_program_table;
    In VALn is t, VALm is reverted to reg[rrr] and the mapping of VALm
    proceed to the next map.
 
-   If VALn is lambda, the whole mapping process terminates, and VALm
-   is the result of this mapping.
+   If VALn is lambda, move to the next map set like reaching to the
+   end of the current map set.
+
+   If VALn is a symbol, call the CCL program refered by it.
+   Then, use reg[rrr] as a mapped value except for -1, -2 and -3.
+   Such special values are regarded as nil, t, and lambda respectively.
 
    Each map is a Lisp vector of the following format (a) or (b):
        (a)......[STARTPOINT VAL1 VAL2 ...]
@@ -577,7 +584,7 @@ Lisp_Object Vccl_program_table;
                                         N:SEPARATOR_z (< 0)
                                      */
 
-#define MAX_MAP_SET_LEVEL 20
+#define MAX_MAP_SET_LEVEL 30
 
 typedef struct
 {
@@ -588,19 +595,44 @@ typedef struct
 static tr_stack mapping_stack[MAX_MAP_SET_LEVEL];
 static tr_stack *mapping_stack_pointer;
 
-#define PUSH_MAPPING_STACK(restlen, orig)                 \
-{                                                           \
-  mapping_stack_pointer->rest_length = (restlen);         \
-  mapping_stack_pointer->orig_val = (orig);               \
-  mapping_stack_pointer++;                                \
-}
+/* If this variable is non-zero, it indicates the stack_idx
+   of immediately called by CCL_MapMultiple. */
+static int stack_idx_of_map_multiple;
 
-#define POP_MAPPING_STACK(restlen, orig)                  \
-{                                                           \
-  mapping_stack_pointer--;                                \
-  (restlen) = mapping_stack_pointer->rest_length;         \
-  (orig) = mapping_stack_pointer->orig_val;               \
-}                                                           \
+#define PUSH_MAPPING_STACK(restlen, orig)              \
+  do {                                                 \
+    mapping_stack_pointer->rest_length = (restlen);    \
+    mapping_stack_pointer->orig_val = (orig);          \
+    mapping_stack_pointer++;                           \
+  } while (0)
+
+#define POP_MAPPING_STACK(restlen, orig)               \
+  do {                                                 \
+    mapping_stack_pointer--;                           \
+    (restlen) = mapping_stack_pointer->rest_length;    \
+    (orig) = mapping_stack_pointer->orig_val;          \
+  } while (0)
+
+#define CCL_CALL_FOR_MAP_INSTRUCTION(symbol, ret_ic)           \
+  do {                                                         \
+    struct ccl_program called_ccl;                             \
+    if (stack_idx >= 256                                       \
+       || (setup_ccl_program (&called_ccl, (symbol)) != 0))    \
+      {                                                                \
+       if (stack_idx > 0)                                      \
+         {                                                     \
+           ccl_prog = ccl_prog_stack_struct[0].ccl_prog;       \
+           ic = ccl_prog_stack_struct[0].ic;                   \
+         }                                                     \
+       CCL_INVALID_CMD;                                        \
+      }                                                                \
+    ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog;      \
+    ccl_prog_stack_struct[stack_idx].ic = (ret_ic);            \
+    stack_idx++;                                               \
+    ccl_prog = called_ccl.prog;                                        \
+    ic = CCL_HEADER_MAIN;                                      \
+    goto ccl_repeat;                                           \
+  } while (0)
 
 #define CCL_MapSingle          0x12 /* Map by single code conversion map
                                        1:ExtendedCOMMNDXXXRRRrrrXXXXX
@@ -666,37 +698,26 @@ static tr_stack *mapping_stack_pointer;
 
 /* Encode one character CH to multibyte form and write to the current
    output buffer.  If CH is less than 256, CH is written as is.  */
-#define CCL_WRITE_CHAR(ch)                                     \
-  do {                                                         \
-    int bytes = SINGLE_BYTE_CHAR_P (ch) ? 1: CHAR_BYTES (ch);  \
-    if (ch == '\n' && ccl->eol_type == CODING_EOL_CRLF)                \
-      bytes++;                                                 \
-    if (!dst)                                                  \
-      CCL_INVALID_CMD;                                         \
-    else if (dst + bytes <= (dst_bytes ? dst_end : src))       \
-      {                                                                \
-       if (ch == '\n')                                         \
-         {                                                     \
-           if (ccl->eol_type == CODING_EOL_CRLF)               \
-             *dst++ = '\r', *dst++ = '\n';                     \
-           else if (ccl->eol_type == CODING_EOL_CR)            \
-             *dst++ = '\r';                                    \
-           else                                                \
-             *dst++ = '\n';                                    \
-         }                                                     \
-       else if (bytes == 1)                                    \
-         {                                                     \
-           *dst++ = (ch);                                      \
-           if ((ch) >= 0x80 && (ch) < 0xA0)                    \
-             /* We may have to convert this eight-bit char to  \
-                multibyte form later.  */                      \
-             dst_end--;                                        \
-         }                                                     \
-       else                                                    \
-         dst += CHAR_STRING (ch, dst);                         \
-      }                                                                \
-    else                                                       \
-      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);                   \
+#define CCL_WRITE_CHAR(ch)                                             \
+  do {                                                                 \
+    int bytes = SINGLE_BYTE_CHAR_P (ch) ? 1: CHAR_BYTES (ch);          \
+    if (!dst)                                                          \
+      CCL_INVALID_CMD;                                                 \
+    else if (dst + bytes + extra_bytes < (dst_bytes ? dst_end : src))  \
+      {                                                                        \
+       if (bytes == 1)                                                 \
+         {                                                             \
+           *dst++ = (ch);                                              \
+           if ((ch) >= 0x80 && (ch) < 0xA0)                            \
+             /* We may have to convert this eight-bit char to          \
+                multibyte form later.  */                              \
+             extra_bytes++;                                            \
+         }                                                             \
+       else                                                            \
+         dst += CHAR_STRING (ch, dst);                                 \
+      }                                                                        \
+    else                                                               \
+      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);                           \
   } while (0)
 
 /* Write a string at ccl_prog[IC] of length LEN to the current output
@@ -714,24 +735,42 @@ static tr_stack *mapping_stack_pointer;
   } while (0)
 
 /* Read one byte from the current input buffer into Rth register.  */
-#define CCL_READ_CHAR(r)                       \
-  do {                                         \
-    if (!src)                                  \
-      CCL_INVALID_CMD;                         \
-    else if (src < src_end)                    \
-      {                                                \
-       r = *src++;                             \
-       if (r == LEADING_CODE_8_BIT_CONTROL     \
-           && ccl->multibyte)                  \
-         r = *src++ - 0x20;                    \
-      }                                                \
-    else if (ccl->last_block)                  \
-      {                                                \
-        ic = ccl->eof_ic;                      \
-        goto ccl_repeat;                       \
-      }                                                \
-    else                                       \
-      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);   \
+#define CCL_READ_CHAR(r)                               \
+  do {                                                 \
+    if (!src)                                          \
+      CCL_INVALID_CMD;                                 \
+    else if (src < src_end)                            \
+      {                                                        \
+       r = *src++;                                     \
+       if (r == '\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;               \
+                   r = '\r';                           \
+                   src--;                              \
+                 }                                     \
+             }                                         \
+           else                                        \
+             r = '\r';                                 \
+         }                                             \
+       if (r == LEADING_CODE_8_BIT_CONTROL             \
+           && ccl->multibyte)                          \
+         r = *src++ - 0x20;                            \
+      }                                                        \
+    else if (ccl->last_block)                          \
+      {                                                        \
+        ic = ccl->eof_ic;                              \
+        goto ccl_repeat;                               \
+      }                                                        \
+    else                                               \
+      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);           \
   } while (0)
 
 
@@ -801,6 +840,11 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
   int stack_idx = ccl->stack_idx;
   /* Instruction counter of the current CCL code. */
   int this_ic;
+  /* CCL_WRITE_CHAR will produce 8-bit code of range 0x80..0x9F.  But,
+     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 = 0;
 
   if (ic >= ccl->eof_ic)
     ic = CCL_HEADER_MAIN;
@@ -808,6 +852,9 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
   if (ccl->buf_magnification ==0) /* We can't produce any bytes.  */
     dst = NULL;
 
+  /* Set mapping stack pointer. */
+  mapping_stack_pointer = mapping_stack;
+
 #ifdef CCL_DEBUG
   ccl_backtrace_idx = 0;
 #endif
@@ -1159,7 +1206,7 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
            ic = jump_address;
          break;
 
-       case CCL_Extention:
+       case CCL_Extension:
          switch (EXCMD)
            {
            case CCL_ReadMultibyteChar2:
@@ -1174,7 +1221,26 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
                  }
              
                i = *src++;
-               if (i < 0x80)
+               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;
@@ -1371,6 +1437,10 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
                        reg[rrr] = XUINT (value);
                        break;
                      }
+                   else if (SYMBOLP (content))
+                     CCL_CALL_FOR_MAP_INSTRUCTION (content, fin_ic);
+                   else
+                     CCL_INVALID_CMD;
                  }
                if (i == j)
                  reg[RRR] = -1;
@@ -1383,10 +1453,27 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
                Lisp_Object map, content, attrib, value;
                int point, size, map_vector_size;
                int map_set_rest_length, fin_ic;
+               int current_ic = this_ic;
+
+               /* inhibit recursive call on MapMultiple. */
+               if (stack_idx_of_map_multiple > 0)
+                 {
+                   if (stack_idx_of_map_multiple <= stack_idx)
+                     {
+                       stack_idx_of_map_multiple = 0;
+                       mapping_stack_pointer = mapping_stack;
+                       CCL_INVALID_CMD;
+                     }
+                 }
+               else
+                 mapping_stack_pointer = mapping_stack;
+               stack_idx_of_map_multiple = 0;
 
                map_set_rest_length =
                  XINT (ccl_prog[ic++]); /* number of maps and separators. */
                fin_ic = ic + map_set_rest_length;
+               op = reg[rrr];
+
                if ((map_set_rest_length > reg[RRR]) && (reg[RRR] >= 0))
                  {
                    ic += reg[RRR];
@@ -1397,101 +1484,165 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
                  {
                    ic = fin_ic;
                    reg[RRR] = -1;
+                   mapping_stack_pointer = mapping_stack;
                    break;
                  }
-               mapping_stack_pointer = mapping_stack;
-               op = reg[rrr];
-               PUSH_MAPPING_STACK (0, op);
-               reg[RRR] = -1;
-               map_vector_size = XVECTOR (Vcode_conversion_map_vector)->size;
-               for (;map_set_rest_length > 0;i++, map_set_rest_length--)
-                 {
-                   point = XINT(ccl_prog[ic++]);
-                   if (point < 0)
-                     {
-                       point = -point;
-                       if (mapping_stack_pointer
-                           >= &mapping_stack[MAX_MAP_SET_LEVEL])
-                         {
-                           CCL_INVALID_CMD;
-                         }
-                       PUSH_MAPPING_STACK (map_set_rest_length - point,
-                                           reg[rrr]);
-                       map_set_rest_length = point + 1;
-                       reg[rrr] = op;
-                       continue;
-                     }
-
-                   if (point >= map_vector_size) continue;
-                   map = (XVECTOR (Vcode_conversion_map_vector)
-                          ->contents[point]);
-
-                   /* Check map varidity.  */
-                   if (!CONSP (map)) continue;
-                   map = XCDR (map);
-                   if (!VECTORP (map)) continue;
-                   size = XVECTOR (map)->size;
-                   if (size <= 1) continue;
-
-                   content = XVECTOR (map)->contents[0];
 
-                   /* check map type,
-                      [STARTPOINT VAL1 VAL2 ...] or
-                      [t ELEMENT STARTPOINT ENDPOINT]  */
-                   if (NUMBERP (content))
-                     {
-                       point = XUINT (content);
-                       point = op - point + 1;
-                       if (!((point >= 1) && (point < size))) continue;
-                       content = XVECTOR (map)->contents[point];
-                     }
-                   else if (EQ (content, Qt))
-                     {
-                       if (size != 4) continue;
-                       if ((op >= XUINT (XVECTOR (map)->contents[2])) &&
-                           (op < XUINT (XVECTOR (map)->contents[3])))
-                         content = XVECTOR (map)->contents[1];
-                       else
-                         continue;
-                     }
-                   else 
-                     continue;
+               if (mapping_stack_pointer <= (mapping_stack + 1))
+                 {
+                   /* Set up initial state. */
+                   mapping_stack_pointer = mapping_stack;
+                   PUSH_MAPPING_STACK (0, op);
+                   reg[RRR] = -1;
+                 }
+               else
+                 {
+                   /* Recover after calling other ccl program. */
+                   int orig_op;
 
-                   if (NILP (content))
-                     continue;
-                   else if (NUMBERP (content))
-                     {
-                       op = XINT (content);
-                       reg[RRR] = i;
-                       i += map_set_rest_length;
-                       POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
-                     }
-                   else if (CONSP (content))
+                   POP_MAPPING_STACK (map_set_rest_length, orig_op);
+                   POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
+                   switch (op)
                      {
-                       attrib = XCAR (content);
-                       value = XCDR (content);
-                       if (!NUMBERP (attrib) || !NUMBERP (value))
-                         continue;
-                       reg[RRR] = i;
-                       op = XUINT (value);
-                       i += map_set_rest_length;
-                       POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
-                     }
-                   else if (EQ (content, Qt))
-                     {
-                       reg[RRR] = i;
+                     case -1:
+                       /* Regard it as Qnil. */
+                       op = orig_op;
+                       i++;
+                       ic++;
+                       map_set_rest_length--;
+                       break;
+                     case -2:
+                       /* Regard it as Qt. */
                        op = reg[rrr];
+                       i++;
+                       ic++;
+                       map_set_rest_length--;
+                       break;
+                     case -3:
+                       /* Regard it as Qlambda. */
+                       op = orig_op;
                        i += map_set_rest_length;
+                       ic += map_set_rest_length;
+                       map_set_rest_length = 0;
+                       break;
+                     default:
+                       /* Regard it as normal mapping. */
+                       i += map_set_rest_length;
+                       ic += map_set_rest_length;
                        POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
-                     }
-                   else if (EQ (content, Qlambda))
-                     {
-                       reg[RRR] = i;
                        break;
                      }
-                   else
-                     CCL_INVALID_CMD;
                  }
+               map_vector_size = XVECTOR (Vcode_conversion_map_vector)->size;
+               
+               do {
+                 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--)
+                   {
+                     point = XINT(ccl_prog[ic]);
+                     if (point < 0)
+                       {
+                         /* +1 is for including separator. */
+                         point = -point + 1;
+                         if (mapping_stack_pointer
+                             >= &mapping_stack[MAX_MAP_SET_LEVEL])
+                           CCL_INVALID_CMD;
+                         PUSH_MAPPING_STACK (map_set_rest_length - point,
+                                             reg[rrr]);
+                         map_set_rest_length = point;
+                         reg[rrr] = op;
+                         continue;
+                       }
+
+                     if (point >= map_vector_size) continue;
+                     map = (XVECTOR (Vcode_conversion_map_vector)
+                            ->contents[point]);
+
+                     /* Check map varidity.  */
+                     if (!CONSP (map)) continue;
+                     map = XCDR (map);
+                     if (!VECTORP (map)) continue;
+                     size = XVECTOR (map)->size;
+                     if (size <= 1) continue;
+
+                     content = XVECTOR (map)->contents[0];
+
+                     /* check map type,
+                        [STARTPOINT VAL1 VAL2 ...] or
+                        [t ELEMENT STARTPOINT ENDPOINT]  */
+                     if (NUMBERP (content))
+                       {
+                         point = XUINT (content);
+                         point = op - point + 1;
+                         if (!((point >= 1) && (point < size))) continue;
+                         content = XVECTOR (map)->contents[point];
+                       }
+                     else if (EQ (content, Qt))
+                       {
+                         if (size != 4) continue;
+                         if ((op >= XUINT (XVECTOR (map)->contents[2])) &&
+                             (op < XUINT (XVECTOR (map)->contents[3])))
+                           content = XVECTOR (map)->contents[1];
+                         else
+                           continue;
+                       }
+                     else 
+                       continue;
+
+                     if (NILP (content))
+                       continue;
+
+                     reg[RRR] = i;
+                     if (NUMBERP (content))
+                       {
+                         op = XINT (content);
+                         i += map_set_rest_length - 1;
+                         ic += map_set_rest_length - 1;
+                         POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
+                         map_set_rest_length++;
+                       }
+                     else if (CONSP (content))
+                       {
+                         attrib = XCAR (content);
+                         value = XCDR (content);
+                         if (!NUMBERP (attrib) || !NUMBERP (value))
+                           continue;
+                         op = XUINT (value);
+                         i += map_set_rest_length - 1;
+                         ic += map_set_rest_length - 1;
+                         POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
+                         map_set_rest_length++;
+                       }
+                     else if (EQ (content, Qt))
+                       {
+                         op = reg[rrr];
+                       }
+                     else if (EQ (content, Qlambda))
+                       {
+                         i += map_set_rest_length;
+                         ic += map_set_rest_length;
+                         break;
+                       }
+                     else if (SYMBOLP (content))
+                       {
+                         if (mapping_stack_pointer
+                             >= &mapping_stack[MAX_MAP_SET_LEVEL])
+                           CCL_INVALID_CMD;
+                         PUSH_MAPPING_STACK (map_set_rest_length, reg[rrr]);
+                         PUSH_MAPPING_STACK (map_set_rest_length, op);
+                         stack_idx_of_map_multiple = stack_idx + 1;
+                         CCL_CALL_FOR_MAP_INSTRUCTION (content, current_ic);
+                       }
+                     else
+                       CCL_INVALID_CMD;
+                   }
+                 if (mapping_stack_pointer <= (mapping_stack + 1))
+                   break;
+                 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
+                 i += map_set_rest_length;
+                 ic += map_set_rest_length;
+                 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
+               } while (1);
+
                ic = fin_ic;
              }
              reg[rrr] = op;
@@ -1545,6 +1696,8 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
                        reg[rrr] = XUINT(value);
                        break;
                      }
+                   else if (SYMBOLP (content))
+                     CCL_CALL_FOR_MAP_INSTRUCTION (content, ic);
                    else
                      reg[RRR] = -1;
                  }
@@ -1839,7 +1992,7 @@ See the documentation of `define-ccl-program' for the detail of CCL program.")
                  ? XINT (XVECTOR (reg)->contents[i])
                  : 0);
 
-  ccl_driver (&ccl, (char *)0, (char *)0, 0, 0, (int *)0);
+  ccl_driver (&ccl, (unsigned char *)0, (unsigned char *)0, 0, 0, (int *)0);
   QUIT;
   if (ccl.status != CCL_STAT_SUCCESS)
     error ("Error in CCL program at %dth code", ccl.ic);
@@ -1913,21 +2066,27 @@ See the documentation of `define-ccl-program' for the detail of CCL program.")
   ccl.last_block = NILP (contin);
   ccl.multibyte = STRING_MULTIBYTE (str);
   produced = ccl_driver (&ccl, XSTRING (str)->data, outbuf,
-                        STRING_BYTES (XSTRING (str)), outbufsize, (int *)0);
+                        STRING_BYTES (XSTRING (str)), outbufsize, (int *) 0);
   for (i = 0; i < 8; i++)
     XSET (XVECTOR (status)->contents[i], Lisp_Int, ccl.reg[i]);
   XSETINT (XVECTOR (status)->contents[8], ccl.ic);
   UNGCPRO;
 
   if (NILP (unibyte_p))
-    val = make_string (outbuf, produced);
+    {
+      int nchars;
+
+      produced = str_as_multibyte (outbuf, outbufsize, produced, &nchars);
+      val = make_multibyte_string (outbuf, nchars, produced);
+    }
   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");
   if (ccl.status != CCL_STAT_SUCCESS
-      && ccl.status != CCL_STAT_SUSPEND_BY_SRC
-      && ccl.status != CCL_STAT_SUSPEND_BY_DST)
+      && ccl.status != CCL_STAT_SUSPEND_BY_SRC)
     error ("Error in CCL program at %dth code", ccl.ic);
 
   return val;
@@ -1952,11 +2111,15 @@ Return index number of the registered CCL program.")
     {
       CHECK_VECTOR (ccl_prog, 1);
       resolved = resolve_symbol_ccl_program (ccl_prog);
-      if (! NILP (resolved))
+      if (NILP (resolved))
+       error ("Error in CCL program");
+      if (VECTORP (resolved))
        {
          ccl_prog = resolved;
          resolved = Qt;
        }
+      else
+       resolved = Qnil;
     }
 
   for (idx = 0; idx < len; idx++)