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);