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
/>.
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
];
41 sa_value.int_value
= CATCODEDEFAULT
;
42 s
= new_sa_tree
(CATCODESTACK
, 1, sa_value
);
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
];
56 sa_value.int_value
= CATCODEDEFAULT
;
57 s
= new_sa_tree
(CATCODESTACK
, 1, sa_value
);
60 return
(halfword
) get_sa_item
(s
, n
).int_value
;
63 void unsave_cat_codes
(int h
, quarterword gl
)
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 };
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));
83 sa_value.int_value
= CATCODEDEFAULT
;
84 catcode_heads
[0] = new_sa_tree
(CATCODESTACK
, 1, sa_value
);
87 static void dumpcatcodes
(void
)
91 for
(k
= 0; k
<= catcode_max
; k
++) {
92 if
(catcode_valid
[k
]) {
96 dump_int
(catcode_max
);
98 for
(k
= 0; k
<= catcode_max
; k
++) {
99 if
(catcode_valid
[k
]) {
101 dump_sa_tree
(catcode_heads
[k
]);
106 static void undumpcatcodes
(void
)
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
);
117 for
(k
= 0; k
< total
; k
++) {
119 catcode_heads
[x
] = undump_sa_tree
();
120 catcode_valid
[x
] = 1;
124 int valid_catcode_table
(int h
)
126 if
(h
<= CATCODE_MAX
&& h >= 0 && catcode_valid[h]) {
132 void copy_cat_codes
(int from
, int to
)
134 if
(from
< 0 || from
> CATCODE_MAX || catcode_valid
[from
] == 0) {
137 if
(to
> catcode_max
)
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
)
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
)
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
);
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
);
213 static void undumplccodes
(void
)
215 lccode_head
= undump_sa_tree
();
218 static void freelccodes
(void
)
220 destroy_sa_tree
(lccode_head
);
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
);
259 static void undumpuccodes
(void
)
261 uccode_head
= undump_sa_tree
();
264 static void freeuccodes
(void
)
266 destroy_sa_tree
(uccode_head
);
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
);
305 static void undumpsfcodes
(void
)
307 sfcode_head
= undump_sa_tree
();
310 static void freesfcodes
(void
)
312 destroy_sa_tree
(sfcode_head
);
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
];
334 sa_value.int_value
= HJCODEDEFAULT
;
335 s
= new_sa_tree
(HJCODESTACK
, 1, sa_value
);
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
];
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 };
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));
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
];
386 } else if
(h
> hjcode_max
) {
390 sa_value.int_value
= HJCODEDEFAULT
;
391 s
= new_sa_tree
(HJCODESTACK
, 1, sa_value
);
394 hjcode_heads
[h
] = copy_sa_tree
(lccode_head
);
398 static void dumphjcodes
(void
)
402 for
(k
= 0; k
<= hjcode_max
; k
++) {
403 if
(hjcode_valid
[k
]) {
407 dump_int
(hjcode_max
);
409 for
(k
= 0; k
<= hjcode_max
; k
++) {
410 if
(hjcode_valid
[k
]) {
412 dump_sa_tree
(hjcode_heads
[k
]);
417 static void undumphjcodes
(void
)
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
);
428 for
(k
= 0; k
< total
; k
++) {
430 hjcode_heads
[x
] = undump_sa_tree
();
435 static void freehjcodes
(void
)
438 for
(k
= 0; k
<= hjcode_max
; k
++) {
439 if
(hjcode_valid
[k
]) {
440 destroy_sa_tree
(hjcode_heads
[k
]);
449 void unsave_text_codes
(quarterword grouplevel
)
451 unsavelccodes
(grouplevel
);
452 unsaveuccodes
(grouplevel
);
453 unsavesfcodes
(grouplevel
);
456 void initialize_text_codes
(void
)
458 initializecatcodes
();
465 void free_text_codes
(void
)
474 void dump_text_codes
(void
)
483 void undump_text_codes
(void
)