diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4uc2l.c |
Initial commit
Diffstat (limited to 'support/dktools/dk4uc2l.c')
-rw-r--r-- | support/dktools/dk4uc2l.c | 2358 |
1 files changed, 2358 insertions, 0 deletions
diff --git a/support/dktools/dk4uc2l.c b/support/dktools/dk4uc2l.c new file mode 100644 index 0000000000..3f8d54446f --- /dev/null +++ b/support/dktools/dk4uc2l.c @@ -0,0 +1,2358 @@ +/* + 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 <stdio.h> + +#if DK4_HAVE_STRING_H +#ifndef STRING_H_INCLUDED +#include <string.h> +#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 l<r. +*/ +static +int +dk4uc2l_pkg_compare(const void *l, const void *r, int cr) +{ + + const dk4_uc2l_pkg_t *pl; + const dk4_uc2l_pkg_t *pr; + int back = 0; + + if (NULL != l) { + if (NULL != r) { + pl = (const dk4_uc2l_pkg_t *)l; + switch (cr) { + case 1: { + back = strcmp(pl->pn, (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 l<r, + 1 if l>r. +*/ +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 l<r, 0 if l=r, 1 if l>r. +*/ +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; +} + + |