* editfns.c (Fformat): Remove unreachable code.
[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 {
f9a68bc5
PE
194 int from;
195 unsigned to;
8f924df7
KH
196
197 if (CONSP (c))
e961d439 198 {
8f924df7
KH
199 from = XINT (XCAR (c));
200 to = XINT (XCDR (c));
e961d439
KH
201 }
202 else
8f924df7 203 from = to = XINT (c);
f9a68bc5 204 for (to++; from < to; from++)
405b0b5a 205 CHAR_TABLE_SET (table, from, make_number (from));
e961d439 206 }
dcfdbac7 207}
c0c15b93 208
da2795b2
KH
209/* Permute the elements of TABLE (which is initially an identity
210 mapping) so that it has one cycle for each equivalence class
211 induced by the translation table on which map_char_table is
212 operated. */
c0c15b93
KH
213
214static void
971de7fb 215shuffle (Lisp_Object table, Lisp_Object c, Lisp_Object elt)
c0c15b93 216{
e961d439 217 if (NATNUMP (elt))
da2795b2 218 {
f9a68bc5
PE
219 int from;
220 unsigned to;
e961d439 221
8f924df7 222 if (CONSP (c))
e961d439 223 {
8f924df7
KH
224 from = XINT (XCAR (c));
225 to = XINT (XCDR (c));
e961d439
KH
226 }
227 else
8f924df7 228 from = to = XINT (c);
e961d439 229
f9a68bc5 230 for (to++; from < to; from++)
fa055055
KH
231 {
232 Lisp_Object tem = Faref (table, elt);
233 Faset (table, elt, make_number (from));
234 Faset (table, make_number (from), tem);
235 }
da2795b2 236 }
c0c15b93 237}
dcfdbac7 238\f
dfcf069d 239void
971de7fb 240init_casetab_once (void)
dcfdbac7
JB
241{
242 register int i;
7f7fef04 243 Lisp_Object down, up;
d67b4f80 244 Qcase_table = intern_c_string ("case-table");
7f7fef04
RS
245 staticpro (&Qcase_table);
246
247 /* Intern this now in case it isn't already done.
248 Setting this variable twice is harmless.
249 But don't staticpro it here--that is done in alloc.c. */
d67b4f80 250 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
dcfdbac7 251
7f7fef04
RS
252 /* Now we are ready to set up this property, so we can
253 create char tables. */
4b3bd052 254 Fput (Qcase_table, Qchar_table_extra_slots, make_number (3));
7f7fef04
RS
255
256 down = Fmake_char_table (Qcase_table, Qnil);
257 Vascii_downcase_table = down;
e1b490ca 258 XCHAR_TABLE (down)->purpose = Qcase_table;
dcfdbac7 259
e961d439 260 for (i = 0; i < 128; i++)
8f924df7
KH
261 {
262 int c = (i >= 'A' && i <= 'Z') ? i + ('a' - 'A') : i;
263 CHAR_TABLE_SET (down, i, make_number (c));
264 }
7f7fef04
RS
265
266 XCHAR_TABLE (down)->extras[1] = Fcopy_sequence (down);
dcfdbac7 267
7f7fef04
RS
268 up = Fmake_char_table (Qcase_table, Qnil);
269 XCHAR_TABLE (down)->extras[0] = up;
dcfdbac7 270
e961d439 271 for (i = 0; i < 128; i++)
8f924df7
KH
272 {
273 int c = ((i >= 'A' && i <= 'Z') ? i + ('a' - 'A')
274 : ((i >= 'a' && i <= 'z') ? i + ('A' - 'a')
8510724d 275 : i));
8f924df7
KH
276 CHAR_TABLE_SET (up, i, make_number (c));
277 }
7f7fef04
RS
278
279 XCHAR_TABLE (down)->extras[2] = Fcopy_sequence (up);
66aa138d
RS
280
281 /* Fill in what isn't filled in. */
282 set_case_table (down, 1);
dcfdbac7
JB
283}
284
dfcf069d 285void
971de7fb 286syms_of_casetab (void)
dcfdbac7 287{
d67b4f80 288 Qcase_table_p = intern_c_string ("case-table-p");
dcfdbac7 289 staticpro (&Qcase_table_p);
7f7fef04 290
8f84b1a1 291 staticpro (&Vascii_canon_table);
dcfdbac7 292 staticpro (&Vascii_downcase_table);
8f84b1a1
EN
293 staticpro (&Vascii_eqv_table);
294 staticpro (&Vascii_upcase_table);
dcfdbac7
JB
295
296 defsubr (&Scase_table_p);
297 defsubr (&Scurrent_case_table);
298 defsubr (&Sstandard_case_table);
299 defsubr (&Sset_case_table);
300 defsubr (&Sset_standard_case_table);
dcfdbac7 301}