mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-21 20:12:51 -08:00
printer: optimize printing of strings. Fixes #403
This commit is contained in:
parent
f104b1f4f0
commit
5947970f6d
3 changed files with 56 additions and 34 deletions
|
|
@ -487,8 +487,10 @@ cl_char_name(cl_object c)
|
|||
cl_object output;
|
||||
if (code <= 127) {
|
||||
output = ecl_gethash_safe(ecl_make_fixnum(code), cl_core.char_names, ECL_NIL);
|
||||
#ifdef ECL_UNICODE
|
||||
} else if (!Null(output = _ecl_ucd_code_to_name(code))) {
|
||||
(void)0;
|
||||
#endif
|
||||
} else {
|
||||
ecl_base_char name[8];
|
||||
ecl_base_char *start;
|
||||
|
|
@ -521,10 +523,12 @@ cl_name_char(cl_object name)
|
|||
if (c != ECL_NIL) {
|
||||
ecl_return1(the_env, ECL_CODE_CHAR(ecl_fixnum(c)));
|
||||
}
|
||||
#ifdef ECL_UNICODE
|
||||
c = _ecl_ucd_name_to_code(name);
|
||||
if (c != ECL_NIL) {
|
||||
ecl_return1(the_env, cl_code_char(c));
|
||||
}
|
||||
#endif
|
||||
if (ecl_stringp(name) && (l = ecl_length(name))) {
|
||||
c = cl_char(name, ecl_make_fixnum(0));
|
||||
if (l == 1) {
|
||||
|
|
|
|||
63
src/c/file.d
63
src/c/file.d
|
|
@ -60,6 +60,8 @@
|
|||
* with 4 being the charset prefix, 2 for the character.
|
||||
*/
|
||||
#define ENCODING_BUFFER_MAX_SIZE 6
|
||||
/* Size of the encoding buffer for vectors */
|
||||
#define VECTOR_ENCODING_BUFFER_SIZE 2048
|
||||
|
||||
static cl_index ecl_read_byte8(cl_object stream, unsigned char *c, cl_index n);
|
||||
static cl_index ecl_write_byte8(cl_object stream, unsigned char *c, cl_index n);
|
||||
|
|
@ -583,6 +585,17 @@ eformat_read_char(cl_object strm)
|
|||
return c;
|
||||
}
|
||||
|
||||
static inline void
|
||||
write_char_increment_column(cl_object strm, ecl_character c)
|
||||
{
|
||||
if (c == '\n')
|
||||
strm->stream.column = 0;
|
||||
else if (c == '\t')
|
||||
strm->stream.column = (strm->stream.column & ~((cl_index)07)) + 8;
|
||||
else
|
||||
strm->stream.column++;
|
||||
}
|
||||
|
||||
static ecl_character
|
||||
eformat_write_char(cl_object strm, ecl_character c)
|
||||
{
|
||||
|
|
@ -590,13 +603,7 @@ eformat_write_char(cl_object strm, ecl_character c)
|
|||
ecl_character nbytes;
|
||||
nbytes = strm->stream.encoder(strm, buffer, c);
|
||||
strm->stream.ops->write_byte8(strm, buffer, nbytes);
|
||||
if (c == '\n')
|
||||
strm->stream.column = 0;
|
||||
else if (c == '\t')
|
||||
strm->stream.column = (strm->stream.column & ~((cl_index)07)) + 8;
|
||||
else
|
||||
strm->stream.column++;
|
||||
fflush(stdout);
|
||||
write_char_increment_column(strm, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
@ -1335,13 +1342,7 @@ const struct ecl_file_ops clos_stream_ops = {
|
|||
static ecl_character
|
||||
str_out_write_char(cl_object strm, ecl_character c)
|
||||
{
|
||||
int column = strm->stream.column;
|
||||
if (c == '\n')
|
||||
strm->stream.column = 0;
|
||||
else if (c == '\t')
|
||||
strm->stream.column = (column&~(cl_index)7) + 8;
|
||||
else
|
||||
strm->stream.column++;
|
||||
write_char_increment_column(strm, c);
|
||||
ecl_string_push_extend(STRING_OUTPUT_STRING(strm), c);
|
||||
return c;
|
||||
}
|
||||
|
|
@ -2892,7 +2893,40 @@ io_file_write_vector(cl_object strm, cl_object data, cl_index start, cl_index en
|
|||
bytes = strm->stream.ops->write_byte8(strm, aux, bytes);
|
||||
return start + bytes / sizeof(cl_fixnum);
|
||||
}
|
||||
} else if (t == ecl_aet_bc) {
|
||||
unsigned char buffer[VECTOR_ENCODING_BUFFER_SIZE + ENCODING_BUFFER_MAX_SIZE];
|
||||
cl_index nbytes = 0;
|
||||
cl_index i;
|
||||
for (i = start; i < end; i++) {
|
||||
ecl_character c = *(data->vector.self.bc + i);
|
||||
nbytes += strm->stream.encoder(strm, buffer + nbytes, c);
|
||||
write_char_increment_column(strm, c);
|
||||
if (nbytes >= VECTOR_ENCODING_BUFFER_SIZE) {
|
||||
strm->stream.ops->write_byte8(strm, buffer, nbytes);
|
||||
nbytes = 0;
|
||||
}
|
||||
}
|
||||
strm->stream.ops->write_byte8(strm, buffer, nbytes);
|
||||
return end;
|
||||
}
|
||||
#ifdef ECL_UNICODE
|
||||
else if (t == ecl_aet_ch) {
|
||||
unsigned char buffer[VECTOR_ENCODING_BUFFER_SIZE + ENCODING_BUFFER_MAX_SIZE];
|
||||
cl_index nbytes = 0;
|
||||
cl_index i;
|
||||
for (i = start; i < end; i++) {
|
||||
ecl_character c = *(data->vector.self.c + i);
|
||||
nbytes += strm->stream.encoder(strm, buffer + nbytes, c);
|
||||
write_char_increment_column(strm, c);
|
||||
if (nbytes >= VECTOR_ENCODING_BUFFER_SIZE) {
|
||||
strm->stream.ops->write_byte8(strm, buffer, nbytes);
|
||||
nbytes = 0;
|
||||
}
|
||||
}
|
||||
strm->stream.ops->write_byte8(strm, buffer, nbytes);
|
||||
return end;
|
||||
}
|
||||
#endif
|
||||
return generic_write_vector(strm, data, start, end);
|
||||
}
|
||||
|
||||
|
|
@ -4696,6 +4730,7 @@ ecl_peek_char(cl_object strm)
|
|||
* SEQUENCES I/O
|
||||
*/
|
||||
|
||||
/* FIXME: We can optimize this to write the whole string at once */
|
||||
void
|
||||
writestr_stream(const char *s, cl_object strm)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ ecl_print_circle(void)
|
|||
@(defun write-string (strng &o strm &k (start ecl_make_fixnum(0)) end)
|
||||
@
|
||||
unlikely_if (!ECL_STRINGP(strng))
|
||||
FEwrong_type_nth_arg(@[write-string], 1, strng, @[string]);
|
||||
FEwrong_type_nth_arg(@[write-string], 1, strng, @[string]);
|
||||
strm = _ecl_stream_or_default_output(strm);
|
||||
#ifdef ECL_CLOS_STREAMS
|
||||
if (!ECL_ANSI_STREAM_P(strm))
|
||||
|
|
@ -234,7 +234,7 @@ ecl_print_circle(void)
|
|||
@(defun write-line (strng &o strm &k (start ecl_make_fixnum(0)) end)
|
||||
@
|
||||
unlikely_if (!ECL_STRINGP(strng))
|
||||
FEwrong_type_nth_arg(@[write-line], 1, strng, @[string]);
|
||||
FEwrong_type_nth_arg(@[write-line], 1, strng, @[string]);
|
||||
strm = _ecl_stream_or_default_output(strm);
|
||||
#ifdef ECL_CLOS_STREAMS
|
||||
if (!ECL_ANSI_STREAM_P(strm))
|
||||
|
|
@ -364,24 +364,7 @@ ecl_terpri(cl_object strm)
|
|||
void
|
||||
ecl_write_string(cl_object strng, cl_object strm)
|
||||
{
|
||||
cl_index i;
|
||||
|
||||
strm = _ecl_stream_or_default_output(strm);
|
||||
switch(ecl_t_of(strng)) {
|
||||
#ifdef ECL_UNICODE
|
||||
case t_string:
|
||||
for (i = 0; i < strng->string.fillp; i++)
|
||||
ecl_write_char(strng->string.self[i], strm);
|
||||
break;
|
||||
#endif
|
||||
case t_base_string:
|
||||
for (i = 0; i < strng->base_string.fillp; i++)
|
||||
ecl_write_char(strng->base_string.self[i], strm);
|
||||
break;
|
||||
default:
|
||||
FEwrong_type_nth_arg(@[write-string], 1, strng, @[string]);
|
||||
}
|
||||
|
||||
cl_write_string(2, strng, strm);
|
||||
ecl_force_output(strm);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue