Commit 17cb263a authored by Paul Eggert's avatar Paul Eggert

New C macro AUTO_STRING_WITH_LEN

Put a bit less pressure on the garbage collector by defining a
macro that is like AUTO_STRING but also allows null bytes in strings,
and by extending AUTO_STRING to work with any unibyte string.
* src/alloc.c (verify_ascii): Remove; all uses removed.
AUTO_STRING can now be used on non-ASCII unibyte strings.
* src/lisp.h (AUTO_STRING): Now allows non-ASCII unibyte strings.
(AUTO_STRING_WITH_LEN): New macro.
* src/coding.c (from_unicode_buffer):
* src/editfns.c (format_time_string):
* src/emacs-module.c (module_make_string, module_format_fun_env):
* src/fileio.c (Fexpand_file_name):
* src/font.c (font_parse_family_registry):
* src/ftfont.c (ftfont_get_charset):
* src/keymap.c (silly_event_symbol_error):
* src/menu.c (single_menu_item):
* src/sysdep.c (system_process_attributes):
Use AUTO_STRING_WITH_LEN if possible.
* src/emacs-module.c (module_make_function):
* src/fileio.c (report_file_errno, report_file_notify_error):
* src/fns.c (Flocale_info):
* src/sysdep.c (system_process_attributes):
Use AUTO_STRING if possible.  This is doable more often now
that AUTO_STRING works on any unibyte string.
parent 0322457e
......@@ -7216,21 +7216,6 @@ die (const char *msg, const char *file, int line)
#if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS
/* Debugging check whether STR is ASCII-only. */
const char *
verify_ascii (const char *str)
{
const unsigned char *ptr = (unsigned char *) str, *end = ptr + strlen (str);
while (ptr < end)
{
int c = STRING_CHAR_ADVANCE (ptr);
if (!ASCII_CHAR_P (c))
emacs_abort ();
}
return str;
}
/* Stress alloca with inconveniently sized requests and check
whether all allocated areas may be used for Lisp_Object. */
......
......@@ -8419,11 +8419,10 @@ from_unicode (Lisp_Object str)
Lisp_Object
from_unicode_buffer (const wchar_t *wstr)
{
return from_unicode (
make_unibyte_string (
(char *) wstr,
/* we get one of the two final 0 bytes for free. */
1 + sizeof (wchar_t) * wcslen (wstr)));
/* We get one of the two final null bytes for free. */
prtdiff_t len = 1 + sizeof (wchar_t) * wcslen (wstr);
AUTO_STRING_WITH_LEN (str, (char *) wstr, len);
return from_unicode (str);
}
wchar_t *
......
......@@ -2042,7 +2042,6 @@ format_time_string (char const *format, ptrdiff_t formatlen,
char *buf = buffer;
ptrdiff_t size = sizeof buffer;
size_t len;
Lisp_Object bufstring;
int ns = t.tv_nsec;
USE_SAFE_ALLOCA;
......@@ -2074,9 +2073,11 @@ format_time_string (char const *format, ptrdiff_t formatlen,
}
xtzfree (tz);
bufstring = make_unibyte_string (buf, len);
AUTO_STRING_WITH_LEN (bufstring, buf, len);
Lisp_Object result = code_convert_string_norecord (bufstring,
Vlocale_coding_system, 0);
SAFE_FREE ();
return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0);
return result;
}
DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0,
......
......@@ -395,11 +395,13 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
envptr->data = data;
Lisp_Object envobj = make_save_ptr (envptr);
Lisp_Object doc
= (documentation
? code_convert_string_norecord (build_unibyte_string (documentation),
Qutf_8, false)
: Qnil);
Lisp_Object doc = Qnil;
if (documentation)
{
AUTO_STRING (unibyte_doc, documentation);
doc = code_convert_string_norecord (unibyte_doc, Qutf_8, false);
}
/* FIXME: Use a bytecompiled object, or even better a subr. */
Lisp_Object ret = list4 (Qlambda,
list2 (Qand_rest, Qargs),
......@@ -537,7 +539,7 @@ static emacs_value
module_make_string (emacs_env *env, const char *str, ptrdiff_t length)
{
MODULE_FUNCTION_BEGIN (module_nil);
Lisp_Object lstr = make_unibyte_string (str, length);
AUTO_STRING_WITH_LEN (lstr, str, length);
return lisp_to_value (code_convert_string_norecord (lstr, Qutf_8, false));
}
......@@ -992,10 +994,12 @@ module_format_fun_env (const struct module_fun_env *env)
? exprintf (&buf, &bufsize, buffer, -1,
"#<module function %s from %s>", sym, path)
: sprintf (buffer, noaddr_format, env->subr));
Lisp_Object unibyte_result = make_unibyte_string (buffer, size);
AUTO_STRING_WITH_LEN (unibyte_result, buffer, size);
Lisp_Object result = code_convert_string_norecord (unibyte_result,
Qutf_8, false);
if (buf != buffer)
xfree (buf);
return code_convert_string_norecord (unibyte_result, Qutf_8, false);
return result;
}
......
......@@ -187,9 +187,9 @@ report_file_errno (char const *string, Lisp_Object name, int errorno)
Lisp_Object data = CONSP (name) || NILP (name) ? name : list1 (name);
synchronize_system_messages_locale ();
char *str = strerror (errorno);
AUTO_STRING (unibyte_str, str);
Lisp_Object errstring
= code_convert_string_norecord (build_unibyte_string (str),
Vlocale_coding_system, 0);
= code_convert_string_norecord (unibyte_str, Vlocale_coding_system, 0);
Lisp_Object errdata = Fcons (errstring, data);
if (errorno == EEXIST)
......@@ -217,9 +217,9 @@ report_file_notify_error (const char *string, Lisp_Object name)
Lisp_Object data = CONSP (name) || NILP (name) ? name : list1 (name);
synchronize_system_messages_locale ();
char *str = strerror (errno);
AUTO_STRING (unibyte_str, str);
Lisp_Object errstring
= code_convert_string_norecord (build_unibyte_string (str),
Vlocale_coding_system, 0);
= code_convert_string_norecord (unibyte_str, Vlocale_coding_system, 0);
Lisp_Object errdata = Fcons (errstring, data);
xsignal (Qfile_notify_error, Fcons (build_string (string), errdata));
......@@ -1015,11 +1015,9 @@ filesystem tree, not (expand-file-name ".." dirname). */)
/* Drive must be set, so this is okay. */
if (strcmp (nm - 2, SSDATA (name)) != 0)
{
char temp[] = " :";
name = make_specified_string (nm, -1, p - nm, multibyte);
temp[0] = DRIVE_LETTER (drive);
AUTO_STRING (drive_prefix, temp);
char temp[] = { DRIVE_LETTER (drive), ':', 0 };
AUTO_STRING_WITH_LEN (drive_prefix, temp, 2);
name = concat2 (drive_prefix, name);
}
#ifdef WINDOWSNT
......
......@@ -2999,7 +2999,6 @@ The data read from the system are decoded using `locale-coding-system'. */)
{
char *str = NULL;
#ifdef HAVE_LANGINFO_CODESET
Lisp_Object val;
if (EQ (item, Qcodeset))
{
str = nl_langinfo (CODESET);
......@@ -3015,7 +3014,7 @@ The data read from the system are decoded using `locale-coding-system'. */)
for (i = 0; i < 7; i++)
{
str = nl_langinfo (days[i]);
val = build_unibyte_string (str);
AUTO_STRING (val, str);
/* Fixme: Is this coding system necessarily right, even if
it is consistent with CODESET? If not, what to do? */
ASET (v, i, code_convert_string_norecord (val, Vlocale_coding_system,
......@@ -3035,7 +3034,7 @@ The data read from the system are decoded using `locale-coding-system'. */)
for (i = 0; i < 12; i++)
{
str = nl_langinfo (months[i]);
val = build_unibyte_string (str);
AUTO_STRING (val, str);
ASET (v, i, code_convert_string_norecord (val, Vlocale_coding_system,
0));
}
......
......@@ -1771,7 +1771,8 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
p1 = strchr (p0, '-');
if (! p1)
{
AUTO_STRING (extra, (&"*-*"[len && p0[len - 1] == '*']));
bool asterisk = len && p0[len - 1] == '*';
AUTO_STRING_WITH_LEN (extra, &"*-*"[asterisk], 3 - asterisk);
registry = concat2 (registry, extra);
}
registry = Fdowncase (registry);
......
......@@ -568,7 +568,6 @@ ftfont_get_charset (Lisp_Object registry)
char *str = SSDATA (SYMBOL_NAME (registry));
USE_SAFE_ALLOCA;
char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
Lisp_Object regexp;
int i, j;
for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
......@@ -582,13 +581,13 @@ ftfont_get_charset (Lisp_Object registry)
re[j] = '.';
}
re[j] = '\0';
regexp = make_unibyte_string (re, j);
SAFE_FREE ();
AUTO_STRING_WITH_LEN (regexp, re, j);
for (i = 0; fc_charset_table[i].name; i++)
if (fast_c_string_match_ignore_case
(regexp, fc_charset_table[i].name,
strlen (fc_charset_table[i].name)) >= 0)
break;
SAFE_FREE ();
if (! fc_charset_table[i].name)
return -1;
if (! fc_charset_table[i].fc_charset)
......
......@@ -1303,7 +1303,7 @@ silly_event_symbol_error (Lisp_Object c)
*p = 0;
c = reorder_modifiers (c);
AUTO_STRING (new_mods_string, new_mods);
AUTO_STRING_WITH_LEN (new_mods_string, new_mods, p - new_mods);
keystring = concat2 (new_mods_string, XCDR (assoc));
error ("To bind the key %s, use [?%s], not [%s]",
......
......@@ -4609,27 +4609,29 @@ enum
STACK_CONS (d, Qnil)))) \
: list4 (a, b, c, d))
/* Check whether stack-allocated strings are ASCII-only. */
/* Declare NAME as an auto Lisp string if possible, a GC-based one if not.
Take its unibyte value from the null-terminated string STR,
an expression that should not have side effects.
STR's value is not necessarily copied. The resulting Lisp string
should not be modified or made visible to user code. */
#if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS
extern const char *verify_ascii (const char *);
#else
# define verify_ascii(str) (str)
#endif
#define AUTO_STRING(name, str) \
AUTO_STRING_WITH_LEN (name, str, strlen (str))
/* Declare NAME as an auto Lisp string if possible, a GC-based one if not.
Take its value from STR. STR is not necessarily copied and should
contain only ASCII characters. The resulting Lisp string should
not be modified or made visible to user code. */
Take its unibyte value from the null-terminated string STR with length LEN.
STR may have side effects and may contain null bytes.
STR's value is not necessarily copied. The resulting Lisp string
should not be modified or made visible to user code. */
#define AUTO_STRING(name, str) \
#define AUTO_STRING_WITH_LEN(name, str, len) \
Lisp_Object name = \
(USE_STACK_STRING \
? (make_lisp_ptr \
((&(union Aligned_String) \
{{strlen (str), -1, 0, (unsigned char *) verify_ascii (str)}}.s), \
Lisp_String)) \
: build_string (verify_ascii (str)))
{{len, -1, 0, (unsigned char *) (str)}}.s), \
Lisp_String)) \
: make_unibyte_string (str, len))
/* Loop over all tails of a list, checking for cycles.
FIXME: Make tortoise and n internal declarations.
......
......@@ -408,7 +408,7 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
if (prefix)
{
AUTO_STRING (prefix_obj, prefix);
AUTO_STRING_WITH_LEN (prefix_obj, prefix, 4);
item_string = concat2 (prefix_obj, item_string);
}
}
......
......@@ -3050,7 +3050,7 @@ system_process_attributes (Lisp_Object pid)
struct timespec tnow, tstart, tboot, telapsed, us_time;
double pcpu, pmem;
Lisp_Object attrs = Qnil;
Lisp_Object cmd_str, decoded_cmd;
Lisp_Object decoded_cmd;
ptrdiff_t count;
CHECK_NUMBER_OR_FLOAT (pid);
......@@ -3107,7 +3107,7 @@ system_process_attributes (Lisp_Object pid)
else
q = NULL;
/* Command name is encoded in locale-coding-system; decode it. */
cmd_str = make_unibyte_string (cmd, cmdsize);
AUTO_STRING_WITH_LEN (cmd_str, cmd, cmdsize);
decoded_cmd = code_convert_string_norecord (cmd_str,
Vlocale_coding_system, 0);
attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
......@@ -3240,7 +3240,7 @@ system_process_attributes (Lisp_Object pid)
sprintf (cmdline, "[%.*s]", cmdsize, cmd);
}
/* Command line is encoded in locale-coding-system; decode it. */
cmd_str = make_unibyte_string (q, nread);
AUTO_STRING_WITH_LEN (cmd_str, q, nread);
decoded_cmd = code_convert_string_norecord (cmd_str,
Vlocale_coding_system, 0);
unbind_to (count, Qnil);
......@@ -3375,13 +3375,13 @@ system_process_attributes (Lisp_Object pid)
make_float (100.0 / 0x8000 * pinfo.pr_pctmem)),
attrs);
decoded_cmd = (code_convert_string_norecord
(build_unibyte_string (pinfo.pr_fname),
Vlocale_coding_system, 0));
AUTO_STRING (fname, pinfo.pr_fname);
decoded_cmd = code_convert_string_norecord (fname,
Vlocale_coding_system, 0);
attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
decoded_cmd = (code_convert_string_norecord
(build_unibyte_string (pinfo.pr_psargs),
Vlocale_coding_system, 0));
AUTO_STRING (psargs, pinfo.pr_psargs);
decoded_cmd = code_convert_string_norecord (psargs,
Vlocale_coding_system, 0);
attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
}
unbind_to (count, Qnil);
......@@ -3446,9 +3446,8 @@ system_process_attributes (Lisp_Object pid)
if (gr)
attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
decoded_comm = (code_convert_string_norecord
(build_unibyte_string (proc.ki_comm),
Vlocale_coding_system, 0));
AUTO_STRING (comm, proc.ki_comm);
decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0);
attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
{
......@@ -3559,10 +3558,9 @@ system_process_attributes (Lisp_Object pid)
args[i] = ' ';
}
decoded_comm =
(code_convert_string_norecord
(build_unibyte_string (args),
Vlocale_coding_system, 0));
AUTO_STRING (comm, args);
decoded_comm = code_convert_string_norecord (comm,
Vlocale_coding_system, 0);
attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment