aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa1997-04-07 07:12:13 +0000
committerKenichi Handa1997-04-07 07:12:13 +0000
commit3720677d59a1e8356c78add992350997a9eaeb13 (patch)
tree4ff578c04767c92ade9322e7a4db3669f603c595 /src
parent1f1ff51db02df55c125f20b7ef4020aba36b3900 (diff)
downloademacs-3720677d59a1e8356c78add992350997a9eaeb13.tar.gz
emacs-3720677d59a1e8356c78add992350997a9eaeb13.zip
(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.
Diffstat (limited to 'src')
-rw-r--r--src/fns.c129
1 files changed, 75 insertions, 54 deletions
diff --git a/src/fns.c b/src/fns.c
index 118f1e121ff..2631210a642 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -293,6 +293,27 @@ Each argument may be a list, vector or string.")
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. */
298static Lisp_Object
299copy_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
296DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0, 317DEFUN ("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\
298The elements of a list or vector are not copied; they are shared\n\ 319The elements of a list or vector are not copied; they are shared\n\
@@ -313,11 +334,13 @@ with the original.")
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 }
@@ -1298,13 +1321,12 @@ or a character code.")
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'");
@@ -1332,22 +1354,12 @@ or a character code.")
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'");
@@ -1366,46 +1378,54 @@ 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;
1376 /* Make INDICES longer if we are about to fill it up. */
1377 if ((depth % 10) == 9)
1378 { 1397 {
1379 Lisp_Object *new_indices 1398 i = 32;
1380 = (Lisp_Object *) alloca ((depth + 10) * sizeof (Lisp_Object)); 1399 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
1381 bcopy (indices, new_indices, depth * sizeof (Lisp_Object));
1382 indices = new_indices;
1383 } 1400 }
1384 1401
1385 for (i = from; i < to; i++) 1402 for (i; i < to; i++)
1386 { 1403 {
1387 Lisp_Object elt; 1404 Lisp_Object elt = XCHAR_TABLE (chartable)->contents[i];
1405
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
@@ -1418,7 +1438,8 @@ The key is always a possible RANGE argument to `set-char-table-range'.")
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;