lcGenConv.c revision 556b6652
1/* 2 * Copyright 1992, 1993 by TOSHIBA Corp. 3 * 4 * Permission to use, copy, modify, and distribute this software and its 5 * documentation for any purpose and without fee is hereby granted, provided 6 * that the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of TOSHIBA not be used in advertising 9 * or publicity pertaining to distribution of the software without specific, 10 * written prior permission. TOSHIBA make no representations about the 11 * suitability of this software for any purpose. It is provided "as is" 12 * without express or implied warranty. 13 * 14 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 * SOFTWARE. 21 * 22 * Author: Katsuhisa Yano TOSHIBA Corp. 23 * mopi@osa.ilab.toshiba.co.jp 24 */ 25/* 26 * (c) Copyright 1995 FUJITSU LIMITED 27 * This is source code modified by FUJITSU LIMITED under the Joint 28 * Development Agreement for the CDE/Motif PST. 29 * 30 * Modifier: Masayoshi Shimamura FUJITSU LIMITED 31 * 32 */ 33/* 34 * 2000 35 * Modifier: Ivan Pascal The XFree86 Project 36 */ 37 38/* 39 * A generic locale loader for all kinds of ISO-2022 based codesets. 40 * Supports: all locales. 41 * How: Provides generic converters for ISO-2022 based codesets. Extensible as 42 * far as ISO-2022 is extensible: codesets can be given by name in the 43 * stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff). 44 * In every chunk between escape sequences, the number of bytes per 45 * character (char_size) is constant. 46 * Platforms: all systems. 47 */ 48 49#ifdef HAVE_CONFIG_H 50#include <config.h> 51#endif 52#include "Xlibint.h" 53#include "XlcGeneric.h" 54#include <stdio.h> 55 56#if !defined(Lynx_22) && !defined(X_LOCALE) 57#define STDCVT 58#endif 59 60typedef struct _CTDataRec { 61 const char *name; 62 const char *encoding; /* Compound Text encoding */ 63} CTDataRec, *CTData; 64 65static CTDataRec directionality_data[] = 66{ 67 { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" }, 68 { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" }, 69 { "END_OF_STRING", "\233]" }, 70}; 71 72typedef struct _StateRec { 73 XLCd lcd; 74 /* CT state */ 75 XlcCharSet charset; /* charset of current state */ 76 XlcCharSet GL_charset; /* charset of initial state in GL */ 77 XlcCharSet GR_charset; /* charset of initial state in GR */ 78 /* MB shift state */ 79 CodeSet GL_codeset; 80 CodeSet GR_codeset; 81} StateRec, *State; 82 83#define GR 0x80 /* begins right-side (non-ascii) region */ 84#define GL 0x7f /* ends left-side (ascii) region */ 85#define ESC 0x1b 86#define CSI 0x9b 87#define STX 0x02 88 89#define isrightside(c) ((c) & GR) 90#define isleftside(c) (!isrightside(c)) 91 92/* Forward declarations for local routines. */ 93static int mbstocts (XlcConv conv, XPointer *from, int *from_left, 94 XPointer *to, int *to_left, XPointer *args, int num_args); 95static int ctstombs (XlcConv conv, XPointer *from, int *from_left, 96 XPointer *to, int *to_left, XPointer *args, int num_args); 97static int cstombs (XlcConv conv, XPointer *from, int *from_left, 98 XPointer *to, int *to_left, XPointer *args, int num_args); 99 100/* ------------------------------------------------------------------------- */ 101/* Misc */ 102/* ------------------------------------------------------------------------- */ 103 104static int 105compare( 106 const char *src, 107 const char *encoding, 108 int length) 109{ 110 const char *start = src; 111 112 while (length-- > 0) { 113 if (*src++ != *encoding++) 114 return 0; 115 if (*encoding == '\0') 116 return src - start; 117 } 118 119 return 0; 120} 121 122static unsigned long 123conv_to_dest( 124 Conversion conv, 125 unsigned long code) 126{ 127 int i; 128 int conv_num = conv->conv_num; 129 FontScope convlist = conv->convlist; 130 131 for (i = 0; i < conv_num; i++) { 132 if (convlist[i].start <= code && code <= convlist[i].end) { 133 switch (convlist[i].shift_direction) { 134 case '+': 135 return(code + convlist[i].shift); 136 case '-': 137 return(code - convlist[i].shift); 138 default: 139 return(code); 140 } 141 } 142 } 143 144 return(code); 145} 146 147static unsigned long 148conv_to_source( 149 Conversion conv, 150 unsigned long code) 151{ 152 int i; 153 int conv_num; 154 FontScope convlist; 155 unsigned long start_p; 156 unsigned long start_m; 157 unsigned long end_p; 158 unsigned long end_m; 159 160 if (!conv) 161 return(code); 162 163 conv_num = conv->conv_num; 164 convlist = conv->convlist; 165 166 for (i = 0; i < conv_num; i++) { 167 switch (convlist[i].shift_direction) { 168 case '+': 169 start_p = convlist[i].start + convlist[i].shift; 170 end_p = convlist[i].end + convlist[i].shift; 171 if (start_p <= code && code <= end_p) 172 return(code - convlist[i].shift); 173 break; 174 case '-': 175 start_m = convlist[i].start - convlist[i].shift; 176 end_m = convlist[i].end - convlist[i].shift; 177 if (start_m <= code && code <= end_m) 178 return(code + convlist[i].shift); 179 break; 180 default: 181 continue; 182 } 183 } 184 185 return(code); 186} 187 188static unsigned long 189mb_to_gi( 190 unsigned long mb, 191 CodeSet codeset) 192{ 193 int i; 194 unsigned long mb_tmp, mask = 0; 195 196 if (codeset->mbconv) { 197 mb_tmp = conv_to_dest(codeset->mbconv, mb); 198 if (mb_tmp != mb) 199 return(mb_tmp); 200 } 201 202 if (codeset->side == XlcC0 || codeset->side == XlcGL || 203 codeset->side == XlcC1 || codeset->side == XlcGR) { 204 205 for (i = 0; i < codeset->length; i++) 206 mask = (mask << 8) | GL; 207 mb = mb & mask; 208 } 209 210 return(mb); 211} 212 213static unsigned long 214gi_to_mb( 215 unsigned long glyph_index, 216 CodeSet codeset) 217{ 218 int i; 219 unsigned long mask = 0; 220 221 if (codeset->side == XlcC1 || codeset->side == XlcGR) { 222 for (i = 0; i < codeset->length; i++) 223 mask = (mask << 8) | GR; 224 glyph_index = glyph_index | mask; 225 } 226 227 if (codeset->mbconv) 228 return( conv_to_source(codeset->mbconv, glyph_index) ); 229 230 return(glyph_index); 231} 232 233static Bool 234gi_to_wc( 235 XLCd lcd, 236 unsigned long glyph_index, 237 CodeSet codeset, 238 wchar_t *wc) 239{ 240 unsigned char mask = 0; 241 unsigned long wc_encoding = codeset->wc_encoding; 242 int length = codeset->length; 243 unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); 244 245 mask = (1 << wc_shift_bits) - 1 ; 246 247 for (*wc = 0, length--; length >= 0; length--) 248 *wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask); 249 250 *wc = *wc | wc_encoding; 251 252 return(True); 253} 254 255static Bool 256wc_to_gi( 257 XLCd lcd, 258 wchar_t wc, 259 unsigned long *glyph_index, 260 CodeSet *codeset) 261{ 262 int i; 263 unsigned char mask = 0; 264 unsigned long wc_encoding; 265 unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask); 266 unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); 267 int codeset_num = XLC_GENERIC(lcd, codeset_num); 268 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 269 270 wc_encoding = wc & wc_encode_mask; 271 for (*codeset = NULL, i = 0; i < codeset_num; i++) { 272 if (wc_encoding == codeset_list[i]->wc_encoding) { 273 *codeset = codeset_list[i]; 274 break; 275 } 276 } 277 if (*codeset == NULL) 278 return(False); 279 280 mask = (1 << wc_shift_bits) - 1 ; 281 282 wc = wc & ~wc_encode_mask; 283 for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--) 284 *glyph_index = (*glyph_index << 8) | 285 ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask ); 286 287 return(True); 288} 289 290static CodeSet 291mb_parse_codeset( 292 State state, 293 int num, 294 const char **inbufptr, 295 int *from_left) 296{ 297 int len; 298 int from_len = (*from_left) + 1; 299 const char *src = (*inbufptr) - 1; 300 ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list); 301 ParseInfo parse_info; 302 CodeSet codeset; 303 304 for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) { 305 len = compare(src, parse_info->encoding, from_len); 306 if (len > 0) { 307 codeset = parse_info->codeset; 308 if (parse_info->type == E_LSL) 309 state->GL_codeset = codeset; 310 else if (parse_info->type == E_LSR) 311 state->GR_codeset = codeset; 312 --len; 313 *inbufptr += len; 314 *from_left -= len; 315 return codeset; 316 } 317 } 318 return (CodeSet) NULL; 319} 320 321static CodeSet 322byteM_parse_codeset( 323 XLCd lcd, 324 const char *inbufptr) 325{ 326 unsigned char ch; 327 CodeSet codeset; 328 ByteInfoList byteM; 329 ByteInfoListRec byteM_rec; 330 ByteInfo byteinfo; 331 ByteInfoRec byteinfo_rec; 332 Bool hit = False; 333 int i, j, k; 334 335 int codeset_num = XLC_GENERIC(lcd, codeset_num); 336 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 337 338 for (i = 0; i < codeset_num; i++) { 339 codeset = codeset_list[i]; 340 byteM = codeset->byteM; 341 if (codeset->side != XlcNONE || byteM == NULL) 342 continue; 343 344 for (j = 0; j < codeset->length; j++) { 345 ch = *((unsigned char *)(inbufptr + j)); 346 byteM_rec = byteM[j]; 347 byteinfo = byteM_rec.byteinfo; 348 349 for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) { 350 byteinfo_rec = byteinfo[k]; 351 if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) { 352 hit = True; 353 break; 354 } 355 } 356 357 if (!hit) 358 break; 359 } 360 361 if (hit) 362 return(codeset); 363 } 364 365 return(NULL); 366} 367 368#define GLGR_parse_codeset(ch) \ 369 (isrightside(ch) ? (state->GR_codeset) : \ 370 (state->GL_codeset) ) 371 372static XlcCharSet 373gi_parse_charset( 374 unsigned long glyph_index, 375 CodeSet codeset) 376{ 377 int i; 378 XlcCharSet *charset_list = codeset->charset_list; 379 int num_charsets = codeset->num_charsets; 380 ExtdSegment ctextseg = codeset->ctextseg; 381 XlcCharSet charset = NULL; 382 int area_num; 383 FontScope area; 384 385 /* lockup ct sequence */ 386 for (i = 0; i < num_charsets; i++) { 387 charset = charset_list[i]; 388 if (*charset->ct_sequence != '\0') 389 break; 390 } 391 if (i >= num_charsets) 392 return(NULL); 393 394 if (charset->source != CSsrcStd) 395 return (charset); 396 397 if (!ctextseg) 398 return(charset); 399 400 area = ctextseg->area; 401 area_num = ctextseg->area_num; 402 403 for (i = 0; i < area_num; i++) { 404 405 if (area[i].start <= glyph_index && glyph_index <= area[i].end) { 406 407 charset = ctextseg->charset; 408 409 if (*charset->ct_sequence == '\0') 410 return(NULL); 411 412 break; 413 } 414 } 415 416 return(charset); 417} 418 419static Bool 420ct_parse_csi( 421 const char *inbufptr, 422 int *ctr_seq_len) 423{ 424 int i; 425 int num = sizeof(directionality_data) / sizeof(directionality_data[0]); 426 427 for (i = 0; i < num; i++) { 428 if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) ) 429 continue; 430 431 if ( strncmp(inbufptr, directionality_data[i].encoding, 432 *ctr_seq_len) == 0) 433 return(True); 434 } 435 436 return(False); 437} 438 439static int 440cmp_esc_sequence( 441 const char *inbufptr, 442 XlcCharSet charset) 443{ 444 int seq_len, name_len, total_len; 445 unsigned char byte_m, byte_l; 446 const char *ct_sequence = charset->ct_sequence; 447 const char *encoding_name = charset->encoding_name; 448 449 /* check esc sequence */ 450 if ( !(seq_len = strlen(ct_sequence) ) ) 451 return(0); 452 if ( strncmp(inbufptr, ct_sequence, seq_len) != 0) 453 return(0); 454 455 /* Standard Character Set Encoding ? */ 456 if (charset->source == CSsrcStd) 457 return(seq_len); 458 459 /* 460 * Non-Standard Character Set Encoding 461 * 462 * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ 463 * | ctseq | M | L | encoding name | STX | contents | 464 * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ 465 * 4bytes 1byte 1byte variable length 1byte variable length 466 * | | 467 * +----------------------------------------------+ 468 * rest length = ((M - 128) * 128) + (L - 128) 469 */ 470 471 /* get length of encoding name */ 472 inbufptr += seq_len; 473 byte_m = *inbufptr++; 474 byte_l = *inbufptr++; 475 name_len = strlen(encoding_name); 476 477 if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len) 478 return(0); 479 480 if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 ) 481 return(0); 482 483 /* check STX (Start of Text) */ 484 inbufptr = inbufptr + name_len; 485 if ( *inbufptr != STX ) 486 return(0); 487 488 total_len = seq_len + name_len + 3; 489 return(total_len); 490} 491 492static Bool 493ct_parse_charset( 494 XLCd lcd, 495 const char *inbufptr, 496 XlcCharSet *charset, 497 int *ctr_seq_len) 498{ 499 int i, j; 500 ExtdSegment ctextseg; 501 int num_charsets; 502 XlcCharSet *charset_list; 503 CodeSet codeset; 504 int codeset_num = XLC_GENERIC(lcd, codeset_num); 505 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 506 int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); 507 SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); 508 509 /* get charset from XLC_XLOCALE by escape sequence */ 510 511 for (i = 0; i < codeset_num; i++) { 512 codeset = codeset_list[i]; 513 514 num_charsets = codeset->num_charsets; 515 charset_list = codeset->charset_list; 516 ctextseg = codeset->ctextseg; 517 518 for (j = 0; j < num_charsets; j++) { 519 *charset = charset_list[j]; 520 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 521 return(True); 522 } 523 524 if (ctextseg) { 525 *charset = ctextseg->charset; 526 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 527 return(True); 528 } 529 } 530 531 /* get charset from XLC_SEGMENTCONVERSION by escape sequence */ 532 533 if (!segment_conv) 534 return(False); 535 536 for (i = 0; i < segment_conv_num; i++) { 537 *charset = segment_conv[i].source; 538 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 539 return(True); 540 *charset = segment_conv[i].dest; 541 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 542 return(True); 543 } 544 545 return(False); 546} 547 548static Bool 549segment_conversion( 550 XLCd lcd, 551 XlcCharSet *charset, 552 unsigned long *glyph_index) 553{ 554 int i; 555 int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); 556 SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); 557 FontScopeRec range; 558 ConversionRec conv_rec; 559 560 if (!segment_conv) 561 return(True); 562 563 for (i = 0; i < segment_conv_num; i++) { 564 if (segment_conv[i].source == *charset) 565 break; 566 } 567 568 if (i >= segment_conv_num) 569 return(True); 570 571 range = segment_conv[i].range; 572 if (*glyph_index < range.start || range.end < *glyph_index) 573 return(True); 574 575 *charset = segment_conv[i].dest; 576 conv_rec.conv_num = segment_conv[i].conv_num; 577 conv_rec.convlist = segment_conv[i].conv; 578 *glyph_index = conv_to_dest(&conv_rec, *glyph_index); 579 580 return(True); 581} 582 583static CodeSet 584_XlcGetCodeSetFromName( 585 XLCd lcd, 586 const char *name) 587{ 588 int i, j; 589 XlcCharSet charset; 590 int num_charsets; 591 XlcCharSet *charset_list; 592 CodeSet codeset; 593 594 int codeset_num = XLC_GENERIC(lcd, codeset_num); 595 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 596 597 for (i = 0; i < codeset_num; i++) { 598 codeset = codeset_list[i]; 599 600 num_charsets = codeset->num_charsets; 601 charset_list = codeset->charset_list; 602 603 for (j = 0; j < num_charsets; j++) { 604 charset = charset_list[j]; 605 606 if (!strlen(charset->name)) 607 continue; 608 if ( strcmp(charset->name, name) == 0) 609 return(codeset); 610 } 611 } 612 613 return(NULL); 614} 615 616static Bool 617_XlcGetCodeSetFromCharSet( 618 XLCd lcd, 619 XlcCharSet charset, 620 CodeSet *codeset, 621 unsigned long *glyph_index) 622{ 623 int j, num; 624 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 625 XlcCharSet *charset_list; 626 int codeset_num, num_charsets; 627 Conversion ctconv; 628 unsigned long glyph_index_tmp = 0; 629 ExtdSegment ctextseg; 630 631 codeset_num = XLC_GENERIC(lcd, codeset_num); 632 633 for (num = 0 ; num < codeset_num; num++) { 634 *codeset = codeset_list[num]; 635 ctconv = (*codeset)->ctconv; 636 ctextseg = (*codeset)->ctextseg; 637 638 num_charsets = (*codeset)->num_charsets; 639 charset_list = (*codeset)->charset_list; 640 641 glyph_index_tmp = conv_to_source(ctconv, *glyph_index); 642 643 if (charset->source == CSsrcStd) { 644 645 /* Standard Character Set Encoding */ 646 if (glyph_index_tmp == *glyph_index) { 647 for (j = 0; j < num_charsets; j++) { 648 if (charset_list[j] == charset) { 649 goto end_loop; 650 } 651 } 652 } 653 654 } else { 655 656 /* Non-Standard Character Set Encoding */ 657 for (j = 0; j < num_charsets; j++) { 658 if (charset_list[j] == charset) { 659 goto end_loop; 660 } 661 } 662 663 if (glyph_index_tmp != *glyph_index) { 664 if (ctextseg && ctextseg->charset == charset) { 665 goto end_loop; 666 } 667 } 668 669 } 670 671 } 672 673end_loop: 674 if (num < codeset_num) { 675 *glyph_index = glyph_index_tmp; 676 return(True); 677 } 678 679 return(False); 680} 681 682#define check_string_encoding(codeset) (codeset->string_encoding) 683 684static void 685output_ulong_value( 686 char *outbufptr, 687 unsigned long code, 688 int length, 689 XlcSide side) 690{ 691 int i; 692 693 for (i = (length - 1) * 8; i >= 0; i -= 8) { 694 *outbufptr = ( code >> i) & 0xff; 695 696 if (side == XlcC0 || side == XlcGL) { 697 *outbufptr = *outbufptr & GL; 698 } else if (side == XlcC1 || side == XlcGR) { 699 *outbufptr = *outbufptr | GR; 700 } 701 702 outbufptr++; 703 } 704} 705 706/* -------------------------------------------------------------------------- */ 707/* Init */ 708/* -------------------------------------------------------------------------- */ 709 710static XlcCharSet default_GL_charset = 0; 711static XlcCharSet default_GR_charset = 0; 712 713static void 714init_state( 715 XlcConv conv) 716{ 717 State state = (State) conv->state; 718 719 /* for CT */ 720 state->charset = NULL; 721 state->GL_charset = default_GL_charset; 722 state->GR_charset = default_GR_charset; 723 724 /* for MB shift state */ 725 state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL); 726 state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR); 727} 728 729/* -------------------------------------------------------------------------- */ 730/* Convert */ 731/* -------------------------------------------------------------------------- */ 732 733static int 734mbstowcs_org( 735 XlcConv conv, 736 XPointer *from, 737 int *from_left, 738 XPointer *to, 739 int *to_left, 740 XPointer *args, 741 int num_args) 742{ 743 State state = (State) conv->state; 744 XLCd lcd = state->lcd; 745 746 unsigned char ch; 747 unsigned long mb = 0; 748 wchar_t wc; 749 750 int length = 0, len_left = 0; 751 int unconv_num = 0; 752 int num; 753 754 CodeSet codeset = NULL; 755 756 const char *inbufptr = *from; 757 wchar_t *outbufptr = (wchar_t *) *to; 758 int from_size = *from_left; 759 760 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 761 762 if (from == NULL || *from == NULL) { 763 _XlcResetConverter(conv); 764 return( 0 ); 765 } 766 767#ifdef notdef 768 if (*from_left > *to_left) 769 *from_left = *to_left; 770#endif 771 772 while (*from_left && *to_left) { 773 774 ch = *inbufptr++; 775 (*from_left)--; 776 777 /* null ? */ 778 if (!ch) { 779 if (outbufptr) {*outbufptr++ = L'\0';} 780 (*to_left)--; 781 782 /* error check */ 783 if (len_left) { 784 unconv_num += (length - len_left); 785 len_left = 0; 786 } 787 788 continue; 789 } 790 791 /* same mb char data */ 792 if (len_left) 793 goto output_one_wc; 794 795 /* next mb char data for single shift ? */ 796 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 797 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 798 if (codeset != NULL) { 799 length = len_left = codeset->length; 800 mb = 0; 801 continue; 802 } 803 } 804 805 /* next mb char data for byteM ? */ 806 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) 807 goto next_mb_char; 808 809 /* next mb char data for GL or GR side ? */ 810 if ((codeset = GLGR_parse_codeset(ch))) 811 goto next_mb_char; 812 813 /* can't find codeset for the ch */ 814 unconv_num++; 815 continue; 816 817next_mb_char: 818 length = len_left = codeset->length; 819 mb = 0; 820 821output_one_wc: 822 mb = (mb << 8) | ch; /* 1 byte left shift */ 823 len_left--; 824 825 /* last of one mb char data */ 826 if (!len_left) { 827 gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc); 828 if (outbufptr) {*outbufptr++ = wc;} 829 (*to_left)--; 830 } 831 832 } /* end of while */ 833 834 /* error check on last char */ 835 if (len_left) { 836 inbufptr -= (length - len_left); 837 (*from_left) += (length - len_left); 838 unconv_num += (length - len_left); 839 } 840 841 *from = (XPointer) ((const char *) *from + from_size); 842 *from_left = 0; 843 *to = (XPointer) outbufptr; 844 845 return unconv_num; 846} 847 848static int 849stdc_mbstowcs( 850 XlcConv conv, 851 XPointer *from, 852 int *from_left, 853 XPointer *to, 854 int *to_left, 855 XPointer *args, 856 int num_args) 857{ 858 const char *src = *((const char **) from); 859 wchar_t *dst = *((wchar_t **) to); 860 int src_left = *from_left; 861 int dst_left = *to_left; 862 int length, unconv_num = 0; 863 864 while (src_left > 0 && dst_left > 0) { 865 length = mbtowc(dst, src, src_left); 866 867 if (length > 0) { 868 src += length; 869 src_left -= length; 870 if (dst) 871 dst++; 872 dst_left--; 873 } else if (length < 0) { 874 src++; 875 src_left--; 876 unconv_num++; 877 } else { 878 /* null ? */ 879 src++; 880 src_left--; 881 if (dst) 882 *dst++ = L'\0'; 883 dst_left--; 884 } 885 } 886 887 *from = (XPointer) src; 888 if (dst) 889 *to = (XPointer) dst; 890 *from_left = src_left; 891 *to_left = dst_left; 892 893 return unconv_num; 894} 895 896static int 897wcstombs_org( 898 XlcConv conv, 899 XPointer *from, 900 int *from_left, 901 XPointer *to, 902 int *to_left, 903 XPointer *args, 904 int num_args) 905{ 906 State state = (State) conv->state; 907 XLCd lcd = state->lcd; 908 909 char *encoding; 910 unsigned long mb, glyph_index; 911 wchar_t wc; 912 913 int length; 914 int unconv_num = 0; 915 916 CodeSet codeset; 917 918 const wchar_t *inbufptr = (const wchar_t *) *from; 919 char *outbufptr = *to; 920 int from_size = *from_left; 921 922 const char *default_string = XLC_PUBLIC(lcd, default_string); 923 int defstr_len = strlen(default_string); 924 925 926#ifdef notdef 927 if (*from_left > *to_left) 928 *from_left = *to_left; 929#endif 930 931 while (*from_left && *to_left) { 932 933 wc = *inbufptr++; 934 (*from_left)--; 935 936 /* null ? */ 937 if (!wc) { 938 if (outbufptr) {*outbufptr++ = '\0';} 939 (*to_left)--; 940 941 continue; 942 } 943 944 /* convert */ 945 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 946 947 /* output default_string of XDefaultString() */ 948 if (*to_left < defstr_len) 949 break; 950 if (outbufptr) { 951 strncpy((char *)outbufptr, default_string, defstr_len); 952 outbufptr += defstr_len; 953 } 954 (*to_left) -= defstr_len; 955 956 unconv_num++; 957 958 } else { 959 mb = gi_to_mb(glyph_index, codeset); 960 if (codeset->parse_info) { 961 Bool need_shift = False; 962 switch (codeset->parse_info->type) { 963 case E_LSL : 964 if (codeset != state->GL_codeset) { 965 need_shift = True; 966 state->GL_codeset = codeset; 967 } 968 break; 969 case E_LSR : 970 if (codeset != state->GR_codeset) { 971 need_shift = True; 972 state->GR_codeset = codeset; 973 } 974 break; 975 /* case E_SS */ 976 default: 977 need_shift = True; 978 } 979 980 /* output shift sequence */ 981 if (need_shift) { 982 encoding = codeset->parse_info->encoding; 983 length = strlen(encoding); 984 if (*to_left < length) 985 break; 986 if (outbufptr) { 987 strncpy((char *)outbufptr, encoding, length); 988 outbufptr += length; 989 } 990 (*to_left) -= length; 991 } 992 } 993 994 /* output characters */ 995 length = codeset->length; 996 if (*to_left < length) 997 break; 998 999 if (outbufptr) { 1000 output_ulong_value(outbufptr, mb, length, XlcNONE); 1001 outbufptr += length; 1002 } 1003 1004 (*to_left) -= length; 1005 } 1006 1007 } /* end of while */ 1008 1009 *from = (XPointer) ((const wchar_t *) *from + from_size); 1010 *from_left = 0; 1011 *to = (XPointer) outbufptr; 1012 1013 return unconv_num; 1014} 1015 1016static int 1017stdc_wcstombs( 1018 XlcConv conv, 1019 XPointer *from, 1020 int *from_left, 1021 XPointer *to, 1022 int *to_left, 1023 XPointer *args, 1024 int num_args) 1025{ 1026 const wchar_t *src = *((const wchar_t **) from); 1027 char *dst = *((char **) to); 1028 int src_left = *from_left; 1029 int dst_left = *to_left; 1030 int length, unconv_num = 0; 1031 1032 while (src_left > 0 && dst_left >= MB_CUR_MAX) { 1033 length = wctomb(dst, *src); /* XXX */ 1034 1035 if (length > 0) { 1036 src++; 1037 src_left--; 1038 if (dst) 1039 dst += length; 1040 dst_left -= length; 1041 } else if (length < 0) { 1042 src++; 1043 src_left--; 1044 unconv_num++; 1045 } 1046 } 1047 1048 *from = (XPointer) src; 1049 if (dst) 1050 *to = (XPointer) dst; 1051 *from_left = src_left; 1052 *to_left = dst_left; 1053 1054 return unconv_num; 1055} 1056 1057static int 1058wcstocts( 1059 XlcConv conv, 1060 XPointer *from, 1061 int *from_left, 1062 XPointer *to, 1063 int *to_left, 1064 XPointer *args, 1065 int num_args) 1066{ 1067 State state = (State) conv->state; 1068 XLCd lcd = state->lcd; 1069 1070 unsigned long glyph_index; 1071 wchar_t wc; 1072 1073 int total_len, seq_len, name_len; 1074 int unconv_num = 0; 1075 Bool first_flag = True, standard_flag; 1076 XlcSide side; 1077 1078 CodeSet codeset; 1079 XlcCharSet charset, old_charset = NULL; 1080 const char *ct_sequence; 1081 1082 const wchar_t *inbufptr = (const wchar_t *) *from; 1083 char *outbufptr = *to; 1084 int from_size = *from_left; 1085 char *ext_seg_len = NULL; 1086 1087#ifdef notdef 1088 if (*from_left > *to_left) 1089 *from_left = *to_left; 1090#endif 1091 1092 while (*from_left && *to_left) { 1093 1094 wc = *inbufptr++; 1095 (*from_left)--; 1096 1097 /* null ? */ 1098 if (!wc) { 1099 if (outbufptr) {*outbufptr++ = '\0';} 1100 (*to_left)--; 1101 1102 continue; 1103 } 1104 1105 /* convert */ 1106 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 1107 unconv_num++; 1108 continue; 1109 } 1110 1111 /* parse charset */ 1112 if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { 1113 unconv_num++; 1114 continue; 1115 } 1116 1117 /* Standard Character Set Encoding ? */ 1118 standard_flag = charset->source == CSsrcStd ? True : False; 1119 1120 /* 1121 * Non-Standard Character Set Encoding 1122 * 1123 * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ 1124 * | esc sequence | M | L | encoding name | STX | 1125 * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ 1126 * 4bytes 1byte 1byte variable length 1byte 1127 * | | 1128 * +-----------------------------------------+ 1129 * name length = ((M - 128) * 128) + (L - 128) 1130 */ 1131 1132 /* make encoding data */ 1133 ct_sequence = charset->ct_sequence; 1134 side = charset->side; 1135 seq_len = strlen(ct_sequence); 1136 if (standard_flag) { 1137 name_len = 0; 1138 total_len = seq_len; 1139 } else { 1140 name_len = strlen(charset->encoding_name) + 1; 1141 total_len = seq_len + name_len + 2; 1142 } 1143 1144 /* output escape sequence of CT */ 1145 if ( (charset != old_charset) && 1146 !(first_flag && charset->string_encoding) ){ 1147 1148 if ( (ext_seg_len != NULL) && outbufptr) { 1149 int i = (outbufptr - ext_seg_len) - 2; 1150 *ext_seg_len++ = i / 128 + 128; 1151 *ext_seg_len = i % 128 + 128; 1152 ext_seg_len = NULL; 1153 } 1154 1155 if (*to_left < total_len + 1) { 1156 unconv_num++; 1157 break; 1158 } 1159 1160 if (outbufptr) { 1161 strcpy((char *)outbufptr, ct_sequence); 1162 outbufptr += seq_len; 1163 1164 if (!standard_flag) { 1165 const char *i = charset->encoding_name; 1166 ext_seg_len = outbufptr; 1167 outbufptr += 2; 1168 for (; *i ; i++) 1169 *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ? 1170 *i - 'A' + 'a' : *i; 1171 *outbufptr++ = STX; 1172 } 1173 } 1174 1175 (*to_left) -= total_len; 1176 1177 first_flag = False; 1178 old_charset = charset; 1179 } 1180 1181 /* output glyph index */ 1182 if (codeset->ctconv) 1183 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 1184 if (*to_left < charset->char_size) { 1185 unconv_num++; 1186 break; 1187 } 1188 1189 if (outbufptr) { 1190 output_ulong_value(outbufptr, glyph_index, charset->char_size, side); 1191 outbufptr += charset->char_size; 1192 } 1193 1194 (*to_left) -= charset->char_size; 1195 1196 } /* end of while */ 1197 1198 if ( (ext_seg_len != NULL) && outbufptr) { 1199 int i = (outbufptr - ext_seg_len) - 2; 1200 *ext_seg_len++ = i / 128 + 128; 1201 *ext_seg_len = i % 128 + 128; 1202 } 1203 1204 *from = (XPointer) ((const wchar_t *) *from + from_size); 1205 *from_left = 0; 1206 *to = (XPointer) outbufptr; 1207 1208 return unconv_num; 1209} 1210 1211static int 1212stdc_wcstocts( 1213 XlcConv conv, 1214 XPointer *from, 1215 int *from_left, 1216 XPointer *to, 1217 int *to_left, 1218 XPointer *args, 1219 int num_args) 1220{ 1221 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1222 char *buf_ptr1 = buf; 1223 int buf_left1 = (*from_left) * MB_CUR_MAX; 1224 char *buf_ptr2 = buf_ptr1; 1225 int buf_left2; 1226 int unconv_num1 = 0, unconv_num2 = 0; 1227 1228 unconv_num1 = stdc_wcstombs(conv, 1229 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1230 if (unconv_num1 < 0) 1231 goto ret; 1232 1233 buf_left2 = buf_ptr1 - buf_ptr2; 1234 1235 unconv_num2 = mbstocts(conv, 1236 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1237 if (unconv_num2 < 0) 1238 goto ret; 1239 1240ret: 1241 if (buf) 1242 Xfree((char *)buf); 1243 1244 return (unconv_num1 + unconv_num2); 1245} 1246 1247static int 1248ctstowcs( 1249 XlcConv conv, 1250 XPointer *from, 1251 int *from_left, 1252 XPointer *to, 1253 int *to_left, 1254 XPointer *args, 1255 int num_args) 1256{ 1257 State state = (State) conv->state; 1258 XLCd lcd = state->lcd; 1259 1260 unsigned char ch; 1261 unsigned long glyph_index = 0; 1262 wchar_t wc; 1263 1264 int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0; 1265 int unconv_num = 0; 1266 1267 CodeSet codeset = NULL; 1268 XlcCharSet charset_tmp; 1269 1270 const char *inbufptr = *from; 1271 wchar_t *outbufptr = (wchar_t *) *to; 1272 int from_size = *from_left; 1273 1274 _XlcResetConverter(conv); /* ??? */ 1275 1276 if (from == NULL || *from == NULL) { 1277 _XlcResetConverter(conv); 1278 return( 0 ); 1279 } 1280 1281#ifdef notdef 1282 if (*from_left > *to_left) 1283 *from_left = *to_left; 1284#endif 1285 1286 while (*from_left && *to_left) { 1287 1288 ch = *inbufptr++; 1289 (*from_left)--; 1290 1291 /* null ? */ 1292 if (!ch) { 1293 if (outbufptr) {*outbufptr++ = L'\0';} 1294 (*to_left)--; 1295 1296 /* error check */ 1297 if (gi_len_left) { 1298 unconv_num += (gi_len - gi_len_left); 1299 gi_len_left = 0; 1300 } 1301 1302 continue; 1303 } 1304 1305 /* same glyph_index data */ 1306 if (gi_len_left) 1307 goto output_one_wc; 1308 1309 /* control sequence ? */ 1310 if (ch == CSI) { 1311 if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) ) 1312 goto skip_the_seg; 1313 1314 if (*from_left + 1 < ctr_seq_len) { 1315 inbufptr--; 1316 (*from_left)++; 1317 unconv_num += *from_left; 1318 break; 1319 } 1320 1321 /* skip the control sequence */ 1322 inbufptr += (ctr_seq_len - 1); 1323 *from_left -= (ctr_seq_len - 1); 1324 1325 continue; 1326 } 1327 1328 /* escape sequence ? */ 1329 if (ch == ESC) { 1330 if ( !ct_parse_charset(lcd, 1331 inbufptr - 1, &state->charset, &ctr_seq_len) ) 1332 goto skip_the_seg; 1333 1334 if (state->charset->side == XlcC0 || 1335 state->charset->side == XlcGL) 1336 { 1337 state->GL_charset = state->charset; 1338 } 1339 else if (state->charset->side == XlcC1 || 1340 state->charset->side == XlcGR) 1341 { 1342 state->GR_charset = state->charset; 1343 } 1344 else if (state->charset->side == XlcGLGR) 1345 { 1346 state->GL_charset = state->charset; 1347 state->GR_charset = state->charset; 1348 } 1349 1350 if (*from_left + 1 < ctr_seq_len) { 1351 inbufptr--; 1352 (*from_left)++; 1353 unconv_num += *from_left; 1354 break; 1355 } 1356 1357 /* skip the escape sequence */ 1358 inbufptr += (ctr_seq_len - 1); 1359 *from_left -= (ctr_seq_len - 1); 1360 1361 continue; 1362 } 1363 1364 /* check current state */ 1365 if (isleftside(ch)) 1366 state->charset = state->GL_charset; 1367 else 1368 state->charset = state->GR_charset; 1369 1370 gi_len = gi_len_left = state->charset->char_size; 1371 glyph_index = 0; 1372 1373output_one_wc: 1374 if (state->charset->side == XlcC1 || state->charset->side == XlcGR) 1375 glyph_index = (glyph_index << 8) | (ch & GL); 1376 else 1377 glyph_index = (glyph_index << 8) | ch; 1378 1379 gi_len_left--; 1380 1381 /* last of one glyph_index data */ 1382 if (!gi_len_left) { 1383 1384 /* segment conversion */ 1385 charset_tmp = state->charset; 1386 segment_conversion(lcd, &charset_tmp, &glyph_index); 1387 1388 /* get codeset */ 1389 if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, 1390 &codeset, &glyph_index) ) { 1391 unconv_num += gi_len; 1392 continue; 1393 } 1394 1395 /* convert glyph index to wicd char */ 1396 gi_to_wc(lcd, glyph_index, codeset, &wc); 1397 if (outbufptr) {*outbufptr++ = wc;} 1398 (*to_left)--; 1399 } 1400 1401 continue; 1402 1403skip_the_seg: 1404 /* skip until next escape or control sequence */ 1405 while ( *from_left ) { 1406 ch = *inbufptr++; 1407 (*from_left)--; 1408 unconv_num++; 1409 1410 if (ch == ESC || ch == CSI) { 1411 inbufptr--; 1412 (*from_left)++; 1413 unconv_num--; 1414 break; 1415 } 1416 } 1417 1418 if ( !(*from_left) ) 1419 break; 1420 1421 } /* end of while */ 1422 1423 /* error check on last char */ 1424 if (gi_len_left) { 1425 inbufptr -= (gi_len - gi_len_left); 1426 (*from_left) += (gi_len - gi_len_left); 1427 unconv_num += (gi_len - gi_len_left); 1428 } 1429 1430 *from = (XPointer) ((const char *) *from + from_size); 1431 *from_left = 0; 1432 *to = (XPointer) outbufptr; 1433 1434 return unconv_num; 1435} 1436 1437static int 1438cstowcs( 1439 XlcConv conv, 1440 XPointer *from, 1441 int *from_left, 1442 XPointer *to, 1443 int *to_left, 1444 XPointer *args, 1445 int num_args) 1446{ 1447 State state = (State) conv->state; 1448 XLCd lcd = state->lcd; 1449 1450 unsigned char ch; 1451 unsigned long glyph_index = 0; 1452 wchar_t wc; 1453 int gi_len_left = 0, gi_len = 0; 1454 1455 int unconv_num = 0; 1456 1457 CodeSet codeset = NULL; 1458 XlcCharSet charset, charset_tmp; 1459 1460 const char *inbufptr = *from; 1461 wchar_t *outbufptr = (wchar_t *) *to; 1462 int from_size = *from_left; 1463 1464 if (from == NULL || *from == NULL) { 1465 return( 0 ); 1466 } 1467 1468 charset = (XlcCharSet) args[0]; 1469 1470 while (*from_left && *to_left) { 1471 1472 if (!gi_len_left) { 1473 gi_len_left = gi_len = charset->char_size; 1474 glyph_index = 0; 1475 } 1476 1477 ch = *inbufptr++; 1478 (*from_left)--; 1479 1480 /* null ? */ 1481 if (!ch) { 1482 if (outbufptr) {*outbufptr++ = L'\0';} 1483 (*to_left)--; 1484 1485 /* error check */ 1486 if (gi_len_left) { 1487 unconv_num += (gi_len - gi_len_left); 1488 gi_len_left = 0; 1489 } 1490 continue; 1491 } 1492 1493 if (charset->side == XlcC1 || charset->side == XlcGR) 1494 glyph_index = (glyph_index << 8) | (ch & GL); 1495 else 1496 glyph_index = (glyph_index << 8) | ch; 1497 1498 gi_len_left--; 1499 1500 /* last of one glyph_index data */ 1501 if (!gi_len_left) { 1502 1503 /* segment conversion */ 1504 charset_tmp = charset; 1505 segment_conversion(lcd, &charset_tmp, &glyph_index); 1506 1507 /* get codeset */ 1508 if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, 1509 &codeset, &glyph_index) ) { 1510 unconv_num += gi_len; 1511 continue; 1512 } 1513 1514 /* convert glyph index to wicd char */ 1515 gi_to_wc(lcd, glyph_index, codeset, &wc); 1516 if (outbufptr) {*outbufptr++ = wc;} 1517 (*to_left)--; 1518 } 1519 1520 } /* end of while */ 1521 1522 /* error check on last char */ 1523 if (gi_len_left) { 1524 inbufptr -= (gi_len - gi_len_left); 1525 (*from_left) += (gi_len - gi_len_left); 1526 unconv_num += (gi_len - gi_len_left); 1527 } 1528 1529 *from = (XPointer) ((const char *) *from + from_size); 1530 *from_left = 0; 1531 *to = (XPointer) outbufptr; 1532 1533 return unconv_num; 1534} 1535 1536static int 1537stdc_ctstowcs( 1538 XlcConv conv, 1539 XPointer *from, 1540 int *from_left, 1541 XPointer *to, 1542 int *to_left, 1543 XPointer *args, 1544 int num_args) 1545{ 1546 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1547 char *buf_ptr1 = buf; 1548 int buf_left1 = (*from_left) * MB_CUR_MAX; 1549 char *buf_ptr2 = buf_ptr1; 1550 int buf_left2; 1551 int unconv_num1 = 0, unconv_num2 = 0; 1552 1553 unconv_num1 = ctstombs(conv, 1554 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1555 if (unconv_num1 < 0) 1556 goto ret; 1557 1558 buf_left2 = buf_ptr1 - buf_ptr2; 1559 1560 unconv_num2 = stdc_mbstowcs(conv, 1561 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1562 if (unconv_num2 < 0) 1563 goto ret; 1564 1565ret: 1566 if (buf) 1567 Xfree((char *)buf); 1568 1569 return (unconv_num1 + unconv_num2); 1570} 1571 1572static int 1573stdc_cstowcs( 1574 XlcConv conv, 1575 XPointer *from, 1576 int *from_left, 1577 XPointer *to, 1578 int *to_left, 1579 XPointer *args, 1580 int num_args) 1581{ 1582 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1583 char *buf_ptr1 = buf; 1584 int buf_left1 = (*from_left) * MB_CUR_MAX; 1585 char *buf_ptr2 = buf_ptr1; 1586 int buf_left2; 1587 int unconv_num1 = 0, unconv_num2 = 0; 1588 1589 unconv_num1 = cstombs(conv, 1590 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1591 if (unconv_num1 < 0) 1592 goto ret; 1593 1594 buf_left2 = buf_ptr1 - buf_ptr2; 1595 1596 unconv_num2 = stdc_mbstowcs(conv, 1597 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1598 if (unconv_num2 < 0) 1599 goto ret; 1600 1601ret: 1602 if (buf) 1603 Xfree((char *)buf); 1604 1605 return (unconv_num1 + unconv_num2); 1606} 1607 1608static int 1609mbstocts( 1610 XlcConv conv, 1611 XPointer *from, 1612 int *from_left, 1613 XPointer *to, 1614 int *to_left, 1615 XPointer *args, 1616 int num_args) 1617{ 1618 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 1619 char *buf_ptr1 = buf; 1620 int buf_left1 = (*from_left); 1621 char *buf_ptr2 = buf_ptr1; 1622 int buf_left2; 1623 int unconv_num1 = 0, unconv_num2 = 0; 1624 1625 unconv_num1 = mbstowcs_org(conv, 1626 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1627 if (unconv_num1 < 0) 1628 goto ret; 1629 1630 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 1631 1632 unconv_num2 += wcstocts(conv, 1633 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1634 if (unconv_num2 < 0) 1635 goto ret; 1636 1637ret: 1638 if (buf) 1639 Xfree((char *)buf); 1640 1641 return (unconv_num1 + unconv_num2); 1642} 1643 1644static int 1645mbstostr( 1646 XlcConv conv, 1647 XPointer *from, 1648 int *from_left, 1649 XPointer *to, 1650 int *to_left, 1651 XPointer *args, 1652 int num_args) 1653{ 1654 State state = (State) conv->state; 1655 XLCd lcd = state->lcd; 1656 1657 unsigned char ch; 1658 unsigned long mb = 0; 1659 1660 int length = 0, len_left = 0; 1661 int unconv_num = 0; 1662 int num; 1663 1664 CodeSet codeset = NULL; 1665 1666 const char *inbufptr = *from; 1667 char *outbufptr = *to; 1668 int from_size = *from_left; 1669 1670 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 1671 1672 if (from == NULL || *from == NULL) { 1673 _XlcResetConverter(conv); 1674 return( 0 ); 1675 } 1676 1677#ifdef notdef 1678 if (*from_left > *to_left) 1679 *from_left = *to_left; 1680#endif 1681 1682 while (*from_left && *to_left) { 1683 1684 ch = *inbufptr++; 1685 (*from_left)--; 1686 1687 /* null ? */ 1688 if (!ch) { 1689 if (outbufptr) {*outbufptr++ = '\0';} 1690 (*to_left)--; 1691 1692 /* error check */ 1693 if (len_left) { 1694 unconv_num += (length - len_left); 1695 len_left = 0; 1696 } 1697 1698 continue; 1699 } 1700 1701 /* same mb char data */ 1702 if (len_left) 1703 goto output_one_mb; 1704 1705 /* next mb char data for single shift ? */ 1706 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 1707 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 1708 if (codeset != NULL) { 1709 length = len_left = codeset->length; 1710 mb = 0; 1711 continue; 1712 } 1713 } 1714 1715 /* next char data : byteM ? */ 1716 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) 1717 goto next_mb_char; 1718 1719 /* next char data : GL or GR side ? */ 1720 if ((codeset = GLGR_parse_codeset(ch))) 1721 goto next_mb_char; 1722 1723 /* can't find codeset for the ch */ 1724 unconv_num++; 1725 continue; 1726 1727next_mb_char: 1728 length = len_left = codeset->length; 1729 mb = 0; 1730 1731output_one_mb: 1732 mb = (mb << 8) | ch; /* 1 byte left shift */ 1733 len_left--; 1734 1735 /* last of one mb char data */ 1736 if (!len_left) { 1737 if (check_string_encoding(codeset)) { 1738 if (outbufptr) {*outbufptr++ = mb & 0xff;} 1739 (*to_left)--; 1740 } else { 1741 unconv_num++; 1742 } 1743 } 1744 1745 } /* end of while */ 1746 1747 /* error check on last char */ 1748 if (len_left) { 1749 inbufptr -= (length - len_left); 1750 (*from_left) += (length - len_left); 1751 unconv_num += (length - len_left); 1752 } 1753 1754 *from = (XPointer) ((const char *) *from + from_size); 1755 *from_left = 0; 1756 *to = (XPointer) outbufptr; 1757 1758 return unconv_num; 1759} 1760 1761static int 1762mbtocs( 1763 XlcConv conv, 1764 XPointer *from, 1765 int *from_left, 1766 XPointer *to, 1767 int *to_left, 1768 XPointer *args, 1769 int num_args) 1770{ 1771 State state = (State) conv->state; 1772 XLCd lcd = state->lcd; 1773 1774 unsigned char ch; 1775 unsigned long mb = 0; 1776 unsigned long glyph_index; 1777 1778 int length = 0, len_left = 0, char_len; 1779 int unconv_num = 0; 1780 int num; 1781 XlcSide side; 1782 1783 CodeSet codeset = NULL; 1784 XlcCharSet charset = NULL; 1785 1786 const char *inbufptr = *from; 1787 char *outbufptr = *to; 1788 int from_size = *from_left; 1789 1790 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 1791 1792 if (from == NULL || *from == NULL) { 1793 _XlcResetConverter(conv); 1794 return( 0 ); 1795 } 1796 1797 while (*from_left && *to_left) { 1798 1799 ch = *inbufptr++; 1800 (*from_left)--; 1801 1802 /* null ? */ 1803 if (!ch) { 1804 unconv_num = 1; 1805 if (len_left) 1806 unconv_num += (length - len_left); 1807 break; 1808 } 1809 1810 /* same mb char data */ 1811 if (len_left) 1812 goto output; 1813 1814 /* next mb char data for single shift ? */ 1815 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 1816 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 1817 if (codeset != NULL) { 1818 length = len_left = codeset->length; 1819 mb = 0; 1820 continue; 1821 } 1822 } 1823 1824 /* next mb char data for byteM ? */ 1825 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) 1826 goto next_mb_char; 1827 1828 /* next mb char data for GL or GR side ? */ 1829 if ((codeset = GLGR_parse_codeset(ch))) 1830 goto next_mb_char; 1831 1832 /* can't find codeset for the ch */ 1833 unconv_num = 1; 1834 break; 1835 1836next_mb_char: 1837 length = len_left = codeset->length; 1838 mb = 0; 1839 1840output: 1841 mb = (mb << 8) | ch; /* 1 byte left shift */ 1842 len_left--; 1843 1844 /* last of one mb char data */ 1845 if (!len_left) { 1846 glyph_index = mb_to_gi(mb, codeset); 1847 if (!(charset = gi_parse_charset(glyph_index, codeset))) { 1848 unconv_num = length; 1849 break; 1850 } 1851 char_len = charset->char_size; 1852 side = charset->side; 1853 1854 /* output glyph index */ 1855 if (codeset->ctconv) 1856 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 1857 if (*to_left < char_len) { 1858 unconv_num = length; 1859 break; 1860 } 1861 1862 if (outbufptr) { 1863 output_ulong_value(outbufptr, glyph_index, char_len, side); 1864 outbufptr += char_len; 1865 } 1866 1867 (*to_left) -= char_len; 1868 1869 break; 1870 } 1871 1872 } /* end of while */ 1873 1874 /* error end */ 1875 if (unconv_num) { 1876 *from = (XPointer) ((const char *) *from + from_size); 1877 *from_left = 0; 1878 *to = (XPointer) outbufptr; 1879 return -1; 1880 } 1881 1882 /* normal end */ 1883 *from = (XPointer) inbufptr; 1884 *to = (XPointer) outbufptr; 1885 1886 if (num_args > 0) 1887 *((XlcCharSet *) args[0]) = charset; 1888 1889 return 0; 1890} 1891 1892static int 1893mbstocs( 1894 XlcConv conv, 1895 XPointer *from, 1896 int *from_left, 1897 XPointer *to, 1898 int *to_left, 1899 XPointer *args, 1900 int num_args) 1901{ 1902 int ret; 1903 XlcCharSet charset_old, charset = NULL; 1904 XPointer tmp_args[1]; 1905 1906 const char *inbufptr; 1907 int in_left; 1908 char *outbufptr; 1909 int out_left; 1910 tmp_args[0] = (XPointer) &charset; 1911 1912 ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); 1913 charset_old = charset; 1914 1915 while ( ret == 0 && *from_left && *to_left) { 1916 inbufptr = *from; 1917 in_left = *from_left; 1918 outbufptr = *to; 1919 out_left = *to_left; 1920 ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); 1921 if (charset_old != charset) { 1922 *from = (XPointer) inbufptr; 1923 *from_left = in_left; 1924 *to = (XPointer) outbufptr; 1925 *to_left = out_left; 1926 break; 1927 } 1928 } 1929 1930 if (num_args > 0) 1931 *((XlcCharSet *) args[0]) = charset_old; 1932 1933 /* error end */ 1934 if (ret != 0) 1935 return( -1 ); 1936 1937 return(0); 1938} 1939 1940static int 1941wcstostr( 1942 XlcConv conv, 1943 XPointer *from, 1944 int *from_left, 1945 XPointer *to, 1946 int *to_left, 1947 XPointer *args, 1948 int num_args) 1949{ 1950 State state = (State) conv->state; 1951 XLCd lcd = state->lcd; 1952 1953 char *encoding; 1954 unsigned long mb, glyph_index; 1955 wchar_t wc; 1956 1957 int length; 1958 int unconv_num = 0; 1959 1960 CodeSet codeset; 1961 1962 const wchar_t *inbufptr = (const wchar_t *) *from; 1963 char *outbufptr = *to; 1964 int from_size = *from_left; 1965 1966 const char *default_string = XLC_PUBLIC(lcd, default_string); 1967 int defstr_len = strlen(default_string); 1968 1969 1970#ifdef notdef 1971 if (*from_left > *to_left) 1972 *from_left = *to_left; 1973#endif 1974 1975 while (*from_left && *to_left) { 1976 1977 wc = *inbufptr++; 1978 (*from_left)--; 1979 1980 /* null ? */ 1981 if (!wc) { 1982 if (outbufptr) {*outbufptr++ = '\0';} 1983 (*to_left)--; 1984 1985 continue; 1986 } 1987 1988 /* convert */ 1989 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 1990 1991 /* output default_string of XDefaultString() */ 1992 if (*to_left < defstr_len) 1993 break; 1994 if (outbufptr) { 1995 strncpy((char *)outbufptr, default_string, defstr_len); 1996 outbufptr += defstr_len; 1997 } 1998 (*to_left) -= defstr_len; 1999 2000 unconv_num++; 2001 2002 } else { 2003 mb = gi_to_mb(glyph_index, codeset); 2004 2005 if (check_string_encoding(codeset)) { 2006 if (codeset->parse_info) { 2007 Bool need_shift = False; 2008 switch (codeset->parse_info->type) { 2009 case E_LSL : 2010 if (codeset != state->GL_codeset) { 2011 need_shift = True; 2012 state->GL_codeset = codeset; 2013 } 2014 break; 2015 case E_LSR : 2016 if (codeset != state->GR_codeset) { 2017 need_shift = True; 2018 state->GR_codeset = codeset; 2019 } 2020 break; 2021 /* case E_SS */ 2022 default: 2023 need_shift = True; 2024 } 2025 2026 /* output shift sequence */ 2027 if (need_shift) { 2028 encoding = codeset->parse_info->encoding; 2029 length = strlen(encoding); 2030 if (*to_left < length) 2031 break; 2032 2033 if (outbufptr) { 2034 strncpy((char *)outbufptr, encoding, length); 2035 outbufptr += length; 2036 } 2037 (*to_left) -= length; 2038 } 2039 } 2040 2041 /* output characters */ 2042 length = codeset->length; 2043 if (*to_left < length) 2044 break; 2045 2046 if (outbufptr) { 2047 output_ulong_value(outbufptr, mb, length, XlcNONE); 2048 outbufptr += length; 2049 } 2050 2051 (*to_left) -= length; 2052 } else { 2053 unconv_num++; 2054 } 2055 } 2056 2057 } /* end of while */ 2058 2059 *from = (XPointer) ((const wchar_t *) *from + from_size); 2060 *from_left = 0; 2061 *to = (XPointer) outbufptr; 2062 2063 return unconv_num; 2064} 2065 2066static int 2067stdc_wcstostr( 2068 XlcConv conv, 2069 XPointer *from, 2070 int *from_left, 2071 XPointer *to, 2072 int *to_left, 2073 XPointer *args, 2074 int num_args) 2075{ 2076 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 2077 char *buf_ptr1 = buf; 2078 int buf_left1 = (*from_left) * MB_CUR_MAX; 2079 char *buf_ptr2 = buf_ptr1; 2080 int buf_left2; 2081 int unconv_num1 = 0, unconv_num2 = 0; 2082 2083 unconv_num1 = stdc_wcstombs(conv, 2084 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2085 if (unconv_num1 < 0) 2086 goto ret; 2087 2088 buf_left2 = buf_ptr1 - buf_ptr2; 2089 2090 unconv_num2 = mbstostr(conv, 2091 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2092 if (unconv_num2 < 0) 2093 goto ret; 2094 2095ret: 2096 if (buf) 2097 Xfree((char *)buf); 2098 2099 return (unconv_num1 + unconv_num2); 2100} 2101 2102static int 2103wctocs( 2104 XlcConv conv, 2105 XPointer *from, 2106 int *from_left, 2107 XPointer *to, 2108 int *to_left, 2109 XPointer *args, 2110 int num_args) 2111{ 2112 State state = (State) conv->state; 2113 XLCd lcd = state->lcd; 2114 2115 wchar_t wc; 2116 unsigned long glyph_index; 2117 2118 int char_len; 2119 int unconv_num = 0; 2120 XlcSide side; 2121 2122 CodeSet codeset; 2123 XlcCharSet charset = NULL; 2124 2125 const wchar_t *inbufptr = (const wchar_t *) *from; 2126 char *outbufptr = *to; 2127 int from_size = *from_left; 2128 2129#ifdef notdef 2130 if (*from_left > *to_left) 2131 *from_left = *to_left; 2132#endif 2133 2134 if (*from_left && *to_left) { 2135 2136 wc = *inbufptr++; 2137 (*from_left)--; 2138 2139 /* null ? */ 2140 if (!wc) { 2141 unconv_num = 1; 2142 goto end; 2143 } 2144 2145 /* convert */ 2146 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 2147 unconv_num = 1; 2148 goto end; 2149 } 2150 2151 if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { 2152 unconv_num = 1; 2153 goto end; 2154 } 2155 char_len = charset->char_size; 2156 side = charset->side; 2157 2158 /* output glyph index */ 2159 if (codeset->ctconv) 2160 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 2161 if (*to_left < char_len) { 2162 unconv_num++; 2163 goto end; 2164 } 2165 2166 if (outbufptr) { 2167 output_ulong_value(outbufptr, glyph_index, char_len, side); 2168 outbufptr += char_len; 2169 } 2170 2171 (*to_left) -= char_len; 2172 2173 } 2174 2175end: 2176 2177 /* error end */ 2178 if (unconv_num) { 2179 *from = (XPointer) ((const wchar_t *) *from + from_size); 2180 *from_left = 0; 2181 *to = (XPointer) outbufptr; 2182 return -1; 2183 } 2184 2185 /* normal end */ 2186 *from = (XPointer) inbufptr; 2187 *to = (XPointer) outbufptr; 2188 2189 if (num_args > 0) 2190 *((XlcCharSet *) args[0]) = charset; 2191 2192 return 0; 2193} 2194 2195static int 2196stdc_wctocs( 2197 XlcConv conv, 2198 XPointer *from, 2199 int *from_left, 2200 XPointer *to, 2201 int *to_left, 2202 XPointer *args, 2203 int num_args) 2204{ 2205 const wchar_t *src = *((const wchar_t **) from); 2206 wchar_t wch; 2207 XPointer tmp_from, save_from = *from; 2208 char tmp[32]; 2209 int length, ret, src_left = *from_left; 2210 int from_size = *from_left; 2211 2212 if (src_left > 0 && *to_left > 0) { 2213 if ((wch = *src)) { 2214 length = wctomb(tmp, wch); 2215 } else { 2216 goto end; 2217 } 2218 2219 if (length < 0) 2220 goto end; 2221 2222 tmp_from = (XPointer) tmp; 2223 ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args); 2224 if (ret < 0) 2225 goto end; 2226 2227 src++; 2228 src_left--; 2229 } 2230 2231end: 2232 /* error end */ 2233 if (save_from == (XPointer) src) { 2234 *from = (XPointer) ((const wchar_t *) *from + from_size); 2235 *from_left = 0; 2236 return -1; 2237 } 2238 2239 /* normal end */ 2240 *from = (XPointer) src; 2241 *from_left = src_left; 2242 2243 return 0; 2244} 2245 2246static int 2247wcstocs( 2248 XlcConv conv, 2249 XPointer *from, 2250 int *from_left, 2251 XPointer *to, 2252 int *to_left, 2253 XPointer *args, 2254 int num_args) 2255{ 2256 int ret; 2257 XlcCharSet charset_old, charset = NULL; 2258 XPointer tmp_args[1]; 2259 2260 const wchar_t *inbufptr; 2261 int in_left; 2262 XPointer outbufptr; 2263 int out_left; 2264 tmp_args[0] = (XPointer) &charset; 2265 2266 ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2267 charset_old = charset; 2268 2269 while ( ret == 0 && *from_left && *to_left) { 2270 inbufptr = (const wchar_t *) *from; 2271 in_left = *from_left; 2272 outbufptr = *to; 2273 out_left = *to_left; 2274 ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2275 if (charset_old != charset) { 2276 *from = (XPointer) inbufptr; 2277 *from_left = in_left; 2278 *to = (XPointer) outbufptr; 2279 *to_left = out_left; 2280 break; 2281 } 2282 } 2283 2284 if (num_args > 0) 2285 *((XlcCharSet *) args[0]) = charset_old; 2286 2287 /* error end */ 2288 if (ret != 0) 2289 return( -1 ); 2290 2291 return(0); 2292} 2293 2294#ifdef STDCVT 2295 2296static int 2297stdc_wcstocs( 2298 XlcConv conv, 2299 XPointer *from, 2300 int *from_left, 2301 XPointer *to, 2302 int *to_left, 2303 XPointer *args, 2304 int num_args) 2305{ 2306 int ret; 2307 XlcCharSet charset_old, charset = NULL; 2308 XPointer tmp_args[1]; 2309 2310 const wchar_t *inbufptr; 2311 int in_left; 2312 XPointer outbufptr; 2313 int out_left; 2314 tmp_args[0] = (XPointer) &charset; 2315 2316 ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2317 charset_old = charset; 2318 2319 while ( ret == 0 && *from_left && *to_left ) { 2320 inbufptr = (const wchar_t *) *from; 2321 in_left = *from_left; 2322 outbufptr = *to; 2323 out_left = *to_left; 2324 ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2325 if (charset_old != charset) { 2326 *from = (XPointer) inbufptr; 2327 *from_left = in_left; 2328 *to = (XPointer) outbufptr; 2329 *to_left = out_left; 2330 break; 2331 } 2332 } 2333 2334 if (num_args > 0) 2335 *((XlcCharSet *) args[0]) = charset_old; 2336 2337 /* error end */ 2338 if (ret != 0) 2339 return( -1 ); 2340 2341 return(0); 2342} 2343 2344#endif 2345 2346static int 2347ctstombs( 2348 XlcConv conv, 2349 XPointer *from, 2350 int *from_left, 2351 XPointer *to, 2352 int *to_left, 2353 XPointer *args, 2354 int num_args) 2355{ 2356 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 2357 char *buf_ptr1 = buf; 2358 int buf_left1 = (*from_left); 2359 char *buf_ptr2 = buf_ptr1; 2360 int buf_left2; 2361 int unconv_num1 = 0, unconv_num2 = 0; 2362 2363 unconv_num1 = ctstowcs(conv, 2364 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2365 if (unconv_num1 < 0) 2366 goto ret; 2367 2368 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 2369 2370 unconv_num2 += wcstombs_org(conv, 2371 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2372 if (unconv_num2 < 0) 2373 goto ret; 2374 2375ret: 2376 if (buf) 2377 Xfree((char *)buf); 2378 2379 return (unconv_num1 + unconv_num2); 2380} 2381 2382static int 2383cstombs( 2384 XlcConv conv, 2385 XPointer *from, 2386 int *from_left, 2387 XPointer *to, 2388 int *to_left, 2389 XPointer *args, 2390 int num_args) 2391{ 2392 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 2393 char *buf_ptr1 = buf; 2394 int buf_left1 = (*from_left); 2395 char *buf_ptr2 = buf_ptr1; 2396 int buf_left2; 2397 int unconv_num1 = 0, unconv_num2 = 0; 2398 2399 unconv_num1 = cstowcs(conv, 2400 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2401 if (unconv_num1 < 0) 2402 goto ret; 2403 2404 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 2405 2406 unconv_num2 += wcstombs_org(conv, 2407 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2408 if (unconv_num2 < 0) 2409 goto ret; 2410 2411ret: 2412 if (buf) 2413 Xfree((char *)buf); 2414 2415 return (unconv_num1 + unconv_num2); 2416} 2417 2418static int 2419strtombs( 2420 XlcConv conv, 2421 XPointer *from, 2422 int *from_left, 2423 XPointer *to, 2424 int *to_left, 2425 XPointer *args, 2426 int num_args) 2427{ 2428 State state = (State) conv->state; 2429 XLCd lcd = state->lcd; 2430 2431 char *encoding; 2432 unsigned long mb, glyph_index; 2433 unsigned char ch; 2434 2435 int length; 2436 int unconv_num = 0; 2437 2438 CodeSet codeset; 2439 2440 const char *inbufptr = *from; 2441 char *outbufptr = *to; 2442 int from_size = *from_left; 2443 2444#ifdef notdef 2445 if (*from_left > *to_left) 2446 *from_left = *to_left; 2447#endif 2448 2449 while (*from_left && *to_left) { 2450 2451 ch = *inbufptr++; 2452 (*from_left)--; 2453 2454 /* null ? */ 2455 if (!ch) { 2456 if (outbufptr) {*outbufptr++ = '\0';} 2457 (*to_left)--; 2458 2459 continue; 2460 } 2461 2462 /* convert */ 2463 if (isleftside(ch)) { 2464 glyph_index = ch; 2465 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); 2466 } else { 2467 glyph_index = ch & GL; 2468 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); 2469 } 2470 2471 if (!codeset) { 2472 unconv_num++; 2473 continue; 2474 } 2475 2476 mb = gi_to_mb(glyph_index, codeset); 2477 if (codeset->parse_info) { 2478 Bool need_shift = False; 2479 switch (codeset->parse_info->type) { 2480 case E_LSL : 2481 if (codeset != state->GL_codeset) { 2482 need_shift = True; 2483 state->GL_codeset = codeset; 2484 } 2485 break; 2486 case E_LSR : 2487 if (codeset != state->GR_codeset) { 2488 need_shift = True; 2489 state->GR_codeset = codeset; 2490 } 2491 break; 2492 /* case E_SS */ 2493 default: 2494 need_shift = True; 2495 } 2496 2497 /* output shift sequence */ 2498 if (need_shift) { 2499 encoding = codeset->parse_info->encoding; 2500 length = strlen(encoding); 2501 if (*to_left < length) 2502 break; 2503 if (outbufptr) { 2504 strncpy((char *)outbufptr, encoding, length); 2505 outbufptr += length; 2506 } 2507 (*to_left) -= length; 2508 } 2509 } 2510 2511 /* output characters */ 2512 length = codeset->length; 2513 if (*to_left < length) 2514 break; 2515 2516 if (outbufptr) { 2517 output_ulong_value(outbufptr, mb, length, XlcNONE); 2518 outbufptr += length; 2519 } 2520 2521 (*to_left) -= length; 2522 2523 } /* end of while */ 2524 2525 *from = (XPointer) ((const char *) *from + from_size); 2526 *from_left = 0; 2527 *to = (XPointer) outbufptr; 2528 2529 return unconv_num; 2530} 2531 2532static int 2533strtowcs( 2534 XlcConv conv, 2535 XPointer *from, 2536 int *from_left, 2537 XPointer *to, 2538 int *to_left, 2539 XPointer *args, 2540 int num_args) 2541{ 2542 State state = (State) conv->state; 2543 XLCd lcd = state->lcd; 2544 2545 unsigned char ch; 2546 unsigned long glyph_index; 2547 wchar_t wc; 2548 2549 int unconv_num = 0; 2550 CodeSet codeset; 2551 2552 const char *inbufptr = *from; 2553 wchar_t *outbufptr = (wchar_t *)*to; 2554 int from_size = *from_left; 2555 2556#ifdef notdef 2557 if (*from_left > *to_left) 2558 *from_left = *to_left; 2559#endif 2560 2561 while (*from_left && *to_left) { 2562 2563 ch = *inbufptr++; 2564 (*from_left)--; 2565 2566 /* null ? */ 2567 if (!ch) { 2568 if (outbufptr) {*outbufptr++ = L'\0';} 2569 (*to_left)--; 2570 2571 continue; 2572 } 2573 2574 /* convert */ 2575 if (isleftside(ch)) { 2576 glyph_index = ch; 2577 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); 2578 } else { 2579 glyph_index = ch & GL; 2580 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); 2581 } 2582 2583 if (!codeset) { 2584 unconv_num++; 2585 continue; 2586 } 2587 2588 gi_to_wc(lcd, glyph_index, codeset, &wc); 2589 if (outbufptr) {*outbufptr++ = wc;} 2590 (*to_left)--; 2591 2592 } /* end of while */ 2593 2594 *from = (XPointer) ((const char *) *from + from_size); 2595 *from_left = 0; 2596 *to = (XPointer) outbufptr; 2597 2598 return unconv_num; 2599} 2600 2601static int 2602stdc_strtowcs( 2603 XlcConv conv, 2604 XPointer *from, 2605 int *from_left, 2606 XPointer *to, 2607 int *to_left, 2608 XPointer *args, 2609 int num_args) 2610{ 2611 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 2612 char *buf_ptr1 = buf; 2613 int buf_left1 = (*from_left) * MB_CUR_MAX; 2614 char *buf_ptr2 = buf_ptr1; 2615 int buf_left2; 2616 int unconv_num1 = 0, unconv_num2 = 0; 2617 2618 unconv_num1 = strtombs(conv, 2619 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2620 if (unconv_num1 < 0) 2621 goto ret; 2622 2623 buf_left2 = buf_ptr1 - buf_ptr2; 2624 2625 unconv_num2 = stdc_mbstowcs(conv, 2626 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2627 if (unconv_num2 < 0) 2628 goto ret; 2629 2630ret: 2631 if (buf) 2632 Xfree((char *)buf); 2633 2634 return (unconv_num1 + unconv_num2); 2635} 2636 2637/* -------------------------------------------------------------------------- */ 2638/* Close */ 2639/* -------------------------------------------------------------------------- */ 2640 2641static void 2642close_converter( 2643 XlcConv conv) 2644{ 2645 if (conv->state) { 2646 Xfree((char *) conv->state); 2647 } 2648 2649 if (conv->methods) { 2650 Xfree((char *) conv->methods); 2651 } 2652 2653 Xfree((char *) conv); 2654} 2655 2656/* -------------------------------------------------------------------------- */ 2657/* Open */ 2658/* -------------------------------------------------------------------------- */ 2659 2660static XlcConv 2661create_conv( 2662 XLCd lcd, 2663 XlcConvMethods methods) 2664{ 2665 XlcConv conv; 2666 State state; 2667 2668 conv = (XlcConv) Xcalloc(1, sizeof(XlcConvRec)); 2669 if (conv == NULL) 2670 return (XlcConv) NULL; 2671 2672 conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); 2673 if (conv->methods == NULL) 2674 goto err; 2675 *conv->methods = *methods; 2676 conv->methods->reset = init_state; 2677 2678 conv->state = Xcalloc(1, sizeof(StateRec)); 2679 if (conv->state == NULL) 2680 goto err; 2681 2682 state = (State) conv->state; 2683 state->lcd = lcd; 2684 2685 _XlcResetConverter(conv); 2686 2687 return conv; 2688 2689err: 2690 close_converter(conv); 2691 2692 return (XlcConv) NULL; 2693} 2694 2695static XlcConvMethodsRec mbstocts_methods = { 2696 close_converter, 2697 mbstocts, 2698 NULL 2699}; 2700 2701static XlcConv 2702open_mbstocts( 2703 XLCd from_lcd, 2704 const char *from_type, 2705 XLCd to_lcd, 2706 const char *to_type) 2707{ 2708 return create_conv(from_lcd, &mbstocts_methods); 2709} 2710 2711static XlcConvMethodsRec mbstostr_methods = { 2712 close_converter, 2713 mbstostr, 2714 NULL 2715}; 2716 2717static XlcConv 2718open_mbstostr( 2719 XLCd from_lcd, 2720 const char *from_type, 2721 XLCd to_lcd, 2722 const char *to_type) 2723{ 2724 return create_conv(from_lcd, &mbstostr_methods); 2725} 2726 2727static XlcConvMethodsRec mbstocs_methods = { 2728 close_converter, 2729 mbstocs, 2730 NULL 2731}; 2732 2733static XlcConv 2734open_mbstocs( 2735 XLCd from_lcd, 2736 const char *from_type, 2737 XLCd to_lcd, 2738 const char *to_type) 2739{ 2740 return create_conv(from_lcd, &mbstocs_methods); 2741} 2742 2743static XlcConvMethodsRec mbtocs_methods = { 2744 close_converter, 2745 mbtocs, 2746 NULL 2747}; 2748 2749static XlcConv 2750open_mbtocs( 2751 XLCd from_lcd, 2752 const char *from_type, 2753 XLCd to_lcd, 2754 const char *to_type) 2755{ 2756 return create_conv(from_lcd, &mbtocs_methods); 2757} 2758 2759static XlcConvMethodsRec ctstombs_methods = { 2760 close_converter, 2761 ctstombs, 2762 NULL 2763}; 2764 2765static XlcConv 2766open_ctstombs( 2767 XLCd from_lcd, 2768 const char *from_type, 2769 XLCd to_lcd, 2770 const char *to_type) 2771{ 2772 return create_conv(from_lcd, &ctstombs_methods); 2773} 2774 2775static XlcConvMethodsRec cstombs_methods = { 2776 close_converter, 2777 cstombs, 2778 NULL 2779}; 2780 2781static XlcConv 2782open_cstombs( 2783 XLCd from_lcd, 2784 const char *from_type, 2785 XLCd to_lcd, 2786 const char *to_type) 2787{ 2788 return create_conv(from_lcd, &cstombs_methods); 2789} 2790 2791static XlcConvMethodsRec strtombs_methods = { 2792 close_converter, 2793 strtombs, 2794 NULL 2795}; 2796 2797static XlcConv 2798open_strtombs( 2799 XLCd from_lcd, 2800 const char *from_type, 2801 XLCd to_lcd, 2802 const char *to_type) 2803{ 2804 return create_conv(from_lcd, &strtombs_methods); 2805} 2806 2807#ifdef STDCVT 2808 2809static XlcConvMethodsRec stdc_mbstowcs_methods = { 2810 close_converter, 2811 stdc_mbstowcs, 2812 NULL 2813}; 2814 2815static XlcConv 2816open_stdc_mbstowcs( 2817 XLCd from_lcd, 2818 const char *from_type, 2819 XLCd to_lcd, 2820 const char *to_type) 2821{ 2822 return create_conv(from_lcd, &stdc_mbstowcs_methods); 2823} 2824 2825static XlcConvMethodsRec stdc_wcstombs_methods = { 2826 close_converter, 2827 stdc_wcstombs, 2828 NULL 2829}; 2830 2831static XlcConv 2832open_stdc_wcstombs( 2833 XLCd from_lcd, 2834 const char *from_type, 2835 XLCd to_lcd, 2836 const char *to_type) 2837{ 2838 return create_conv(from_lcd, &stdc_wcstombs_methods); 2839} 2840 2841static XlcConvMethodsRec stdc_wcstocts_methods = { 2842 close_converter, 2843 stdc_wcstocts, 2844 NULL 2845}; 2846 2847static XlcConv 2848open_stdc_wcstocts( 2849 XLCd from_lcd, 2850 const char *from_type, 2851 XLCd to_lcd, 2852 const char *to_type) 2853{ 2854 return create_conv(from_lcd, &stdc_wcstocts_methods); 2855} 2856 2857static XlcConvMethodsRec stdc_wcstostr_methods = { 2858 close_converter, 2859 stdc_wcstostr, 2860 NULL 2861}; 2862 2863static XlcConv 2864open_stdc_wcstostr( 2865 XLCd from_lcd, 2866 const char *from_type, 2867 XLCd to_lcd, 2868 const char *to_type) 2869{ 2870 return create_conv(from_lcd, &stdc_wcstostr_methods); 2871} 2872 2873static XlcConvMethodsRec stdc_wcstocs_methods = { 2874 close_converter, 2875 stdc_wcstocs, 2876 NULL 2877}; 2878 2879static XlcConv 2880open_stdc_wcstocs( 2881 XLCd from_lcd, 2882 const char *from_type, 2883 XLCd to_lcd, 2884 const char *to_type) 2885{ 2886 return create_conv(from_lcd, &stdc_wcstocs_methods); 2887} 2888 2889static XlcConvMethodsRec stdc_wctocs_methods = { 2890 close_converter, 2891 stdc_wctocs, 2892 NULL 2893}; 2894 2895static XlcConv 2896open_stdc_wctocs( 2897 XLCd from_lcd, 2898 const char *from_type, 2899 XLCd to_lcd, 2900 const char *to_type) 2901{ 2902 return create_conv(from_lcd, &stdc_wctocs_methods); 2903} 2904 2905static XlcConvMethodsRec stdc_ctstowcs_methods = { 2906 close_converter, 2907 stdc_ctstowcs, 2908 NULL 2909}; 2910 2911static XlcConv 2912open_stdc_ctstowcs( 2913 XLCd from_lcd, 2914 const char *from_type, 2915 XLCd to_lcd, 2916 const char *to_type) 2917{ 2918 return create_conv(from_lcd, &stdc_ctstowcs_methods); 2919} 2920 2921static XlcConvMethodsRec stdc_cstowcs_methods = { 2922 close_converter, 2923 stdc_cstowcs, 2924 NULL 2925}; 2926 2927static XlcConv 2928open_stdc_cstowcs( 2929 XLCd from_lcd, 2930 const char *from_type, 2931 XLCd to_lcd, 2932 const char *to_type) 2933{ 2934 return create_conv(from_lcd, &stdc_cstowcs_methods); 2935} 2936 2937static XlcConvMethodsRec stdc_strtowcs_methods = { 2938 close_converter, 2939 stdc_strtowcs, 2940 NULL 2941}; 2942 2943static XlcConv 2944open_stdc_strtowcs( 2945 XLCd from_lcd, 2946 const char *from_type, 2947 XLCd to_lcd, 2948 const char *to_type) 2949{ 2950 return create_conv(from_lcd, &stdc_strtowcs_methods); 2951} 2952 2953#endif /* STDCVT */ 2954 2955static XlcConvMethodsRec mbstowcs_methods = { 2956 close_converter, 2957 mbstowcs_org, 2958 NULL 2959}; 2960 2961static XlcConv 2962open_mbstowcs( 2963 XLCd from_lcd, 2964 const char *from_type, 2965 XLCd to_lcd, 2966 const char *to_type) 2967{ 2968 return create_conv(from_lcd, &mbstowcs_methods); 2969} 2970 2971static XlcConvMethodsRec wcstombs_methods = { 2972 close_converter, 2973 wcstombs_org, 2974 NULL 2975}; 2976 2977static XlcConv 2978open_wcstombs( 2979 XLCd from_lcd, 2980 const char *from_type, 2981 XLCd to_lcd, 2982 const char *to_type) 2983{ 2984 return create_conv(from_lcd, &wcstombs_methods); 2985} 2986 2987static XlcConvMethodsRec wcstocts_methods = { 2988 close_converter, 2989 wcstocts, 2990 NULL 2991}; 2992 2993static XlcConv 2994open_wcstocts( 2995 XLCd from_lcd, 2996 const char *from_type, 2997 XLCd to_lcd, 2998 const char *to_type) 2999{ 3000 return create_conv(from_lcd, &wcstocts_methods); 3001} 3002 3003static XlcConvMethodsRec wcstostr_methods = { 3004 close_converter, 3005 wcstostr, 3006 NULL 3007}; 3008 3009static XlcConv 3010open_wcstostr( 3011 XLCd from_lcd, 3012 const char *from_type, 3013 XLCd to_lcd, 3014 const char *to_type) 3015{ 3016 return create_conv(from_lcd, &wcstostr_methods); 3017} 3018 3019static XlcConvMethodsRec wcstocs_methods = { 3020 close_converter, 3021 wcstocs, 3022 NULL 3023}; 3024 3025static XlcConv 3026open_wcstocs( 3027 XLCd from_lcd, 3028 const char *from_type, 3029 XLCd to_lcd, 3030 const char *to_type) 3031{ 3032 return create_conv(from_lcd, &wcstocs_methods); 3033} 3034 3035static XlcConvMethodsRec wctocs_methods = { 3036 close_converter, 3037 wctocs, 3038 NULL 3039}; 3040 3041static XlcConv 3042open_wctocs( 3043 XLCd from_lcd, 3044 const char *from_type, 3045 XLCd to_lcd, 3046 const char *to_type) 3047{ 3048 return create_conv(from_lcd, &wctocs_methods); 3049} 3050 3051static XlcConvMethodsRec ctstowcs_methods = { 3052 close_converter, 3053 ctstowcs, 3054 NULL 3055}; 3056 3057static XlcConv 3058open_ctstowcs( 3059 XLCd from_lcd, 3060 const char *from_type, 3061 XLCd to_lcd, 3062 const char *to_type) 3063{ 3064 return create_conv(from_lcd, &ctstowcs_methods); 3065} 3066 3067static XlcConvMethodsRec cstowcs_methods = { 3068 close_converter, 3069 cstowcs, 3070 NULL 3071}; 3072 3073static XlcConv 3074open_cstowcs( 3075 XLCd from_lcd, 3076 const char *from_type, 3077 XLCd to_lcd, 3078 const char *to_type) 3079{ 3080 return create_conv(from_lcd, &cstowcs_methods); 3081} 3082 3083static XlcConvMethodsRec strtowcs_methods = { 3084 close_converter, 3085 strtowcs, 3086 NULL 3087}; 3088 3089static XlcConv 3090open_strtowcs( 3091 XLCd from_lcd, 3092 const char *from_type, 3093 XLCd to_lcd, 3094 const char *to_type) 3095{ 3096 return create_conv(from_lcd, &strtowcs_methods); 3097} 3098 3099/* -------------------------------------------------------------------------- */ 3100/* Loader */ 3101/* -------------------------------------------------------------------------- */ 3102 3103XLCd 3104_XlcGenericLoader( 3105 const char *name) 3106{ 3107 XLCd lcd; 3108#ifdef STDCVT 3109 XLCdGenericPart *gen; 3110#endif 3111 3112 lcd = _XlcCreateLC(name, _XlcGenericMethods); 3113 3114 if (lcd == NULL) 3115 return lcd; 3116 3117 default_GL_charset = _XlcGetCharSet("ISO8859-1:GL"); 3118 default_GR_charset = _XlcGetCharSet("ISO8859-1:GR"); 3119 3120 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts); 3121 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr); 3122 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); 3123 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); 3124 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs); 3125 _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs); 3126 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); 3127 3128#ifdef STDCVT 3129 gen = XLC_GENERIC_PART(lcd); 3130 3131 if (gen->use_stdc_env != True) { 3132#endif 3133 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs); 3134 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs); 3135 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts); 3136 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr); 3137 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); 3138 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_wctocs); 3139 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs); 3140 _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_strtowcs); 3141 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); 3142#ifdef STDCVT 3143 } 3144#endif 3145 3146#ifdef STDCVT 3147 if (gen->use_stdc_env == True) { 3148 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_stdc_mbstowcs); 3149 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_stdc_wcstombs); 3150 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_stdc_wcstocts); 3151 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_stdc_wcstostr); 3152 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_stdc_wcstocs); 3153 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_stdc_wctocs); 3154 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_stdc_ctstowcs); 3155 _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_stdc_strtowcs); 3156 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_stdc_cstowcs); 3157 } 3158#endif 3159 3160 _XlcAddUtf8Converters(lcd); 3161 3162 return lcd; 3163} 3164