You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/*** TABLE OF CONTENTS ***
static void
decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
- unsigned char *source, *destination;
+ const unsigned char *source;
+ unsigned char *destination;
int src_bytes, dst_bytes;
{
...
Lisp_Object Qvalid_codes;
extern Lisp_Object Qinsert_file_contents, Qwrite_region;
-Lisp_Object Qcall_process, Qcall_process_region, Qprocess_argument;
+Lisp_Object Qcall_process, Qcall_process_region;
Lisp_Object Qstart_process, Qopen_network_stream;
Lisp_Object Qtarget_idx;
decode_composition_emacs_mule (coding, src, src_end,
destination, dst_end, dst_bytes)
struct coding_system *coding;
- unsigned char *src, *src_end, **destination, *dst_end;
+ const unsigned char *src, *src_end;
+ unsigned char **destination, *dst_end;
int dst_bytes;
{
unsigned char *dst = *destination;
int method, data_len, nchars;
- unsigned char *src_base = src++;
+ const unsigned char *src_base = src++;
/* Store components of composition. */
int component[COMPOSITION_DATA_MAX_BUNCH_LENGTH];
int ncomponent;
static void
decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
- unsigned char *source, *destination;
+ const unsigned char *source;
+ unsigned char *destination;
int src_bytes, dst_bytes;
{
- unsigned char *src = source;
- unsigned char *src_end = source + src_bytes;
+ const unsigned char *src = source;
+ const unsigned char *src_end = source + src_bytes;
unsigned char *dst = destination;
unsigned char *dst_end = destination + dst_bytes;
/* SRC_BASE remembers the start position in source in each loop.
The loop will be exited when there's not enough source code, or
when there's not enough destination area to produce a
character. */
- unsigned char *src_base;
+ const unsigned char *src_base;
coding->produced_char = 0;
while ((src_base = src) < src_end)
{
- unsigned char tmp[MAX_MULTIBYTE_LENGTH], *p;
+ unsigned char tmp[MAX_MULTIBYTE_LENGTH];
+ const unsigned char *p;
int bytes;
if (*src == '\r')
static void
encode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
- unsigned char *source, *destination;
+ const unsigned char *source;
+ unsigned char *destination;
int src_bytes, dst_bytes;
{
- unsigned char *src = source;
- unsigned char *src_end = source + src_bytes;
+ const unsigned char *src = source;
+ const unsigned char *src_end = source + src_bytes;
unsigned char *dst = destination;
unsigned char *dst_end = destination + dst_bytes;
- unsigned char *src_base;
+ const unsigned char *src_base;
int c;
int char_offset;
int *data;
static void
decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
- unsigned char *source, *destination;
+ const unsigned char *source;
+ unsigned char *destination;
int src_bytes, dst_bytes;
{
- unsigned char *src = source;
- unsigned char *src_end = source + src_bytes;
+ const unsigned char *src = source;
+ const unsigned char *src_end = source + src_bytes;
unsigned char *dst = destination;
unsigned char *dst_end = destination + dst_bytes;
/* Charsets invoked to graphic plane 0 and 1 respectively. */
(within macro ONE_MORE_BYTE), or when there's not enough
destination area to produce a character (within macro
EMIT_CHAR). */
- unsigned char *src_base;
+ const unsigned char *src_base;
int c, charset;
Lisp_Object translation_table;
Lisp_Object safe_chars;
DECODE_COMPOSITION_END ('1');
src = src_base;
c = *src++;
+ if (! NILP (translation_table))
+ c = translate_char (translation_table, c, 0, 0, 0);
EMIT_CHAR (c);
}
encode_designation_at_bol (coding, translation_table, src, src_end, dst)
struct coding_system *coding;
Lisp_Object translation_table;
- unsigned char *src, *src_end, *dst;
+ const unsigned char *src, *src_end;
+ unsigned char *dst;
{
int charset, c, found = 0, reg;
/* Table of charsets to be designated to each graphic register. */
static void
encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
- unsigned char *source, *destination;
+ const unsigned char *source;
+ unsigned char *destination;
int src_bytes, dst_bytes;
{
- unsigned char *src = source;
- unsigned char *src_end = source + src_bytes;
+ const unsigned char *src = source;
+ const unsigned char *src_end = source + src_bytes;
unsigned char *dst = destination;
unsigned char *dst_end = destination + dst_bytes;
/* Since the maximum bytes produced by each loop is 20, we subtract 19
analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
there's not enough destination area to produce encoded codes
(within macro EMIT_BYTES). */
- unsigned char *src_base;
+ const unsigned char *src_base;
int c;
Lisp_Object translation_table;
Lisp_Object safe_chars;
decode_coding_sjis_big5 (coding, source, destination,
src_bytes, dst_bytes, sjis_p)
struct coding_system *coding;
- unsigned char *source, *destination;
+ const unsigned char *source;
+ unsigned char *destination;
int src_bytes, dst_bytes;
int sjis_p;
{
- unsigned char *src = source;
- unsigned char *src_end = source + src_bytes;
+ const unsigned char *src = source;
+ const unsigned char *src_end = source + src_bytes;
unsigned char *dst = destination;
unsigned char *dst_end = destination + dst_bytes;
/* SRC_BASE remembers the start position in source in each loop.
(within macro ONE_MORE_BYTE), or when there's not enough
destination area to produce a character (within macro
EMIT_CHAR). */
- unsigned char *src_base;
+ const unsigned char *src_base;
Lisp_Object translation_table;
if (NILP (Venable_character_translation))
static void
decode_eol (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
- unsigned char *source, *destination;
+ const unsigned char *source;
+ unsigned char *destination;
int src_bytes, dst_bytes;
{
- unsigned char *src = source;
+ const unsigned char *src = source;
unsigned char *dst = destination;
- unsigned char *src_end = src + src_bytes;
+ const unsigned char *src_end = src + src_bytes;
unsigned char *dst_end = dst + dst_bytes;
Lisp_Object translation_table;
/* SRC_BASE remembers the start position in source in each loop.
(within macro ONE_MORE_BYTE), or when there's not enough
destination area to produce a character (within macro
EMIT_CHAR). */
- unsigned char *src_base;
+ const unsigned char *src_base;
int c;
translation_table = Qnil;
} \
} while (0)
+/* ARG is (CODING . BUFFER) where CODING is what to be set in
+ Vlast_coding_system_used and BUFFER if non-nil is a buffer to
+ kill. */
static Lisp_Object
code_convert_region_unwind (arg)
Lisp_Object arg;
{
inhibit_pre_post_conversion = 0;
- Vlast_coding_system_used = arg;
+ Vlast_coding_system_used = XCAR (arg);
+ if (! NILP (XCDR (arg)))
+ Fkill_buffer (XCDR (arg));
return Qnil;
}
Lisp_Object new;
record_unwind_protect (code_convert_region_unwind,
- Vlast_coding_system_used);
+ Fcons (Vlast_coding_system_used, Qnil));
/* We should not call any more pre-write/post-read-conversion
functions while this pre-write-conversion is running. */
inhibit_pre_post_conversion = 1;
coding_allocate_composition_data (coding, from);
}
- /* Try to skip the heading and tailing ASCIIs. */
- if (coding->type != coding_type_ccl)
+ /* Try to skip the heading and tailing ASCIIs. We can't skip them
+ if we must run CCL program or there are compositions to
+ encode. */
+ if (coding->type != coding_type_ccl
+ && (! coding->cmp_data || coding->cmp_data->used == 0))
{
int from_byte_orig = from_byte, to_byte_orig = to_byte;
if (!replace)
/* We must record and adjust for this new text now. */
adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);
+ coding_free_composition_data (coding);
return 0;
}
REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG)
REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG
Here, we are sure that NEW >= ORIG. */
- float ratio;
if (coding->produced <= coding->consumed)
{
}
else
{
- ratio = (coding->produced - coding->consumed) / coding->consumed;
+ float ratio = coding->produced - coding->consumed;
+ ratio /= coding->consumed;
require = len_byte * ratio;
}
first = 0;
TEMP_SET_PT_BOTH (from, from_byte);
prev_Z = Z;
record_unwind_protect (code_convert_region_unwind,
- Vlast_coding_system_used);
+ Fcons (Vlast_coding_system_used, Qnil));
saved_coding_system = Vlast_coding_system_used;
Vlast_coding_system_used = coding->symbol;
/* We should not call any more pre-write/post-read-conversion
return 0;
}
+/* Name (or base name) of work buffer for code conversion. */
+static Lisp_Object Vcode_conversion_workbuf_name;
+
+/* Set the current buffer to the working buffer prepared for
+ code-conversion. MULTIBYTE specifies the multibyteness of the
+ buffer. Return the buffer we set if it must be killed after use.
+ Otherwise return Qnil. */
+
+static Lisp_Object
+set_conversion_work_buffer (multibyte)
+ int multibyte;
+{
+ Lisp_Object buffer, buffer_to_kill;
+ struct buffer *buf;
+
+ buffer = Fget_buffer_create (Vcode_conversion_workbuf_name);
+ buf = XBUFFER (buffer);
+ if (buf == current_buffer)
+ {
+ /* As we are already in the work buffer, we must generate a new
+ buffer for the work. */
+ Lisp_Object name;
+
+ name = Fgenerate_new_buffer_name (Vcode_conversion_workbuf_name, Qnil);
+ buffer = buffer_to_kill = Fget_buffer_create (name);
+ buf = XBUFFER (buffer);
+ }
+ else
+ buffer_to_kill = Qnil;
+
+ delete_all_overlays (buf);
+ buf->directory = current_buffer->directory;
+ buf->read_only = Qnil;
+ buf->filename = Qnil;
+ buf->undo_list = Qt;
+ eassert (buf->overlays_before == NULL);
+ eassert (buf->overlays_after == NULL);
+ set_buffer_internal (buf);
+ if (BEG != BEGV || Z != ZV)
+ Fwiden ();
+ del_range_2 (BEG, BEG_BYTE, Z, Z_BYTE, 0);
+ buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
+ return buffer_to_kill;
+}
+
Lisp_Object
run_pre_post_conversion_on_str (str, coding, encodep)
Lisp_Object str;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2;
int multibyte = STRING_MULTIBYTE (str);
- Lisp_Object buffer;
- struct buffer *buf;
Lisp_Object old_deactivate_mark;
+ Lisp_Object buffer_to_kill;
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
- record_unwind_protect (code_convert_region_unwind,
- Vlast_coding_system_used);
/* It is not crucial to specbind this. */
old_deactivate_mark = Vdeactivate_mark;
GCPRO2 (str, old_deactivate_mark);
- buffer = Fget_buffer_create (build_string (" *code-converting-work*"));
- buf = XBUFFER (buffer);
-
- delete_all_overlays (buf);
- buf->directory = current_buffer->directory;
- buf->read_only = Qnil;
- buf->filename = Qnil;
- buf->undo_list = Qt;
- eassert (buf->overlays_before == NULL);
- eassert (buf->overlays_after == NULL);
-
- set_buffer_internal (buf);
/* We must insert the contents of STR as is without
unibyte<->multibyte conversion. For that, we adjust the
multibyteness of the working buffer to that of STR. */
- Ferase_buffer ();
- buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
+ buffer_to_kill = set_conversion_work_buffer (multibyte);
+ record_unwind_protect (code_convert_region_unwind,
+ Fcons (Vlast_coding_system_used, buffer_to_kill));
insert_from_string (str, 0, 0,
SCHARS (str), SBYTES (str), 0);
return unbind_to (count, str);
}
+
+/* Run pre-write-conversion function of CODING on NCHARS/NBYTES
+ text in *STR. *SIZE is the allocated bytes for STR. As it
+ is intended that this function is called from encode_terminal_code,
+ the pre-write-conversion function is run by safe_call and thus
+ "Error during redisplay: ..." is logged when an error occurs.
+
+ Store the resulting text in *STR and set CODING->produced_char and
+ CODING->produced to the number of characters and bytes
+ respectively. If the size of *STR is too small, enlarge it by
+ xrealloc and update *STR and *SIZE. */
+
+void
+run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
+ unsigned char **str;
+ int *size, nchars, nbytes;
+ struct coding_system *coding;
+{
+ struct gcpro gcpro1, gcpro2;
+ struct buffer *cur = current_buffer;
+ Lisp_Object old_deactivate_mark, old_last_coding_system_used;
+ Lisp_Object args[3];
+ Lisp_Object buffer_to_kill;
+
+ /* It is not crucial to specbind this. */
+ old_deactivate_mark = Vdeactivate_mark;
+ old_last_coding_system_used = Vlast_coding_system_used;
+ GCPRO2 (old_deactivate_mark, old_last_coding_system_used);
+
+ /* We must insert the contents of STR as is without
+ unibyte<->multibyte conversion. For that, we adjust the
+ multibyteness of the working buffer to that of STR. */
+ buffer_to_kill = set_conversion_work_buffer (coding->src_multibyte);
+ insert_1_both (*str, nchars, nbytes, 0, 0, 0);
+ UNGCPRO;
+ inhibit_pre_post_conversion = 1;
+ args[0] = coding->pre_write_conversion;
+ args[1] = make_number (BEG);
+ args[2] = make_number (Z);
+ safe_call (3, args);
+ inhibit_pre_post_conversion = 0;
+ Vdeactivate_mark = old_deactivate_mark;
+ Vlast_coding_system_used = old_last_coding_system_used;
+ coding->produced_char = Z - BEG;
+ coding->produced = Z_BYTE - BEG_BYTE;
+ if (coding->produced > *size)
+ {
+ *size = coding->produced;
+ *str = xrealloc (*str, *size);
+ }
+ if (BEG < GPT && GPT < Z)
+ move_gap (BEG);
+ bcopy (BEG_ADDR, *str, coding->produced);
+ coding->src_multibyte
+ = ! NILP (current_buffer->enable_multibyte_characters);
+ set_buffer_internal (cur);
+ if (! NILP (buffer_to_kill))
+ Fkill_buffer (buffer_to_kill);
+}
+
+
Lisp_Object
decode_coding_string (str, coding, nocopy)
Lisp_Object str;
produced += coding->produced;
produced_char += coding->produced_char;
if (result == CODING_FINISH_NORMAL
+ || result == CODING_FINISH_INTERRUPT
|| (result == CODING_FINISH_INSUFFICIENT_SRC
&& coding->consumed == 0))
break;
shrinked_bytes - from);
free_conversion_buffer (&buf);
+ coding->consumed += shrinked_bytes;
+ coding->consumed_char += shrinked_bytes;
+ coding->produced += shrinked_bytes;
+ coding->produced_char += shrinked_bytes;
+
if (coding->cmp_data && coding->cmp_data->used)
coding_restore_composition (coding, newstr);
coding_free_composition_data (coding);
if (SYMBOLP (coding->pre_write_conversion)
&& !NILP (Ffboundp (coding->pre_write_conversion)))
- str = run_pre_post_conversion_on_str (str, coding, 1);
+ {
+ str = run_pre_post_conversion_on_str (str, coding, 1);
+ /* As STR is just newly generated, we don't have to copy it
+ anymore. */
+ nocopy = 1;
+ }
from = 0;
to = SCHARS (str);
/* Encoding routines determine the multibyteness of the source text
by coding->src_multibyte. */
- coding->src_multibyte = STRING_MULTIBYTE (str);
+ coding->src_multibyte = SCHARS (str) < SBYTES (str);
coding->dst_multibyte = 0;
if (! CODING_REQUIRE_ENCODING (coding))
- {
- coding->consumed = SBYTES (str);
- coding->consumed_char = SCHARS (str);
- if (STRING_MULTIBYTE (str))
- {
- str = Fstring_as_unibyte (str);
- nocopy = 1;
- }
- coding->produced = SBYTES (str);
- coding->produced_char = SCHARS (str);
- return (nocopy ? str : Fcopy_sequence (str));
- }
+ goto no_need_of_encoding;
if (coding->composing != COMPOSITION_DISABLED)
coding_save_composition (coding, from, to, str);
- /* Try to skip the heading and tailing ASCIIs. */
- if (coding->type != coding_type_ccl)
+ /* Try to skip the heading and tailing ASCIIs. We can't skip them
+ if we must run CCL program or there are compositions to
+ encode. */
+ if (coding->type != coding_type_ccl
+ && (! coding->cmp_data || coding->cmp_data->used == 0))
{
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),
1);
if (from == to_byte)
- return (nocopy ? str : Fcopy_sequence (str));
+ {
+ coding_free_composition_data (coding);
+ goto no_need_of_encoding;
+ }
shrinked_bytes = from + (SBYTES (str) - to_byte);
}
coding_free_composition_data (coding);
return newstr;
+
+ no_need_of_encoding:
+ coding->consumed = SBYTES (str);
+ coding->consumed_char = SCHARS (str);
+ if (STRING_MULTIBYTE (str))
+ {
+ if (nocopy)
+ /* We are sure that STR doesn't contain a multibyte
+ character. */
+ STRING_SET_UNIBYTE (str);
+ else
+ {
+ str = Fstring_as_unibyte (str);
+ nocopy = 1;
+ }
+ }
+ coding->produced = SBYTES (str);
+ coding->produced_char = SCHARS (str);
+ return (nocopy ? str : Fcopy_sequence (str));
}
\f
STRING_MULTIBYTE (string));
}
-/* Subroutine for Fsafe_coding_systems_region_internal.
+/* Subroutine for Ffind_coding_systems_region_internal.
Return a list of coding systems that safely encode the multibyte
text between P and PEND. SAFE_CODINGS, if non-nil, is an alist of
void
syms_of_coding ()
{
+ staticpro (&Vcode_conversion_workbuf_name);
+ Vcode_conversion_workbuf_name = build_string (" *code-conversion-work*");
+
Qtarget_idx = intern ("target-idx");
staticpro (&Qtarget_idx);
On detecting a coding system, Emacs tries code detection algorithms
associated with each coding-category one by one in this order. When
one algorithm agrees with a byte sequence of source text, the coding
-system bound to the corresponding coding-category is selected. */);
+system bound to the corresponding coding-category is selected.
+
+Don't modify this variable directly, but use `set-coding-priority'. */);
{
int i;