comparison src/fns.c @ 17318:224e100b393c

(copy_sub_char_table): New function. (Fcopy_sequence): Call copy_sub_char_table for copying a sub char table. (Fchar_table_range, Fset_char_table_range, map_char_table, Fmap_char_table): Handle multibyte characters correctly.
author Kenichi Handa <handa@m17n.org>
date Mon, 07 Apr 1997 07:12:13 +0000
parents b66473f0d0fe
children 120a8d934816
comparison
equal deleted inserted replaced
17317:51b7fded4356 17318:224e100b393c
291 Lisp_Object *args; 291 Lisp_Object *args;
292 { 292 {
293 return concat (nargs, args, Lisp_Vectorlike, 0); 293 return concat (nargs, args, Lisp_Vectorlike, 0);
294 } 294 }
295 295
296 /* Retrun a copy of a sub char table ARG. The elements except for a
297 nested sub char table are not copied. */
298 static Lisp_Object
299 copy_sub_char_table (arg)
300 {
301 Lisp_Object copy = make_sub_char_table (XCHAR_TABLE (arg)->defalt);
302 int i;
303
304 /* Copy all the contents. */
305 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
306 SUB_CHAR_TABLE_ORDINARY_SLOTS * sizeof (Lisp_Object));
307 /* Recursively copy any sub char-tables in the ordinary slots. */
308 for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
309 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
310 XCHAR_TABLE (copy)->contents[i]
311 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
312
313 return copy;
314 }
315
316
296 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0, 317 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
297 "Return a copy of a list, vector or string.\n\ 318 "Return a copy of a list, vector or string.\n\
298 The elements of a list or vector are not copied; they are shared\n\ 319 The elements of a list or vector are not copied; they are shared\n\
299 with the original.") 320 with the original.")
300 (arg) 321 (arg)
311 /* Copy all the slots, including the extra ones. */ 332 /* Copy all the slots, including the extra ones. */
312 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents, 333 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
313 ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK) 334 ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK)
314 * sizeof (Lisp_Object))); 335 * sizeof (Lisp_Object)));
315 336
316 /* Recursively copy any char-tables in the ordinary slots. */ 337 /* Recursively copy any sub char tables in the ordinary slots
317 for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++) 338 for multibyte characters. */
318 if (CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i])) 339 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS;
340 i < CHAR_TABLE_ORDINARY_SLOTS; i++)
341 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
319 XCHAR_TABLE (copy)->contents[i] 342 XCHAR_TABLE (copy)->contents[i]
320 = Fcopy_sequence (XCHAR_TABLE (copy)->contents[i]); 343 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
321 344
322 return copy; 345 return copy;
323 } 346 }
324 347
325 if (BOOL_VECTOR_P (arg)) 348 if (BOOL_VECTOR_P (arg))
1296 return XCHAR_TABLE (char_table)->defalt; 1319 return XCHAR_TABLE (char_table)->defalt;
1297 else if (INTEGERP (range)) 1320 else if (INTEGERP (range))
1298 return Faref (char_table, range); 1321 return Faref (char_table, range);
1299 else if (VECTORP (range)) 1322 else if (VECTORP (range))
1300 { 1323 {
1301 for (i = 0; i < XVECTOR (range)->size - 1; i++) 1324 int size = XVECTOR (range)->size;
1302 char_table = Faref (char_table, XVECTOR (range)->contents[i]); 1325 Lisp_Object *val = XVECTOR (range)->contents;
1303 1326 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1304 if (EQ (XVECTOR (range)->contents[i], Qnil)) 1327 size <= 1 ? Qnil : val[1],
1305 return XCHAR_TABLE (char_table)->defalt; 1328 size <= 2 ? Qnil : val[2]);
1306 else 1329 return Faref (char_table, ch);
1307 return Faref (char_table, XVECTOR (range)->contents[i]);
1308 } 1330 }
1309 else 1331 else
1310 error ("Invalid RANGE argument to `char-table-range'"); 1332 error ("Invalid RANGE argument to `char-table-range'");
1311 } 1333 }
1312 1334
1330 XCHAR_TABLE (char_table)->defalt = value; 1352 XCHAR_TABLE (char_table)->defalt = value;
1331 else if (INTEGERP (range)) 1353 else if (INTEGERP (range))
1332 Faset (char_table, range, value); 1354 Faset (char_table, range, value);
1333 else if (VECTORP (range)) 1355 else if (VECTORP (range))
1334 { 1356 {
1335 for (i = 0; i < XVECTOR (range)->size - 1; i++) 1357 int size = XVECTOR (range)->size;
1336 { 1358 Lisp_Object *val = XVECTOR (range)->contents;
1337 Lisp_Object tmp = Faref (char_table, XVECTOR (range)->contents[i]); 1359 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1338 if (NILP (tmp)) 1360 size <= 1 ? Qnil : val[1],
1339 { 1361 size <= 2 ? Qnil : val[2]);
1340 /* Make this char-table deeper. */ 1362 return Faset (char_table, ch, value);
1341 XVECTOR (char_table)->contents[XVECTOR (range)->contents[i]]
1342 = tmp = Fmake_char_table (Qnil, Qnil);
1343 }
1344 char_table = tmp;
1345 }
1346
1347 if (EQ (XVECTOR (range)->contents[i], Qnil))
1348 XCHAR_TABLE (char_table)->defalt = value;
1349 else
1350 Faset (char_table, XVECTOR (range)->contents[i], value);
1351 } 1363 }
1352 else 1364 else
1353 error ("Invalid RANGE argument to `set-char-table-range'"); 1365 error ("Invalid RANGE argument to `set-char-table-range'");
1354 1366
1355 return value; 1367 return value;
1364 void 1376 void
1365 map_char_table (c_function, function, chartable, depth, indices) 1377 map_char_table (c_function, function, chartable, depth, indices)
1366 Lisp_Object (*c_function) (), function, chartable, *indices; 1378 Lisp_Object (*c_function) (), function, chartable, *indices;
1367 int depth; 1379 int depth;
1368 { 1380 {
1369 int i; 1381 int i, to;
1370 int from, to;
1371 1382
1372 if (depth == 0) 1383 if (depth == 0)
1373 from = 0, to = CHAR_TABLE_ORDINARY_SLOTS; 1384 {
1385 /* At first, handle ASCII and 8-bit European characters. */
1386 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
1387 {
1388 Lisp_Object elt = XCHAR_TABLE (chartable)->contents[i];
1389 if (c_function)
1390 (*c_function) (i, elt);
1391 else
1392 call2 (function, make_number (i), elt);
1393 }
1394 to = CHAR_TABLE_ORDINARY_SLOTS;
1395 }
1374 else 1396 else
1375 from = 32, to = 128; 1397 {
1376 /* Make INDICES longer if we are about to fill it up. */ 1398 i = 32;
1377 if ((depth % 10) == 9) 1399 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
1378 { 1400 }
1379 Lisp_Object *new_indices 1401
1380 = (Lisp_Object *) alloca ((depth + 10) * sizeof (Lisp_Object)); 1402 for (i; i < to; i++)
1381 bcopy (indices, new_indices, depth * sizeof (Lisp_Object)); 1403 {
1382 indices = new_indices; 1404 Lisp_Object elt = XCHAR_TABLE (chartable)->contents[i];
1383 } 1405
1384
1385 for (i = from; i < to; i++)
1386 {
1387 Lisp_Object elt;
1388 indices[depth] = i; 1406 indices[depth] = i;
1389 elt = XCHAR_TABLE (chartable)->contents[i]; 1407
1390 if (CHAR_TABLE_P (elt)) 1408 if (SUB_CHAR_TABLE_P (elt))
1391 map_char_table (c_function, function, elt, depth + 1, indices); 1409 {
1392 else if (c_function) 1410 if (depth >= 3)
1393 (*c_function) (depth + 1, indices, elt); 1411 error ("Too deep char table");
1394 else if (depth == 0 && i < 256) 1412 map_char_table (c_function, function, elt, depth + 1, indices);
1395 /* This is an ASCII or 8-bit European character. */ 1413 }
1396 call2 (function, make_number (i), elt);
1397 else 1414 else
1398 { 1415 {
1399 /* This is an entry for multibyte characters. */ 1416 int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
1400 unsigned int charset = XFASTINT (indices[0]) - 128, c1, c2, c; 1417
1401 if (CHARSET_DEFINED_P (charset)) 1418 if (CHARSET_DEFINED_P (charset))
1402 { 1419 {
1403 c1 = depth < 1 ? 0 : XFASTINT (indices[1]); 1420 c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
1404 c2 = depth < 2 ? 0 : XFASTINT (indices[2]); 1421 c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
1405 c = MAKE_NON_ASCII_CHAR (charset, c1, c2); 1422 c = MAKE_NON_ASCII_CHAR (charset, c1, c2);
1406 call2 (function, make_number (c), elt); 1423 if (c_function)
1424 (*c_function) (c, elt);
1425 else
1426 call2 (function, make_number (c), elt);
1407 } 1427 }
1408 } 1428 }
1409 } 1429 }
1410 } 1430 }
1411 1431
1412 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table, 1432 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
1413 2, 2, 0, 1433 2, 2, 0,
1416 The key is always a possible RANGE argument to `set-char-table-range'.") 1436 The key is always a possible RANGE argument to `set-char-table-range'.")
1417 (function, char_table) 1437 (function, char_table)
1418 Lisp_Object function, char_table; 1438 Lisp_Object function, char_table;
1419 { 1439 {
1420 Lisp_Object keyvec; 1440 Lisp_Object keyvec;
1421 Lisp_Object *indices = (Lisp_Object *) alloca (10 * sizeof (Lisp_Object)); 1441 /* The depth of char table is at most 3. */
1442 Lisp_Object *indices = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
1422 1443
1423 map_char_table (NULL, function, char_table, 0, indices); 1444 map_char_table (NULL, function, char_table, 0, indices);
1424 return Qnil; 1445 return Qnil;
1425 } 1446 }
1426 1447