Previous: General Guidelines for Writing Mule-Aware Code, Up: Coding for Mule [Contents][Index]
As an example of Mule-aware code, we will analyze the string
function, which conses up a Lisp string from the character arguments it
receives. Here is the definition, pasted from alloc.c
:
DEFUN ("string", Fstring, 0, MANY, 0, /* Concatenate all the argument characters and make the result a string. */ (int nargs, Lisp_Object *args)) { Bufbyte *storage = alloca_array (Bufbyte, nargs * MAX_EMCHAR_LEN); Bufbyte *p = storage; for (; nargs; nargs--, args++) { Lisp_Object lisp_char = *args; CHECK_CHAR_COERCE_INT (lisp_char); p += set_charptr_emchar (p, XCHAR (lisp_char)); } return make_string (storage, p - storage); }
Now we can analyze the source line by line.
Obviously, string will be as long as there are arguments to the
function. This is why we allocate MAX_EMCHAR_LEN
* nargs
bytes on the stack, i.e. the worst-case number of bytes for nargs
Emchar
s to fit in the string.
Then, the loop checks that each element is a character, converting
integers in the process. Like many other functions in SXEmacs, this
function silently accepts integers where characters are expected, for
historical and compatibility reasons. Unless you know what you are
doing, CHECK_CHAR
will also suffice. XCHAR (lisp_char)
extracts the Emchar
from the Lisp_Object
, and
set_charptr_emchar
stores it to storage, increasing p
in
the process.
Other instructive examples of correct coding under Mule can be found all
over the SXEmacs code. For starters, I recommend
Fnormalize_menu_item_name
in menubar.c. After you have
understood this section of the manual and studied the examples, you can
proceed writing new Mule-aware code.