diff options
| author | Kenichi Handa | 1997-04-07 07:12:13 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1997-04-07 07:12:13 +0000 |
| commit | 3720677d59a1e8356c78add992350997a9eaeb13 (patch) | |
| tree | 4ff578c04767c92ade9322e7a4db3669f603c595 /src | |
| parent | 1f1ff51db02df55c125f20b7ef4020aba36b3900 (diff) | |
| download | emacs-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.c | 129 |
1 files changed, 75 insertions, 54 deletions
| @@ -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. */ | ||
| 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\ |
| @@ -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; |