Mercurial > hg > xemacs-beta
comparison src/mule-ccl.c @ 278:90d73dddcdc4 r21-0b37
Import from CVS: tag r21-0b37
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:31:29 +0200 |
parents | 6330739388db |
children | 7c94d56991e1 |
comparison
equal
deleted
inserted
replaced
277:cfdf3ff11843 | 278:90d73dddcdc4 |
---|---|
434 buffer or full output buffer. */ | 434 buffer or full output buffer. */ |
435 #define CCL_STAT_INVALID_CMD 2 /* Terminated because of invalid | 435 #define CCL_STAT_INVALID_CMD 2 /* Terminated because of invalid |
436 command. */ | 436 command. */ |
437 #define CCL_STAT_QUIT 3 /* Terminated because of quit. */ | 437 #define CCL_STAT_QUIT 3 /* Terminated because of quit. */ |
438 | 438 |
439 /* Terminate CCL program successfully. */ | |
440 #define CCL_SUCCESS \ | |
441 do { \ | |
442 ccl->status = CCL_STAT_SUCCESS; \ | |
443 ccl->ic = CCL_HEADER_MAIN; \ | |
444 goto ccl_finish; \ | |
445 } while (0) | |
446 | |
447 /* Suspend CCL program because of reading from empty input buffer or | |
448 writing to full output buffer. When this program is resumed, the | |
449 same I/O command is executed. */ | |
450 #define CCL_SUSPEND \ | |
451 do { \ | |
452 ic--; \ | |
453 ccl->status = CCL_STAT_SUSPEND; \ | |
454 goto ccl_finish; \ | |
455 } while (0) | |
456 | |
457 /* Terminate CCL program because of invalid command. Should not occur | |
458 in the normal case. */ | |
459 #define CCL_INVALID_CMD \ | |
460 do { \ | |
461 ccl->status = CCL_STAT_INVALID_CMD; \ | |
462 goto ccl_error_handler; \ | |
463 } while (0) | |
464 | |
465 /* Encode one character CH to multibyte form and write to the current | 439 /* Encode one character CH to multibyte form and write to the current |
466 output buffer. If CH is less than 256, CH is written as is. */ | 440 output buffer. If CH is less than 256, CH is written as is. */ |
467 #define CCL_WRITE_CHAR(ch) \ | 441 #define CCL_WRITE_CHAR(ch) do { \ |
468 do { \ | 442 if (!destination) \ |
469 if (!destination) \ | 443 { \ |
470 CCL_INVALID_CMD; \ | 444 ccl->status = CCL_STAT_INVALID_CMD; \ |
471 else \ | 445 goto ccl_error_handler; \ |
472 { \ | 446 } \ |
473 Bufbyte work[MAX_EMCHAR_LEN]; \ | 447 else \ |
474 int len = ( ch < 256 ) ? \ | 448 { \ |
475 simple_set_charptr_emchar (work, ch) : \ | 449 Bufbyte work[MAX_EMCHAR_LEN]; \ |
476 non_ascii_set_charptr_emchar (work, ch); \ | 450 int len = ( ch < 256 ) ? \ |
477 Dynarr_add_many (destination, work, len); \ | 451 simple_set_charptr_emchar (work, ch) : \ |
478 } \ | 452 non_ascii_set_charptr_emchar (work, ch); \ |
479 } while (0) | 453 Dynarr_add_many (destination, work, len); \ |
454 } \ | |
455 } while (0) | |
480 | 456 |
481 /* Write a string at ccl_prog[IC] of length LEN to the current output | 457 /* Write a string at ccl_prog[IC] of length LEN to the current output |
482 buffer. */ | 458 buffer. */ |
483 #define CCL_WRITE_STRING(len) \ | 459 #define CCL_WRITE_STRING(len) do { \ |
484 do { \ | 460 if (!destination) \ |
485 if (!destination) \ | 461 { \ |
486 CCL_INVALID_CMD; \ | 462 ccl->status = CCL_STAT_INVALID_CMD; \ |
487 else \ | 463 goto ccl_error_handler; \ |
488 for (i = 0; i < len; i++) \ | 464 } \ |
489 Dynarr_add(destination, (XINT (ccl_prog[ic + (i / 3)]) \ | 465 else \ |
490 >> ((2 - (i % 3)) * 8)) & 0xFF); \ | 466 for (i = 0; i < len; i++) \ |
491 } while (0) | 467 Dynarr_add(destination, \ |
468 (XINT (ccl_prog[ic + (i / 3)]) \ | |
469 >> ((2 - (i % 3)) * 8)) & 0xFF); \ | |
470 } while (0) | |
492 | 471 |
493 /* Read one byte from the current input buffer into Rth register. */ | 472 /* Read one byte from the current input buffer into Rth register. */ |
494 #define CCL_READ_CHAR(r) \ | 473 #define CCL_READ_CHAR(r) do { \ |
495 do { \ | 474 if (!src) \ |
496 if (!src) \ | 475 { \ |
497 CCL_INVALID_CMD; \ | 476 ccl->status = CCL_STAT_INVALID_CMD; \ |
498 else if (src < src_end) \ | 477 goto ccl_error_handler; \ |
499 r = *src++; \ | 478 } \ |
500 else if (ccl->last_block) \ | 479 else if (src < src_end) \ |
501 { \ | 480 r = *src++; \ |
502 ic = ccl->eof_ic; \ | 481 else if (ccl->last_block) \ |
503 goto ccl_finish; \ | 482 { \ |
504 } \ | 483 ic = ccl->eof_ic; \ |
505 else \ | 484 goto ccl_finish; \ |
506 CCL_SUSPEND; \ | 485 } \ |
507 } while (0) | 486 else \ |
487 /* Suspend CCL program because of \ | |
488 reading from empty input buffer or \ | |
489 writing to full output buffer. \ | |
490 When this program is resumed, the \ | |
491 same I/O command is executed. */ \ | |
492 { \ | |
493 ic--; \ | |
494 ccl->status = CCL_STAT_SUSPEND; \ | |
495 goto ccl_finish; \ | |
496 } \ | |
497 } while (0) | |
508 | 498 |
509 | 499 |
510 /* Execute CCL code on SRC_BYTES length text at SOURCE. The resulting | 500 /* Execute CCL code on SRC_BYTES length text at SOURCE. The resulting |
511 text goes to a place pointed by DESTINATION. The bytes actually | 501 text goes to a place pointed by DESTINATION. The bytes actually |
512 processed is returned as *CONSUMED. The return value is the length | 502 processed is returned as *CONSUMED. The return value is the length |
725 if (stack_idx > 0) | 715 if (stack_idx > 0) |
726 { | 716 { |
727 ccl_prog = ccl_prog_stack_struct[0].ccl_prog; | 717 ccl_prog = ccl_prog_stack_struct[0].ccl_prog; |
728 ic = ccl_prog_stack_struct[0].ic; | 718 ic = ccl_prog_stack_struct[0].ic; |
729 } | 719 } |
730 CCL_INVALID_CMD; | 720 ccl->status = CCL_STAT_INVALID_CMD; |
721 goto ccl_error_handler; | |
731 } | 722 } |
732 | 723 |
733 ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; | 724 ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; |
734 ccl_prog_stack_struct[stack_idx].ic = ic; | 725 ccl_prog_stack_struct[stack_idx].ic = ic; |
735 stack_idx++; | 726 stack_idx++; |
763 { | 754 { |
764 ccl_prog = ccl_prog_stack_struct[stack_idx].ccl_prog; | 755 ccl_prog = ccl_prog_stack_struct[stack_idx].ccl_prog; |
765 ic = ccl_prog_stack_struct[stack_idx].ic; | 756 ic = ccl_prog_stack_struct[stack_idx].ic; |
766 break; | 757 break; |
767 } | 758 } |
768 CCL_SUCCESS; | 759 /* Terminate CCL program successfully. */ |
760 ccl->status = CCL_STAT_SUCCESS; | |
761 ccl->ic = CCL_HEADER_MAIN; | |
762 goto ccl_finish; | |
769 | 763 |
770 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ | 764 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ |
771 i = XINT (ccl_prog[ic]); | 765 i = XINT (ccl_prog[ic]); |
772 ic++; | 766 ic++; |
773 op = field1 >> 6; | 767 op = field1 >> 6; |
797 case CCL_GT: reg[rrr] = reg[rrr] > i; break; | 791 case CCL_GT: reg[rrr] = reg[rrr] > i; break; |
798 case CCL_EQ: reg[rrr] = reg[rrr] == i; break; | 792 case CCL_EQ: reg[rrr] = reg[rrr] == i; break; |
799 case CCL_LE: reg[rrr] = reg[rrr] <= i; break; | 793 case CCL_LE: reg[rrr] = reg[rrr] <= i; break; |
800 case CCL_GE: reg[rrr] = reg[rrr] >= i; break; | 794 case CCL_GE: reg[rrr] = reg[rrr] >= i; break; |
801 case CCL_NE: reg[rrr] = reg[rrr] != i; break; | 795 case CCL_NE: reg[rrr] = reg[rrr] != i; break; |
802 default: CCL_INVALID_CMD; | 796 default: |
797 ccl->status = CCL_STAT_INVALID_CMD; | |
798 goto ccl_error_handler; | |
803 } | 799 } |
804 break; | 800 break; |
805 | 801 |
806 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ | 802 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ |
807 i = reg[RRR]; | 803 i = reg[RRR]; |
860 case CCL_LE: reg[rrr] = i <= j; break; | 856 case CCL_LE: reg[rrr] = i <= j; break; |
861 case CCL_GE: reg[rrr] = i >= j; break; | 857 case CCL_GE: reg[rrr] = i >= j; break; |
862 case CCL_NE: reg[rrr] = i != j; break; | 858 case CCL_NE: reg[rrr] = i != j; break; |
863 case CCL_ENCODE_SJIS: ENCODE_SJIS (i, j, reg[rrr], reg[7]); break; | 859 case CCL_ENCODE_SJIS: ENCODE_SJIS (i, j, reg[rrr], reg[7]); break; |
864 case CCL_DECODE_SJIS: DECODE_SJIS (i, j, reg[rrr], reg[7]); break; | 860 case CCL_DECODE_SJIS: DECODE_SJIS (i, j, reg[rrr], reg[7]); break; |
865 default: CCL_INVALID_CMD; | 861 default: |
862 ccl->status = CCL_STAT_INVALID_CMD; | |
863 goto ccl_error_handler; | |
866 } | 864 } |
867 code &= 0x1F; | 865 code &= 0x1F; |
868 if (code == CCL_WriteExprConst || code == CCL_WriteExprRegister) | 866 if (code == CCL_WriteExprConst || code == CCL_WriteExprRegister) |
869 { | 867 { |
870 i = reg[rrr]; | 868 i = reg[rrr]; |
873 else if (!reg[rrr]) | 871 else if (!reg[rrr]) |
874 ic = jump_address; | 872 ic = jump_address; |
875 break; | 873 break; |
876 | 874 |
877 default: | 875 default: |
878 CCL_INVALID_CMD; | 876 ccl->status = CCL_STAT_INVALID_CMD; |
877 goto ccl_error_handler; | |
879 } | 878 } |
880 } | 879 } |
881 | 880 |
882 ccl_error_handler: | 881 ccl_error_handler: |
883 if (destination) | 882 if (destination) |
887 there. */ | 886 there. */ |
888 char msg[256]; | 887 char msg[256]; |
889 | 888 |
890 switch (ccl->status) | 889 switch (ccl->status) |
891 { | 890 { |
891 /* Terminate CCL program because of invalid command. | |
892 Should not occur in the normal case. */ | |
892 case CCL_STAT_INVALID_CMD: | 893 case CCL_STAT_INVALID_CMD: |
893 sprintf(msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", | 894 sprintf(msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", |
894 code & 0x1F, code, ic); | 895 code & 0x1F, code, ic); |
895 #ifdef CCL_DEBUG | 896 #ifdef CCL_DEBUG |
896 { | 897 { |