Mercurial > hg > xemacs-beta
comparison src/file-coding.c @ 4303:cee827542370
[xemacs-hg @ 2007-12-04 20:18:33 by aidan]
Implement coding system autoloads; use them for the variable-length ISO 2022
Latin coding systems.
author | aidan |
---|---|
date | Tue, 04 Dec 2007 20:18:43 +0000 |
parents | d1cf2b9c4dfd |
children | 383ab474a241 1d74a1d115ee |
comparison
equal
deleted
inserted
replaced
4302:2f5ccbd44293 | 4303:cee827542370 |
---|---|
226 Lisp_Object Qdo_eol, Qdo_coding; | 226 Lisp_Object Qdo_eol, Qdo_coding; |
227 | 227 |
228 Lisp_Object Qcanonicalize_after_coding; | 228 Lisp_Object Qcanonicalize_after_coding; |
229 | 229 |
230 Lisp_Object QScoding_system_cookie; | 230 Lisp_Object QScoding_system_cookie; |
231 | |
232 Lisp_Object Qposix_charset_to_coding_system_hash; | |
231 | 233 |
232 /* This is used to convert autodetected coding systems into existing | 234 /* This is used to convert autodetected coding systems into existing |
233 systems. For example, the chain undecided->convert-eol-autodetect may | 235 systems. For example, the chain undecided->convert-eol-autodetect may |
234 have its separate parts detected as mswindows-multibyte and | 236 have its separate parts detected as mswindows-multibyte and |
235 convert-eol-crlf, and the result needs to be mapped to | 237 convert-eol-crlf, and the result needs to be mapped to |
467 (object)) | 469 (object)) |
468 { | 470 { |
469 return CODING_SYSTEMP (object) ? Qt : Qnil; | 471 return CODING_SYSTEMP (object) ? Qt : Qnil; |
470 } | 472 } |
471 | 473 |
474 static Lisp_Object | |
475 find_coding_system (Lisp_Object coding_system_or_name, | |
476 int do_autoloads) | |
477 { | |
478 Lisp_Object lookup; | |
479 | |
480 if (NILP (coding_system_or_name)) | |
481 coding_system_or_name = Qbinary; | |
482 else if (CODING_SYSTEMP (coding_system_or_name)) | |
483 return coding_system_or_name; | |
484 else | |
485 CHECK_SYMBOL (coding_system_or_name); | |
486 | |
487 while (1) | |
488 { | |
489 lookup = | |
490 Fgethash (coding_system_or_name, Vcoding_system_hash_table, Qnil); | |
491 | |
492 if (CONSP (lookup) && do_autoloads) | |
493 { | |
494 struct gcpro gcpro1; | |
495 int length; | |
496 DECLARE_EISTRING (desired_base); | |
497 DECLARE_EISTRING (warning_info); | |
498 | |
499 eicpy_lstr (desired_base, XSYMBOL_NAME (coding_system_or_name)); | |
500 | |
501 /* Work out the name of the base coding system. */ | |
502 length = eilen (desired_base); | |
503 if (length > (int)(sizeof ("-unix") - 1)) | |
504 { | |
505 if (0 == qxestrcmp ((UAscbyte *)"-unix", (eidata (desired_base)) | |
506 + (length - (sizeof ("-unix") - 1)))) | |
507 { | |
508 eidel (desired_base, length - (sizeof ("-unix") - 1), | |
509 -1, 5, 5); | |
510 } | |
511 } | |
512 else if (length > (int)(sizeof ("-dos") - 1)) | |
513 { | |
514 if ((0 == qxestrcmp ((UAscbyte *)"-dos", (eidata (desired_base)) | |
515 + (length - (sizeof ("-dos") - 1)))) || | |
516 (0 == qxestrcmp ((UAscbyte *)"-mac", (eidata (desired_base)) | |
517 + (length - (sizeof ("-mac") - 1))))) | |
518 { | |
519 eidel (desired_base, length - (sizeof ("-dos") - 1), -1, | |
520 4, 4); | |
521 } | |
522 } | |
523 | |
524 coding_system_or_name = intern_int (eidata (desired_base)); | |
525 | |
526 /* Remove this coding system and its subsidiary coding | |
527 systems from the hash, to avoid calling this code recursively. */ | |
528 Fremhash (coding_system_or_name, Vcoding_system_hash_table); | |
529 Fremhash (add_suffix_to_symbol(coding_system_or_name, "-unix"), | |
530 Vcoding_system_hash_table); | |
531 Fremhash (add_suffix_to_symbol(coding_system_or_name, "-dos"), | |
532 Vcoding_system_hash_table); | |
533 Fremhash (add_suffix_to_symbol(coding_system_or_name, "-mac"), | |
534 Vcoding_system_hash_table); | |
535 | |
536 eicpy_ascii (warning_info, "Error autoloading coding system "); | |
537 eicat_lstr (warning_info, XSYMBOL_NAME (coding_system_or_name)); | |
538 | |
539 /* Keep around the form so it doesn't disappear from under | |
540 #'eval's feet. */ | |
541 GCPRO1 (lookup); | |
542 call1_trapping_problems ((const CIbyte *)eidata (warning_info), | |
543 Qeval, lookup, 0); | |
544 UNGCPRO; | |
545 | |
546 lookup = | |
547 Fgethash (coding_system_or_name, Vcoding_system_hash_table, Qnil); | |
548 } | |
549 | |
550 if (CODING_SYSTEMP (lookup) || NILP (lookup)) | |
551 return lookup; | |
552 | |
553 coding_system_or_name = lookup; | |
554 } | |
555 } | |
556 | |
472 DEFUN ("find-coding-system", Ffind_coding_system, 1, 1, 0, /* | 557 DEFUN ("find-coding-system", Ffind_coding_system, 1, 1, 0, /* |
473 Retrieve the coding system of the given name. | 558 Retrieve the coding system of the given name. |
474 | 559 |
475 If CODING-SYSTEM-OR-NAME is a coding-system object, it is simply | 560 If CODING-SYSTEM-OR-NAME is a coding-system object, it is simply |
476 returned. Otherwise, CODING-SYSTEM-OR-NAME should be a symbol. | 561 returned. Otherwise, CODING-SYSTEM-OR-NAME should be a symbol. |
477 If there is no such coding system, nil is returned. Otherwise the | 562 If there is no such coding system, nil is returned. Otherwise the |
478 associated coding system object is returned. | 563 associated coding system object is returned. |
479 */ | 564 */ |
480 (coding_system_or_name)) | 565 (coding_system_or_name)) |
481 { | 566 { |
482 if (NILP (coding_system_or_name)) | 567 return find_coding_system(coding_system_or_name, 1); |
483 coding_system_or_name = Qbinary; | 568 } |
484 else if (CODING_SYSTEMP (coding_system_or_name)) | 569 |
485 return coding_system_or_name; | 570 DEFUN ("autoload-coding-system", Fautoload_coding_system, 2, 2, 0, /* |
486 else | 571 Define SYMBOL as a coding-system that is loaded on demand. |
487 CHECK_SYMBOL (coding_system_or_name); | 572 |
488 | 573 FORM is a form to evaluate to define the coding-system. |
489 while (1) | 574 */ |
490 { | 575 (symbol, form)) |
491 coding_system_or_name = | 576 { |
492 Fgethash (coding_system_or_name, Vcoding_system_hash_table, Qnil); | 577 Lisp_Object lookup; |
493 | 578 |
494 if (CODING_SYSTEMP (coding_system_or_name) | 579 CHECK_SYMBOL (symbol); |
495 || NILP (coding_system_or_name)) | 580 CHECK_CONS (form); |
496 return coding_system_or_name; | 581 |
497 } | 582 lookup = find_coding_system (symbol, 0); |
583 | |
584 if (!NILP (lookup) && | |
585 /* Allow autoloads to be redefined. */ | |
586 !CONSP (lookup)) | |
587 { | |
588 invalid_operation ("Cannot redefine existing coding system", | |
589 symbol); | |
590 } | |
591 | |
592 Fputhash (symbol, form, Vcoding_system_hash_table); | |
593 Fputhash (add_suffix_to_symbol(symbol, "-unix"), form, | |
594 Vcoding_system_hash_table); | |
595 Fputhash (add_suffix_to_symbol(symbol, "-dos"), form, | |
596 Vcoding_system_hash_table); | |
597 Fputhash (add_suffix_to_symbol(symbol, "-mac"), form, | |
598 Vcoding_system_hash_table); | |
599 | |
600 /* Tell the POSIX locale infrastructure about this coding system (though | |
601 unfortunately it'll be too late for the startup locale sniffing. */ | |
602 if (!UNBOUNDP (Qposix_charset_to_coding_system_hash)) | |
603 { | |
604 Lisp_Object val = Fsymbol_value (Qposix_charset_to_coding_system_hash); | |
605 DECLARE_EISTRING (minimal_name); | |
606 Ibyte *full_name; | |
607 int len = XSTRING_LENGTH (XSYMBOL_NAME (symbol)), i; | |
608 | |
609 if (!NILP (val)) | |
610 { | |
611 full_name = XSTRING_DATA (XSYMBOL_NAME (symbol)); | |
612 for (i = 0; i < len; ++i) | |
613 { | |
614 if (full_name[i] >= '0' && full_name[i] <= '9') | |
615 { | |
616 eicat_ch (minimal_name, full_name[i]); | |
617 } | |
618 else if (full_name[i] >= 'a' && full_name[i] <= 'z') | |
619 { | |
620 eicat_ch (minimal_name, full_name[i]); | |
621 } | |
622 else if (full_name[i] >= 'A' && full_name[i] <= 'Z') | |
623 { | |
624 eicat_ch (minimal_name, full_name[i] + | |
625 ('a' - 'A')); | |
626 } | |
627 } | |
628 | |
629 if (eilen (minimal_name)) | |
630 { | |
631 CHECK_HASH_TABLE (val); | |
632 Fputhash (eimake_string(minimal_name), symbol, val); | |
633 } | |
634 } | |
635 } | |
636 | |
637 return Qt; | |
498 } | 638 } |
499 | 639 |
500 DEFUN ("get-coding-system", Fget_coding_system, 1, 1, 0, /* | 640 DEFUN ("get-coding-system", Fget_coding_system, 1, 1, 0, /* |
501 Retrieve the coding system of the given name. | 641 Retrieve the coding system of the given name. |
502 Same as `find-coding-system' except that if there is no such | 642 Same as `find-coding-system' except that if there is no such |
649 int normal; | 789 int normal; |
650 int internal; | 790 int internal; |
651 }; | 791 }; |
652 | 792 |
653 static int | 793 static int |
654 add_coding_system_to_list_mapper (Lisp_Object key, Lisp_Object UNUSED (value), | 794 add_coding_system_to_list_mapper (Lisp_Object key, Lisp_Object value, |
655 void *coding_system_list_closure) | 795 void *coding_system_list_closure) |
656 { | 796 { |
657 /* This function can GC */ | 797 /* This function can GC */ |
658 struct coding_system_list_closure *cscl = | 798 struct coding_system_list_closure *cscl = |
659 (struct coding_system_list_closure *) coding_system_list_closure; | 799 (struct coding_system_list_closure *) coding_system_list_closure; |
660 Lisp_Object *coding_system_list = cscl->coding_system_list; | 800 Lisp_Object *coding_system_list = cscl->coding_system_list; |
661 | 801 |
662 /* We can't just use VALUE because KEY might be an alias, and we need | 802 /* We can't just use VALUE because KEY might be an alias, and we need |
663 the real coding system object. */ | 803 the real coding system object. |
664 if (XCODING_SYSTEM (Ffind_coding_system (key))->internal_p ? | 804 |
665 cscl->internal : cscl->normal) | 805 Autoloaded coding systems have conses for their values, and can't be |
806 internal coding systems, or coding system aliases. */ | |
807 if (CONSP (value) || | |
808 (XCODING_SYSTEM (Ffind_coding_system (key))->internal_p ? | |
809 cscl->internal : cscl->normal)) | |
666 *coding_system_list = Fcons (key, *coding_system_list); | 810 *coding_system_list = Fcons (key, *coding_system_list); |
667 return 0; | 811 return 0; |
668 } | 812 } |
669 | 813 |
670 /* #### should we specify a conventional for "all coding systems"? */ | 814 /* #### should we specify a conventional for "all coding systems"? */ |
919 xfree (newname, Ibyte *); | 1063 xfree (newname, Ibyte *); |
920 } | 1064 } |
921 else | 1065 else |
922 CHECK_SYMBOL (name_or_existing); | 1066 CHECK_SYMBOL (name_or_existing); |
923 | 1067 |
924 if (!NILP (Ffind_coding_system (name_or_existing))) | 1068 /* See is there an entry for name_or_existing in the defined coding system |
1069 hash table. */ | |
1070 csobj = find_coding_system (name_or_existing, 0); | |
1071 /* Error if it's there and not an autoload form. */ | |
1072 if (!NILP (csobj) && !CONSP (csobj)) | |
925 invalid_operation ("Cannot redefine existing coding system", | 1073 invalid_operation ("Cannot redefine existing coding system", |
926 name_or_existing); | 1074 name_or_existing); |
927 | 1075 |
928 cs = allocate_coding_system (meths, meths->extra_data_size, | 1076 cs = allocate_coding_system (meths, meths->extra_data_size, |
929 name_or_existing); | 1077 name_or_existing); |
930 csobj = wrap_coding_system (cs); | 1078 csobj = wrap_coding_system (cs); |
931 | 1079 |
996 { | 1144 { |
997 XCODING_SYSTEM_CANONICAL (csobj) = | 1145 XCODING_SYSTEM_CANONICAL (csobj) = |
998 CODESYSMETH_OR_GIVEN (cs, canonicalize, (csobj), Qnil); | 1146 CODESYSMETH_OR_GIVEN (cs, canonicalize, (csobj), Qnil); |
999 XCODING_SYSTEM_EOL_TYPE (csobj) = EOL_AUTODETECT; /* for copy-coding-system | 1147 XCODING_SYSTEM_EOL_TYPE (csobj) = EOL_AUTODETECT; /* for copy-coding-system |
1000 below */ | 1148 below */ |
1149 | |
1150 Fputhash (name_or_existing, csobj, Vcoding_system_hash_table); | |
1001 | 1151 |
1002 if (need_to_setup_eol_systems && !cs->internal_p) | 1152 if (need_to_setup_eol_systems && !cs->internal_p) |
1003 setup_eol_coding_systems (csobj); | 1153 setup_eol_coding_systems (csobj); |
1004 else if (eol_wrapper == EOL_CR || eol_wrapper == EOL_CRLF) | 1154 else if (eol_wrapper == EOL_CR || eol_wrapper == EOL_CRLF) |
1005 { | 1155 { |
1035 Qcanonicalize_after_coding, | 1185 Qcanonicalize_after_coding, |
1036 csobj)); | 1186 csobj)); |
1037 } | 1187 } |
1038 XCODING_SYSTEM_EOL_TYPE (csobj) = eol_wrapper; | 1188 XCODING_SYSTEM_EOL_TYPE (csobj) = eol_wrapper; |
1039 } | 1189 } |
1040 | |
1041 Fputhash (name_or_existing, csobj, Vcoding_system_hash_table); | |
1042 | 1190 |
1043 return csobj; | 1191 return csobj; |
1044 } | 1192 } |
1045 | 1193 |
1046 Lisp_Object | 1194 Lisp_Object |
1394 (old_coding_system, new_name)) | 1542 (old_coding_system, new_name)) |
1395 { | 1543 { |
1396 Lisp_Object new_coding_system; | 1544 Lisp_Object new_coding_system; |
1397 old_coding_system = Fget_coding_system (old_coding_system); | 1545 old_coding_system = Fget_coding_system (old_coding_system); |
1398 new_coding_system = | 1546 new_coding_system = |
1399 UNBOUNDP (new_name) ? Qnil : Ffind_coding_system (new_name); | 1547 UNBOUNDP (new_name) ? Qnil : find_coding_system (new_name, 0); |
1400 if (NILP (new_coding_system)) | 1548 if (NILP (new_coding_system)) |
1401 { | 1549 { |
1402 new_coding_system = | 1550 new_coding_system = |
1403 wrap_coding_system | 1551 wrap_coding_system |
1404 (allocate_coding_system | 1552 (allocate_coding_system |
4384 INIT_LRECORD_IMPLEMENTATION (coding_system); | 4532 INIT_LRECORD_IMPLEMENTATION (coding_system); |
4385 | 4533 |
4386 DEFSUBR (Fvalid_coding_system_type_p); | 4534 DEFSUBR (Fvalid_coding_system_type_p); |
4387 DEFSUBR (Fcoding_system_type_list); | 4535 DEFSUBR (Fcoding_system_type_list); |
4388 DEFSUBR (Fcoding_system_p); | 4536 DEFSUBR (Fcoding_system_p); |
4537 DEFSUBR (Fautoload_coding_system); | |
4389 DEFSUBR (Ffind_coding_system); | 4538 DEFSUBR (Ffind_coding_system); |
4390 DEFSUBR (Fget_coding_system); | 4539 DEFSUBR (Fget_coding_system); |
4391 DEFSUBR (Fcoding_system_list); | 4540 DEFSUBR (Fcoding_system_list); |
4392 DEFSUBR (Fcoding_system_name); | 4541 DEFSUBR (Fcoding_system_name); |
4393 DEFSUBR (Fmake_coding_system); | 4542 DEFSUBR (Fmake_coding_system); |
4454 | 4603 |
4455 DEFSYMBOL (Qdo_eol); | 4604 DEFSYMBOL (Qdo_eol); |
4456 DEFSYMBOL (Qdo_coding); | 4605 DEFSYMBOL (Qdo_coding); |
4457 | 4606 |
4458 DEFSYMBOL (Qcanonicalize_after_coding); | 4607 DEFSYMBOL (Qcanonicalize_after_coding); |
4608 | |
4609 DEFSYMBOL (Qposix_charset_to_coding_system_hash); | |
4459 | 4610 |
4460 DEFSYMBOL (Qescape_quoted); | 4611 DEFSYMBOL (Qescape_quoted); |
4461 | 4612 |
4462 #ifdef HAVE_ZLIB | 4613 #ifdef HAVE_ZLIB |
4463 DEFSYMBOL (Qgzip); | 4614 DEFSYMBOL (Qgzip); |