/* 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
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 <http://www.gnu.org/licenses/>. */
#include <config.h>
#endif
#include <time.h>
-#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"
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'
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 ();
}
result_len += len;
+ if (result_len < 0)
+ error ("String overflow");
}
if (! some_multibyte)
thisindex++;
}
else
- elt = AREF (this, thisindex++);
+ {
+ elt = AREF (this, thisindex);
+ thisindex++;
+ }
/* Store this element into the result. */
if (toindex < 0)
tail = XCDR (tail);
}
else if (VECTORP (val))
- AREF (val, toindex++) = elt;
+ {
+ ASET (val, toindex, elt);
+ toindex++;
+ }
else
{
CHECK_NUMBER (elt);
}
\f
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 ()
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);
\f
/* 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);
Lisp_Object string;
{
unsigned char *buf;
- int nbytes;
+ EMACS_INT nbytes;
Lisp_Object ret;
USE_SAFE_ALLOCA;
Lisp_Object string;
{
unsigned char *buf;
- int nbytes;
+ EMACS_INT nbytes;
Lisp_Object ret;
USE_SAFE_ALLOCA;
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;
+}
+
\f
DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
doc: /* Return a copy of ALIST.
}
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;
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;
}
xprompt = prompt;
GCPRO2 (prompt, xprompt);
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
cancel_hourglass ();
#endif
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++)
{
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,
/* 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;
{
}
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;
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
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;
}
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,
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);
void
init_fns ()
{
- weak_hash_tables = NULL;
}
/* arch-tag: 787f8219-5b74-46bd-8469-7e1cc475fa31