aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1995-10-07 21:52:15 +0000
committerRichard M. Stallman1995-10-07 21:52:15 +0000
commite03f79336240cf8f1a4f59aeb4347ef54e419c28 (patch)
tree9787a0bf189f0dbcdc93950fe8a884e272566ff3 /src
parentce0af8d5e4d29ee58cf612d75934f2329237912d (diff)
downloademacs-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.c252
1 files changed, 246 insertions, 6 deletions
diff --git a/src/fns.c b/src/fns.c
index 287187d5a85..efa8e23f453 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -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
1060DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, 1128DEFUN ("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\
1130ARRAY 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
1179DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
1180 1, 1, 0,
1181 "Return the parent char-table of CHAR-TABLE.\n\
1182The value is either nil or another char-table.\n\
1183If CHAR-TABLE holds nil for a given character,\n\
1184then 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
1194DEFUN ("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\
1197PARENT 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
1215DEFUN ("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
1230DEFUN ("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
1246DEFUN ("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\
1249RANGE should be t (for all characters), nil (for the default value)\n\
1250a vector which identifies a character set or a row of a character set,\n\
1251or 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
1282static void
1283map_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
1310DEFUN ("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\
1313FUNCTION is called with two arguments--a key and a value.\n\
1314The 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 */
1092Lisp_Object 1326Lisp_Object
1093nconc2 (s1, s2) 1327nconc2 (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);