Previous: , Up: Coding for Mule   [Contents][Index]


8.7.5 An Example of Mule-Aware Code

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 Emchars 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.