/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4uc2l.ctr */ /* Copyright (C) 2015-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dk4uc2l.c The dk4uc2l module. */ #line 238 "dk4uc2l.ctr" #include "dk4conf.h" #include #if DK4_HAVE_STRING_H #ifndef STRING_H_INCLUDED #include #define STRING_H_INCLUDED 1 #endif #endif #include "dk4const.h" #include "dk4uc2l.h" #include "dk4mem.h" #include "dk4mema.h" #include "dk4str8.h" #include "dk4strd.h" #include "dk4maasz.h" #include "dk4filed.h" #include "dk4mpl.h" #include "dk4strm.h" #include "dk4strmr.h" #include "dk4dir.h" #include "dk4dira.h" #include "dk4pathd.h" #include "dk4tsp08.h" #include "dk4enc.h" #include "dk4mai8hdu.h" #include "dk4maodh.h" #include "dk4maodd.h" #line 274 "dk4uc2l.ctr" typedef char *dk4_uc2l_char_ptr; typedef dk4_uc2l_pkg_t *dk4_uc2l_pkg_ptr; typedef dk4_uc2l_pkg_ptr *dk4_uc2l_pkg_ptr_ptr; /** Data passed to the line handler. */ typedef struct { dk4_uc2l_t *ulptr; /**< Conversion structure. */ dk4_app_t *app; /**< Application for diagnostics, may be NULL. */ const dkChar *sfn; /**< Short file name (pass 1). */ dk4_sto_t *s_r; /**< Storage for file ranges. */ dk4_sto_it_t *i_r; /**< Iterator for file ranges. */ int e_d; /**< Decoding errors. */ int e_e; /**< Encoding errors. */ int e_p; /**< Processing errors. */ } dk4_uc2l_lhobj; /** Fixed keywords used by the module, not localized. */ static const dkChar * const dk4uc2l_kwnl[] = { /* 0 */ dkT("dir.charmap"), /* 1 */ dkT("/dktools/charmap"), /* 2 */ dkT("/dk4app/charmap"), /* 3 */ dkT("/dk3app/charmap"), /* 4 */ dkT(".t2l"), /* 5 */ dkT(".t2l.gz"), /* 6 */ dkT(".t2l.bz2"), /* 7 */ dkT("/"), /* 8 */ dkT("dk4uc2l.str"), NULL #line 327 "dk4uc2l.ctr" }; /** Localized texts. */ static const dkChar * const dk4uc2l_kw_def[] = { /* 0 */ dkT("Syntax error!\n\tHexadecimal number required at start of line!"), /* 1 */ dkT("Syntax error!\n\tHexadecimal value outside allowed 32 bit range!"), /* 2 */ dkT("Syntax error!\n\tRedefinition of "), /* 3 */ dkT("!"), /* 4 */ dkT("Syntax error! Redefintion of character!"), /* 5 */ dkT("Failed to set up text processing!"), /* 6 */ dkT("Failed to open file for reading:\n\t\""), /* 7 */ dkT("\"!"), /* 8 */ dkT("Syntax error!\n\tIllegal font encoding name!"), /* 9 */ dkT("Syntax error!\n\t1 to 15 packages names are allowed!"), /* 10 */ dkT("Syntax error!\n\tIllegal attribute name!"), /* 11 */ dkT("Syntax error!\n\tAttribute specified without value!"), /* 12 */ dkT("Conversion to UTF-8 failed for 0x"), /* 13 */ dkT("!"), /* 14 */ dkT("Conversion to UTF-8 failed for a character!"), /* 15 */ dkT("No directory for character mapping information found!"), /* 16 */ dkT("Decoding failed!\n\tByte:"), /* 17 */ dkT("Encoding failed!\n\tByte:"), /* 18 */ dkT("Processing failed!\n\tByte:"), /* 19 */ dkT(",\n\tCharacter:"), /* 20 */ dkT(",\n\tPosition in line:"), /* 21 */ dkT("."), /* 22 */ dkT("Decoding failed!"), /* 23 */ dkT("Encoding failed!"), /* 24 */ dkT("Processing failed!"), /* 25 */ dkT("Further decoding failures!"), /* 26 */ dkT("Further encoding failures!"), /* 27 */ dkT("Further processing failures!"), NULL #line 403 "dk4uc2l.ctr" }; static const char * const dk4uc2l_kw8[] = { /* 0 */ "% Font encodings:", /* 1 */ "% Recommended package: ", /* 2 */ " ot1", /* 3 */ " t1", /* 4 */ " t4", /* 5 */ " t5", NULL #line 428 "dk4uc2l.ctr" }; /** Attribute names. */ static const char * const dk4uc2l_attribute_names[] = { /* 0 */ "b$oth", /* 1 */ "t$ext", /* 2 */ "m$ath", /* 3 */ "e$ncoding", /* 4 */ "p$ackages", NULL #line 441 "dk4uc2l.ctr" }; static const char * const dk4uc2l_font_encodings[] = { /* 0 */ "ot1", /* 1 */ "t1", /* 2 */ "t4", /* 3 */ "t5", NULL #line 452 "dk4uc2l.ctr" }; /** Destroy LaTeX package structure, release memory. @param pptr Package to destroy. */ static void dk4uc2l_pkg_close(dk4_uc2l_pkg_t *pptr) { #line 464 "dk4uc2l.ctr" if (NULL != pptr) { pptr->used = 0x00; dk4mem_release(pptr->pn); dk4mem_free(pptr); } #line 470 "dk4uc2l.ctr" } /** Create LaTeX package structure, allocate memory. @param pn Package name. @param app Application structure for diagnostics, may be NULL. @return Pointer to new structure on success, NULL on error. */ static dk4_uc2l_pkg_t * dk4uc2l_pkg_open(const char *pn, dk4_app_t *app) { dk4_uc2l_pkg_t *back = NULL; #line 485 "dk4uc2l.ctr" if (NULL != pn) { back = dk4mem_new_app(dk4_uc2l_pkg_t,1,app); if (NULL != back) { back->used = 0x00; back->pn = dk4str8_dup(pn, NULL); if (NULL == back->pn) { dk4uc2l_pkg_close(back); back = NULL; dk4app_log_base1(app, DK4_LL_ERROR, 90); } } } #line 497 "dk4uc2l.ctr" return back; } /** Compare two LaTeX package structures. @param l Left pointer, always a package structure. @param r Right pointer. @param cr Comparison criteria: 0 if r is a package pointer, 1 if r is just a package name string. @return Comparison result: 1 if l>r, 0 if l==r, -1 if lpn, (const char *)r); } break; default: { pr = (const dk4_uc2l_pkg_t *)r; back = strcmp(pl->pn, pr->pn); } break; } if (-1 > back) back = -1; if ( 1 < back) back = 1; } else { back = 1; } } else { if (NULL != r) { back = -1; } } return back; } /** Destroy file information structure, release memory. @param fptr File information structure to destroy. */ static void dk4uc2l_file_close(dk4_uc2l_file_t *fptr) { #line 549 "dk4uc2l.ctr" if (NULL != fptr) { fptr->loaded = 0x00; dk4mem_release(fptr->fn); dk4mem_free(fptr); } #line 554 "dk4uc2l.ctr" } /** Create file information structure, allocate memory. @param fn File name to create structure for. @param app Application structure for diagnostics, may be NULL. @return Pointer to new structure on success, NULL on error. */ static dk4_uc2l_file_t * dk4uc2l_file_open(const dkChar *fn, dk4_app_t *app) { dk4_uc2l_file_t *back = NULL; #line 569 "dk4uc2l.ctr" if (NULL != fn) { back = dk4mem_new_app(dk4_uc2l_file_t,1,app); if (NULL != back) { back->loaded = 0x00; back->fn = dk4str_dup(fn, NULL); if (NULL == back->fn) { dk4uc2l_file_close(back); back = NULL; dk4app_log_base1(app, DK4_LL_ERROR, 90); } } } #line 581 "dk4uc2l.ctr" return back; } /** Compare two file information structures. @param l Left pointer, always a file information structure. @param r Right pointer. @param cr Comparison criteria: 0 if the right pointer is a file information structure pointer, 1 if the right pointer is a file name string. @return Comparison result: 0 if file names are equal, -1 if lr. */ static int dk4uc2l_file_compare(const void *l, const void *r, int cr) { const dk4_uc2l_file_t *pl; const dk4_uc2l_file_t *pr; int back = 0; if (NULL != l) { if (NULL != r) { pl = (const dk4_uc2l_file_t *)l; switch (cr) { case 1: { back = dk4str_pathcmp(pl->fn, (const dkChar *)r); } break; default: { pr = (const dk4_uc2l_file_t *)r; back = dk4str_pathcmp(pl->fn, pr->fn); } break; } if (-1 > back) { back = -1; } if ( 1 < back) { back = 1; } } else { back = 1; } } else { if (NULL != r) { back = -1; } } return back; } /** Destroy range structure, release memory. @param rptr Range structure to destroy. */ static void dk4uc2l_range_close(dk4_uc2l_range_t *rptr) { dk4_er_t er; size_t nelem; size_t i; #line 637 "dk4uc2l.ctr" #if TRACE_DEBUG if (NULL != rptr->file) { if (NULL != (rptr->file)->fn) { #line 641 "dk4uc2l.ctr" } } #endif if (NULL != rptr) { /* Overflow check when calculating number of elements in range as end-start+1 */ dk4error_init(&er); nelem = dk4ma_size_t_add( dk4ma_size_t_sub((size_t)(rptr->end), (size_t)(rptr->start), &er), (size_t)1U, &er ); if (DK4_E_NONE == er.ec) { /* Release dynamic memory. */ if (NULL != rptr->both) { for (i = 0; i < nelem; i++) { dk4mem_release((rptr->both)[i]); } dk4mem_release(rptr->both); } if (NULL != rptr->text) { for (i = 0; i < nelem; i++) { dk4mem_release((rptr->text)[i]); } dk4mem_release(rptr->text); } if (NULL != rptr->math) { for (i = 0; i < nelem; i++) { dk4mem_release((rptr->math)[i]); } dk4mem_release(rptr->math); } if (NULL != rptr->pkgs) { for (i = 0; i < nelem; i++) { dk4mem_release((rptr->pkgs)[i]); } dk4mem_release(rptr->pkgs); } if (NULL != rptr->fenc) { dk4mem_release(rptr->fenc); } } rptr->file = NULL; rptr->start = rptr->end = (dk4_c32_t)0UL; rptr->ia = 0x00; dk4mem_free(rptr); } #line 684 "dk4uc2l.ctr" } /** Create range structure, partially allocate memory. @param c Character, initially start and end of range. @param fptr Pointer to exisiting file information structure. @param app Application structure for diagnostics, may be NULL. @return Pointer to new structure on success, NULL on error. */ static dk4_uc2l_range_t * dk4uc2l_range_open(dk4_c32_t c, dk4_uc2l_file_t *fptr, dk4_app_t *app) { dk4_uc2l_range_t *back = NULL; #line 700 "dk4uc2l.ctr" if (NULL != fptr) { back = dk4mem_new_app(dk4_uc2l_range_t,1,app); if (NULL != back) { back->file = fptr; back->both = NULL; back->text = NULL; back->math = NULL; back->pkgs = NULL; back->fenc = NULL; back->start = back->end = c; back->ia = 0x00; } } #line 713 "dk4uc2l.ctr" return back; } /** Compare two range informations or a range information against a character. @param l Left pointer, always a range information strucutre. @param r Right pointer. @param cr Comparison criteria: 0 if the right pointer is a range information strucutre, 1 if the right pointer is a pointer to a dk4_c32_t. @return Comparison result: -1 if lr. */ static int dk4uc2l_range_compare(const void *l, const void *r, int cr) { const dk4_uc2l_range_t *pl; const dk4_uc2l_range_t *pr; const dk4_c32_t *pc; int back = 0; if (NULL != l) { if (NULL != r) { pl = (const dk4_uc2l_range_t *)l; switch (cr) { case 1: { pc = (const dk4_c32_t *)r; if (pl->start > *pc) { back = 1; } else { if (pl->end < *pc) { back = -1; } } } break; default: { pr = (const dk4_uc2l_range_t *)r; if (pl->start < pr->start) { back = -1; } else { if (pl->start > pr->start) { back = 1; } } } break; } } else { back = 1; } } else { if (NULL != r) { back = -1; } } return back; } void dk4uc2l_close(dk4_uc2l_t *ulptr) { dk4_uc2l_pkg_t *pptr; dk4_uc2l_file_t *fptr; dk4_uc2l_range_t *rptr; #line 776 "dk4uc2l.ctr" if (NULL != ulptr) { /* Directory name. */ dk4mem_release(ulptr->dname); /* Ranges. */ if (NULL != ulptr->s_ranges) { if (NULL != ulptr->i_ranges) { dk4sto_it_reset(ulptr->i_ranges); do { rptr = (dk4_uc2l_range_t *)dk4sto_it_next(ulptr->i_ranges); if (NULL != rptr) { dk4uc2l_range_close(rptr); } } while (NULL != rptr); dk4sto_it_close(ulptr->i_ranges); } dk4sto_close(ulptr->s_ranges); } /* File information. */ if (NULL != ulptr->s_files) { if (NULL != ulptr->i_files) { dk4sto_it_reset(ulptr->i_files); do { fptr = (dk4_uc2l_file_t *)dk4sto_it_next(ulptr->i_files); if (NULL != fptr) { dk4uc2l_file_close(fptr); } } while (NULL != fptr); dk4sto_it_close(ulptr->i_files); } dk4sto_close(ulptr->s_files); } /* Package information. */ if (NULL != ulptr->s_pkgs) { if (NULL != ulptr->i_pkgs) { dk4sto_it_reset(ulptr->i_pkgs); do { pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs); if (NULL != pptr) { dk4uc2l_pkg_close(pptr); } } while (NULL != pptr); dk4sto_it_close(ulptr->i_pkgs); } dk4sto_close(ulptr->s_pkgs); } ulptr->s_ranges = NULL; ulptr->i_ranges = NULL; ulptr->s_files = NULL; ulptr->i_files = NULL; ulptr->s_pkgs = NULL; ulptr->i_pkgs = NULL; ulptr->msgs = NULL; ulptr->szmsgs = 0; dk4mem_free(ulptr); } #line 833 "dk4uc2l.ctr" } static dk4_uc2l_t * dk4uc2l_create(const dkChar *dn, dk4_app_t *app) { dk4_uc2l_t *back = NULL; int ok = 0; #line 844 "dk4uc2l.ctr" if (NULL != dn) { back = dk4mem_new_app(dk4_uc2l_t,1,app); if (NULL != back) { back->dname = NULL; back->s_ranges = NULL; back->i_ranges = NULL; back->s_files = NULL; back->i_files = NULL; back->s_pkgs = NULL; back->i_pkgs = NULL; back->fallowed = 0xFF; back->utf8allowed = 0x00; back->had_error = 0; back->msgs = NULL; back->szmsgs = 0; back->dname = dk4str_dup(dn, NULL); if (NULL != back->dname) { back->s_ranges = dk4sto_open(NULL); if (NULL != back->s_ranges) { dk4sto_set_comp(back->s_ranges, dk4uc2l_range_compare, 0); back->s_files = dk4sto_open(NULL); if (NULL != back->s_files) { dk4sto_set_comp(back->s_files, dk4uc2l_file_compare, 0); back->s_pkgs = dk4sto_open(NULL); if (NULL != back->s_pkgs) { dk4sto_set_comp(back->s_pkgs, dk4uc2l_pkg_compare, 0); back->i_ranges = dk4sto_it_open(back->s_ranges, NULL); if (NULL != back->i_ranges) { back->i_files = dk4sto_it_open(back->s_files, NULL); if (NULL != back->i_files) { back->i_pkgs = dk4sto_it_open(back->s_pkgs, NULL); if (NULL != back->i_pkgs) { if (NULL != app) { back->msgs = dk4app_string_table( app, dk4uc2l_kwnl[8], dk4uc2l_kw_def ); } else { back->msgs = dk4uc2l_kw_def; } back->szmsgs = dk4app_string_table_size(dk4uc2l_kw_def); ok = 1; } } } } } } } if (0 == ok) { dk4uc2l_close(back); back = NULL; /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); } } } #line 900 "dk4uc2l.ctr" return back; } /** Handler function for text lines. @param obj Object to modify while processing the character. @param line Text line to process. @param lineno Current line number. @param erp Error report, may be NULL. @return DK4_TSP_RES_OK if the character was processed successfully, DK4_TSP_RES_ERROR if there was an error but we can continue, DK4_TSP_RES_FATAL if there was a fatal error so we should abort processing. */ static int dk4uc2l_fp_handler( void *obj, char *line, dk4_um_t lineno, dk4_er_t *erp ) { dkChar numbuf[16*sizeof(dk4_um_t)]; dk4_uc2l_range_t *rptr; dk4_uc2l_range_t *rptrn; dk4_uc2l_file_t *fptr; dk4_uc2l_lhobj *lhobj; dk4_app_t *app; dk4_uc2l_t *ulptr; char *p1; #if VERSION_BEFORE_20150821 char *p2; #endif const char *p3; dk4_um_t um; dk4_c32_t c32; dk4_c32_t c32a; size_t sznumbuf; int back = DK4_TSP_RES_OK; int res = 0; #line 945 "dk4uc2l.ctr" /* Obtain contents from object. */ lhobj = (dk4_uc2l_lhobj *)obj; ulptr = lhobj->ulptr; app = lhobj->app; dk4app_set_log_source_line(app, lineno); /* Check for any text. Empty lines ok, comments ok. */ p1 = dk4str8_start(line, NULL); if (NULL == p1) { #line 957 "dk4uc2l.ctr" goto finished; } if ('#' == *p1) { #line 960 "dk4uc2l.ctr" goto finished; } /* Retrieve hexadecimal number. */ #if VERSION_BEFORE_20150821 p2 = dk4str8_next(p1, NULL); #else (void)dk4str8_next(p1, NULL); #endif um = (dk4_um_t)0UL; #if VERSION_BEFORE_20150821 p2 = NULL; #endif p3 = NULL; res = dk4ma_input_c8_hex_dk4_um_t(&um, p1, &p3, 1, NULL); if (0 == res) { #line 977 "dk4uc2l.ctr" back = DK4_TSP_RES_ERROR; /* ERROR: Syntax, not a number */ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 0); ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; goto finished; } #line 983 "dk4uc2l.ctr" c32 = (dk4_c32_t)um; #line 984 "dk4uc2l.ctr" /* Check numeric range. */ if ((dk4_um_t)0xFFFFFFFFUL < um) { #line 988 "dk4uc2l.ctr" back = DK4_TSP_RES_ERROR; /* ERROR: Syntax, out of range */ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 1); ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; goto finished; } /* Check whether number is already contained in a range. */ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32, 1); if (NULL != rptr) { #line 999 "dk4uc2l.ctr" #line 1000 "dk4uc2l.ctr" back = DK4_TSP_RES_ERROR; /* ERROR: Already defined */ sznumbuf = DK4_SIZEOF(numbuf,dkChar); if (0 != dk4ma_write_hex_unsigned(numbuf,sznumbuf,(dk4_um_t)c32,8,NULL)) { dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf); } else { dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 4); } ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; goto finished; } rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(ulptr->i_ranges, &c32, 1); if (NULL != rptr) { #line 1013 "dk4uc2l.ctr" back = DK4_TSP_RES_ERROR; /* ERROR: Already defined */ sznumbuf = DK4_SIZEOF(numbuf,dkChar); if (0 != dk4ma_write_hex_unsigned(numbuf,sznumbuf,(dk4_um_t)c32,8,NULL)) { dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf); } else { dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 4); } ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; goto finished; } /* Check whether we can append to an existing range. */ if (dkC32(0) < c32) { c32a = c32 - dkC32(1); rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1); if (NULL != rptr) { rptr->end = c32; #line 1032 "dk4uc2l.ctr" /* Also check if c32 closes a gap between two ranges. */ if (dkC32(0xFFFFFFFF) > c32) { c32a = c32 + dkC32(1); rptrn = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1); if (NULL != rptrn) { #line 1038 "dk4uc2l.ctr" c32a = rptrn->end; dk4sto_remove(lhobj->s_r, rptrn, NULL); rptr->end = c32a; } } goto finished; } } /* Check whether we can prepend before an existing range. */ if (dkC32(0xFFFFFFFF) > c32) { c32a = c32 + dkC32(1); rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1); if (NULL != rptr) { #line 1053 "dk4uc2l.ctr" rptr->start = c32; goto finished; } } /* Create a new range. */ #line 1060 "dk4uc2l.ctr" fptr = (dk4_uc2l_file_t *)dk4sto_it_find_like(ulptr->i_files, lhobj->sfn, 1); if (NULL == fptr) { fptr = dk4uc2l_file_open(lhobj->sfn, app); if (NULL != fptr) { if (0 == dk4sto_add(ulptr->s_files, fptr, NULL)) { dk4uc2l_file_close(fptr); #line 1066 "dk4uc2l.ctr" fptr = NULL; } } } if (NULL == fptr) { #line 1071 "dk4uc2l.ctr" back = DK4_TSP_RES_ERROR; /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; goto finished; } rptr = dk4uc2l_range_open(c32, fptr, app); if (NULL != rptr) { if (0 == dk4sto_add(lhobj->s_r, rptr, NULL)) { dk4uc2l_range_close(rptr); #line 1081 "dk4uc2l.ctr" rptr = NULL; back = DK4_TSP_RES_ERROR; /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); } } else { #line 1087 "dk4uc2l.ctr" back = DK4_TSP_RES_ERROR; /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } #line 1092 "dk4uc2l.ctr" finished: #line 1095 "dk4uc2l.ctr" return back; } /** Report an error with position in source line. @param ulptr Conversion structure. @param i1 Index of first message part in array. @param i2 Index of alternative first message part. @param bno Byte processed. @param lno Current line number. @param cno Current character number. @param cil Current character number in line. */ static void dk4uc2l_report_with_pos( dk4_uc2l_t *ulptr, dk4_app_t *app, size_t i1, size_t i2, dk4_um_t bno, dk4_um_t lno, dk4_um_t cno, dk4_um_t cil ) { dkChar b1[8*(1+sizeof(dk4_um_t))]; dkChar b2[8*(1+sizeof(dk4_um_t))]; dkChar b3[8*(1+sizeof(dk4_um_t))]; dk4_um_t oldlogline = (dk4_um_t)0UL; int allbuffersok = 0; oldlogline = dk4app_get_log_source_line(app); dk4app_set_log_source_line(app, lno); if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) { if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) { if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) { allbuffersok = 1; } } } if (0 != allbuffersok) { dk4app_log_7( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, i1, 19, 20, 21, b1, b2, b3 ); } else { dk4app_log_1( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, i2 ); } dk4app_set_log_source_line(app, oldlogline); } static void dk4uc2l_report_errors( dk4_uc2l_t *ulptr, dk4_app_t *app, dk4_uc2l_lhobj *obj, dk4_er_t *er_en, dk4_er_t *er_pr ) { if (NULL != er_en) { switch (er_en->ec) { case DK4_E_DECODING_FAILED: { switch (obj->e_d) { case 0: case 1: { dk4uc2l_report_with_pos( ulptr, app, 16, 22, er_en->dt.fpos.byteno, er_en->dt.fpos.lineno, er_en->dt.fpos.charno, er_en->dt.fpos.charinline ); } break; case 2: { dk4app_log_1( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 25 ); } break; } if (3 > obj->e_d) { obj->e_d += 1; } } break; case DK4_E_ENCODING_FAILED: { switch (obj->e_e) { case 0: case 1: { dk4uc2l_report_with_pos( ulptr, app, 17, 23, er_en->dt.fpos.byteno, er_en->dt.fpos.lineno, er_en->dt.fpos.charno, er_en->dt.fpos.charinline ); } break; case 2: { dk4app_log_1( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 26 ); } break; } if (3 > obj->e_e) { obj->e_e += 1; } } break; } } if (NULL != er_pr) { if (DK4_E_NONE != er_pr->ec) { switch (obj->e_p) { case 0: case 1: { dk4uc2l_report_with_pos( ulptr, app, 18, 24, er_pr->dt.fpos.byteno, er_pr->dt.fpos.lineno, er_pr->dt.fpos.charno, er_pr->dt.fpos.charinline ); } break; case 2: { dk4app_log_1( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 27 ); } break; } if (3 > obj->e_p) { obj->e_p += 1; } } } } /** Process data from a stream. @param ulptr Conversion structure. @param rstrm Stream to read data from. @param sfn Short file name. @param app Application structure for diagnostics, may be NULL. @return 1 on success, 0 on error. */ static int dk4uc2l_fp_process_stream( dk4_uc2l_t *ulptr, dk4_stream_t *rstrm, const dkChar *sfn, dk4_app_t *app ) { char buf[256]; /* Line buffer */ dk4_tsp08_t tsp08; /* Text stream processor */ dk4_er_t er; /* General error report */ dk4_er_t er_en; /* Error report for decoding/encoding */ dk4_er_t er_pr; /* Error report for processing */ dk4_uc2l_lhobj obj; /* Processing object */ dk4_uc2l_range_t *rptr; /* Range to append to */ int back = 1; int res; /* Line processing result */ int cc; /* Flag: Can continue */ char c; /* Current character */ #line 1256 "dk4uc2l.ctr" dk4error_init(&er); dk4error_init(&er_en); dk4error_init(&er_pr); obj.ulptr = ulptr; obj.app = app; obj.sfn = sfn; obj.e_d = 0; obj.e_e = 0; obj.e_p = 0; obj.s_r = dk4sto_open(NULL); if (NULL != obj.s_r) { dk4sto_set_comp(obj.s_r, dk4uc2l_range_compare, 0); obj.i_r = dk4sto_it_open(obj.s_r, NULL); if (NULL != obj.i_r) { res = dk4tsp08_setup_line( &tsp08, (void *)(&obj), dk4uc2l_fp_handler, buf, sizeof(buf), DK4_ENCODING_ASCII, DK4_ENCODING_ASCII, &er ); if (0 != res) { cc = 1; while (1 == cc) { res = dk4stream_c8_read_byte(&c, rstrm, &er); if (0 != res) { res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c); switch (res) { case DK4_TSP_RES_ERROR: { back = 0; dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); /* Report errors */ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr); dk4error_init(&er_en); dk4error_init(&er_pr); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } break; case DK4_TSP_RES_FATAL: { back = 0; cc = -1; dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); /* Report errors */ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr); dk4error_init(&er_en); dk4error_init(&er_pr); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } break; } } else { cc = 0; } } if (0 == cc) { res = dk4tsp08_finish(&tsp08); switch (res) { case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { back = 0; dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); /* Report errors */ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } break; } } } else { /* ERROR: Failed to set up text processing */ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 5); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } /* Move range descriptions from local storage to global storage. */ dk4sto_it_reset(obj.i_r); do { rptr = (dk4_uc2l_range_t *)dk4sto_it_next(obj.i_r); if (NULL != rptr) { if (0 == dk4sto_add(ulptr->s_ranges, rptr, NULL)) { back = 0; /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); dk4uc2l_range_close(rptr); } } } while (NULL != rptr); dk4sto_it_close(obj.i_r); } else { back = 0; /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } dk4sto_close(obj.s_r); obj.s_r = NULL; } else { back = 0; /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } #line 1354 "dk4uc2l.ctr" return back; } /** Process one data file in the first pass. @param ulptr Conversion structure. @param fn Full file name. @param sfn Short file name. @param app Application structure for diagnostics, may be NULL. @return 1 on success, 0 on error. */ static int dk4uc2l_fp_process_file_name( dk4_uc2l_t *ulptr, const dkChar *fn, const dkChar *sfn, dk4_app_t *app ) { dk4_er_t er; /* Error report */ dk4_stream_t *rstrm; /* Stream to read file */ const dkChar *oldsourcefile; /* Previous source file */ dk4_um_t oldsourceline; /* Previous source line */ size_t fnl; /* File name length */ size_t fns; /* Suffix length */ size_t i; /* Traverse suffix list */ int back = 1; int done = 0; /* Flag: Attempted to open file */ #line 1385 "dk4uc2l.ctr" fnl = dk4str_len(fn); for (i = 4; ((i < 7) && (0 == done)); i++) { #line 1387 "dk4uc2l.ctr" fns = dk4str_len(dk4uc2l_kwnl[i]); if (fnl > fns) { #line 1389 "dk4uc2l.ctr" if (0 == dk4str_pathcmp(&(fn[fnl - fns]), dk4uc2l_kwnl[i])) { done = 1; #line 1391 "dk4uc2l.ctr" dk4error_init(&er); rstrm = dk4stream_open_file_reader(fn, &er); if (NULL != rstrm) { #line 1394 "dk4uc2l.ctr" oldsourcefile = dk4app_get_log_source_file(app); oldsourceline = dk4app_get_log_source_line(app); dk4app_set_log_source_file(app, fn); dk4app_set_log_source_line(app, (dk4_um_t)0UL); back = dk4uc2l_fp_process_stream(ulptr, rstrm, sfn, app); dk4app_set_log_source_file(app, oldsourcefile); dk4app_set_log_source_line(app, oldsourceline); dk4stream_close(rstrm, NULL); } else { #line 1403 "dk4uc2l.ctr" back = 0; /* ERROR: Failed to open file */ dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 6, 7, fn); ulptr->had_error |= DK4_UC2L_ERROR_FOPEN; } } else { #line 1409 "dk4uc2l.ctr" } } else { #line 1411 "dk4uc2l.ctr" } } #line 1414 "dk4uc2l.ctr" return back; } /** First pass to fill information to the structure, obtain information which character is handled by which file. @param ulptr New structure to fill with data. @param app Application structure for diagnostics. @return 1 on success, 0 on error. */ static int dk4uc2l_first_pass(dk4_uc2l_t *ulptr, dk4_app_t *app) { dkChar fnb[DK4_MAX_PATH]; /* File name buffer */ const dkChar *pth = NULL; /* Path for directory */ const dkChar *fn = NULL; /* Current file to process */ dk4_dir_t *dir = NULL; /* Traverse the directory */ int back = 0; #line 1435 "dk4uc2l.ctr" dir = dk4dir_open_app(ulptr->dname, 0, app); if (NULL != dir) { back = 1; do { fn = dk4dir_next_file(dir); if (NULL != fn) { pth = dk4dir_get_path(dir); if (NULL != pth) { if (dk4str_cpy_s(fnb,DK4_SIZEOF(fnb,dkChar),pth,NULL)) { if (dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),dk4uc2l_kwnl[7],NULL)) { if (dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),fn,NULL)) { dk4path_correct_sep(fnb); if (0 == dk4uc2l_fp_process_file_name(ulptr, fnb, fn, app)) { back = 0; } } else { back = 0; /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } } else { back = 0; /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } } else { back = 0; /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } } else { if (0 == dk4uc2l_fp_process_file_name(ulptr, fn, fn, app)) { back = 0; } } } } while (NULL != fn); dk4dir_close(dir); } else { /* ERROR: Failed to open directory */ ulptr->had_error |= DK4_UC2L_ERROR_FOPEN; } #line 1480 "dk4uc2l.ctr" return back; } static void dk4uc2l_initialize_range( dk4_uc2l_t *ulptr, dk4_uc2l_range_t *rptr, dk4_app_t *app ) { dk4_er_t er; size_t nelem; size_t i; int errmem; dk4error_init(&er); nelem = dk4ma_size_t_add( dk4ma_size_t_sub((size_t)(rptr->end), (size_t)(rptr->start), &er), (size_t)1U, &er ); if (DK4_E_NONE == er.ec) { errmem = 0; rptr->both = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app); if (NULL != rptr->both) { for (i = 0; i < nelem; i++) { (rptr->both)[i] = NULL; } } else { errmem = 1; } rptr->text = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app); if (NULL != rptr->text) { for (i = 0; i < nelem; i++) { (rptr->text)[i] = NULL; } } else { errmem = 1; } rptr->math = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app); if (NULL != rptr->math) { for (i = 0; i < nelem; i++) { (rptr->math)[i] = NULL; } } else { errmem = 1; } rptr->pkgs = dk4mem_new_app(dk4_uc2l_pkg_ptr_ptr, nelem, app); if (NULL != rptr->pkgs) { for (i = 0; i < nelem; i++) { (rptr->pkgs)[i] = NULL; } } else { errmem = 1; } rptr->fenc = dk4mem_new_app(unsigned char,nelem,app); if (NULL != rptr->fenc) { for (i = 0; i < nelem; i++) { (rptr->fenc)[i] = (unsigned char)DK4_UC2L_FONT_ENCODING_ALL; } } else { errmem = 1; } if (0 != errmem) { /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } } /** Handler function for text lines. @param obj Object to modify while processing the character. @param line Text line to process. @param lineno Current line number. @param erp Error report, may be NULL. @return DK4_TSP_RES_OK if the character was processed successfully, DK4_TSP_RES_ERROR if there was an error but we can continue, DK4_TSP_RES_FATAL if there was a fatal error so we should abort processing. */ static int dk4uc2l_sp_handler( void *obj, char *line, dk4_um_t lineno, dk4_er_t *erp ) { dkChar numbuf[16*sizeof(dk4_um_t)]; dk4_er_t er; /* Error report */ dk4_uc2l_lhobj *lhobj; /* Handler object */ dk4_app_t *app; /* Application */ dk4_uc2l_range_t *rptr; /* Current range to modify */ dk4_uc2l_pkg_t *pkgptr; /* Current package to create */ dk4_uc2l_t *ulptr; /* Conversion structure */ char *pkgn[16]; /* Package names */ char *p1; /* Attribute name */ char *p2; /* Next attribute to process */ char *p4; /* Value, current value part */ char *p5; /* Next value part */ const char *pe; /* End of text when reading number */ dk4_um_t um; /* Number read at start of line */ size_t sznumbuf; /* Buffer size */ size_t ind; /* Index of current char in range */ size_t numpkg; /* Number of package names found */ size_t i; /* Current package index */ dk4_c32_t c32; /* Current character to configure */ int numres; /* Number conversion result */ int encadd; /* Flag: Add font encodings */ int res; /* Operation result */ int back = DK4_TSP_RES_OK; #line 1582 "dk4uc2l.ctr" /* Set variables. */ lhobj = (dk4_uc2l_lhobj *)obj; ulptr = lhobj->ulptr; app = lhobj->app; dk4app_set_log_source_line(app, lineno); /* Skip empty lines and comments. */ p1 = dk4str8_start(line, NULL); if (NULL == p1) { goto finished; } if ('#' == *p1) { goto finished; } p2 = dk4str8_next(p1, NULL); /* Retrieve character number. */ um = (dk4_um_t)0UL; pe = NULL; res = dk4ma_input_c8_hex_dk4_um_t(&um, p1, &pe, 1, NULL); if (0 == res) { back = DK4_TSP_RES_ERROR; /* ERROR: Syntax, not a number, already reported in first pass. */ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; goto finished; } c32 = (dk4_c32_t)um; if ((dk4_um_t)0xFFFFFFFFUL < um) { back = DK4_TSP_RES_ERROR; /* ERROR: Syntax, out of range, already reported in first pass. */ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; goto finished; } /* Find range. */ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(ulptr->i_ranges, &c32, 1); if (NULL == rptr) { back = DK4_TSP_RES_ERROR; /* ERROR: Bug, range not found, must be memory problem reported in pass 1 */ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; goto finished; } /* Initialize range if not yet done. */ if (0x00 == rptr->ia) { rptr->ia = 0x01; dk4uc2l_initialize_range(ulptr, rptr, app); } ind = (size_t)(c32 - rptr->start); p1 = p2; while (NULL != p1) { p2 = dk4str8_next(p1, NULL); p4 = dk4str8_chr(p1, '='); if (NULL != p4) { *(p4++) = '\0'; p4 = dk4str8_start(p4, NULL); if (NULL != p4) { switch (dk4str8_abbr_index(dk4uc2l_attribute_names, '$', p1, 0)) { case 0: { /* both */ if (NULL != rptr->both) { if (NULL == (rptr->both)[ind]) { (rptr->both)[ind] = dk4str8_dup(p4, NULL); if (NULL == (rptr->both)[ind]) { /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } else { /* ERROR: Already defined, reported in first pass */ sznumbuf = DK4_SIZEOF(numbuf,dkChar); numres = dk4ma_write_hex_unsigned( numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL ); if (0 != numres) { dk4app_log_3( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf ); } else { dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4); } ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } } else { /* ERROR */ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } break; case 1: { /* text */ if (NULL != rptr->text) { if (NULL == (rptr->text)[ind]) { (rptr->text)[ind] = dk4str8_dup(p4, NULL); if (NULL == (rptr->text)[ind]) { /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } else { /* ERROR: Already defined, reported in first pass */ sznumbuf = DK4_SIZEOF(numbuf,dkChar); numres = dk4ma_write_hex_unsigned( numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL ); if (0 != numres) { dk4app_log_3( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf ); } else { dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4); } ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } } else { /* ERROR */ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } break; case 2: { /* math */ if (NULL != rptr->math) { if (NULL == (rptr->math)[ind]) { (rptr->math)[ind] = dk4str8_dup(p4, NULL); if (NULL == (rptr->math)[ind]) { /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } else { /* ERROR: Already defined */ sznumbuf = DK4_SIZEOF(numbuf,dkChar); numres = dk4ma_write_hex_unsigned( numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL ); if (0 != numres) { dk4app_log_3( app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf ); } else { dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4); } ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } } else { /* ERROR */ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } break; case 3: { /* encoding */ encadd = 1; if (NULL != rptr->fenc) { if ('!' == *p4) { p4++; encadd = 0; (rptr->fenc)[ind] = (unsigned char)DK4_UC2L_FONT_ENCODING_ALL; } else { (rptr->fenc)[ind] = 0x00; } while (NULL != p4) { p5 = dk4str8_chr(p4, ','); if (NULL != p5) { *(p5++) = '\0'; } switch (dk4str8_array_index(dk4uc2l_font_encodings, p4, 0)) { case 0: { /* OT1 */ if (0 != encadd) { (rptr->fenc)[ind] |= (unsigned char)DK4_UC2L_FONT_ENCODING_OT1; } else { (rptr->fenc)[ind] &= (~((unsigned char)DK4_UC2L_FONT_ENCODING_OT1)); } } break; case 1: { /* T1 */ if (0 != encadd) { (rptr->fenc)[ind] |= (unsigned char)DK4_UC2L_FONT_ENCODING_T1; } else { (rptr->fenc)[ind] &= (~((unsigned char)DK4_UC2L_FONT_ENCODING_T1)); } } break; case 2: { /* T4 */ if (0 != encadd) { (rptr->fenc)[ind] |= (unsigned char)DK4_UC2L_FONT_ENCODING_T4; } else { (rptr->fenc)[ind] &= (~((unsigned char)DK4_UC2L_FONT_ENCODING_T4)); } } break; case 3: { /* T5 */ if (0 != encadd) { (rptr->fenc)[ind] |= (unsigned char)DK4_UC2L_FONT_ENCODING_T5; } else { (rptr->fenc)[ind] &= (~((unsigned char)DK4_UC2L_FONT_ENCODING_T5)); } } break; default : { /* ERROR: Syntax, undefined encoding */ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,8); ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } break; } p4 = p5; } } else { /* ERROR */ } } break; case 4: { /* packages */ dk4error_init(&er); numpkg = dk4str8_tokenize(pkgn, 16, p4, ",", &er); if (0 < numpkg) { if (NULL != rptr->pkgs) { if (NULL == (rptr->pkgs)[ind]) { (rptr->pkgs)[ind] = dk4mem_new_app(dk4_uc2l_pkg_ptr,(numpkg+1),app); if (NULL != (rptr->pkgs)[ind]) { for (i = 0; i <= numpkg; i++) { ((rptr->pkgs)[ind])[i] = NULL; } for (i = 0; i < numpkg; i++) { pkgptr = (dk4_uc2l_pkg_t *)dk4sto_it_find_like( ulptr->i_pkgs, pkgn[i], 1 ); if (NULL != pkgptr) { ((rptr->pkgs)[ind])[i] = pkgptr; } else { pkgptr = dk4uc2l_pkg_open(pkgn[i], app); if (NULL != pkgptr) { if (0 == dk4sto_add(ulptr->s_pkgs, pkgptr, NULL)) { dk4uc2l_pkg_close(pkgptr); pkgptr = NULL; } } if (NULL != pkgptr) { ((rptr->pkgs)[ind])[i] = pkgptr; } else { /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } } } else { /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } else { /* ERROR: Redefinition */ sznumbuf = DK4_SIZEOF(numbuf,dkChar); numres = dk4ma_write_hex_unsigned( numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL ); if (0 != numres) { dk4app_log_3( app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf ); } else { dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4); } ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } } else { /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_ERROR, 90); ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; } } else { /* ERROR Syntax */ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 9); ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } } break; default: { /* ERROR: Syntax error */ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 10); ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } break; } } else { /* ERROR: Syntax */ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 11); ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } } else { /* ERROR: Syntax */ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 11); ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; } p1 = p2; } finished: #line 1887 "dk4uc2l.ctr" return back; } static void dk4uc2l_sp_process_stream( dk4_uc2l_t *ulptr, dk4_stream_t *rstrm, const dkChar *fnb, dk4_app_t *app ) { char buf[256]; /* Line buffer */ dk4_uc2l_lhobj obj; /* Processing object */ dk4_tsp08_t tsp08; /* Text stream processor */ dk4_er_t er; /* General error report */ dk4_er_t er_en; /* Error report encoding/decoding */ dk4_er_t er_pr; /* Error report processing */ int res; /* Operation result */ int cc; /* Flag: Can continue */ char c; /* Current character to process */ obj.ulptr = ulptr; obj.app = app; obj.sfn = fnb; obj.e_d = 0; obj.e_e = 0; obj.e_p = 0; dk4error_init(&er); dk4error_init(&er_en); dk4error_init(&er_pr); res = dk4tsp08_setup_line( &tsp08, (void *)(&obj), dk4uc2l_sp_handler, buf, sizeof(buf), DK4_ENCODING_ASCII, DK4_ENCODING_ASCII, &er ); if (0 != res) { cc = 1; while (1 == cc) { res = dk4stream_c8_read_byte(&c, rstrm, &er); if (0 != res) { res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c); switch (res) { case DK4_TSP_RES_ERROR: { dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); /* Report errors */ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr); dk4error_init(&er_en); dk4error_init(&er_pr); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } break; case DK4_TSP_RES_FATAL: { cc = -1; dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); /* Report errors */ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr); dk4error_init(&er_en); dk4error_init(&er_pr); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } break; } } else { cc = 0; } } if (0 == cc) { res = dk4tsp08_finish(&tsp08); switch (res) { case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); /* Report errors */ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } break; } } } else { ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } } /** Attempt to load one data file if not yet loaded. @param ulptr Conversion structure. @param rptr Pointer to range causing the attempt to load. @param app Application structure for diagnostics, may be NULL. */ static void dk4uc2l_load_if_not_yet_done( dk4_uc2l_t *ulptr, dk4_uc2l_range_t *rptr, dk4_app_t *app ) { dkChar fnb[DK4_MAX_PATH]; dk4_er_t er; const dkChar *oldsourcefile; dk4_uc2l_file_t *fptr; dk4_stream_t *rstrm; dk4_um_t oldsourceline; size_t fnbsz; #line 1992 "dk4uc2l.ctr" fptr = rptr->file; if (NULL != fptr) { #line 1994 "dk4uc2l.ctr" if (0x00 == fptr->loaded) { #line 1995 "dk4uc2l.ctr" fptr->loaded = 0x01; fnbsz = DK4_SIZEOF(fnb, dkChar); if (0 != dk4str_cpy_s(fnb, fnbsz, ulptr->dname, NULL)) { if (0 != dk4str_cat_s(fnb, fnbsz, dk4uc2l_kwnl[7], NULL)) { if (0 != dk4str_cat_s(fnb, fnbsz, fptr->fn, NULL)) { dk4path_correct_sep(fnb); dk4error_init(&er); rstrm = dk4stream_open_file_reader(fnb, &er); if (NULL != rstrm) { oldsourcefile = dk4app_get_log_source_file(app); oldsourceline = dk4app_get_log_source_line(app); dk4app_set_log_source_file(app, fnb); dk4app_set_log_source_line(app, (dk4_um_t)0UL); dk4uc2l_sp_process_stream(ulptr, rstrm, fnb, app); dk4app_set_log_source_file(app, oldsourcefile); dk4app_set_log_source_line(app, oldsourceline); dk4stream_close(rstrm, NULL); } else { #line 2013 "dk4uc2l.ctr" /* ERROR: Failed to open file */ dk4app_log_3( app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 6, 7, fnb ); ulptr->had_error |= DK4_UC2L_ERROR_FOPEN; } } else { #line 2020 "dk4uc2l.ctr" /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } } else { #line 2025 "dk4uc2l.ctr" /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } } else { #line 2030 "dk4uc2l.ctr" /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname); ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } } else { #line 2035 "dk4uc2l.ctr" } } else { #line 2037 "dk4uc2l.ctr" ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; } #line 2039 "dk4uc2l.ctr" } const char * dk4uc2l_find(dk4_uc2l_t *ulptr, dk4_c32_t c, int mm, dk4_app_t *app) { dkChar numbuf[16*sizeof(dk4_um_t)]; dk4_uc2l_range_t *rptr; dk4_uc2l_pkg_t **pptr; dk4_uc2l_pkg_t *xpptr; const char *back = NULL; size_t blgt; size_t sznumbuf; int numres; #line 2055 "dk4uc2l.ctr" if (NULL != ulptr) { /* Attempt direct output. */ if (0 != dk4uc2lat_direct(c)) { ulptr->buf[0] = (char)c; ulptr->buf[1] = '\0'; back = &(ulptr->buf[0]); goto finished; } /* Attempt to find output string in data. */ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like( ulptr->i_ranges, &c, 1 ); if (NULL != rptr) { dk4uc2l_load_if_not_yet_done(ulptr, rptr, app); if (0 != mm) { if (NULL != rptr->math) { back = (rptr->math)[(size_t)(c - rptr->start)]; } if (NULL == back) { if (NULL != rptr->both) { back = (rptr->both)[(size_t)(c - rptr->start)]; } } } else { if (NULL != rptr->text) { back = (rptr->text)[(size_t)(c - rptr->start)]; } if (NULL == back) { if (NULL != rptr->both) { back = (rptr->both)[(size_t)(c - rptr->start)]; } } } if (NULL != back) { if (NULL != rptr->fenc) { ulptr->fallowed &= (rptr->fenc)[(size_t)(c - rptr->start)]; } if (NULL != rptr->pkgs) { if (NULL != (rptr->pkgs)[(size_t)(c - rptr->start)]) { pptr = (rptr->pkgs)[(size_t)(c - rptr->start)]; while (NULL != *pptr) { xpptr = *(pptr++); xpptr->used = 0x01; } } } } } if (NULL != back) { goto finished; } /* If everything failed so far, attempt to use UTF-8 output or direct output. */ if (0 != mm) { goto finished; } if (0x00 != ulptr->utf8allowed) { blgt = 15; if (0 != dk4utf8_encode((unsigned char *)(&(ulptr->buf[0])),&blgt,c,NULL)) { ulptr->buf[blgt] = '\0'; back = &(ulptr->buf[0]); } else { /* ERROR: UTF-8 encoding failed */ sznumbuf = DK4_SIZEOF(numbuf,dkChar); numres = dk4ma_write_hex_unsigned( numbuf, sznumbuf, (dk4_um_t)c, 8, NULL ); if (0 != numres) { dk4app_log_3( app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 12, 13, numbuf ); } else { dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,14); } } } else { if (dkC32(0x00000100) > c) { ulptr->buf[0] = (char)c; ulptr->buf[1] = '\0'; back = &(ulptr->buf[0]); } else { /* ERROR: No encoding found */ } } } finished: #line 2150 "dk4uc2l.ctr" return back; } dk4_uc2l_t * dk4uc2l_open(const dkChar *dn, dk4_app_t *app) { dk4_er_t er; dk4_uc2l_t *back = NULL; #line 2161 "dk4uc2l.ctr" dk4error_init(&er); if (NULL != dn) { if (0 != dk4file_is_directory(dn, &er)) { back = dk4uc2l_create(dn, app); if (NULL != back) { if (0 == dk4uc2l_first_pass(back, app)) { dk4uc2l_close(back); back = NULL; } } } else { /* ERROR: Not a directory */ dk4app_log_base3(app, DK4_LL_ERROR, 152, 153, dn); } } #line 2176 "dk4uc2l.ctr" return back; } dk4_uc2l_t * dk4uc2l_open_from_app(dk4_app_t *app) { dkChar fnb[DK4_MAX_PATH]; /* Buffer to construct name */ const dkChar * const *debmsg; dk4_uc2l_t *back = NULL; size_t i = 0; /* Traverse possible dirs */ size_t szdm = 0; int done = 0; /* Flag: Attempted */ int toolo = 0; /* Flag: Name too long */ int res = 0; /* Operation result */ #line 2193 "dk4uc2l.ctr" if (NULL != app) { res = dk4app_pref_get(fnb,DK4_SIZEOF(fnb,dkChar),app,dk4uc2l_kwnl[0],0); if (0 != res) { dk4path_correct_sep(fnb); if (0 != dk4file_is_directory(fnb, NULL)) { done = 1; back = dk4uc2l_open(fnb, app); } } for (i = 1; i < 4; i++) { if ((0 == done) && (NULL == back)) { if (0 != dk4str_cpy_s(fnb,DK4_SIZEOF(fnb,dkChar),app->dir_share,NULL)) { if (0 != dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),dk4uc2l_kwnl[i],NULL)) { dk4path_correct_sep(fnb); if (0 != dk4file_is_directory(fnb, NULL)) { done = 1; back = dk4uc2l_open(fnb, app); } } else { toolo = 1; } } else { toolo = 1; } } } } if (NULL == back) { if (0 == done) { if (0 != toolo) { /* ERROR: shared directory name too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, app->dir_share); } else { /* ERROR: No charmap directory found */ debmsg = dk4app_string_table(app, dk4uc2l_kwnl[8], dk4uc2l_kw_def); szdm = dk4app_string_table_size(dk4uc2l_kw_def); dk4app_log_1(app, debmsg, szdm, DK4_LL_ERROR, 15); } } } #line 2234 "dk4uc2l.ctr" return back; } void dk4uc2l_clean_packages_and_fonts(dk4_uc2l_t *ulptr) { dk4_uc2l_pkg_t *pptr; #line 2244 "dk4uc2l.ctr" if (NULL != ulptr) { ulptr->fallowed = DK4_UC2L_FONT_ENCODING_ALL; dk4sto_it_reset(ulptr->i_pkgs); do { pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs); if (NULL != pptr) { pptr->used = 0x00; } } while (NULL != pptr); } #line 2254 "dk4uc2l.ctr" } unsigned char dk4uc2l_retrieve_allowed_fe(dk4_uc2l_t *ulptr) { unsigned char back = 0x00; #line 2263 "dk4uc2l.ctr" if (NULL != ulptr) { back = ulptr->fallowed; } #line 2266 "dk4uc2l.ctr" return back; } void dk4uc2l_allow_utf8(dk4_uc2l_t *ulptr, int enabled) { if (NULL != ulptr) { ulptr->utf8allowed = ((0 != enabled) ? 0x01 : 0x00); } } int dk4uc2lat_direct(dk4_c32_t c32) { int back = 0; char c; /* 8-bit character version of c32. */ #line 2287 "dk4uc2l.ctr" if((unsigned long)c32 < 128UL) { c = (char)c32; switch(c) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ',': case '.': case ':': case ';': case '+': case '-': case '?': case '!': case '|': case '@': case '(': case ')': case '/': case '=': case ' ': { back = 1; } break; } } #line 2307 "dk4uc2l.ctr" return back; } void dk4uc2l_recommendations(dk4_uc2l_t *ulptr, FILE *fipo) { dk4_uc2l_pkg_t *pptr; if ((NULL != ulptr) && (NULL != fipo)) { fputs(dk4uc2l_kw8[0], fipo); if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T1)) { fputs(dk4uc2l_kw8[3], fipo); } if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_OT1)) { fputs(dk4uc2l_kw8[2], fipo); } if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T4)) { fputs(dk4uc2l_kw8[4], fipo); } if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T5)) { fputs(dk4uc2l_kw8[5], fipo); } fputc('\n', stdout); dk4sto_it_reset(ulptr->i_pkgs); do { pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs); if (NULL != pptr) { if (0x00 != pptr->used) { fputs(dk4uc2l_kw8[1], fipo); fputs(pptr->pn, fipo); fputc('\n', fipo); } } } while (NULL != pptr); } } int dk4uc2l_retrieve_errors(dk4_uc2l_t *ulptr) { int back = 0; if (NULL != ulptr) { back = ulptr->had_error; } return back; }