#include <config.h>
#include <sys/types.h>
+#include <stdio.h>
#ifdef VMS
#include "vms-pwd.h"
#include <unistd.h>
#endif
-/* Without this, sprintf on Mac OS Classic will produce wrong
- result. */
-#ifdef MAC_OS8
-#include <stdio.h>
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+/* systime.h includes <sys/time.h> which, on some systems, is required
+ for <sys/resource.h>; thus systime.h must be included before
+ <sys/resource.h> */
+#include "systime.h"
+
+#if defined HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
#endif
#include <ctype.h>
#include "frame.h"
#include "window.h"
-#include "systime.h"
-
#ifdef STDC_HEADERS
#include <float.h>
#define MAX_10_EXP DBL_MAX_10_EXP
Lisp_Object Vuser_real_login_name; /* login name of current user ID */
Lisp_Object Vuser_full_name; /* full name of current user */
Lisp_Object Vuser_login_name; /* user name from LOGNAME or USER */
+Lisp_Object Voperating_system_release; /* Operating System Release */
/* Symbol for the text property used to mark fields. */
Vuser_full_name = build_string (p);
else if (NILP (Vuser_full_name))
Vuser_full_name = build_string ("unknown");
+
+#ifdef HAVE_SYS_UTSNAME_H
+ {
+ struct utsname uts;
+ uname (&uts);
+ Voperating_system_release = build_string (uts.release);
+ }
+#else
+ Voperating_system_release = Qnil;
+#endif
}
\f
DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
return "";
}
+char *
+get_operating_system_release()
+{
+ if (STRINGP (Voperating_system_release))
+ return (char *) SDATA (Voperating_system_release);
+ else
+ return "";
+}
+
DEFUN ("emacs-pid", Femacs_pid, Semacs_pid, 0, 0, 0,
doc: /* Return the process ID of Emacs, as an integer. */)
()
return Flist (3, result);
}
+
+DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
+ 0, 0, 0,
+ doc: /* Return the current run time used by Emacs.
+The time is returned as a list of three integers. The first has the
+most significant 16 bits of the seconds, while the second has the
+least significant 16 bits. The third integer gives the microsecond
+count.
+
+On systems that can't determine the run time, get-internal-run-time
+does the same thing as current-time. The microsecond count is zero on
+systems that do not provide resolution finer than a second. */)
+ ()
+{
+#ifdef HAVE_GETRUSAGE
+ struct rusage usage;
+ Lisp_Object result[3];
+ int secs, usecs;
+
+ if (getrusage (RUSAGE_SELF, &usage) < 0)
+ /* This shouldn't happen. What action is appropriate? */
+ Fsignal (Qerror, Qnil);
+
+ /* Sum up user time and system time. */
+ secs = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
+ usecs = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
+ if (usecs >= 1000000)
+ {
+ usecs -= 1000000;
+ secs++;
+ }
+
+ XSETINT (result[0], (secs >> 16) & 0xffff);
+ XSETINT (result[1], (secs >> 0) & 0xffff);
+ XSETINT (result[2], usecs);
+
+ return Flist (3, result);
+#else
+ return Fcurrent_time ();
+#endif
+}
\f
int
return Qnil;
}
-DEFUN ("translate-region", Ftranslate_region, Stranslate_region, 3, 3, 0,
- doc: /* From START to END, translate characters according to TABLE.
+DEFUN ("translate-region-internal", Ftranslate_region_internal,
+ Stranslate_region_internal, 3, 3, 0,
+ doc: /* Internal use only.
+From START to END, translate characters according to TABLE.
TABLE is a string; the Nth character in it is the mapping
for the character with code N.
It returns the number of characters changed. */)
register int nc; /* New character. */
int cnt; /* Number of changes made. */
int size; /* Size of translate table. */
- int pos, pos_byte;
+ int pos, pos_byte, end_pos;
int multibyte = !NILP (current_buffer->enable_multibyte_characters);
int string_multibyte;
validate_region (&start, &end);
- CHECK_STRING (table);
-
- if (multibyte != (SCHARS (table) < SBYTES (table)))
- table = (multibyte
- ? string_make_multibyte (table)
- : string_make_unibyte (table));
- string_multibyte = SCHARS (table) < SBYTES (table);
+ if (CHAR_TABLE_P (table))
+ {
+ size = MAX_CHAR;
+ tt = NULL;
+ }
+ else
+ {
+ CHECK_STRING (table);
- size = SCHARS (table);
- tt = SDATA (table);
+ if (! multibyte && (SCHARS (table) < SBYTES (table)))
+ table = string_make_unibyte (table);
+ string_multibyte = SCHARS (table) < SBYTES (table);
+ size = SCHARS (table);
+ tt = SDATA (table);
+ }
pos = XINT (start);
pos_byte = CHAR_TO_BYTE (pos);
+ end_pos = XINT (end);
modify_region (current_buffer, pos, XINT (end));
cnt = 0;
- for (; pos < XINT (end); )
+ for (; pos < end_pos; )
{
register unsigned char *p = BYTE_POS_ADDR (pos_byte);
- unsigned char *str;
+ unsigned char *str, buf[MAX_MULTIBYTE_LENGTH];
int len, str_len;
int oc;
oc = *p, len = 1;
if (oc < size)
{
- if (string_multibyte)
+ if (tt)
{
- str = tt + string_char_to_byte (table, oc);
- nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH, str_len);
+ if (string_multibyte)
+ {
+ str = tt + string_char_to_byte (table, oc);
+ nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH,
+ str_len);
+ }
+ else
+ {
+ nc = tt[oc];
+ if (! ASCII_BYTE_P (nc) && multibyte)
+ {
+ str_len = CHAR_STRING (nc, buf);
+ str = buf;
+ }
+ else
+ {
+ str_len = 1;
+ str = tt + oc;
+ }
+ }
}
else
{
- str = tt + oc;
- nc = tt[oc], str_len = 1;
+ Lisp_Object val;
+ int c;
+
+ nc = oc;
+ val = CHAR_TABLE_REF (table, oc);
+ if (INTEGERP (val)
+ && (c = XINT (val), CHAR_VALID_P (c, 0)))
+ {
+ nc = c;
+ str_len = CHAR_STRING (nc, buf);
+ str = buf;
+ }
}
+
if (nc != oc)
{
if (len != str_len)
Lisp_Object start, end;
{
validate_region (&start, &end);
+ if (XINT (start) == XINT (end))
+ return build_string ("");
return del_range_1 (XINT (start), XINT (end), 1, 1);
}
\f
DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
doc: /* Print a one-line message at the bottom of the screen.
+The message also goes into the `*Messages*' buffer.
+\(In keyboard macros, that's all it does.)
+
The first argument is a format control string, and the rest are data
to be formatted under control of the string. See `format' for details.
-If the first argument is nil, clear any existing message; let the
-minibuffer contents show.
+If the first argument is nil, the function clears any existing message;
+this lets the minibuffer contents show. See also `current-message'.
usage: (message STRING &rest ARGS) */)
(nargs, args)
&& SBYTES (args[0]) == 0))
{
message (0);
- return Qnil;
+ return args[0];
}
else
{
/* discarded[I] is 1 if byte I of the format
string was not copied into the output.
It is 2 if byte I was not the first byte of its character. */
- char *discarded;
+ char *discarded = 0;
/* Each element records, for one argument,
the start and end bytepos in the output string,
{
int nbytes = (nargs+1) * sizeof *info;
int i;
- info = (struct info *) alloca (nbytes);
+ if (!info)
+ info = (struct info *) alloca (nbytes);
bzero (info, nbytes);
for (i = 0; i <= nargs; i++)
info[i].start = -1;
- discarded = (char *) alloca (SBYTES (args[0]));
+ if (!discarded)
+ SAFE_ALLOCA (discarded, char *, SBYTES (args[0]));
bzero (discarded, SBYTES (args[0]));
}
val = make_specified_string (buf, nchars, p - buf, multibyte);
/* If we allocated BUF with malloc, free it too. */
- SAFE_FREE (total);
+ SAFE_FREE ();
/* If the format string has text properties, or any of the string
arguments has text properties, set up text properties of the
bcopy (start2_addr, temp, len2_byte);
bcopy (start1_addr, start1_addr + len2_byte, len1_byte);
bcopy (temp, start1_addr, len2_byte);
- SAFE_FREE (len2_byte);
+ SAFE_FREE ();
}
else
/* First region not smaller than second. */
bcopy (start1_addr, temp, len1_byte);
bcopy (start2_addr, start1_addr, len2_byte);
bcopy (temp, start1_addr + len2_byte, len1_byte);
- SAFE_FREE (len1_byte);
+ SAFE_FREE ();
}
graft_intervals_into_buffer (tmp_interval1, start1 + len2,
len1, current_buffer, 0);
bcopy (start1_addr, temp, len1_byte);
bcopy (start2_addr, start1_addr, len2_byte);
bcopy (temp, start2_addr, len1_byte);
- SAFE_FREE (len1_byte);
+ SAFE_FREE ();
graft_intervals_into_buffer (tmp_interval1, start2,
len1, current_buffer, 0);
bcopy (start1_addr, start1_addr + len_mid + len2_byte, len1_byte);
safe_bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
bcopy (temp, start1_addr, len2_byte);
- SAFE_FREE (len2_byte);
+ SAFE_FREE ();
graft_intervals_into_buffer (tmp_interval1, end2 - len1,
len1, current_buffer, 0);
bcopy (start2_addr, start1_addr, len2_byte);
bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
bcopy (temp, start1_addr + len2_byte + len_mid, len1_byte);
- SAFE_FREE (len1_byte);
+ SAFE_FREE ();
graft_intervals_into_buffer (tmp_interval1, end2 - len1,
len1, current_buffer, 0);
DEFVAR_LISP ("user-real-login-name", &Vuser_real_login_name,
doc: /* The user's name, based upon the real uid only. */);
+ DEFVAR_LISP ("operating-system-release", &Voperating_system_release,
+ doc: /* The release of the operating system Emacs is running on. */);
+
defsubr (&Spropertize);
defsubr (&Schar_equal);
defsubr (&Sgoto_char);
defsubr (&Suser_full_name);
defsubr (&Semacs_pid);
defsubr (&Scurrent_time);
+ defsubr (&Sget_internal_run_time);
defsubr (&Sformat_time_string);
defsubr (&Sfloat_time);
defsubr (&Sdecode_time);
defsubr (&Sinsert_buffer_substring);
defsubr (&Scompare_buffer_substrings);
defsubr (&Ssubst_char_in_region);
- defsubr (&Stranslate_region);
+ defsubr (&Stranslate_region_internal);
defsubr (&Sdelete_region);
defsubr (&Sdelete_and_extract_region);
defsubr (&Swiden);