* chartab.c (sub_char_table_set_range, char_table_set_range): Likewise.
[bpt/emacs.git] / src / casetab.c
CommitLineData
dcfdbac7 1/* GNU Emacs routines to deal with case tables.
73b0cd50 2 Copyright (C) 1993-1994, 2001-2011 Free Software Foundation, Inc.
8deda4af
GM
3
4Author: Howard Gayle
dcfdbac7
JB
5
6This file is part of GNU Emacs.
7
9ec0b715 8GNU Emacs is free software: you can redistribute it and/or modify
dcfdbac7 9it under the terms of the GNU General Public License as published by
9ec0b715
GM
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
dcfdbac7
JB
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
9ec0b715 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
dcfdbac7 20
18160b98 21#include <config.h>
d7306fe6 22#include <setjmp.h>
dcfdbac7
JB
23#include "lisp.h"
24#include "buffer.h"
e961d439 25#include "character.h"
dcfdbac7 26
7f7fef04 27Lisp_Object Qcase_table_p, Qcase_table;
dcfdbac7
JB
28Lisp_Object Vascii_downcase_table, Vascii_upcase_table;
29Lisp_Object Vascii_canon_table, Vascii_eqv_table;
30
971de7fb
DN
31static void set_canon (Lisp_Object case_table, Lisp_Object range, Lisp_Object elt);
32static void set_identity (Lisp_Object table, Lisp_Object c, Lisp_Object elt);
33static void shuffle (Lisp_Object table, Lisp_Object c, Lisp_Object elt);
dcfdbac7
JB
34
35DEFUN ("case-table-p", Fcase_table_p, Scase_table_p, 1, 1, 0,
e0f24100 36 doc: /* Return t if OBJECT is a case table.
fdb82f93 37See `set-case-table' for more information on these data structures. */)
5842a27b 38 (Lisp_Object object)
dcfdbac7 39{
4b3bd052 40 Lisp_Object up, canon, eqv;
dcfdbac7 41
2858a1c1 42 if (! CHAR_TABLE_P (object))
7f7fef04 43 return Qnil;
2858a1c1 44 if (! EQ (XCHAR_TABLE (object)->purpose, Qcase_table))
7f7fef04 45 return Qnil;
dcfdbac7 46
2858a1c1
EN
47 up = XCHAR_TABLE (object)->extras[0];
48 canon = XCHAR_TABLE (object)->extras[1];
49 eqv = XCHAR_TABLE (object)->extras[2];
7f7fef04
RS
50
51 return ((NILP (up) || CHAR_TABLE_P (up))
d427b66a 52 && ((NILP (canon) && NILP (eqv))
7f7fef04
RS
53 || (CHAR_TABLE_P (canon)
54 && (NILP (eqv) || CHAR_TABLE_P (eqv))))
dcfdbac7
JB
55 ? Qt : Qnil);
56}
57
58static Lisp_Object
971de7fb 59check_case_table (Lisp_Object obj)
dcfdbac7 60{
a5f07f6d 61 CHECK_TYPE (!NILP (Fcase_table_p (obj)), Qcase_table_p, obj);
dcfdbac7 62 return (obj);
177c0ea7 63}
dcfdbac7
JB
64
65DEFUN ("current-case-table", Fcurrent_case_table, Scurrent_case_table, 0, 0, 0,
fdb82f93 66 doc: /* Return the case table of the current buffer. */)
5842a27b 67 (void)
dcfdbac7 68{
4b4deea2 69 return BVAR (current_buffer, downcase_table);
dcfdbac7
JB
70}
71
a1de6b4b 72DEFUN ("standard-case-table", Fstandard_case_table, Sstandard_case_table, 0, 0, 0,
fdb82f93
PJ
73 doc: /* Return the standard case table.
74This is the one used for new buffers. */)
5842a27b 75 (void)
dcfdbac7 76{
7f7fef04 77 return Vascii_downcase_table;
dcfdbac7
JB
78}
79
971de7fb 80static Lisp_Object set_case_table (Lisp_Object table, int standard);
d9da9451 81
dcfdbac7 82DEFUN ("set-case-table", Fset_case_table, Sset_case_table, 1, 1, 0,
fdb82f93
PJ
83 doc: /* Select a new case table for the current buffer.
84A case table is a char-table which maps characters
85to their lower-case equivalents. It also has three \"extra\" slots
86which may be additional char-tables or nil.
87These slots are called UPCASE, CANONICALIZE and EQUIVALENCES.
f6a18aa2
RS
88UPCASE maps each non-upper-case character to its upper-case equivalent.
89 (The value in UPCASE for an upper-case character is never used.)
90 If lower and upper case characters are in 1-1 correspondence,
fdb82f93
PJ
91 you may use nil and the upcase table will be deduced from DOWNCASE.
92CANONICALIZE maps each character to a canonical equivalent;
93 any two characters that are related by case-conversion have the same
94 canonical equivalent character; it may be nil, in which case it is
95 deduced from DOWNCASE and UPCASE.
96EQUIVALENCES is a map that cyclicly permutes each equivalence class
97 (of characters with the same canonical equivalent); it may be nil,
98 in which case it is deduced from CANONICALIZE. */)
5842a27b 99 (Lisp_Object table)
dcfdbac7 100{
d9da9451 101 return set_case_table (table, 0);
dcfdbac7
JB
102}
103
a1de6b4b 104DEFUN ("set-standard-case-table", Fset_standard_case_table, Sset_standard_case_table, 1, 1, 0,
fdb82f93
PJ
105 doc: /* Select a new standard case table for new buffers.
106See `set-case-table' for more info on case tables. */)
5842a27b 107 (Lisp_Object table)
dcfdbac7 108{
d9da9451 109 return set_case_table (table, 1);
dcfdbac7
JB
110}
111
d9da9451 112static Lisp_Object
971de7fb 113set_case_table (Lisp_Object table, int standard)
dcfdbac7 114{
4b3bd052 115 Lisp_Object up, canon, eqv;
dcfdbac7
JB
116
117 check_case_table (table);
118
7f7fef04
RS
119 up = XCHAR_TABLE (table)->extras[0];
120 canon = XCHAR_TABLE (table)->extras[1];
121 eqv = XCHAR_TABLE (table)->extras[2];
dcfdbac7 122
d427b66a 123 if (NILP (up))
dcfdbac7 124 {
7f7fef04 125 up = Fmake_char_table (Qcase_table, Qnil);
8f924df7
KH
126 map_char_table (set_identity, Qnil, table, up);
127 map_char_table (shuffle, Qnil, table, up);
7f7fef04 128 XCHAR_TABLE (table)->extras[0] = up;
dcfdbac7
JB
129 }
130
d427b66a 131 if (NILP (canon))
dcfdbac7 132 {
4b3bd052 133 canon = Fmake_char_table (Qcase_table, Qnil);
7f7fef04 134 XCHAR_TABLE (table)->extras[1] = canon;
8f924df7 135 map_char_table (set_canon, Qnil, table, table);
5a0fd72f
RS
136 }
137
138 if (NILP (eqv))
139 {
7f7fef04 140 eqv = Fmake_char_table (Qcase_table, Qnil);
8f924df7
KH
141 map_char_table (set_identity, Qnil, canon, eqv);
142 map_char_table (shuffle, Qnil, canon, eqv);
4b3bd052 143 XCHAR_TABLE (table)->extras[2] = eqv;
dcfdbac7
JB
144 }
145
426f6c23
RS
146 /* This is so set_image_of_range_1 in regex.c can find the EQV table. */
147 XCHAR_TABLE (canon)->extras[2] = eqv;
148
dcfdbac7 149 if (standard)
f79609dc
KH
150 {
151 Vascii_downcase_table = table;
152 Vascii_upcase_table = up;
153 Vascii_canon_table = canon;
154 Vascii_eqv_table = eqv;
155 }
dcfdbac7 156 else
6c6fcbf8 157 {
4b4deea2
TT
158 BVAR (current_buffer, downcase_table) = table;
159 BVAR (current_buffer, upcase_table) = up;
160 BVAR (current_buffer, case_canon_table) = canon;
161 BVAR (current_buffer, case_eqv_table) = eqv;
6c6fcbf8 162 }
7f7fef04 163
dcfdbac7
JB
164 return table;
165}
166\f
da2795b2
KH
167/* The following functions are called in map_char_table. */
168
8f924df7
KH
169/* Set CANON char-table element for characters in RANGE to a
170 translated ELT by UP and DOWN char-tables. This is done only when
171 ELT is a character. The char-tables CANON, UP, and DOWN are in
172 CASE_TABLE. */
e16696ba 173
c0c15b93 174static void
971de7fb 175set_canon (Lisp_Object case_table, Lisp_Object range, Lisp_Object elt)
c0c15b93 176{
da2795b2
KH
177 Lisp_Object up = XCHAR_TABLE (case_table)->extras[0];
178 Lisp_Object canon = XCHAR_TABLE (case_table)->extras[1];
c0c15b93 179
da2795b2 180 if (NATNUMP (elt))
405b0b5a 181 Fset_char_table_range (canon, range, Faref (case_table, Faref (up, elt)));
c0c15b93 182}
dcfdbac7 183
8f924df7
KH
184/* Set elements of char-table TABLE for C to C itself. C may be a
185 cons specifying a character range. In that case, set characters in
186 that range to themselves. This is done only when ELT is a
187 character. This is called in map_char_table. */
e16696ba 188
7f7fef04 189static void
971de7fb 190set_identity (Lisp_Object table, Lisp_Object c, Lisp_Object elt)
dcfdbac7 191{
da2795b2 192 if (NATNUMP (elt))
e961d439 193 {
8f924df7
KH
194 int from, to;
195
196 if (CONSP (c))
e961d439 197 {
8f924df7
KH
198 from = XINT (XCAR (c));
199 to = XINT (XCDR (c));
e961d439
KH
200 }
201 else
8f924df7 202 from = to = XINT (c);
e961d439 203 for (; from <= to; from++)
405b0b5a 204 CHAR_TABLE_SET (table, from, make_number (from));
e961d439 205 }
dcfdbac7 206}
c0c15b93 207
da2795b2
KH
208/* Permute the elements of TABLE (which is initially an identity
209 mapping) so that it has one cycle for each equivalence class
210 induced by the translation table on which map_char_table is
211 operated. */
c0c15b93
KH
212
213static void
971de7fb 214shuffle (Lisp_Object table, Lisp_Object c, Lisp_Object elt)
c0c15b93 215{
e961d439 216 if (NATNUMP (elt))
da2795b2 217 {
8f924df7 218 int from, to;
e961d439 219
8f924df7 220 if (CONSP (c))
e961d439 221 {
8f924df7
KH
222 from = XINT (XCAR (c));
223 to = XINT (XCDR (c));
e961d439
KH
224 }
225 else
8f924df7 226 from = to = XINT (c);
e961d439
KH
227
228 for (; from <= to; from++)
fa055055
KH
229 {
230 Lisp_Object tem = Faref (table, elt);
231 Faset (table, elt, make_number (from));
232 Faset (table, make_number (from), tem);
233 }
da2795b2 234 }
c0c15b93 235}
dcfdbac7 236\f
dfcf069d 237void
971de7fb 238init_casetab_once (void)
dcfdbac7
JB
239{
240 register int i;
7f7fef04 241 Lisp_Object down, up;
d67b4f80 242 Qcase_table = intern_c_string ("case-table");
7f7fef04
RS
243 staticpro (&Qcase_table);
244
245 /* Intern this now in case it isn't already done.
246 Setting this variable twice is harmless.
247 But don't staticpro it here--that is done in alloc.c. */
d67b4f80 248 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
dcfdbac7 249
7f7fef04
RS
250 /* Now we are ready to set up this property, so we can
251 create char tables. */
4b3bd052 252 Fput (Qcase_table, Qchar_table_extra_slots, make_number (3));
7f7fef04
RS
253
254 down = Fmake_char_table (Qcase_table, Qnil);
255 Vascii_downcase_table = down;
e1b490ca 256 XCHAR_TABLE (down)->purpose = Qcase_table;
dcfdbac7 257
e961d439 258 for (i = 0; i < 128; i++)
8f924df7
KH
259 {
260 int c = (i >= 'A' && i <= 'Z') ? i + ('a' - 'A') : i;
261 CHAR_TABLE_SET (down, i, make_number (c));
262 }
7f7fef04
RS
263
264 XCHAR_TABLE (down)->extras[1] = Fcopy_sequence (down);
dcfdbac7 265
7f7fef04
RS
266 up = Fmake_char_table (Qcase_table, Qnil);
267 XCHAR_TABLE (down)->extras[0] = up;
dcfdbac7 268
e961d439 269 for (i = 0; i < 128; i++)
8f924df7
KH
270 {
271 int c = ((i >= 'A' && i <= 'Z') ? i + ('a' - 'A')
272 : ((i >= 'a' && i <= 'z') ? i + ('A' - 'a')
8510724d 273 : i));
8f924df7
KH
274 CHAR_TABLE_SET (up, i, make_number (c));
275 }
7f7fef04
RS
276
277 XCHAR_TABLE (down)->extras[2] = Fcopy_sequence (up);
66aa138d
RS
278
279 /* Fill in what isn't filled in. */
280 set_case_table (down, 1);
dcfdbac7
JB
281}
282
dfcf069d 283void
971de7fb 284syms_of_casetab (void)
dcfdbac7 285{
d67b4f80 286 Qcase_table_p = intern_c_string ("case-table-p");
dcfdbac7 287 staticpro (&Qcase_table_p);
7f7fef04 288
8f84b1a1 289 staticpro (&Vascii_canon_table);
dcfdbac7 290 staticpro (&Vascii_downcase_table);
8f84b1a1
EN
291 staticpro (&Vascii_eqv_table);
292 staticpro (&Vascii_upcase_table);
dcfdbac7
JB
293
294 defsubr (&Scase_table_p);
295 defsubr (&Scurrent_case_table);
296 defsubr (&Sstandard_case_table);
297 defsubr (&Sset_case_table);
298 defsubr (&Sset_standard_case_table);
dcfdbac7 299}