Mercurial > hg > xemacs-beta
comparison src/fns.c @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | ee648375d8d6 |
children | c0c698873ce1 |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
121 extern long get_random (void); | 121 extern long get_random (void); |
122 extern void seed_random (long arg); | 122 extern void seed_random (long arg); |
123 | 123 |
124 DEFUN ("random", Frandom, 0, 1, 0, /* | 124 DEFUN ("random", Frandom, 0, 1, 0, /* |
125 Return a pseudo-random number. | 125 Return a pseudo-random number. |
126 All integers representable in Lisp are equally likely. | 126 All integers representable in Lisp are equally likely.\n\ |
127 On most systems, this is 28 bits' worth. | 127 On most systems, this is 28 bits' worth.\n\ |
128 With positive integer argument N, return random number in interval [0,N). | 128 With positive integer argument N, return random number in interval [0,N).\n\ |
129 With argument t, set the random number seed from the current time and pid. | 129 With argument t, set the random number seed from the current time and pid. |
130 */ | 130 */ |
131 (limit)) | 131 (limit)) |
132 { | 132 { |
133 EMACS_INT val; | 133 EMACS_INT val; |
270 Case is significant. Text properties are ignored. | 270 Case is significant. Text properties are ignored. |
271 (Under XEmacs, `equal' also ignores text properties and extents in | 271 (Under XEmacs, `equal' also ignores text properties and extents in |
272 strings, but this is not the case under FSF Emacs.) | 272 strings, but this is not the case under FSF Emacs.) |
273 Symbols are also allowed; their print names are used instead. | 273 Symbols are also allowed; their print names are used instead. |
274 */ | 274 */ |
275 (s1, s2)) | 275 (s1, s2)) |
276 { | 276 { |
277 int len; | 277 int len; |
278 | 278 |
279 if (SYMBOLP (s1)) | 279 if (SYMBOLP (s1)) |
280 XSETSTRING (s1, XSYMBOL (s1)->name); | 280 XSETSTRING (s1, XSYMBOL (s1)->name); |
291 } | 291 } |
292 | 292 |
293 | 293 |
294 DEFUN ("string-lessp", Fstring_lessp, 2, 2, 0, /* | 294 DEFUN ("string-lessp", Fstring_lessp, 2, 2, 0, /* |
295 T if first arg string is less than second in lexicographic order. | 295 T if first arg string is less than second in lexicographic order. |
296 If I18N2 support was compiled in, ordering is determined by the locale. | 296 If I18N2 support (but not Mule support) was compiled in, ordering is |
297 Case is significant for the default C locale. | 297 determined by the locale. (Case is significant for the default C locale.) |
298 In all other cases, comparison is simply done on a character-by- | |
299 character basis using the numeric value of a character. (Note that | |
300 this may not produce particularly meaningful results under Mule if | |
301 characters from different charsets are being compared.) | |
302 | |
298 Symbols are also allowed; their print names are used instead. | 303 Symbols are also allowed; their print names are used instead. |
304 | |
305 The reason that the I18N2 locale-specific collation is not used under | |
306 Mule is that the locale model of internationalization does not handle | |
307 multiple charsets and thus has no hope of working properly under Mule. | |
308 What we really should do is create a collation table over all built-in | |
309 charsets. This is extremely difficult to do from scratch, however. | |
310 | |
311 Unicode is a good first step towards solving this problem. In fact, | |
312 it is quite likely that a collation table exists (or will exist) for | |
313 Unicode. When Unicode support is added to XEmacs/Mule, this problem | |
314 may be solved. | |
299 */ | 315 */ |
300 (s1, s2)) | 316 (s1, s2)) |
301 { | 317 { |
302 struct Lisp_String *p1, *p2; | 318 struct Lisp_String *p1, *p2; |
303 Charcount end, len2; | 319 Charcount end, len2; |
317 end = len2; | 333 end = len2; |
318 | 334 |
319 { | 335 { |
320 int i; | 336 int i; |
321 | 337 |
322 #ifdef I18N2 | 338 #if defined (I18N2) && !defined (MULE) |
339 /* There is no hope of this working under Mule. Even if we converted | |
340 the data into an external format so that strcoll() processed it | |
341 properly, it would still not work because strcoll() does not | |
342 handle multiple locales. This is the fundamental flaw in the | |
343 locale model. */ | |
323 Bytecount bcend = charcount_to_bytecount (string_data (p1), end); | 344 Bytecount bcend = charcount_to_bytecount (string_data (p1), end); |
324 /* Compare strings using collation order of locale. */ | 345 /* Compare strings using collation order of locale. */ |
325 /* Need to be tricky to handle embedded nulls. */ | 346 /* Need to be tricky to handle embedded nulls. */ |
326 | 347 |
327 for (i = 0; i < bcend; i += strlen((char *) string_data (p1) + i) + 1) | 348 for (i = 0; i < bcend; i += strlen((char *) string_data (p1) + i) + 1) |
331 if (val < 0) | 352 if (val < 0) |
332 return Qt; | 353 return Qt; |
333 if (val > 0) | 354 if (val > 0) |
334 return Qnil; | 355 return Qnil; |
335 } | 356 } |
336 #else /* not I18N2 */ | 357 #else /* not I18N2, or MULE */ |
358 /* #### It is not really necessary to do this: We could compare | |
359 byte-by-byte and still get a reasonable comparison, since this | |
360 would compare characters with a charset in the same way. | |
361 With a little rearrangement of the leading bytes, we could | |
362 make most inter-charset comparisons work out the same, too; | |
363 even if some don't, this is not a big deal because inter-charset | |
364 comparisons aren't really well-defined anyway. */ | |
337 for (i = 0; i < end; i++) | 365 for (i = 0; i < end; i++) |
338 { | 366 { |
339 if (string_char (p1, i) != string_char (p2, i)) | 367 if (string_char (p1, i) != string_char (p2, i)) |
340 return string_char (p1, i) < string_char (p2, i) ? Qt : Qnil; | 368 return string_char (p1, i) < string_char (p2, i) ? Qt : Qnil; |
341 } | 369 } |
342 #endif /* not I18N2 */ | 370 #endif /* not I18N2, or MULE */ |
343 /* Can't do i < len2 because then comparison between "foo" and "foo^@" | 371 /* Can't do i < len2 because then comparison between "foo" and "foo^@" |
344 won't work right in I18N2 case */ | 372 won't work right in I18N2 case */ |
345 return ((end < len2) ? Qt : Qnil); | 373 return ((end < len2) ? Qt : Qnil); |
346 } | 374 } |
347 } | 375 } |
1057 QUIT; | 1085 QUIT; |
1058 } | 1086 } |
1059 return Qnil; | 1087 return Qnil; |
1060 } | 1088 } |
1061 | 1089 |
1090 DEFUN ("old-member", Fold_member, 2, 2, 0, /* | |
1091 Return non-nil if ELT is an element of LIST. Comparison done with `old-equal'. | |
1092 The value is actually the tail of LIST whose car is ELT. | |
1093 This function is provided only for byte-code compatibility with v19. | |
1094 Do not use it. | |
1095 */ | |
1096 (elt, list)) | |
1097 { | |
1098 REGISTER Lisp_Object tail, tem; | |
1099 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | |
1100 { | |
1101 tem = Fcar (tail); | |
1102 if (! NILP (Fold_equal (elt, tem))) | |
1103 return tail; | |
1104 QUIT; | |
1105 } | |
1106 return Qnil; | |
1107 } | |
1108 | |
1062 DEFUN ("memq", Fmemq, 2, 2, 0, /* | 1109 DEFUN ("memq", Fmemq, 2, 2, 0, /* |
1063 Return non-nil if ELT is an element of LIST. Comparison done with `eq'. | 1110 Return non-nil if ELT is an element of LIST. Comparison done with `eq'. |
1064 The value is actually the tail of LIST whose car is ELT. | 1111 The value is actually the tail of LIST whose car is ELT. |
1065 */ | 1112 */ |
1066 (elt, list)) | 1113 (elt, list)) |
1067 { | 1114 { |
1068 REGISTER Lisp_Object tail, tem; | 1115 REGISTER Lisp_Object tail, tem; |
1069 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1116 for (tail = list; !NILP (tail); tail = Fcdr (tail)) |
1070 { | 1117 { |
1071 tem = Fcar (tail); | 1118 tem = Fcar (tail); |
1119 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) return tail; | |
1120 QUIT; | |
1121 } | |
1122 return Qnil; | |
1123 } | |
1124 | |
1125 DEFUN ("old-memq", Fold_memq, 2, 2, 0, /* | |
1126 Return non-nil if ELT is an element of LIST. Comparison done with `old-eq'. | |
1127 The value is actually the tail of LIST whose car is ELT. | |
1128 This function is provided only for byte-code compatibility with v19. | |
1129 Do not use it. | |
1130 */ | |
1131 (elt, list)) | |
1132 { | |
1133 REGISTER Lisp_Object tail, tem; | |
1134 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | |
1135 { | |
1136 tem = Fcar (tail); | |
1072 if (HACKEQ_UNSAFE (elt, tem)) return tail; | 1137 if (HACKEQ_UNSAFE (elt, tem)) return tail; |
1073 QUIT; | 1138 QUIT; |
1074 } | 1139 } |
1075 return Qnil; | 1140 return Qnil; |
1076 } | 1141 } |
1080 { | 1145 { |
1081 REGISTER Lisp_Object tail, tem; | 1146 REGISTER Lisp_Object tail, tem; |
1082 for (tail = list; CONSP (tail); tail = XCDR (tail)) | 1147 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
1083 { | 1148 { |
1084 tem = XCAR (tail); | 1149 tem = XCAR (tail); |
1085 if (HACKEQ_UNSAFE (elt, tem)) return tail; | 1150 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) return tail; |
1086 } | 1151 } |
1087 return Qnil; | 1152 return Qnil; |
1088 } | 1153 } |
1089 | 1154 |
1090 DEFUN ("assoc", Fassoc, 2, 2, 0, /* | 1155 DEFUN ("assoc", Fassoc, 2, 2, 0, /* |
1104 QUIT; | 1169 QUIT; |
1105 } | 1170 } |
1106 return Qnil; | 1171 return Qnil; |
1107 } | 1172 } |
1108 | 1173 |
1174 DEFUN ("old-assoc", Fold_assoc, 2, 2, 0, /* | |
1175 Return non-nil if KEY is `old-equal' to the car of an element of LIST. | |
1176 The value is actually the element of LIST whose car equals KEY. | |
1177 */ | |
1178 (key, list)) | |
1179 { | |
1180 /* This function can GC. */ | |
1181 REGISTER Lisp_Object tail, elt, tem; | |
1182 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | |
1183 { | |
1184 elt = Fcar (tail); | |
1185 if (!CONSP (elt)) continue; | |
1186 tem = Fold_equal (Fcar (elt), key); | |
1187 if (!NILP (tem)) return elt; | |
1188 QUIT; | |
1189 } | |
1190 return Qnil; | |
1191 } | |
1192 | |
1109 Lisp_Object | 1193 Lisp_Object |
1110 assoc_no_quit (Lisp_Object key, Lisp_Object list) | 1194 assoc_no_quit (Lisp_Object key, Lisp_Object list) |
1111 { | 1195 { |
1112 int speccount = specpdl_depth (); | 1196 int speccount = specpdl_depth (); |
1113 specbind (Qinhibit_quit, Qt); | 1197 specbind (Qinhibit_quit, Qt); |
1116 | 1200 |
1117 DEFUN ("assq", Fassq, 2, 2, 0, /* | 1201 DEFUN ("assq", Fassq, 2, 2, 0, /* |
1118 Return non-nil if KEY is `eq' to the car of an element of LIST. | 1202 Return non-nil if KEY is `eq' to the car of an element of LIST. |
1119 The value is actually the element of LIST whose car is KEY. | 1203 The value is actually the element of LIST whose car is KEY. |
1120 Elements of LIST that are not conses are ignored. | 1204 Elements of LIST that are not conses are ignored. |
1205 */ | |
1206 (key, list)) | |
1207 { | |
1208 REGISTER Lisp_Object tail, elt, tem; | |
1209 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | |
1210 { | |
1211 elt = Fcar (tail); | |
1212 if (!CONSP (elt)) continue; | |
1213 tem = Fcar (elt); | |
1214 if (EQ_WITH_EBOLA_NOTICE (key, tem)) return elt; | |
1215 QUIT; | |
1216 } | |
1217 return Qnil; | |
1218 } | |
1219 | |
1220 DEFUN ("old-assq", Fold_assq, 2, 2, 0, /* | |
1221 Return non-nil if KEY is `old-eq' to the car of an element of LIST. | |
1222 The value is actually the element of LIST whose car is KEY. | |
1223 Elements of LIST that are not conses are ignored. | |
1224 This function is provided only for byte-code compatibility with v19. | |
1225 Do not use it. | |
1121 */ | 1226 */ |
1122 (key, list)) | 1227 (key, list)) |
1123 { | 1228 { |
1124 REGISTER Lisp_Object tail, elt, tem; | 1229 REGISTER Lisp_Object tail, elt, tem; |
1125 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1230 for (tail = list; !NILP (tail); tail = Fcdr (tail)) |
1144 for (tail = list; CONSP (tail); tail = XCDR (tail)) | 1249 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
1145 { | 1250 { |
1146 elt = XCAR (tail); | 1251 elt = XCAR (tail); |
1147 if (!CONSP (elt)) continue; | 1252 if (!CONSP (elt)) continue; |
1148 tem = XCAR (elt); | 1253 tem = XCAR (elt); |
1149 if (HACKEQ_UNSAFE (key, tem)) return elt; | 1254 if (EQ_WITH_EBOLA_NOTICE (key, tem)) return elt; |
1150 } | 1255 } |
1151 return Qnil; | 1256 return Qnil; |
1152 } | 1257 } |
1153 | 1258 |
1154 DEFUN ("rassoc", Frassoc, 2, 2, 0, /* | 1259 DEFUN ("rassoc", Frassoc, 2, 2, 0, /* |
1168 QUIT; | 1273 QUIT; |
1169 } | 1274 } |
1170 return Qnil; | 1275 return Qnil; |
1171 } | 1276 } |
1172 | 1277 |
1278 DEFUN ("old-rassoc", Fold_rassoc, 2, 2, 0, /* | |
1279 Return non-nil if KEY is `old-equal' to the cdr of an element of LIST. | |
1280 The value is actually the element of LIST whose cdr equals KEY. | |
1281 */ | |
1282 (key, list)) | |
1283 { | |
1284 REGISTER Lisp_Object tail; | |
1285 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | |
1286 { | |
1287 REGISTER Lisp_Object elt, tem; | |
1288 elt = Fcar (tail); | |
1289 if (!CONSP (elt)) continue; | |
1290 tem = Fold_equal (Fcdr (elt), key); | |
1291 if (!NILP (tem)) return elt; | |
1292 QUIT; | |
1293 } | |
1294 return Qnil; | |
1295 } | |
1296 | |
1173 DEFUN ("rassq", Frassq, 2, 2, 0, /* | 1297 DEFUN ("rassq", Frassq, 2, 2, 0, /* |
1174 Return non-nil if KEY is `eq' to the cdr of an element of LIST. | 1298 Return non-nil if KEY is `eq' to the cdr of an element of LIST. |
1299 The value is actually the element of LIST whose cdr is KEY. | |
1300 */ | |
1301 (key, list)) | |
1302 { | |
1303 REGISTER Lisp_Object tail, elt, tem; | |
1304 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | |
1305 { | |
1306 elt = Fcar (tail); | |
1307 if (!CONSP (elt)) continue; | |
1308 tem = Fcdr (elt); | |
1309 if (EQ_WITH_EBOLA_NOTICE (key, tem)) return elt; | |
1310 QUIT; | |
1311 } | |
1312 return Qnil; | |
1313 } | |
1314 | |
1315 DEFUN ("old-rassq", Fold_rassq, 2, 2, 0, /* | |
1316 Return non-nil if KEY is `old-eq' to the cdr of an element of LIST. | |
1175 The value is actually the element of LIST whose cdr is KEY. | 1317 The value is actually the element of LIST whose cdr is KEY. |
1176 */ | 1318 */ |
1177 (key, list)) | 1319 (key, list)) |
1178 { | 1320 { |
1179 REGISTER Lisp_Object tail, elt, tem; | 1321 REGISTER Lisp_Object tail, elt, tem; |
1195 for (tail = list; CONSP (tail); tail = XCDR (tail)) | 1337 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
1196 { | 1338 { |
1197 elt = XCAR (tail); | 1339 elt = XCAR (tail); |
1198 if (!CONSP (elt)) continue; | 1340 if (!CONSP (elt)) continue; |
1199 tem = XCDR (elt); | 1341 tem = XCDR (elt); |
1200 if (HACKEQ_UNSAFE (key, tem)) return elt; | 1342 if (EQ_WITH_EBOLA_NOTICE (key, tem)) return elt; |
1201 } | 1343 } |
1202 return Qnil; | 1344 return Qnil; |
1203 } | 1345 } |
1204 | 1346 |
1205 | 1347 |
1231 QUIT; | 1373 QUIT; |
1232 } | 1374 } |
1233 return list; | 1375 return list; |
1234 } | 1376 } |
1235 | 1377 |
1378 DEFUN ("old-delete", Fold_delete, 2, 2, 0, /* | |
1379 Delete by side effect any occurrences of ELT as a member of LIST. | |
1380 The modified LIST is returned. Comparison is done with `old-equal'. | |
1381 If the first member of LIST is ELT, there is no way to remove it by side | |
1382 effect; therefore, write `(setq foo (delete element foo))' to be sure | |
1383 of changing the value of `foo'. | |
1384 */ | |
1385 (elt, list)) | |
1386 { | |
1387 REGISTER Lisp_Object tail, prev; | |
1388 | |
1389 tail = list; | |
1390 prev = Qnil; | |
1391 while (!NILP (tail)) | |
1392 { | |
1393 if (!NILP (Fold_equal (elt, Fcar (tail)))) | |
1394 { | |
1395 if (NILP (prev)) | |
1396 list = Fcdr (tail); | |
1397 else | |
1398 Fsetcdr (prev, Fcdr (tail)); | |
1399 } | |
1400 else | |
1401 prev = tail; | |
1402 tail = Fcdr (tail); | |
1403 QUIT; | |
1404 } | |
1405 return list; | |
1406 } | |
1407 | |
1236 DEFUN ("delq", Fdelq, 2, 2, 0, /* | 1408 DEFUN ("delq", Fdelq, 2, 2, 0, /* |
1237 Delete by side effect any occurrences of ELT as a member of LIST. | 1409 Delete by side effect any occurrences of ELT as a member of LIST. |
1238 The modified LIST is returned. Comparison is done with `eq'. | 1410 The modified LIST is returned. Comparison is done with `eq'. |
1239 If the first member of LIST is ELT, there is no way to remove it by side | 1411 If the first member of LIST is ELT, there is no way to remove it by side |
1240 effect; therefore, write `(setq foo (delq element foo))' to be sure of | 1412 effect; therefore, write `(setq foo (delq element foo))' to be sure of |
1248 tail = list; | 1420 tail = list; |
1249 prev = Qnil; | 1421 prev = Qnil; |
1250 while (!NILP (tail)) | 1422 while (!NILP (tail)) |
1251 { | 1423 { |
1252 tem = Fcar (tail); | 1424 tem = Fcar (tail); |
1253 if (HACKEQ_UNSAFE (elt, tem)) | 1425 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) |
1254 { | 1426 { |
1255 if (NILP (prev)) | 1427 if (NILP (prev)) |
1256 list = Fcdr (tail); | 1428 list = Fcdr (tail); |
1257 else | 1429 else |
1258 Fsetcdr (prev, Fcdr (tail)); | 1430 Fsetcdr (prev, Fcdr (tail)); |
1263 QUIT; | 1435 QUIT; |
1264 } | 1436 } |
1265 return list; | 1437 return list; |
1266 } | 1438 } |
1267 | 1439 |
1440 DEFUN ("old-delq", Fold_delq, 2, 2, 0, /* | |
1441 Delete by side effect any occurrences of ELT as a member of LIST. | |
1442 The modified LIST is returned. Comparison is done with `old-eq'. | |
1443 If the first member of LIST is ELT, there is no way to remove it by side | |
1444 effect; therefore, write `(setq foo (delq element foo))' to be sure of | |
1445 changing the value of `foo'. | |
1446 */ | |
1447 (elt, list)) | |
1448 { | |
1449 REGISTER Lisp_Object tail, prev; | |
1450 REGISTER Lisp_Object tem; | |
1451 | |
1452 tail = list; | |
1453 prev = Qnil; | |
1454 while (!NILP (tail)) | |
1455 { | |
1456 tem = Fcar (tail); | |
1457 if (HACKEQ_UNSAFE (elt, tem)) | |
1458 { | |
1459 if (NILP (prev)) | |
1460 list = Fcdr (tail); | |
1461 else | |
1462 Fsetcdr (prev, Fcdr (tail)); | |
1463 } | |
1464 else | |
1465 prev = tail; | |
1466 tail = Fcdr (tail); | |
1467 QUIT; | |
1468 } | |
1469 return list; | |
1470 } | |
1471 | |
1268 /* no quit, no errors; be careful */ | 1472 /* no quit, no errors; be careful */ |
1269 | 1473 |
1270 Lisp_Object | 1474 Lisp_Object |
1271 delq_no_quit (Lisp_Object elt, Lisp_Object list) | 1475 delq_no_quit (Lisp_Object elt, Lisp_Object list) |
1272 { | 1476 { |
1276 tail = list; | 1480 tail = list; |
1277 prev = Qnil; | 1481 prev = Qnil; |
1278 while (CONSP (tail)) | 1482 while (CONSP (tail)) |
1279 { | 1483 { |
1280 tem = XCAR (tail); | 1484 tem = XCAR (tail); |
1281 if (HACKEQ_UNSAFE (elt, tem)) | 1485 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) |
1282 { | 1486 { |
1283 if (NILP (prev)) | 1487 if (NILP (prev)) |
1284 list = XCDR (tail); | 1488 list = XCDR (tail); |
1285 else | 1489 else |
1286 XCDR (prev) = XCDR (tail); | 1490 XCDR (prev) = XCDR (tail); |
1309 prev = Qnil; | 1513 prev = Qnil; |
1310 while (CONSP (tail)) | 1514 while (CONSP (tail)) |
1311 { | 1515 { |
1312 Lisp_Object cons_to_free = Qnil; | 1516 Lisp_Object cons_to_free = Qnil; |
1313 tem = XCAR (tail); | 1517 tem = XCAR (tail); |
1314 if (HACKEQ_UNSAFE (elt, tem)) | 1518 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) |
1315 { | 1519 { |
1316 if (NILP (prev)) | 1520 if (NILP (prev)) |
1317 list = XCDR (tail); | 1521 list = XCDR (tail); |
1318 else | 1522 else |
1319 XCDR (prev) = XCDR (tail); | 1523 XCDR (prev) = XCDR (tail); |
1381 tail = list; | 1585 tail = list; |
1382 prev = Qnil; | 1586 prev = Qnil; |
1383 while (!NILP (tail)) | 1587 while (!NILP (tail)) |
1384 { | 1588 { |
1385 Lisp_Object elt = Fcar (tail); | 1589 Lisp_Object elt = Fcar (tail); |
1386 if (CONSP (elt) && HACKEQ_UNSAFE (key, Fcar (elt))) | 1590 if (CONSP (elt) && EQ_WITH_EBOLA_NOTICE (key, Fcar (elt))) |
1387 { | 1591 { |
1388 if (NILP (prev)) | 1592 if (NILP (prev)) |
1389 list = Fcdr (tail); | 1593 list = Fcdr (tail); |
1390 else | 1594 else |
1391 Fsetcdr (prev, Fcdr (tail)); | 1595 Fsetcdr (prev, Fcdr (tail)); |
1409 tail = list; | 1613 tail = list; |
1410 prev = Qnil; | 1614 prev = Qnil; |
1411 while (CONSP (tail)) | 1615 while (CONSP (tail)) |
1412 { | 1616 { |
1413 tem = XCAR (tail); | 1617 tem = XCAR (tail); |
1414 if (CONSP (tem) && HACKEQ_UNSAFE (key, XCAR (tem))) | 1618 if (CONSP (tem) && EQ_WITH_EBOLA_NOTICE (key, XCAR (tem))) |
1415 { | 1619 { |
1416 if (NILP (prev)) | 1620 if (NILP (prev)) |
1417 list = XCDR (tail); | 1621 list = XCDR (tail); |
1418 else | 1622 else |
1419 XCDR (prev) = XCDR (tail); | 1623 XCDR (prev) = XCDR (tail); |
1470 tail = list; | 1674 tail = list; |
1471 prev = Qnil; | 1675 prev = Qnil; |
1472 while (!NILP (tail)) | 1676 while (!NILP (tail)) |
1473 { | 1677 { |
1474 Lisp_Object elt = Fcar (tail); | 1678 Lisp_Object elt = Fcar (tail); |
1475 if (CONSP (elt) && HACKEQ_UNSAFE (value, Fcdr (elt))) | 1679 if (CONSP (elt) && EQ_WITH_EBOLA_NOTICE (value, Fcdr (elt))) |
1476 { | 1680 { |
1477 if (NILP (prev)) | 1681 if (NILP (prev)) |
1478 list = Fcdr (tail); | 1682 list = Fcdr (tail); |
1479 else | 1683 else |
1480 Fsetcdr (prev, Fcdr (tail)); | 1684 Fsetcdr (prev, Fcdr (tail)); |
1498 tail = list; | 1702 tail = list; |
1499 prev = Qnil; | 1703 prev = Qnil; |
1500 while (CONSP (tail)) | 1704 while (CONSP (tail)) |
1501 { | 1705 { |
1502 tem = XCAR (tail); | 1706 tem = XCAR (tail); |
1503 if (CONSP (tem) && HACKEQ_UNSAFE (value, XCDR (tem))) | 1707 if (CONSP (tem) && EQ_WITH_EBOLA_NOTICE (value, XCDR (tem))) |
1504 { | 1708 { |
1505 if (NILP (prev)) | 1709 if (NILP (prev)) |
1506 list = XCDR (tail); | 1710 list = XCDR (tail); |
1507 else | 1711 else |
1508 XCDR (prev) = XCDR (tail); | 1712 XCDR (prev) = XCDR (tail); |
1755 for (i = 0; i < fill; i++) | 1959 for (i = 0; i < fill; i++) |
1756 { | 1960 { |
1757 if (!laxp ? EQ (k, keys [i]) : internal_equal (k, keys [i], depth)) | 1961 if (!laxp ? EQ (k, keys [i]) : internal_equal (k, keys [i], depth)) |
1758 { | 1962 { |
1759 if ((eqp | 1963 if ((eqp |
1760 /* Ebolified here too, sigh ... */ | 1964 /* We narrowly escaped being Ebolified here. */ |
1761 ? !HACKEQ_UNSAFE (v, vals [i]) | 1965 ? !EQ_WITH_EBOLA_NOTICE (v, vals [i]) |
1762 : !internal_equal (v, vals [i], depth))) | 1966 : !internal_equal (v, vals [i], depth))) |
1763 /* a property in B has a different value than in A */ | 1967 /* a property in B has a different value than in A */ |
1764 goto MISMATCH; | 1968 goto MISMATCH; |
1765 flags [i] = 1; | 1969 flags [i] = 1; |
1766 break; | 1970 break; |
2516 This is the last VALUE stored with `(put OBJECT PROPNAME VALUE)'. | 2720 This is the last VALUE stored with `(put OBJECT PROPNAME VALUE)'. |
2517 If there is no such property, return optional third arg DEFAULT | 2721 If there is no such property, return optional third arg DEFAULT |
2518 (which defaults to `nil'). OBJECT can be a symbol, face, extent, | 2722 (which defaults to `nil'). OBJECT can be a symbol, face, extent, |
2519 or string. See also `put', `remprop', and `object-plist'. | 2723 or string. See also `put', `remprop', and `object-plist'. |
2520 */ | 2724 */ |
2521 (object, propname, defalt)) /* Cant spel in C */ | 2725 (object, propname, defalt)) /* Cant spel in C */ |
2522 { | 2726 { |
2523 Lisp_Object val; | 2727 Lisp_Object val; |
2524 | 2728 |
2525 /* Various places in emacs call Fget() and expect it not to quit, | 2729 /* Various places in emacs call Fget() and expect it not to quit, |
2526 so don't quit. */ | 2730 so don't quit. */ |
2675 { | 2879 { |
2676 if (depth > 200) | 2880 if (depth > 200) |
2677 error ("Stack overflow in equal"); | 2881 error ("Stack overflow in equal"); |
2678 do_cdr: | 2882 do_cdr: |
2679 QUIT; | 2883 QUIT; |
2680 if (HACKEQ_UNSAFE (o1, o2)) | 2884 if (EQ_WITH_EBOLA_NOTICE (o1, o2)) |
2681 return (1); | 2885 return (1); |
2682 /* Note that (equal 20 20.0) should be nil */ | 2886 /* Note that (equal 20 20.0) should be nil */ |
2683 else if (XTYPE (o1) != XTYPE (o2)) | 2887 else if (XTYPE (o1) != XTYPE (o2)) |
2684 return (0); | 2888 return (0); |
2685 else if (CONSP (o1)) | 2889 else if (CONSP (o1)) |
2733 } | 2937 } |
2734 | 2938 |
2735 return (0); | 2939 return (0); |
2736 } | 2940 } |
2737 | 2941 |
2942 /* Note that we may be calling sub-objects that will use | |
2943 internal_equal() (instead of internal_old_equal()). Oh well. | |
2944 We will get an Ebola note if there's any possibility of confusion, | |
2945 but that seems unlikely. */ | |
2946 | |
2947 static int | |
2948 internal_old_equal (Lisp_Object o1, Lisp_Object o2, int depth) | |
2949 { | |
2950 if (depth > 200) | |
2951 error ("Stack overflow in equal"); | |
2952 do_cdr: | |
2953 QUIT; | |
2954 if (HACKEQ_UNSAFE (o1, o2)) | |
2955 return (1); | |
2956 /* Note that (equal 20 20.0) should be nil */ | |
2957 else if (XTYPE (o1) != XTYPE (o2)) | |
2958 return (0); | |
2959 else if (CONSP (o1)) | |
2960 { | |
2961 if (!internal_old_equal (Fcar (o1), Fcar (o2), depth + 1)) | |
2962 return (0); | |
2963 o1 = Fcdr (o1); | |
2964 o2 = Fcdr (o2); | |
2965 goto do_cdr; | |
2966 } | |
2967 | |
2968 #ifndef LRECORD_VECTOR | |
2969 else if (VECTORP (o1)) | |
2970 { | |
2971 int indecks; | |
2972 int len = vector_length (XVECTOR (o1)); | |
2973 if (len != vector_length (XVECTOR (o2))) | |
2974 return (0); | |
2975 for (indecks = 0; indecks < len; indecks++) | |
2976 { | |
2977 Lisp_Object v1, v2; | |
2978 v1 = vector_data (XVECTOR (o1)) [indecks]; | |
2979 v2 = vector_data (XVECTOR (o2)) [indecks]; | |
2980 if (!internal_old_equal (v1, v2, depth + 1)) | |
2981 return (0); | |
2982 } | |
2983 return (1); | |
2984 } | |
2985 #endif /* !LRECORD_VECTOR */ | |
2986 else if (STRINGP (o1)) | |
2987 { | |
2988 Bytecount len = XSTRING_LENGTH (o1); | |
2989 if (len != XSTRING_LENGTH (o2)) | |
2990 return (0); | |
2991 if (memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len)) | |
2992 return (0); | |
2993 return (1); | |
2994 } | |
2995 else if (LRECORDP (o1)) | |
2996 { | |
2997 CONST struct lrecord_implementation | |
2998 *imp1 = XRECORD_LHEADER (o1)->implementation, | |
2999 *imp2 = XRECORD_LHEADER (o2)->implementation; | |
3000 if (imp1 != imp2) | |
3001 return (0); | |
3002 else if (imp1->equal == 0) | |
3003 /* EQ-ness of the objects was noticed above */ | |
3004 return (0); | |
3005 else | |
3006 return ((imp1->equal) (o1, o2, depth)); | |
3007 } | |
3008 | |
3009 return (0); | |
3010 } | |
3011 | |
2738 DEFUN ("equal", Fequal, 2, 2, 0, /* | 3012 DEFUN ("equal", Fequal, 2, 2, 0, /* |
2739 T if two Lisp objects have similar structure and contents. | 3013 T if two Lisp objects have similar structure and contents. |
2740 They must have the same data type. | 3014 They must have the same data type. |
2741 Conses are compared by comparing the cars and the cdrs. | 3015 Conses are compared by comparing the cars and the cdrs. |
2742 Vectors and strings are compared element by element. | 3016 Vectors and strings are compared element by element. |
2745 (o1, o2)) | 3019 (o1, o2)) |
2746 { | 3020 { |
2747 return ((internal_equal (o1, o2, 0)) ? Qt : Qnil); | 3021 return ((internal_equal (o1, o2, 0)) ? Qt : Qnil); |
2748 } | 3022 } |
2749 | 3023 |
3024 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /* | |
3025 T if two Lisp objects have similar structure and contents. | |
3026 They must have the same data type. | |
3027 \(Note, however, that an exception is made for characters and integers; | |
3028 this is known as the \"char-int confoundance disease.\" See `eq' and | |
3029 `old-eq'.) | |
3030 This function is provided only for byte-code compatibility with v19. | |
3031 Do not use it. | |
3032 */ | |
3033 (o1, o2)) | |
3034 { | |
3035 return (internal_old_equal (o1, o2, 0) ? Qt : Qnil); | |
3036 } | |
3037 | |
2750 | 3038 |
2751 DEFUN ("fillarray", Ffillarray, 2, 2, 0, /* | 3039 DEFUN ("fillarray", Ffillarray, 2, 2, 0, /* |
2752 Store each element of ARRAY with ITEM. | 3040 Store each element of ARRAY with ITEM. |
2753 ARRAY is a vector, bit vector, or string. | 3041 ARRAY is a vector, bit vector, or string. |
2754 */ | 3042 */ |
2755 (array, item)) | 3043 (array, item)) |
2756 { | 3044 { |
2757 retry: | 3045 retry: |
2758 if (STRINGP (array)) | 3046 if (VECTORP (array)) |
2759 { | |
2760 Charcount size; | |
2761 Charcount i; | |
2762 Emchar charval; | |
2763 struct Lisp_String *s; | |
2764 CHECK_CHAR_COERCE_INT (item); | |
2765 CHECK_IMPURE (array); | |
2766 charval = XCHAR (item); | |
2767 s = XSTRING (array); | |
2768 size = string_char_length (s); | |
2769 for (i = 0; i < size; i++) | |
2770 set_string_char (s, i, charval); | |
2771 bump_string_modiff (array); | |
2772 } | |
2773 else if (VECTORP (array)) | |
2774 { | 3047 { |
2775 Lisp_Object *p; | 3048 Lisp_Object *p; |
2776 int size; | 3049 int size; |
2777 int i; | 3050 int indecks; |
2778 CHECK_IMPURE (array); | 3051 CHECK_IMPURE (array); |
2779 size = vector_length (XVECTOR (array)); | 3052 size = vector_length (XVECTOR (array)); |
2780 p = vector_data (XVECTOR (array)); | 3053 p = vector_data (XVECTOR (array)); |
2781 for (i = 0; i < size; i++) | 3054 for (indecks = 0; indecks < size; indecks++) |
2782 p[i] = item; | 3055 p[indecks] = item; |
2783 } | 3056 } |
2784 else if (BIT_VECTORP (array)) | 3057 else if (VECTORP (array)) |
2785 { | 3058 { |
2786 struct Lisp_Bit_Vector *v; | 3059 struct Lisp_Bit_Vector *v; |
2787 int size; | 3060 int size; |
2788 int i; | 3061 int indecks; |
3062 | |
2789 CHECK_BIT (item); | 3063 CHECK_BIT (item); |
2790 CHECK_IMPURE (array); | 3064 CHECK_IMPURE (array); |
2791 v = XBIT_VECTOR (array); | 3065 v = XBIT_VECTOR (array); |
2792 size = bit_vector_length (v); | 3066 size = bit_vector_length (v); |
2793 for (i = 0; i < size; i++) | 3067 for (indecks = 0; indecks < size; indecks++) |
2794 set_bit_vector_bit (v, i, XINT (item)); | 3068 set_bit_vector_bit (v, indecks, XINT (item)); |
3069 } | |
3070 else if (STRINGP (array)) | |
3071 { | |
3072 Charcount size; | |
3073 Charcount indecks; | |
3074 Emchar charval; | |
3075 CHECK_CHAR_COERCE_INT (item); | |
3076 CHECK_IMPURE (array); | |
3077 charval = XCHAR (item); | |
3078 size = string_char_length (XSTRING (array)); | |
3079 for (indecks = 0; indecks < size; indecks++) | |
3080 set_string_char (XSTRING (array), indecks, charval); | |
3081 bump_string_modiff (array); | |
2795 } | 3082 } |
2796 else | 3083 else |
2797 { | 3084 { |
2798 array = wrong_type_argument (Qarrayp, array); | 3085 array = wrong_type_argument (Qarrayp, array); |
2799 goto retry; | 3086 goto retry; |
3006 then converted to integer. | 3293 then converted to integer. |
3007 | 3294 |
3008 If the 5-minute or 15-minute load averages are not available, return a | 3295 If the 5-minute or 15-minute load averages are not available, return a |
3009 shortened list, containing only those averages which are available. | 3296 shortened list, containing only those averages which are available. |
3010 | 3297 |
3011 On some systems, this won't work due to permissions on /dev/kmem in | 3298 On most systems, this won't work unless the emacs executable is installed |
3012 which case you can't use this. | 3299 as setgid kmem (assuming that /dev/kmem is in the group kmem). |
3013 */ | 3300 */ |
3014 ()) | 3301 ()) |
3015 { | 3302 { |
3016 double load_ave[10]; /* hey, just in case */ | 3303 double load_ave[10]; /* hey, just in case */ |
3017 int loads = getloadavg (load_ave, 3); | 3304 int loads = getloadavg (load_ave, 3); |
3029 return ret; | 3316 return ret; |
3030 } | 3317 } |
3031 | 3318 |
3032 | 3319 |
3033 Lisp_Object Vfeatures; | 3320 Lisp_Object Vfeatures; |
3034 extern Lisp_Object Vemacs_major_version, Vemacs_minor_version; | |
3035 | 3321 |
3036 DEFUN ("featurep", Ffeaturep, 1, 1, 0, /* | 3322 DEFUN ("featurep", Ffeaturep, 1, 1, 0, /* |
3037 Return non-nil if feature expression FEXP is true. | 3323 Return t if FEATURE is present in this Emacs. |
3038 */ | 3324 Use this to conditionalize execution of lisp code based on the |
3039 (fexp)) | 3325 presence or absence of emacs or environment extensions. |
3040 { | 3326 Use `provide' to declare that a feature is available. |
3041 static double featurep_emacs_version; | 3327 This function looks at the value of the variable `features'. |
3042 | 3328 */ |
3043 /* Brute force translation from Erik Naggum's lisp function. */ | 3329 (feature)) |
3044 if (SYMBOLP(fexp)) | 3330 { |
3045 { | 3331 CHECK_SYMBOL (feature); |
3046 /* Original definition */ | 3332 return NILP (Fmemq (feature, Vfeatures)) ? Qnil : Qt; |
3047 return NILP (Fmemq (fexp, Vfeatures)) ? Qnil : Qt; | |
3048 } | |
3049 else if (INTP(fexp) || FLOATP(fexp)) | |
3050 { | |
3051 double d = extract_float(fexp); | |
3052 | |
3053 if (featurep_emacs_version == 0.0) | |
3054 { | |
3055 featurep_emacs_version = XINT (Vemacs_major_version) + | |
3056 (XINT (Vemacs_minor_version) / 100.0); | |
3057 } | |
3058 return featurep_emacs_version >= d ? Qt : Qnil; | |
3059 } | |
3060 else if (CONSP(fexp)) | |
3061 { | |
3062 Lisp_Object tem; | |
3063 | |
3064 tem = XCAR(fexp); | |
3065 if (EQ(tem, Qnot)) | |
3066 { | |
3067 Lisp_Object negate = XCDR(fexp); | |
3068 | |
3069 if (!NILP(XCDR(fexp))) | |
3070 { | |
3071 return Fsignal(Qinvalid_read_syntax, list1(XCDR(fexp))); | |
3072 } | |
3073 else | |
3074 { | |
3075 return NILP(Ffeaturep(negate)) ? Qt : Qnil; | |
3076 } | |
3077 } | |
3078 else if (EQ(tem, Qand)) | |
3079 { | |
3080 tem = XCDR(fexp); | |
3081 while (!NILP(tem) && !NILP(Ffeaturep(XCAR(tem)))) | |
3082 { | |
3083 tem = XCDR(tem); | |
3084 } | |
3085 return NILP(tem) ? Qt : Qnil; | |
3086 } | |
3087 else if (EQ(tem, Qor)) | |
3088 { | |
3089 tem = XCDR(fexp); | |
3090 while (!NILP(tem) && NILP(Ffeaturep(XCAR(tem)))) | |
3091 { | |
3092 tem = XCDR(tem); | |
3093 } | |
3094 return NILP(tem) ? Qnil : Qt; | |
3095 } | |
3096 else | |
3097 { | |
3098 return Fsignal(Qinvalid_read_syntax, list1(XCDR(fexp))); | |
3099 } | |
3100 } | |
3101 else | |
3102 { | |
3103 return Fsignal(Qinvalid_read_syntax, list1 (fexp)); | |
3104 } | |
3105 } | 3333 } |
3106 | 3334 |
3107 DEFUN ("provide", Fprovide, 1, 1, 0, /* | 3335 DEFUN ("provide", Fprovide, 1, 1, 0, /* |
3108 Announce that FEATURE is a feature of the current Emacs. | 3336 Announce that FEATURE is a feature of the current Emacs. |
3109 This function updates the value of the variable `features'. | 3337 This function updates the value of the variable `features'. |
3185 DEFSUBR (Fsubseq); | 3413 DEFSUBR (Fsubseq); |
3186 DEFSUBR (Fnthcdr); | 3414 DEFSUBR (Fnthcdr); |
3187 DEFSUBR (Fnth); | 3415 DEFSUBR (Fnth); |
3188 DEFSUBR (Felt); | 3416 DEFSUBR (Felt); |
3189 DEFSUBR (Fmember); | 3417 DEFSUBR (Fmember); |
3418 DEFSUBR (Fold_member); | |
3190 DEFSUBR (Fmemq); | 3419 DEFSUBR (Fmemq); |
3420 DEFSUBR (Fold_memq); | |
3191 DEFSUBR (Fassoc); | 3421 DEFSUBR (Fassoc); |
3422 DEFSUBR (Fold_assoc); | |
3192 DEFSUBR (Fassq); | 3423 DEFSUBR (Fassq); |
3424 DEFSUBR (Fold_assq); | |
3193 DEFSUBR (Frassoc); | 3425 DEFSUBR (Frassoc); |
3426 DEFSUBR (Fold_rassoc); | |
3194 DEFSUBR (Frassq); | 3427 DEFSUBR (Frassq); |
3428 DEFSUBR (Fold_rassq); | |
3195 DEFSUBR (Fdelete); | 3429 DEFSUBR (Fdelete); |
3430 DEFSUBR (Fold_delete); | |
3196 DEFSUBR (Fdelq); | 3431 DEFSUBR (Fdelq); |
3432 DEFSUBR (Fold_delq); | |
3197 DEFSUBR (Fremassoc); | 3433 DEFSUBR (Fremassoc); |
3198 DEFSUBR (Fremassq); | 3434 DEFSUBR (Fremassq); |
3199 DEFSUBR (Fremrassoc); | 3435 DEFSUBR (Fremrassoc); |
3200 DEFSUBR (Fremrassq); | 3436 DEFSUBR (Fremrassq); |
3201 DEFSUBR (Fnreverse); | 3437 DEFSUBR (Fnreverse); |
3221 DEFSUBR (Fget); | 3457 DEFSUBR (Fget); |
3222 DEFSUBR (Fput); | 3458 DEFSUBR (Fput); |
3223 DEFSUBR (Fremprop); | 3459 DEFSUBR (Fremprop); |
3224 DEFSUBR (Fobject_plist); | 3460 DEFSUBR (Fobject_plist); |
3225 DEFSUBR (Fequal); | 3461 DEFSUBR (Fequal); |
3462 DEFSUBR (Fold_equal); | |
3226 DEFSUBR (Ffillarray); | 3463 DEFSUBR (Ffillarray); |
3227 DEFSUBR (Fnconc); | 3464 DEFSUBR (Fnconc); |
3228 DEFSUBR (Fmapcar); | 3465 DEFSUBR (Fmapcar); |
3229 DEFSUBR (Fmapc_internal); | 3466 DEFSUBR (Fmapc_internal); |
3230 DEFSUBR (Fmapconcat); | 3467 DEFSUBR (Fmapconcat); |