home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / e20313sr.zip / emacs / 20.3.1 / src / fns.c < prev    next >
C/C++ Source or Header  |  1999-07-31  |  79KB  |  2,813 lines

  1. /* Random utility Lisp functions.
  2.    Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.  */
  20.  
  21.  
  22. #include <config.h>
  23.  
  24. #ifdef HAVE_UNISTD_H
  25. #include <unistd.h>
  26. #endif
  27. #include <time.h>
  28.  
  29. /* Note on some machines this defines `vector' as a typedef,
  30.    so make sure we don't use that name in this file.  */
  31. #undef vector
  32. #define vector *****
  33.  
  34. #include "lisp.h"
  35. #include "commands.h"
  36. #include "charset.h"
  37.  
  38. #include "buffer.h"
  39. #include "keyboard.h"
  40. #include "intervals.h"
  41. #include "frame.h"
  42. #include "window.h"
  43. #if defined (HAVE_MENUS) && defined (HAVE_X_WINDOWS)
  44. # ifndef HAVE_PM
  45. # include "xterm.h"
  46. # else /* HAVE_PM */
  47. # include "pmterm.h"
  48. # endif /* HAVE_PM */
  49. #endif    /* HAVE_X_WINDOWS */
  50.  
  51. #ifndef NULL
  52. #define NULL (void *)0
  53. #endif
  54.  
  55. /* Nonzero enables use of dialog boxes for questions
  56.    asked by mouse commands.  */
  57. int use_dialog_box;
  58.  
  59. extern int minibuffer_auto_raise;
  60. extern Lisp_Object minibuf_window;
  61.  
  62. Lisp_Object Qstring_lessp, Qprovide, Qrequire;
  63. Lisp_Object Qyes_or_no_p_history;
  64. Lisp_Object Qcursor_in_echo_area;
  65. Lisp_Object Qwidget_type;
  66.  
  67. extern Lisp_Object Qinput_method_function;
  68.  
  69. static int internal_equal ();
  70.  
  71. extern long get_random ();
  72. extern void seed_random ();
  73.  
  74. #ifndef HAVE_UNISTD_H
  75. extern long time ();
  76. #endif
  77.  
  78. DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
  79.   "Return the argument unchanged.")
  80.   (arg)
  81.      Lisp_Object arg;
  82. {
  83.   return arg;
  84. }
  85.  
  86. DEFUN ("random", Frandom, Srandom, 0, 1, 0,
  87.   "Return a pseudo-random number.\n\
  88. All integers representable in Lisp are equally likely.\n\
  89.   On most systems, this is 28 bits' worth.\n\
  90. With positive integer argument N, return random number in interval [0,N).\n\
  91. With argument t, set the random number seed from the current time and pid.")
  92.   (n)
  93.      Lisp_Object n;
  94. {
  95.   EMACS_INT val;
  96.   Lisp_Object lispy_val;
  97.   unsigned long denominator;
  98.  
  99.   if (EQ (n, Qt))
  100.     seed_random (getpid () + time (NULL));
  101.   if (NATNUMP (n) && XFASTINT (n) != 0)
  102.     {
  103.       /* Try to take our random number from the higher bits of VAL,
  104.      not the lower, since (says Gentzel) the low bits of `random'
  105.      are less random than the higher ones.  We do this by using the
  106.      quotient rather than the remainder.  At the high end of the RNG
  107.      it's possible to get a quotient larger than n; discarding
  108.      these values eliminates the bias that would otherwise appear
  109.      when using a large n.  */
  110.       denominator = ((unsigned long)1 << VALBITS) / XFASTINT (n);
  111.       do
  112.     val = get_random () / denominator;
  113.       while (val >= XFASTINT (n));
  114.     }
  115.   else
  116.     val = get_random ();
  117.   XSETINT (lispy_val, val);
  118.   return lispy_val;
  119. }
  120.  
  121. /* Random data-structure functions */
  122.  
  123. DEFUN ("length", Flength, Slength, 1, 1, 0,
  124.   "Return the length of vector, list or string SEQUENCE.\n\
  125. A byte-code function object is also allowed.\n\
  126. If the string contains multibyte characters, this is not the necessarily\n\
  127. the number of bytes in the string; it is the number of characters.\n\
  128. To get the number of bytes, use `string-bytes'")
  129.   (sequence)
  130.      register Lisp_Object sequence;
  131. {
  132.   register Lisp_Object tail, val;
  133.   register int i;
  134.  
  135.  retry:
  136.   if (STRINGP (sequence))
  137.     XSETFASTINT (val, XSTRING (sequence)->size);
  138.   else if (VECTORP (sequence))
  139.     XSETFASTINT (val, XVECTOR (sequence)->size);
  140.   else if (CHAR_TABLE_P (sequence))
  141.     XSETFASTINT (val, (MIN_CHAR_COMPOSITION
  142.                + (CHAR_FIELD2_MASK | CHAR_FIELD3_MASK)
  143.                - 1));
  144.   else if (BOOL_VECTOR_P (sequence))
  145.     XSETFASTINT (val, XBOOL_VECTOR (sequence)->size);
  146.   else if (COMPILEDP (sequence))
  147.     XSETFASTINT (val, XVECTOR (sequence)->size & PSEUDOVECTOR_SIZE_MASK);
  148.   else if (CONSP (sequence))
  149.     {
  150.       for (i = 0, tail = sequence; !NILP (tail); i++)
  151.     {
  152.       QUIT;
  153.       tail = Fcdr (tail);
  154.     }
  155.  
  156.       XSETFASTINT (val, i);
  157.     }
  158.   else if (NILP (sequence))
  159.     XSETFASTINT (val, 0);
  160.   else
  161.     {
  162.       sequence = wrong_type_argument (Qsequencep, sequence);
  163.       goto retry;
  164.     }
  165.   return val;
  166. }
  167.  
  168. /* This does not check for quits.  That is safe
  169.    since it must terminate.  */
  170.  
  171. DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0,
  172.   "Return the length of a list, but avoid error or infinite loop.\n\
  173. This function never gets an error.  If LIST is not really a list,\n\
  174. it returns 0.  If LIST is circular, it returns a finite value\n\
  175. which is at least the number of distinct elements.")
  176.   (list)
  177.      Lisp_Object list;
  178. {
  179.   Lisp_Object tail, halftail, length;
  180.   int len = 0;
  181.  
  182.   /* halftail is used to detect circular lists.  */
  183.   halftail = list;
  184.   for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
  185.     {
  186.       if (EQ (tail, halftail) && len != 0)
  187.     break;
  188.       len++;
  189.       if ((len & 1) == 0)
  190.     halftail = XCONS (halftail)->cdr;
  191.     }
  192.  
  193.   XSETINT (length, len);
  194.   return length;
  195. }
  196.  
  197. DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
  198.   "Return the number of bytes in STRING.\n\
  199. If STRING is a multibyte string, this is greater than the length of STRING.")
  200.   (string)
  201.      Lisp_Object string;
  202. {
  203.   CHECK_STRING (string, 1);
  204.   return make_number (STRING_BYTES (XSTRING (string)));
  205. }
  206.  
  207. DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
  208.   "Return t if two strings have identical contents.\n\
  209. Case is significant, but text properties are ignored.\n\
  210. Symbols are also allowed; their print names are used instead.")
  211.   (s1, s2)
  212.      register Lisp_Object s1, s2;
  213. {
  214.   if (SYMBOLP (s1))
  215.     XSETSTRING (s1, XSYMBOL (s1)->name);
  216.   if (SYMBOLP (s2))
  217.     XSETSTRING (s2, XSYMBOL (s2)->name);
  218.   CHECK_STRING (s1, 0);
  219.   CHECK_STRING (s2, 1);
  220.  
  221.   if (XSTRING (s1)->size != XSTRING (s2)->size
  222.       || STRING_BYTES (XSTRING (s1)) != STRING_BYTES (XSTRING (s2))
  223.       || bcmp (XSTRING (s1)->data, XSTRING (s2)->data, STRING_BYTES (XSTRING (s1))))
  224.     return Qnil;
  225.   return Qt;
  226. }
  227.  
  228. DEFUN ("compare-strings", Fcompare_strings,
  229.        Scompare_strings, 6, 7, 0,
  230.   "Compare the contents of two strings, converting to multibyte if needed.\n\
  231. In string STR1, skip the first START1 characters and stop at END1.\n\
  232. In string STR2, skip the first START2 characters and stop at END2.\n\
  233. END1 and END2 default to the full lengths of the respective strings.\n\
  234. \n\
  235. Case is significant in this comparison if IGNORE-CASE is nil.\n\
  236. Unibyte strings are converted to multibyte for comparison.\n\
  237. \n\
  238. The value is t if the strings (or specified portions) match.\n\
  239. If string STR1 is less, the value is a negative number N;\n\
  240.   - 1 - N is the number of characters that match at the beginning.\n\
  241. If string STR1 is greater, the value is a positive number N;\n\
  242.   N - 1 is the number of characters that match at the beginning.")
  243.   (str1, start1, end1, str2, start2, end2, ignore_case)
  244.      Lisp_Object str1, start1, end1, start2, str2, end2, ignore_case;
  245. {
  246.   register int end1_char, end2_char;
  247.   register int i1, i1_byte, i2, i2_byte;
  248.  
  249.   CHECK_STRING (str1, 0);
  250.   CHECK_STRING (str2, 1);
  251.   if (NILP (start1))
  252.     start1 = make_number (0);
  253.   if (NILP (start2))
  254.     start2 = make_number (0);
  255.   CHECK_NATNUM (start1, 2);
  256.   CHECK_NATNUM (start2, 3);
  257.   if (! NILP (end1))
  258.     CHECK_NATNUM (end1, 4);
  259.   if (! NILP (end2))
  260.     CHECK_NATNUM (end2, 4);
  261.  
  262.   i1 = XINT (start1);
  263.   i2 = XINT (start2);
  264.  
  265.   i1_byte = string_char_to_byte (str1, i1);
  266.   i2_byte = string_char_to_byte (str2, i2);
  267.  
  268.   end1_char = XSTRING (str1)->size;
  269.   if (! NILP (end1) && end1_char > XINT (end1))
  270.     end1_char = XINT (end1);
  271.  
  272.   end2_char = XSTRING (str2)->size;
  273.   if (! NILP (end2) && end2_char > XINT (end2))
  274.     end2_char = XINT (end2);
  275.  
  276.   while (i1 < end1_char && i2 < end2_char)
  277.     {
  278.       /* When we find a mismatch, we must compare the
  279.      characters, not just the bytes.  */
  280.       int c1, c2;
  281.  
  282.       if (STRING_MULTIBYTE (str1))
  283.     FETCH_STRING_CHAR_ADVANCE (c1, str1, i1, i1_byte);
  284.       else
  285.     {
  286.       c1 = XSTRING (str1)->data[i1++];
  287.       c1 = unibyte_char_to_multibyte (c1);
  288.     }
  289.  
  290.       if (STRING_MULTIBYTE (str2))
  291.     FETCH_STRING_CHAR_ADVANCE (c2, str2, i2, i2_byte);
  292.       else
  293.     {
  294.       c2 = XSTRING (str2)->data[i2++];
  295.       c2 = unibyte_char_to_multibyte (c2);
  296.     }
  297.  
  298.       if (c1 == c2)
  299.     continue;
  300.  
  301.       if (! NILP (ignore_case))
  302.     {
  303.       Lisp_Object tem;
  304.  
  305.       tem = Fupcase (make_number (c1));
  306.       c1 = XINT (tem);
  307.       tem = Fupcase (make_number (c2));
  308.       c2 = XINT (tem);
  309.     }
  310.  
  311.       if (c1 == c2)
  312.     continue;
  313.  
  314.       /* Note that I1 has already been incremented
  315.      past the character that we are comparing;
  316.      hence we don't add or subtract 1 here.  */
  317.       if (c1 < c2)
  318.     return make_number (- i1);
  319.       else
  320.     return make_number (i1);
  321.     }
  322.  
  323.   if (i1 < end1_char)
  324.     return make_number (i1 - XINT (start1) + 1);
  325.   if (i2 < end2_char)
  326.     return make_number (- i1 + XINT (start1) - 1);
  327.  
  328.   return Qt;
  329. }
  330.  
  331. DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
  332.   "Return t if first arg string is less than second in lexicographic order.\n\
  333. Case is significant.\n\
  334. Symbols are also allowed; their print names are used instead.")
  335.   (s1, s2)
  336.      register Lisp_Object s1, s2;
  337. {
  338.   register int end;
  339.   register int i1, i1_byte, i2, i2_byte;
  340.  
  341.   if (SYMBOLP (s1))
  342.     XSETSTRING (s1, XSYMBOL (s1)->name);
  343.   if (SYMBOLP (s2))
  344.     XSETSTRING (s2, XSYMBOL (s2)->name);
  345.   CHECK_STRING (s1, 0);
  346.   CHECK_STRING (s2, 1);
  347.  
  348.   i1 = i1_byte = i2 = i2_byte = 0;
  349.  
  350.   end = XSTRING (s1)->size;
  351.   if (end > XSTRING (s2)->size)
  352.     end = XSTRING (s2)->size;
  353.  
  354.   while (i1 < end)
  355.     {
  356.       /* When we find a mismatch, we must compare the
  357.      characters, not just the bytes.  */
  358.       int c1, c2;
  359.  
  360.       if (STRING_MULTIBYTE (s1))
  361.     FETCH_STRING_CHAR_ADVANCE (c1, s1, i1, i1_byte);
  362.       else
  363.     c1 = XSTRING (s1)->data[i1++];
  364.  
  365.       if (STRING_MULTIBYTE (s2))
  366.     FETCH_STRING_CHAR_ADVANCE (c2, s2, i2, i2_byte);
  367.       else
  368.     c2 = XSTRING (s2)->data[i2++];
  369.  
  370.       if (c1 != c2)
  371.     return c1 < c2 ? Qt : Qnil;
  372.     }
  373.   return i1 < XSTRING (s2)->size ? Qt : Qnil;
  374. }
  375.  
  376. static Lisp_Object concat ();
  377.  
  378. /* ARGSUSED */
  379. Lisp_Object
  380. concat2 (s1, s2)
  381.      Lisp_Object s1, s2;
  382. {
  383. #ifdef NO_ARG_ARRAY
  384.   Lisp_Object args[2];
  385.   args[0] = s1;
  386.   args[1] = s2;
  387.   return concat (2, args, Lisp_String, 0);
  388. #else
  389.   return concat (2, &s1, Lisp_String, 0);
  390. #endif /* NO_ARG_ARRAY */
  391. }
  392.  
  393. /* ARGSUSED */
  394. Lisp_Object
  395. concat3 (s1, s2, s3)
  396.      Lisp_Object s1, s2, s3;
  397. {
  398. #ifdef NO_ARG_ARRAY
  399.   Lisp_Object args[3];
  400.   args[0] = s1;
  401.   args[1] = s2;
  402.   args[2] = s3;
  403.   return concat (3, args, Lisp_String, 0);
  404. #else
  405.   return concat (3, &s1, Lisp_String, 0);
  406. #endif /* NO_ARG_ARRAY */
  407. }
  408.  
  409. DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
  410.   "Concatenate all the arguments and make the result a list.\n\
  411. The result is a list whose elements are the elements of all the arguments.\n\
  412. Each argument may be a list, vector or string.\n\
  413. The last argument is not copied, just used as the tail of the new list.")
  414.   (nargs, args)
  415.      int nargs;
  416.      Lisp_Object *args;
  417. {
  418.   return concat (nargs, args, Lisp_Cons, 1);
  419. }
  420.  
  421. DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
  422.   "Concatenate all the arguments and make the result a string.\n\
  423. The result is a string whose elements are the elements of all the arguments.\n\
  424. Each argument may be a string or a list or vector of characters (integers).\n\
  425. \n\
  426. Do not use individual integers as arguments!\n\
  427. The behavior of `concat' in that case will be changed later!\n\
  428. If your program passes an integer as an argument to `concat',\n\
  429. you should change it right away not to do so.")
  430.   (nargs, args)
  431.      int nargs;
  432.      Lisp_Object *args;
  433. {
  434.   return concat (nargs, args, Lisp_String, 0);
  435. }
  436.  
  437. DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
  438.   "Concatenate all the arguments and make the result a vector.\n\
  439. The result is a vector whose elements are the elements of all the arguments.\n\
  440. Each argument may be a list, vector or string.")
  441.   (nargs, args)
  442.      int nargs;
  443.      Lisp_Object *args;
  444. {
  445.   return concat (nargs, args, Lisp_Vectorlike, 0);
  446. }
  447.  
  448. /* Retrun a copy of a sub char table ARG.  The elements except for a
  449.    nested sub char table are not copied.  */
  450. static Lisp_Object
  451. copy_sub_char_table (arg)
  452.      Lisp_Object arg;
  453. {
  454.   Lisp_Object copy = make_sub_char_table (XCHAR_TABLE (arg)->defalt);
  455.   int i;
  456.  
  457.   /* Copy all the contents.  */
  458.   bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
  459.      SUB_CHAR_TABLE_ORDINARY_SLOTS * sizeof (Lisp_Object));
  460.   /* Recursively copy any sub char-tables in the ordinary slots.  */
  461.   for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
  462.     if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
  463.       XCHAR_TABLE (copy)->contents[i]
  464.     = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
  465.  
  466.   return copy;
  467. }
  468.  
  469.  
  470. DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
  471.   "Return a copy of a list, vector or string.\n\
  472. The elements of a list or vector are not copied; they are shared\n\
  473. with the original.")
  474.   (arg)
  475.      Lisp_Object arg;
  476. {
  477.   if (NILP (arg)) return arg;
  478.  
  479.   if (CHAR_TABLE_P (arg))
  480.     {
  481.       int i;
  482.       Lisp_Object copy;
  483.  
  484.       copy = Fmake_char_table (XCHAR_TABLE (arg)->purpose, Qnil);
  485.       /* Copy all the slots, including the extra ones.  */
  486.       bcopy (XVECTOR (arg)->contents, XVECTOR (copy)->contents,
  487.          ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK)
  488.           * sizeof (Lisp_Object)));
  489.  
  490.       /* Recursively copy any sub char tables in the ordinary slots
  491.          for multibyte characters.  */
  492.       for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS;
  493.        i < CHAR_TABLE_ORDINARY_SLOTS; i++)
  494.     if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
  495.       XCHAR_TABLE (copy)->contents[i]
  496.         = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
  497.  
  498.       return copy;
  499.     }
  500.  
  501.   if (BOOL_VECTOR_P (arg))
  502.     {
  503.       Lisp_Object val;
  504.       int size_in_chars
  505.     = (XBOOL_VECTOR (arg)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
  506.  
  507.       val = Fmake_bool_vector (Flength (arg), Qnil);
  508.       bcopy (XBOOL_VECTOR (arg)->data, XBOOL_VECTOR (val)->data,
  509.          size_in_chars);
  510.       return val;
  511.     }
  512.  
  513.   if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg))
  514.     arg = wrong_type_argument (Qsequencep, arg);
  515.   return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
  516. }
  517.  
  518. static Lisp_Object
  519. concat (nargs, args, target_type, last_special)
  520.      int nargs;
  521.      Lisp_Object *args;
  522.      enum Lisp_Type target_type;
  523.      int last_special;
  524. {
  525.   Lisp_Object val;
  526.   register Lisp_Object tail;
  527.   register Lisp_Object this;
  528.   int toindex;
  529.   int toindex_byte;
  530.   register int result_len;
  531.   register int result_len_byte;
  532.   register int argnum;
  533.   Lisp_Object last_tail;
  534.   Lisp_Object prev;
  535.   int some_multibyte;
  536.   /* When we make a multibyte string, we must pay attention to the
  537.      byte combining problem, i.e., a byte may be combined with a
  538.      multibyte charcter of the previous string.  This flag tells if we
  539.      must consider such a situation or not.  */
  540.   int maybe_combine_byte;
  541.  
  542.   /* In append, the last arg isn't treated like the others */
  543.   if (last_special && nargs > 0)
  544.     {
  545.       nargs--;
  546.       last_tail = args[nargs];
  547.     }
  548.   else
  549.     last_tail = Qnil;
  550.  
  551.   /* Canonicalize each argument.  */
  552.   for (argnum = 0; argnum < nargs; argnum++)
  553.     {
  554.       this = args[argnum];
  555.       if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
  556.         || COMPILEDP (this) || BOOL_VECTOR_P (this)))
  557.     {
  558.       if (INTEGERP (this))
  559.             args[argnum] = Fnumber_to_string (this);
  560.       else
  561.         args[argnum] = wrong_type_argument (Qsequencep, this);
  562.     }
  563.     }
  564.  
  565.   /* Compute total length in chars of arguments in RESULT_LEN.
  566.      If desired output is a string, also compute length in bytes
  567.      in RESULT_LEN_BYTE, and determine in SOME_MULTIBYTE
  568.      whether the result should be a multibyte string.  */
  569.   result_len_byte = 0;
  570.   result_len = 0;
  571.   some_multibyte = 0;
  572.   for (argnum = 0; argnum < nargs; argnum++)
  573.     {
  574.       int len;
  575.       this = args[argnum];
  576.       len = XFASTINT (Flength (this));
  577.       if (target_type == Lisp_String)
  578.     {
  579.       /* We must count the number of bytes needed in the string
  580.          as well as the number of characters.  */
  581.       int i;
  582.       Lisp_Object ch;
  583.       int this_len_byte;
  584.  
  585.       if (VECTORP (this))
  586.         for (i = 0; i < len; i++)
  587.           {
  588.         ch = XVECTOR (this)->contents[i];
  589.         if (! INTEGERP (ch))
  590.           wrong_type_argument (Qintegerp, ch);
  591.         this_len_byte = XFASTINT (Fchar_bytes (ch));
  592.         result_len_byte += this_len_byte;
  593.         if (this_len_byte > 1)
  594.           some_multibyte = 1;
  595.           }
  596.       else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0)
  597.         wrong_type_argument (Qintegerp, Faref (this, make_number (0)));
  598.       else if (CONSP (this))
  599.         for (; CONSP (this); this = XCONS (this)->cdr)
  600.           {
  601.         ch = XCONS (this)->car;
  602.         if (! INTEGERP (ch))
  603.           wrong_type_argument (Qintegerp, ch);
  604.         this_len_byte = XFASTINT (Fchar_bytes (ch));
  605.         result_len_byte += this_len_byte;
  606.         if (this_len_byte > 1)
  607.           some_multibyte = 1;
  608.           }
  609.       else if (STRINGP (this))
  610.         {
  611.           if (STRING_MULTIBYTE (this))
  612.         {
  613.           some_multibyte = 1;
  614.           result_len_byte += STRING_BYTES (XSTRING (this));
  615.         }
  616.           else
  617.         result_len_byte += count_size_as_multibyte (XSTRING (this)->data,
  618.                                 XSTRING (this)->size);
  619.         }
  620.     }
  621.  
  622.       result_len += len;
  623.     }
  624.  
  625.   if (! some_multibyte)
  626.     result_len_byte = result_len;
  627.  
  628.   /* Create the output object.  */
  629.   if (target_type == Lisp_Cons)
  630.     val = Fmake_list (make_number (result_len), Qnil);
  631.   else if (target_type == Lisp_Vectorlike)
  632.     val = Fmake_vector (make_number (result_len), Qnil);
  633.   else if (some_multibyte)
  634.     val = make_uninit_multibyte_string (result_len, result_len_byte);
  635.   else
  636.     val = make_uninit_string (result_len);
  637.  
  638.   /* In `append', if all but last arg are nil, return last arg.  */
  639.   if (target_type == Lisp_Cons && EQ (val, Qnil))
  640.     return last_tail;
  641.  
  642.   /* Copy the contents of the args into the result.  */
  643.   if (CONSP (val))
  644.     tail = val, toindex = -1;        /* -1 in toindex is flag we are making a list */
  645.   else
  646.     toindex = 0, toindex_byte = 0;
  647.  
  648.   prev = Qnil;
  649.  
  650.   maybe_combine_byte = 0;
  651.   for (argnum = 0; argnum < nargs; argnum++)
  652.     {
  653.       Lisp_Object thislen;
  654.       int thisleni;
  655.       register unsigned int thisindex = 0;
  656.       register unsigned int thisindex_byte = 0;
  657.  
  658.       this = args[argnum];
  659.       if (!CONSP (this))
  660.     thislen = Flength (this), thisleni = XINT (thislen);
  661.  
  662.       if (STRINGP (this) && STRINGP (val)
  663.       && ! NULL_INTERVAL_P (XSTRING (this)->intervals))
  664.     copy_text_properties (make_number (0), thislen, this,
  665.                   make_number (toindex), val, Qnil);
  666.  
  667.       /* Between strings of the same kind, copy fast.  */
  668.       if (STRINGP (this) && STRINGP (val)
  669.       && STRING_MULTIBYTE (this) == some_multibyte)
  670.     {
  671.       int thislen_byte = STRING_BYTES (XSTRING (this));
  672.       bcopy (XSTRING (this)->data, XSTRING (val)->data + toindex_byte,
  673.          STRING_BYTES (XSTRING (this)));
  674.       if (some_multibyte
  675.           && toindex_byte > 0
  676.           && !ASCII_BYTE_P (XSTRING (val)->data[toindex_byte - 1])
  677.           && !CHAR_HEAD_P (XSTRING (this)->data[0]))
  678.         maybe_combine_byte = 1;
  679.       toindex_byte += thislen_byte;
  680.       toindex += thisleni;
  681.     }
  682.       /* Copy a single-byte string to a multibyte string.  */
  683.       else if (STRINGP (this) && STRINGP (val))
  684.     {
  685.       toindex_byte += copy_text (XSTRING (this)->data,
  686.                      XSTRING (val)->data + toindex_byte,
  687.                      XSTRING (this)->size, 0, 1);
  688.       toindex += thisleni;
  689.     }
  690.       else
  691.     /* Copy element by element.  */
  692.     while (1)
  693.       {
  694.         register Lisp_Object elt;
  695.  
  696.         /* Fetch next element of `this' arg into `elt', or break if
  697.            `this' is exhausted. */
  698.         if (NILP (this)) break;
  699.         if (CONSP (this))
  700.           elt = XCONS (this)->car, this = XCONS (this)->cdr;
  701.         else if (thisindex >= thisleni)
  702.           break;
  703.         else if (STRINGP (this))
  704.           {
  705.         int c;
  706.         if (STRING_MULTIBYTE (this))
  707.           {
  708.             FETCH_STRING_CHAR_ADVANCE (c, this,
  709.                            thisindex,
  710.                            thisindex_byte);
  711.             XSETFASTINT (elt, c);
  712.           }
  713.         else
  714.           {
  715.             XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
  716.             if (some_multibyte && XINT (elt) >= 0200
  717.             && XINT (elt) < 0400)
  718.               {
  719.             c = unibyte_char_to_multibyte (XINT (elt));
  720.             XSETINT (elt, c);
  721.               }
  722.           }
  723.           }
  724.         else if (BOOL_VECTOR_P (this))
  725.           {
  726.         int byte;
  727.         byte = XBOOL_VECTOR (this)->data[thisindex / BITS_PER_CHAR];
  728.         if (byte & (1 << (thisindex % BITS_PER_CHAR)))
  729.           elt = Qt;
  730.         else
  731.           elt = Qnil;
  732.         thisindex++;
  733.           }
  734.         else
  735.           elt = XVECTOR (this)->contents[thisindex++];
  736.  
  737.         /* Store this element into the result.  */
  738.         if (toindex < 0)
  739.           {
  740.         XCONS (tail)->car = elt;
  741.         prev = tail;
  742.         tail = XCONS (tail)->cdr;
  743.           }
  744.         else if (VECTORP (val))
  745.           XVECTOR (val)->contents[toindex++] = elt;
  746.         else
  747.           {
  748.         CHECK_NUMBER (elt, 0);
  749.         if (SINGLE_BYTE_CHAR_P (XINT (elt)))
  750.           {
  751.             if (some_multibyte
  752.             && toindex_byte > 0
  753.             && !ASCII_BYTE_P (XSTRING (val)->data[toindex_byte - 1])
  754.             && !CHAR_HEAD_P (XINT (elt)))
  755.               maybe_combine_byte = 1;
  756.             XSTRING (val)->data[toindex_byte++] = XINT (elt);
  757.             toindex++;
  758.           }
  759.         else
  760.           /* If we have any multibyte characters,
  761.              we already decided to make a multibyte string.  */
  762.           {
  763.             int c = XINT (elt);
  764.             unsigned char work[4], *str;
  765.             int i = CHAR_STRING (c, work, str);
  766.  
  767.             /* P exists as a variable
  768.                to avoid a bug on the Masscomp C compiler.  */
  769.             unsigned char *p = & XSTRING (val)->data[toindex_byte];
  770.             bcopy (str, p, i);
  771.             toindex_byte += i;
  772.             toindex++;
  773.           }
  774.           }
  775.       }
  776.     }
  777.   if (!NILP (prev))
  778.     XCONS (prev)->cdr = last_tail;
  779.  
  780.   if (maybe_combine_byte)
  781.     /* Character counter of the multibyte string VAL may be wrong
  782.        because of byte combining problem.  We must re-calculate it.  */
  783.     XSTRING (val)->size = multibyte_chars_in_text (XSTRING (val)->data,
  784.                            XSTRING (val)->size_byte);
  785.  
  786.   return val;
  787. }
  788.  
  789. static Lisp_Object string_char_byte_cache_string;
  790. static int string_char_byte_cache_charpos;
  791. static int string_char_byte_cache_bytepos;
  792.  
  793. /* Return the character index corresponding to CHAR_INDEX in STRING.  */
  794.  
  795. int
  796. string_char_to_byte (string, char_index)
  797.      Lisp_Object string;
  798.      int char_index;
  799. {
  800.   int i, i_byte;
  801.   int best_below, best_below_byte;
  802.   int best_above, best_above_byte;
  803.  
  804.   if (! STRING_MULTIBYTE (string))
  805.     return char_index;
  806.  
  807.   best_below = best_below_byte = 0;
  808.   best_above = XSTRING (string)->size;
  809.   best_above_byte = STRING_BYTES (XSTRING (string));
  810.  
  811.   if (EQ (string, string_char_byte_cache_string))
  812.     {
  813.       if (string_char_byte_cache_charpos < char_index)
  814.     {
  815.       best_below = string_char_byte_cache_charpos;
  816.       best_below_byte = string_char_byte_cache_bytepos;
  817.     }
  818.       else
  819.     {
  820.       best_above = string_char_byte_cache_charpos;
  821.       best_above_byte = string_char_byte_cache_bytepos;
  822.     }
  823.     }
  824.  
  825.   if (char_index - best_below < best_above - char_index)
  826.     {
  827.       while (best_below < char_index)
  828.     {
  829.       int c;
  830.       FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte);
  831.     }
  832.       i = best_below;
  833.       i_byte = best_below_byte;
  834.     }
  835.   else
  836.     {
  837.       while (best_above > char_index)
  838.     {
  839.       int best_above_byte_saved = --best_above_byte;
  840.  
  841.       while (best_above_byte > 0
  842.          && !CHAR_HEAD_P (XSTRING (string)->data[best_above_byte]))
  843.         best_above_byte--;
  844.       if (XSTRING (string)->data[best_above_byte] < 0x80)
  845.         best_above_byte = best_above_byte_saved;
  846.       best_above--;
  847.     }
  848.       i = best_above;
  849.       i_byte = best_above_byte;
  850.     }
  851.  
  852.   string_char_byte_cache_bytepos = i_byte;
  853.   string_char_byte_cache_charpos = i;
  854.   string_char_byte_cache_string = string;
  855.  
  856.   return i_byte;
  857. }
  858.  
  859. /* Return the character index corresponding to BYTE_INDEX in STRING.  */
  860.  
  861. int
  862. string_byte_to_char (string, byte_index)
  863.      Lisp_Object string;
  864.      int byte_index;
  865. {
  866.   int i, i_byte;
  867.   int best_below, best_below_byte;
  868.   int best_above, best_above_byte;
  869.  
  870.   if (! STRING_MULTIBYTE (string))
  871.     return byte_index;
  872.  
  873.   best_below = best_below_byte = 0;
  874.   best_above = XSTRING (string)->size;
  875.   best_above_byte = STRING_BYTES (XSTRING (string));
  876.  
  877.   if (EQ (string, string_char_byte_cache_string))
  878.     {
  879.       if (string_char_byte_cache_bytepos < byte_index)
  880.     {
  881.       best_below = string_char_byte_cache_charpos;
  882.       best_below_byte = string_char_byte_cache_bytepos;
  883.     }
  884.       else
  885.     {
  886.       best_above = string_char_byte_cache_charpos;
  887.       best_above_byte = string_char_byte_cache_bytepos;
  888.     }
  889.     }
  890.  
  891.   if (byte_index - best_below_byte < best_above_byte - byte_index)
  892.     {
  893.       while (best_below_byte < byte_index)
  894.     {
  895.       int c;
  896.       FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte);
  897.     }
  898.       i = best_below;
  899.       i_byte = best_below_byte;
  900.     }
  901.   else
  902.     {
  903.       while (best_above_byte > byte_index)
  904.     {
  905.       int best_above_byte_saved = --best_above_byte;
  906.  
  907.       while (best_above_byte > 0
  908.          && !CHAR_HEAD_P (XSTRING (string)->data[best_above_byte]))
  909.         best_above_byte--;
  910.       if (XSTRING (string)->data[best_above_byte] < 0x80)
  911.         best_above_byte = best_above_byte_saved;
  912.       best_above--;
  913.     }
  914.       i = best_above;
  915.       i_byte = best_above_byte;
  916.     }
  917.  
  918.   string_char_byte_cache_bytepos = i_byte;
  919.   string_char_byte_cache_charpos = i;
  920.   string_char_byte_cache_string = string;
  921.  
  922.   return i;
  923. }
  924.  
  925. /* Convert STRING to a multibyte string.
  926.    Single-byte characters 0240 through 0377 are converted
  927.    by adding nonascii_insert_offset to each.  */
  928.  
  929. Lisp_Object
  930. string_make_multibyte (string)
  931.      Lisp_Object string;
  932. {
  933.   unsigned char *buf;
  934.   int nbytes;
  935.  
  936.   if (STRING_MULTIBYTE (string))
  937.     return string;
  938.  
  939.   nbytes = count_size_as_multibyte (XSTRING (string)->data,
  940.                     XSTRING (string)->size);
  941.   /* If all the chars are ASCII, they won't need any more bytes
  942.      once converted.  In that case, we can return STRING itself.  */
  943.   if (nbytes == STRING_BYTES (XSTRING (string)))
  944.     return string;
  945.  
  946.   buf = (unsigned char *) alloca (nbytes);
  947.   copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
  948.          0, 1);
  949.  
  950.   return make_multibyte_string (buf, XSTRING (string)->size, nbytes);
  951. }
  952.  
  953. /* Convert STRING to a single-byte string.  */
  954.  
  955. Lisp_Object
  956. string_make_unibyte (string)
  957.      Lisp_Object string;
  958. {
  959.   unsigned char *buf;
  960.  
  961.   if (! STRING_MULTIBYTE (string))
  962.     return string;
  963.  
  964.   buf = (unsigned char *) alloca (XSTRING (string)->size);
  965.  
  966.   copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
  967.          1, 0);
  968.  
  969.   return make_unibyte_string (buf, XSTRING (string)->size);
  970. }
  971.  
  972. DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
  973.        1, 1, 0,
  974.   "Return the multibyte equivalent of STRING.\n\
  975. The function `unibyte-char-to-multibyte' is used to convert\n\
  976. each unibyte character to a multibyte character.")
  977.   (string)
  978.      Lisp_Object string;
  979. {
  980.   CHECK_STRING (string, 0);
  981.  
  982.   return string_make_multibyte (string);
  983. }
  984.  
  985. DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
  986.        1, 1, 0,
  987.   "Return the unibyte equivalent of STRING.\n\
  988. Multibyte character codes are converted to unibyte\n\
  989. by using just the low 8 bits.")
  990.   (string)
  991.      Lisp_Object string;
  992. {
  993.   CHECK_STRING (string, 0);
  994.  
  995.   return string_make_unibyte (string);
  996. }
  997.  
  998. DEFUN ("string-as-unibyte", Fstring_as_unibyte, Sstring_as_unibyte,
  999.        1, 1, 0,
  1000.   "Return a unibyte string with the same individual bytes as STRING.\n\
  1001. If STRING is unibyte, the result is STRING itself.")
  1002.   (string)
  1003.      Lisp_Object string;
  1004. {
  1005.   CHECK_STRING (string, 0);
  1006.  
  1007.   if (STRING_MULTIBYTE (string))
  1008.     {
  1009.       string = Fcopy_sequence (string);
  1010.       XSTRING (string)->size = STRING_BYTES (XSTRING (string));
  1011.       SET_STRING_BYTES (XSTRING (string), -1);
  1012.     }
  1013.   return string;
  1014. }
  1015.  
  1016. DEFUN ("string-as-multibyte", Fstring_as_multibyte, Sstring_as_multibyte,
  1017.        1, 1, 0,
  1018.   "Return a multibyte string with the same individual bytes as STRING.\n\
  1019. If STRING is multibyte, the result is STRING itself.")
  1020.   (string)
  1021.      Lisp_Object string;
  1022. {
  1023.   CHECK_STRING (string, 0);
  1024.  
  1025.   if (! STRING_MULTIBYTE (string))
  1026.     {
  1027.       int nbytes = STRING_BYTES (XSTRING (string));
  1028.       int newlen = multibyte_chars_in_text (XSTRING (string)->data, nbytes);
  1029.  
  1030.       string = Fcopy_sequence (string);
  1031.       XSTRING (string)->size = newlen;
  1032.       XSTRING (string)->size_byte = nbytes;
  1033.     }
  1034.   return string;
  1035. }
  1036.  
  1037. DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
  1038.   "Return a copy of ALIST.\n\
  1039. This is an alist which represents the same mapping from objects to objects,\n\
  1040. but does not share the alist structure with ALIST.\n\
  1041. The objects mapped (cars and cdrs of elements of the alist)\n\
  1042. are shared, however.\n\
  1043. Elements of ALIST that are not conses are also shared.")
  1044.   (alist)
  1045.      Lisp_Object alist;
  1046. {
  1047.   register Lisp_Object tem;
  1048.  
  1049.   CHECK_LIST (alist, 0);
  1050.   if (NILP (alist))
  1051.     return alist;
  1052.   alist = concat (1, &alist, Lisp_Cons, 0);
  1053.   for (tem = alist; CONSP (tem); tem = XCONS (tem)->cdr)
  1054.     {
  1055.       register Lisp_Object car;
  1056.       car = XCONS (tem)->car;
  1057.  
  1058.       if (CONSP (car))
  1059.     XCONS (tem)->car = Fcons (XCONS (car)->car, XCONS (car)->cdr);
  1060.     }
  1061.   return alist;
  1062. }
  1063.  
  1064. DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
  1065.   "Return a substring of STRING, starting at index FROM and ending before TO.\n\
  1066. TO may be nil or omitted; then the substring runs to the end of STRING.\n\
  1067. If FROM or TO is negative, it counts from the end.\n\
  1068. \n\
  1069. This function allows vectors as well as strings.")
  1070.   (string, from, to)
  1071.      Lisp_Object string;
  1072.      register Lisp_Object from, to;
  1073. {
  1074.   Lisp_Object res;
  1075.   int size;
  1076.   int size_byte;
  1077.   int from_char, to_char;
  1078.   int from_byte, to_byte;
  1079.  
  1080.   if (! (STRINGP (string) || VECTORP (string)))
  1081.     wrong_type_argument (Qarrayp, string);
  1082.  
  1083.   CHECK_NUMBER (from, 1);
  1084.  
  1085.   if (STRINGP (string))
  1086.     {
  1087.       size = XSTRING (string)->size;
  1088.       size_byte = STRING_BYTES (XSTRING (string));
  1089.     }
  1090.   else
  1091.     size = XVECTOR (string)->size;
  1092.  
  1093.   if (NILP (to))
  1094.     {
  1095.       to_char = size;
  1096.       to_byte = size_byte;
  1097.     }
  1098.   else
  1099.     {
  1100.       CHECK_NUMBER (to, 2);
  1101.  
  1102.       to_char = XINT (to);
  1103.       if (to_char < 0)
  1104.     to_char += size;
  1105.  
  1106.       if (STRINGP (string))
  1107.     to_byte = string_char_to_byte (string, to_char);
  1108.     }
  1109.  
  1110.   from_char = XINT (from);
  1111.   if (from_char < 0)
  1112.     from_char += size;
  1113.   if (STRINGP (string))
  1114.     from_byte = string_char_to_byte (string, from_char);
  1115.  
  1116.   if (!(0 <= from_char && from_char <= to_char && to_char <= size))
  1117.     args_out_of_range_3 (string, make_number (from_char),
  1118.              make_number (to_char));
  1119.  
  1120.   if (STRINGP (string))
  1121.     {
  1122.       res = make_specified_string (XSTRING (string)->data + from_byte,
  1123.                    to_char - from_char, to_byte - from_byte,
  1124.                    STRING_MULTIBYTE (string));
  1125.       copy_text_properties (make_number (from_char), make_number (to_char),
  1126.                 string, make_number (0), res, Qnil);
  1127.     }
  1128.   else
  1129.     res = Fvector (to_char - from_char,
  1130.            XVECTOR (string)->contents + from_char);
  1131.  
  1132.   return res;
  1133. }
  1134.  
  1135. /* Extract a substring of STRING, giving start and end positions
  1136.    both in characters and in bytes.  */
  1137.  
  1138. Lisp_Object
  1139. substring_both (string, from, from_byte, to, to_byte)
  1140.      Lisp_Object string;
  1141.      int from, from_byte, to, to_byte;
  1142. {
  1143.   Lisp_Object res;
  1144.   int size;
  1145.   int size_byte;
  1146.  
  1147.   if (! (STRINGP (string) || VECTORP (string)))
  1148.     wrong_type_argument (Qarrayp, string);
  1149.  
  1150.   if (STRINGP (string))
  1151.     {
  1152.       size = XSTRING (string)->size;
  1153.       size_byte = STRING_BYTES (XSTRING (string));
  1154.     }
  1155.   else
  1156.     size = XVECTOR (string)->size;
  1157.  
  1158.   if (!(0 <= from && from <= to && to <= size))
  1159.     args_out_of_range_3 (string, make_number (from), make_number (to));
  1160.  
  1161.   if (STRINGP (string))
  1162.     {
  1163.       res = make_specified_string (XSTRING (string)->data + from_byte,
  1164.                    to - from, to_byte - from_byte,
  1165.                    STRING_MULTIBYTE (string));
  1166.       copy_text_properties (make_number (from), make_number (to),
  1167.                 string, make_number (0), res, Qnil);
  1168.     }
  1169.   else
  1170.     res = Fvector (to - from,
  1171.            XVECTOR (string)->contents + from);
  1172.  
  1173.   return res;
  1174. }
  1175.  
  1176. DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
  1177.   "Take cdr N times on LIST, returns the result.")
  1178.   (n, list)
  1179.      Lisp_Object n;
  1180.      register Lisp_Object list;
  1181. {
  1182.   register int i, num;
  1183.   CHECK_NUMBER (n, 0);
  1184.   num = XINT (n);
  1185.   for (i = 0; i < num && !NILP (list); i++)
  1186.     {
  1187.       QUIT;
  1188.       list = Fcdr (list);
  1189.     }
  1190.   return list;
  1191. }
  1192.  
  1193. DEFUN ("nth", Fnth, Snth, 2, 2, 0,
  1194.   "Return the Nth element of LIST.\n\
  1195. N counts from zero.  If LIST is not that long, nil is returned.")
  1196.   (n, list)
  1197.      Lisp_Object n, list;
  1198. {
  1199.   return Fcar (Fnthcdr (n, list));
  1200. }
  1201.  
  1202. DEFUN ("elt", Felt, Selt, 2, 2, 0,
  1203.   "Return element of SEQUENCE at index N.")
  1204.   (sequence, n)
  1205.      register Lisp_Object sequence, n;
  1206. {
  1207.   CHECK_NUMBER (n, 0);
  1208.   while (1)
  1209.     {
  1210.       if (CONSP (sequence) || NILP (sequence))
  1211.     return Fcar (Fnthcdr (n, sequence));
  1212.       else if (STRINGP (sequence) || VECTORP (sequence)
  1213.            || BOOL_VECTOR_P (sequence) || CHAR_TABLE_P (sequence))
  1214.     return Faref (sequence, n);
  1215.       else
  1216.     sequence = wrong_type_argument (Qsequencep, sequence);
  1217.     }
  1218. }
  1219.  
  1220. DEFUN ("member", Fmember, Smember, 2, 2, 0,
  1221.   "Return non-nil if ELT is an element of LIST.  Comparison done with `equal'.\n\
  1222. The value is actually the tail of LIST whose car is ELT.")
  1223.   (elt, list)
  1224.      register Lisp_Object elt;
  1225.      Lisp_Object list;
  1226. {
  1227.   register Lisp_Object tail;
  1228.   for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
  1229.     {
  1230.       register Lisp_Object tem;
  1231.       tem = Fcar (tail);
  1232.       if (! NILP (Fequal (elt, tem)))
  1233.     return tail;
  1234.       QUIT;
  1235.     }
  1236.   return Qnil;
  1237. }
  1238.  
  1239. DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
  1240.   "Return non-nil if ELT is an element of LIST.  Comparison done with EQ.\n\
  1241. The value is actually the tail of LIST whose car is ELT.")
  1242.   (elt, list)
  1243.      register Lisp_Object elt;
  1244.      Lisp_Object list;
  1245. {
  1246.   register Lisp_Object tail;
  1247.   for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
  1248.     {
  1249.       register Lisp_Object tem;
  1250.       tem = Fcar (tail);
  1251.       if (EQ (elt, tem)) return tail;
  1252.       QUIT;
  1253.     }
  1254.   return Qnil;
  1255. }
  1256.  
  1257. DEFUN ("assq", Fassq, Sassq, 2, 2, 0,
  1258.   "Return non-nil if KEY is `eq' to the car of an element of LIST.\n\
  1259. The value is actually the element of LIST whose car is KEY.\n\
  1260. Elements of LIST that are not conses are ignored.")
  1261.   (key, list)
  1262.      register Lisp_Object key;
  1263.      Lisp_Object list;
  1264. {
  1265.   register Lisp_Object tail;
  1266.   for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
  1267.     {
  1268.       register Lisp_Object elt, tem;
  1269.       elt = Fcar (tail);
  1270.       if (!CONSP (elt)) continue;
  1271.       tem = XCONS (elt)->car;
  1272.       if (EQ (key, tem)) return elt;
  1273.       QUIT;
  1274.     }
  1275.   return Qnil;
  1276. }
  1277.  
  1278. /* Like Fassq but never report an error and do not allow quits.
  1279.    Use only on lists known never to be circular.  */
  1280.  
  1281. Lisp_Object
  1282. assq_no_quit (key, list)
  1283.      register Lisp_Object key;
  1284.      Lisp_Object list;
  1285. {
  1286.   register Lisp_Object tail;
  1287.   for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
  1288.     {
  1289.       register Lisp_Object elt, tem;
  1290.       elt = Fcar (tail);
  1291.       if (!CONSP (elt)) continue;
  1292.       tem = XCONS (elt)->car;
  1293.       if (EQ (key, tem)) return elt;
  1294.     }
  1295.   return Qnil;
  1296. }
  1297.  
  1298. DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
  1299.   "Return non-nil if KEY is `equal' to the car of an element of LIST.\n\
  1300. The value is actually the element of LIST whose car equals KEY.")
  1301.   (key, list)
  1302.      register Lisp_Object key;
  1303.      Lisp_Object list;
  1304. {
  1305.   register Lisp_Object tail;
  1306.   for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
  1307.     {
  1308.       register Lisp_Object elt, tem;
  1309.       elt = Fcar (tail);
  1310.       if (!CONSP (elt)) continue;
  1311.       tem = Fequal (XCONS (elt)->car, key);
  1312.       if (!NILP (tem)) return elt;
  1313.       QUIT;
  1314.     }
  1315.   return Qnil;
  1316. }
  1317.  
  1318. DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
  1319.   "Return non-nil if ELT is `eq' to the cdr of an element of LIST.\n\
  1320. The value is actually the element of LIST whose cdr is ELT.")
  1321.   (key, list)
  1322.      register Lisp_Object key;
  1323.      Lisp_Object list;
  1324. {
  1325.   register Lisp_Object tail;
  1326.   for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
  1327.     {
  1328.       register Lisp_Object elt, tem;
  1329.       elt = Fcar (tail);
  1330.       if (!CONSP (elt)) continue;
  1331.       tem = XCONS (elt)->cdr;
  1332.       if (EQ (key, tem)) return elt;
  1333.       QUIT;
  1334.     }
  1335.   return Qnil;
  1336. }
  1337.  
  1338. DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
  1339.   "Return non-nil if KEY is `equal' to the cdr of an element of LIST.\n\
  1340. The value is actually the element of LIST whose cdr equals KEY.")
  1341.   (key, list)
  1342.      register Lisp_Object key;
  1343.      Lisp_Object list;
  1344. {
  1345.   register Lisp_Object tail;
  1346.   for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
  1347.     {
  1348.       register Lisp_Object elt, tem;
  1349.       elt = Fcar (tail);
  1350.       if (!CONSP (elt)) continue;
  1351.       tem = Fequal (XCONS (elt)->cdr, key);
  1352.       if (!NILP (tem)) return elt;
  1353.       QUIT;
  1354.     }
  1355.   return Qnil;
  1356. }
  1357.  
  1358. DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0,
  1359.   "Delete by side effect any occurrences of ELT as a member of LIST.\n\
  1360. The modified LIST is returned.  Comparison is done with `eq'.\n\
  1361. If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
  1362. therefore, write `(setq foo (delq element foo))'\n\
  1363. to be sure of changing the value of `foo'.")
  1364.   (elt, list)
  1365.      register Lisp_Object elt;
  1366.      Lisp_Object list;
  1367. {
  1368.   register Lisp_Object tail, prev;
  1369.   register Lisp_Object tem;
  1370.  
  1371.   tail = list;
  1372.   prev = Qnil;
  1373.   while (!NILP (tail))
  1374.     {
  1375.       tem = Fcar (tail);
  1376.       if (EQ (elt, tem))
  1377.     {
  1378.       if (NILP (prev))
  1379.         list = XCONS (tail)->cdr;
  1380.       else
  1381.         Fsetcdr (prev, XCONS (tail)->cdr);
  1382.     }
  1383.       else
  1384.     prev = tail;
  1385.       tail = XCONS (tail)->cdr;
  1386.       QUIT;
  1387.     }
  1388.   return list;
  1389. }
  1390.  
  1391. DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
  1392.   "Delete by side effect any occurrences of ELT as a member of LIST.\n\
  1393. The modified LIST is returned.  Comparison is done with `equal'.\n\
  1394. If the first member of LIST is ELT, deleting it is not a side effect;\n\
  1395. it is simply using a different list.\n\
  1396. Therefore, write `(setq foo (delete element foo))'\n\
  1397. to be sure of changing the value of `foo'.")
  1398.   (elt, list)
  1399.      register Lisp_Object elt;
  1400.      Lisp_Object list;
  1401. {
  1402.   register Lisp_Object tail, prev;
  1403.   register Lisp_Object tem;
  1404.  
  1405.   tail = list;
  1406.   prev = Qnil;
  1407.   while (!NILP (tail))
  1408.     {
  1409.       tem = Fcar (tail);
  1410.       if (! NILP (Fequal (elt, tem)))
  1411.     {
  1412.       if (NILP (prev))
  1413.         list = XCONS (tail)->cdr;
  1414.       else
  1415.         Fsetcdr (prev, XCONS (tail)->cdr);
  1416.     }
  1417.       else
  1418.     prev = tail;
  1419.       tail = XCONS (tail)->cdr;
  1420.       QUIT;
  1421.     }
  1422.   return list;
  1423. }
  1424.  
  1425. DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
  1426.   "Reverse LIST by modifying cdr pointers.\n\
  1427. Returns the beginning of the reversed list.")
  1428.   (list)
  1429.      Lisp_Object list;
  1430. {
  1431.   register Lisp_Object prev, tail, next;
  1432.  
  1433.   if (NILP (list)) return list;
  1434.   prev = Qnil;
  1435.   tail = list;
  1436.   while (!NILP (tail))
  1437.     {
  1438.       QUIT;
  1439.       next = Fcdr (tail);
  1440.       Fsetcdr (tail, prev);
  1441.       prev = tail;
  1442.       tail = next;
  1443.     }
  1444.   return prev;
  1445. }
  1446.  
  1447. DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
  1448.   "Reverse LIST, copying.  Returns the beginning of the reversed list.\n\
  1449. See also the function `nreverse', which is used more often.")
  1450.   (list)
  1451.      Lisp_Object list;
  1452. {
  1453.   Lisp_Object new;
  1454.  
  1455.   for (new = Qnil; CONSP (list); list = XCONS (list)->cdr)
  1456.     new = Fcons (XCONS (list)->car, new);
  1457.   if (!NILP (list))
  1458.     wrong_type_argument (Qconsp, list);
  1459.   return new;
  1460. }
  1461.  
  1462. Lisp_Object merge ();
  1463.  
  1464. DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
  1465.   "Sort LIST, stably, comparing elements using PREDICATE.\n\
  1466. Returns the sorted list.  LIST is modified by side effects.\n\
  1467. PREDICATE is called with two elements of LIST, and should return T\n\
  1468. if the first element is \"less\" than the second.")
  1469.   (list, predicate)
  1470.      Lisp_Object list, predicate;
  1471. {
  1472.   Lisp_Object front, back;
  1473.   register Lisp_Object len, tem;
  1474.   struct gcpro gcpro1, gcpro2;
  1475.   register int length;
  1476.  
  1477.   front = list;
  1478.   len = Flength (list);
  1479.   length = XINT (len);
  1480.   if (length < 2)
  1481.     return list;
  1482.  
  1483.   XSETINT (len, (length / 2) - 1);
  1484.   tem = Fnthcdr (len, list);
  1485.   back = Fcdr (tem);
  1486.   Fsetcdr (tem, Qnil);
  1487.  
  1488.   GCPRO2 (front, back);
  1489.   front = Fsort (front, predicate);
  1490.   back = Fsort (back, predicate);
  1491.   UNGCPRO;
  1492.   return merge (front, back, predicate);
  1493. }
  1494.  
  1495. Lisp_Object
  1496. merge (org_l1, org_l2, pred)
  1497.      Lisp_Object org_l1, org_l2;
  1498.      Lisp_Object pred;
  1499. {
  1500.   Lisp_Object value;
  1501.   register Lisp_Object tail;
  1502.   Lisp_Object tem;
  1503.   register Lisp_Object l1, l2;
  1504.   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
  1505.  
  1506.   l1 = org_l1;
  1507.   l2 = org_l2;
  1508.   tail = Qnil;
  1509.   value = Qnil;
  1510.  
  1511.   /* It is sufficient to protect org_l1 and org_l2.
  1512.      When l1 and l2 are updated, we copy the new values
  1513.      back into the org_ vars.  */
  1514.   GCPRO4 (org_l1, org_l2, pred, value);
  1515.  
  1516.   while (1)
  1517.     {
  1518.       if (NILP (l1))
  1519.     {
  1520.       UNGCPRO;
  1521.       if (NILP (tail))
  1522.         return l2;
  1523.       Fsetcdr (tail, l2);
  1524.       return value;
  1525.     }
  1526.       if (NILP (l2))
  1527.     {
  1528.       UNGCPRO;
  1529.       if (NILP (tail))
  1530.         return l1;
  1531.       Fsetcdr (tail, l1);
  1532.       return value;
  1533.     }
  1534.       tem = call2 (pred, Fcar (l2), Fcar (l1));
  1535.       if (NILP (tem))
  1536.     {
  1537.       tem = l1;
  1538.       l1 = Fcdr (l1);
  1539.       org_l1 = l1;
  1540.     }
  1541.       else
  1542.     {
  1543.       tem = l2;
  1544.       l2 = Fcdr (l2);
  1545.       org_l2 = l2;
  1546.     }
  1547.       if (NILP (tail))
  1548.     value = tem;
  1549.       else
  1550.     Fsetcdr (tail, tem);
  1551.       tail = tem;
  1552.     }
  1553. }
  1554.  
  1555.  
  1556. DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
  1557.   "Extract a value from a property list.\n\
  1558. PLIST is a property list, which is a list of the form\n\
  1559. \(PROP1 VALUE1 PROP2 VALUE2...).  This function returns the value\n\
  1560. corresponding to the given PROP, or nil if PROP is not\n\
  1561. one of the properties on the list.")
  1562.   (plist, prop)
  1563.      Lisp_Object plist;
  1564.      register Lisp_Object prop;
  1565. {
  1566.   register Lisp_Object tail;
  1567.   for (tail = plist; !NILP (tail); tail = Fcdr (XCONS (tail)->cdr))
  1568.     {
  1569.       register Lisp_Object tem;
  1570.       tem = Fcar (tail);
  1571.       if (EQ (prop, tem))
  1572.     return Fcar (XCONS (tail)->cdr);
  1573.     }
  1574.   return Qnil;
  1575. }
  1576.  
  1577. DEFUN ("get", Fget, Sget, 2, 2, 0,
  1578.   "Return the value of SYMBOL's PROPNAME property.\n\
  1579. This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.")
  1580.   (symbol, propname)
  1581.      Lisp_Object symbol, propname;
  1582. {
  1583.   CHECK_SYMBOL (symbol, 0);
  1584.   return Fplist_get (XSYMBOL (symbol)->plist, propname);
  1585. }
  1586.  
  1587. DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
  1588.   "Change value in PLIST of PROP to VAL.\n\
  1589. PLIST is a property list, which is a list of the form\n\
  1590. \(PROP1 VALUE1 PROP2 VALUE2 ...).  PROP is a symbol and VAL is any object.\n\
  1591. If PROP is already a property on the list, its value is set to VAL,\n\
  1592. otherwise the new PROP VAL pair is added.  The new plist is returned;\n\
  1593. use `(setq x (plist-put x prop val))' to be sure to use the new value.\n\
  1594. The PLIST is modified by side effects.")
  1595.   (plist, prop, val)
  1596.      Lisp_Object plist;
  1597.      register Lisp_Object prop;
  1598.      Lisp_Object val;
  1599. {
  1600.   register Lisp_Object tail, prev;
  1601.   Lisp_Object newcell;
  1602.   prev = Qnil;
  1603.   for (tail = plist; CONSP (tail) && CONSP (XCONS (tail)->cdr);
  1604.        tail = XCONS (XCONS (tail)->cdr)->cdr)
  1605.     {
  1606.       if (EQ (prop, XCONS (tail)->car))
  1607.     {
  1608.       Fsetcar (XCONS (tail)->cdr, val);
  1609.       return plist;
  1610.     }
  1611.       prev = tail;
  1612.     }
  1613.   newcell = Fcons (prop, Fcons (val, Qnil));
  1614.   if (NILP (prev))
  1615.     return newcell;
  1616.   else
  1617.     Fsetcdr (XCONS (prev)->cdr, newcell);
  1618.   return plist;
  1619. }
  1620.  
  1621. DEFUN ("put", Fput, Sput, 3, 3, 0,
  1622.   "Store SYMBOL's PROPNAME property with value VALUE.\n\
  1623. It can be retrieved with `(get SYMBOL PROPNAME)'.")
  1624.   (symbol, propname, value)
  1625.      Lisp_Object symbol, propname, value;
  1626. {
  1627.   CHECK_SYMBOL (symbol, 0);
  1628.   XSYMBOL (symbol)->plist
  1629.     = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
  1630.   return value;
  1631. }
  1632.  
  1633. DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
  1634.   "Return t if two Lisp objects have similar structure and contents.\n\
  1635. They must have the same data type.\n\
  1636. Conses are compared by comparing the cars and the cdrs.\n\
  1637. Vectors and strings are compared element by element.\n\
  1638. Numbers are compared by value, but integers cannot equal floats.\n\
  1639.  (Use `=' if you want integers and floats to be able to be equal.)\n\
  1640. Symbols must match exactly.")
  1641.   (o1, o2)
  1642.      register Lisp_Object o1, o2;
  1643. {
  1644.   return internal_equal (o1, o2, 0) ? Qt : Qnil;
  1645. }
  1646.  
  1647. static int
  1648. internal_equal (o1, o2, depth)
  1649.      register Lisp_Object o1, o2;
  1650.      int depth;
  1651. {
  1652.   if (depth > 200)
  1653.     error ("Stack overflow in equal");
  1654.  
  1655.  tail_recurse:
  1656.   QUIT;
  1657.   if (EQ (o1, o2))
  1658.     return 1;
  1659.   if (XTYPE (o1) != XTYPE (o2))
  1660.     return 0;
  1661.  
  1662.   switch (XTYPE (o1))
  1663.     {
  1664. #ifdef LISP_FLOAT_TYPE
  1665.     case Lisp_Float:
  1666.       return (extract_float (o1) == extract_float (o2));
  1667. #endif
  1668.  
  1669.     case Lisp_Cons:
  1670.       if (!internal_equal (XCONS (o1)->car, XCONS (o2)->car, depth + 1))
  1671.     return 0;
  1672.       o1 = XCONS (o1)->cdr;
  1673.       o2 = XCONS (o2)->cdr;
  1674.       goto tail_recurse;
  1675.  
  1676.     case Lisp_Misc:
  1677.       if (XMISCTYPE (o1) != XMISCTYPE (o2))
  1678.     return 0;
  1679.       if (OVERLAYP (o1))
  1680.     {
  1681.       if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o1),
  1682.                    depth + 1)
  1683.           || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o1),
  1684.                   depth + 1))
  1685.         return 0;
  1686.       o1 = XOVERLAY (o1)->plist;
  1687.       o2 = XOVERLAY (o2)->plist;
  1688.       goto tail_recurse;
  1689.     }
  1690.       if (MARKERP (o1))
  1691.     {
  1692.       return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
  1693.           && (XMARKER (o1)->buffer == 0
  1694.               || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
  1695.     }
  1696.       break;
  1697.  
  1698.     case Lisp_Vectorlike:
  1699.       {
  1700.     register int i, size;
  1701.     size = XVECTOR (o1)->size;
  1702.     /* Pseudovectors have the type encoded in the size field, so this test
  1703.        actually checks that the objects have the same type as well as the
  1704.        same size.  */
  1705.     if (XVECTOR (o2)->size != size)
  1706.       return 0;
  1707.     /* Boolvectors are compared much like strings.  */
  1708.     if (BOOL_VECTOR_P (o1))
  1709.       {
  1710.         int size_in_chars
  1711.           = (XBOOL_VECTOR (o1)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
  1712.  
  1713.         if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
  1714.           return 0;
  1715.         if (bcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data,
  1716.               size_in_chars))
  1717.           return 0;
  1718.         return 1;
  1719.       }
  1720.     if (WINDOW_CONFIGURATIONP (o1))
  1721.       return compare_window_configurations (o1, o2, 0);
  1722.  
  1723.     /* Aside from them, only true vectors, char-tables, and compiled
  1724.        functions are sensible to compare, so eliminate the others now.  */
  1725.     if (size & PSEUDOVECTOR_FLAG)
  1726.       {
  1727.         if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
  1728.           return 0;
  1729.         size &= PSEUDOVECTOR_SIZE_MASK;
  1730.       }
  1731.     for (i = 0; i < size; i++)
  1732.       {
  1733.         Lisp_Object v1, v2;
  1734.         v1 = XVECTOR (o1)->contents [i];
  1735.         v2 = XVECTOR (o2)->contents [i];
  1736.         if (!internal_equal (v1, v2, depth + 1))
  1737.           return 0;
  1738.       }
  1739.     return 1;
  1740.       }
  1741.       break;
  1742.  
  1743.     case Lisp_String:
  1744.       if (XSTRING (o1)->size != XSTRING (o2)->size)
  1745.     return 0;
  1746.       if (STRING_BYTES (XSTRING (o1)) != STRING_BYTES (XSTRING (o2)))
  1747.     return 0;
  1748.       if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
  1749.         STRING_BYTES (XSTRING (o1))))
  1750.     return 0;
  1751.       return 1;
  1752.     }
  1753.   return 0;
  1754. }
  1755.  
  1756. extern Lisp_Object Fmake_char_internal ();
  1757.  
  1758. DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
  1759.   "Store each element of ARRAY with ITEM.\n\
  1760. ARRAY is a vector, string, char-table, or bool-vector.")
  1761.   (array, item)
  1762.      Lisp_Object array, item;
  1763. {
  1764.   register int size, index, charval;
  1765.  retry:
  1766.   if (VECTORP (array))
  1767.     {
  1768.       register Lisp_Object *p = XVECTOR (array)->contents;
  1769.       size = XVECTOR (array)->size;
  1770.       for (index = 0; index < size; index++)
  1771.     p[index] = item;
  1772.     }
  1773.   else if (CHAR_TABLE_P (array))
  1774.     {
  1775.       register Lisp_Object *p = XCHAR_TABLE (array)->contents;
  1776.       size = CHAR_TABLE_ORDINARY_SLOTS;
  1777.       for (index = 0; index < size; index++)
  1778.     p[index] = item;
  1779.       XCHAR_TABLE (array)->defalt = Qnil;
  1780.     }
  1781.   else if (STRINGP (array))
  1782.     {
  1783.       register unsigned char *p = XSTRING (array)->data;
  1784.       CHECK_NUMBER (item, 1);
  1785.       charval = XINT (item);
  1786.       size = XSTRING (array)->size;
  1787.       for (index = 0; index < size; index++)
  1788.     p[index] = charval;
  1789.     }
  1790.   else if (BOOL_VECTOR_P (array))
  1791.     {
  1792.       register unsigned char *p = XBOOL_VECTOR (array)->data;
  1793.       int size_in_chars
  1794.     = (XBOOL_VECTOR (array)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
  1795.  
  1796.       charval = (! NILP (item) ? -1 : 0);
  1797.       for (index = 0; index < size_in_chars; index++)
  1798.     p[index] = charval;
  1799.     }
  1800.   else
  1801.     {
  1802.       array = wrong_type_argument (Qarrayp, array);
  1803.       goto retry;
  1804.     }
  1805.   return array;
  1806. }
  1807.  
  1808. DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
  1809.        1, 1, 0,
  1810.   "Return the subtype of char-table CHAR-TABLE.   The value is a symbol.")
  1811.   (char_table)
  1812.      Lisp_Object char_table;
  1813. {
  1814.   CHECK_CHAR_TABLE (char_table, 0);
  1815.  
  1816.   return XCHAR_TABLE (char_table)->purpose;
  1817. }
  1818.  
  1819. DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
  1820.        1, 1, 0,
  1821.   "Return the parent char-table of CHAR-TABLE.\n\
  1822. The value is either nil or another char-table.\n\
  1823. If CHAR-TABLE holds nil for a given character,\n\
  1824. then the actual applicable value is inherited from the parent char-table\n\
  1825. \(or from its parents, if necessary).")
  1826.   (char_table)
  1827.      Lisp_Object char_table;
  1828. {
  1829.   CHECK_CHAR_TABLE (char_table, 0);
  1830.  
  1831.   return XCHAR_TABLE (char_table)->parent;
  1832. }
  1833.  
  1834. DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
  1835.        2, 2, 0,
  1836.   "Set the parent char-table of CHAR-TABLE to PARENT.\n\
  1837. PARENT must be either nil or another char-table.")
  1838.   (char_table, parent)
  1839.      Lisp_Object char_table, parent;
  1840. {
  1841.   Lisp_Object temp;
  1842.  
  1843.   CHECK_CHAR_TABLE (char_table, 0);
  1844.  
  1845.   if (!NILP (parent))
  1846.     {
  1847.       CHECK_CHAR_TABLE (parent, 0);
  1848.  
  1849.       for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
  1850.     if (EQ (temp, char_table))
  1851.       error ("Attempt to make a chartable be its own parent");
  1852.     }
  1853.  
  1854.   XCHAR_TABLE (char_table)->parent = parent;
  1855.  
  1856.   return parent;
  1857. }
  1858.  
  1859. DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
  1860.        2, 2, 0,
  1861.   "Return the value of CHAR-TABLE's extra-slot number N.")
  1862.   (char_table, n)
  1863.      Lisp_Object char_table, n;
  1864. {
  1865.   CHECK_CHAR_TABLE (char_table, 1);
  1866.   CHECK_NUMBER (n, 2);
  1867.   if (XINT (n) < 0
  1868.       || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
  1869.     args_out_of_range (char_table, n);
  1870.  
  1871.   return XCHAR_TABLE (char_table)->extras[XINT (n)];
  1872. }
  1873.  
  1874. DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
  1875.        Sset_char_table_extra_slot,
  1876.        3, 3, 0,
  1877.   "Set CHAR-TABLE's extra-slot number N to VALUE.")
  1878.   (char_table, n, value)
  1879.      Lisp_Object char_table, n, value;
  1880. {
  1881.   CHECK_CHAR_TABLE (char_table, 1);
  1882.   CHECK_NUMBER (n, 2);
  1883.   if (XINT (n) < 0
  1884.       || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
  1885.     args_out_of_range (char_table, n);
  1886.  
  1887.   return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
  1888. }
  1889.  
  1890. DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
  1891.        2, 2, 0,
  1892.   "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
  1893. RANGE should be nil (for the default value)\n\
  1894. a vector which identifies a character set or a row of a character set,\n\
  1895. a character set name, or a character code.")
  1896.   (char_table, range)
  1897.      Lisp_Object char_table, range;
  1898. {
  1899.   int i;
  1900.  
  1901.   CHECK_CHAR_TABLE (char_table, 0);
  1902.  
  1903.   if (EQ (range, Qnil))
  1904.     return XCHAR_TABLE (char_table)->defalt;
  1905.   else if (INTEGERP (range))
  1906.     return Faref (char_table, range);
  1907.   else if (SYMBOLP (range))
  1908.     {
  1909.       Lisp_Object charset_info;
  1910.  
  1911.       charset_info = Fget (range, Qcharset);
  1912.       CHECK_VECTOR (charset_info, 0);
  1913.  
  1914.       return Faref (char_table,
  1915.             make_number (XINT (XVECTOR (charset_info)->contents[0])
  1916.                  + 128));
  1917.     }
  1918.   else if (VECTORP (range))
  1919.     {
  1920.       if (XVECTOR (range)->size == 1)
  1921.     return Faref (char_table,
  1922.               make_number (XINT (XVECTOR (range)->contents[0]) + 128));
  1923.       else
  1924.     {
  1925.       int size = XVECTOR (range)->size;
  1926.       Lisp_Object *val = XVECTOR (range)->contents;
  1927.       Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
  1928.                         size <= 1 ? Qnil : val[1],
  1929.                         size <= 2 ? Qnil : val[2]);
  1930.       return Faref (char_table, ch);
  1931.     }
  1932.     }
  1933.   else
  1934.     error ("Invalid RANGE argument to `char-table-range'");
  1935. }
  1936.  
  1937. DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
  1938.        3, 3, 0,
  1939.   "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
  1940. RANGE should be t (for all characters), nil (for the default value)\n\
  1941. a vector which identifies a character set or a row of a character set,\n\
  1942. a coding system, or a character code.")
  1943.   (char_table, range, value)
  1944.      Lisp_Object char_table, range, value;
  1945. {
  1946.   int i;
  1947.  
  1948.   CHECK_CHAR_TABLE (char_table, 0);
  1949.  
  1950.   if (EQ (range, Qt))
  1951.     for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
  1952.       XCHAR_TABLE (char_table)->contents[i] = value;
  1953.   else if (EQ (range, Qnil))
  1954.     XCHAR_TABLE (char_table)->defalt = value;
  1955.   else if (SYMBOLP (range))
  1956.     {
  1957.       Lisp_Object charset_info;
  1958.  
  1959.       charset_info = Fget (range, Qcharset);
  1960.       CHECK_VECTOR (charset_info, 0);
  1961.  
  1962.       return Faset (char_table,
  1963.             make_number (XINT (XVECTOR (charset_info)->contents[0])
  1964.                  + 128),
  1965.             value);
  1966.     }
  1967.   else if (INTEGERP (range))
  1968.     Faset (char_table, range, value);
  1969.   else if (VECTORP (range))
  1970.     {
  1971.       if (XVECTOR (range)->size == 1)
  1972.     return Faset (char_table,
  1973.               make_number (XINT (XVECTOR (range)->contents[0]) + 128),
  1974.               value);
  1975.       else
  1976.     {
  1977.       int size = XVECTOR (range)->size;
  1978.       Lisp_Object *val = XVECTOR (range)->contents;
  1979.       Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
  1980.                         size <= 1 ? Qnil : val[1],
  1981.                         size <= 2 ? Qnil : val[2]);
  1982.       return Faset (char_table, ch, value);
  1983.     }
  1984.     }
  1985.   else
  1986.     error ("Invalid RANGE argument to `set-char-table-range'");
  1987.  
  1988.   return value;
  1989. }
  1990.  
  1991. DEFUN ("set-char-table-default", Fset_char_table_default,
  1992.        Sset_char_table_default, 3, 3, 0,
  1993.   "Set the default value in CHAR-TABLE for a generic character CHAR to VALUE.\n\
  1994. The generic character specifies the group of characters.\n\
  1995. See also the documentation of make-char.")
  1996.   (char_table, ch, value)
  1997.      Lisp_Object char_table, ch, value;
  1998. {
  1999.   int c, i, charset, code1, code2;
  2000.   Lisp_Object temp;
  2001.  
  2002.   CHECK_CHAR_TABLE (char_table, 0);
  2003.   CHECK_NUMBER (ch, 1);
  2004.  
  2005.   c = XINT (ch);
  2006.   SPLIT_NON_ASCII_CHAR (c, charset, code1, code2);
  2007.  
  2008.   /* Since we may want to set the default value for a character set
  2009.      not yet defined, we check only if the character set is in the
  2010.      valid range or not, instead of it is already defined or not.  */
  2011.   if (! CHARSET_VALID_P (charset))
  2012.     invalid_character (c);
  2013.  
  2014.   if (charset == CHARSET_ASCII)
  2015.     return (XCHAR_TABLE (char_table)->defalt = value);
  2016.  
  2017.   /* Even if C is not a generic char, we had better behave as if a
  2018.      generic char is specified.  */
  2019.   if (charset == CHARSET_COMPOSITION || CHARSET_DIMENSION (charset) == 1)
  2020.     code1 = 0;
  2021.   temp = XCHAR_TABLE (char_table)->contents[charset + 128];
  2022.   if (!code1)
  2023.     {
  2024.       if (SUB_CHAR_TABLE_P (temp))
  2025.     XCHAR_TABLE (temp)->defalt = value;
  2026.       else
  2027.     XCHAR_TABLE (char_table)->contents[charset + 128] = value;
  2028.       return value;
  2029.     }
  2030.   char_table = temp;
  2031.   if (! SUB_CHAR_TABLE_P (char_table))
  2032.     char_table = (XCHAR_TABLE (char_table)->contents[charset + 128]
  2033.         = make_sub_char_table (temp));
  2034.   temp = XCHAR_TABLE (char_table)->contents[code1];
  2035.   if (SUB_CHAR_TABLE_P (temp))
  2036.     XCHAR_TABLE (temp)->defalt = value;
  2037.   else
  2038.     XCHAR_TABLE (char_table)->contents[code1] = value;
  2039.   return value;
  2040. }
  2041.  
  2042. /* Look up the element in TABLE at index CH,
  2043.    and return it as an integer.
  2044.    If the element is nil, return CH itself.
  2045.    (Actually we do that for any non-integer.)  */
  2046.  
  2047. int
  2048. char_table_translate (table, ch)
  2049.      Lisp_Object table;
  2050.      int ch;
  2051. {
  2052.   Lisp_Object value;
  2053.   value = Faref (table, make_number (ch));
  2054.   if (! INTEGERP (value))
  2055.     return ch;
  2056.   return XINT (value);
  2057. }
  2058.  
  2059. /* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
  2060.    character or group of characters that share a value.
  2061.    DEPTH is the current depth in the originally specified
  2062.    chartable, and INDICES contains the vector indices
  2063.    for the levels our callers have descended.
  2064.  
  2065.    ARG is passed to C_FUNCTION when that is called.  */
  2066.  
  2067. void
  2068. map_char_table (c_function, function, subtable, arg, depth, indices)
  2069.      void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
  2070.      Lisp_Object function, subtable, arg, *indices;
  2071.      int depth;
  2072. {
  2073.   int i, to;
  2074.  
  2075.   if (depth == 0)
  2076.     {
  2077.       /* At first, handle ASCII and 8-bit European characters.  */
  2078.       for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
  2079.     {
  2080.       Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
  2081.       if (c_function)
  2082.         (*c_function) (arg, make_number (i), elt);
  2083.       else
  2084.         call2 (function, make_number (i), elt);
  2085.     }
  2086. #if 0 /* If the char table has entries for higher characters,
  2087.      we should report them.  */
  2088.       if (NILP (current_buffer->enable_multibyte_characters))
  2089.     return;
  2090. #endif
  2091.       to = CHAR_TABLE_ORDINARY_SLOTS;
  2092.     }
  2093.   else
  2094.     {
  2095.       i = 32;
  2096.       to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
  2097.     }
  2098.  
  2099.   for (; i < to; i++)
  2100.     {
  2101.       Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
  2102.  
  2103.       XSETFASTINT (indices[depth], i);
  2104.  
  2105.       if (SUB_CHAR_TABLE_P (elt))
  2106.     {
  2107.       if (depth >= 3)
  2108.         error ("Too deep char table");
  2109.       map_char_table (c_function, function, elt, arg, depth + 1, indices);
  2110.     }
  2111.       else
  2112.     {
  2113.       int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
  2114.  
  2115.       if (CHARSET_DEFINED_P (charset))
  2116.         {
  2117.           c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
  2118.           c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
  2119.           c = MAKE_NON_ASCII_CHAR (charset, c1, c2);
  2120.           if (c_function)
  2121.         (*c_function) (arg, make_number (c), elt);
  2122.           else
  2123.         call2 (function, make_number (c), elt);
  2124.         }
  2125.       }
  2126.     }
  2127. }
  2128.  
  2129. DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
  2130.   2, 2, 0,
  2131.   "Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.\n\
  2132. FUNCTION is called with two arguments--a key and a value.\n\
  2133. The key is always a possible IDX argument to `aref'.")
  2134.   (function, char_table)
  2135.      Lisp_Object function, char_table;
  2136. {
  2137.   /* The depth of char table is at most 3. */
  2138.   Lisp_Object indices[3];
  2139.  
  2140.   CHECK_CHAR_TABLE (char_table, 1);
  2141.  
  2142.   map_char_table (NULL, function, char_table, char_table, 0, indices);
  2143.   return Qnil;
  2144. }
  2145.  
  2146. /* ARGSUSED */
  2147. Lisp_Object
  2148. nconc2 (s1, s2)
  2149.      Lisp_Object s1, s2;
  2150. {
  2151. #ifdef NO_ARG_ARRAY
  2152.   Lisp_Object args[2];
  2153.   args[0] = s1;
  2154.   args[1] = s2;
  2155.   return Fnconc (2, args);
  2156. #else
  2157.   return Fnconc (2, &s1);
  2158. #endif /* NO_ARG_ARRAY */
  2159. }
  2160.  
  2161. DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
  2162.   "Concatenate any number of lists by altering them.\n\
  2163. Only the last argument is not altered, and need not be a list.")
  2164.   (nargs, args)
  2165.      int nargs;
  2166.      Lisp_Object *args;
  2167. {
  2168.   register int argnum;
  2169.   register Lisp_Object tail, tem, val;
  2170.  
  2171.   val = Qnil;
  2172.  
  2173.   for (argnum = 0; argnum < nargs; argnum++)
  2174.     {
  2175.       tem = args[argnum];
  2176.       if (NILP (tem)) continue;
  2177.  
  2178.       if (NILP (val))
  2179.     val = tem;
  2180.  
  2181.       if (argnum + 1 == nargs) break;
  2182.  
  2183.       if (!CONSP (tem))
  2184.     tem = wrong_type_argument (Qlistp, tem);
  2185.  
  2186.       while (CONSP (tem))
  2187.     {
  2188.       tail = tem;
  2189.       tem = Fcdr (tail);
  2190.       QUIT;
  2191.     }
  2192.  
  2193.       tem = args[argnum + 1];
  2194.       Fsetcdr (tail, tem);
  2195.       if (NILP (tem))
  2196.     args[argnum + 1] = tail;
  2197.     }
  2198.  
  2199.   return val;
  2200. }
  2201.  
  2202. /* This is the guts of all mapping functions.
  2203.  Apply FN to each element of SEQ, one by one,
  2204.  storing the results into elements of VALS, a C vector of Lisp_Objects.
  2205.  LENI is the length of VALS, which should also be the length of SEQ.  */
  2206.  
  2207. static void
  2208. mapcar1 (leni, vals, fn, seq)
  2209.      int leni;
  2210.      Lisp_Object *vals;
  2211.      Lisp_Object fn, seq;
  2212. {
  2213.   register Lisp_Object tail;
  2214.   Lisp_Object dummy;
  2215.   register int i;
  2216.   struct gcpro gcpro1, gcpro2, gcpro3;
  2217.  
  2218.   /* Don't let vals contain any garbage when GC happens.  */
  2219.   for (i = 0; i < leni; i++)
  2220.     vals[i] = Qnil;
  2221.  
  2222.   GCPRO3 (dummy, fn, seq);
  2223.   gcpro1.var = vals;
  2224.   gcpro1.nvars = leni;
  2225.   /* We need not explicitly protect `tail' because it is used only on lists, and
  2226.     1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
  2227.  
  2228.   if (VECTORP (seq))
  2229.     {
  2230.       for (i = 0; i < leni; i++)
  2231.     {
  2232.       dummy = XVECTOR (seq)->contents[i];
  2233.       vals[i] = call1 (fn, dummy);
  2234.     }
  2235.     }
  2236.   else if (BOOL_VECTOR_P (seq))
  2237.     {
  2238.       for (i = 0; i < leni; i++)
  2239.     {
  2240.       int byte;
  2241.       byte = XBOOL_VECTOR (seq)->data[i / BITS_PER_CHAR];
  2242.       if (byte & (1 << (i % BITS_PER_CHAR)))
  2243.         dummy = Qt;
  2244.       else
  2245.         dummy = Qnil;
  2246.  
  2247.       vals[i] = call1 (fn, dummy);
  2248.     }
  2249.     }
  2250.   else if (STRINGP (seq) && ! STRING_MULTIBYTE (seq))
  2251.     {
  2252.       /* Single-byte string.  */
  2253.       for (i = 0; i < leni; i++)
  2254.     {
  2255.       XSETFASTINT (dummy, XSTRING (seq)->data[i]);
  2256.       vals[i] = call1 (fn, dummy);
  2257.     }
  2258.     }
  2259.   else if (STRINGP (seq))
  2260.     {
  2261.       /* Multi-byte string.  */
  2262.       int len_byte = STRING_BYTES (XSTRING (seq));
  2263.       int i_byte;
  2264.  
  2265.       for (i = 0, i_byte = 0; i < leni;)
  2266.     {
  2267.       int c;
  2268.       int i_before = i;
  2269.  
  2270.       FETCH_STRING_CHAR_ADVANCE (c, seq, i, i_byte);
  2271.       XSETFASTINT (dummy, c);
  2272.       vals[i_before] = call1 (fn, dummy);
  2273.     }
  2274.     }
  2275.   else   /* Must be a list, since Flength did not get an error */
  2276.     {
  2277.       tail = seq;
  2278.       for (i = 0; i < leni; i++)
  2279.     {
  2280.       vals[i] = call1 (fn, Fcar (tail));
  2281.       tail = XCONS (tail)->cdr;
  2282.     }
  2283.     }
  2284.  
  2285.   UNGCPRO;
  2286. }
  2287.  
  2288. DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
  2289.   "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
  2290. In between each pair of results, stick in SEPARATOR.  Thus, \" \" as\n\
  2291. SEPARATOR results in spaces between the values returned by FUNCTION.\n\
  2292. SEQUENCE may be a list, a vector, a bool-vector, or a string.")
  2293.   (function, sequence, separator)
  2294.      Lisp_Object function, sequence, separator;
  2295. {
  2296.   Lisp_Object len;
  2297.   register int leni;
  2298.   int nargs;
  2299.   register Lisp_Object *args;
  2300.   register int i;
  2301.   struct gcpro gcpro1;
  2302.  
  2303.   len = Flength (sequence);
  2304.   leni = XINT (len);
  2305.   nargs = leni + leni - 1;
  2306.   if (nargs < 0) return build_string ("");
  2307.  
  2308.   args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
  2309.  
  2310.   GCPRO1 (separator);
  2311.   mapcar1 (leni, args, function, sequence);
  2312.   UNGCPRO;
  2313.  
  2314.   for (i = leni - 1; i >= 0; i--)
  2315.     args[i + i] = args[i];
  2316.  
  2317.   for (i = 1; i < nargs; i += 2)
  2318.     args[i] = separator;
  2319.  
  2320.   return Fconcat (nargs, args);
  2321. }
  2322.  
  2323. DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
  2324.   "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
  2325. The result is a list just as long as SEQUENCE.\n\
  2326. SEQUENCE may be a list, a vector, a bool-vector, or a string.")
  2327.   (function, sequence)
  2328.      Lisp_Object function, sequence;
  2329. {
  2330.   register Lisp_Object len;
  2331.   register int leni;
  2332.   register Lisp_Object *args;
  2333.  
  2334.   len = Flength (sequence);
  2335.   leni = XFASTINT (len);
  2336.   args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
  2337.  
  2338.   mapcar1 (leni, args, function, sequence);
  2339.  
  2340.   return Flist (leni, args);
  2341. }
  2342.  
  2343. /* Anything that calls this function must protect from GC!  */
  2344.  
  2345. DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
  2346.   "Ask user a \"y or n\" question.  Return t if answer is \"y\".\n\
  2347. Takes one argument, which is the string to display to ask the question.\n\
  2348. It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
  2349. No confirmation of the answer is requested; a single character is enough.\n\
  2350. Also accepts Space to mean yes, or Delete to mean no.")
  2351.   (prompt)
  2352.      Lisp_Object prompt;
  2353. {
  2354.   register Lisp_Object obj, key, def, answer_string, map;
  2355.   register int answer;
  2356.   Lisp_Object xprompt;
  2357.   Lisp_Object args[2];
  2358.   struct gcpro gcpro1, gcpro2;
  2359.   int count = specpdl_ptr - specpdl;
  2360.  
  2361.   specbind (Qcursor_in_echo_area, Qt);
  2362.  
  2363.   map = Fsymbol_value (intern ("query-replace-map"));
  2364.  
  2365.   CHECK_STRING (prompt, 0);
  2366.   xprompt = prompt;
  2367.   GCPRO2 (prompt, xprompt);
  2368.  
  2369.   while (1)
  2370.     {
  2371.  
  2372. #ifdef HAVE_MENUS
  2373.       if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
  2374.       && use_dialog_box
  2375.       && have_menus_p ())
  2376.     {
  2377.       Lisp_Object pane, menu;
  2378.       redisplay_preserve_echo_area ();
  2379.       pane = Fcons (Fcons (build_string ("Yes"), Qt),
  2380.             Fcons (Fcons (build_string ("No"), Qnil),
  2381.                    Qnil));
  2382.       menu = Fcons (prompt, pane);
  2383.       obj = Fx_popup_dialog (Qt, menu);
  2384.       answer = !NILP (obj);
  2385.       break;
  2386.     }
  2387. #endif /* HAVE_MENUS */
  2388.       cursor_in_echo_area = 1;
  2389.       choose_minibuf_frame ();
  2390.       message_with_string ("%s(y or n) ", xprompt, 0);
  2391.  
  2392.       if (minibuffer_auto_raise)
  2393.     {
  2394.       Lisp_Object mini_frame;
  2395.  
  2396.       mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
  2397.  
  2398.       Fraise_frame (mini_frame);
  2399.     }
  2400.  
  2401.       obj = read_filtered_event (1, 0, 0, 0);
  2402.       cursor_in_echo_area = 0;
  2403.       /* If we need to quit, quit with cursor_in_echo_area = 0.  */
  2404.       QUIT;
  2405.  
  2406.       key = Fmake_vector (make_number (1), obj);
  2407.       def = Flookup_key (map, key, Qt);
  2408.       answer_string = Fsingle_key_description (obj);
  2409.  
  2410.       if (EQ (def, intern ("skip")))
  2411.     {
  2412.       answer = 0;
  2413.       break;
  2414.     }
  2415.       else if (EQ (def, intern ("act")))
  2416.     {
  2417.       answer = 1;
  2418.       break;
  2419.     }
  2420.       else if (EQ (def, intern ("recenter")))
  2421.     {
  2422.       Frecenter (Qnil);
  2423.       xprompt = prompt;
  2424.       continue;
  2425.     }
  2426.       else if (EQ (def, intern ("quit")))
  2427.     Vquit_flag = Qt;
  2428.       /* We want to exit this command for exit-prefix,
  2429.      and this is the only way to do it.  */
  2430.       else if (EQ (def, intern ("exit-prefix")))
  2431.     Vquit_flag = Qt;
  2432.  
  2433.       QUIT;
  2434.  
  2435.       /* If we don't clear this, then the next call to read_char will
  2436.      return quit_char again, and we'll enter an infinite loop.  */
  2437.       Vquit_flag = Qnil;
  2438.  
  2439.       Fding (Qnil);
  2440.       Fdiscard_input ();
  2441.       if (EQ (xprompt, prompt))
  2442.     {
  2443.       args[0] = build_string ("Please answer y or n.  ");
  2444.       args[1] = prompt;
  2445.       xprompt = Fconcat (2, args);
  2446.     }
  2447.     }
  2448.   UNGCPRO;
  2449.  
  2450.   if (! noninteractive)
  2451.     {
  2452.       cursor_in_echo_area = -1;
  2453.       message_with_string (answer ? "%s(y or n) y" : "%s(y or n) n",
  2454.                xprompt, 0);
  2455.     }
  2456.  
  2457.   unbind_to (count, Qnil);
  2458.   return answer ? Qt : Qnil;
  2459. }
  2460.  
  2461. /* This is how C code calls `yes-or-no-p' and allows the user
  2462.    to redefined it.
  2463.  
  2464.    Anything that calls this function must protect from GC!  */
  2465.  
  2466. Lisp_Object
  2467. do_yes_or_no_p (prompt)
  2468.      Lisp_Object prompt;
  2469. {
  2470.   return call1 (intern ("yes-or-no-p"), prompt);
  2471. }
  2472.  
  2473. /* Anything that calls this function must protect from GC!  */
  2474.  
  2475. DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
  2476.   "Ask user a yes-or-no question.  Return t if answer is yes.\n\
  2477. Takes one argument, which is the string to display to ask the question.\n\
  2478. It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
  2479. The user must confirm the answer with RET,\n\
  2480. and can edit it until it has been confirmed.")
  2481.   (prompt)
  2482.      Lisp_Object prompt;
  2483. {
  2484.   register Lisp_Object ans;
  2485.   Lisp_Object args[2];
  2486.   struct gcpro gcpro1;
  2487.   Lisp_Object menu;
  2488.  
  2489.   CHECK_STRING (prompt, 0);
  2490.  
  2491. #ifdef HAVE_MENUS
  2492.   if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
  2493.       && use_dialog_box
  2494.       && have_menus_p ())
  2495.     {
  2496.       Lisp_Object pane, menu, obj;
  2497.       redisplay_preserve_echo_area ();
  2498.       pane = Fcons (Fcons (build_string ("Yes"), Qt),
  2499.             Fcons (Fcons (build_string ("No"), Qnil),
  2500.                Qnil));
  2501.       GCPRO1 (pane);
  2502.       menu = Fcons (prompt, pane);
  2503.       obj = Fx_popup_dialog (Qt, menu);
  2504.       UNGCPRO;
  2505.       return obj;
  2506.     }
  2507. #endif /* HAVE_MENUS */
  2508.  
  2509.   args[0] = prompt;
  2510.   args[1] = build_string ("(yes or no) ");
  2511.   prompt = Fconcat (2, args);
  2512.  
  2513.   GCPRO1 (prompt);
  2514.  
  2515.   while (1)
  2516.     {
  2517.       ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
  2518.                           Qyes_or_no_p_history, Qnil,
  2519.                           Qnil));
  2520.       if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
  2521.     {
  2522.       UNGCPRO;
  2523.       return Qt;
  2524.     }
  2525.       if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
  2526.     {
  2527.       UNGCPRO;
  2528.       return Qnil;
  2529.     }
  2530.  
  2531.       Fding (Qnil);
  2532.       Fdiscard_input ();
  2533.       message ("Please answer yes or no.");
  2534.       Fsleep_for (make_number (2), Qnil);
  2535.     }
  2536. }
  2537.  
  2538. DEFUN ("load-average", Fload_average, Sload_average, 0, 1, 0,
  2539.   "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
  2540. Each of the three load averages is multiplied by 100,\n\
  2541. then converted to integer.\n\
  2542. When USE-FLOATS is non-nil, floats will be used instead of integers.\n\
  2543. These floats are not multiplied by 100.\n\n\
  2544. If the 5-minute or 15-minute load averages are not available, return a\n\
  2545. shortened list, containing only those averages which are available.")
  2546.   (use_floats)
  2547.      Lisp_Object use_floats;
  2548. {
  2549.   double load_ave[3];
  2550.   int loads = getloadavg (load_ave, 3);
  2551.   Lisp_Object ret = Qnil;
  2552.  
  2553.   if (loads < 0)
  2554.     error ("load-average not implemented for this operating system");
  2555.  
  2556.   while (loads-- > 0)
  2557.     {
  2558.       Lisp_Object load = (NILP (use_floats) ?
  2559.               make_number ((int) (100.0 * load_ave[loads]))
  2560.               : make_float (load_ave[loads]));
  2561.       ret = Fcons (load, ret);
  2562.     }
  2563.  
  2564.   return ret;
  2565. }
  2566.  
  2567. Lisp_Object Vfeatures;
  2568.  
  2569. DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0,
  2570.   "Returns t if FEATURE is present in this Emacs.\n\
  2571. Use this to conditionalize execution of lisp code based on the presence or\n\
  2572. absence of emacs or environment extensions.\n\
  2573. Use `provide' to declare that a feature is available.\n\
  2574. This function looks at the value of the variable `features'.")
  2575.   (feature)
  2576.      Lisp_Object feature;
  2577. {
  2578.   register Lisp_Object tem;
  2579.   CHECK_SYMBOL (feature, 0);
  2580.   tem = Fmemq (feature, Vfeatures);
  2581.   return (NILP (tem)) ? Qnil : Qt;
  2582. }
  2583.  
  2584. DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0,
  2585.   "Announce that FEATURE is a feature of the current Emacs.")
  2586.   (feature)
  2587.      Lisp_Object feature;
  2588. {
  2589.   register Lisp_Object tem;
  2590.   CHECK_SYMBOL (feature, 0);
  2591.   if (!NILP (Vautoload_queue))
  2592.     Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
  2593.   tem = Fmemq (feature, Vfeatures);
  2594.   if (NILP (tem))
  2595.     Vfeatures = Fcons (feature, Vfeatures);
  2596.   LOADHIST_ATTACH (Fcons (Qprovide, feature));
  2597.   return feature;
  2598. }
  2599.  
  2600. DEFUN ("require", Frequire, Srequire, 1, 2, 0,
  2601.   "If feature FEATURE is not loaded, load it from FILENAME.\n\
  2602. If FEATURE is not a member of the list `features', then the feature\n\
  2603. is not loaded; so load the file FILENAME.\n\
  2604. If FILENAME is omitted, the printname of FEATURE is used as the file name,\n\
  2605. but in this case `load' insists on adding the suffix `.el' or `.elc'.")
  2606.   (feature, file_name)
  2607.      Lisp_Object feature, file_name;
  2608. {
  2609.   register Lisp_Object tem;
  2610.   CHECK_SYMBOL (feature, 0);
  2611.   tem = Fmemq (feature, Vfeatures);
  2612.   LOADHIST_ATTACH (Fcons (Qrequire, feature));
  2613.   if (NILP (tem))
  2614.     {
  2615.       int count = specpdl_ptr - specpdl;
  2616.  
  2617.       /* Value saved here is to be restored into Vautoload_queue */
  2618.       record_unwind_protect (un_autoload, Vautoload_queue);
  2619.       Vautoload_queue = Qt;
  2620.  
  2621.       Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
  2622.          Qnil, Qt, Qnil, (NILP (file_name) ? Qt : Qnil));
  2623.  
  2624.       tem = Fmemq (feature, Vfeatures);
  2625.       if (NILP (tem))
  2626.     error ("Required feature %s was not provided",
  2627.            XSYMBOL (feature)->name->data);
  2628.  
  2629.       /* Once loading finishes, don't undo it.  */
  2630.       Vautoload_queue = Qt;
  2631.       feature = unbind_to (count, feature);
  2632.     }
  2633.   return feature;
  2634. }
  2635.  
  2636. /* Primitives for work of the "widget" library.
  2637.    In an ideal world, this section would not have been necessary.
  2638.    However, lisp function calls being as slow as they are, it turns
  2639.    out that some functions in the widget library (wid-edit.el) are the
  2640.    bottleneck of Widget operation.  Here is their translation to C,
  2641.    for the sole reason of efficiency.  */
  2642.  
  2643. DEFUN ("widget-plist-member", Fwidget_plist_member, Swidget_plist_member, 2, 2, 0,
  2644.   "Return non-nil if PLIST has the property PROP.\n\
  2645. PLIST is a property list, which is a list of the form\n\
  2646. \(PROP1 VALUE1 PROP2 VALUE2 ...\).  PROP is a symbol.\n\
  2647. Unlike `plist-get', this allows you to distinguish between a missing\n\
  2648. property and a property with the value nil.\n\
  2649. The value is actually the tail of PLIST whose car is PROP.")
  2650.   (plist, prop)
  2651.      Lisp_Object plist, prop;
  2652. {
  2653.   while (CONSP (plist) && !EQ (XCAR (plist), prop))
  2654.     {
  2655.       QUIT;
  2656.       plist = XCDR (plist);
  2657.       plist = CDR (plist);
  2658.     }
  2659.   return plist;
  2660. }
  2661.  
  2662. DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0,
  2663.   "In WIDGET, set PROPERTY to VALUE.\n\
  2664. The value can later be retrieved with `widget-get'.")
  2665.   (widget, property, value)
  2666.      Lisp_Object widget, property, value;
  2667. {
  2668.   CHECK_CONS (widget, 1);
  2669.   XCDR (widget) = Fplist_put (XCDR (widget), property, value);
  2670. }
  2671.  
  2672. DEFUN ("widget-get", Fwidget_get, Swidget_get, 2, 2, 0,
  2673.   "In WIDGET, get the value of PROPERTY.\n\
  2674. The value could either be specified when the widget was created, or\n\
  2675. later with `widget-put'.")
  2676.   (widget, property)
  2677.      Lisp_Object widget, property;
  2678. {
  2679.   Lisp_Object tmp;
  2680.  
  2681.   while (1)
  2682.     {
  2683.       if (NILP (widget))
  2684.     return Qnil;
  2685.       CHECK_CONS (widget, 1);
  2686.       tmp = Fwidget_plist_member (XCDR (widget), property);
  2687.       if (CONSP (tmp))
  2688.     {
  2689.       tmp = XCDR (tmp);
  2690.       return CAR (tmp);
  2691.     }
  2692.       tmp = XCAR (widget);
  2693.       if (NILP (tmp))
  2694.     return Qnil;
  2695.       widget = Fget (tmp, Qwidget_type);
  2696.     }
  2697. }
  2698.  
  2699. DEFUN ("widget-apply", Fwidget_apply, Swidget_apply, 2, MANY, 0,
  2700.   "Apply the value of WIDGET's PROPERTY to the widget itself.\n\
  2701. ARGS are passed as extra arguments to the function.")
  2702.   (nargs, args)
  2703.      int nargs;
  2704.      Lisp_Object *args;
  2705. {
  2706.   /* This function can GC. */
  2707.   Lisp_Object newargs[3];
  2708.   struct gcpro gcpro1, gcpro2;
  2709.   Lisp_Object result;
  2710.  
  2711.   newargs[0] = Fwidget_get (args[0], args[1]);
  2712.   newargs[1] = args[0];
  2713.   newargs[2] = Flist (nargs - 2, args + 2);
  2714.   GCPRO2 (newargs[0], newargs[2]);
  2715.   result = Fapply (3, newargs);
  2716.   UNGCPRO;
  2717.   return result;
  2718. }
  2719.  
  2720. void
  2721. syms_of_fns ()
  2722. {
  2723.   Qstring_lessp = intern ("string-lessp");
  2724.   staticpro (&Qstring_lessp);
  2725.   Qprovide = intern ("provide");
  2726.   staticpro (&Qprovide);
  2727.   Qrequire = intern ("require");
  2728.   staticpro (&Qrequire);
  2729.   Qyes_or_no_p_history = intern ("yes-or-no-p-history");
  2730.   staticpro (&Qyes_or_no_p_history);
  2731.   Qcursor_in_echo_area = intern ("cursor-in-echo-area");
  2732.   staticpro (&Qcursor_in_echo_area);
  2733.   Qwidget_type = intern ("widget-type");
  2734.   staticpro (&Qwidget_type);
  2735.  
  2736.   staticpro (&string_char_byte_cache_string);
  2737.   string_char_byte_cache_string = Qnil;
  2738.  
  2739.   Fset (Qyes_or_no_p_history, Qnil);
  2740.  
  2741.   DEFVAR_LISP ("features", &Vfeatures,
  2742.     "A list of symbols which are the features of the executing emacs.\n\
  2743. Used by `featurep' and `require', and altered by `provide'.");
  2744.   Vfeatures = Qnil;
  2745.  
  2746.   DEFVAR_BOOL ("use-dialog-box", &use_dialog_box,
  2747.     "*Non-nil means mouse commands use dialog boxes to ask questions.\n\
  2748. This applies to y-or-n and yes-or-no questions asked by commands\n\
  2749. invoked by mouse clicks and mouse menu items.");
  2750.   use_dialog_box = 1;
  2751.  
  2752.   defsubr (&Sidentity);
  2753.   defsubr (&Srandom);
  2754.   defsubr (&Slength);
  2755.   defsubr (&Ssafe_length);
  2756.   defsubr (&Sstring_bytes);
  2757.   defsubr (&Sstring_equal);
  2758.   defsubr (&Scompare_strings);
  2759.   defsubr (&Sstring_lessp);
  2760.   defsubr (&Sappend);
  2761.   defsubr (&Sconcat);
  2762.   defsubr (&Svconcat);
  2763.   defsubr (&Scopy_sequence);
  2764.   defsubr (&Sstring_make_multibyte);
  2765.   defsubr (&Sstring_make_unibyte);
  2766.   defsubr (&Sstring_as_multibyte);
  2767.   defsubr (&Sstring_as_unibyte);
  2768.   defsubr (&Scopy_alist);
  2769.   defsubr (&Ssubstring);
  2770.   defsubr (&Snthcdr);
  2771.   defsubr (&Snth);
  2772.   defsubr (&Selt);
  2773.   defsubr (&Smember);
  2774.   defsubr (&Smemq);
  2775.   defsubr (&Sassq);
  2776.   defsubr (&Sassoc);
  2777.   defsubr (&Srassq);
  2778.   defsubr (&Srassoc);
  2779.   defsubr (&Sdelq);
  2780.   defsubr (&Sdelete);
  2781.   defsubr (&Snreverse);
  2782.   defsubr (&Sreverse);
  2783.   defsubr (&Ssort);
  2784.   defsubr (&Splist_get);
  2785.   defsubr (&Sget);
  2786.   defsubr (&Splist_put);
  2787.   defsubr (&Sput);
  2788.   defsubr (&Sequal);
  2789.   defsubr (&Sfillarray);
  2790.   defsubr (&Schar_table_subtype);
  2791.   defsubr (&Schar_table_parent);
  2792.   defsubr (&Sset_char_table_parent);
  2793.   defsubr (&Schar_table_extra_slot);
  2794.   defsubr (&Sset_char_table_extra_slot);
  2795.   defsubr (&Schar_table_range);
  2796.   defsubr (&Sset_char_table_range);
  2797.   defsubr (&Sset_char_table_default);
  2798.   defsubr (&Smap_char_table);
  2799.   defsubr (&Snconc);
  2800.   defsubr (&Smapcar);
  2801.   defsubr (&Smapconcat);
  2802.   defsubr (&Sy_or_n_p);
  2803.   defsubr (&Syes_or_no_p);
  2804.   defsubr (&Sload_average);
  2805.   defsubr (&Sfeaturep);
  2806.   defsubr (&Srequire);
  2807.   defsubr (&Sprovide);
  2808.   defsubr (&Swidget_plist_member);
  2809.   defsubr (&Swidget_put);
  2810.   defsubr (&Swidget_get);
  2811.   defsubr (&Swidget_apply);
  2812. }
  2813.