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