diff options
| author | Richard M. Stallman | 1995-10-07 21:52:15 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-10-07 21:52:15 +0000 |
| commit | e03f79336240cf8f1a4f59aeb4347ef54e419c28 (patch) | |
| tree | 9787a0bf189f0dbcdc93950fe8a884e272566ff3 /src | |
| parent | ce0af8d5e4d29ee58cf612d75934f2329237912d (diff) | |
| download | emacs-e03f79336240cf8f1a4f59aeb4347ef54e419c28.tar.gz emacs-e03f79336240cf8f1a4f59aeb4347ef54e419c28.zip | |
(Fset_char_table_range): New function.
(make_char_table, Fmap_char_table): New function.
(Fchar_table_extra_slot, Fset_char_table_extra_slot): New functions.
(Fcopy_sequence, Felt, internal_equal, Ffillarray):
Handle chartables and boolvectors.
(Flength, concat): Handle boolvectors as args.
(Flength): Handle chartables as args.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fns.c | 252 |
1 files changed, 246 insertions, 6 deletions
| @@ -106,6 +106,10 @@ A byte-code function object is also allowed.") | |||
| 106 | XSETFASTINT (val, XSTRING (obj)->size); | 106 | XSETFASTINT (val, XSTRING (obj)->size); |
| 107 | else if (VECTORP (obj)) | 107 | else if (VECTORP (obj)) |
| 108 | XSETFASTINT (val, XVECTOR (obj)->size); | 108 | XSETFASTINT (val, XVECTOR (obj)->size); |
| 109 | else if (CHAR_TABLE_P (obj)) | ||
| 110 | XSETFASTINT (val, CHAR_TABLE_ORDINARY_SLOTS); | ||
| 111 | else if (BOOL_VECTOR_P (obj)) | ||
| 112 | XSETFASTINT (val, XBOOL_VECTOR (obj)->size); | ||
| 109 | else if (COMPILEDP (obj)) | 113 | else if (COMPILEDP (obj)) |
| 110 | XSETFASTINT (val, XVECTOR (obj)->size & PSEUDOVECTOR_SIZE_MASK); | 114 | XSETFASTINT (val, XVECTOR (obj)->size & PSEUDOVECTOR_SIZE_MASK); |
| 111 | else if (CONSP (obj)) | 115 | else if (CONSP (obj)) |
| @@ -289,6 +293,41 @@ with the original.") | |||
| 289 | Lisp_Object arg; | 293 | Lisp_Object arg; |
| 290 | { | 294 | { |
| 291 | if (NILP (arg)) return arg; | 295 | if (NILP (arg)) return arg; |
| 296 | |||
| 297 | if (CHAR_TABLE_P (arg)) | ||
| 298 | { | ||
| 299 | int i, size; | ||
| 300 | Lisp_Object copy; | ||
| 301 | |||
| 302 | /* Calculate the number of extra slots. */ | ||
| 303 | size = CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (arg)); | ||
| 304 | copy = Fmake_char_table (make_number (size), Qnil); | ||
| 305 | /* Copy all the slots, including the extra ones. */ | ||
| 306 | bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents, | ||
| 307 | (XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK) * sizeof (Lisp_Object)); | ||
| 308 | |||
| 309 | /* Recursively copy any char-tables in the ordinary slots. */ | ||
| 310 | for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++) | ||
| 311 | if (CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i])) | ||
| 312 | XCHAR_TABLE (copy)->contents[i] | ||
| 313 | = Fcopy_sequence (XCHAR_TABLE (copy)->contents[i]); | ||
| 314 | |||
| 315 | return copy; | ||
| 316 | } | ||
| 317 | |||
| 318 | if (BOOL_VECTOR_P (arg)) | ||
| 319 | { | ||
| 320 | Lisp_Object val; | ||
| 321 | int bits_per_char = INTBITS / sizeof (int); | ||
| 322 | int size_in_chars | ||
| 323 | = (XBOOL_VECTOR (arg)->size + bits_per_char) / bits_per_char; | ||
| 324 | |||
| 325 | val = Fmake_bool_vector (Flength (arg), Qnil); | ||
| 326 | bcopy (XBOOL_VECTOR (arg)->data, XBOOL_VECTOR (val)->data, | ||
| 327 | size_in_chars); | ||
| 328 | return val; | ||
| 329 | } | ||
| 330 | |||
| 292 | if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg)) | 331 | if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg)) |
| 293 | arg = wrong_type_argument (Qsequencep, arg); | 332 | arg = wrong_type_argument (Qsequencep, arg); |
| 294 | return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0); | 333 | return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0); |
| @@ -324,7 +363,7 @@ concat (nargs, args, target_type, last_special) | |||
| 324 | { | 363 | { |
| 325 | this = args[argnum]; | 364 | this = args[argnum]; |
| 326 | if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this) | 365 | if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this) |
| 327 | || COMPILEDP (this))) | 366 | || COMPILEDP (this) || BOOL_VECTOR_P (this))) |
| 328 | { | 367 | { |
| 329 | if (INTEGERP (this)) | 368 | if (INTEGERP (this)) |
| 330 | args[argnum] = Fnumber_to_string (this); | 369 | args[argnum] = Fnumber_to_string (this); |
| @@ -391,6 +430,19 @@ concat (nargs, args, target_type, last_special) | |||
| 391 | if (thisindex >= thisleni) break; | 430 | if (thisindex >= thisleni) break; |
| 392 | if (STRINGP (this)) | 431 | if (STRINGP (this)) |
| 393 | XSETFASTINT (elt, XSTRING (this)->data[thisindex++]); | 432 | XSETFASTINT (elt, XSTRING (this)->data[thisindex++]); |
| 433 | else if (BOOL_VECTOR_P (this)) | ||
| 434 | { | ||
| 435 | int bits_per_char = INTBITS / sizeof (int); | ||
| 436 | int size_in_chars | ||
| 437 | = ((XBOOL_VECTOR (this)->size + bits_per_char) | ||
| 438 | / bits_per_char); | ||
| 439 | int byte; | ||
| 440 | byte = XBOOL_VECTOR (val)->data[thisindex / bits_per_char]; | ||
| 441 | if (byte & (1 << thisindex)) | ||
| 442 | elt = Qt; | ||
| 443 | else | ||
| 444 | elt = Qnil; | ||
| 445 | } | ||
| 394 | else | 446 | else |
| 395 | elt = XVECTOR (this)->contents[thisindex++]; | 447 | elt = XVECTOR (this)->contents[thisindex++]; |
| 396 | } | 448 | } |
| @@ -521,7 +573,8 @@ DEFUN ("elt", Felt, Selt, 2, 2, 0, | |||
| 521 | { | 573 | { |
| 522 | if (CONSP (seq) || NILP (seq)) | 574 | if (CONSP (seq) || NILP (seq)) |
| 523 | return Fcar (Fnthcdr (n, seq)); | 575 | return Fcar (Fnthcdr (n, seq)); |
| 524 | else if (STRINGP (seq) || VECTORP (seq)) | 576 | else if (STRINGP (seq) || VECTORP (seq) || BOOL_VECTOR_P (seq) |
| 577 | || CHAR_TABLE_P (seq)) | ||
| 525 | return Faref (seq, n); | 578 | return Faref (seq, n); |
| 526 | else | 579 | else |
| 527 | seq = wrong_type_argument (Qsequencep, seq); | 580 | seq = wrong_type_argument (Qsequencep, seq); |
| @@ -1019,11 +1072,26 @@ internal_equal (o1, o2, depth) | |||
| 1019 | same size. */ | 1072 | same size. */ |
| 1020 | if (XVECTOR (o2)->size != size) | 1073 | if (XVECTOR (o2)->size != size) |
| 1021 | return 0; | 1074 | return 0; |
| 1022 | /* But only true vectors and compiled functions are actually sensible | 1075 | /* Boolvectors are compared much like strings. */ |
| 1023 | to compare, so eliminate the others now. */ | 1076 | if (BOOL_VECTOR_P (o1)) |
| 1077 | { | ||
| 1078 | int bits_per_char = INTBITS / sizeof (int); | ||
| 1079 | int size_in_chars | ||
| 1080 | = (XBOOL_VECTOR (o1)->size + bits_per_char) / bits_per_char; | ||
| 1081 | |||
| 1082 | if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size) | ||
| 1083 | return 0; | ||
| 1084 | if (bcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data, | ||
| 1085 | size_in_chars)) | ||
| 1086 | return 0; | ||
| 1087 | return 1; | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | /* Aside from them, only true vectors, char-tables, and compiled | ||
| 1091 | functions are sensible to compare, so eliminate the others now. */ | ||
| 1024 | if (size & PSEUDOVECTOR_FLAG) | 1092 | if (size & PSEUDOVECTOR_FLAG) |
| 1025 | { | 1093 | { |
| 1026 | if (!(size & PVEC_COMPILED)) | 1094 | if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE))) |
| 1027 | return 0; | 1095 | return 0; |
| 1028 | size &= PSEUDOVECTOR_SIZE_MASK; | 1096 | size &= PSEUDOVECTOR_SIZE_MASK; |
| 1029 | } | 1097 | } |
| @@ -1058,7 +1126,8 @@ internal_equal (o1, o2, depth) | |||
| 1058 | } | 1126 | } |
| 1059 | 1127 | ||
| 1060 | DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, | 1128 | DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, |
| 1061 | "Store each element of ARRAY with ITEM. ARRAY is a vector or string.") | 1129 | "Store each element of ARRAY with ITEM.\n\ |
| 1130 | ARRAY is a vector, string, char-table, or bool-vector.") | ||
| 1062 | (array, item) | 1131 | (array, item) |
| 1063 | Lisp_Object array, item; | 1132 | Lisp_Object array, item; |
| 1064 | { | 1133 | { |
| @@ -1071,6 +1140,14 @@ DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, | |||
| 1071 | for (index = 0; index < size; index++) | 1140 | for (index = 0; index < size; index++) |
| 1072 | p[index] = item; | 1141 | p[index] = item; |
| 1073 | } | 1142 | } |
| 1143 | else if (CHAR_TABLE_P (array)) | ||
| 1144 | { | ||
| 1145 | register Lisp_Object *p = XCHAR_TABLE (array)->contents; | ||
| 1146 | size = CHAR_TABLE_ORDINARY_SLOTS; | ||
| 1147 | for (index = 0; index < size; index++) | ||
| 1148 | p[index] = item; | ||
| 1149 | XCHAR_TABLE (array)->defalt = Qnil; | ||
| 1150 | } | ||
| 1074 | else if (STRINGP (array)) | 1151 | else if (STRINGP (array)) |
| 1075 | { | 1152 | { |
| 1076 | register unsigned char *p = XSTRING (array)->data; | 1153 | register unsigned char *p = XSTRING (array)->data; |
| @@ -1080,6 +1157,17 @@ DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, | |||
| 1080 | for (index = 0; index < size; index++) | 1157 | for (index = 0; index < size; index++) |
| 1081 | p[index] = charval; | 1158 | p[index] = charval; |
| 1082 | } | 1159 | } |
| 1160 | else if (BOOL_VECTOR_P (array)) | ||
| 1161 | { | ||
| 1162 | register unsigned char *p = XBOOL_VECTOR (array)->data; | ||
| 1163 | int bits_per_char = INTBITS / sizeof (int); | ||
| 1164 | int size_in_chars | ||
| 1165 | = (XBOOL_VECTOR (array)->size + bits_per_char) / bits_per_char; | ||
| 1166 | |||
| 1167 | charval = (! NILP (item) ? -1 : 0); | ||
| 1168 | for (index = 0; index < size_in_chars; index++) | ||
| 1169 | p[index] = charval; | ||
| 1170 | } | ||
| 1083 | else | 1171 | else |
| 1084 | { | 1172 | { |
| 1085 | array = wrong_type_argument (Qarrayp, array); | 1173 | array = wrong_type_argument (Qarrayp, array); |
| @@ -1088,6 +1176,152 @@ DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, | |||
| 1088 | return array; | 1176 | return array; |
| 1089 | } | 1177 | } |
| 1090 | 1178 | ||
| 1179 | DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent, | ||
| 1180 | 1, 1, 0, | ||
| 1181 | "Return the parent char-table of CHAR-TABLE.\n\ | ||
| 1182 | The value is either nil or another char-table.\n\ | ||
| 1183 | If CHAR-TABLE holds nil for a given character,\n\ | ||
| 1184 | then the actual applicable value is inherited from the parent char-table\n\ | ||
| 1185 | \(or from its parents, if necessary).") | ||
| 1186 | (chartable) | ||
| 1187 | Lisp_Object chartable; | ||
| 1188 | { | ||
| 1189 | CHECK_CHAR_TABLE (chartable, 0); | ||
| 1190 | |||
| 1191 | return XCHAR_TABLE (chartable)->parent; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent, | ||
| 1195 | 2, 2, 0, | ||
| 1196 | "Set the parent char-table of CHAR-TABLE to PARENT.\n\ | ||
| 1197 | PARENT must be either nil or another char-table.") | ||
| 1198 | (chartable, parent) | ||
| 1199 | Lisp_Object chartable, parent; | ||
| 1200 | { | ||
| 1201 | Lisp_Object temp; | ||
| 1202 | |||
| 1203 | CHECK_CHAR_TABLE (chartable, 0); | ||
| 1204 | CHECK_CHAR_TABLE (parent, 0); | ||
| 1205 | |||
| 1206 | for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent) | ||
| 1207 | if (EQ (temp, chartable)) | ||
| 1208 | error ("Attempt to make a chartable be its own parent"); | ||
| 1209 | |||
| 1210 | XCHAR_TABLE (chartable)->parent = parent; | ||
| 1211 | |||
| 1212 | return parent; | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot, | ||
| 1216 | 2, 2, 0, | ||
| 1217 | "Return the value in extra-slot number N of char-table CHAR-TABLE.") | ||
| 1218 | (chartable, n) | ||
| 1219 | Lisp_Object chartable, n; | ||
| 1220 | { | ||
| 1221 | CHECK_CHAR_TABLE (chartable, 1); | ||
| 1222 | CHECK_NUMBER (n, 2); | ||
| 1223 | if (XINT (n) < 0 | ||
| 1224 | || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (chartable))) | ||
| 1225 | args_out_of_range (chartable, n); | ||
| 1226 | |||
| 1227 | return XCHAR_TABLE (chartable)->extras[XINT (n)]; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot, | ||
| 1231 | Sset_char_table_extra_slot, | ||
| 1232 | 3, 3, 0, | ||
| 1233 | "Set extra-slot number N of CHAR-TABLE to VALUE.") | ||
| 1234 | (chartable, n, value) | ||
| 1235 | Lisp_Object chartable, n, value; | ||
| 1236 | { | ||
| 1237 | CHECK_CHAR_TABLE (chartable, 1); | ||
| 1238 | CHECK_NUMBER (n, 2); | ||
| 1239 | if (XINT (n) < 0 | ||
| 1240 | || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (chartable))) | ||
| 1241 | args_out_of_range (chartable, n); | ||
| 1242 | |||
| 1243 | return XCHAR_TABLE (chartable)->extras[XINT (n)] = value; | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range, | ||
| 1247 | 3, 3, 0, | ||
| 1248 | "Set the value in CHARTABLE for a range of characters RANGE to VALUE.\n\ | ||
| 1249 | RANGE should be t (for all characters), nil (for the default value)\n\ | ||
| 1250 | a vector which identifies a character set or a row of a character set,\n\ | ||
| 1251 | or a character code.") | ||
| 1252 | (chartable, range, value) | ||
| 1253 | Lisp_Object chartable, range, value; | ||
| 1254 | { | ||
| 1255 | int i; | ||
| 1256 | |||
| 1257 | CHECK_CHAR_TABLE (chartable, 0); | ||
| 1258 | |||
| 1259 | if (EQ (range, Qt)) | ||
| 1260 | for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++) | ||
| 1261 | XCHAR_TABLE (chartable)->contents[i] = value; | ||
| 1262 | else if (EQ (range, Qnil)) | ||
| 1263 | XCHAR_TABLE (chartable)->defalt = value; | ||
| 1264 | else if (INTEGERP (range)) | ||
| 1265 | Faset (chartable, range, value); | ||
| 1266 | else if (VECTORP (range)) | ||
| 1267 | { | ||
| 1268 | for (i = 0; i < XVECTOR (range)->size - 1; i++) | ||
| 1269 | chartable = Faref (chartable, XVECTOR (range)->contents[i]); | ||
| 1270 | |||
| 1271 | if (EQ (XVECTOR (range)->contents[i], Qnil)) | ||
| 1272 | XCHAR_TABLE (chartable)->defalt = value; | ||
| 1273 | else | ||
| 1274 | Faset (chartable, XVECTOR (range)->contents[i], value); | ||
| 1275 | } | ||
| 1276 | else | ||
| 1277 | error ("Invalid RANGE argument to `set-char-table-range'"); | ||
| 1278 | |||
| 1279 | return value; | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | static void | ||
| 1283 | map_char_table (function, chartable, depth, indices) | ||
| 1284 | Lisp_Object function, chartable, depth, *indices; | ||
| 1285 | { | ||
| 1286 | int i; | ||
| 1287 | int size = XCHAR_TABLE (chartable)->size; | ||
| 1288 | |||
| 1289 | /* Make INDICES longer if we are about to fill it up. */ | ||
| 1290 | if ((depth % 10) == 9) | ||
| 1291 | { | ||
| 1292 | Lisp_Object *new_indices | ||
| 1293 | = (Lisp_Object *) alloca ((depth += 10) * sizeof (Lisp_Object)); | ||
| 1294 | bcopy (indices, new_indices, depth * sizeof (Lisp_Object)); | ||
| 1295 | indices = new_indices; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | for (i = 0; i < size; i++) | ||
| 1299 | { | ||
| 1300 | Lisp_Object elt; | ||
| 1301 | indices[depth] = i; | ||
| 1302 | elt = XCHAR_TABLE (chartable)->contents[i]; | ||
| 1303 | if (!CHAR_TABLE_P (elt)) | ||
| 1304 | call2 (function, Fvector (depth + 1, indices), elt); | ||
| 1305 | else | ||
| 1306 | map_char_table (chartable, function, depth + 1, indices); | ||
| 1307 | } | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | DEFUN ("map-char-table", Fmap_char_table, Smap_char_table, | ||
| 1311 | 2, 2, 0, | ||
| 1312 | "Call FUNCTION for each range of like characters in CHARTABLE.\n\ | ||
| 1313 | FUNCTION is called with two arguments--a key and a value.\n\ | ||
| 1314 | The key is always a possible RANGE argument to `set-char-table-range'.") | ||
| 1315 | (function, chartable) | ||
| 1316 | Lisp_Object function, chartable; | ||
| 1317 | { | ||
| 1318 | Lisp_Object keyvec; | ||
| 1319 | Lisp_Object *indices = (Lisp_Object *) alloca (10 * sizeof (Lisp_Object)); | ||
| 1320 | |||
| 1321 | map_char_table (function, chartable, 0, indices); | ||
| 1322 | return Qnil; | ||
| 1323 | } | ||
| 1324 | |||
| 1091 | /* ARGSUSED */ | 1325 | /* ARGSUSED */ |
| 1092 | Lisp_Object | 1326 | Lisp_Object |
| 1093 | nconc2 (s1, s2) | 1327 | nconc2 (s1, s2) |
| @@ -1570,6 +1804,12 @@ Used by `featurep' and `require', and altered by `provide'."); | |||
| 1570 | defsubr (&Sput); | 1804 | defsubr (&Sput); |
| 1571 | defsubr (&Sequal); | 1805 | defsubr (&Sequal); |
| 1572 | defsubr (&Sfillarray); | 1806 | defsubr (&Sfillarray); |
| 1807 | defsubr (&Schar_table_parent); | ||
| 1808 | defsubr (&Sset_char_table_parent); | ||
| 1809 | defsubr (&Schar_table_extra_slot); | ||
| 1810 | defsubr (&Sset_char_table_extra_slot); | ||
| 1811 | defsubr (&Sset_char_table_range); | ||
| 1812 | defsubr (&Smap_char_table); | ||
| 1573 | defsubr (&Snconc); | 1813 | defsubr (&Snconc); |
| 1574 | defsubr (&Smapcar); | 1814 | defsubr (&Smapcar); |
| 1575 | defsubr (&Smapconcat); | 1815 | defsubr (&Smapconcat); |