Function: ccl-execute-on-string
ccl-execute-on-string is a function defined in ccl.c.
Signature
(ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBYTE-P)
Documentation
Execute CCL-PROGRAM with initial STATUS on STRING.
CCL-PROGRAM is a symbol registered by register-ccl-program,
or a compiled code generated by ccl-compile (for backward compatibility,
in this case, the execution is slower).
Read buffer is set to STRING, and write buffer is allocated automatically.
STATUS is a vector of [R0 R1 ... R7 IC], where
R0..R7 are initial values of corresponding registers,
IC is the instruction counter specifying from where to start the program.
If R0..R7 are nil, they are initialized to 0.
If IC is nil, it is initialized to head of the CCL program.
If optional 4th arg CONTINUE is non-nil, keep IC on read operation when read buffer is exhausted, else, IC is always set to the end of CCL-PROGRAM on exit.
It returns the contents of write buffer as a string,
and as side effect, STATUS is updated.
If the optional 5th arg UNIBYTE-P is non-nil, the returned string
is a unibyte string. By default it is a multibyte string.
See the documentation of define-ccl-program for the detail of CCL program.
Source Code
// Defined in /usr/src/emacs/src/ccl.c
{
Lisp_Object val;
struct ccl_program ccl;
int i;
ptrdiff_t outbufsize;
unsigned char *outbuf, *outp;
ptrdiff_t str_chars, str_bytes;
#define CCL_EXECUTE_BUF_SIZE 1024
int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE];
ptrdiff_t consumed_chars, consumed_bytes, produced_chars;
int buf_magnification;
if (! setup_ccl_program (&ccl, ccl_prog))
error ("Invalid CCL program");
CHECK_VECTOR (status);
if (ASIZE (status) != 9)
error ("Length of vector STATUS is not 9");
CHECK_STRING (str);
str_chars = SCHARS (str);
str_bytes = SBYTES (str);
for (i = 0; i < 8; i++)
{
if (NILP (AREF (status, i)))
ASET (status, i, make_fixnum (0));
intmax_t n;
if (INTEGERP (AREF (status, i))
&& integer_to_intmax (AREF (status, i), &n)
&& INT_MIN <= n && n <= INT_MAX)
ccl.reg[i] = n;
}
intmax_t ic;
if (INTEGERP (AREF (status, 8)) && integer_to_intmax (AREF (status, 8), &ic))
{
if (ccl.ic < ic && ic < ccl.size)
ccl.ic = ic;
}
buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1;
outbufsize = str_bytes;
if (ckd_mul (&outbufsize, outbufsize, buf_magnification)
|| ckd_add (&outbufsize, outbufsize, 256))
memory_full (SIZE_MAX);
outp = outbuf = xmalloc (outbufsize);
consumed_chars = consumed_bytes = 0;
produced_chars = 0;
while (1)
{
const unsigned char *p = SDATA (str) + consumed_bytes;
const unsigned char *endp = SDATA (str) + str_bytes;
int j = 0;
int *src, src_size;
if (endp - p == str_chars - consumed_chars)
while (j < CCL_EXECUTE_BUF_SIZE && p < endp)
source[j++] = *p++;
else
while (j < CCL_EXECUTE_BUF_SIZE && p < endp)
source[j++] = string_char_advance (&p);
consumed_chars += j;
consumed_bytes = p - SDATA (str);
if (consumed_bytes == str_bytes)
ccl.last_block = NILP (contin);
src = source;
src_size = j;
while (1)
{
int max_expansion = NILP (unibyte_p) ? MAX_MULTIBYTE_LENGTH : 1;
ptrdiff_t offset, shortfall;
ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE,
Qnil);
produced_chars += ccl.produced;
offset = outp - outbuf;
shortfall = ccl.produced * max_expansion - (outbufsize - offset);
if (shortfall > 0)
{
outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1);
outp = outbuf + offset;
}
if (NILP (unibyte_p))
{
for (j = 0; j < ccl.produced; j++)
outp += CHAR_STRING (destination[j], outp);
}
else
{
for (j = 0; j < ccl.produced; j++)
*outp++ = destination[j];
}
src += ccl.consumed;
src_size -= ccl.consumed;
if (ccl.status != CCL_STAT_SUSPEND_BY_DST)
break;
}
if (ccl.status != CCL_STAT_SUSPEND_BY_SRC
|| str_chars == consumed_chars)
break;
}
if (ccl.status == CCL_STAT_INVALID_CMD)
error ("Error in CCL program at %dth code", ccl.ic);
if (ccl.status == CCL_STAT_QUIT)
error ("CCL program interrupted at %dth code", ccl.ic);
for (i = 0; i < 8; i++)
ASET (status, i, make_int (ccl.reg[i]));
ASET (status, 8, make_int (ccl.ic));
val = make_specified_string ((const char *) outbuf, produced_chars,
outp - outbuf, NILP (unibyte_p));
xfree (outbuf);
return val;
}