+/* Resolve symbols in the specified CCL code (Lisp vector). This
+ function converts symbols of code conversion maps and character
+ translation tables embeded in the CCL code into their ID numbers.
+
+ The return value is a vector (CCL itself or a new vector in which
+ all symbols are resolved), Qt if resolving of some symbol failed,
+ or nil if CCL contains invalid data. */
+
+static Lisp_Object
+resolve_symbol_ccl_program (ccl)
+ Lisp_Object ccl;
+{
+ int i, veclen, unresolved = 0;
+ Lisp_Object result, contents, val;
+
+ result = ccl;
+ veclen = ASIZE (result);
+
+ for (i = 0; i < veclen; i++)
+ {
+ contents = AREF (result, i);
+ if (INTEGERP (contents))
+ continue;
+ else if (CONSP (contents)
+ && SYMBOLP (XCAR (contents))
+ && SYMBOLP (XCDR (contents)))
+ {
+ /* This is the new style for embedding symbols. The form is
+ (SYMBOL . PROPERTY). (get SYMBOL PROPERTY) should give
+ an index number. */
+
+ if (EQ (result, ccl))
+ result = Fcopy_sequence (ccl);
+
+ val = Fget (XCAR (contents), XCDR (contents));
+ if (NATNUMP (val))
+ AREF (result, i) = val;
+ else
+ unresolved = 1;
+ continue;
+ }
+ else if (SYMBOLP (contents))
+ {
+ /* This is the old style for embedding symbols. This style
+ may lead to a bug if, for instance, a translation table
+ and a code conversion map have the same name. */
+ if (EQ (result, ccl))
+ result = Fcopy_sequence (ccl);
+
+ val = Fget (contents, Qtranslation_table_id);
+ if (NATNUMP (val))
+ AREF (result, i) = val;
+ else
+ {
+ val = Fget (contents, Qcode_conversion_map_id);
+ if (NATNUMP (val))
+ AREF (result, i) = val;
+ else
+ {
+ val = Fget (contents, Qccl_program_idx);
+ if (NATNUMP (val))
+ AREF (result, i) = val;
+ else
+ unresolved = 1;
+ }
+ }
+ continue;
+ }
+ return Qnil;
+ }
+
+ return (unresolved ? Qt : result);
+}
+
+/* Return the compiled code (vector) of CCL program CCL_PROG.
+ CCL_PROG is a name (symbol) of the program or already compiled
+ code. If necessary, resolve symbols in the compiled code to index
+ numbers. If we failed to get the compiled code or to resolve
+ symbols, return Qnil. */
+
+static Lisp_Object
+ccl_get_compiled_code (ccl_prog, idx)
+ Lisp_Object ccl_prog;
+ int *idx;
+{
+ Lisp_Object val, slot;
+
+ if (VECTORP (ccl_prog))
+ {
+ val = resolve_symbol_ccl_program (ccl_prog);
+ *idx = -1;
+ return (VECTORP (val) ? val : Qnil);
+ }
+ if (!SYMBOLP (ccl_prog))
+ return Qnil;
+
+ val = Fget (ccl_prog, Qccl_program_idx);
+ if (! NATNUMP (val)
+ || XINT (val) >= ASIZE (Vccl_program_table))
+ return Qnil;
+ slot = AREF (Vccl_program_table, XINT (val));
+ if (! VECTORP (slot)
+ || ASIZE (slot) != 4
+ || ! VECTORP (AREF (slot, 1)))
+ return Qnil;
+ *idx = XINT (val);
+ if (NILP (AREF (slot, 2)))
+ {
+ val = resolve_symbol_ccl_program (AREF (slot, 1));
+ if (! VECTORP (val))
+ return Qnil;
+ AREF (slot, 1) = val;
+ AREF (slot, 2) = Qt;
+ }
+ return AREF (slot, 1);
+}
+