Function: check-coding-systems-region
check-coding-systems-region is a function defined in coding.c.
Signature
(check-coding-systems-region START END CODING-SYSTEM-LIST)
Documentation
Check if text between START and END is encodable by CODING-SYSTEM-LIST.
START and END are buffer positions specifying the region. CODING-SYSTEM-LIST is a list of coding systems to check.
If all coding systems in CODING-SYSTEM-LIST can encode the region, the function returns nil.
If some of the coding systems cannot encode the whole region, value is an alist, each element of which has the form (CODING-SYSTEM POS1 POS2 ...), which means that CODING-SYSTEM cannot encode the text at buffer positions POS1, POS2, ...
START may be a string. In that case, check if the string is encodable, and the value contains character indices into the string instead of buffer positions. END is ignored in this case.
If the current buffer (or START if it is a string) is unibyte, the value is nil.
Probably introduced at or before Emacs version 23.1.
Source Code
// Defined in /usr/src/emacs/src/coding.c
{
Lisp_Object list;
ptrdiff_t start_byte, end_byte;
ptrdiff_t pos;
const unsigned char *p, *pbeg, *pend;
int c;
Lisp_Object tail, elt, attrs;
if (STRINGP (start))
{
if (!STRING_MULTIBYTE (start)
|| SCHARS (start) == SBYTES (start))
return Qnil;
start_byte = 0;
end_byte = SBYTES (start);
pos = 0;
}
else
{
EMACS_INT s = fix_position (start);
EMACS_INT e = fix_position (end);
if (! (BEG <= s && s <= e && e <= Z))
args_out_of_range (start, end);
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
return Qnil;
start_byte = CHAR_TO_BYTE (s);
end_byte = CHAR_TO_BYTE (e);
if (e - s == end_byte - start_byte)
return Qnil;
if (s < GPT && GPT < e)
{
if (GPT - s < e - GPT)
move_gap_both (s, start_byte);
else
move_gap_both (e, end_byte);
}
pos = s;
}
list = Qnil;
for (tail = coding_system_list; CONSP (tail); tail = XCDR (tail))
{
elt = XCAR (tail);
Lisp_Object spec = CODING_SYSTEM_SPEC (elt);
if (!VECTORP (spec))
xsignal1 (Qcoding_system_error, elt);
attrs = AREF (spec, 0);
ASET (attrs, coding_attr_trans_tbl,
get_translation_table (attrs, 1, NULL));
list = Fcons (list2 (elt, attrs), list);
}
if (STRINGP (start))
p = pbeg = SDATA (start);
else
p = pbeg = BYTE_POS_ADDR (start_byte);
pend = p + (end_byte - start_byte);
while (p < pend && ASCII_CHAR_P (*p)) p++, pos++;
while (p < pend && ASCII_CHAR_P (*(pend - 1))) pend--;
while (p < pend)
{
if (ASCII_CHAR_P (*p))
p++;
else
{
c = string_char_advance (&p);
charset_map_loaded = 0;
for (tail = list; CONSP (tail); tail = XCDR (tail))
{
elt = XCDR (XCAR (tail));
if (! char_encodable_p (c, XCAR (elt)))
XSETCDR (elt, Fcons (make_fixnum (pos), XCDR (elt)));
}
if (charset_map_loaded)
{
ptrdiff_t p_offset = p - pbeg, pend_offset = pend - pbeg;
if (STRINGP (start))
pbeg = SDATA (start);
else
pbeg = BYTE_POS_ADDR (start_byte);
p = pbeg + p_offset;
pend = pbeg + pend_offset;
}
}
pos++;
}
tail = list;
list = Qnil;
for (; CONSP (tail); tail = XCDR (tail))
{
elt = XCAR (tail);
if (CONSP (XCDR (XCDR (elt))))
list = Fcons (Fcons (XCAR (elt), Fnreverse (XCDR (XCDR (elt)))),
list);
}
return list;
}