+ case CCL_Extension:
+ switch (EXCMD)
+ {
+ case CCL_ReadMultibyteChar2:
+ if (!src)
+ CCL_INVALID_CMD;
+
+ do {
+ if (src >= src_end)
+ {
+ src++;
+ goto ccl_read_multibyte_character_suspend;
+ }
+
+ i = *src++;
+#if 0
+ if (i == LEADING_CODE_COMPOSITION)
+ {
+ if (src >= src_end)
+ goto ccl_read_multibyte_character_suspend;
+ if (*src == 0xFF)
+ {
+ ccl->private_state = COMPOSING_WITH_RULE_HEAD;
+ src++;
+ }
+ else
+ ccl->private_state = COMPOSING_NO_RULE_HEAD;
+
+ continue;
+ }
+ if (ccl->private_state != COMPOSING_NO)
+ {
+ /* composite character */
+ if (i < 0xA0)
+ ccl->private_state = COMPOSING_NO;
+ else
+ {
+ if (COMPOSING_WITH_RULE_RULE == ccl->private_state)
+ {
+ ccl->private_state = COMPOSING_WITH_RULE_HEAD;
+ continue;
+ }
+ else if (COMPOSING_WITH_RULE_HEAD == ccl->private_state)
+ ccl->private_state = COMPOSING_WITH_RULE_RULE;
+
+ if (i == 0xA0)
+ {
+ if (src >= src_end)
+ goto ccl_read_multibyte_character_suspend;
+ i = *src++ & 0x7F;
+ }
+ else
+ i -= 0x20;
+ }
+ }
+#endif
+
+ if (i < 0x80)
+ {
+ /* ASCII */
+ reg[rrr] = i;
+ reg[RRR] = LEADING_BYTE_ASCII;
+ }
+ else if (i <= MAX_LEADING_BYTE_OFFICIAL_1)
+ {
+ if (src >= src_end)
+ goto ccl_read_multibyte_character_suspend;
+ reg[RRR] = i;
+ reg[rrr] = (*src++ & 0x7F);
+ }
+ else if (i <= MAX_LEADING_BYTE_OFFICIAL_2)
+ {
+ if ((src + 1) >= src_end)
+ goto ccl_read_multibyte_character_suspend;
+ reg[RRR] = i;
+ i = (*src++ & 0x7F);
+ reg[rrr] = ((i << 7) | (*src & 0x7F));
+ src++;
+ }
+ else if (i == PRE_LEADING_BYTE_PRIVATE_1)
+ {
+ if ((src + 1) >= src_end)
+ goto ccl_read_multibyte_character_suspend;
+ reg[RRR] = *src++;
+ reg[rrr] = (*src++ & 0x7F);
+ }
+ else if (i == PRE_LEADING_BYTE_PRIVATE_2)
+ {
+ 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
+ {
+ /* INVALID CODE. Return a single byte character. */
+ reg[RRR] = LEADING_BYTE_ASCII;
+ reg[rrr] = i;
+ }
+ break;
+ } while (1);
+ break;
+
+ ccl_read_multibyte_character_suspend:
+ src--;
+ if (ccl->last_block)
+ {
+ ic = ccl->eof_ic;
+ goto ccl_repeat;
+ }
+ else
+ CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);
+
+ break;
+
+ case CCL_WriteMultibyteChar2:
+ i = reg[RRR]; /* charset */
+ if (i == LEADING_BYTE_ASCII)
+ i = reg[rrr] & 0xFF;
+#if 0
+ else if (i == CHARSET_COMPOSITION)
+ i = MAKE_COMPOSITE_CHAR (reg[rrr]);
+#endif
+ else if (XCHARSET_DIMENSION (CHARSET_BY_LEADING_BYTE (i)) == 1)
+ i = ((i - FIELD2_TO_OFFICIAL_LEADING_BYTE) << 7)
+ | (reg[rrr] & 0x7F);
+ else if (i < MIN_LEADING_BYTE_OFFICIAL_2)
+ i = ((i - FIELD1_TO_OFFICIAL_LEADING_BYTE) << 14) | reg[rrr];
+ else
+ i = ((i - FIELD1_TO_PRIVATE_LEADING_BYTE) << 14) | reg[rrr];
+
+ CCL_WRITE_CHAR (i);
+
+ break;
+
+#if 0
+ case CCL_TranslateCharacter:
+ i = reg[RRR]; /* charset */
+ if (i == LEADING_BYTE_ASCII)
+ i = reg[rrr];
+ else if (i == CHARSET_COMPOSITION)
+ {
+ reg[RRR] = -1;
+ break;
+ }
+ else if (CHARSET_DIMENSION (i) == 1)
+ i = ((i - 0x70) << 7) | (reg[rrr] & 0x7F);
+ else if (i < MIN_LEADING_BYTE_OFFICIAL_2)
+ i = ((i - 0x8F) << 14) | (reg[rrr] & 0x3FFF);
+ else
+ i = ((i - 0xE0) << 14) | (reg[rrr] & 0x3FFF);
+
+ op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]),
+ i, -1, 0, 0);
+ SPLIT_CHAR (op, reg[RRR], i, j);
+ if (j != -1)
+ i = (i << 7) | j;
+
+ reg[rrr] = i;
+ break;
+
+ case CCL_TranslateCharacterConstTbl:
+ op = XINT (ccl_prog[ic]); /* table */
+ ic++;
+ i = reg[RRR]; /* charset */
+ if (i == LEADING_BYTE_ASCII)
+ i = reg[rrr];
+ else if (i == CHARSET_COMPOSITION)
+ {
+ reg[RRR] = -1;
+ break;
+ }
+ else if (CHARSET_DIMENSION (i) == 1)
+ i = ((i - 0x70) << 7) | (reg[rrr] & 0x7F);
+ else if (i < MIN_LEADING_BYTE_OFFICIAL_2)
+ i = ((i - 0x8F) << 14) | (reg[rrr] & 0x3FFF);
+ else
+ i = ((i - 0xE0) << 14) | (reg[rrr] & 0x3FFF);
+
+ op = translate_char (GET_TRANSLATION_TABLE (op), i, -1, 0, 0);
+ SPLIT_CHAR (op, reg[RRR], i, j);
+ if (j != -1)
+ i = (i << 7) | j;
+
+ reg[rrr] = i;
+ break;
+
+ case CCL_IterateMultipleMap:
+ {
+ Lisp_Object map, content, attrib, value;
+ int point, size, fin_ic;
+
+ j = XINT (ccl_prog[ic++]); /* number of maps. */
+ fin_ic = ic + j;
+ op = reg[rrr];
+ if ((j > reg[RRR]) && (j >= 0))
+ {
+ ic += reg[RRR];
+ i = reg[RRR];
+ }
+ else
+ {
+ reg[RRR] = -1;
+ ic = fin_ic;
+ break;
+ }
+
+ for (;i < j;i++)
+ {
+
+ size = XVECTOR (Vcode_conversion_map_vector)->size;
+ point = XINT (ccl_prog[ic++]);
+ if (point >= size) continue;
+ map =
+ XVECTOR (Vcode_conversion_map_vector)->contents[point];
+
+ /* Check map varidity. */
+ if (!CONSP (map)) continue;
+ map = XCONS(map)->cdr;
+ 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 ELELMENT 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;
+ else if (NUMBERP (content))
+ {
+ reg[RRR] = i;
+ reg[rrr] = XINT(content);
+ break;
+ }
+ else if (EQ (content, Qt) || EQ (content, Qlambda))
+ {
+ reg[RRR] = i;
+ break;
+ }
+ else if (CONSP (content))
+ {
+ attrib = XCONS (content)->car;
+ value = XCONS (content)->cdr;
+ if (!NUMBERP (attrib) || !NUMBERP (value))
+ continue;
+ reg[RRR] = i;
+ reg[rrr] = XUINT (value);
+ break;
+ }
+ }
+ if (i == j)
+ reg[RRR] = -1;
+ ic = fin_ic;
+ }
+ break;
+
+ case CCL_MapMultiple:
+ {
+ Lisp_Object map, content, attrib, value;
+ int point, size, map_vector_size;
+ int map_set_rest_length, fin_ic;
+
+ map_set_rest_length =
+ XINT (ccl_prog[ic++]); /* number of maps and separators. */
+ fin_ic = ic + map_set_rest_length;
+ if ((map_set_rest_length > reg[RRR]) && (reg[RRR] >= 0))
+ {
+ ic += reg[RRR];
+ i = reg[RRR];
+ map_set_rest_length -= i;
+ }
+ else
+ {
+ ic = fin_ic;
+ reg[RRR] = -1;
+ 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 = XCONS (map)->cdr;
+ 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;
+ 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))
+ {
+ attrib = XCONS (content)->car;
+ value = XCONS (content)->cdr;
+ 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;
+ op = reg[rrr];
+ i += map_set_rest_length;
+ POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
+ }
+ else if (EQ (content, Qlambda))
+ {
+ break;
+ }
+ else
+ CCL_INVALID_CMD;
+ }
+ ic = fin_ic;
+ }
+ reg[rrr] = op;
+ break;
+
+ case CCL_MapSingle:
+ {
+ Lisp_Object map, attrib, value, content;
+ int size, point;
+ j = XINT (ccl_prog[ic++]); /* map_id */
+ op = reg[rrr];
+ if (j >= XVECTOR (Vcode_conversion_map_vector)->size)
+ {
+ reg[RRR] = -1;
+ break;
+ }
+ map = XVECTOR (Vcode_conversion_map_vector)->contents[j];
+ if (!CONSP (map))
+ {
+ reg[RRR] = -1;
+ break;
+ }
+ map = XCONS(map)->cdr;
+ if (!VECTORP (map))
+ {
+ reg[RRR] = -1;
+ break;
+ }
+ size = XVECTOR (map)->size;
+ point = XUINT (XVECTOR (map)->contents[0]);
+ point = op - point + 1;
+ reg[RRR] = 0;
+ if ((size <= 1) ||
+ (!((point >= 1) && (point < size))))
+ reg[RRR] = -1;
+ else
+ {
+ content = XVECTOR (map)->contents[point];
+ if (NILP (content))
+ reg[RRR] = -1;
+ else if (NUMBERP (content))
+ reg[rrr] = XINT (content);
+ else if (EQ (content, Qt))
+ reg[RRR] = i;
+ else if (CONSP (content))
+ {
+ attrib = XCONS (content)->car;
+ value = XCONS (content)->cdr;
+ if (!NUMBERP (attrib) || !NUMBERP (value))
+ continue;
+ reg[rrr] = XUINT(value);
+ break;
+ }
+ else
+ reg[RRR] = -1;
+ }
+ }
+ break;
+#endif
+
+ default:
+ CCL_INVALID_CMD;
+ }
+ break;
+