summaryrefslogtreecommitdiff
path: root/src/casetab.c
diff options
context:
space:
mode:
authorKarl Heuer <kwzh@gnu.org>1997-05-15 02:23:20 +0000
committerKarl Heuer <kwzh@gnu.org>1997-05-15 02:23:20 +0000
commit07d690d9c86b1856175c4a3767a047a916e42eb5 (patch)
tree5f3406c760060a5ddadf6c0515994533cbc1296a /src/casetab.c
parentbc168c92b9a5d118a8389f5709f5c4ef0fbc2c7b (diff)
downloademacs-07d690d9c86b1856175c4a3767a047a916e42eb5.tar.gz
Include charset.h.
(compute_trt_inverse): Totally rewritten. Args are now Lisp_Object. Callers changed. (compute_trt_identity, compute_trt_shuffle): New subroutines. (init_casetab_once): Use XSETFASTINT to store into case table; use CHAR_TABLE_SINGLE_BYTE_SLOTS to end the loop.
Diffstat (limited to 'src/casetab.c')
-rw-r--r--src/casetab.c111
1 files changed, 83 insertions, 28 deletions
diff --git a/src/casetab.c b/src/casetab.c
index 9bec57f068e..4e901cc1cb4 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
#include <config.h>
#include "lisp.h"
#include "buffer.h"
+#include "charset.h"
Lisp_Object Qcase_table_p, Qcase_table;
Lisp_Object Vascii_downcase_table, Vascii_upcase_table;
@@ -129,7 +130,7 @@ set_case_table (table, standard)
if (NILP (up))
{
up = Fmake_char_table (Qcase_table, Qnil);
- compute_trt_inverse (XCHAR_TABLE (table), XCHAR_TABLE (up));
+ compute_trt_inverse (table, up);
XCHAR_TABLE (table)->extras[0] = up;
}
@@ -144,7 +145,7 @@ set_case_table (table, standard)
/* Set up the CANON vector; for each character,
this sequence of upcasing and downcasing ought to
get the "preferred" lowercase equivalent. */
- for (i = 0; i < 256; i++)
+ for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
XCHAR_TABLE (canon)->contents[i] = downvec[upvec[downvec[i]]];
XCHAR_TABLE (table)->extras[1] = canon;
}
@@ -152,7 +153,7 @@ set_case_table (table, standard)
if (NILP (eqv))
{
eqv = Fmake_char_table (Qcase_table, Qnil);
- compute_trt_inverse (XCHAR_TABLE (canon), XCHAR_TABLE (eqv));
+ compute_trt_inverse (canon, eqv);
XCHAR_TABLE (table)->extras[2] = eqv;
}
@@ -169,32 +170,85 @@ set_case_table (table, standard)
return table;
}
-/* Given a translate table TRT, store the inverse mapping into INVERSE.
- Since TRT is not one-to-one, INVERSE is not a simple mapping.
- Instead, it divides the space of characters into equivalence classes.
- All characters in a given class form one circular list, chained through
- the elements of INVERSE. */
+static void
+compute_trt_identity (bytes, depth, trt, inverse)
+ unsigned char *bytes;
+ int depth;
+ struct Lisp_Char_Table *trt, *inverse;
+{
+ register int i;
+
+ for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
+ {
+ if (NATNUMP (trt->contents[i]))
+ {
+ bytes[depth] = i;
+ XSETFASTINT (inverse->contents[i],
+ (depth == 0 && i < CHAR_TABLE_SINGLE_BYTE_SLOTS ? i
+ : MAKE_NON_ASCII_CHAR (bytes[0]-128,
+ bytes[1], bytes[2])));
+ }
+ else if (CHAR_TABLE_P (trt->contents[i]))
+ {
+ bytes[depth] = i;
+ inverse->contents[i] = Fmake_char_table (Qnil, Qnil);
+ compute_trt_identity (bytes, depth + 1,
+ XCHAR_TABLE (trt->contents[i]),
+ XCHAR_TABLE (inverse->contents[i]));
+ }
+ else /* must be Qnil or Qidentity */
+ inverse->contents[i] = trt->contents[i];
+ }
+}
static void
-compute_trt_inverse (trt, inverse)
+compute_trt_shuffle (bytes, depth, ibase, trt, inverse)
+ unsigned char *bytes;
+ int depth;
+ Lisp_Object ibase;
struct Lisp_Char_Table *trt, *inverse;
{
- register int i = 0400;
- register unsigned char c, q;
+ register int i;
+ Lisp_Object j, tem, q;
- while (i--)
- inverse->contents[i] = i;
- i = 0400;
- while (i--)
+ for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
{
- if ((q = trt->contents[i]) != (unsigned char) i)
+ bytes[depth] = i;
+ XSETFASTINT (j,
+ (depth == 0 && i < CHAR_TABLE_SINGLE_BYTE_SLOTS ? i
+ : MAKE_NON_ASCII_CHAR (bytes[0]-128,
+ bytes[1], bytes[2])));
+ q = trt->contents[i];
+ if (NATNUMP (q) && XFASTINT (q) != XFASTINT (j))
+ {
+ tem = Faref (ibase, q);
+ Faset (ibase, q, j);
+ Faset (ibase, j, tem);
+ }
+ else if (CHAR_TABLE_P (q))
{
- c = inverse->contents[q];
- inverse->contents[q] = i;
- inverse->contents[i] = c;
+ bytes[depth] = i;
+ compute_trt_shuffle (bytes, depth + 1, ibase,
+ XCHAR_TABLE (trt->contents[i]),
+ XCHAR_TABLE (inverse->contents[i]));
}
}
}
+
+/* Given a translate table TRT, store the inverse mapping into INVERSE.
+ Since TRT is not one-to-one, INVERSE is not a simple mapping.
+ Instead, it divides the space of characters into equivalence classes.
+ All characters in a given class form one circular list, chained through
+ the elements of INVERSE. */
+
+static void
+compute_trt_inverse (trt, inv)
+ Lisp_Object trt, inv;
+{
+ unsigned char bytes[3];
+ compute_trt_identity (bytes, 0, XCHAR_TABLE (trt), XCHAR_TABLE (inv));
+ compute_trt_shuffle (bytes, 0, inv, XCHAR_TABLE (trt), XCHAR_TABLE (inv));
+}
init_casetab_once ()
{
@@ -216,21 +270,22 @@ init_casetab_once ()
Vascii_downcase_table = down;
XCHAR_TABLE (down)->purpose = Qcase_table;
- for (i = 0; i < 256; i++)
- XCHAR_TABLE (down)->contents[i] = (i >= 'A' && i <= 'Z') ? i + 040 : i;
+ for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
+ XSETFASTINT (XCHAR_TABLE (down)->contents[i],
+ (i >= 'A' && i <= 'Z') ? i + ('a' - 'A') : i);
XCHAR_TABLE (down)->extras[1] = Fcopy_sequence (down);
up = Fmake_char_table (Qcase_table, Qnil);
XCHAR_TABLE (down)->extras[0] = up;
- for (i = 0; i < 256; i++)
- XCHAR_TABLE (up)->contents[i]
- = ((i >= 'A' && i <= 'Z')
- ? i + ('a' - 'A')
- : ((i >= 'a' && i <= 'z')
- ? i + ('A' - 'a')
- : i));
+ for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
+ XSETFASTINT (XCHAR_TABLE (up)->contents[i],
+ ((i >= 'A' && i <= 'Z')
+ ? i + ('a' - 'A')
+ : ((i >= 'a' && i <= 'z')
+ ? i + ('A' - 'a')
+ : i)));
XCHAR_TABLE (down)->extras[2] = Fcopy_sequence (up);
}