aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c209
1 files changed, 142 insertions, 67 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 28690e7c76d..1f98ff040b3 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -45,6 +45,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45#endif 45#endif
46 46
47#include <ctype.h> 47#include <ctype.h>
48#include <limits.h>
49#include <intprops.h>
48#include <strftime.h> 50#include <strftime.h>
49 51
50#include "intervals.h" 52#include "intervals.h"
@@ -87,6 +89,7 @@ extern char **environ;
87extern Lisp_Object w32_get_internal_run_time (void); 89extern Lisp_Object w32_get_internal_run_time (void);
88#endif 90#endif
89 91
92static void time_overflow (void) NO_RETURN;
90static int tm_diff (struct tm *, struct tm *); 93static int tm_diff (struct tm *, struct tm *);
91static void find_field (Lisp_Object, Lisp_Object, Lisp_Object, 94static void find_field (Lisp_Object, Lisp_Object, Lisp_Object,
92 EMACS_INT *, Lisp_Object, EMACS_INT *); 95 EMACS_INT *, Lisp_Object, EMACS_INT *);
@@ -119,7 +122,7 @@ Lisp_Object Qboundary;
119void 122void
120init_editfns (void) 123init_editfns (void)
121{ 124{
122 char *user_name; 125 const char *user_name;
123 register char *p; 126 register char *p;
124 struct passwd *pw; /* password entry for the current user */ 127 struct passwd *pw; /* password entry for the current user */
125 Lisp_Object tem; 128 Lisp_Object tem;
@@ -133,7 +136,7 @@ init_editfns (void)
133 return; 136 return;
134#endif /* not CANNOT_DUMP */ 137#endif /* not CANNOT_DUMP */
135 138
136 pw = (struct passwd *) getpwuid (getuid ()); 139 pw = getpwuid (getuid ());
137#ifdef MSDOS 140#ifdef MSDOS
138 /* We let the real user name default to "root" because that's quite 141 /* We let the real user name default to "root" because that's quite
139 accurate on MSDOG and because it lets Emacs find the init file. 142 accurate on MSDOG and because it lets Emacs find the init file.
@@ -145,17 +148,17 @@ init_editfns (void)
145 148
146 /* Get the effective user name, by consulting environment variables, 149 /* Get the effective user name, by consulting environment variables,
147 or the effective uid if those are unset. */ 150 or the effective uid if those are unset. */
148 user_name = (char *) getenv ("LOGNAME"); 151 user_name = getenv ("LOGNAME");
149 if (!user_name) 152 if (!user_name)
150#ifdef WINDOWSNT 153#ifdef WINDOWSNT
151 user_name = (char *) getenv ("USERNAME"); /* it's USERNAME on NT */ 154 user_name = getenv ("USERNAME"); /* it's USERNAME on NT */
152#else /* WINDOWSNT */ 155#else /* WINDOWSNT */
153 user_name = (char *) getenv ("USER"); 156 user_name = getenv ("USER");
154#endif /* WINDOWSNT */ 157#endif /* WINDOWSNT */
155 if (!user_name) 158 if (!user_name)
156 { 159 {
157 pw = (struct passwd *) getpwuid (geteuid ()); 160 pw = getpwuid (geteuid ());
158 user_name = (char *) (pw ? pw->pw_name : "unknown"); 161 user_name = pw ? pw->pw_name : "unknown";
159 } 162 }
160 Vuser_login_name = build_string (user_name); 163 Vuser_login_name = build_string (user_name);
161 164
@@ -1263,9 +1266,9 @@ of the user with that uid, or nil if there is no such user. */)
1263 if (NILP (uid)) 1266 if (NILP (uid))
1264 return Vuser_login_name; 1267 return Vuser_login_name;
1265 1268
1266 id = (uid_t)XFLOATINT (uid); 1269 id = XFLOATINT (uid);
1267 BLOCK_INPUT; 1270 BLOCK_INPUT;
1268 pw = (struct passwd *) getpwuid (id); 1271 pw = getpwuid (id);
1269 UNBLOCK_INPUT; 1272 UNBLOCK_INPUT;
1270 return (pw ? build_string (pw->pw_name) : Qnil); 1273 return (pw ? build_string (pw->pw_name) : Qnil);
1271} 1274}
@@ -1297,7 +1300,7 @@ Value is an integer or a float, depending on the value. */)
1297 /* Make sure we don't produce a negative UID due to signed integer 1300 /* Make sure we don't produce a negative UID due to signed integer
1298 overflow. */ 1301 overflow. */
1299 if (euid < 0) 1302 if (euid < 0)
1300 return make_float ((double)geteuid ()); 1303 return make_float (geteuid ());
1301 return make_fixnum_or_float (euid); 1304 return make_fixnum_or_float (euid);
1302} 1305}
1303 1306
@@ -1313,7 +1316,7 @@ Value is an integer or a float, depending on the value. */)
1313 /* Make sure we don't produce a negative UID due to signed integer 1316 /* Make sure we don't produce a negative UID due to signed integer
1314 overflow. */ 1317 overflow. */
1315 if (uid < 0) 1318 if (uid < 0)
1316 return make_float ((double)getuid ()); 1319 return make_float (getuid ());
1317 return make_fixnum_or_float (uid); 1320 return make_fixnum_or_float (uid);
1318} 1321}
1319 1322
@@ -1336,14 +1339,15 @@ name, or nil if there is no such user. */)
1336 return Vuser_full_name; 1339 return Vuser_full_name;
1337 else if (NUMBERP (uid)) 1340 else if (NUMBERP (uid))
1338 { 1341 {
1342 uid_t u = XFLOATINT (uid);
1339 BLOCK_INPUT; 1343 BLOCK_INPUT;
1340 pw = (struct passwd *) getpwuid ((uid_t) XFLOATINT (uid)); 1344 pw = getpwuid (u);
1341 UNBLOCK_INPUT; 1345 UNBLOCK_INPUT;
1342 } 1346 }
1343 else if (STRINGP (uid)) 1347 else if (STRINGP (uid))
1344 { 1348 {
1345 BLOCK_INPUT; 1349 BLOCK_INPUT;
1346 pw = (struct passwd *) getpwnam (SSDATA (uid)); 1350 pw = getpwnam (SSDATA (uid));
1347 UNBLOCK_INPUT; 1351 UNBLOCK_INPUT;
1348 } 1352 }
1349 else 1353 else
@@ -1371,7 +1375,7 @@ name, or nil if there is no such user. */)
1371 memcpy (r, p, q - p); 1375 memcpy (r, p, q - p);
1372 r[q - p] = 0; 1376 r[q - p] = 0;
1373 strcat (r, SSDATA (login)); 1377 strcat (r, SSDATA (login));
1374 r[q - p] = UPCASE ((unsigned char) r[q - p]); 1378 r[q - p] = upcase ((unsigned char) r[q - p]);
1375 strcat (r, q + 1); 1379 strcat (r, q + 1);
1376 full = build_string (r); 1380 full = build_string (r);
1377 } 1381 }
@@ -1387,8 +1391,6 @@ DEFUN ("system-name", Fsystem_name, Ssystem_name, 0, 0, 0,
1387 return Vsystem_name; 1391 return Vsystem_name;
1388} 1392}
1389 1393
1390/* For the benefit of callers who don't want to include lisp.h */
1391
1392const char * 1394const char *
1393get_system_name (void) 1395get_system_name (void)
1394{ 1396{
@@ -1414,6 +1416,49 @@ DEFUN ("emacs-pid", Femacs_pid, Semacs_pid, 0, 0, 0,
1414 return make_number (getpid ()); 1416 return make_number (getpid ());
1415} 1417}
1416 1418
1419
1420
1421#ifndef TIME_T_MIN
1422# define TIME_T_MIN TYPE_MINIMUM (time_t)
1423#endif
1424#ifndef TIME_T_MAX
1425# define TIME_T_MAX TYPE_MAXIMUM (time_t)
1426#endif
1427
1428/* Report that a time value is out of range for Emacs. */
1429static void
1430time_overflow (void)
1431{
1432 error ("Specified time is not representable");
1433}
1434
1435/* Return the upper part of the time T (everything but the bottom 16 bits),
1436 making sure that it is representable. */
1437static EMACS_INT
1438hi_time (time_t t)
1439{
1440 time_t hi = t >> 16;
1441
1442 /* Check for overflow, helping the compiler for common cases where
1443 no runtime check is needed, and taking care not to convert
1444 negative numbers to unsigned before comparing them. */
1445 if (! ((! TYPE_SIGNED (time_t)
1446 || MOST_NEGATIVE_FIXNUM <= TIME_T_MIN >> 16
1447 || MOST_NEGATIVE_FIXNUM <= hi)
1448 && (TIME_T_MAX >> 16 <= MOST_POSITIVE_FIXNUM
1449 || hi <= MOST_POSITIVE_FIXNUM)))
1450 time_overflow ();
1451
1452 return hi;
1453}
1454
1455/* Return the bottom 16 bits of the time T. */
1456static EMACS_INT
1457lo_time (time_t t)
1458{
1459 return t & ((1 << 16) - 1);
1460}
1461
1417DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0, 1462DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
1418 doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00. 1463 doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00.
1419The time is returned as a list of three integers. The first has the 1464The time is returned as a list of three integers. The first has the
@@ -1428,8 +1473,8 @@ resolution finer than a second. */)
1428 EMACS_TIME t; 1473 EMACS_TIME t;
1429 1474
1430 EMACS_GET_TIME (t); 1475 EMACS_GET_TIME (t);
1431 return list3 (make_number ((EMACS_SECS (t) >> 16) & 0xffff), 1476 return list3 (make_number (hi_time (EMACS_SECS (t))),
1432 make_number ((EMACS_SECS (t) >> 0) & 0xffff), 1477 make_number (lo_time (EMACS_SECS (t))),
1433 make_number (EMACS_USECS (t))); 1478 make_number (EMACS_USECS (t)));
1434} 1479}
1435 1480
@@ -1448,7 +1493,8 @@ on systems that do not provide resolution finer than a second. */)
1448{ 1493{
1449#ifdef HAVE_GETRUSAGE 1494#ifdef HAVE_GETRUSAGE
1450 struct rusage usage; 1495 struct rusage usage;
1451 int secs, usecs; 1496 time_t secs;
1497 int usecs;
1452 1498
1453 if (getrusage (RUSAGE_SELF, &usage) < 0) 1499 if (getrusage (RUSAGE_SELF, &usage) < 0)
1454 /* This shouldn't happen. What action is appropriate? */ 1500 /* This shouldn't happen. What action is appropriate? */
@@ -1463,8 +1509,8 @@ on systems that do not provide resolution finer than a second. */)
1463 secs++; 1509 secs++;
1464 } 1510 }
1465 1511
1466 return list3 (make_number ((secs >> 16) & 0xffff), 1512 return list3 (make_number (hi_time (secs)),
1467 make_number ((secs >> 0) & 0xffff), 1513 make_number (lo_time (secs)),
1468 make_number (usecs)); 1514 make_number (usecs));
1469#else /* ! HAVE_GETRUSAGE */ 1515#else /* ! HAVE_GETRUSAGE */
1470#ifdef WINDOWSNT 1516#ifdef WINDOWSNT
@@ -1476,6 +1522,19 @@ on systems that do not provide resolution finer than a second. */)
1476} 1522}
1477 1523
1478 1524
1525/* Make a Lisp list that represents the time T. */
1526Lisp_Object
1527make_time (time_t t)
1528{
1529 return list2 (make_number (hi_time (t)),
1530 make_number (lo_time (t)));
1531}
1532
1533/* Decode a Lisp list SPECIFIED_TIME that represents a time.
1534 If SPECIFIED_TIME is nil, use the current time.
1535 Set *RESULT to seconds since the Epoch.
1536 If USEC is not null, set *USEC to the microseconds component.
1537 Return nonzero if successful. */
1479int 1538int
1480lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec) 1539lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec)
1481{ 1540{
@@ -1496,6 +1555,7 @@ lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec)
1496 else 1555 else
1497 { 1556 {
1498 Lisp_Object high, low; 1557 Lisp_Object high, low;
1558 EMACS_INT hi;
1499 high = Fcar (specified_time); 1559 high = Fcar (specified_time);
1500 CHECK_NUMBER (high); 1560 CHECK_NUMBER (high);
1501 low = Fcdr (specified_time); 1561 low = Fcdr (specified_time);
@@ -1519,8 +1579,21 @@ lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec)
1519 else if (usec) 1579 else if (usec)
1520 *usec = 0; 1580 *usec = 0;
1521 CHECK_NUMBER (low); 1581 CHECK_NUMBER (low);
1522 *result = (XINT (high) << 16) + (XINT (low) & 0xffff); 1582 hi = XINT (high);
1523 return *result >> 16 == XINT (high); 1583
1584 /* Check for overflow, helping the compiler for common cases
1585 where no runtime check is needed, and taking care not to
1586 convert negative numbers to unsigned before comparing them. */
1587 if (! ((TYPE_SIGNED (time_t)
1588 ? (TIME_T_MIN >> 16 <= MOST_NEGATIVE_FIXNUM
1589 || TIME_T_MIN >> 16 <= hi)
1590 : 0 <= hi)
1591 && (MOST_POSITIVE_FIXNUM <= TIME_T_MAX >> 16
1592 || hi <= TIME_T_MAX >> 16)))
1593 return 0;
1594
1595 *result = (hi << 16) + (XINT (low) & 0xffff);
1596 return 1;
1524 } 1597 }
1525} 1598}
1526 1599
@@ -1648,7 +1721,7 @@ The modifiers are `E' and `O'. For certain characters X,
1648%OX is like %X, but uses the locale's number symbols. 1721%OX is like %X, but uses the locale's number symbols.
1649 1722
1650For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */) 1723For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1651 (Lisp_Object format_string, Lisp_Object time, Lisp_Object universal) 1724 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1652{ 1725{
1653 time_t value; 1726 time_t value;
1654 int size; 1727 int size;
@@ -1659,7 +1732,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1659 1732
1660 CHECK_STRING (format_string); 1733 CHECK_STRING (format_string);
1661 1734
1662 if (! (lisp_time_argument (time, &value, &usec) 1735 if (! (lisp_time_argument (timeval, &value, &usec)
1663 && 0 <= usec && usec < 1000000)) 1736 && 0 <= usec && usec < 1000000))
1664 error ("Invalid time specification"); 1737 error ("Invalid time specification");
1665 ns = usec * 1000; 1738 ns = usec * 1000;
@@ -1674,7 +1747,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1674 tm = ut ? gmtime (&value) : localtime (&value); 1747 tm = ut ? gmtime (&value) : localtime (&value);
1675 UNBLOCK_INPUT; 1748 UNBLOCK_INPUT;
1676 if (! tm) 1749 if (! tm)
1677 error ("Specified time is not representable"); 1750 time_overflow ();
1678 1751
1679 synchronize_system_time_locale (); 1752 synchronize_system_time_locale ();
1680 1753
@@ -1732,8 +1805,10 @@ DOW and ZONE.) */)
1732 BLOCK_INPUT; 1805 BLOCK_INPUT;
1733 decoded_time = localtime (&time_spec); 1806 decoded_time = localtime (&time_spec);
1734 UNBLOCK_INPUT; 1807 UNBLOCK_INPUT;
1735 if (! decoded_time) 1808 if (! (decoded_time
1736 error ("Specified time is not representable"); 1809 && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= decoded_time->tm_year
1810 && decoded_time->tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
1811 time_overflow ();
1737 XSETFASTINT (list_args[0], decoded_time->tm_sec); 1812 XSETFASTINT (list_args[0], decoded_time->tm_sec);
1738 XSETFASTINT (list_args[1], decoded_time->tm_min); 1813 XSETFASTINT (list_args[1], decoded_time->tm_min);
1739 XSETFASTINT (list_args[2], decoded_time->tm_hour); 1814 XSETFASTINT (list_args[2], decoded_time->tm_hour);
@@ -1757,6 +1832,20 @@ DOW and ZONE.) */)
1757 return Flist (9, list_args); 1832 return Flist (9, list_args);
1758} 1833}
1759 1834
1835/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that
1836 the result is representable as an int. Assume OFFSET is small and
1837 nonnegative. */
1838static int
1839check_tm_member (Lisp_Object obj, int offset)
1840{
1841 EMACS_INT n;
1842 CHECK_NUMBER (obj);
1843 n = XINT (obj);
1844 if (! (INT_MIN + offset <= n && n - offset <= INT_MAX))
1845 time_overflow ();
1846 return n - offset;
1847}
1848
1760DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0, 1849DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
1761 doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time. 1850 doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.
1762This is the reverse operation of `decode-time', which see. 1851This is the reverse operation of `decode-time', which see.
@@ -1781,23 +1870,16 @@ year values as low as 1901 do work.
1781usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) 1870usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1782 (int nargs, register Lisp_Object *args) 1871 (int nargs, register Lisp_Object *args)
1783{ 1872{
1784 time_t time; 1873 time_t value;
1785 struct tm tm; 1874 struct tm tm;
1786 Lisp_Object zone = (nargs > 6 ? args[nargs - 1] : Qnil); 1875 Lisp_Object zone = (nargs > 6 ? args[nargs - 1] : Qnil);
1787 1876
1788 CHECK_NUMBER (args[0]); /* second */ 1877 tm.tm_sec = check_tm_member (args[0], 0);
1789 CHECK_NUMBER (args[1]); /* minute */ 1878 tm.tm_min = check_tm_member (args[1], 0);
1790 CHECK_NUMBER (args[2]); /* hour */ 1879 tm.tm_hour = check_tm_member (args[2], 0);
1791 CHECK_NUMBER (args[3]); /* day */ 1880 tm.tm_mday = check_tm_member (args[3], 0);
1792 CHECK_NUMBER (args[4]); /* month */ 1881 tm.tm_mon = check_tm_member (args[4], 1);
1793 CHECK_NUMBER (args[5]); /* year */ 1882 tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
1794
1795 tm.tm_sec = XINT (args[0]);
1796 tm.tm_min = XINT (args[1]);
1797 tm.tm_hour = XINT (args[2]);
1798 tm.tm_mday = XINT (args[3]);
1799 tm.tm_mon = XINT (args[4]) - 1;
1800 tm.tm_year = XINT (args[5]) - TM_YEAR_BASE;
1801 tm.tm_isdst = -1; 1883 tm.tm_isdst = -1;
1802 1884
1803 if (CONSP (zone)) 1885 if (CONSP (zone))
@@ -1805,7 +1887,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1805 if (NILP (zone)) 1887 if (NILP (zone))
1806 { 1888 {
1807 BLOCK_INPUT; 1889 BLOCK_INPUT;
1808 time = mktime (&tm); 1890 value = mktime (&tm);
1809 UNBLOCK_INPUT; 1891 UNBLOCK_INPUT;
1810 } 1892 }
1811 else 1893 else
@@ -1833,7 +1915,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1833 set_time_zone_rule (tzstring); 1915 set_time_zone_rule (tzstring);
1834 1916
1835 BLOCK_INPUT; 1917 BLOCK_INPUT;
1836 time = mktime (&tm); 1918 value = mktime (&tm);
1837 UNBLOCK_INPUT; 1919 UNBLOCK_INPUT;
1838 1920
1839 /* Restore TZ to previous value. */ 1921 /* Restore TZ to previous value. */
@@ -1845,10 +1927,10 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1845#endif 1927#endif
1846 } 1928 }
1847 1929
1848 if (time == (time_t) -1) 1930 if (value == (time_t) -1)
1849 error ("Specified time is not representable"); 1931 time_overflow ();
1850 1932
1851 return make_time (time); 1933 return make_time (value);
1852} 1934}
1853 1935
1854DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0, 1936DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0,
@@ -1881,7 +1963,7 @@ but this is considered obsolete. */)
1881 tm = localtime (&value); 1963 tm = localtime (&value);
1882 UNBLOCK_INPUT; 1964 UNBLOCK_INPUT;
1883 if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year) && (tem = asctime (tm)))) 1965 if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year) && (tem = asctime (tm))))
1884 error ("Specified time is not representable"); 1966 time_overflow ();
1885 1967
1886 /* Remove the trailing newline. */ 1968 /* Remove the trailing newline. */
1887 tem[strlen (tem) - 1] = '\0'; 1969 tem[strlen (tem) - 1] = '\0';
@@ -2258,7 +2340,7 @@ from adjoining text, if those properties are sticky. */)
2258 (Lisp_Object character, Lisp_Object count, Lisp_Object inherit) 2340 (Lisp_Object character, Lisp_Object count, Lisp_Object inherit)
2259{ 2341{
2260 register char *string; 2342 register char *string;
2261 register EMACS_INT strlen; 2343 register EMACS_INT stringlen;
2262 register int i; 2344 register int i;
2263 register EMACS_INT n; 2345 register EMACS_INT n;
2264 int len; 2346 int len;
@@ -2276,18 +2358,18 @@ from adjoining text, if those properties are sticky. */)
2276 n = XINT (count) * len; 2358 n = XINT (count) * len;
2277 if (n <= 0) 2359 if (n <= 0)
2278 return Qnil; 2360 return Qnil;
2279 strlen = min (n, 256 * len); 2361 stringlen = min (n, 256 * len);
2280 string = (char *) alloca (strlen); 2362 string = (char *) alloca (stringlen);
2281 for (i = 0; i < strlen; i++) 2363 for (i = 0; i < stringlen; i++)
2282 string[i] = str[i % len]; 2364 string[i] = str[i % len];
2283 while (n >= strlen) 2365 while (n >= stringlen)
2284 { 2366 {
2285 QUIT; 2367 QUIT;
2286 if (!NILP (inherit)) 2368 if (!NILP (inherit))
2287 insert_and_inherit (string, strlen); 2369 insert_and_inherit (string, stringlen);
2288 else 2370 else
2289 insert (string, strlen); 2371 insert (string, stringlen);
2290 n -= strlen; 2372 n -= stringlen;
2291 } 2373 }
2292 if (n > 0) 2374 if (n > 0)
2293 { 2375 {
@@ -2946,8 +3028,7 @@ It returns the number of characters changed. */)
2946 EMACS_INT size; /* Size of translate table. */ 3028 EMACS_INT size; /* Size of translate table. */
2947 EMACS_INT pos, pos_byte, end_pos; 3029 EMACS_INT pos, pos_byte, end_pos;
2948 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); 3030 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2949 int string_multibyte; 3031 int string_multibyte IF_LINT (= 0);
2950 Lisp_Object val;
2951 3032
2952 validate_region (&start, &end); 3033 validate_region (&start, &end);
2953 if (CHAR_TABLE_P (table)) 3034 if (CHAR_TABLE_P (table))
@@ -3846,7 +3927,7 @@ usage: (format STRING &rest OBJECTS) */)
3846 /* handle case (precision[n] >= 0) */ 3927 /* handle case (precision[n] >= 0) */
3847 3928
3848 int width, padding; 3929 int width, padding;
3849 EMACS_INT nbytes, start, end; 3930 EMACS_INT nbytes, start;
3850 EMACS_INT nchars_string; 3931 EMACS_INT nchars_string;
3851 3932
3852 /* lisp_string_width ignores a precision of 0, but GNU 3933 /* lisp_string_width ignores a precision of 0, but GNU
@@ -3878,7 +3959,6 @@ usage: (format STRING &rest OBJECTS) */)
3878 3959
3879 info[n].start = start = nchars; 3960 info[n].start = start = nchars;
3880 nchars += nchars_string; 3961 nchars += nchars_string;
3881 end = nchars;
3882 3962
3883 if (p > buf 3963 if (p > buf
3884 && multibyte 3964 && multibyte
@@ -4130,7 +4210,7 @@ Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
4130{ 4210{
4131 int i1, i2; 4211 int i1, i2;
4132 /* Check they're chars, not just integers, otherwise we could get array 4212 /* Check they're chars, not just integers, otherwise we could get array
4133 bounds violations in DOWNCASE. */ 4213 bounds violations in downcase. */
4134 CHECK_CHARACTER (c1); 4214 CHECK_CHARACTER (c1);
4135 CHECK_CHARACTER (c2); 4215 CHECK_CHARACTER (c2);
4136 4216
@@ -4139,9 +4219,6 @@ Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
4139 if (NILP (BVAR (current_buffer, case_fold_search))) 4219 if (NILP (BVAR (current_buffer, case_fold_search)))
4140 return Qnil; 4220 return Qnil;
4141 4221
4142 /* Do these in separate statements,
4143 then compare the variables.
4144 because of the way DOWNCASE uses temp variables. */
4145 i1 = XFASTINT (c1); 4222 i1 = XFASTINT (c1);
4146 if (NILP (BVAR (current_buffer, enable_multibyte_characters)) 4223 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
4147 && ! ASCII_CHAR_P (i1)) 4224 && ! ASCII_CHAR_P (i1))
@@ -4154,9 +4231,7 @@ Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
4154 { 4231 {
4155 MAKE_CHAR_MULTIBYTE (i2); 4232 MAKE_CHAR_MULTIBYTE (i2);
4156 } 4233 }
4157 i1 = DOWNCASE (i1); 4234 return (downcase (i1) == downcase (i2) ? Qt : Qnil);
4158 i2 = DOWNCASE (i2);
4159 return (i1 == i2 ? Qt : Qnil);
4160} 4235}
4161 4236
4162/* Transpose the markers in two regions of the current buffer, and 4237/* Transpose the markers in two regions of the current buffer, and