153 |
|
|
154 |
|
|
155 |
|
|
156 |
/* Set to 1 when a charset map is loaded to warn that a buffer text |
/* Set to 1 to warn that a charset map is loaded and thus a buffer |
157 |
and a string data may be relocated. */ |
text and a string data may be relocated. */ |
158 |
int charset_map_loaded; |
int charset_map_loaded; |
159 |
|
|
160 |
/* Parse the mapping vector MAP which has this form: |
struct charset_map_entries |
161 |
[CODE0 CHAR0 CODE1 CHAR1 ... ] |
{ |
162 |
|
struct { |
163 |
|
unsigned from, to; |
164 |
|
int c; |
165 |
|
} entry[0x10000]; |
166 |
|
struct charset_map_entries *next; |
167 |
|
}; |
168 |
|
|
169 |
|
/* Load the mapping information for CHARSET from ENTRIES. |
170 |
|
|
171 |
If CONTROL_FLAG is 0, setup CHARSET->min_char and CHARSET->max_char. |
If CONTROL_FLAG is 0, setup CHARSET->min_char and CHARSET->max_char. |
172 |
|
|
178 |
setup it too. */ |
setup it too. */ |
179 |
|
|
180 |
static void |
static void |
181 |
parse_charset_map (charset, map, control_flag) |
load_charset_map (charset, entries, n_entries, control_flag) |
182 |
struct charset *charset; |
struct charset *charset; |
183 |
Lisp_Object map; |
struct charset_map_entries *entries; |
184 |
|
int n_entries; |
185 |
int control_flag; |
int control_flag; |
186 |
{ |
{ |
187 |
Lisp_Object vec, table; |
Lisp_Object vec, table; |
189 |
unsigned max_code = CHARSET_MAX_CODE (charset); |
unsigned max_code = CHARSET_MAX_CODE (charset); |
190 |
int ascii_compatible_p = charset->ascii_compatible_p; |
int ascii_compatible_p = charset->ascii_compatible_p; |
191 |
int min_char, max_char, nonascii_min_char; |
int min_char, max_char, nonascii_min_char; |
|
int size; |
|
192 |
int i; |
int i; |
193 |
int first; |
int first; |
194 |
unsigned char *fast_map = charset->fast_map; |
unsigned char *fast_map = charset->fast_map; |
195 |
|
|
196 |
if (control_flag) |
if (n_entries <= 0) |
197 |
|
return; |
198 |
|
|
199 |
|
if (control_flag > 0) |
200 |
{ |
{ |
201 |
int n = CODE_POINT_TO_INDEX (charset, max_code) + 1; |
int n = CODE_POINT_TO_INDEX (charset, max_code) + 1; |
202 |
unsigned invalid_code = CHARSET_INVALID_CODE (charset); |
unsigned invalid_code = CHARSET_INVALID_CODE (charset); |
210 |
charset_map_loaded = 1; |
charset_map_loaded = 1; |
211 |
} |
} |
212 |
|
|
213 |
size = ASIZE (map); |
min_char = max_char = entries->entry[0].c; |
214 |
nonascii_min_char = MAX_CHAR; |
nonascii_min_char = MAX_CHAR; |
215 |
CHARSET_COMPACT_CODES_P (charset) = 1; |
for (i = 0; i < n_entries; i++) |
|
for (first = 1, i = 0; i < size; i += 2) |
|
216 |
{ |
{ |
217 |
Lisp_Object val; |
unsigned from, to; |
|
unsigned code; |
|
218 |
int c, char_index; |
int c, char_index; |
219 |
|
int idx = i % 0x10000; |
220 |
|
|
221 |
val = AREF (map, i); |
if (i > 0 && idx == 0) |
222 |
CHECK_NATNUM (val); |
entries = entries->next; |
223 |
code = XFASTINT (val); |
from = entries->entry[idx].from; |
224 |
val = AREF (map, i + 1); |
to = entries->entry[idx].to; |
225 |
CHECK_NATNUM (val); |
c = entries->entry[idx].c; |
|
c = XFASTINT (val); |
|
226 |
|
|
|
if (code < min_code || code > max_code) |
|
|
continue; |
|
|
char_index = CODE_POINT_TO_INDEX (charset, code); |
|
|
if (char_index < 0 |
|
|
|| c > MAX_CHAR) |
|
|
continue; |
|
|
|
|
227 |
if (control_flag < 2) |
if (control_flag < 2) |
228 |
{ |
{ |
229 |
if (first) |
if (control_flag == 1) |
230 |
{ |
{ |
231 |
min_char = max_char = c; |
unsigned code = from; |
232 |
first = 0; |
int from_index, to_index; |
233 |
|
|
234 |
|
from_index = CODE_POINT_TO_INDEX (charset, from); |
235 |
|
if (from == to) |
236 |
|
to_index = from_index; |
237 |
|
else |
238 |
|
to_index = CODE_POINT_TO_INDEX (charset, to); |
239 |
|
if (from_index < 0 || to_index < 0) |
240 |
|
continue; |
241 |
|
if (CHARSET_COMPACT_CODES_P (charset)) |
242 |
|
while (1) |
243 |
|
{ |
244 |
|
ASET (vec, from_index, make_number (c)); |
245 |
|
CHAR_TABLE_SET (table, c, make_number (code)); |
246 |
|
if (from_index == to_index) |
247 |
|
break; |
248 |
|
from_index++, c++; |
249 |
|
code = INDEX_TO_CODE_POINT (charset, from_index); |
250 |
|
} |
251 |
|
else |
252 |
|
for (; from_index <= to_index; from_index++, c++) |
253 |
|
{ |
254 |
|
ASET (vec, from_index, make_number (c)); |
255 |
|
CHAR_TABLE_SET (table, c, make_number (from_index)); |
256 |
|
} |
257 |
} |
} |
258 |
else if (c > max_char) |
|
259 |
|
if (c > max_char) |
260 |
max_char = c; |
max_char = c; |
261 |
else if (c < min_char) |
else if (c < min_char) |
262 |
min_char = c; |
min_char = c; |
266 |
|
|
267 |
CHARSET_FAST_MAP_SET (c, fast_map); |
CHARSET_FAST_MAP_SET (c, fast_map); |
268 |
} |
} |
269 |
|
else |
|
if (control_flag) |
|
270 |
{ |
{ |
271 |
if (control_flag == 1) |
for (; from <= to; from++) |
|
{ |
|
|
if (char_index >= ASIZE (vec)) |
|
|
abort (); |
|
|
ASET (vec, char_index, make_number (c)); |
|
|
if (code > 0x7FFFFFF) |
|
|
{ |
|
|
CHAR_TABLE_SET (table, c, |
|
|
Fcons (make_number (code >> 16), |
|
|
make_number (code & 0xFFFF))); |
|
|
CHARSET_COMPACT_CODES_P (charset) = 0; |
|
|
} |
|
|
else |
|
|
CHAR_TABLE_SET (table, c, make_number (code)); |
|
|
} |
|
|
else |
|
272 |
{ |
{ |
273 |
int c1 = DECODE_CHAR (charset, code); |
int c1 = DECODE_CHAR (charset, from); |
274 |
|
|
275 |
if (c1 >= 0) |
if (c1 >= 0) |
276 |
{ |
{ |
277 |
CHAR_TABLE_SET (table, c, make_number (c1)); |
CHAR_TABLE_SET (table, c, make_number (c1)); |
289 |
CHARSET_MIN_CHAR (charset) = (ascii_compatible_p |
CHARSET_MIN_CHAR (charset) = (ascii_compatible_p |
290 |
? nonascii_min_char : min_char); |
? nonascii_min_char : min_char); |
291 |
CHARSET_MAX_CHAR (charset) = max_char; |
CHARSET_MAX_CHAR (charset) = max_char; |
292 |
if (control_flag) |
if (control_flag == 1) |
293 |
{ |
{ |
294 |
CHARSET_DECODER (charset) = vec; |
CHARSET_DECODER (charset) = vec; |
295 |
CHARSET_ENCODER (charset) = table; |
CHARSET_ENCODER (charset) = table; |
337 |
else |
else |
338 |
while ((c = getc (fp)) != EOF && isdigit (c)) |
while ((c = getc (fp)) != EOF && isdigit (c)) |
339 |
n = (n * 10) + c - '0'; |
n = (n * 10) + c - '0'; |
340 |
|
if (c != EOF) |
341 |
|
ungetc (c, fp); |
342 |
return n; |
return n; |
343 |
} |
} |
344 |
|
|
345 |
|
|
346 |
/* Return a mapping vector for CHARSET loaded from MAPFILE. |
/* Return a mapping vector for CHARSET loaded from MAPFILE. |
347 |
Each line of MAPFILE has this form: |
Each line of MAPFILE has this form |
348 |
0xAAAA 0xBBBB |
0xAAAA 0xCCCC |
349 |
where 0xAAAA is a code-point and 0xBBBB is the corresponding |
where 0xAAAA is a code-point and 0xCCCC is the corresponding |
350 |
character code. |
character code, or this form |
351 |
|
0xAAAA-0xBBBB 0xCCCC |
352 |
|
where 0xAAAA and 0xBBBB are code-points specifying a range, and |
353 |
|
0xCCCC is the first character code of the range. |
354 |
|
|
355 |
The returned vector has this form: |
The returned vector has this form: |
356 |
[ CODE1 CHAR1 CODE2 CHAR2 .... ] |
[ CODE1 CHAR1 CODE2 CHAR2 .... ] |
357 |
*/ |
where CODE1 is a code-point or a cons of code-points specifying a |
358 |
|
range. */ |
359 |
|
|
360 |
extern void add_to_log P_ ((char *, Lisp_Object, Lisp_Object)); |
extern void add_to_log P_ ((char *, Lisp_Object, Lisp_Object)); |
361 |
|
|
362 |
static Lisp_Object |
static void |
363 |
load_charset_map (charset, mapfile) |
load_charset_map_from_file (charset, mapfile, control_flag) |
364 |
struct charset *charset; |
struct charset *charset; |
365 |
Lisp_Object mapfile; |
Lisp_Object mapfile; |
366 |
|
int control_flag; |
367 |
{ |
{ |
368 |
|
unsigned min_code = CHARSET_MIN_CODE (charset); |
369 |
|
unsigned max_code = CHARSET_MAX_CODE (charset); |
370 |
int fd; |
int fd; |
371 |
FILE *fp; |
FILE *fp; |
|
int num; |
|
|
unsigned *numbers_table[256]; |
|
|
int numbers_table_used; |
|
|
unsigned *numbers; |
|
372 |
int eof; |
int eof; |
373 |
Lisp_Object suffixes; |
Lisp_Object suffixes; |
|
Lisp_Object vec; |
|
374 |
int i; |
int i; |
375 |
|
struct charset_map_entries *head, *entries; |
376 |
|
int n_entries; |
377 |
|
|
378 |
suffixes = Fcons (build_string (".map"), |
suffixes = Fcons (build_string (".map"), |
379 |
Fcons (build_string (".TXT"), Qnil)); |
Fcons (build_string (".TXT"), Qnil)); |
384 |
|| ! (fp = fdopen (fd, "r"))) |
|| ! (fp = fdopen (fd, "r"))) |
385 |
{ |
{ |
386 |
add_to_log ("Failure in loading charset map: %S", mapfile, Qnil); |
add_to_log ("Failure in loading charset map: %S", mapfile, Qnil); |
387 |
return Qnil; |
return; |
388 |
} |
} |
389 |
|
|
390 |
numbers_table_used = 0; |
head = entries = ((struct charset_map_entries *) |
391 |
num = 0; |
alloca (sizeof (struct charset_map_entries))); |
392 |
|
n_entries = 0; |
393 |
eof = 0; |
eof = 0; |
394 |
while (1) |
while (1) |
395 |
{ |
{ |
396 |
unsigned n = read_hex (fp, &eof); |
unsigned from, to; |
397 |
|
int c; |
398 |
|
int idx; |
399 |
|
|
400 |
|
from = read_hex (fp, &eof); |
401 |
if (eof) |
if (eof) |
402 |
break; |
break; |
403 |
if ((num % 0x10000) == 0) |
if (getc (fp) == '-') |
404 |
|
to = read_hex (fp, &eof); |
405 |
|
else |
406 |
|
to = from; |
407 |
|
c = (int) read_hex (fp, &eof); |
408 |
|
|
409 |
|
if (from < min_code || to > max_code || from > to || c > MAX_CHAR) |
410 |
|
continue; |
411 |
|
|
412 |
|
if (n_entries > 0 && (n_entries % 0x10000) == 0) |
413 |
{ |
{ |
414 |
if (numbers_table_used == 256) |
entries->next = ((struct charset_map_entries *) |
415 |
break; |
alloca (sizeof (struct charset_map_entries))); |
416 |
numbers = (unsigned *) alloca (sizeof (unsigned) * 0x10000); |
entries = entries->next; |
|
numbers_table[numbers_table_used++] = numbers; |
|
417 |
} |
} |
418 |
*numbers++ = n; |
idx = n_entries % 0x10000; |
419 |
num++; |
entries->entry[idx].from = from; |
420 |
|
entries->entry[idx].to = to; |
421 |
|
entries->entry[idx].c = c; |
422 |
|
n_entries++; |
423 |
} |
} |
424 |
fclose (fp); |
fclose (fp); |
425 |
close (fd); |
close (fd); |
426 |
|
|
427 |
vec = Fmake_vector (make_number (num), Qnil); |
load_charset_map (charset, head, n_entries, control_flag); |
428 |
for (i = 0; i < num; i++, numbers++) |
} |
429 |
|
|
430 |
|
static void |
431 |
|
load_charset_map_from_vector (charset, vec, control_flag) |
432 |
|
struct charset *charset; |
433 |
|
Lisp_Object vec; |
434 |
|
int control_flag; |
435 |
|
{ |
436 |
|
unsigned min_code = CHARSET_MIN_CODE (charset); |
437 |
|
unsigned max_code = CHARSET_MAX_CODE (charset); |
438 |
|
struct charset_map_entries *head, *entries; |
439 |
|
int n_entries; |
440 |
|
int len = ASIZE (vec); |
441 |
|
int i; |
442 |
|
|
443 |
|
if (len % 2 == 1) |
444 |
{ |
{ |
445 |
if ((i % 0x10000) == 0) |
add_to_log ("Failure in loading charset map: %V", vec, Qnil); |
446 |
numbers = numbers_table[i / 0x10000]; |
return; |
|
ASET (vec, i, make_number (*numbers)); |
|
447 |
} |
} |
448 |
|
|
449 |
charset_map_loaded = 1; |
head = entries = ((struct charset_map_entries *) |
450 |
|
alloca (sizeof (struct charset_map_entries))); |
451 |
|
n_entries = 0; |
452 |
|
for (i = 0; i < len; i += 2) |
453 |
|
{ |
454 |
|
Lisp_Object val, val2; |
455 |
|
unsigned from, to; |
456 |
|
int c; |
457 |
|
int idx; |
458 |
|
|
459 |
return vec; |
val = AREF (vec, i); |
460 |
|
if (CONSP (val)) |
461 |
|
{ |
462 |
|
val2 = XCDR (val); |
463 |
|
val = XCAR (val); |
464 |
|
CHECK_NATNUM (val); |
465 |
|
CHECK_NATNUM (val2); |
466 |
|
from = XFASTINT (val); |
467 |
|
to = XFASTINT (val2); |
468 |
|
} |
469 |
|
else |
470 |
|
{ |
471 |
|
CHECK_NATNUM (val); |
472 |
|
from = to = XFASTINT (val); |
473 |
|
} |
474 |
|
val = AREF (vec, i + 1); |
475 |
|
CHECK_NATNUM (val); |
476 |
|
c = XFASTINT (val); |
477 |
|
|
478 |
|
if (from < min_code || to > max_code || from > to || c > MAX_CHAR) |
479 |
|
continue; |
480 |
|
|
481 |
|
if ((n_entries % 0x10000) == 0) |
482 |
|
{ |
483 |
|
entries->next = ((struct charset_map_entries *) |
484 |
|
alloca (sizeof (struct charset_map_entries))); |
485 |
|
entries = entries->next; |
486 |
|
} |
487 |
|
idx = n_entries % 0x10000; |
488 |
|
entries->entry[idx].from = from; |
489 |
|
entries->entry[idx].to = to; |
490 |
|
entries->entry[idx].c = c; |
491 |
|
n_entries++; |
492 |
|
} |
493 |
|
|
494 |
|
load_charset_map (charset, head, n_entries, control_flag); |
495 |
} |
} |
496 |
|
|
497 |
static void |
static void |
504 |
|
|
505 |
map = CHARSET_MAP (charset); |
map = CHARSET_MAP (charset); |
506 |
if (STRINGP (map)) |
if (STRINGP (map)) |
507 |
map = load_charset_map (charset, map); |
load_charset_map_from_file (charset, map, 1); |
508 |
parse_charset_map (charset, map, 1); |
else |
509 |
|
load_charset_map_from_vector (charset, map, 1); |
510 |
CHARSET_METHOD (charset) = CHARSET_METHOD_MAP; |
CHARSET_METHOD (charset) = CHARSET_METHOD_MAP; |
511 |
} |
} |
512 |
} |
} |
713 |
| (charset.code_space[9] << 16) |
| (charset.code_space[9] << 16) |
714 |
| (charset.code_space[13] << 24)); |
| (charset.code_space[13] << 24)); |
715 |
|
|
716 |
|
charset.compact_codes_p = charset.max_code < 0x1000000; |
717 |
|
|
718 |
val = args[charset_arg_invalid_code]; |
val = args[charset_arg_invalid_code]; |
719 |
if (NILP (val)) |
if (NILP (val)) |
720 |
{ |
{ |
802 |
val = args[charset_arg_map]; |
val = args[charset_arg_map]; |
803 |
ASET (attrs, charset_map, val); |
ASET (attrs, charset_map, val); |
804 |
if (STRINGP (val)) |
if (STRINGP (val)) |
805 |
val = load_charset_map (&charset, val); |
load_charset_map_from_file (&charset, val, 0); |
806 |
CHECK_VECTOR (val); |
else |
807 |
parse_charset_map (&charset, val, 0); |
load_charset_map_from_vector (&charset, val, 0); |
808 |
charset.method = CHARSET_METHOD_MAP_DEFERRED; |
charset.method = CHARSET_METHOD_MAP_DEFERRED; |
809 |
} |
} |
810 |
else if (! NILP (args[charset_arg_parents])) |
else if (! NILP (args[charset_arg_parents])) |
995 |
if (NILP (unify_map)) |
if (NILP (unify_map)) |
996 |
unify_map = CHARSET_UNIFY_MAP (cs); |
unify_map = CHARSET_UNIFY_MAP (cs); |
997 |
if (STRINGP (unify_map)) |
if (STRINGP (unify_map)) |
998 |
unify_map = load_charset_map (cs, unify_map); |
load_charset_map_from_file (cs, unify_map, 2); |
999 |
parse_charset_map (cs, unify_map, 2); |
else |
1000 |
|
load_charset_map_from_vector (cs, unify_map, 2); |
1001 |
CHARSET_UNIFIED_P (cs) = 1; |
CHARSET_UNIFIED_P (cs) = 1; |
1002 |
return Qnil; |
return Qnil; |
1003 |
} |
} |
1372 |
if (! CHAR_TABLE_P (CHARSET_ENCODER (charset))) |
if (! CHAR_TABLE_P (CHARSET_ENCODER (charset))) |
1373 |
return CHARSET_INVALID_CODE (charset); |
return CHARSET_INVALID_CODE (charset); |
1374 |
val = CHAR_TABLE_REF (encoder, c); |
val = CHAR_TABLE_REF (encoder, c); |
1375 |
if (CONSP (val)) |
code = XINT (val); |
1376 |
code = (XINT (XCAR (val)) << 16) | XINT (XCDR (val)); |
if (! CHARSET_COMPACT_CODES_P (charset)) |
1377 |
else |
code = INDEX_TO_CODE_POINT (charset, code); |
|
code = XINT (val); |
|
1378 |
} |
} |
1379 |
else |
else |
1380 |
{ |
{ |