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 {