1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include <config.h>
25: #include "lisp.h"
26: #include "buffer.h"
27: #include "charset.h"
28:
29: Lisp_Object Qcase_table_p, Qcase_table;
30: Lisp_Object Vascii_downcase_table, Vascii_upcase_table;
31: Lisp_Object Vascii_canon_table, Vascii_eqv_table;
32:
33:
34:
35: int case_temp1;
36: Lisp_Object case_temp2;
37:
38: static void set_canon ();
39: static void set_identity ();
40: static void shuffle ();
41:
42: DEFUN ("case-table-p", Fcase_table_p, Scase_table_p, 1, 1, 0,
43: doc:
44: )
45: (object)
46: Lisp_Object object;
47: {
48: Lisp_Object up, canon, eqv;
49:
50: if (! CHAR_TABLE_P (object))
51: return Qnil;
52: if (! EQ (XCHAR_TABLE (object)->purpose, Qcase_table))
53: return Qnil;
54:
55: up = XCHAR_TABLE (object)->extras[0];
56: canon = XCHAR_TABLE (object)->extras[1];
57: eqv = XCHAR_TABLE (object)->extras[2];
58:
59: return ((NILP (up) || CHAR_TABLE_P (up))
60: && ((NILP (canon) && NILP (eqv))
61: || (CHAR_TABLE_P (canon)
62: && (NILP (eqv) || CHAR_TABLE_P (eqv))))
63: ? Qt : Qnil);
64: }
65:
66: static Lisp_Object
67: check_case_table (obj)
68: Lisp_Object obj;
69: {
70: CHECK_TYPE (!NILP (Fcase_table_p (obj)), Qcase_table_p, obj);
71: return (obj);
72: }
73:
74: DEFUN ("current-case-table", Fcurrent_case_table, Scurrent_case_table, 0, 0, 0,
75: doc: )
76: ()
77: {
78: return current_buffer->downcase_table;
79: }
80:
81: DEFUN ("standard-case-table", Fstandard_case_table, Sstandard_case_table, 0, 0, 0,
82: doc:
83: )
84: ()
85: {
86: return Vascii_downcase_table;
87: }
88:
89: static Lisp_Object set_case_table ();
90:
91: DEFUN ("set-case-table", Fset_case_table, Sset_case_table, 1, 1, 0,
92: doc:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107: )
108: (table)
109: Lisp_Object table;
110: {
111: return set_case_table (table, 0);
112: }
113:
114: DEFUN ("set-standard-case-table", Fset_standard_case_table, Sset_standard_case_table, 1, 1, 0,
115: doc:
116: )
117: (table)
118: Lisp_Object table;
119: {
120: return set_case_table (table, 1);
121: }
122:
123: static Lisp_Object
124: set_case_table (table, standard)
125: Lisp_Object table;
126: int standard;
127: {
128: Lisp_Object up, canon, eqv;
129: Lisp_Object indices[3];
130:
131: check_case_table (table);
132:
133: up = XCHAR_TABLE (table)->extras[0];
134: canon = XCHAR_TABLE (table)->extras[1];
135: eqv = XCHAR_TABLE (table)->extras[2];
136:
137: if (NILP (up))
138: {
139: up = Fmake_char_table (Qcase_table, Qnil);
140: map_char_table (set_identity, Qnil, table, table, up, 0, indices);
141: map_char_table (shuffle, Qnil, table, table, up, 0, indices);
142: XCHAR_TABLE (table)->extras[0] = up;
143: }
144:
145: if (NILP (canon))
146: {
147: canon = Fmake_char_table (Qcase_table, Qnil);
148: XCHAR_TABLE (table)->extras[1] = canon;
149: map_char_table (set_canon, Qnil, table, table, table, 0, indices);
150: }
151:
152: if (NILP (eqv))
153: {
154: eqv = Fmake_char_table (Qcase_table, Qnil);
155: map_char_table (set_identity, Qnil, canon, canon, eqv, 0, indices);
156: map_char_table (shuffle, Qnil, canon, canon, eqv, 0, indices);
157: XCHAR_TABLE (table)->extras[2] = eqv;
158: }
159:
160:
161: XCHAR_TABLE (canon)->extras[2] = eqv;
162:
163: if (standard)
164: {
165: Vascii_downcase_table = table;
166: Vascii_upcase_table = up;
167: Vascii_canon_table = canon;
168: Vascii_eqv_table = eqv;
169: }
170: else
171: {
172: current_buffer->downcase_table = table;
173: current_buffer->upcase_table = up;
174: current_buffer->case_canon_table = canon;
175: current_buffer->case_eqv_table = eqv;
176: }
177:
178: return table;
179: }
180: ^L
181:
182:
183:
184:
185:
186:
187: static void
188: set_canon (case_table, c, elt)
189: Lisp_Object case_table, c, elt;
190: {
191: Lisp_Object up = XCHAR_TABLE (case_table)->extras[0];
192: Lisp_Object canon = XCHAR_TABLE (case_table)->extras[1];
193:
194: if (NATNUMP (elt))
195: Faset (canon, c, Faref (case_table, Faref (up, elt)));
196: }
197:
198:
199:
200:
201: static void
202: set_identity (table, c, elt)
203: Lisp_Object table, c, elt;
204: {
205: if (NATNUMP (elt))
206: Faset (table, c, c);
207: }
208:
209:
210:
211:
212:
213:
214: static void
215: shuffle (table, c, elt)
216: Lisp_Object table, c, elt;
217: {
218: if (NATNUMP (elt) && !EQ (c, elt))
219: {
220: Lisp_Object tem = Faref (table, elt);
221: Faset (table, elt, c);
222: Faset (table, c, tem);
223: }
224: }
225: ^L
226: void
227: init_casetab_once ()
228: {
229: register int i;
230: Lisp_Object down, up;
231: Qcase_table = intern ("case-table");
232: staticpro (&Qcase_table);
233:
234:
235:
236:
237: Qchar_table_extra_slots = intern ("char-table-extra-slots");
238:
239:
240:
241: Fput (Qcase_table, Qchar_table_extra_slots, make_number (3));
242:
243: down = Fmake_char_table (Qcase_table, Qnil);
244: Vascii_downcase_table = down;
245: XCHAR_TABLE (down)->purpose = Qcase_table;
246:
247: for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
248: XSETFASTINT (XCHAR_TABLE (down)->contents[i],
249: (i >= 'A' && i <= 'Z') ? i + ('a' - 'A') : i);
250:
251: XCHAR_TABLE (down)->extras[1] = Fcopy_sequence (down);
252:
253: up = Fmake_char_table (Qcase_table, Qnil);
254: XCHAR_TABLE (down)->extras[0] = up;
255:
256: for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
257: XSETFASTINT (XCHAR_TABLE (up)->contents[i],
258: ((i >= 'A' && i <= 'Z')
259: ? i + ('a' - 'A')
260: : ((i >= 'a' && i <= 'z')
261: ? i + ('A' - 'a')
262: : i)));
263:
264: XCHAR_TABLE (down)->extras[2] = Fcopy_sequence (up);
265:
266:
267: set_case_table (down, 1);
268: }
269:
270: void
271: syms_of_casetab ()
272: {
273: Qcase_table_p = intern ("case-table-p");
274: staticpro (&Qcase_table_p);
275:
276: staticpro (&Vascii_canon_table);
277: staticpro (&Vascii_downcase_table);
278: staticpro (&Vascii_eqv_table);
279: staticpro (&Vascii_upcase_table);
280:
281: defsubr (&Scase_table_p);
282: defsubr (&Scurrent_case_table);
283: defsubr (&Sstandard_case_table);
284: defsubr (&Sset_case_table);
285: defsubr (&Sset_standard_case_table);
286: }
287:
288:
289: