X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a9989764a4d54bf58381d5c3902e575bdf314245..9719d4f782be2b7b70c8a4f0548d7f3e65a6ede1:/src/fns.c diff --git a/src/fns.c b/src/fns.c index 3a12768e62..0766383024 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1,14 +1,14 @@ /* Random utility Lisp functions. Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GNU Emacs. -GNU Emacs is free software; you can redistribute it and/or modify +GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GNU Emacs. If not, see . */ #include @@ -27,16 +25,11 @@ Boston, MA 02110-1301, USA. */ #endif #include -#ifndef MAC_OS -/* On Mac OS, defining this conflicts with precompiled headers. */ - /* Note on some machines this defines `vector' as a typedef, so make sure we don't use that name in this file. */ #undef vector #define vector ***** -#endif /* ! MAC_OSX */ - #include "lisp.h" #include "commands.h" #include "character.h" @@ -102,18 +95,19 @@ DEFUN ("random", Frandom, Srandom, 0, 1, 0, doc: /* Return a pseudo-random number. All integers representable in Lisp are equally likely. On most systems, this is 29 bits' worth. -With positive integer argument N, return random number in interval [0,N). -With argument t, set the random number seed from the current time and pid. */) - (n) - Lisp_Object n; +With positive integer LIMIT, return random number in interval [0,LIMIT). +With argument t, set the random number seed from the current time and pid. +Other values of LIMIT are ignored. */) + (limit) + Lisp_Object limit; { EMACS_INT val; Lisp_Object lispy_val; unsigned long denominator; - if (EQ (n, Qt)) + if (EQ (limit, Qt)) seed_random (getpid () + time (NULL)); - if (NATNUMP (n) && XFASTINT (n) != 0) + if (NATNUMP (limit) && XFASTINT (limit) != 0) { /* Try to take our random number from the higher bits of VAL, not the lower, since (says Gentzel) the low bits of `random' @@ -122,10 +116,10 @@ With argument t, set the random number seed from the current time and pid. */) it's possible to get a quotient larger than n; discarding these values eliminates the bias that would otherwise appear when using a large n. */ - denominator = ((unsigned long)1 << VALBITS) / XFASTINT (n); + denominator = ((unsigned long)1 << VALBITS) / XFASTINT (limit); do val = get_random () / denominator; - while (val >= XFASTINT (n)); + while (val >= XFASTINT (limit)); } else val = get_random (); @@ -609,6 +603,8 @@ concat (nargs, args, target_type, last_special) } result_len += len; + if (result_len < 0) + error ("String overflow"); } if (! some_multibyte) @@ -727,7 +723,10 @@ concat (nargs, args, target_type, last_special) thisindex++; } else - elt = AREF (this, thisindex++); + { + elt = AREF (this, thisindex); + thisindex++; + } /* Store this element into the result. */ if (toindex < 0) @@ -737,7 +736,10 @@ concat (nargs, args, target_type, last_special) tail = XCDR (tail); } else if (VECTORP (val)) - AREF (val, toindex++) = elt; + { + ASET (val, toindex, elt); + toindex++; + } else { CHECK_NUMBER (elt); @@ -780,8 +782,8 @@ concat (nargs, args, target_type, last_special) } static Lisp_Object string_char_byte_cache_string; -static int string_char_byte_cache_charpos; -static int string_char_byte_cache_bytepos; +static EMACS_INT string_char_byte_cache_charpos; +static EMACS_INT string_char_byte_cache_bytepos; void clear_string_char_byte_cache () @@ -789,16 +791,16 @@ clear_string_char_byte_cache () string_char_byte_cache_string = Qnil; } -/* Return the character index corresponding to CHAR_INDEX in STRING. */ +/* Return the byte index corresponding to CHAR_INDEX in STRING. */ -int +EMACS_INT string_char_to_byte (string, char_index) Lisp_Object string; - int char_index; + EMACS_INT char_index; { - int i_byte; - int best_below, best_below_byte; - int best_above, best_above_byte; + EMACS_INT i_byte; + EMACS_INT best_below, best_below_byte; + EMACS_INT best_above, best_above_byte; best_below = best_below_byte = 0; best_above = SCHARS (string); @@ -853,14 +855,14 @@ string_char_to_byte (string, char_index) /* Return the character index corresponding to BYTE_INDEX in STRING. */ -int +EMACS_INT string_byte_to_char (string, byte_index) Lisp_Object string; - int byte_index; + EMACS_INT byte_index; { - int i, i_byte; - int best_below, best_below_byte; - int best_above, best_above_byte; + EMACS_INT i, i_byte; + EMACS_INT best_below, best_below_byte; + EMACS_INT best_above, best_above_byte; best_below = best_below_byte = 0; best_above = SCHARS (string); @@ -924,7 +926,7 @@ string_make_multibyte (string) Lisp_Object string; { unsigned char *buf; - int nbytes; + EMACS_INT nbytes; Lisp_Object ret; USE_SAFE_ALLOCA; @@ -958,7 +960,7 @@ string_to_multibyte (string) Lisp_Object string; { unsigned char *buf; - int nbytes; + EMACS_INT nbytes; Lisp_Object ret; USE_SAFE_ALLOCA; @@ -1127,6 +1129,33 @@ correct sequence. */) return string_to_multibyte (string); } +DEFUN ("string-to-unibyte", Fstring_to_unibyte, Sstring_to_unibyte, + 1, 1, 0, + doc: /* Return a unibyte string with the same individual chars as STRING. +If STRING is unibyte, the result is STRING itself. +Otherwise it is a newly created string, with no text properties, +where each `eight-bit' character is converted to the corresponding byte. +If STRING contains a non-ASCII, non-`eight-bit' character, +an error is signaled. */) + (string) + Lisp_Object string; +{ + CHECK_STRING (string); + + if (STRING_MULTIBYTE (string)) + { + EMACS_INT chars = SCHARS (string); + unsigned char *str = (unsigned char *) xmalloc (chars); + EMACS_INT converted = str_to_unibyte (SDATA (string), str, chars, 0); + + if (converted < chars) + error ("Can't convert the %dth character to unibyte", converted); + string = make_unibyte_string (str, chars); + xfree (str); + } + return string; +} + DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0, doc: /* Return a copy of ALIST. @@ -1156,11 +1185,16 @@ Elements of ALIST that are not conses are also shared. */) } DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0, - doc: /* Return a substring of STRING, starting at index FROM and ending before TO. -TO may be nil or omitted; then the substring runs to the end of STRING. -FROM and TO start at 0. If either is negative, it counts from the end. - -This function allows vectors as well as strings. */) + doc: /* Return a new string whose contents are a substring of STRING. +The returned string consists of the characters between index FROM +\(inclusive) and index TO (exclusive) of STRING. FROM and TO are +zero-indexed: 0 means the first character of STRING. Negative values +are counted from the end of STRING. If TO is nil, the substring runs +to the end of STRING. + +The STRING argument may also be a vector. In that case, the return +value is a new vector that contains the elements between index FROM +\(inclusive) and index TO (exclusive) of that vector argument. */) (string, from, to) Lisp_Object string; register Lisp_Object from, to; @@ -2201,12 +2235,13 @@ internal_equal (o1, o2, depth, props) if (WINDOW_CONFIGURATIONP (o1)) return compare_window_configurations (o1, o2, 0); - /* Aside from them, only true vectors, char-tables, and compiled - functions are sensible to compare, so eliminate the others now. */ + /* Aside from them, only true vectors, char-tables, compiled + functions, and fonts (font-spec, font-entity, font-ojbect) + are sensible to compare, so eliminate the others now. */ if (size & PSEUDOVECTOR_FLAG) { if (!(size & (PVEC_COMPILED - | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE))) + | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE | PVEC_FONT))) return 0; size &= PSEUDOVECTOR_SIZE_MASK; } @@ -2594,7 +2629,7 @@ is nil and `use-dialog-box' is non-nil. */) xprompt = prompt; GCPRO2 (prompt, xprompt); -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) cancel_hourglass (); #endif @@ -3100,8 +3135,10 @@ The data read from the system are decoded using `locale-coding-system'. */) else if (EQ (item, Qdays)) /* e.g. for calendar-day-name-array */ { Lisp_Object v = Fmake_vector (make_number (7), Qnil); - int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7}; + const int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7}; int i; + struct gcpro gcpro1; + GCPRO1 (v); synchronize_system_time_locale (); for (i = 0; i < 7; i++) { @@ -3113,26 +3150,29 @@ The data read from the system are decoded using `locale-coding-system'. */) code_convert_string_norecord (val, Vlocale_coding_system, 0)); } + UNGCPRO; return v; } #endif /* DAY_1 */ #ifdef MON_1 else if (EQ (item, Qmonths)) /* e.g. for calendar-month-name-array */ { - struct Lisp_Vector *p = allocate_vector (12); - int months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7, - MON_8, MON_9, MON_10, MON_11, MON_12}; + Lisp_Object v = Fmake_vector (make_number (12), Qnil); + const int months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7, + MON_8, MON_9, MON_10, MON_11, MON_12}; int i; + struct gcpro gcpro1; + GCPRO1 (v); synchronize_system_time_locale (); for (i = 0; i < 12; i++) { str = nl_langinfo (months[i]); val = make_unibyte_string (str, strlen (str)); - p->contents[i] = - code_convert_string_norecord (val, Vlocale_coding_system, 0); + Faset (v, make_number (i), + code_convert_string_norecord (val, Vlocale_coding_system, 0)); } - XSETVECTOR (val, p); - return val; + UNGCPRO; + return v; } #endif /* MON_1 */ /* LC_PAPER stuff isn't defined as accessible in glibc as of 2.3.1, @@ -4172,8 +4212,8 @@ hash_put (h, key, value, hash) /* Remove the entry matching KEY from hash table H, if there is one. */ -void -hash_remove (h, key) +static void +hash_remove_from_table (h, key) struct Lisp_Hash_Table *h; Lisp_Object key; { @@ -4239,7 +4279,7 @@ hash_clear (h) } for (i = 0; i < ASIZE (h->index); ++i) - AREF (h->index, i) = Qnil; + ASET (h->index, i, Qnil); h->next_free = make_number (0); h->count = 0; @@ -4252,6 +4292,12 @@ hash_clear (h) Weak Hash Tables ************************************************************************/ +void +init_weak_hash_tables () +{ + weak_hash_tables = NULL; +} + /* Sweep weak hash table H. REMOVE_ENTRIES_P non-zero means remove entries from the table that don't survive the current GC. REMOVE_ENTRIES_P zero means mark entries that are in use. Value is @@ -4828,7 +4874,7 @@ DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0, Lisp_Object key, table; { struct Lisp_Hash_Table *h = check_hash_table (table); - hash_remove (h, key); + hash_remove_from_table (h, key); return Qnil; } @@ -5196,7 +5242,10 @@ Used by `featurep' and `require', and altered by `provide'. */); DEFVAR_BOOL ("use-dialog-box", &use_dialog_box, doc: /* *Non-nil means mouse commands use dialog boxes to ask questions. This applies to `y-or-n-p' and `yes-or-no-p' questions asked by commands -invoked by mouse clicks and mouse menu items. */); +invoked by mouse clicks and mouse menu items. + +On some platforms, file selection dialogs are also enabled if this is +non-nil. */); use_dialog_box = 1; DEFVAR_BOOL ("use-file-dialog", &use_file_dialog, @@ -5224,6 +5273,7 @@ both `use-dialog-box' and this variable are non-nil. */); defsubr (&Sstring_as_multibyte); defsubr (&Sstring_as_unibyte); defsubr (&Sstring_to_multibyte); + defsubr (&Sstring_to_unibyte); defsubr (&Scopy_alist); defsubr (&Ssubstring); defsubr (&Ssubstring_no_properties); @@ -5279,7 +5329,6 @@ both `use-dialog-box' and this variable are non-nil. */); void init_fns () { - weak_hash_tables = NULL; } /* arch-tag: 787f8219-5b74-46bd-8469-7e1cc475fa31