comparison src/fns.c @ 5125:b5df3737028a ben-lisp-object

merge
author Ben Wing <ben@xemacs.org>
date Wed, 24 Feb 2010 01:58:04 -0600
parents 623d57b7fbe8 9624523604c5
children 2a462149bd6a
comparison
equal deleted inserted replaced
5124:623d57b7fbe8 5125:b5df3737028a
1 /* Random utility Lisp functions. 1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc. 2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996, 2000, 2001, 2002, 2003 Ben Wing. 3 Copyright (C) 1995, 1996, 2000, 2001, 2002, 2003, 2010 Ben Wing.
4 4
5 This file is part of XEmacs. 5 This file is part of XEmacs.
6 6
7 XEmacs is free software; you can redistribute it and/or modify it 7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
54 /* NOTE: This symbol is also used in lread.c */ 54 /* NOTE: This symbol is also used in lread.c */
55 #define FEATUREP_SYNTAX 55 #define FEATUREP_SYNTAX
56 56
57 Lisp_Object Qstring_lessp; 57 Lisp_Object Qstring_lessp;
58 Lisp_Object Qidentity; 58 Lisp_Object Qidentity;
59 Lisp_Object Qvector, Qarray, Qbit_vector;
59 60
60 Lisp_Object Qbase64_conversion_error; 61 Lisp_Object Qbase64_conversion_error;
61 62
62 Lisp_Object Vpath_separator; 63 Lisp_Object Vpath_separator;
63 64
79 Elemcount len = bit_vector_length (v); 80 Elemcount len = bit_vector_length (v);
80 Elemcount last = len; 81 Elemcount last = len;
81 82
82 if (INTP (Vprint_length)) 83 if (INTP (Vprint_length))
83 last = min (len, XINT (Vprint_length)); 84 last = min (len, XINT (Vprint_length));
84 write_c_string (printcharfun, "#*"); 85 write_ascstring (printcharfun, "#*");
85 for (i = 0; i < last; i++) 86 for (i = 0; i < last; i++)
86 { 87 {
87 if (bit_vector_bit (v, i)) 88 if (bit_vector_bit (v, i))
88 write_c_string (printcharfun, "1"); 89 write_ascstring (printcharfun, "1");
89 else 90 else
90 write_c_string (printcharfun, "0"); 91 write_ascstring (printcharfun, "0");
91 } 92 }
92 93
93 if (last != len) 94 if (last != len)
94 write_c_string (printcharfun, "..."); 95 write_ascstring (printcharfun, "...");
95 } 96 }
96 97
97 static int 98 static int
98 bit_vector_equal (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth)) 99 bit_vector_equal (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth),
100 int UNUSED (foldcase))
99 { 101 {
100 Lisp_Bit_Vector *v1 = XBIT_VECTOR (obj1); 102 Lisp_Bit_Vector *v1 = XBIT_VECTOR (obj1);
101 Lisp_Bit_Vector *v2 = XBIT_VECTOR (obj2); 103 Lisp_Bit_Vector *v2 = XBIT_VECTOR (obj2);
102 104
103 return ((bit_vector_length (v1) == bit_vector_length (v2)) && 105 return ((bit_vector_length (v1) == bit_vector_length (v2)) &&
214 } 216 }
215 217
216 #endif /* LOSING_BYTECODE */ 218 #endif /* LOSING_BYTECODE */
217 219
218 void 220 void
219 check_losing_bytecode (const char *function, Lisp_Object seq) 221 check_losing_bytecode (const Ascbyte *function, Lisp_Object seq)
220 { 222 {
221 if (COMPILED_FUNCTIONP (seq)) 223 if (COMPILED_FUNCTIONP (seq))
222 signal_ferror_with_frob 224 signal_ferror_with_frob
223 (Qinvalid_argument, seq, 225 (Qinvalid_argument, seq,
224 "As of 20.3, `%s' no longer works with compiled-function objects", 226 "As of 20.3, `%s' no longer works with compiled-function objects",
312 314
313 DEFUN ("compare-strings", Fcompare_strings, 6, 7, 0, /* 315 DEFUN ("compare-strings", Fcompare_strings, 6, 7, 0, /*
314 Compare the contents of two strings, maybe ignoring case. 316 Compare the contents of two strings, maybe ignoring case.
315 In string STR1, skip the first START1 characters and stop at END1. 317 In string STR1, skip the first START1 characters and stop at END1.
316 In string STR2, skip the first START2 characters and stop at END2. 318 In string STR2, skip the first START2 characters and stop at END2.
317 END1 and END2 default to the full lengths of the respective strings. 319 END1 and END2 default to the full lengths of the respective strings,
318 320 and arguments that are outside the string (negative STARTi or ENDi
319 Case is significant in this comparison if IGNORE-CASE is nil. 321 greater than length) are coerced to 0 or string length as appropriate.
322
323 Optional IGNORE-CASE non-nil means use case-insensitive comparison.
324 Case is significant by default.
320 325
321 The value is t if the strings (or specified portions) match. 326 The value is t if the strings (or specified portions) match.
322 If string STR1 is less, the value is a negative number N; 327 If string STR1 is less, the value is a negative number N;
323 - 1 - N is the number of characters that match at the beginning. 328 - 1 - N is the number of characters that match at the beginning.
324 If string STR1 is greater, the value is a positive number N; 329 If string STR1 is greater, the value is a positive number N;
332 int res; 337 int res;
333 338
334 CHECK_STRING (str1); 339 CHECK_STRING (str1);
335 CHECK_STRING (str2); 340 CHECK_STRING (str2);
336 get_string_range_char (str1, start1, end1, &ccstart1, &ccend1, 341 get_string_range_char (str1, start1, end1, &ccstart1, &ccend1,
337 GB_HISTORICAL_STRING_BEHAVIOR); 342 GB_HISTORICAL_STRING_BEHAVIOR|GB_COERCE_RANGE);
338 get_string_range_char (str2, start2, end2, &ccstart2, &ccend2, 343 get_string_range_char (str2, start2, end2, &ccstart2, &ccend2,
339 GB_HISTORICAL_STRING_BEHAVIOR); 344 GB_HISTORICAL_STRING_BEHAVIOR|GB_COERCE_RANGE);
340 345
341 bstart1 = string_index_char_to_byte (str1, ccstart1); 346 bstart1 = string_index_char_to_byte (str1, ccstart1);
342 blen1 = string_offset_char_to_byte_len (str1, bstart1, ccend1 - ccstart1); 347 blen1 = string_offset_char_to_byte_len (str1, bstart1, ccend1 - ccstart1);
343 bstart2 = string_index_char_to_byte (str2, ccstart2); 348 bstart2 = string_index_char_to_byte (str2, ccstart2);
344 blen2 = string_offset_char_to_byte_len (str2, bstart2, ccend2 - ccstart2); 349 blen2 = string_offset_char_to_byte_len (str2, bstart2, ccend2 - ccstart2);
975 */ 980 */
976 (sequence, start, end)) 981 (sequence, start, end))
977 { 982 {
978 EMACS_INT len, s, e; 983 EMACS_INT len, s, e;
979 984
985 CHECK_SEQUENCE (sequence);
986
980 if (STRINGP (sequence)) 987 if (STRINGP (sequence))
981 return Fsubstring (sequence, start, end); 988 return Fsubstring (sequence, start, end);
982 989
983 len = XINT (Flength (sequence)); 990 len = XINT (Flength (sequence));
984 991
1036 bit_vector_bit (XBIT_VECTOR (sequence), i)); 1043 bit_vector_bit (XBIT_VECTOR (sequence), i));
1037 return result; 1044 return result;
1038 } 1045 }
1039 else 1046 else
1040 { 1047 {
1041 ABORT (); /* unreachable, since Flength (sequence) did not get 1048 ABORT (); /* unreachable, since CHECK_SEQUENCE (sequence) did not
1042 an error */ 1049 error */
1043 return Qnil; 1050 return Qnil;
1044 } 1051 }
1045 } 1052 }
1046 1053
1047 /* Split STRING into a list of substrings. The substrings are the 1054 /* Split STRING into a list of substrings. The substrings are the
1048 parts of original STRING separated by SEPCHAR. */ 1055 parts of original STRING separated by SEPCHAR.
1056
1057 If UNESCAPE is non-zero, ESCAPECHAR specifies a character that will quote
1058 SEPCHAR, and cause it not to split STRING. A double ESCAPECHAR is
1059 necessary for ESCAPECHAR to appear once in a substring. */
1060
1049 static Lisp_Object 1061 static Lisp_Object
1050 split_string_by_ichar_1 (const Ibyte *string, Bytecount size, 1062 split_string_by_ichar_1 (const Ibyte *string, Bytecount size,
1051 Ichar sepchar) 1063 Ichar sepchar, int unescape, Ichar escapechar)
1052 { 1064 {
1053 Lisp_Object result = Qnil; 1065 Lisp_Object result = Qnil;
1054 const Ibyte *end = string + size; 1066 const Ibyte *end = string + size;
1055 1067
1056 while (1) 1068 if (unescape)
1057 { 1069 {
1058 const Ibyte *p = string; 1070 Ibyte unescape_buffer[64], *unescape_buffer_ptr = unescape_buffer,
1059 while (p < end) 1071 escaped[MAX_ICHAR_LEN], *unescape_cursor;
1060 { 1072 Bytecount unescape_buffer_size = countof (unescape_buffer),
1061 if (itext_ichar (p) == sepchar) 1073 escaped_len = set_itext_ichar (escaped, escapechar);
1062 break; 1074 Boolint deleting_escapes, previous_escaped;
1063 INC_IBYTEPTR (p); 1075 Ichar pchar;
1064 } 1076
1065 result = Fcons (make_string (string, p - string), result); 1077 while (1)
1066 if (p < end) 1078 {
1067 { 1079 const Ibyte *p = string, *cursor;
1068 string = p; 1080 deleting_escapes = 0;
1069 INC_IBYTEPTR (string); /* skip sepchar */ 1081 previous_escaped = 0;
1070 } 1082
1071 else 1083 while (p < end)
1072 break; 1084 {
1085 pchar = itext_ichar (p);
1086
1087 if (pchar == sepchar)
1088 {
1089 if (!previous_escaped)
1090 {
1091 break;
1092 }
1093 }
1094 else if (pchar == escapechar
1095 /* Doubled escapes don't escape: */
1096 && !previous_escaped)
1097 {
1098 ++deleting_escapes;
1099 previous_escaped = 1;
1100 }
1101 else
1102 {
1103 previous_escaped = 0;
1104 }
1105
1106 INC_IBYTEPTR (p);
1107 }
1108
1109 if (deleting_escapes)
1110 {
1111 if (((p - string) - (escaped_len * deleting_escapes))
1112 > unescape_buffer_size)
1113 {
1114 unescape_buffer_size =
1115 ((p - string) - (escaped_len * deleting_escapes)) * 1.5;
1116 unescape_buffer_ptr = alloca_ibytes (unescape_buffer_size);
1117 }
1118
1119 cursor = string;
1120 unescape_cursor = unescape_buffer_ptr;
1121 previous_escaped = 0;
1122
1123 while (cursor < p)
1124 {
1125 pchar = itext_ichar (cursor);
1126
1127 if (pchar != escapechar || previous_escaped)
1128 {
1129 memcpy (unescape_cursor, cursor,
1130 itext_ichar_len (cursor));
1131 INC_IBYTEPTR (unescape_cursor);
1132 }
1133
1134 previous_escaped = !previous_escaped
1135 && (pchar == escapechar);
1136
1137 INC_IBYTEPTR (cursor);
1138 }
1139
1140 result = Fcons (make_string (unescape_buffer_ptr,
1141 unescape_cursor
1142 - unescape_buffer_ptr),
1143 result);
1144 }
1145 else
1146 {
1147 result = Fcons (make_string (string, p - string), result);
1148 }
1149 if (p < end)
1150 {
1151 string = p;
1152 INC_IBYTEPTR (string); /* skip sepchar */
1153 }
1154 else
1155 break;
1156 }
1157 }
1158 else
1159 {
1160 while (1)
1161 {
1162 const Ibyte *p = string;
1163 while (p < end)
1164 {
1165 if (itext_ichar (p) == sepchar)
1166 break;
1167 INC_IBYTEPTR (p);
1168 }
1169 result = Fcons (make_string (string, p - string), result);
1170 if (p < end)
1171 {
1172 string = p;
1173 INC_IBYTEPTR (string); /* skip sepchar */
1174 }
1175 else
1176 break;
1177 }
1073 } 1178 }
1074 return Fnreverse (result); 1179 return Fnreverse (result);
1075 } 1180 }
1076 1181
1077 /* The same as the above, except PATH is an external C string (it is 1182 /* The same as the above, except PATH is an external C string (it is
1092 depend on split_external_path("") returning nil instead of an empty 1197 depend on split_external_path("") returning nil instead of an empty
1093 string? */ 1198 string? */
1094 if (!newlen) 1199 if (!newlen)
1095 return Qnil; 1200 return Qnil;
1096 1201
1097 return split_string_by_ichar_1 (newpath, newlen, SEPCHAR); 1202 return split_string_by_ichar_1 (newpath, newlen, SEPCHAR, 0, 0);
1098 } 1203 }
1099 1204
1100 Lisp_Object 1205 Lisp_Object
1101 split_env_path (const CIbyte *evarname, const Ibyte *default_) 1206 split_env_path (const CIbyte *evarname, const Ibyte *default_)
1102 { 1207 {
1105 path = egetenv (evarname); 1210 path = egetenv (evarname);
1106 if (!path) 1211 if (!path)
1107 path = default_; 1212 path = default_;
1108 if (!path) 1213 if (!path)
1109 return Qnil; 1214 return Qnil;
1110 return split_string_by_ichar_1 (path, qxestrlen (path), SEPCHAR); 1215 return split_string_by_ichar_1 (path, qxestrlen (path), SEPCHAR, 0, 0);
1111 } 1216 }
1112 1217
1113 /* Ben thinks this function should not exist or be exported to Lisp. 1218 /* Ben thinks this function should not exist or be exported to Lisp.
1114 We use it to define split-path-string in subr.el (not!). */ 1219 We use it to define split-path-string in subr.el (not!). */
1115 1220
1116 DEFUN ("split-string-by-char", Fsplit_string_by_char, 2, 2, 0, /* 1221 DEFUN ("split-string-by-char", Fsplit_string_by_char, 2, 3, 0, /*
1117 Split STRING into a list of substrings originally separated by SEPCHAR. 1222 Split STRING into a list of substrings originally separated by SEPCHAR.
1118 */ 1223
1119 (string, sepchar)) 1224 With optional ESCAPE-CHAR, any instances of SEPCHAR preceded by that
1120 { 1225 character will not split the string, and a double instance of ESCAPE-CHAR
1226 will be necessary for a single ESCAPE-CHAR to appear in the output string.
1227 */
1228 (string, sepchar, escape_char))
1229 {
1230 Ichar escape_ichar = 0;
1231
1121 CHECK_STRING (string); 1232 CHECK_STRING (string);
1122 CHECK_CHAR (sepchar); 1233 CHECK_CHAR (sepchar);
1234 if (!NILP (escape_char))
1235 {
1236 CHECK_CHAR (escape_char);
1237 escape_ichar = XCHAR (escape_char);
1238 }
1123 return split_string_by_ichar_1 (XSTRING_DATA (string), 1239 return split_string_by_ichar_1 (XSTRING_DATA (string),
1124 XSTRING_LENGTH (string), 1240 XSTRING_LENGTH (string),
1125 XCHAR (sepchar)); 1241 XCHAR (sepchar),
1242 !NILP (escape_char), escape_ichar);
1126 } 1243 }
1127 1244
1128 /* #### This was supposed to be in subr.el, but is used VERY early in 1245 /* #### This was supposed to be in subr.el, but is used VERY early in
1129 the bootstrap process, so it goes here. Damn. */ 1246 the bootstrap process, so it goes here. Damn. */
1130 1247
1144 "`path-separator' should be set to a single-character string", 1261 "`path-separator' should be set to a single-character string",
1145 Vpath_separator); 1262 Vpath_separator);
1146 1263
1147 return (split_string_by_ichar_1 1264 return (split_string_by_ichar_1
1148 (XSTRING_DATA (path), XSTRING_LENGTH (path), 1265 (XSTRING_DATA (path), XSTRING_LENGTH (path),
1149 itext_ichar (XSTRING_DATA (Vpath_separator)))); 1266 itext_ichar (XSTRING_DATA (Vpath_separator)), 0, 0));
1150 } 1267 }
1151 1268
1152 1269
1153 DEFUN ("nthcdr", Fnthcdr, 2, 2, 0, /* 1270 DEFUN ("nthcdr", Fnthcdr, 2, 2, 0, /*
1154 Take cdr N times on LIST, and return the result. 1271 Take cdr N times on LIST, and return the result.
1976 NIL_MEANS_NOT_PRESENT is as in `plists-eq' etc. 2093 NIL_MEANS_NOT_PRESENT is as in `plists-eq' etc.
1977 LAXP means use `equal' for comparisons. 2094 LAXP means use `equal' for comparisons.
1978 */ 2095 */
1979 int 2096 int
1980 plists_differ (Lisp_Object a, Lisp_Object b, int nil_means_not_present, 2097 plists_differ (Lisp_Object a, Lisp_Object b, int nil_means_not_present,
1981 int laxp, int depth) 2098 int laxp, int depth, int foldcase)
1982 { 2099 {
1983 int eqp = (depth == -1); /* -1 as depth means use eq, not equal. */ 2100 int eqp = (depth == -1); /* -1 as depth means use eq, not equal. */
1984 int la, lb, m, i, fill; 2101 int la, lb, m, i, fill;
1985 Lisp_Object *keys, *vals; 2102 Lisp_Object *keys, *vals;
1986 char *flags; 2103 Boolbyte *flags;
1987 Lisp_Object rest; 2104 Lisp_Object rest;
1988 2105
1989 if (NILP (a) && NILP (b)) 2106 if (NILP (a) && NILP (b))
1990 return 0; 2107 return 0;
1991 2108
1996 lb = XINT (Flength (b)); 2113 lb = XINT (Flength (b));
1997 m = (la > lb ? la : lb); 2114 m = (la > lb ? la : lb);
1998 fill = 0; 2115 fill = 0;
1999 keys = alloca_array (Lisp_Object, m); 2116 keys = alloca_array (Lisp_Object, m);
2000 vals = alloca_array (Lisp_Object, m); 2117 vals = alloca_array (Lisp_Object, m);
2001 flags = alloca_array (char, m); 2118 flags = alloca_array (Boolbyte, m);
2002 2119
2003 /* First extract the pairs from A. */ 2120 /* First extract the pairs from A. */
2004 for (rest = a; !NILP (rest); rest = XCDR (XCDR (rest))) 2121 for (rest = a; !NILP (rest); rest = XCDR (XCDR (rest)))
2005 { 2122 {
2006 Lisp_Object k = XCAR (rest); 2123 Lisp_Object k = XCAR (rest);
2020 Lisp_Object v = XCAR (XCDR (rest)); 2137 Lisp_Object v = XCAR (XCDR (rest));
2021 /* Maybe be Ebolified. */ 2138 /* Maybe be Ebolified. */
2022 if (nil_means_not_present && NILP (v)) continue; 2139 if (nil_means_not_present && NILP (v)) continue;
2023 for (i = 0; i < fill; i++) 2140 for (i = 0; i < fill; i++)
2024 { 2141 {
2025 if (!laxp ? EQ (k, keys [i]) : internal_equal (k, keys [i], depth)) 2142 if (!laxp ? EQ (k, keys [i]) :
2143 internal_equal_0 (k, keys [i], depth, foldcase))
2026 { 2144 {
2027 if (eqp 2145 if (eqp
2028 /* We narrowly escaped being Ebolified here. */ 2146 /* We narrowly escaped being Ebolified here. */
2029 ? !EQ_WITH_EBOLA_NOTICE (v, vals [i]) 2147 ? !EQ_WITH_EBOLA_NOTICE (v, vals [i])
2030 : !internal_equal (v, vals [i], depth)) 2148 : !internal_equal_0 (v, vals [i], depth, foldcase))
2031 /* a property in B has a different value than in A */ 2149 /* a property in B has a different value than in A */
2032 goto MISMATCH; 2150 goto MISMATCH;
2033 flags [i] = 1; 2151 flags [i] = 1;
2034 break; 2152 break;
2035 } 2153 }
2061 old Lisp implementations, but should not be used except for backward 2179 old Lisp implementations, but should not be used except for backward
2062 compatibility. 2180 compatibility.
2063 */ 2181 */
2064 (a, b, nil_means_not_present)) 2182 (a, b, nil_means_not_present))
2065 { 2183 {
2066 return (plists_differ (a, b, !NILP (nil_means_not_present), 0, -1) 2184 return (plists_differ (a, b, !NILP (nil_means_not_present), 0, -1, 0)
2067 ? Qnil : Qt); 2185 ? Qnil : Qt);
2068 } 2186 }
2069 2187
2070 DEFUN ("plists-equal", Fplists_equal, 2, 3, 0, /* 2188 DEFUN ("plists-equal", Fplists_equal, 2, 3, 0, /*
2071 Return non-nil if property lists A and B are `equal'. 2189 Return non-nil if property lists A and B are `equal'.
2078 old Lisp implementations, but should not be used except for backward 2196 old Lisp implementations, but should not be used except for backward
2079 compatibility. 2197 compatibility.
2080 */ 2198 */
2081 (a, b, nil_means_not_present)) 2199 (a, b, nil_means_not_present))
2082 { 2200 {
2083 return (plists_differ (a, b, !NILP (nil_means_not_present), 0, 1) 2201 return (plists_differ (a, b, !NILP (nil_means_not_present), 0, 1, 0)
2084 ? Qnil : Qt); 2202 ? Qnil : Qt);
2085 } 2203 }
2086 2204
2087 2205
2088 DEFUN ("lax-plists-eq", Flax_plists_eq, 2, 3, 0, /* 2206 DEFUN ("lax-plists-eq", Flax_plists_eq, 2, 3, 0, /*
2098 old Lisp implementations, but should not be used except for backward 2216 old Lisp implementations, but should not be used except for backward
2099 compatibility. 2217 compatibility.
2100 */ 2218 */
2101 (a, b, nil_means_not_present)) 2219 (a, b, nil_means_not_present))
2102 { 2220 {
2103 return (plists_differ (a, b, !NILP (nil_means_not_present), 1, -1) 2221 return (plists_differ (a, b, !NILP (nil_means_not_present), 1, -1, 0)
2104 ? Qnil : Qt); 2222 ? Qnil : Qt);
2105 } 2223 }
2106 2224
2107 DEFUN ("lax-plists-equal", Flax_plists_equal, 2, 3, 0, /* 2225 DEFUN ("lax-plists-equal", Flax_plists_equal, 2, 3, 0, /*
2108 Return non-nil if lax property lists A and B are `equal'. 2226 Return non-nil if lax property lists A and B are `equal'.
2117 old Lisp implementations, but should not be used except for backward 2235 old Lisp implementations, but should not be used except for backward
2118 compatibility. 2236 compatibility.
2119 */ 2237 */
2120 (a, b, nil_means_not_present)) 2238 (a, b, nil_means_not_present))
2121 { 2239 {
2122 return (plists_differ (a, b, !NILP (nil_means_not_present), 1, 1) 2240 return (plists_differ (a, b, !NILP (nil_means_not_present), 1, 1, 0)
2123 ? Qnil : Qt); 2241 ? Qnil : Qt);
2124 } 2242 }
2125 2243
2126 /* Return the value associated with key PROPERTY in property list PLIST. 2244 /* Return the value associated with key PROPERTY in property list PLIST.
2127 Return nil if key not found. This function is used for internal 2245 Return nil if key not found. This function is used for internal
2802 return make_int (internal_equal (obj1, obj2, XINT (depth))); 2920 return make_int (internal_equal (obj1, obj2, XINT (depth)));
2803 } 2921 }
2804 2922
2805 int 2923 int
2806 internal_equal_trapping_problems (Lisp_Object warning_class, 2924 internal_equal_trapping_problems (Lisp_Object warning_class,
2807 const char *warning_string, 2925 const Ascbyte *warning_string,
2808 int flags, 2926 int flags,
2809 struct call_trapping_problems_result *p, 2927 struct call_trapping_problems_result *p,
2810 int retval, 2928 int retval,
2811 Lisp_Object obj1, Lisp_Object obj2, 2929 Lisp_Object obj1, Lisp_Object obj2,
2812 int depth) 2930 int depth)
2839 *imp1 = XRECORD_LHEADER_IMPLEMENTATION (obj1), 2957 *imp1 = XRECORD_LHEADER_IMPLEMENTATION (obj1),
2840 *imp2 = XRECORD_LHEADER_IMPLEMENTATION (obj2); 2958 *imp2 = XRECORD_LHEADER_IMPLEMENTATION (obj2);
2841 2959
2842 return (imp1 == imp2) && 2960 return (imp1 == imp2) &&
2843 /* EQ-ness of the objects was noticed above */ 2961 /* EQ-ness of the objects was noticed above */
2844 (imp1->equal && (imp1->equal) (obj1, obj2, depth)); 2962 (imp1->equal && (imp1->equal) (obj1, obj2, depth, 0));
2845 } 2963 }
2846 2964
2847 return 0; 2965 return 0;
2966 }
2967
2968 enum array_type
2969 {
2970 ARRAY_NONE = 0,
2971 ARRAY_STRING,
2972 ARRAY_VECTOR,
2973 ARRAY_BIT_VECTOR
2974 };
2975
2976 static enum array_type
2977 array_type (Lisp_Object obj)
2978 {
2979 if (STRINGP (obj))
2980 return ARRAY_STRING;
2981 if (VECTORP (obj))
2982 return ARRAY_VECTOR;
2983 if (BIT_VECTORP (obj))
2984 return ARRAY_BIT_VECTOR;
2985 return ARRAY_NONE;
2848 } 2986 }
2849 2987
2850 int 2988 int
2851 internal_equalp (Lisp_Object obj1, Lisp_Object obj2, int depth) 2989 internal_equalp (Lisp_Object obj1, Lisp_Object obj2, int depth)
2852 { 2990 {
2853 if (depth > 200) 2991 if (depth > 200)
2854 stack_overflow ("Stack overflow in equalp", Qunbound); 2992 stack_overflow ("Stack overflow in equalp", Qunbound);
2855 QUIT; 2993 QUIT;
2994
2995 /* 1. Objects that are `eq' are equal. This will catch the common case
2996 of two equal fixnums or the same object seen twice. */
2856 if (EQ_WITH_EBOLA_NOTICE (obj1, obj2)) 2997 if (EQ_WITH_EBOLA_NOTICE (obj1, obj2))
2857 return 1; 2998 return 1;
2858 #ifdef WITH_NUMBER_TYPES 2999
3000 /* 2. If both numbers, compare with `='. */
2859 if (NUMBERP (obj1) && NUMBERP (obj2)) 3001 if (NUMBERP (obj1) && NUMBERP (obj2))
2860 { 3002 {
2861 switch (promote_args (&obj1, &obj2)) 3003 return (0 == bytecode_arithcompare (obj1, obj2));
2862 { 3004 }
2863 case FIXNUM_T: 3005
2864 return XREALINT (obj1) == XREALINT (obj2); 3006 /* 3. If characters, compare case-insensitively. */
2865 #ifdef HAVE_BIGNUM
2866 case BIGNUM_T:
2867 return bignum_eql (XBIGNUM_DATA (obj1), XBIGNUM_DATA (obj2));
2868 #endif
2869 #ifdef HAVE_RATIO
2870 case RATIO_T:
2871 return ratio_eql (XRATIO_DATA (obj1), XRATIO_DATA (obj2));
2872 #endif
2873 case FLOAT_T:
2874 return XFLOAT_DATA (obj1) == XFLOAT_DATA (obj2);
2875 #ifdef HAVE_BIGFLOAT
2876 case BIGFLOAT_T:
2877 return bigfloat_eql (XBIGFLOAT_DATA (obj1), XBIGFLOAT_DATA (obj2));
2878 #endif
2879 }
2880 }
2881 #else
2882 if ((INTP (obj1) && FLOATP (obj2)) || (FLOATP (obj1) && INTP (obj2)))
2883 return extract_float (obj1) == extract_float (obj2);
2884 #endif
2885 if (CHARP (obj1) && CHARP (obj2)) 3007 if (CHARP (obj1) && CHARP (obj2))
2886 return DOWNCASE (0, XCHAR (obj1)) == DOWNCASE (0, XCHAR (obj2)); 3008 return CANONCASE (0, XCHAR (obj1)) == CANONCASE (0, XCHAR (obj2));
3009
3010 /* 4. If arrays of different types, compare their lengths, and
3011 then compare element-by-element. */
3012 {
3013 enum array_type artype1, artype2;
3014 artype1 = array_type (obj1);
3015 artype2 = array_type (obj2);
3016 if (artype1 != artype2 && artype1 && artype2)
3017 {
3018 EMACS_INT i;
3019 EMACS_INT l1 = XINT (Flength (obj1));
3020 EMACS_INT l2 = XINT (Flength (obj2));
3021 /* Both arrays, but of different lengths */
3022 if (l1 != l2)
3023 return 0;
3024 for (i = 0; i < l1; i++)
3025 if (!internal_equalp (Faref (obj1, make_int (i)),
3026 Faref (obj2, make_int (i)), depth + 1))
3027 return 0;
3028 return 1;
3029 }
3030 }
3031 /* 5. Else, they must be the same type. If so, call the equal() method,
3032 telling it to fold case. For objects that care about case-folding
3033 their contents, the equal() method will call internal_equal_0(). */
2887 if (XTYPE (obj1) != XTYPE (obj2)) 3034 if (XTYPE (obj1) != XTYPE (obj2))
2888 return 0; 3035 return 0;
2889 if (LRECORDP (obj1)) 3036 if (LRECORDP (obj1))
2890 { 3037 {
2891 const struct lrecord_implementation 3038 const struct lrecord_implementation
2892 *imp1 = XRECORD_LHEADER_IMPLEMENTATION (obj1), 3039 *imp1 = XRECORD_LHEADER_IMPLEMENTATION (obj1),
2893 *imp2 = XRECORD_LHEADER_IMPLEMENTATION (obj2); 3040 *imp2 = XRECORD_LHEADER_IMPLEMENTATION (obj2);
2894 3041
2895 /* #### not yet implemented properly, needs another flag to specify
2896 equalp-ness */
2897 return (imp1 == imp2) && 3042 return (imp1 == imp2) &&
2898 /* EQ-ness of the objects was noticed above */ 3043 /* EQ-ness of the objects was noticed above */
2899 (imp1->equal && (imp1->equal) (obj1, obj2, depth)); 3044 (imp1->equal && (imp1->equal) (obj1, obj2, depth, 1));
2900 } 3045 }
2901 3046
2902 return 0; 3047 return 0;
3048 }
3049
3050 int
3051 internal_equal_0 (Lisp_Object obj1, Lisp_Object obj2, int depth, int foldcase)
3052 {
3053 if (foldcase)
3054 return internal_equalp (obj1, obj2, depth);
3055 else
3056 return internal_equal (obj1, obj2, depth);
2903 } 3057 }
2904 3058
2905 /* Note that we may be calling sub-objects that will use 3059 /* Note that we may be calling sub-objects that will use
2906 internal_equal() (instead of internal_old_equal()). Oh well. 3060 internal_equal() (instead of internal_old_equal()). Oh well.
2907 We will get an Ebola note if there's any possibility of confusion, 3061 We will get an Ebola note if there's any possibility of confusion,
2930 Numbers are compared by value. Symbols must match exactly. 3084 Numbers are compared by value. Symbols must match exactly.
2931 */ 3085 */
2932 (object1, object2)) 3086 (object1, object2))
2933 { 3087 {
2934 return internal_equal (object1, object2, 0) ? Qt : Qnil; 3088 return internal_equal (object1, object2, 0) ? Qt : Qnil;
3089 }
3090
3091 DEFUN ("equalp", Fequalp, 2, 2, 0, /*
3092 Return t if two Lisp objects have similar structure and contents.
3093
3094 This is like `equal', except that it accepts numerically equal
3095 numbers of different types (float, integer, bignum, bigfloat), and also
3096 compares strings and characters case-insensitively.
3097
3098 Type objects that are arrays (that is, strings, bit-vectors, and vectors)
3099 of the same length and with contents that are `equalp' are themselves
3100 `equalp', regardless of whether the two objects have the same type.
3101
3102 Other objects whose primary purpose is as containers of other objects are
3103 `equalp' if they would otherwise be equal (same length, type, etc.) and
3104 their contents are `equalp'. This goes for conses, weak lists,
3105 weak boxes, ephemerons, specifiers, hash tables, char tables and range
3106 tables. However, objects that happen to contain other objects but are not
3107 primarily designed for this purpose (e.g. compiled functions, events or
3108 display-related objects such as glyphs, faces or extents) are currently
3109 compared using `equalp' the same way as using `equal'.
3110
3111 More specifically, two hash tables are `equalp' if they have the same test
3112 (see `hash-table-test'), the same number of entries, and the same value for
3113 `hash-table-weakness', and if, for each entry in one hash table, its key is
3114 equivalent to a key in the other hash table using the hash table test, and
3115 its value is `equalp' to the other hash table's value for that key.
3116 */
3117 (object1, object2))
3118 {
3119 return internal_equalp (object1, object2, 0) ? Qt : Qnil;
2935 } 3120 }
2936 3121
2937 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /* 3122 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /*
2938 Return t if two Lisp objects have similar structure and contents. 3123 Return t if two Lisp objects have similar structure and contents.
2939 They must have the same data type. 3124 They must have the same data type.
3148 RETURN_UNGCPRO (Qnil); /* No non-nil args provided. */ 3333 RETURN_UNGCPRO (Qnil); /* No non-nil args provided. */
3149 } 3334 }
3150 3335
3151 3336
3152 /* This is the guts of several mapping functions. 3337 /* This is the guts of several mapping functions.
3153 Apply FUNCTION to each element of SEQUENCE, one by one, 3338
3154 storing the results into elements of VALS, a C vector of Lisp_Objects. 3339 Call FUNCTION CALL_COUNT times, with NSEQUENCES arguments each time,
3155 LENI is the length of VALS, which should also be the length of SEQUENCE. 3340 taking the elements from SEQUENCES. If VALS is non-NULL, store the
3156 3341 results into VALS, a C array of Lisp_Objects; else, if LISP_VALS is
3157 If VALS is a null pointer, do not accumulate the results. */ 3342 non-nil, store the results into LISP_VALS, a sequence with sufficient
3343 room for CALL_COUNT results (but see the documentation of SOME_OR_EVERY.)
3344 Else, do not accumulate any result.
3345
3346 If VALS is non-NULL, NSEQUENCES is one, and SEQUENCES[0] is a cons,
3347 mapcarX will store the elements of SEQUENCES[0] in stack and GCPRO them,
3348 so FUNCTION cannot insert a non-cons into SEQUENCES[0] and throw off
3349 mapcarX.
3350
3351 Otherwise, mapcarX signals a wrong-type-error if it encounters a
3352 non-cons, non-array when traversing SEQUENCES. Common Lisp specifies in
3353 MAPPING-DESTRUCTIVE-INTERACTION that it is an error when FUNCTION
3354 destructively modifies SEQUENCES in a way that might affect the ongoing
3355 traversal operation.
3356
3357 If SOME_OR_EVERY is SOME_OR_EVERY_SOME, return the (possibly multiple)
3358 values given by FUNCTION the first time it is non-nil, and abandon the
3359 iterations. LISP_VALS must be a cons, and the return value will be
3360 stored in its car. If SOME_OR_EVERY is SOME_OR_EVERY_EVERY, store Qnil
3361 in the car of LISP_VALS if FUNCTION gives nil; otherwise leave it
3362 alone. */
3363
3364 #define SOME_OR_EVERY_NEITHER 0
3365 #define SOME_OR_EVERY_SOME 1
3366 #define SOME_OR_EVERY_EVERY 2
3158 3367
3159 static void 3368 static void
3160 mapcar1 (Elemcount leni, Lisp_Object *vals, 3369 mapcarX (Elemcount call_count, Lisp_Object *vals, Lisp_Object lisp_vals,
3161 Lisp_Object function, Lisp_Object sequence) 3370 Lisp_Object function, int nsequences, Lisp_Object *sequences,
3162 { 3371 int some_or_every)
3163 Lisp_Object result; 3372 {
3164 Lisp_Object args[2]; 3373 Lisp_Object called, *args;
3165 struct gcpro gcpro1; 3374 struct gcpro gcpro1, gcpro2;
3166 3375 int i, j;
3167 if (vals) 3376 enum lrecord_type lisp_vals_type;
3168 { 3377
3169 GCPRO1 (vals[0]); 3378 assert (LRECORDP (lisp_vals));
3170 gcpro1.nvars = 0; 3379 lisp_vals_type = (enum lrecord_type) XRECORD_LHEADER (lisp_vals)->type;
3171 } 3380
3172 3381 args = alloca_array (Lisp_Object, nsequences + 1);
3173 args[0] = function; 3382 args[0] = function;
3174 3383 for (i = 1; i <= nsequences; ++i)
3175 if (LISTP (sequence)) 3384 {
3176 { 3385 args[i] = Qnil;
3177 /* A devious `function' could either: 3386 }
3178 - insert garbage into the list in front of us, causing XCDR to crash 3387
3179 - amputate the list behind us using (setcdr), causing the remaining 3388 if (vals != NULL)
3180 elts to lose their GCPRO status. 3389 {
3181 3390 GCPRO2 (args[0], vals[0]);
3182 if (vals != 0) we avoid this by copying the elts into the 3391 gcpro1.nvars = nsequences + 1;
3183 `vals' array. By a stroke of luck, `vals' is exactly large 3392 gcpro2.nvars = 0;
3184 enough to hold the elts left to be traversed as well as the 3393 }
3185 results computed so far. 3394 else
3186 3395 {
3187 if (vals == 0) we don't have any free space available and 3396 GCPRO1 (args[0]);
3188 don't want to eat up any more stack with ALLOCA (). 3397 gcpro1.nvars = nsequences + 1;
3189 So we use EXTERNAL_LIST_LOOP_3_NO_DECLARE and GCPRO the tail. */ 3398 }
3190 3399
3191 if (vals) 3400 /* Be extra nice in the event that we've been handed one list and one
3401 only; make it possible for FUNCTION to set cdrs not yet processed to
3402 non-cons, non-nil objects without ill-effect, if we have been handed
3403 the stack space to do that. */
3404 if (vals != NULL && 1 == nsequences && CONSP (sequences[0]))
3405 {
3406 Lisp_Object lst = sequences[0];
3407 Lisp_Object *val = vals;
3408 for (i = 0; i < call_count; ++i)
3192 { 3409 {
3193 Lisp_Object *val = vals; 3410 *val++ = XCAR (lst);
3194 Elemcount i; 3411 lst = XCDR (lst);
3195 3412 }
3196 LIST_LOOP_2 (elt, sequence) 3413 gcpro2.nvars = call_count;
3197 *val++ = elt; 3414
3198 3415 for (i = 0; i < call_count; ++i)
3199 gcpro1.nvars = leni; 3416 {
3200 3417 args[1] = vals[i];
3201 for (i = 0; i < leni; i++) 3418 vals[i] = IGNORE_MULTIPLE_VALUES (Ffuncall (nsequences + 1, args));
3419 }
3420 }
3421 else
3422 {
3423 Binbyte *sequence_types = alloca_array (Binbyte, nsequences);
3424 for (j = 0; j < nsequences; ++j)
3425 {
3426 sequence_types[j] = XRECORD_LHEADER (sequences[j])->type;
3427 }
3428
3429 for (i = 0; i < call_count; ++i)
3430 {
3431 for (j = 0; j < nsequences; ++j)
3202 { 3432 {
3203 args[1] = vals[i]; 3433 switch (sequence_types[j])
3204 vals[i] = Ffuncall (2, args); 3434 {
3435 case lrecord_type_cons:
3436 {
3437 if (!CONSP (sequences[j]))
3438 {
3439 /* This means FUNCTION has probably messed
3440 around with a cons in one of the sequences,
3441 since we checked the type
3442 (CHECK_SEQUENCE()) and the length and
3443 structure (with Flength()) correctly in our
3444 callers. */
3445 dead_wrong_type_argument (Qconsp, sequences[j]);
3446 }
3447 args[j + 1] = XCAR (sequences[j]);
3448 sequences[j] = XCDR (sequences[j]);
3449 break;
3450 }
3451 case lrecord_type_vector:
3452 {
3453 args[j + 1] = XVECTOR_DATA (sequences[j])[i];
3454 break;
3455 }
3456 case lrecord_type_string:
3457 {
3458 args[j + 1] = make_char (string_ichar (sequences[j], i));
3459 break;
3460 }
3461 case lrecord_type_bit_vector:
3462 {
3463 args[j + 1]
3464 = make_int (bit_vector_bit (XBIT_VECTOR (sequences[j]),
3465 i));
3466 break;
3467 }
3468 default:
3469 ABORT();
3470 }
3471 }
3472 called = Ffuncall (nsequences + 1, args);
3473 if (vals != NULL)
3474 {
3475 vals[i] = IGNORE_MULTIPLE_VALUES (called);
3476 gcpro2.nvars += 1;
3477 }
3478 else
3479 {
3480 switch (lisp_vals_type)
3481 {
3482 case lrecord_type_symbol:
3483 break;
3484 case lrecord_type_cons:
3485 {
3486 if (SOME_OR_EVERY_NEITHER == some_or_every)
3487 {
3488 called = IGNORE_MULTIPLE_VALUES (called);
3489 if (!CONSP (lisp_vals))
3490 {
3491 /* If FUNCTION has inserted a non-cons non-nil
3492 cdr into the list before we've processed the
3493 relevant part, error. */
3494 dead_wrong_type_argument (Qconsp, lisp_vals);
3495 }
3496
3497 XSETCAR (lisp_vals, called);
3498 lisp_vals = XCDR (lisp_vals);
3499 break;
3500 }
3501
3502 if (SOME_OR_EVERY_SOME == some_or_every)
3503 {
3504 if (!NILP (IGNORE_MULTIPLE_VALUES (called)))
3505 {
3506 XCAR (lisp_vals) = called;
3507 UNGCPRO;
3508 return;
3509 }
3510 break;
3511 }
3512
3513 if (SOME_OR_EVERY_EVERY == some_or_every)
3514 {
3515 called = IGNORE_MULTIPLE_VALUES (called);
3516 if (NILP (called))
3517 {
3518 XCAR (lisp_vals) = Qnil;
3519 UNGCPRO;
3520 return;
3521 }
3522 break;
3523 }
3524
3525 goto bad_some_or_every_flag;
3526 }
3527 case lrecord_type_vector:
3528 {
3529 called = IGNORE_MULTIPLE_VALUES (called);
3530 i < XVECTOR_LENGTH (lisp_vals) ?
3531 (XVECTOR_DATA (lisp_vals)[i] = called) :
3532 /* Let #'aset error. */
3533 Faset (lisp_vals, make_int (i), called);
3534 break;
3535 }
3536 case lrecord_type_string:
3537 {
3538 /* If this ever becomes a code hotspot, we can keep
3539 around pointers into the data of the string, checking
3540 each time that it hasn't been relocated. */
3541 called = IGNORE_MULTIPLE_VALUES (called);
3542 Faset (lisp_vals, make_int (i), called);
3543 break;
3544 }
3545 case lrecord_type_bit_vector:
3546 {
3547 called = IGNORE_MULTIPLE_VALUES (called);
3548 (BITP (called) &&
3549 i < bit_vector_length (XBIT_VECTOR (lisp_vals))) ?
3550 set_bit_vector_bit (XBIT_VECTOR (lisp_vals), i,
3551 XINT (called)) :
3552 (void) Faset (lisp_vals, make_int (i), called);
3553 break;
3554 }
3555 bad_some_or_every_flag:
3556 default:
3557 {
3558 ABORT();
3559 break;
3560 }
3561 }
3205 } 3562 }
3206 } 3563 }
3207 else 3564 }
3208 { 3565 UNGCPRO;
3209 Lisp_Object elt, tail; 3566 }
3210 EMACS_INT len_unused; 3567
3211 struct gcpro ngcpro1; 3568 DEFUN ("mapconcat", Fmapconcat, 3, MANY, 0, /*
3212 3569 Call FUNCTION on each element of SEQUENCE, and concat results to a string.
3213 NGCPRO1 (tail);
3214
3215 {
3216 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len_unused)
3217 {
3218 args[1] = elt;
3219 Ffuncall (2, args);
3220 }
3221 }
3222
3223 NUNGCPRO;
3224 }
3225 }
3226 else if (VECTORP (sequence))
3227 {
3228 Lisp_Object *objs = XVECTOR_DATA (sequence);
3229 Elemcount i;
3230 for (i = 0; i < leni; i++)
3231 {
3232 args[1] = *objs++;
3233 result = Ffuncall (2, args);
3234 if (vals) vals[gcpro1.nvars++] = result;
3235 }
3236 }
3237 else if (STRINGP (sequence))
3238 {
3239 /* The string data of `sequence' might be relocated during GC. */
3240 Bytecount slen = XSTRING_LENGTH (sequence);
3241 Ibyte *p = alloca_ibytes (slen);
3242 Ibyte *end = p + slen;
3243
3244 memcpy (p, XSTRING_DATA (sequence), slen);
3245
3246 while (p < end)
3247 {
3248 args[1] = make_char (itext_ichar (p));
3249 INC_IBYTEPTR (p);
3250 result = Ffuncall (2, args);
3251 if (vals) vals[gcpro1.nvars++] = result;
3252 }
3253 }
3254 else if (BIT_VECTORP (sequence))
3255 {
3256 Lisp_Bit_Vector *v = XBIT_VECTOR (sequence);
3257 Elemcount i;
3258 for (i = 0; i < leni; i++)
3259 {
3260 args[1] = make_int (bit_vector_bit (v, i));
3261 result = Ffuncall (2, args);
3262 if (vals) vals[gcpro1.nvars++] = result;
3263 }
3264 }
3265 else
3266 ABORT (); /* unreachable, since Flength (sequence) did not get an error */
3267
3268 if (vals)
3269 UNGCPRO;
3270 }
3271
3272 DEFUN ("mapconcat", Fmapconcat, 3, 3, 0, /*
3273 Apply FUNCTION to each element of SEQUENCE, and concat the results to a string.
3274 Between each pair of results, insert SEPARATOR. 3570 Between each pair of results, insert SEPARATOR.
3275 3571
3276 Each result, and SEPARATOR, should be strings. Thus, using " " as SEPARATOR 3572 Each result, and SEPARATOR, should be strings. Thus, using " " as SEPARATOR
3277 results in spaces between the values returned by FUNCTION. SEQUENCE itself 3573 results in spaces between the values returned by FUNCTION. SEQUENCE itself
3278 may be a list, a vector, a bit vector, or a string. 3574 may be a list, a vector, a bit vector, or a string.
3279 */ 3575
3280 (function, sequence, separator)) 3576 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3281 { 3577 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3282 EMACS_INT len = XINT (Flength (sequence)); 3578 from each sequence will be used each time FUNCTION is called, and
3283 Lisp_Object *args; 3579 `mapconcat' will give up once the shortest sequence is exhausted.
3284 EMACS_INT i; 3580
3285 EMACS_INT nargs = len + len - 1; 3581 arguments: (FUNCTION SEQUENCE SEPARATOR &rest SEQUENCES)
3286 3582 */
3287 if (len == 0) return build_string (""); 3583 (int nargs, Lisp_Object *args))
3288 3584 {
3289 args = alloca_array (Lisp_Object, nargs); 3585 Lisp_Object function = args[0];
3290 3586 Lisp_Object sequence = args[1];
3291 mapcar1 (len, args, function, sequence); 3587 Lisp_Object separator = args[2];
3588 Elemcount len = EMACS_INT_MAX;
3589 Lisp_Object *args0;
3590 EMACS_INT i, nargs0;
3591
3592 args[2] = sequence;
3593 args[1] = separator;
3594
3595 for (i = 2; i < nargs; ++i)
3596 {
3597 CHECK_SEQUENCE (args[i]);
3598 len = min (len, XINT (Flength (args[i])));
3599 }
3600
3601 if (len == 0) return build_ascstring ("");
3602
3603 nargs0 = len + len - 1;
3604 args0 = alloca_array (Lisp_Object, nargs0);
3605
3606 /* Special-case this, it's very common and doesn't require any
3607 funcalls. Upside of doing it here, instead of cl-macs.el: no consing,
3608 apart from the final string, we allocate everything on the stack. */
3609 if (EQ (function, Qidentity) && 3 == nargs && CONSP (sequence))
3610 {
3611 for (i = 0; i < len; ++i)
3612 {
3613 args0[i] = XCAR (sequence);
3614 sequence = XCDR (sequence);
3615 }
3616 }
3617 else
3618 {
3619 mapcarX (len, args0, Qnil, function, nargs - 2, args + 2,
3620 SOME_OR_EVERY_NEITHER);
3621 }
3292 3622
3293 for (i = len - 1; i >= 0; i--) 3623 for (i = len - 1; i >= 0; i--)
3294 args[i + i] = args[i]; 3624 args0[i + i] = args0[i];
3295 3625
3296 for (i = 1; i < nargs; i += 2) 3626 for (i = 1; i < nargs0; i += 2)
3297 args[i] = separator; 3627 args0[i] = separator;
3298 3628
3299 return Fconcat (nargs, args); 3629 return Fconcat (nargs0, args0);
3300 } 3630 }
3301 3631
3302 DEFUN ("mapcar", Fmapcar, 2, 2, 0, /* 3632 DEFUN ("mapcar*", FmapcarX, 2, MANY, 0, /*
3303 Apply FUNCTION to each element of SEQUENCE; return a list of the results. 3633 Call FUNCTION on each element of SEQUENCE; return a list of the results.
3304 The result is a list of the same length as SEQUENCE. 3634 The result is a list of the same length as SEQUENCE.
3305 SEQUENCE may be a list, a vector, a bit vector, or a string. 3635 SEQUENCE may be a list, a vector, a bit vector, or a string.
3306 */ 3636
3307 (function, sequence)) 3637 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3308 { 3638 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3309 Elemcount len = XINT (Flength (sequence)); 3639 from each sequence will be used each time FUNCTION is called, and `mapcar'
3310 Lisp_Object *args = alloca_array (Lisp_Object, len); 3640 stops calling FUNCTION once the shortest sequence is exhausted.
3311 3641
3312 mapcar1 (len, args, function, sequence); 3642 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3313 3643 */
3314 return Flist ((int) len, args); 3644 (int nargs, Lisp_Object *args))
3315 } 3645 {
3316 3646 Lisp_Object function = args[0];
3317 DEFUN ("mapvector", Fmapvector, 2, 2, 0, /* 3647 Elemcount len = EMACS_INT_MAX;
3318 Apply FUNCTION to each element of SEQUENCE; return a vector of the results. 3648 Lisp_Object *args0;
3649 int i;
3650
3651 for (i = 1; i < nargs; ++i)
3652 {
3653 CHECK_SEQUENCE (args[i]);
3654 len = min (len, XINT (Flength (args[i])));
3655 }
3656
3657 args0 = alloca_array (Lisp_Object, len);
3658 mapcarX (len, args0, Qnil, function, nargs - 1, args + 1,
3659 SOME_OR_EVERY_NEITHER);
3660
3661 return Flist ((int) len, args0);
3662 }
3663
3664 DEFUN ("mapvector", Fmapvector, 2, MANY, 0, /*
3665 Call FUNCTION on each element of SEQUENCE; return a vector of the results.
3319 The result is a vector of the same length as SEQUENCE. 3666 The result is a vector of the same length as SEQUENCE.
3320 SEQUENCE may be a list, a vector, a bit vector, or a string. 3667 SEQUENCE may be a list, a vector, a bit vector, or a string.
3321 */ 3668
3322 (function, sequence)) 3669 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3323 { 3670 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3324 Elemcount len = XINT (Flength (sequence)); 3671 from each sequence will be used each time FUNCTION is called, and
3325 Lisp_Object result = make_vector (len, Qnil); 3672 `mapvector' stops calling FUNCTION once the shortest sequence is exhausted.
3673
3674 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3675 */
3676 (int nargs, Lisp_Object *args))
3677 {
3678 Lisp_Object function = args[0];
3679 Elemcount len = EMACS_INT_MAX;
3680 Lisp_Object result;
3326 struct gcpro gcpro1; 3681 struct gcpro gcpro1;
3327 3682 int i;
3683
3684 for (i = 1; i < nargs; ++i)
3685 {
3686 CHECK_SEQUENCE (args[i]);
3687 len = min (len, XINT (Flength (args[i])));
3688 }
3689
3690 result = make_vector (len, Qnil);
3328 GCPRO1 (result); 3691 GCPRO1 (result);
3329 mapcar1 (len, XVECTOR_DATA (result), function, sequence); 3692 /* Don't pass result as the lisp_object argument, we want mapcarX to protect
3693 a single list argument's elements from being garbage-collected. */
3694 mapcarX (len, XVECTOR_DATA (result), Qnil, function, nargs - 1, args +1,
3695 SOME_OR_EVERY_NEITHER);
3330 UNGCPRO; 3696 UNGCPRO;
3331 3697
3332 return result; 3698 return result;
3333 } 3699 }
3334 3700
3335 DEFUN ("mapc-internal", Fmapc_internal, 2, 2, 0, /* 3701 DEFUN ("mapcan", Fmapcan, 2, MANY, 0, /*
3336 Apply FUNCTION to each element of SEQUENCE. 3702 Call FUNCTION on each element of SEQUENCE; chain the results together.
3703
3704 FUNCTION must normally return a list; the results will be concatenated
3705 together using `nconc'.
3706
3707 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3708 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3709 from each sequence will be used each time FUNCTION is called, and
3710 `mapcan' stops calling FUNCTION once the shortest sequence is exhausted.
3711
3712 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3713 */
3714 (int nargs, Lisp_Object *args))
3715 {
3716 Lisp_Object function = args[0], nconcing;
3717 Elemcount len = EMACS_INT_MAX;
3718 Lisp_Object *args0;
3719 struct gcpro gcpro1;
3720 int i;
3721
3722 for (i = 1; i < nargs; ++i)
3723 {
3724 CHECK_SEQUENCE (args[i]);
3725 len = min (len, XINT (Flength (args[i])));
3726 }
3727
3728 args0 = alloca_array (Lisp_Object, len + 1);
3729 mapcarX (len, args0 + 1, Qnil, function, nargs - 1, args + 1,
3730 SOME_OR_EVERY_NEITHER);
3731
3732 if (len < 2)
3733 {
3734 return len ? args0[1] : Qnil;
3735 }
3736
3737 /* bytecode_nconc2 can signal and return, we need to GCPRO the args, since
3738 mapcarX is no longer doing this for us. */
3739 args0[0] = Fcons (Qnil, Qnil);
3740 GCPRO1 (args0[0]);
3741 gcpro1.nvars = len + 1;
3742
3743 for (i = 0; i < len; ++i)
3744 {
3745 nconcing = bytecode_nconc2 (args0 + i);
3746 args0[i + 1] = nconcing;
3747 }
3748
3749 RETURN_UNGCPRO (XCDR (nconcing));
3750 }
3751
3752 DEFUN ("mapc", Fmapc, 2, MANY, 0, /*
3753 Call FUNCTION on each element of SEQUENCE.
3754
3337 SEQUENCE may be a list, a vector, a bit vector, or a string. 3755 SEQUENCE may be a list, a vector, a bit vector, or a string.
3338 This function is like `mapcar' but does not accumulate the results, 3756 This function is like `mapcar' but does not accumulate the results,
3339 which is more efficient if you do not use the results. 3757 which is more efficient if you do not use the results.
3340 3758
3341 The difference between this and `mapc' is that `mapc' supports all 3759 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3342 the spiffy Common Lisp arguments. You should normally use `mapc'. 3760 there are SEQUENCES, plus one for the elements from SEQUENCE. One element
3343 */ 3761 from each sequence will be used each time FUNCTION is called, and
3344 (function, sequence)) 3762 `mapc' stops calling FUNCTION once the shortest sequence is exhausted.
3345 { 3763
3346 mapcar1 (XINT (Flength (sequence)), 0, function, sequence); 3764 Return SEQUENCE.
3347 3765
3348 return sequence; 3766 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3349 } 3767 */
3350 3768 (int nargs, Lisp_Object *args))
3769 {
3770 Elemcount len = EMACS_INT_MAX;
3771 Lisp_Object sequence = args[1];
3772 struct gcpro gcpro1;
3773 int i;
3774
3775 for (i = 1; i < nargs; ++i)
3776 {
3777 CHECK_SEQUENCE (args[i]);
3778 len = min (len, XINT (Flength (args[i])));
3779 }
3780
3781 /* We need to GCPRO sequence, because mapcarX will modify the
3782 elements of the args array handed to it, and this may involve
3783 elements of sequence getting garbage collected. */
3784 GCPRO1 (sequence);
3785 mapcarX (len, NULL, Qnil, args[0], nargs - 1, args + 1,
3786 SOME_OR_EVERY_NEITHER);
3787 RETURN_UNGCPRO (sequence);
3788 }
3789
3790 DEFUN ("map", Fmap, 3, MANY, 0, /*
3791 Map FUNCTION across one or more sequences, returning a sequence.
3792
3793 TYPE is the sequence type to return, FUNCTION is the function, SEQUENCE is
3794 the first argument sequence, SEQUENCES are the other argument sequences.
3795
3796 FUNCTION will be called with (1+ (length SEQUENCES)) arguments, and must be
3797 capable of accepting this number of arguments.
3798
3799 Certain TYPEs are recognised internally by `map', but others are not, and
3800 `coerce' may throw an error on an attempt to convert to a TYPE it does not
3801 understand. A null TYPE means do not accumulate any values.
3802
3803 arguments: (TYPE FUNCTION SEQUENCE &rest SEQUENCES)
3804 */
3805 (int nargs, Lisp_Object *args))
3806 {
3807 Lisp_Object type = args[0];
3808 Lisp_Object function = args[1];
3809 Lisp_Object result = Qnil;
3810 Lisp_Object *args0 = NULL;
3811 Elemcount len = EMACS_INT_MAX;
3812 int i;
3813 struct gcpro gcpro1;
3814
3815 for (i = 2; i < nargs; ++i)
3816 {
3817 CHECK_SEQUENCE (args[i]);
3818 len = min (len, XINT (Flength (args[i])));
3819 }
3820
3821 if (!NILP (type))
3822 {
3823 args0 = alloca_array (Lisp_Object, len);
3824 }
3825
3826 mapcarX (len, args0, Qnil, function, nargs - 2, args + 2,
3827 SOME_OR_EVERY_NEITHER);
3828
3829 if (EQ (type, Qnil))
3830 {
3831 return result;
3832 }
3833
3834 if (EQ (type, Qvector) || EQ (type, Qarray))
3835 {
3836 result = Fvector (len, args0);
3837 }
3838 else if (EQ (type, Qstring))
3839 {
3840 result = Fstring (len, args0);
3841 }
3842 else if (EQ (type, Qlist))
3843 {
3844 result = Flist (len, args0);
3845 }
3846 else if (EQ (type, Qbit_vector))
3847 {
3848 result = Fbit_vector (len, args0);
3849 }
3850 else
3851 {
3852 result = Flist (len, args0);
3853 GCPRO1 (result);
3854 result = call2 (Qcoerce, result, type);
3855 UNGCPRO;
3856 }
3857
3858 return result;
3859 }
3860
3861 DEFUN ("map-into", Fmap_into, 2, MANY, 0, /*
3862 Modify RESULT-SEQUENCE using the return values of FUNCTION on SEQUENCES.
3863
3864 RESULT-SEQUENCE and SEQUENCES can be lists or arrays.
3865
3866 FUNCTION must accept at least as many arguments as there are SEQUENCES
3867 \(possibly zero). If RESULT-SEQUENCE and the elements of SEQUENCES are not
3868 the same length, stop when the shortest is exhausted; any elements of
3869 RESULT-SEQUENCE beyond that are unmodified.
3870
3871 Return RESULT-SEQUENCE.
3872
3873 arguments: (RESULT-SEQUENCE FUNCTION &rest SEQUENCES)
3874 */
3875 (int nargs, Lisp_Object *args))
3876 {
3877 Elemcount len = EMACS_INT_MAX;
3878 Lisp_Object result_sequence = args[0];
3879 Lisp_Object function = args[1];
3880 int i;
3881
3882 args[0] = function;
3883 args[1] = result_sequence;
3884
3885 for (i = 1; i < nargs; ++i)
3886 {
3887 CHECK_SEQUENCE (args[i]);
3888 len = min (len, XINT (Flength (args[i])));
3889 }
3890
3891 mapcarX (len, NULL, result_sequence, function, nargs - 2, args + 2,
3892 SOME_OR_EVERY_NEITHER);
3893
3894 return result_sequence;
3895 }
3896
3897 DEFUN ("some", Fsome, 2, MANY, 0, /*
3898 Return true if PREDICATE gives non-nil for an element of SEQUENCE.
3899
3900 If so, return the value (possibly multiple) given by PREDICATE.
3901
3902 With optional SEQUENCES, call PREDICATE each time with as many arguments as
3903 there are SEQUENCES (plus one for the element from SEQUENCE).
3904
3905 arguments: (PREDICATE SEQUENCE &rest SEQUENCES)
3906 */
3907 (int nargs, Lisp_Object *args))
3908 {
3909 Lisp_Object result_box = Fcons (Qnil, Qnil);
3910 struct gcpro gcpro1;
3911 Elemcount len = EMACS_INT_MAX;
3912 int i;
3913
3914 GCPRO1 (result_box);
3915
3916 for (i = 1; i < nargs; ++i)
3917 {
3918 CHECK_SEQUENCE (args[i]);
3919 len = min (len, XINT (Flength (args[i])));
3920 }
3921
3922 mapcarX (len, NULL, result_box, args[0], nargs - 1, args +1,
3923 SOME_OR_EVERY_SOME);
3924
3925 RETURN_UNGCPRO (XCAR (result_box));
3926 }
3927
3928 DEFUN ("every", Fevery, 2, MANY, 0, /*
3929 Return true if PREDICATE is true of every element of SEQUENCE.
3930
3931 With optional SEQUENCES, call PREDICATE each time with as many arguments as
3932 there are SEQUENCES (plus one for the element from SEQUENCE).
3933
3934 In contrast to `some', `every' never returns multiple values.
3935
3936 arguments: (PREDICATE SEQUENCE &rest SEQUENCES)
3937 */
3938 (int nargs, Lisp_Object *args))
3939 {
3940 Lisp_Object result_box = Fcons (Qt, Qnil);
3941 struct gcpro gcpro1;
3942 Elemcount len = EMACS_INT_MAX;
3943 int i;
3944
3945 GCPRO1 (result_box);
3946
3947 for (i = 1; i < nargs; ++i)
3948 {
3949 CHECK_SEQUENCE (args[i]);
3950 len = min (len, XINT (Flength (args[i])));
3951 }
3952
3953 mapcarX (len, NULL, result_box, args[0], nargs - 1, args +1,
3954 SOME_OR_EVERY_EVERY);
3955
3956 RETURN_UNGCPRO (XCAR (result_box));
3957 }
3958
3959 /* Call FUNCTION with NLISTS arguments repeatedly, each Nth argument
3960 corresponding to the result of calling (nthcdr ITERATION-COUNT LISTS[N]),
3961 until that #'nthcdr expression gives nil for some element of LISTS.
3962
3963 If MAPLP is zero, return LISTS[0]. Otherwise, return a list of the return
3964 values from FUNCTION; if NCONCP is non-zero, nconc them together.
3965
3966 In contrast to mapcarX, we don't require our callers to check LISTS for
3967 well-formedness, we signal wrong-type-argument if it's not a list, or
3968 circular-list if it's circular. */
3969
3970 static Lisp_Object
3971 maplist (Lisp_Object function, int nlists, Lisp_Object *lists, int maplp,
3972 int nconcp)
3973 {
3974 Lisp_Object result = maplp ? lists[0] : Fcons (Qnil, Qnil), funcalled;
3975 Lisp_Object nconcing[2], accum = result, *args;
3976 struct gcpro gcpro1, gcpro2, gcpro3;
3977 int i, j, continuing = (nlists > 0), called_count = 0;
3978
3979 args = alloca_array (Lisp_Object, nlists + 1);
3980 args[0] = function;
3981 for (i = 1; i <= nlists; ++i)
3982 {
3983 args[i] = Qnil;
3984 }
3985
3986 if (nconcp)
3987 {
3988 nconcing[0] = result;
3989 nconcing[1] = Qnil;
3990 GCPRO3 (args[0], nconcing[0], result);
3991 gcpro1.nvars = 1;
3992 gcpro2.nvars = 2;
3993 }
3994 else
3995 {
3996 GCPRO2 (args[0], result);
3997 gcpro1.nvars = 1;
3998 }
3999
4000 while (continuing)
4001 {
4002 for (j = 0; j < nlists; ++j)
4003 {
4004 if (CONSP (lists[j]))
4005 {
4006 args[j + 1] = lists[j];
4007 lists[j] = XCDR (lists[j]);
4008 }
4009 else if (NILP (lists[j]))
4010 {
4011 continuing = 0;
4012 break;
4013 }
4014 else
4015 {
4016 dead_wrong_type_argument (Qlistp, lists[j]);
4017 }
4018 }
4019 if (!continuing) break;
4020 funcalled = IGNORE_MULTIPLE_VALUES (Ffuncall (nlists + 1, args));
4021 if (!maplp)
4022 {
4023 if (nconcp)
4024 {
4025 /* This order of calls means we check that each list is
4026 well-formed once and once only. The last result does
4027 not have to be a list. */
4028 nconcing[1] = funcalled;
4029 nconcing[0] = bytecode_nconc2 (nconcing);
4030 }
4031 else
4032 {
4033 /* Add to the end, avoiding the need to call nreverse
4034 once we're done: */
4035 XSETCDR (accum, Fcons (funcalled, Qnil));
4036 accum = XCDR (accum);
4037 }
4038 }
4039
4040 if (++called_count % CIRCULAR_LIST_SUSPICION_LENGTH) continue;
4041
4042 for (j = 0; j < nlists; ++j)
4043 {
4044 EXTERNAL_LIST_LOOP_1 (lists[j])
4045 {
4046 /* Just check the lists aren't circular, using the
4047 EXTERNAL_LIST_LOOP_1 macro. */
4048 }
4049 }
4050 }
4051
4052 if (!maplp)
4053 {
4054 result = XCDR (result);
4055 }
4056
4057 RETURN_UNGCPRO (result);
4058 }
4059
4060 DEFUN ("maplist", Fmaplist, 2, MANY, 0, /*
4061 Call FUNCTION on each sublist of LIST and LISTS.
4062 Like `mapcar', except applies to lists and their cdr's rather than to
4063 the elements themselves."
4064
4065 arguments: (FUNCTION LIST &rest LISTS)
4066 */
4067 (int nargs, Lisp_Object *args))
4068 {
4069 return maplist (args[0], nargs - 1, args + 1, 0, 0);
4070 }
4071
4072 DEFUN ("mapl", Fmapl, 2, MANY, 0, /*
4073 Like `maplist', but do not accumulate values returned by the function.
4074
4075 arguments: (FUNCTION LIST &rest LISTS)
4076 */
4077 (int nargs, Lisp_Object *args))
4078 {
4079 return maplist (args[0], nargs - 1, args + 1, 1, 0);
4080 }
4081
4082 DEFUN ("mapcon", Fmapcon, 2, MANY, 0, /*
4083 Like `maplist', but chains together the values returned by FUNCTION.
4084
4085 FUNCTION must return a list (unless it happens to be the last
4086 iteration); the results will be concatenated together using `nconc'.
4087
4088 arguments: (FUNCTION LIST &rest LISTS)
4089 */
4090 (int nargs, Lisp_Object *args))
4091 {
4092 return maplist (args[0], nargs - 1, args + 1, 0, 1);
4093 }
3351 4094
3352 /* Extra random functions */ 4095 /* Extra random functions */
3353 4096
3354 DEFUN ("replace-list", Freplace_list, 2, 2, 0, /* 4097 DEFUN ("replace-list", Freplace_list, 2, 2, 0, /*
3355 Destructively replace the list OLD with NEW. 4098 Destructively replace the list OLD with NEW.
3389 old = Qnil; 4132 old = Qnil;
3390 4133
3391 return old; 4134 return old;
3392 } 4135 }
3393 4136
4137
3394 Lisp_Object 4138 Lisp_Object
3395 add_suffix_to_symbol (Lisp_Object symbol, const Ascbyte *ascii_string) 4139 add_suffix_to_symbol (Lisp_Object symbol, const Ascbyte *ascii_string)
3396 { 4140 {
3397 return Fintern (concat2 (Fsymbol_name (symbol), 4141 return Fintern (concat2 (Fsymbol_name (symbol),
3398 build_string (ascii_string)), 4142 build_ascstring (ascii_string)),
3399 Qnil); 4143 Qnil);
3400 } 4144 }
3401 4145
3402 Lisp_Object 4146 Lisp_Object
3403 add_prefix_to_symbol (const Ascbyte *ascii_string, Lisp_Object symbol) 4147 add_prefix_to_symbol (const Ascbyte *ascii_string, Lisp_Object symbol)
3404 { 4148 {
3405 return Fintern (concat2 (build_string (ascii_string), 4149 return Fintern (concat2 (build_ascstring (ascii_string),
3406 Fsymbol_name (symbol)), 4150 Fsymbol_name (symbol)),
3407 Qnil); 4151 Qnil);
3408 } 4152 }
3409 4153
3410 4154
3650 ((Character) < 128) 4394 ((Character) < 128)
3651 #define IS_BASE64(Character) \ 4395 #define IS_BASE64(Character) \
3652 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0) 4396 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
3653 4397
3654 /* Table of characters coding the 64 values. */ 4398 /* Table of characters coding the 64 values. */
3655 static char base64_value_to_char[64] = 4399 static Ascbyte base64_value_to_char[64] =
3656 { 4400 {
3657 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */ 4401 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */
3658 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */ 4402 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
3659 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */ 4403 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */
3660 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */ 4404 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */
3697 `--------+--------+--------+--------' 4441 `--------+--------+--------+--------'
3698 4442
3699 The octets are divided into 6 bit chunks, which are then encoded into 4443 The octets are divided into 6 bit chunks, which are then encoded into
3700 base64 characters. */ 4444 base64 characters. */
3701 4445
3702 static DECLARE_DOESNT_RETURN (base64_conversion_error (const char *, 4446 static DECLARE_DOESNT_RETURN (base64_conversion_error (const Ascbyte *,
3703 Lisp_Object)); 4447 Lisp_Object));
3704 4448
3705 static DOESNT_RETURN 4449 static DOESNT_RETURN
3706 base64_conversion_error (const char *reason, Lisp_Object frob) 4450 base64_conversion_error (const Ascbyte *reason, Lisp_Object frob)
3707 { 4451 {
3708 signal_error (Qbase64_conversion_error, reason, frob); 4452 signal_error (Qbase64_conversion_error, reason, frob);
3709 } 4453 }
3710 4454
3711 #define ADVANCE_INPUT(c, stream) \ 4455 #define ADVANCE_INPUT(c, stream) \
3784 if (ec < 0 || IS_BASE64 (ec) || ec == '=') \ 4528 if (ec < 0 || IS_BASE64 (ec) || ec == '=') \
3785 break; \ 4529 break; \
3786 } while (1) 4530 } while (1)
3787 4531
3788 #define STORE_BYTE(pos, val, ccnt) do { \ 4532 #define STORE_BYTE(pos, val, ccnt) do { \
3789 pos += set_itext_ichar (pos, (Ichar)((unsigned char)(val))); \ 4533 pos += set_itext_ichar (pos, (Ichar)((Binbyte)(val))); \
3790 ++ccnt; \ 4534 ++ccnt; \
3791 } while (0) 4535 } while (0)
3792 4536
3793 static Bytebpos 4537 static Bytebpos
3794 base64_decode_1 (Lstream *istream, Ibyte *to, Charcount *ccptr) 4538 base64_decode_1 (Lstream *istream, Ibyte *to, Charcount *ccptr)
4027 { 4771 {
4028 INIT_LISP_OBJECT (bit_vector); 4772 INIT_LISP_OBJECT (bit_vector);
4029 4773
4030 DEFSYMBOL (Qstring_lessp); 4774 DEFSYMBOL (Qstring_lessp);
4031 DEFSYMBOL (Qidentity); 4775 DEFSYMBOL (Qidentity);
4776 DEFSYMBOL (Qvector);
4777 DEFSYMBOL (Qarray);
4778 DEFSYMBOL (Qstring);
4779 DEFSYMBOL (Qlist);
4780 DEFSYMBOL (Qbit_vector);
4781
4032 DEFSYMBOL (Qyes_or_no_p); 4782 DEFSYMBOL (Qyes_or_no_p);
4033 4783
4034 DEFERROR_STANDARD (Qbase64_conversion_error, Qconversion_error); 4784 DEFERROR_STANDARD (Qbase64_conversion_error, Qconversion_error);
4035 4785
4036 DEFSUBR (Fidentity); 4786 DEFSUBR (Fidentity);
4100 DEFSUBR (Fget); 4850 DEFSUBR (Fget);
4101 DEFSUBR (Fput); 4851 DEFSUBR (Fput);
4102 DEFSUBR (Fremprop); 4852 DEFSUBR (Fremprop);
4103 DEFSUBR (Fobject_plist); 4853 DEFSUBR (Fobject_plist);
4104 DEFSUBR (Fequal); 4854 DEFSUBR (Fequal);
4855 DEFSUBR (Fequalp);
4105 DEFSUBR (Fold_equal); 4856 DEFSUBR (Fold_equal);
4106 DEFSUBR (Ffillarray); 4857 DEFSUBR (Ffillarray);
4107 DEFSUBR (Fnconc); 4858 DEFSUBR (Fnconc);
4108 DEFSUBR (Fmapcar); 4859 DEFSUBR (FmapcarX);
4109 DEFSUBR (Fmapvector); 4860 DEFSUBR (Fmapvector);
4110 DEFSUBR (Fmapc_internal); 4861 DEFSUBR (Fmapcan);
4862 DEFSUBR (Fmapc);
4111 DEFSUBR (Fmapconcat); 4863 DEFSUBR (Fmapconcat);
4864 DEFSUBR (Fmap);
4865 DEFSUBR (Fmap_into);
4866 DEFSUBR (Fsome);
4867 DEFSUBR (Fevery);
4868 Ffset (intern ("mapc-internal"), Fsymbol_function (intern ("mapc")));
4869 Ffset (intern ("mapcar"), Fsymbol_function (intern ("mapcar*")));
4870 DEFSUBR (Fmaplist);
4871 DEFSUBR (Fmapl);
4872 DEFSUBR (Fmapcon);
4873
4112 DEFSUBR (Freplace_list); 4874 DEFSUBR (Freplace_list);
4113 DEFSUBR (Fload_average); 4875 DEFSUBR (Fload_average);
4114 DEFSUBR (Ffeaturep); 4876 DEFSUBR (Ffeaturep);
4115 DEFSUBR (Frequire); 4877 DEFSUBR (Frequire);
4116 DEFSUBR (Fprovide); 4878 DEFSUBR (Fprovide);
4128 { 4890 {
4129 DEFVAR_LISP ("path-separator", &Vpath_separator /* 4891 DEFVAR_LISP ("path-separator", &Vpath_separator /*
4130 The directory separator in search paths, as a string. 4892 The directory separator in search paths, as a string.
4131 */ ); 4893 */ );
4132 { 4894 {
4133 char c = SEPCHAR; 4895 Ascbyte c = SEPCHAR;
4134 Vpath_separator = make_string ((Ibyte *) &c, 1); 4896 Vpath_separator = make_string ((Ibyte *) &c, 1);
4135 } 4897 }
4136 } 4898 }
4137 4899
4138 void 4900 void