beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / tex / textcodes.w
blob89e936841328821fa787ac8c030e054d1f30e1f9
1 % textcodes.w
3 % Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
5 % This file is part of LuaTeX.
7 % LuaTeX is free software; you can redistribute it and/or modify it under
8 % the terms of the GNU General Public License as published by the Free
9 % Software Foundation; either version 2 of the License, or (at your
10 % option) any later version.
12 % LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 % FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 % License for more details.
17 % You should have received a copy of the GNU General Public License along
18 % with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
20 @ @c
22 #include "ptexlib.h"
24 @ catcodes @c
26 #define CATCODESTACK 8
27 #define CATCODEDEFAULT 12
28 #define CATCODE_MAX 32767
30 static sa_tree *catcode_heads = NULL;
31 static int catcode_max = 0;
32 static unsigned char *catcode_valid = NULL;
34 void set_cat_code(int h, int n, halfword v, quarterword gl)
36 sa_tree_item sa_value = { 0 };
37 sa_tree s = catcode_heads[h];
38 if (h > catcode_max)
39 catcode_max = h;
40 if (s == NULL) {
41 sa_value.int_value = CATCODEDEFAULT;
42 s = new_sa_tree(CATCODESTACK, 1, sa_value);
43 catcode_heads[h] = s;
45 sa_value.int_value = (int) v;
46 set_sa_item(s, n, sa_value, gl);
49 halfword get_cat_code(int h, int n)
51 sa_tree_item sa_value = { 0 };
52 sa_tree s = catcode_heads[h];
53 if (h > catcode_max)
54 catcode_max = h;
55 if (s == NULL) {
56 sa_value.int_value = CATCODEDEFAULT;
57 s = new_sa_tree(CATCODESTACK, 1, sa_value);
58 catcode_heads[h] = s;
60 return (halfword) get_sa_item(s, n).int_value;
63 void unsave_cat_codes(int h, quarterword gl)
65 int k;
66 if (h > catcode_max)
67 catcode_max = h;
68 for (k = 0; k <= catcode_max; k++) {
69 if (catcode_heads[k] != NULL)
70 restore_sa_stack(catcode_heads[k], gl);
74 static void initializecatcodes(void)
76 sa_tree_item sa_value = { 0 };
77 catcode_max = 0;
78 catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1));
79 catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1));
80 memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1));
81 memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1));
82 catcode_valid[0] = 1;
83 sa_value.int_value = CATCODEDEFAULT;
84 catcode_heads[0] = new_sa_tree(CATCODESTACK, 1, sa_value);
87 static void dumpcatcodes(void)
89 int total = 0;
90 int k;
91 for (k = 0; k <= catcode_max; k++) {
92 if (catcode_valid[k]) {
93 total++;
96 dump_int(catcode_max);
97 dump_int(total);
98 for (k = 0; k <= catcode_max; k++) {
99 if (catcode_valid[k]) {
100 dump_int(k);
101 dump_sa_tree(catcode_heads[k],"catcodes");
106 static void undumpcatcodes(void)
108 int total, k, x;
109 xfree(catcode_heads);
110 xfree(catcode_valid);
111 catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1));
112 catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1));
113 memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1));
114 memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1));
115 undump_int(catcode_max);
116 undump_int(total);
117 for (k = 0; k < total; k++) {
118 undump_int(x);
119 catcode_heads[x] = undump_sa_tree("catcodes");
120 catcode_valid[x] = 1;
124 int valid_catcode_table(int h)
126 if (h <= CATCODE_MAX && h >= 0 && catcode_valid[h]) {
127 return 1;
129 return 0;
132 void copy_cat_codes(int from, int to)
134 if (from < 0 || from > CATCODE_MAX || catcode_valid[from] == 0) {
135 uexit(1);
137 if (to > catcode_max)
138 catcode_max = to;
139 destroy_sa_tree(catcode_heads[to]);
140 catcode_heads[to] = copy_sa_tree(catcode_heads[from]);
141 catcode_valid[to] = 1;
144 void initex_cat_codes(int h)
146 int k;
147 if (h > catcode_max)
148 catcode_max = h;
149 destroy_sa_tree(catcode_heads[h]);
150 catcode_heads[h] = NULL;
151 set_cat_code(h, '\r', car_ret_cmd, 1);
152 set_cat_code(h, ' ', spacer_cmd, 1);
153 set_cat_code(h, '\\', escape_cmd, 1);
154 set_cat_code(h, '%', comment_cmd, 1);
155 set_cat_code(h, 127, invalid_char_cmd, 1);
156 set_cat_code(h, 0, ignore_cmd, 1);
157 set_cat_code(h, 0xFEFF, ignore_cmd, 1);
158 for (k = 'A'; k <= 'Z'; k++) {
159 set_cat_code(h, k, letter_cmd, 1);
160 set_cat_code(h, k + 'a' - 'A', letter_cmd, 1);
162 catcode_valid[h] = 1;
165 static void freecatcodes(void)
167 int k;
168 for (k = 0; k <= catcode_max; k++) {
169 if (catcode_valid[k]) {
170 destroy_sa_tree(catcode_heads[k]);
173 xfree(catcode_heads);
174 xfree(catcode_valid);
177 @ lccodes @c
179 #define LCCODESTACK 8
180 #define LCCODEDEFAULT 0
182 static sa_tree lccode_head = NULL;
184 void set_lc_code(int n, halfword v, quarterword gl)
186 sa_tree_item sa_value = { 0 };
187 sa_value.int_value = (int) v;
188 set_sa_item(lccode_head, n, sa_value, gl);
191 halfword get_lc_code(int n)
193 return (halfword) get_sa_item(lccode_head, n).int_value;
196 static void unsavelccodes(quarterword gl)
198 restore_sa_stack(lccode_head, gl);
201 static void initializelccodes(void)
203 sa_tree_item sa_value = { 0 };
204 sa_value.int_value = LCCODEDEFAULT;
205 lccode_head = new_sa_tree(LCCODESTACK, 1, sa_value);
208 static void dumplccodes(void)
210 dump_sa_tree(lccode_head,"lccodes");
213 static void undumplccodes(void)
215 lccode_head = undump_sa_tree("lccodes");
218 static void freelccodes(void)
220 destroy_sa_tree(lccode_head);
223 @ uccodes @c
225 #define UCCODESTACK 8
226 #define UCCODEDEFAULT 0
228 static sa_tree uccode_head = NULL;
230 void set_uc_code(int n, halfword v, quarterword gl)
232 sa_tree_item sa_value = { 0 };
233 sa_value.int_value = (int) v;
234 set_sa_item(uccode_head, n, sa_value, gl);
237 halfword get_uc_code(int n)
239 return (halfword) get_sa_item(uccode_head, n).int_value;
242 static void unsaveuccodes(quarterword gl)
244 restore_sa_stack(uccode_head, gl);
247 static void initializeuccodes(void)
249 sa_tree_item sa_value = { 0 };
250 sa_value.int_value = UCCODEDEFAULT;
251 uccode_head = new_sa_tree(UCCODESTACK, 1, sa_value);
254 static void dumpuccodes(void)
256 dump_sa_tree(uccode_head,"uccodes");
259 static void undumpuccodes(void)
261 uccode_head = undump_sa_tree("uccodes");
264 static void freeuccodes(void)
266 destroy_sa_tree(uccode_head);
269 @ sfcodes @c
271 #define SFCODESTACK 8
272 #define SFCODEDEFAULT 1000
274 static sa_tree sfcode_head = NULL;
276 void set_sf_code(int n, halfword v, quarterword gl)
278 sa_tree_item sa_value = { 0 };
279 sa_value.int_value = (int) v;
280 set_sa_item(sfcode_head, n, sa_value, gl);
283 halfword get_sf_code(int n)
285 return (halfword) get_sa_item(sfcode_head, n).int_value;
288 static void unsavesfcodes(quarterword gl)
290 restore_sa_stack(sfcode_head, gl);
293 static void initializesfcodes(void)
295 sa_tree_item sa_value = { 0 };
296 sa_value.int_value = SFCODEDEFAULT;
297 sfcode_head = new_sa_tree(SFCODESTACK, 1, sa_value);
300 static void dumpsfcodes(void)
302 dump_sa_tree(sfcode_head,"sfcodes");
305 static void undumpsfcodes(void)
307 sfcode_head = undump_sa_tree("sfcodes");
310 static void freesfcodes(void)
312 destroy_sa_tree(sfcode_head);
315 @ hjcodes @c
317 #define HJCODESTACK 8
318 #define HJCODEDEFAULT 0
319 #define HJCODE_MAX 16383 /* number of languages */
321 static sa_tree *hjcode_heads = NULL;
322 static int hjcode_max = 0;
323 static unsigned char *hjcode_valid = NULL;
325 @ Here we set codes but we don't initialize from lccodes.
327 @c void set_hj_code(int h, int n, halfword v, quarterword gl)
329 sa_tree_item sa_value = { 0 };
330 sa_tree s = hjcode_heads[h];
331 if (h > hjcode_max)
332 hjcode_max = h;
333 if (s == NULL) {
334 sa_value.int_value = HJCODEDEFAULT;
335 s = new_sa_tree(HJCODESTACK, 1, sa_value);
336 hjcode_heads[h] = s;
338 sa_value.int_value = (int) v;
339 set_sa_item(s, n, sa_value, gl);
342 @ We just return the lccodes when nothing is set.
344 @c halfword get_hj_code(int h, int n)
346 sa_tree s = hjcode_heads[h];
347 if (s == NULL) {
348 s = lccode_head;
350 return (halfword) get_sa_item(s, n).int_value;
353 @ We don't restore as we can have more languages in a paragraph
354 and hyphenation takes place at a later stage so we would get
355 weird grouping side effects .. so, one can overload settings
356 but management is then upto the used, so no:
360 static void unsavehjcodes(quarterword gl) { }
363 static void initializehjcodes(void)
366 sa_tree_item sa_value = { 0 };
368 hjcode_max = 0;
369 hjcode_heads = Mxmalloc_array(sa_tree, (HJCODE_MAX + 1));
370 hjcode_valid = Mxmalloc_array(unsigned char, (HJCODE_MAX + 1));
371 memset(hjcode_heads, 0, sizeof(sa_tree) * (HJCODE_MAX + 1));
372 memset(hjcode_valid, 0, sizeof(unsigned char) * (HJCODE_MAX + 1));
374 hjcode_valid[0] = 1;
375 sa_value.int_value = HJCODEDEFAULT;
376 hjcode_heads[0] = new_sa_tree(HJCODESTACK, 1, sa_value);
380 void hj_codes_from_lc_codes(int h)
382 sa_tree_item sa_value = { 0 };
383 sa_tree s = hjcode_heads[h];
384 if (s != NULL) {
385 destroy_sa_tree(s);
386 } else if (h > hjcode_max) {
387 hjcode_max = h;
389 if (s == NULL) {
390 sa_value.int_value = HJCODEDEFAULT;
391 s = new_sa_tree(HJCODESTACK, 1, sa_value);
392 hjcode_heads[h] = s;
394 hjcode_heads[h] = copy_sa_tree(lccode_head);
395 hjcode_valid[h] = 1;
398 static void dumphjcodes(void)
400 int total = 0;
401 int k;
402 for (k = 0; k <= hjcode_max; k++) {
403 if (hjcode_valid[k]) {
404 total++;
407 dump_int(hjcode_max);
408 dump_int(total);
409 for (k = 0; k <= hjcode_max; k++) {
410 if (hjcode_valid[k]) {
411 dump_int(k);
412 dump_sa_tree(hjcode_heads[k],"hjcodes");
417 static void undumphjcodes(void)
419 int total, k, x;
420 xfree(hjcode_heads);
421 xfree(hjcode_valid);
422 hjcode_heads = Mxmalloc_array(sa_tree, (HJCODE_MAX + 1));
423 hjcode_valid = Mxmalloc_array(unsigned char, (HJCODE_MAX + 1));
424 memset(hjcode_heads, 0, sizeof(sa_tree) * (HJCODE_MAX + 1));
425 memset(hjcode_valid, 0, sizeof(unsigned char) * (HJCODE_MAX + 1));
426 undump_int(hjcode_max);
427 undump_int(total);
428 for (k = 0; k < total; k++) {
429 undump_int(x);
430 hjcode_heads[x] = undump_sa_tree("hjcodes");
431 hjcode_valid[x] = 1;
435 static void freehjcodes(void)
437 int k;
438 for (k = 0; k <= hjcode_max; k++) {
439 if (hjcode_valid[k]) {
440 destroy_sa_tree(hjcode_heads[k]);
443 xfree(hjcode_heads);
444 xfree(hjcode_valid);
447 /* management */
449 void unsave_text_codes(quarterword grouplevel)
451 unsavelccodes(grouplevel);
452 unsaveuccodes(grouplevel);
453 unsavesfcodes(grouplevel);
456 void initialize_text_codes(void)
458 initializecatcodes();
459 initializelccodes();
460 initializeuccodes();
461 initializesfcodes();
462 initializehjcodes();
465 void free_text_codes(void)
467 freecatcodes();
468 freelccodes();
469 freeuccodes();
470 freesfcodes();
471 freehjcodes();
474 void dump_text_codes(void)
476 dumpcatcodes();
477 dumplccodes();
478 dumpuccodes();
479 dumpsfcodes();
480 dumphjcodes();
483 void undump_text_codes(void)
485 undumpcatcodes();
486 undumplccodes();
487 undumpuccodes();
488 undumpsfcodes();
489 undumphjcodes();