1%% options 2 3copyright owner = Dirk Krause 4copyright year = 2011-xxxx 5SPDX-License-Identifier: BSD-3-Clause 6 7 8 9%% header 10 11/** @file dk3uc2l.h 32-bit character to LaTeX conversion. 12 13This module was rewritten in August 2015, so it uses the same *.t2l files 14as the dk4uc2l module. 15During this rewrite the functionality was stripped down to those functions 16used by the itadmin program. 17 18*/ 19 20#include "dk3conf.h" 21#include <libdk3c/dk3types.h> 22 23#ifdef __cplusplus 24extern "C" { 25#endif 26 27/** Open LaTeX encoder. 28 @param d Directory containing the tables. 29 @param f_utf8 Flag: UTF-8 output encoding. 30 @param app Application structure for diagnostics, may be NULL. 31 @return Pointer to new encoder on success, NULL on error. 32*/ 33dk3_uc2lat_t * 34dk3uc2lat_open_app(dkChar const *d, int f_utf8, dk3_app_t *app); 35 36/** Close LaTeX encoder. 37 @param u Encoder to close. 38*/ 39void 40dk3uc2lat_close(dk3_uc2lat_t *u); 41 42/** Retrieve LaTeX encoding for one 32-bit character. 43 @param u LaTeX encoder. 44 @param c32 Character to obtain LaTeX encoding for. 45 @param ismath Flag: In math mode. 46 @return Pointer to encoding on success, NULL on error. 47*/ 48char const * 49dk3uc2lat_get(dk3_uc2lat_t *u, dk3_c32_t c32, int ismath); 50 51/** Check whether a character can be written to a LaTeX file directly. 52 @param c32 Character to check. 53 @return 1 for yes, 0 for no. 54*/ 55int 56dk3uc2lat_direct(dk3_c32_t c32); 57 58/** Write LaTeX encoding for a string to a stream. 59 @param u LaTeX encoder. 60 @param st Stream to write to. 61 @param t Text to write (ASCII/ISO-LATIN-1 encoded). 62 @return 1 on success, 0 on error. 63*/ 64int 65dk3uc2lat_c8_plain_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t); 66 67/** Write LaTeX encoding for a string to a stream. 68 @param u LaTeX encoder. 69 @param st Stream to write to. 70 @param t Text to write (UTF-8 encoded). 71 @return 1 on success, 0 on error. 72*/ 73int 74dk3uc2lat_c8_utf8_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t); 75 76/** Write LaTeX encoding for a string to a stream. 77 @param u LaTeX encoder. 78 @param st Stream to write to. 79 @param t Text to write (UTF-16 encoded). 80 @return 1 on success, 0 on error. 81*/ 82int 83dk3uc2lat_c16_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c16_t const *t); 84 85/** Write LaTeX encoding for a string to a stream. 86 @param u LaTeX encoder. 87 @param st Stream to write to. 88 @param t Text to write (32-bit characters). 89 @return 1 on success, 0 on error. 90*/ 91int 92dk3uc2lat_c32_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t const *t); 93 94/** Write LaTeX encoding for a string to a stream. 95 @param u LaTeX encoder. 96 @param st Stream to write to. 97 @param t Text to write (dkChar characters). 98 @param e Encoding (only used for 8-bit characters). 99 @return 1 on success, 0 on error. 100*/ 101int 102dk3uc2lat_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dkChar const *t, int e); 103 104#if HAVE_PACKAGES 105 106/** Prepare LaTeX encoder to retrieve package information. 107 @param u LaTeX encoder. 108*/ 109void 110dk3uc2lat_package_reset(dk3_uc2lat_t *u); 111 112/** Retrieve next package information from LaTeX encoder. 113 @param u LaTeX encoder. 114 @return Pointer to next package information or NULL. 115*/ 116dk3_uc2lat_pkg_t * 117dk3uc2lat_package_next(dk3_uc2lat_t *u); 118 119#endif 120 121/** Reset font encoding information. 122*/ 123void 124dk3uc2lat_font_encoding_reset(void); 125 126/** Check for font encoding conflicts. 127 @return 1 on conflicts, 0 otherwise (no problems). 128*/ 129int 130dk3uc2lat_font_encoding_conflict(void); 131 132/** Report font encoding requirement conflicts. 133 @param u LaTeX encoder. 134*/ 135void 136dk3uc2lat_font_encoding_report_conflict(dk3_uc2lat_t *u); 137 138/** Report font encoding requirement conflicts. 139 @param u LaTeX encoder. 140*/ 141void 142dk3uc2lat_font_encoding_report(dk3_uc2lat_t *u); 143 144/** Write some final comments to output stream about 145 usable encdings and required packages. 146 @param u LaTeX encoder. 147 @param st Output stream. 148*/ 149void 150dk3uc2lat_final_report(dk3_uc2lat_t *u, dk3_stream_t *st); 151 152#ifdef __cplusplus 153} 154#endif 155 156 157 158%% module 159 160/** Enable or disable support for dk3_uc2l_pkg_t. 161*/ 162#define HAVE_PACKAGES 1 163 164 165#include <libdk3c/dk3all.h> 166#include <libdk3c/dk3maih8.h> 167#include <libdk3c/dk3unused.h> 168#include <itadmin/dk3uc2l.h> 169 170 171$!trace-include 172 173 174 175/** LaTeX commands to start and end math mode. 176*/ 177static char const * const dk3uc2lat_mm[] = { 178"\\(", 179"\\)", 180"% font encodings:", 181"% package: ", 182"\n", 183}; 184 185 186 187#if 0 188/** Font encoding names. 189*/ 190static char const * const dk3uc2lat_font_encodings[] = { 191"ot1", 192"!ot1", 193"t1", 194"!t1", 195"t4", 196"!t4", 197"t5", 198"!t5", 199NULL 200}; 201#endif 202 203 204#if 0 205/** Font encoding names, used in error messages. 206 Why unused ?! 207*/ 208static dkChar const * const dk3uc2l_font_encoding_names[] = { 209dkT("OT1"), 210dkT("T1"), 211dkT("T4"), 212dkT("T5"), 213NULL 214}; 215#endif 216 217 218/** Font encoding names written at end of output file. 219*/ 220static const char * const dk3uc2l_c8_font_encoding_names[] = { 221$!string-table 222 OT1 223 T1 224 T4 225 T5 226$!end 227}; 228 229 230 231/** Allowed suffixes for conversion data files. 232*/ 233static dkChar const * const dk3uc2l_suffixes[] = { 234dkT(".t2l"), 235#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1) 236dkT(".t2l.gz"), 237#endif 238#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1) 239dkT(".t2l.bz2"), 240#endif 241NULL 242}; 243 244 245 246/** Compression suffixes. 247*/ 248static dkChar const * const dk3uc2l_co_suf[] = { 249$!string-table macro=dkT 250.gz 251.bz2 252$!end 253}; 254 255 256 257/** Attribute keywords. 258*/ 259static const char * const dk3uc2l_kw[] = { 260$!string-table 261b$oth 262t$ext 263m$ath 264e$ncoding 265p$ackages 266$!end 267}; 268 269 270 271/** Encoding names, used for reporting. 272*/ 273static const char * const dk3uc2l_enco[] = { 274$!string-table 275ot1 276t1 277t4 278t5 279$!end 280}; 281 282 283 284/** Release an array of string pointers. 285 @param ap Array base address. 286 @param ns Number of strings. 287*/ 288static 289void 290dk3uc2lat_release_pointer_array(char const **ap, size_t ns) 291{ 292 char const **ptr; /* Current string in array. */ 293 size_t i; /* Current string index in array. */ 294 $? "+ dk3uc2lat_release_pointer_array %lu", (unsigned long)ns 295 ptr = ap; i = ns; 296 while(i--) { 297 dk3_release(*ptr); 298 ptr++; 299 } $? "- dk3uc2lat_release_pointer_array" 300 dk3_delete(ap); 301} 302 303 304 305/** Destroy range structure, release memory. 306 @param rp Structure to destroy. 307*/ 308static 309void 310dk3uc2lat_range_delete(dk3_uc2lat_range_t *rp) 311{ 312 size_t numchar; /* Number of characters in this range. */ 313 dkChar const **ptr; /* Release all descriptions. */ 314 dk3_uc2lat_pkg_t ***pkgppp; 315 size_t i; /* Number of descriptions to release. */ 316 $? "+ dk3uc2lat_range_delete %lx %lx", dk3enc_uc_to_ul(rp->start), dk3enc_uc_to_ul(rp->end) 317 if(rp) { 318 numchar = (size_t)(rp->end - rp->start + 1); 319 if(numchar > 0) { 320 rp->dir = NULL; 321 if(rp->f) { 322 dk3_release(rp->f); 323 } rp->f = NULL; 324 if(rp->dsc) { 325 ptr = rp->dsc; 326 i = (size_t)(rp->end - rp->start + 1); 327 while(i--) { 328 dk3_release(*ptr); 329 ptr++; 330 } 331 } rp->dsc = NULL; 332 if(rp->a) { 333 dk3uc2lat_release_pointer_array(rp->a, numchar); 334 } rp->a = NULL; 335 if(rp->t) { 336 dk3uc2lat_release_pointer_array(rp->t, numchar); 337 } rp->t = NULL; 338 if(rp->m) { 339 dk3uc2lat_release_pointer_array(rp->m, numchar); 340 } rp->m = NULL; 341 if(rp->p) { 342 pkgppp = rp->p; 343 i = (size_t)(rp->end - rp->start + 1); 344 while (i--) { 345 dk3_release(*pkgppp); 346 pkgppp++; 347 } 348 dk3_delete(rp->p); 349 } rp->p = NULL; 350 rp->start = (dk3_c32_t)0UL; rp->end = (dk3_c32_t)0UL; 351 rp->ia = 0x00; 352 } 353 dk3_delete(rp); 354 } $? "- dk3uc2lat_range_delete" 355} 356 357 358#if HAVE_PACKAGES 359 360/** Destroy package structure, release memory. 361 @param pp Structure to release. 362*/ 363static 364void 365dk3uc2lat_pkg_delete(dk3_uc2lat_pkg_t *pp) 366{ 367 $? "+ dk3uc2lat_pkg_delete %!8s", TR_8PTR(pp) 368 if(pp) { $? ". pkg name = \"%!8s\"", TR_8STR(pp->name) 369 dk3_release(pp->name); 370 pp->used = 0x00; 371 dk3_delete(pp); 372 } $? "- dk3uc2lat_pkg_delete" 373} 374 375#endif 376 377 378/** Destroy UC to LaTeX directory structure, release memory. 379 @param dp Structure to destroy. 380*/ 381static 382void 383dk3uc2lat_dir_delete(dk3_uc2lat_dir_t *dp) 384{ 385 $? "+ dk3uc2lat_dir_delete %!8s", TR_8PTR(dp) 386 if(dp) { 387 if(dp->s_ran) { 388 if(dp->i_ran) { 389 dk3sto_it_close(dp->i_ran); 390 } dp->i_ran = NULL; 391 dk3sto_close(dp->s_ran); 392 } dp->s_ran = NULL; 393 dk3_release(dp->sn); 394 dp->loaded = 0x00; 395 dk3_delete(dp); 396 } $? "- dk3uc2lat_dir_delete" 397} 398 399 400 401#if HAVE_PACKAGES 402 403/** Compare two package records. 404 @param l Left record. 405 @param r Right record or name. 406 @param cr Comparison criteria (0=record/record, 1=record/name). 407 @return Comparison result. 408*/ 409static 410int 411dk3uc2lat_pkg_compare(void const *l, void const *r, int cr) 412{ 413 int back = 0; 414 dk3_uc2lat_pkg_t const *pl; /* Left pointer. */ 415 dk3_uc2lat_pkg_t const *pr; /* Right pointer. */ 416 417 pl = (dk3_uc2lat_pkg_t const *)l; 418 pr = (dk3_uc2lat_pkg_t const *)r; 419 if(l) { 420 if(r) { 421 switch(cr) { 422 case 1: { 423 if(pl->name) { 424 back = dk3str_c8_cmp(pl->name, (char const *)r); 425 } else { back = -1; } 426 } break; 427 default: { 428 if(pl->name) { 429 if(pr->name) { 430 back = dk3str_c8_cmp(pl->name, pr->name); 431 } else { back = 1; } 432 } else { 433 if(pr->name) { back = -1; } 434 } 435 } break; 436 } 437 } else { back = 1; } 438 } else { 439 if(r) { back = -1; } 440 } 441 if(back < -1) { back = -1; } 442 if(back > 1) { back = 1; } 443 return back; 444} 445 446#endif 447 448 449 450/** Compare two range structures by start and end character. 451 @param l Left structure. 452 @param r Right structure/UC character. 453 @param cr Comparison criteria (0=struct/struct, 1=struct/char). 454 @return Comparison result. 455*/ 456static 457int 458dk3uc2lat_range_compare(void const *l, void const *r, int cr) 459{ 460 int back = 0; 461 dk3_uc2lat_range_t const *pl; /* Left pointer. */ 462 dk3_uc2lat_range_t const *pr; /* Right pointer. */ 463 dk3_c32_t *ucptr; /* Right pointer is a character pointer. */ 464 465 pl = (dk3_uc2lat_range_t const *)l; 466 pr = (dk3_uc2lat_range_t const *)r; 467 if(l) { 468 if(r) { 469 switch(cr) { 470 case 1: { 471 ucptr = (dk3_c32_t *)r; 472 if(pl->start > (*ucptr)) { 473 back = 1; 474 } else { 475 if(pl->end < (*ucptr)) { 476 back = -1; 477 } 478 } 479 } break; 480 default: { 481 if(pl->start > pr->end) { 482 back = 1; 483 } else { 484 if(pl->end < pr->start) { 485 back = -1; 486 } 487 } 488 } break; 489 } 490 } else { back = 1; } 491 } else { 492 if(r) { back = -1; } 493 } 494 return back; 495} 496 497 498 499/** Compare two UC to LaTeX directory structures. 500 @param l Left structure. 501 @param r Right structure/name. 502 @param cr Comparison criteria (0=struct/struct, 1=struct/name). 503 @return Comparison result. 504*/ 505static 506int 507dk3uc2lat_dir_compare(void const *l, void const *r, int cr) 508{ 509 int back = 0; 510 dk3_uc2lat_dir_t const *pl; /* Left pointer. */ 511 dk3_uc2lat_dir_t const *pr; /* Right pointer. */ 512 513 pl = (dk3_uc2lat_dir_t const *)l; 514 pr = (dk3_uc2lat_dir_t const *)r; 515 if(l) { 516 if(r) { 517 switch(cr) { 518 case 1: { 519 if(pl->sn) { 520 back = dk3str_fncmp(pl->sn, (dkChar const *)r); 521 } else { back = -1; } 522 } break; 523 default: { 524 if(pl->sn) { 525 if(pr->sn) { 526 back = dk3str_fncmp(pl->sn, pr->sn); 527 } else { back = 1; } 528 } else { 529 if(pr->sn) { back = -1; } 530 } 531 } break; 532 } 533 } else { back = 1; } 534 } else { 535 if(r) { back = -1; } 536 } 537 return back; 538} 539 540 541 542void 543dk3uc2lat_close(dk3_uc2lat_t *u) 544{ 545#if HAVE_PACKAGES 546 dk3_uc2lat_pkg_t *ppkg; 547#endif 548 dk3_uc2lat_dir_t *pdir; 549 dk3_uc2lat_range_t *pran; 550 $? "+ dk3uc2lat_close" 551 if (NULL != u) { 552 u->app = NULL; 553 dk3_release(u->dir); 554 dk3_release(u->buf); 555 if (NULL != u->s_ran) { 556 if (NULL != u->i_ran) { 557 dk3sto_it_reset(u->i_ran); 558 do { 559 pran = (dk3_uc2lat_range_t *)dk3sto_it_next(u->i_ran); 560 if (NULL != pran) { 561 dk3uc2lat_range_delete(pran); 562 } 563 } while (NULL != pran); 564 dk3sto_it_close(u->i_ran); 565 } 566 dk3sto_close(u->s_ran); 567 } 568 u->s_ran = NULL; u->i_ran = NULL; 569 if (NULL != u->s_dir) { 570 if (NULL != u->i_dir) { 571 dk3sto_it_reset(u->i_dir); 572 do { 573 pdir = (dk3_uc2lat_dir_t *)dk3sto_it_next(u->i_dir); 574 if (NULL != pdir) { 575 dk3uc2lat_dir_delete(pdir); 576 } 577 } while (NULL != pdir); 578 dk3sto_it_close(u->i_dir); 579 } 580 dk3sto_close(u->s_dir); 581 } 582 u->s_dir = NULL; u->i_dir = NULL; 583#if HAVE_PACKAGES 584 if (NULL != u->s_pkg) { 585 if (NULL != u->i_pkg) { 586 dk3sto_it_reset(u->i_pkg); 587 do { 588 ppkg = (dk3_uc2lat_pkg_t *)dk3sto_it_next(u->i_pkg); 589 if (NULL != ppkg) { 590 dk3uc2lat_pkg_delete(ppkg); 591 } 592 } while (NULL != ppkg); 593 dk3sto_it_close(u->i_pkg); 594 } 595 dk3sto_close(u->s_pkg); 596 } 597 u->s_pkg = NULL; u->i_pkg = NULL; 598#endif 599 u->rca = NULL; 600 u->szbuf = 0; 601 u->f_dsc = 0; 602 u->f_utf8 = 0; 603 u->fe = 0; 604 dk3_delete(u); 605 } 606 $? "- dk3uc2lat_close" 607} 608 609 610 611#if HAVE_PACKAGES 612 613/** Create package structure, allocate memory. 614 @param pn Package name. 615 @param app Application structure for diagnostics. 616 @return Pointer to new structure on success, NULL on error. 617*/ 618static 619dk3_uc2lat_pkg_t * 620dk3uc2lat_pkg_new(char const *pn, dk3_app_t *app) 621{ 622 dk3_uc2lat_pkg_t *back = NULL; 623 $? "+ dk3uc2lat_pkg_new \"%!8s\"", TR_8STR(pn) 624 back = dk3_new_app(dk3_uc2lat_pkg_t,1,app); 625 if(back) { 626 back->used = 0x00; 627 back->name = dk3str_c8_dup_app(pn,app); 628 if(!(back->name)) { 629 dk3uc2lat_pkg_delete(back); 630 back = NULL; 631 } 632 } $? "- dk3uc2lat_pkg_new %!8s", TR_8PTR(back) 633 return back; 634} 635 636#endif 637 638 639/** Create range structure, allocate memory. 640 @param start Start character of range. 641 @param end End character of range. 642 @param dir Directory structure (parent of this range). 643 @param app Application structure for diagnostics. 644 @return Pointer to new range structure on success, NULL on error. 645*/ 646static 647dk3_uc2lat_range_t * 648dk3uc2lat_range_new( 649 dk3_c32_t start, dk3_c32_t end, dk3_uc2lat_dir_t *dir, dk3_app_t *app 650) 651{ 652 dk3_uc2lat_range_t *back = NULL; 653 char range_text[32]; /* Buffer for number range. */ 654 dkChar dk_range_text[32]; /* Buffer for number range. */ 655 $? "+ dk3uc2lat_range_new %lx %lx", dk3enc_uc_to_ul(start), dk3enc_uc_to_ul(end) 656 if(dk3app_max_log_level(app) >= DK3_LL_DEBUG) { 657 sprintf(range_text, "%lx-%lx", (long)start, (long)end); 658 (void)dk3str_c8_to_str_simple_app(dk_range_text, 32, range_text, app); 659 dk3app_log_i3(app, DK3_LL_DEBUG, 238, 239, dk_range_text); 660 } 661 if(end >= start) { 662 back = dk3_new_app(dk3_uc2lat_range_t,1,app); 663 if(back) { 664 back->dir = dir; 665 back->dsc = NULL; 666 back->a = NULL; 667 back->t = NULL; 668 back->m = NULL; 669#if HAVE_PACKAGES 670 back->p = NULL; 671#endif 672 back->f = NULL; 673 back->start = start; 674 back->end = end; 675 back->ia = 0x00; 676 } 677 } else { 678 if(app) { 679 dk3app_log_i1(app, DK3_LL_ERROR, 220); 680 } 681 } $? "- dk3uc2lat_range_new %!8s", TR_8PTR(back) 682 return back; 683} 684 685 686 687/** Create UC to LaTeX directory structure, allocate memory. 688 @param sn Short directory file name. 689 @param app Application structure for diagnostics. 690 @return Pointer to new directory structure on success, NULL on error. 691*/ 692static 693dk3_uc2lat_dir_t * 694dk3uc2lat_dir_new(dkChar const *sn, dk3_app_t *app) 695{ 696 dk3_uc2lat_dir_t *back = NULL; 697 $? "+ dk3uc2lat_dir_new \"%!ds\"", TR_STR(sn) 698 back = dk3_new_app(dk3_uc2lat_dir_t,1,app); 699 if(back) { 700 back->s_ran = NULL; back->i_ran = NULL; back->sn = NULL; 701 back->loaded = 0x00; 702 back->s_ran = dk3sto_open_app(app); 703 if(back->s_ran) { 704 dk3sto_set_comp(back->s_ran, dk3uc2lat_range_compare, 0); 705 back->i_ran = dk3sto_it_open(back->s_ran); 706 if(back->i_ran) { 707 back->sn = dk3str_dup_app(sn,app); 708 } 709 } 710 if(!((back->s_ran) && (back->i_ran) && (back->sn))) { 711 dk3uc2lat_dir_delete(back); back = NULL; 712 } 713 } $? "- dk3uc2lat_dir_new PTR:%d", TR_IPTR(back) 714 return back; 715} 716 717 718 719/** Create new LaTeX encoder. 720 @param dn Directory containing the data files. 721 @param f_utf8 Flag: Allowed to write UTF-8 output. 722 @param app Application structure for diagnostics, may be NULL. 723 @return Pointer to new encoder on success, NULL on error. 724*/ 725static 726dk3_uc2lat_t * 727dk3uc2lat_t_new( 728 const dkChar *dn, 729 int f_utf8, 730 dk3_app_t *app 731) 732{ 733 dk3_uc2lat_t *back = NULL; 734 int ok = 0; 735 $? "+ dk3uc2lat_t_new %!ds", dn 736 back = dk3_new_app(dk3_uc2lat_t,1,app); 737 if (NULL != back) { 738 back->app = app; 739 back->dir = NULL; 740 back->buf = NULL; 741 back->s_ran = NULL; 742 back->i_ran = NULL; 743 back->s_dir = NULL; 744 back->i_dir = NULL; 745#if HAVE_PACKAGES 746 back->s_pkg = NULL; 747 back->i_pkg = NULL; 748#endif 749 back->rca = NULL; 750 back->szbuf = 0; 751 back->f_dsc = 0; 752 back->f_utf8 = f_utf8; 753 back->fe = 754 DK3_FONT_ENCODING_OT1 + DK3_FONT_ENCODING_T1 755 + DK3_FONT_ENCODING_T4 + DK3_FONT_ENCODING_T5; 756 back->dir = dk3str_dup_app(dn, app); 757 back->buf = dk3_new_app(char,16,app); 758 if (NULL != back->buf) { back->szbuf = 16; } 759 if ((NULL != back->dir) && (NULL != back->buf)) { 760 back->s_ran = dk3sto_open_app(app); 761 if (NULL != back->s_ran) { 762 dk3sto_set_comp(back->s_ran, dk3uc2lat_range_compare, 0); 763 back->s_dir = dk3sto_open_app(app); 764 if (NULL != back->s_dir) { 765 dk3sto_set_comp(back->s_dir, dk3uc2lat_dir_compare, 0); 766#if HAVE_PACKAGES 767 back->s_pkg = dk3sto_open_app(app); 768 if (NULL != back->s_pkg) { 769 dk3sto_set_comp(back->s_pkg, dk3uc2lat_pkg_compare, 0); 770#endif 771 back->i_ran = dk3sto_it_open(back->s_ran); 772 if (NULL != back->i_ran) { 773 back->i_dir = dk3sto_it_open(back->s_dir); 774 if (NULL != back->i_dir) { 775#if HAVE_PACKAGES 776 back->i_pkg = dk3sto_it_open(back->s_pkg); 777 if (NULL != back->i_pkg) { 778#endif 779 ok = 1; 780#if HAVE_PACKAGES 781 } 782#endif 783 } 784 } 785#if HAVE_PACKAGES 786 } 787#endif 788 } 789 } 790 } 791 if (0 == ok) { 792 dk3uc2lat_close(back); 793 back = NULL; 794 } 795 } $? "- dk3uc2lat_t_new PTR:%d", TR_IPTR(back) 796 return back; 797} 798 799 800 801/** Check the file name whether it contains LaTeX conversion data 802 and can be processed. 803 @param fn File name to check. 804 @return 1 if yes, 0 otherwise. 805*/ 806static 807int 808dk3uc2lat_is_suitable_file(const dkChar *fn) 809{ 810 const dkChar * const *ptr; /* Traverse allowed suffixes array */ 811 size_t szfn = 0; /* File name size */ 812 size_t szsu = 0; /* Allowed suffix size */ 813 int back = 0; 814 $? "+ dk3uc2lat_is_suitable_file %!ds", fn 815 szfn = dk3str_len(fn); 816 ptr = dk3uc2l_suffixes; 817 while ((NULL != *ptr) && (0 == back)) { 818 szsu = dk3str_len(*ptr); 819 if (szfn > szsu) { 820 if (0 == dk3str_fncmp(&(fn[szfn - szsu]), *ptr)) { 821 back = 1; 822 } 823 } 824 ptr++; 825 } $? "- dk3uc2lat_is_suitable_file %d", back 826 return back; 827} 828 829 830 831/** Add one character to the range descriptions of a file directory. 832 @param uptr Conversion structure to set up. 833 @param pdir File directory to set up. 834 @param chr Character to add. 835 @param app Application structure for diagnostics, may be NULL. 836 @return 1 on success, 0 on error. 837*/ 838static 839int 840dk3uc2l_add_char_to_dir( 841 dk3_uc2lat_t *uptr, 842 dk3_uc2lat_dir_t *pdir, 843 dk3_c32_t chr, 844 dk3_app_t *app 845) 846{ 847 dkChar cbuf[64]; 848 dk3_uc2lat_range_t *prange; 849 dk3_uc2lat_range_t *pr2; 850 size_t szcbuf = DK3_SIZEOF(cbuf,dkChar); 851 dk3_c32_t tchr; 852 int back = 0; 853 $? "+ dk3uc2l_add_char_to_dir %lx", dk3enc_uc_to_ul(chr) 854 prange = (dk3_uc2lat_range_t *)dk3sto_it_find_like(uptr->i_ran, &chr, 1); 855 if (NULL == prange) { 856 prange = (dk3_uc2lat_range_t *)dk3sto_it_find_like(pdir->i_ran, &chr, 1); 857 if (NULL == prange) { 858 if ((dk3_c32_t)0UL < chr) { $? ". try to append" 859 tchr = chr - 1; 860 prange = (dk3_uc2lat_range_t *)dk3sto_it_find_like(pdir->i_ran,&tchr,1); 861 if (NULL != prange) { $? ". found %lx-%lx", dk3enc_uc_to_ul(prange->start), dk3enc_uc_to_ul(prange->end) 862 prange->end = chr; 863 back = 1; $? ". changed to %lx-%lx", dk3enc_uc_to_ul(prange->start), dk3enc_uc_to_ul(prange->end) 864 if (dkC32(0xFFFFFFFF) > chr) { 865 tchr = chr + (dk3_c32_t)1UL; 866 pr2 = (dk3_uc2lat_range_t *)dk3sto_it_find_like( 867 pdir->i_ran, &tchr, 1 868 ); 869 if (NULL != pr2) { $? ". found %lx-%lx", dk3enc_uc_to_ul(pr2->start), dk3enc_uc_to_ul(pr2->end) 870 tchr = pr2->end; 871 dk3sto_remove(pdir->s_ran, pr2); 872 dk3uc2lat_range_delete(pr2); 873 prange->end = tchr; 874 $? ". changed %lx-%lx", dk3enc_uc_to_ul(prange->start), dk3enc_uc_to_ul(prange->end) 875 } 876 } 877 } 878 } 879 if (0 == back) { $? ". try to prepend" 880 if (dkC32(0xFFFFFFFF) > chr) { $? ". can" 881 tchr = chr + (dk3_c32_t)1UL; 882 prange = (dk3_uc2lat_range_t *)dk3sto_it_find_like( 883 pdir->i_ran, &tchr, 1 884 ); 885 if (NULL != prange) { $? ". found %lx-%lx", dk3enc_uc_to_ul(prange->start), dk3enc_uc_to_ul(prange->end) 886 prange->start = chr; 887 back = 1; $? ". changed to %lx-%lx", dk3enc_uc_to_ul(prange->start), dk3enc_uc_to_ul(prange->end) 888 } 889 } 890 } 891 if (0 == back) { $? ". try to add" 892 prange = dk3uc2lat_range_new(chr, chr, pdir, app); 893 if (NULL != prange) { 894 if (dk3sto_add(pdir->s_ran, prange)) { 895 back = 1; $? ". added %lx-%lx", dk3enc_uc_to_ul(prange->start), dk3enc_uc_to_ul(prange->end) 896 } else { 897 dk3uc2lat_range_delete(prange); 898 } 899 } 900 } 901 } else { $? "! already found" 902 /* ERROR: Already found! */ 903 if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)chr, 8)) { 904 dk3app_log_i3(uptr->app, DK3_LL_ERROR, 395, 396, cbuf); 905 } else { 906 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 397); 907 } 908 } 909 } else { $? "! already found" 910 /* ERROR: Already found ! */ 911 if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)chr, 8)) { 912 dk3app_log_i3(uptr->app, DK3_LL_ERROR, 395, 396, cbuf); 913 } else { 914 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 397); 915 } 916 } $? "- dk3uc2l_add_char_to_dir %d", back 917 return back; 918} 919 920 921 922/** Apply data from stream to directory information for one file. 923 @param uptr Conversion structure to set up. 924 @param pdir File directory entry to configure. 925 @param istrm Input stream for file (normal or compressed). 926 @param app Application structure for diagnostics, may be NULL. 927 @return 1 on success, 0 on error. 928*/ 929static 930int 931dk3uc2l_apply_1( 932 dk3_uc2lat_t *uptr, 933 dk3_uc2lat_dir_t *pdir, 934 dk3_stream_t *istrm, 935 dk3_app_t *app 936) 937{ 938 char buf[512]; 939 char *p1; 940 char *p2; 941 dk3_uc2lat_range_t *prange; 942 unsigned long lineno = 0UL; 943 unsigned long chr; 944 int back = 1; 945 $? "+ dk3uc2l_apply_1" 946 while ((1 == back) && (1 == dk3stream_c8_fgets(istrm, buf, sizeof(buf)))) { 947 dk3app_set_source_line(app, ++lineno); 948 buf[sizeof(buf) - 1] = '\0'; 949 $? ". processing line %lu: %s", lineno, buf 950 p1 = dk3str_c8_start(buf, NULL); 951 if (NULL != p1) { 952 if ('#' != *p1) { 953 p2 = dk3str_c8_next(p1, NULL); 954 if (NULL != p2) { 955 if (0 != dk3ma_ul_from_c8_hex_string(&chr, p1, NULL)) { 956 if (0 == dk3uc2l_add_char_to_dir(uptr, pdir, (dk3_c32_t)chr, app)) { 957 back = 0; $? "! failed to add %lx", chr 958 } 959 } else { 960 /* ERROR: Syntax error, not a hexadecimal number */ 961 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 398); 962 } 963 } else { 964 /* ERROR: Syntax error, missing configuration */ 965 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 400); 966 } 967 } 968 } 969 } 970 if (1 == back) { $? ". copying ranges to global container" 971 dk3sto_it_reset(pdir->i_ran); 972 do { 973 prange = (dk3_uc2lat_range_t *)dk3sto_it_next(pdir->i_ran); 974 if (NULL != prange) { $? ". range %lx-%lx", dk3enc_uc_to_ul(prange->start), dk3enc_uc_to_ul(prange->end) 975 if (0 == dk3sto_add(uptr->s_ran, prange)) { 976 dk3uc2lat_range_delete(prange); 977 back = 0; $? "! failed to copy range" 978 } 979 } 980 } while (NULL != prange); 981 } else { $? "! deleting ranges due to error" 982 dk3sto_it_reset(pdir->i_ran); 983 do { 984 prange = (dk3_uc2lat_range_t *)dk3sto_it_next(pdir->i_ran); 985 if (NULL != prange) { 986 dk3uc2lat_range_delete(prange); 987 } 988 } while (NULL != prange); 989 } $? "- dk3uc2l_apply_1 %d", back 990 return back; 991} 992 993 994 995/** Apply directory information for a file. 996 @param uptr Conversion structure to set up. 997 @param fn File name containing conversion data. 998 @param app Application structure for diagnostics, may be NULL. 999 @return 1 on success, 0 on error. 1000*/ 1001static 1002int 1003dk3uc2lat_pass_1( 1004 dk3_uc2lat_t *uptr, const dkChar *fn, const dkChar *sn, dk3_app_t *app 1005) 1006{ 1007 dk3_uc2lat_dir_t *pdir = NULL; 1008 dk3_stream_t *istrm = NULL; 1009 FILE *fipo = NULL; 1010 const dkChar *oldsrc = NULL; 1011 const dkChar *fsuf = NULL; 1012#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1) 1013 gzFile gzf = NULL; 1014#endif 1015#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1) 1016 BZFILE *bzf = NULL; 1017#endif 1018 unsigned long oldln = 0UL; 1019#if DK3_HAVE_FNCASEINS 1020 int fncs = 0; 1021#else 1022 int fncs = 1; 1023#endif 1024 int back = 0; 1025 $? ". dk3uc2lat_pass_1 %!ds", fn 1026 pdir = dk3uc2lat_dir_new(sn, app); 1027 if (NULL != pdir) { 1028 oldsrc = dk3app_get_source_file(app); 1029 oldln = dk3app_get_source_line(app); 1030 dk3app_set_source_file(app, fn); 1031 dk3app_set_source_line(app, 0UL); 1032 if (0 != dk3sto_add(uptr->s_dir, pdir)) { 1033 fsuf = dk3str_get_suffix(fn); 1034 switch (dk3str_array_index(dk3uc2l_co_suf, fsuf, fncs)) { 1035 case 0: { /* gz */ 1036#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1) 1037 gzf = gzopen(fn, "r"); 1038 if (NULL != gzf) { 1039 istrm = dk3stream_open_gz_app(gzf, DK3_STREAM_FLAG_READ, app); 1040 if (NULL != istrm) { 1041 back = dk3uc2l_apply_1(uptr, pdir, istrm, app); 1042 (void)dk3stream_close(istrm); 1043 } 1044 gzclose(gzf); 1045 } else { 1046 /* ERROR: Failed to open file */ 1047 dk3app_log_i3(uptr->app, DK3_LL_ERROR, 143, 144, fn); 1048 } 1049#else 1050 /* ERROR: No zlib support */ 1051 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 401); 1052#endif 1053 } break; 1054 case 1: { /* bz2 */ 1055#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1) 1056 bzf = BZ2_bzopen(fn, "r"); 1057 if (NULL != bzf) { 1058 istrm = dk3stream_open_bz2_app(bzf, DK3_STREAM_FLAG_READ, app); 1059 if (NULL != istrm) { 1060 back = dk3uc2l_apply_1(uptr, pdir, istrm, app); 1061 (void)dk3stream_close(istrm); 1062 } 1063 BZ2_bzclose(bzf); 1064 } else { 1065 /* ERROR: Failed to open file */ 1066 dk3app_log_i3(uptr->app, DK3_LL_ERROR, 143, 144, fn); 1067 } 1068#else 1069 /* ERROR: No bzip2 support */ 1070 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 402); 1071#endif 1072 } break; 1073 default : { /* normal file */ 1074 fipo = dk3sf_fopen_app(fn, dkT("r"), app); 1075 if (NULL != fipo) { 1076 istrm = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app); 1077 if (NULL != istrm) { 1078 back = dk3uc2l_apply_1(uptr, pdir, istrm, app); 1079 (void)dk3stream_close(istrm); 1080 } 1081 fclose(fipo); 1082 } 1083 } break; 1084 } 1085 } else { 1086 dk3uc2lat_dir_delete(pdir); 1087 } 1088 dk3app_set_source_file(app, oldsrc); 1089 dk3app_set_source_line(app, oldln); 1090 } $? "- dk3uc2lat_pass_1 %d", back 1091 return back; 1092} 1093 1094 1095 1096/** Read directory information (check existing data files, retrieve ranges. 1097 @param d Directory containing the data files. 1098 @param uptr Conversion structure to initialize. 1099 @param app Application structure for diagnostics, may be NULL. 1100 @return 1 on success, 0 on error. 1101*/ 1102static 1103int 1104dk3uc2lat_read_dir_info(dk3_uc2lat_t *uptr, dk3_app_t *app) 1105{ 1106 dk3_dir_t *dir = NULL; 1107 const dkChar *fn = NULL; 1108 const dkChar *sn = NULL; 1109 int back = 0; 1110 int found = 0; 1111 $? "+ dk3uc2lat_read_dir_info" 1112 dir = dk3dir_open_app(uptr->dir, uptr->app); 1113 if (NULL != dir) { 1114 back = 1; 1115 while (0 != dk3dir_get_next_file(dir)) { 1116 sn = dk3dir_get_shortname(dir); 1117 fn = dk3dir_get_fullname(dir); 1118 if ((NULL != sn) && (NULL != fn)) { 1119 if (0 != dk3uc2lat_is_suitable_file(fn)) { 1120 found = 1; 1121 if (0 == dk3uc2lat_pass_1(uptr, fn, sn, app)) { 1122 back = 0; 1123 } 1124 } 1125 } 1126 } 1127 dk3dir_close(dir); 1128 if (0 == found) { 1129 back = 0; 1130 /* ERROR: No suitable files found */ 1131 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 403); 1132 } 1133 } 1134 $? "- dk3uc2lat_read_dir_info %d", back 1135 return back; 1136} 1137 1138 1139 1140/** Allocate memory for all ranges details for a file directory. 1141 @param uptr Conversion structure to set up. 1142 @param pdir Directory information to set up. 1143 @return 1 on success, 0 on error. 1144*/ 1145static 1146int 1147dk3uc2l_allocate_memory( 1148 dk3_uc2lat_t *uptr, 1149 dk3_uc2lat_dir_t *pdir 1150) 1151{ 1152 dk3_uc2lat_range_t *prange; 1153 size_t sz; 1154 size_t i; 1155 int back = 1; 1156 int allenc = 0; 1157 1158 dk3sto_it_reset(pdir->i_ran); 1159 allenc = DK3_FONT_ENCODING_OT1 1160 + DK3_FONT_ENCODING_T1 1161 + DK3_FONT_ENCODING_T4 1162 + DK3_FONT_ENCODING_T5; 1163 do { 1164 prange = (dk3_uc2lat_range_t *)dk3sto_it_next(pdir->i_ran); 1165 if (NULL != prange) { 1166 sz = (size_t)(prange->end - prange->start) + 1; 1167 if (NULL == prange->a) { 1168 prange->a = dk3_new_app(DK3_PCCHAR,sz,uptr->app); 1169 if (NULL != prange->a) { 1170 for (i = 0; i < sz; i++) { (prange->a)[i] = NULL; } 1171 } else { 1172 back = 0; 1173 } 1174 } 1175 if (NULL == prange->t) { 1176 prange->t = dk3_new_app(DK3_PCCHAR,sz,uptr->app); 1177 if (NULL != prange->t) { 1178 for (i = 0; i < sz; i++) { (prange->t)[i] = NULL; } 1179 } else { 1180 back = 0; 1181 } 1182 } 1183 if (NULL == prange->m) { 1184 prange->m = dk3_new_app(DK3_PCCHAR,sz,uptr->app); 1185 if (NULL != prange->m) { 1186 for (i = 0; i < sz; i++) { (prange->m)[i] = NULL; } 1187 } else { 1188 back = 0; 1189 } 1190 } 1191#if HAVE_PACKAGES 1192 if (NULL == prange->p) { 1193 prange->p = dk3_new_app(dk3_uc2lat_pkg_pptr,sz,uptr->app); 1194 if (NULL != prange->p) { 1195 for (i = 0; i < sz; i++) { (prange->p)[i] = NULL; } 1196 } else { 1197 back = 0; 1198 } 1199 } 1200#endif 1201 if (NULL == prange->f) { 1202 prange->f = dk3_new_app(dk3_font_encoding_t,sz,uptr->app); 1203 if (NULL != prange->f) { 1204 for(i = 0; i < sz; i++) { 1205 (prange->f)[i] = (dk3_font_encoding_t)allenc; 1206 } 1207 } else { 1208 back = 0; 1209 } 1210 } 1211 } 1212 } while (NULL != prange); 1213 return back; 1214} 1215 1216 1217 1218static 1219void 1220dk3uc2l_apply_2( 1221 dk3_uc2lat_t *uptr, 1222 dk3_uc2lat_dir_t *pdir, 1223 dk3_stream_t *istrm 1224) 1225{ 1226 char buf[512]; /* Input line buffer */ 1227#if HAVE_PACKAGES 1228 char *parts[16]; /* Package names */ 1229#endif 1230 char *p1; /* Hex value or next item */ 1231 char *p2; /* Current item key */ 1232 char *p3; /* Current item value */ 1233 char *p4; /* Dynamic value copy */ 1234 dk3_uc2lat_range_t *prange; /* Current range */ 1235#if HAVE_PACKAGES 1236 dk3_uc2lat_pkg_t *ppkg; /* Current package */ 1237#endif 1238 unsigned long lineno = 0UL; /* Current line number */ 1239 unsigned long chr; /* Current character */ 1240 size_t ind; /* Index of chr in range */ 1241#if HAVE_PACKAGES 1242 size_t nparts; /* Number of packages */ 1243 size_t i; /* Traverse */ 1244 size_t j; /* Add new packages */ 1245#endif 1246 int cc = 1; /* Flag: Can continue */ 1247 int action; /* Action to take */ 1248 int isneg; /* Flag: Deny encodings */ 1249 int encod; /* Encodings selection */ 1250 $? "+ dk3uc2l_apply_2" 1251 while ((1 == cc) && (1 == dk3stream_c8_fgets(istrm, buf, sizeof(buf)))) { 1252 dk3app_set_source_line(uptr->app, ++lineno); 1253 buf[sizeof(buf) - 1] = '\0'; 1254 $? ". processing line %lu: %s", lineno, buf 1255 p1 = dk3str_c8_start(buf, NULL); 1256 if (NULL != p1) { $? ". p1=\"%!8s\"", p1 1257 if ('#' != *p1) { $? ". normal line" 1258 p2 = dk3str_c8_next(p1, NULL); 1259 if (NULL != p2) { $? ". attributes=\"%!8s\"", p2 1260 if (0 != dk3ma_ul_from_c8_hex_string(&chr, p1, NULL)) { 1261 prange = 1262 (dk3_uc2lat_range_t *)dk3sto_it_find_like(pdir->i_ran, &chr, 1); 1263 if (NULL != prange) { $? ". range found" 1264 ind = (size_t)(chr - (unsigned long)(prange->start)); 1265 while (NULL != p2) { 1266 p1 = dk3str_c8_next(p2, NULL); 1267 p3 = dk3str_c8_chr(p2, '='); 1268 if (NULL != p3) { 1269 *(p3++) = '\0'; 1270#if 0 1271 /* 2015-08-10 Bugfix: Must be start */ 1272 p3 = dk3str_c8_next(p3, NULL); 1273#endif 1274 p3 = dk3str_c8_start(p3, NULL); 1275 if (NULL != p3) { $? ". \"%!8s\"=\"%!8s\"", p2, p3 1276 action = dk3str_c8_array_abbr(dk3uc2l_kw, p2, '$', 0); 1277 $? ". action = %d", action 1278 switch (action) { 1279 case 0: { /* both */ $? ". both" 1280 if (NULL != prange->a) { 1281 p4 = dk3str_c8_dup_app(p3, uptr->app); 1282 if (NULL != p4) { 1283 dk3_release((prange->a)[ind]); 1284 (prange->a)[ind] = p4; 1285 } 1286 } 1287 } break; 1288 case 1: { /* text */ $? ". text" 1289 if (NULL != prange->t) { 1290 p4 = dk3str_c8_dup_app(p3, uptr->app); 1291 if (NULL != p4) { 1292 dk3_release((prange->t)[ind]); 1293 (prange->t)[ind] = p4; 1294 } 1295 } 1296 } break; 1297 case 2: { /* math */ $? ". math" 1298 if (NULL != prange->m) { 1299 p4 = dk3str_c8_dup_app(p3, uptr->app); 1300 if (NULL != p4) { 1301 dk3_release((prange->m)[ind]); 1302 (prange->m)[ind] = p4; 1303 } 1304 } 1305 } break; 1306 case 3: { /* encoding */ $? ". encoding" 1307 if (NULL != prange->f) { 1308 isneg = 0; encod = 0; 1309 if ('!' == *p3) { 1310 isneg = 1; p3++; 1311 } 1312 while (NULL != p3) { 1313 p4 = dk3str_c8_chr(p3, ','); 1314 if (NULL != p4) { 1315 *(p4++) = '\0'; 1316 p4 = dk3str_c8_start(p4, NULL); 1317 } 1318 switch (dk3str_c8_array_index(dk3uc2l_enco, p3, 0)) 1319 { 1320 case 0: { /* OT1 */ 1321 encod |= DK3_FONT_ENCODING_OT1; 1322 } break; 1323 case 1: { /* T1 */ 1324 encod |= DK3_FONT_ENCODING_T1; 1325 } break; 1326 case 2: { /* T4 */ 1327 encod |= DK3_FONT_ENCODING_T4; 1328 } break; 1329 case 3: { /* T5 */ 1330 encod |= DK3_FONT_ENCODING_T5; 1331 } break; 1332 default : { 1333 /* Syntax error, unknown encoding */ 1334 dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 404); 1335 } break; 1336 } 1337 p3 = p4; 1338 } 1339 if (0 != isneg) { encod = (~(encod)); } 1340 (prange->f)[ind] = (dk3_font_encoding_t)encod; 1341 } 1342 } break; 1343 case 4: { /* packages */ $? ". packages" 1344#if HAVE_PACKAGES 1345 if (NULL != prange->p) { 1346 nparts = dk3str_c8_explode(parts, 15, p3, ","); 1347 if (0 < nparts) { 1348 dk3_release((prange->p)[ind]); 1349 (prange->p)[ind] = 1350 dk3_new_app(dk3_uc2lat_pkg_ptr,(nparts+1),uptr->app); 1351 if (NULL != (prange->p)[ind]) { 1352 for (i = 0; i < (nparts+1); i++) { 1353 ((prange->p)[ind])[i] = NULL; 1354 } 1355 j = 0; 1356 for (i = 0; i < nparts; i++) { 1357 ppkg = (dk3_uc2lat_pkg_t *)dk3sto_it_find_like( 1358 uptr->i_pkg, parts[i], 1 1359 ); 1360 if (NULL != ppkg) { 1361 ((prange->p)[ind])[j++] = ppkg; 1362 } else { 1363 ppkg = dk3uc2lat_pkg_new(parts[i], uptr->app); 1364 if (NULL != ppkg) { 1365 if (dk3sto_add(uptr->s_pkg, ppkg)) { 1366 ((prange->p)[ind])[j++] = ppkg; 1367 } else { 1368 dk3uc2lat_pkg_delete(ppkg); 1369 } 1370 } 1371 } 1372 } 1373 } 1374 } else { 1375 /* ERROR: Syntax, no packages */ 1376 dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 405); 1377 } 1378 } 1379#endif 1380 } break; 1381 default: { $? "! unknown key" 1382 } break; 1383 } 1384 } else { $? "! missing attribute value" 1385 /* ERROR: Value missing */ 1386 dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 406); 1387 } 1388 } else { $? "! missing attribute value" 1389 /* ERROR: Syntax, not a key value pair */ 1390 dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 406); 1391 } 1392 p2 = p1; 1393 } 1394 } else { $? "! bug: range not found" 1395 /* BUG or file changed */ 1396 } 1397 } else { 1398 /* ERROR: Syntax error, not a hexadecimal number */ 1399 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 398); 1400 } 1401 } else { $? "! missing attributes" 1402 /* ERROR: Syntax error, missing configuration */ 1403 dk3app_log_i1(uptr->app, DK3_LL_ERROR, 401); 1404 } 1405 } else { $? ". ignore comment line" 1406 } 1407 } else { $? ". ignore empty line" 1408 } 1409 } $? "- dk3uc2l_apply_2" 1410} 1411 1412 1413 1414static 1415void 1416dk3uc2lat_load_file(dk3_uc2lat_t *u, dk3_uc2lat_dir_t *pdir) 1417{ 1418 dkChar fnb[DK3_MAX_PATH]; 1419 dk3_stream_t *istrm = NULL; 1420 FILE *fipo = NULL; 1421 const dkChar *oldsrc = NULL; 1422 const dkChar *fsuf = NULL; 1423#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1) 1424 gzFile gzf = NULL; 1425#endif 1426#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1) 1427 BZFILE *bzf = NULL; 1428#endif 1429 unsigned long oldln = 0UL; 1430#if DK3_HAVE_FNCASEINS 1431 int fncs = 0; 1432#else 1433 int fncs = 1; 1434#endif 1435 size_t sz; 1436 $? "+ dk3uc2lat_load_file" 1437 sz = dk3str_len(u->dir); 1438 sz += dk3str_len(pdir->sn); 1439 sz += 1; 1440 if (sizeof(fnb) > sz) { $? ". file name length ok" 1441 dk3str_cpy(fnb, u->dir); 1442 dk3str_cat(fnb, dk3app_not_localized(20)); 1443 dk3str_cat(fnb, pdir->sn); 1444 dk3str_correct_filename(fnb); 1445 oldsrc = dk3app_get_source_file(u->app); 1446 oldln = dk3app_get_source_line(u->app); 1447 dk3app_set_source_file(u->app, fnb); 1448 dk3app_set_source_line(u->app, 0UL); 1449 if (0 != dk3uc2l_allocate_memory(u, pdir)) { $? ". memory allocated" 1450 fsuf = dk3str_get_suffix(fnb); 1451 switch (dk3str_array_index(dk3uc2l_co_suf, fsuf, fncs)) { 1452 case 0: { $? ". zlib compressed" 1453#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1) 1454 gzf = gzopen(fnb, "r"); 1455 if (NULL != gzf) { 1456 istrm = dk3stream_open_gz_app(gzf, DK3_STREAM_FLAG_READ, u->app); 1457 if (NULL != istrm) { 1458 dk3uc2l_apply_2(u, pdir, istrm); 1459 (void)dk3stream_close(istrm); 1460 } 1461 gzclose(gzf); 1462 } else { 1463 /* ERROR: Failed to open file */ 1464 dk3app_log_i3(u->app, DK3_LL_ERROR, 143, 144, fnb); 1465 } 1466#else 1467 /* ERROR: No zlib support */ 1468 dk3app_log_i1(u->app, DK3_LL_ERROR, 401); 1469#endif 1470 } break; 1471 case 1: { $? ". bzip2 compressed" 1472#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1) 1473 bzf = BZ2_bzopen(fnb, "r"); 1474 if (NULL != bzf) { 1475 istrm = dk3stream_open_bz2_app(bzf, DK3_STREAM_FLAG_READ, u->app); 1476 if (NULL != istrm) { 1477 dk3uc2l_apply_2(u, pdir, istrm); 1478 (void)dk3stream_close(istrm); 1479 } 1480 BZ2_bzclose(bzf); 1481 } else { 1482 /* ERROR: Failed to open file */ 1483 dk3app_log_i3(u->app, DK3_LL_ERROR, 143, 144, fnb); 1484 } 1485#else 1486 /* ERROR: No bzip2 support */ 1487 dk3app_log_i1(u->app, DK3_LL_ERROR, 402); 1488#endif 1489 } break; 1490 default: { $? ". normal file" 1491 fipo = dk3sf_fopen_app(fnb, dkT("r"), u->app); 1492 if (NULL != fipo) { 1493 istrm = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, u->app); 1494 if (NULL != istrm) { 1495 dk3uc2l_apply_2(u, pdir, istrm); 1496 (void)dk3stream_close(istrm); 1497 } 1498 fclose(fipo); 1499 } 1500 } break; 1501 } 1502 } else { $? "! memory allocation error" 1503 } 1504 dk3app_set_source_file(u->app, oldsrc); 1505 dk3app_set_source_line(u->app, oldln); 1506 } else { $? "! file name too long" 1507 /* ERROR: Name too long */ 1508 dk3app_log_i3(u->app, DK3_LL_ERROR, 65, 66, pdir->sn); 1509 } 1510 pdir->loaded = 0x01; 1511 $? "- dk3uc2lat_load_file" 1512} 1513 1514 1515 1516/** Open conversion structure for a given directory. 1517 @param d Directory containing conversion files. 1518 @param f_desc Flag: Load glyph descriptions (ignored). 1519 @param f_utf8 Flag: UTF-8 output allowed. 1520 @param app Application structure for diagnostics, may be NULL. 1521 @return Pointer to new structure on success, NULL on error. 1522*/ 1523static 1524dk3_uc2lat_t * 1525dk3uc2lat_i_open_app( 1526 const dkChar *d, 1527 int f_utf8, 1528 dk3_app_t *app 1529) 1530{ 1531 dk3_uc2lat_t *back = NULL; 1532 $? "+ dk3uc2lat_i_open_app %!ds", d 1533 if (0 != dk3sf_is_dir_app(d, NULL)) { 1534 back = dk3uc2lat_t_new(d, f_utf8, app); 1535 if (NULL != back) { 1536 if (0 == dk3uc2lat_read_dir_info(back, app)) { 1537 dk3uc2lat_close(back); 1538 back = NULL; 1539 } 1540 } 1541 } else { 1542 /* ERROR: Not a directory ... */ 1543 dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, d); 1544 } 1545 $? "- dk3uc2lat_i_open_app PTR:%d", TR_IPTR(back) 1546 return back; 1547} 1548 1549 1550 1551dk3_uc2lat_t * 1552dk3uc2lat_open_app(dkChar const *d, int f_utf8, dk3_app_t *app) 1553{ 1554 dkChar fnb[DK3_MAX_PATH]; 1555 dk3_uc2lat_t *back = NULL; 1556 const dkChar *shd = NULL; 1557 const dkChar *dirn = NULL; 1558 size_t szfnb = DK3_SIZEOF(fnb,dkChar); 1559 size_t szshd = 0; 1560 $? "+ dk3uc2lat_open_app %!ds", TR_DKSTR(d) 1561 if (NULL != d) { 1562 back = dk3uc2lat_i_open_app(d, f_utf8, app); 1563 } else { 1564 if (NULL != app) { 1565 if (dk3app_get_dir_from_pref(app,dk3app_not_localized(48),fnb,szfnb,1)) 1566 { 1567 dk3str_correct_filename(fnb); 1568 back = dk3uc2lat_i_open_app(fnb, f_utf8, app); 1569 } else 1570 { 1571 shd = dk3app_get_sharedir(app); 1572 if (NULL != shd) { 1573 szshd = dk3str_len(shd); 1574 if (szfnb > szshd) { 1575 dk3str_cpy_not_overlapped(fnb, shd); 1576 dirn = dk3app_not_localized(49); 1577 if (szfnb > (szshd + dk3str_len(dirn))) { 1578 dk3str_cat(fnb, dirn); 1579 dk3str_correct_filename(fnb); 1580 back = dk3uc2lat_i_open_app(fnb, f_utf8, app); 1581 } else { 1582 /* ERROR: Directory name too long! */ 1583 dk3app_log_i3(app, DK3_LL_ERROR, 64, 66, dirn); 1584 } 1585 } else { 1586 /* ERROR: Share directory name too long! */ 1587 dk3app_log_i3(app, DK3_LL_ERROR, 64, 66, shd); 1588 } 1589 } else { 1590 /* ERROR: Missing share directory */ 1591 dk3app_log_i1(app, DK3_LL_ERROR, 407); 1592 } 1593 } 1594 } 1595 } $? "- dk3uc2lat_open_app %d", TR_IPTR(back) 1596 return back; 1597} 1598 1599 1600 1601char const * 1602dk3uc2lat_get(dk3_uc2lat_t *u, dk3_c32_t c32, int ismath) 1603{ 1604 dkChar cbuf[64]; 1605 dk3_uc2lat_range_t *prange = NULL; 1606 dk3_uc2lat_pkg_t **pkgpp; 1607 const char *back = NULL; 1608 size_t szcbuf = DK3_SIZEOF(cbuf,dkChar); 1609 $? "+ dk3uc2lat_get" 1610 if (NULL != u) { 1611 if (NULL != u->rca) { $? ". range cache available" 1612 if ((u->rca)->start <= c32) { $? ". start ok" 1613 if ((u->rca)->end >= c32) { $? ". end ok" 1614 prange = u->rca; $? ". use range cache" 1615 } 1616 } 1617 } 1618 if (NULL == prange) { $? ". find character" 1619 prange = (dk3_uc2lat_range_t *)dk3sto_it_find_like(u->i_ran, &c32, 1); 1620 if (NULL != prange) { $? ". range found" 1621 u->rca = prange; 1622 if (NULL != prange->p) { $? ". range->package" 1623 pkgpp = (prange->p)[(size_t)(c32 - prange->start)]; 1624 if (NULL != pkgpp) { 1625 while (NULL != *pkgpp) { 1626 (*(pkgpp++))->used = 0x01; 1627 } $? ". packages marked as used" 1628 } 1629 } 1630 } else { $? "! no range found" 1631 } 1632 } 1633 if (NULL != prange) { $? ". range found" 1634 if (NULL != prange->dir) { $? ". range has dir entry" 1635 if (0x00 == (prange->dir)->loaded) { $? ". must load" 1636 dk3uc2lat_load_file(u, prange->dir); 1637 } 1638 } 1639 if (0 != ismath) { $? ". math mode" 1640 if (NULL != prange->m) { $? ". math" 1641 back = (prange->m)[(size_t)(c32 - prange->start)]; 1642 } 1643 if (NULL == back) { 1644 if (NULL != prange->a) { $? ". all" 1645 back = (prange->a)[(size_t)(c32 - prange->start)]; 1646 } 1647 } 1648 } else { $? ". normal mode" 1649 if (NULL != prange->t) { $? ". text" 1650 back = (prange->t)[(size_t)(c32 - prange->start)]; 1651 } 1652 if (NULL == back) { $? ". all" 1653 if (NULL != prange->a) { 1654 back = (prange->a)[(size_t)(c32 - prange->start)]; 1655 } 1656 } 1657 } 1658 if (NULL != prange->f) { 1659 u->fe &= ((prange->f)[(size_t)(c32 - prange->start)]); 1660 } 1661 } else { 1662 /* ERROR: Not found */ 1663 if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)c32, 8)) { 1664 dk3app_log_i3(u->app, DK3_LL_ERROR, 409, 410, cbuf); 1665 } else { 1666 dk3app_log_i1(u->app, DK3_LL_ERROR, 408); 1667 } 1668 } 1669 } $? "- dk3uc2lat_get PTR:%d", TR_IPTR(back) 1670 return back; 1671} 1672 1673 1674 1675#if HAVE_PACKAGES 1676 1677void 1678dk3uc2lat_package_reset(dk3_uc2lat_t *u) 1679{ 1680 if (NULL != u) { 1681 dk3sto_it_reset(u->i_pkg); 1682 } 1683} 1684 1685 1686 1687dk3_uc2lat_pkg_t * 1688dk3uc2lat_package_next(dk3_uc2lat_t *u) 1689{ 1690 dk3_uc2lat_pkg_t *back = NULL; 1691 if (NULL != u) { 1692 back = (dk3_uc2lat_pkg_t *)dk3sto_it_next(u->i_pkg); 1693 } 1694 return back; 1695} 1696 1697#endif 1698 1699 1700 1701void 1702dk3uc2lat_font_encoding_reset(void) 1703{ 1704 /* UNUSED */ 1705} 1706 1707 1708 1709int 1710dk3uc2lat_font_encoding_conflict(void) 1711{ 1712 int back = 0; 1713 /* UNUSED */ 1714 return back; 1715} 1716 1717 1718 1719void 1720dk3uc2lat_font_encoding_report_conflict(dk3_uc2lat_t *u) 1721{ 1722 if (0x00 == u->fe) { 1723 /* Error */ 1724 dk3app_log_i1(u->app, DK3_LL_ERROR, 411); 1725 } 1726} 1727 1728 1729 1730static 1731void 1732dk3uc2lat_report_for_encoding(dk3_uc2lat_t *u, const char *eptr) 1733{ 1734#if DK3_CHAR_SIZE > 1 1735 dkChar buffer[32]; 1736 dkChar *dkptr = NULL; 1737 size_t szbu = DK3_SIZEOF(buffer,dkChar); 1738 if (szbu > strlen(eptr)) { 1739 dkptr = buffer; 1740 while ('\0' != *eptr) { 1741 *(dkptr++) = (dkChar)(*(eptr++)); 1742 } 1743 *dkptr = dkT('\0'); 1744 dk3app_log_i3(u->app, DK3_LL_INFO, 381, 382, buffer); 1745 } 1746#else 1747 dk3app_log_i3(u->app, DK3_LL_INFO, 381, 382, eptr); 1748#endif 1749} 1750 1751 1752 1753void 1754dk3uc2lat_font_encoding_report(dk3_uc2lat_t *u) 1755{ 1756 if (0 != ((u->fe) & DK3_FONT_ENCODING_OT1)) { 1757 dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[0]); 1758 } 1759 if (0 != ((u->fe) & DK3_FONT_ENCODING_T1)) { 1760 dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[1]); 1761 } 1762 if (0 != ((u->fe) & DK3_FONT_ENCODING_T4)) { 1763 dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[2]); 1764 } 1765 if (0 != ((u->fe) & DK3_FONT_ENCODING_T5)) { 1766 dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[3]); 1767 } 1768} 1769 1770 1771 1772int 1773dk3uc2lat_direct(dk3_c32_t c32) 1774{ 1775 int back = 0; 1776 char c; /* 8-bit character version of c32. */ 1777 $? "+ dk3uc2lat_direct %lx", dk3enc_uc_to_ul(c32) 1778 if(128UL > dk3enc_uc_to_ul((unsigned long)c32)) { 1779 c = (char)c32; 1780 switch(c) { 1781 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': 1782 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 1783 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': 1784 case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': 1785 case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': 1786 case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': 1787 case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': 1788 case 'X': case 'Y': case 'Z': case '0': case '1': case '2': case '3': 1789 case '4': case '5': case '6': case '7': case '8': case '9': case ',': 1790 case '.': case ':': case ';': case '+': case '-': case '?': case '!': 1791 case '|': case '@': case '(': case ')': case '/': case '=': case ' ': 1792 case '\t': 1793 { 1794 back = 1; 1795 } 1796 break; 1797 } 1798 } $? "- dk3uc2lat_direct %d", back 1799 return back; 1800} 1801 1802 1803 1804static 1805int 1806dk3uc2lat_stputc(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t ul, int *mmptr) 1807{ 1808 char buf[16]; 1809 const char *ptr; 1810 size_t sz; 1811 int back = 0; 1812 1813 if (0 != dk3uc2lat_direct(ul)) { 1814 if (0 != *mmptr) { 1815 dk3stream_c8_fputs(st, dk3uc2lat_mm[1]); 1816 *mmptr = 0; 1817 } 1818 if (u->f_utf8) { 1819 sz = dk3enc_uc2utf8(ul, (unsigned char *)buf, sizeof(buf)); 1820 buf[sz] = '\0'; 1821 } else { 1822 buf[0] = (char)ul; 1823 buf[1] = '\0'; 1824 } 1825 dk3stream_c8_fputs(st, buf); 1826 back = 1; 1827 } else { 1828 ptr = dk3uc2lat_get(u, ul, 0); 1829 if (NULL != ptr) { 1830 if (0 != *mmptr) { 1831 dk3stream_c8_fputs(st, dk3uc2lat_mm[1]); 1832 *mmptr = 0; 1833 } 1834 dk3stream_c8_fputs(st, ptr); 1835 } else { 1836 ptr = dk3uc2lat_get(u, ul, 1); 1837 if (NULL != ptr) { 1838 if (0 == *mmptr) { 1839 dk3stream_c8_fputs(st, dk3uc2lat_mm[0]); 1840 *mmptr = 1; 1841 } 1842 dk3stream_c8_fputs(st, ptr); 1843 } else { 1844 /* ERROR: Not found, already reported */ 1845 } 1846 } 1847 } 1848 return back; 1849} 1850 1851 1852 1853int 1854dk3uc2lat_c8_plain_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t) 1855{ 1856 int back = 0; 1857 int mm = 0; /* Flag: In math mode. */ 1858 char const *ptr; /* Current position. */ 1859 dk3_c32_t ul; /* Output character. */ 1860 char c; /* Current character. */ 1861 $? "+ dk3uc2lat_c8_plain_stputs \"%!8s\"", TR_8STR(t) 1862 if((u) && (st) && (t)) { 1863 ptr = t; back = 1; 1864 while(*ptr) { 1865 c = *ptr; 1866 ul = (unsigned long)c; 1867 ul &= 0x000000FFUL; 1868 if(!dk3uc2lat_stputc(u, st, ul, &mm)) { back = 0; } 1869 ptr++; 1870 } 1871 if(mm) { 1872 dk3stream_c8_fputs(st, dk3uc2lat_mm[1]); 1873 } 1874 } 1875 $? "- dk3uc2lat_c8_plain_stputs %d", back 1876 return back; 1877} 1878 1879 1880 1881int 1882dk3uc2lat_c8_utf8_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t) 1883{ 1884 int back = 0; 1885 int mm = 0; /* Flag: Math mode. */ 1886 unsigned char const *sp; /* String pointer, current pos. */ 1887 size_t sl; /* Remaining bytes. */ 1888 size_t used; /* Bytes used for current c32. */ 1889 dk3_c32_t c32; /* Current character. */ 1890 $? "+ dk3uc2lat_c8_utf8_stputs \"%!8s\"", TR_8STR(t) 1891 if((u) && (st) && (t)) { 1892 sp = (unsigned char const *)t; sl = dk3str_c8_len(t); back = 1; 1893 while(sl) { 1894 used = 0; 1895 if(dk3enc_utf82uc(&c32, sp, sl, &used)) { 1896 if(!dk3uc2lat_stputc(u, st, c32, &mm)) { 1897 back = 0; 1898 } 1899 if(used) { 1900 if(sl >= used) { 1901 sl = sl - used; 1902 sp = &(sp[used]); 1903 } else { 1904 sl = 0; back = 0; 1905 } 1906 } else { 1907 sl = 0; back = 0; /* No byte used, will appear again and again. */ 1908 } 1909 } else { 1910 sl = 0; back = 0; 1911 if(u->app) { 1912 /* ERROR: Decoding failed! */ 1913 dk3app_log_i1(u->app, DK3_LL_ERROR, 118); 1914 } 1915 } 1916 } 1917 if(mm) { 1918 dk3stream_c8_fputs(st, dk3uc2lat_mm[1]); 1919 } 1920 } 1921 $? "- dk3uc2lat_c8_utf8_stputs %d", back 1922 return back; 1923} 1924 1925 1926 1927int 1928dk3uc2lat_c16_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c16_t const *t) 1929{ 1930 int back = 0; 1931 int mm = 0; /* Flag: Math mode. */ 1932 dk3_c16_t const *sp; /* Current position. */ 1933 size_t sl; /* Number of 16-bit characters remaining. */ 1934 size_t used; /* Number of 16-bit characters used. */ 1935 dk3_c32_t c32; /* Current output character. */ 1936 $? "+ dk3uc2lat_c16_stputs %!8s", TR_8PTR(t) 1937 if((u) && (st) && (t)) { 1938 sp = t; sl = dk3str_c16_len(t); back = 1; 1939 while(sl) { 1940 used = 0; 1941 if(dk3enc_utf162uc(&c32, sp, sl, &used)) { 1942 if(used) { 1943 if(!dk3uc2lat_stputc(u, st, c32, &mm)) { back = 0; } 1944 if(sl >= used) { 1945 sl = sl - used; 1946 sp = &(sp[used]); 1947 } else { 1948 sl = 0; 1949 } 1950 } else { 1951 back = 0; sl = 0; 1952 if(u->app) { 1953 /* ERROR: Decoding */ 1954 dk3app_log_i1(u->app, DK3_LL_ERROR, 119); 1955 } 1956 } 1957 } else { 1958 sl = 0; back = 0; 1959 if(u->app) { 1960 /* Decoding error */ 1961 dk3app_log_i1(u->app, DK3_LL_ERROR, 119); 1962 } 1963 } 1964 } 1965 if(mm) { 1966 dk3stream_c8_fputs(st, dk3uc2lat_mm[1]); 1967 } 1968 } 1969 $? "- dk3uc2lat_c16_stputs %d", back 1970 return back; 1971} 1972 1973 1974 1975int 1976dk3uc2lat_c32_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t const *t) 1977{ 1978 int back = 0; 1979 int mm = 0; /* Flag: Math mode. */ 1980 dk3_c32_t const *ptr; /* Current position. */ 1981 $? "+ dk3uc2lat_c32_stputs %!8s", TR_8PTR(t) 1982 if((u) && (st) && (t)) { 1983 back = 1; 1984 ptr = t; 1985 while(*ptr) { 1986 if(!dk3uc2lat_stputc(u, st, *(ptr++), &mm)) { 1987 back = 0; 1988 } 1989 } 1990 if(mm) { 1991 dk3stream_c8_fputs(st, dk3uc2lat_mm[1]); 1992 } 1993 } 1994 $? "- dk3uc2lat_c32_stputs %d", back 1995 return back; 1996} 1997 1998 1999 2000int 2001dk3uc2lat_stputs( 2002 dk3_uc2lat_t *u, 2003 dk3_stream_t *st, 2004 dkChar const *t, 2005#if DK3_CHAR_SIZE > 1 2006 int DK3_ARG_UNUSED(e) 2007#else 2008 int e 2009#endif 2010) 2011{ 2012 int back = 0; 2013 $? "+ dk3uc2lat_stputs \"%!ds\"", TR_STR(t) 2014#if DK3_CHAR_SIZE > 1 2015 DK3_UNUSED_ARG(e) 2016#if DK3_CHAR_SIZE > 2 2017 back = dk3uc2lat_c32_stputs(u, st, t); 2018#else 2019 back = dk3uc2lat_c16_stputs(u, st, t); 2020#endif 2021#else 2022 switch(e) { 2023 case DK3_ENCODING_UTF8: { 2024 back = dk3uc2lat_c8_utf8_stputs(u, st, t); 2025 } break; 2026 default: { 2027 back = dk3uc2lat_c8_plain_stputs(u, st, t); 2028 } break; 2029 } 2030#endif 2031 $? "- dk3uc2lat_stputs %d", back 2032 return back; 2033} 2034 2035 2036 2037void 2038dk3uc2lat_final_report(dk3_uc2lat_t *u, dk3_stream_t *st) 2039{ 2040 dk3_uc2lat_pkg_t *pkgp; 2041 dk3stream_c8_fputs(st, dk3uc2lat_mm[2]); 2042 if (0 != ((u->fe) & DK3_FONT_ENCODING_OT1)) { 2043 dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[0]); 2044 } 2045 if (0 != ((u->fe) & DK3_FONT_ENCODING_T1)) { 2046 dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[1]); 2047 } 2048 if (0 != ((u->fe) & DK3_FONT_ENCODING_T4)) { 2049 dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[2]); 2050 } 2051 if (0 != ((u->fe) & DK3_FONT_ENCODING_T5)) { 2052 dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[3]); 2053 } 2054 dk3stream_c8_fputs(st, dk3uc2lat_mm[4]); 2055 dk3uc2lat_package_reset(u); 2056 do { 2057 pkgp = dk3uc2lat_package_next(u); 2058 if (NULL != pkgp) { 2059 $!trace-code if (NULL != pkgp->name) { 2060 $!trace-code if (0x00 != pkgp->used) { 2061 $? ". pkg used %!8s", pkgp->name 2062 $!trace-code } else { 2063 $? ". pkg not used %!8s", pkgp->name 2064 $!trace-code } 2065 $!trace-code } 2066 if ((0x00 != pkgp->used) && (NULL != pkgp->name)) { 2067 dk3stream_c8_fputs(st, dk3uc2lat_mm[3]); 2068 dk3stream_c8_fputs(st, pkgp->name); 2069 dk3stream_c8_fputs(st, dk3uc2lat_mm[4]); 2070 } 2071 } 2072 } while (NULL != pkgp); 2073} 2074 2075 2076 2077/* vim: set ai sw=2 : */ 2078