Mercurial > emacs
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 |