diff options
author | Norbert Preining <norbert@preining.info> | 2020-09-20 03:03:26 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-09-20 03:03:26 +0000 |
commit | 1f457376b478257b88d4a857f5ec1b6155442dd7 (patch) | |
tree | 2a06a60551dea362cf8cb0cb0ba66c78608717c4 /support/dktools/dk4uc2la.c | |
parent | ac690ca29ad5bf8a5203a65fd6252f7b564f4727 (diff) |
CTAN sync 202009200303
Diffstat (limited to 'support/dktools/dk4uc2la.c')
-rw-r--r-- | support/dktools/dk4uc2la.c | 2445 |
1 files changed, 2445 insertions, 0 deletions
diff --git a/support/dktools/dk4uc2la.c b/support/dktools/dk4uc2la.c new file mode 100644 index 0000000000..855e157ac5 --- /dev/null +++ b/support/dktools/dk4uc2la.c @@ -0,0 +1,2445 @@ +/* +Copyright (C) 2015-2020, Dirk Krause +SPDX-License-Identifier: BSD-3-Clause +*/ + +/* + WARNING: This file was generated by the dkct program (see + http://dktools.sourceforge.net/ for details). + 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: dk4uc2la.ctr +*/ + +/** @file dk4uc2la.c The dk4uc2la module. +*/ + + +#line 250 "dk4uc2la.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 "dk4uc2la.h" +#include "dk4mem.h" +#include "dk4mema.h" +#include "dk4str8.h" +#include "dk4strd.h" +#include "dk4utf8.h" +#include "dk4utf16.h" +#include "dk4ansi.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 "dk4mai8hul.h" +#include "dk4maodh.h" +#include "dk4maodd.h" +#include "dk4unused.h" +#include "dk4rec26.h" +#include "uc2l.h" + +#if DK4_HAVE_ASSERT_H +#ifndef ASSERT_H_INCLUDED +#include <assert.h> +#define ASSERT_H_INCLUDED 1 +#endif +#endif + + + + +#line 298 "dk4uc2la.ctr" + + + +/** Convert to unsigned long. +*/ +#define UL(x) ((unsigned long)(x)) + + + +/** Object to use and modify from line handler. +*/ +typedef struct { + dk4_uc2l_t *ulptr; /**< Conversion structure. */ + dk4_sto_t *s_ra; /**< Local range storage. */ + dk4_sto_it_t *i_ra; /**< Local range iterator. */ + dk4_uc2l_file_t *file; /**< File structure. */ + dk4_uc2l_range_t *rpc; /**< Range pointer cache, pass 2. */ + dk4_app_t *app; /**< Application structure. */ + const dkChar * const *msgs; /**< Localized message texts. */ + size_t szmsgs; /**< Number of elements in msgs. */ + int e_d; /**< Reported decoding errors. */ + int e_e; /**< Reported encoding errors. */ + int e_p; /**< Reported processing errors. */ +} handler_object_t; + + + +/** 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 354 "dk4uc2la.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\tIgnoring redefinition of 0x"), + +/* 3 */ +dkT("!"), + +/* 4 */ +dkT("Syntax error!\n\tIgnoring redefinition 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!"), + +/* 28 */ +dkT("Syntax error!\n\tIgnoring redefinition of 0x"), + +/* 29 */ +dkT("\n\tpreviously defined in \""), + +/* 30 */ +dkT("\"!"), + +/* 31 */ +dkT("No LaTeX encoding found for U+"), + +/* 32 */ +dkT("!"), + +NULL + + +#line 444 "dk4uc2la.ctr" +}; + + + +/** Opening and closing tag for math mode. +*/ +static const char * const dk4uc2l_mm[] = { +"\\(", "\\)" +}; + + + + +/** Handler to process a line during pass 1. + @param obj Object to use and modify during processing. + @param line Current text line to process. + @param lineno Current line number. + @param erp Error report, may be NULL. + @return DK4_TSP_RES_OK on success, DK4_TSP_RES_ERROR on recoverable + errors, DK4_TSP_RES_FATAL on fatal errors requiring an abort. +*/ +static +int +dk4uc2l_handler_pass1( + void *obj, + char *line, + dk4_um_t lineno, + dk4_er_t *erp +) +{ + dkChar numbuf[16*sizeof(dk4_um_t)]; + handler_object_t *pho; + char *p1; + dk4_uc2l_range_t *rptr; + dk4_uc2l_range_t *r2; + const char *pe = NULL; + size_t sznb = DK4_SIZEOF(numbuf,dkChar); + size_t padsz = 8; + unsigned long ul = 0UL; + dk4_c32_t c32; + dk4_c32_t rbo; + int res; + int back = DK4_TSP_RES_OK; +#if TRACE_DEBUG + dk4str8_delnl(line); +#endif + + +#line 491 "dk4uc2la.ctr" + pho = (handler_object_t *)obj; + dk4app_set_log_source_line(pho->app, lineno); + + /* Find start of line, ignore empty lines and comments + */ + p1 = dk4str8_start(line, NULL); + if (NULL == p1) { + goto finished; + } + if ('#' == *p1) { + goto finished; + } + + /* Retrieve hexadecimal number at start + */ + (void)dk4str8_next(p1, NULL); + res = dk4ma_input_c8_hex_ulong(&ul, p1, &pe, 1, erp); + if (0 == res) { + /* ERROR: Syntax, not a number */ + dk4app_log_1(pho->app, pho->msgs, pho->szmsgs, DK4_LL_ERROR, 0); + goto finished; + } + c32 = (dk4_c32_t)ul; + +#line 514 "dk4uc2la.ctr" + + /* Check for number in global storage + */ + rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like( + pho->ulptr->i_ranges, &c32, 1 + ); + if (NULL != rptr) { + +#line 521 "dk4uc2la.ctr" + /* ERROR: Ignoring redefinition */ + if ((dk4_c32_t)0xFFUL < c32) { + if ((dk4_c32_t)0xFFFFUL < c32) { + if ((dk4_c32_t)0xFFFFFFUL < c32) { + padsz = 8; + } + else { + padsz = 6; + } + } + else { + padsz = 4; + } + } + else { + padsz = 2; + } + if (0 != dk4ma_write_hex_unsigned(numbuf, sznb, c32, padsz, NULL)) { + dk4app_log_5( + pho->app, pho->msgs, pho->szmsgs, DK4_LL_ERROR, + 28, 29, 30, numbuf, rptr->file->fn + ); + } + else { + dk4app_log_1(pho->app, pho->msgs, pho->szmsgs, DK4_LL_ERROR, 4); + } + goto finished; + } + + /* Check for number in storage for file + */ + rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(pho->i_ra, &c32, 1); + if (NULL != rptr) { + +#line 554 "dk4uc2la.ctr" + /* ERROR: Ignoring redefinition */ + if ((dk4_c32_t)0xFFUL < c32) { + if ((dk4_c32_t)0xFFFFUL < c32) { + if ((dk4_c32_t)0xFFFFFFUL < c32) { + padsz = 8; + } + else { + padsz = 6; + } + } + else { + padsz = 4; + } + } + else { + padsz = 2; + } + if (0 != dk4ma_write_hex_unsigned(numbuf, sznb, c32, padsz, NULL)) { + dk4app_log_3( + pho->app, pho->msgs, pho->szmsgs, DK4_LL_ERROR, 2, 3, numbuf + ); + } + else { + dk4app_log_1(pho->app, pho->msgs, pho->szmsgs, DK4_LL_ERROR, 4); + } + goto finished; + } + + /* Check whether appending to an existing range + */ + if (0UL < c32) { + rbo = c32 - 1UL; + rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(pho->i_ra, &rbo, 1); + if (NULL != rptr) { + rptr->end = c32; +#if DK4_SIZEOF_LONG <= 4 + if ((dk4_um_t)(ULONG_MAX) > (dk4_um_t)c32) { +#endif + rbo = c32 + 1UL; + r2 = (dk4_uc2l_range_t *)dk4sto_it_find_like( + pho->i_ra, &rbo, 1 + ); + if (NULL != r2) { + dk4sto_remove(pho->s_ra, r2, NULL); + rptr->end = r2->end; + dk4uc2l_i_close_range(r2); + } +#if DK4_SIZEOF_LONG <= 4 + } +#endif + goto finished; + } +#if TRACE_DEBUG + else { + +#line 608 "dk4uc2la.ctr" + } +#endif + } + + /* Check whether prepending to an existing range + */ +#if DK4_SIZEOF_LONG <= 4 + if ((dk4_um_t)(ULONG_MAX) > (dk4_um_t)c32) { +#endif + rbo = c32 + 1UL; + rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(pho->i_ra, &rbo, 1); + if (NULL != rptr) { + rptr->start = c32; + if ((dk4_c32_t)0UL < c32) { + rbo = c32 - 1UL; + r2 = (dk4_uc2l_range_t *)dk4sto_it_find_like( + pho->i_ra, &rbo, 1 + ); + if (NULL != r2) { + dk4sto_remove(pho->s_ra, r2, NULL); + rptr->start = r2->start; + dk4uc2l_i_close_range(r2); + } + } + goto finished; + } +#if TRACE_DEBUG + else { + +#line 636 "dk4uc2la.ctr" + } +#endif +#if DK4_SIZEOF_LONG <= 4 + } +#endif + + /* Create new range for one character on its own + */ + rptr = dk4uc2l_i_open_range(c32, pho->file, erp); + if (NULL == rptr) { + back = DK4_TSP_RES_FATAL; + /* ERROR: Memory */ + dk4app_log_base1(pho->app, DK4_LL_ERROR, 90); + goto finished; + } + if (0 == dk4sto_add(pho->s_ra, rptr, erp)) { + dk4uc2l_i_close_range(rptr); + /* ERROR: Memory */ + dk4app_log_base1(pho->app, DK4_LL_ERROR, 90); + back = DK4_TSP_RES_FATAL; + } + + finished: + + +#line 660 "dk4uc2la.ctr" + return back; +} + + + +/** Report an error with position in source line. + @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. + @param dmsg Localized error message texts. + @param szdmsg Number of elements in dmsg array. +*/ +static +void +dk4uc2l_report_with_pos( + 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, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + dkChar b1[8*(1+sizeof(dk4_um_t))]; + dkChar b2[DK4_SIZEOF(b1,dkChar)]; + dkChar b3[DK4_SIZEOF(b1,dkChar)]; + size_t szbuf = DK4_SIZEOF(b1,dkChar); + 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, szbuf, cil, 0, NULL)) { + if (0 != dk4ma_write_decimal_unsigned(b2, szbuf, cno, 0, NULL)) { + if (0 != dk4ma_write_decimal_unsigned(b1, szbuf, bno, 0, NULL)) { + allbuffersok = 1; + } + } + } + if (0 != allbuffersok) { + dk4app_log_7( + app, dmsg, szdmsg, DK4_LL_ERROR, i1, 19, 20, 21, b1, b2, b3 + ); + } + else { + dk4app_log_1( + app, dmsg, szdmsg, DK4_LL_ERROR, i2 + ); + } + dk4app_set_log_source_line(app, oldlogline); +} + + + +/** Report errors from text stream processing. + @param app Application structure, may be NULL. + @param obj Object modified by line handler. + @param er_en Error report for decoding and encoding errors. + @param er_pr Error report for processing errors. + @param dmsg Localized error message texts. + @param szmsg Number of elements in dmsg array. +*/ +static +void +dk4uc2l_report_errors( + dk4_app_t *app, + handler_object_t *obj, + dk4_er_t *er_en, + dk4_er_t *er_pr, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + 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( + app, 16, 22, + er_en->dt.fpos.byteno, + er_en->dt.fpos.lineno, + er_en->dt.fpos.charno, + er_en->dt.fpos.charinline, + dmsg, szdmsg + ); + } break; + case 2: { + dk4app_log_1(app, dmsg, szdmsg, 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( + app, 17, 23, + er_en->dt.fpos.byteno, + er_en->dt.fpos.lineno, + er_en->dt.fpos.charno, + er_en->dt.fpos.charinline, + dmsg, szdmsg + ); + } break; + case 2: { + dk4app_log_1(app, dmsg, szdmsg, 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( + app, 18, 24, + er_pr->dt.fpos.byteno, + er_pr->dt.fpos.lineno, + er_pr->dt.fpos.charno, + er_pr->dt.fpos.charinline, + dmsg, szdmsg + ); + } break; + case 2: { + dk4app_log_1(app, dmsg, szdmsg, DK4_LL_ERROR, 27); + } break; + } + if (3 > obj->e_p) { obj->e_p += 1; } + } + } +} + + +/** Process one stream from file in pass 1. + @param ulptr Conversion structure to set up. + @param rstrm Stream to read data from. + @param puc2lf File structure. + @param bptr Address of success variable to reset on error. + @param app Application structure for diagnostics. + @param dmsg Localized messages texts. + @param szdmsg Size of dmsg array (number of string pointers). +*/ +static +void +dk4uc2l_i_process_stream_pass1( + dk4_uc2l_t *ulptr, + dk4_stream_t *rstrm, + dk4_uc2l_file_t *puc2lf, + int *bptr, + dk4_app_t *app, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + char lnbuf[256]; + dk4_tsp08_t tsp08; + handler_object_t ho; + dk4_er_t er_en; + dk4_er_t er_pr; + dk4_uc2l_range_t *rptr; + int res; + int cc; + char c; + + +#line 831 "dk4uc2la.ctr" + + /* Initialize handler object + */ + ho.file = puc2lf; + ho.ulptr = ulptr; + ho.s_ra = NULL; + ho.i_ra = NULL; + ho.app = app; + ho.msgs = dmsg; + ho.szmsgs = szdmsg; + ho.e_d = 0; + ho.e_e = 0; + ho.e_p = 0; + dk4error_init(&er_en); + dk4error_init(&er_pr); + + /* Allocate storage and iterator + */ + ho.s_ra = dk4sto_open(NULL); + if (NULL == ho.s_ra) { + *bptr = 0; + ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + /* ERROR: Memory */ + dk4app_log_base1(app, DK4_LL_ERROR, 90); + goto finished; + } + dk4sto_set_comp(ho.s_ra, dk4uc2l_i_range_compare, 0); + ho.i_ra = dk4sto_it_open(ho.s_ra, NULL); + if (NULL == ho.i_ra) { + *bptr = 0; + ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + /* ERROR: Memory */ + dk4app_log_base1(app, DK4_LL_ERROR, 90); + goto finished; + } + + /* Initialize text stream processor + */ + res = dk4tsp08_setup_line( + &tsp08, (void *)(&ho), dk4uc2l_handler_pass1, lnbuf, sizeof(lnbuf), + DK4_ENCODING_PLAIN, DK4_ENCODING_PLAIN, NULL + ); + if (0 == res) { + *bptr = 0; + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + /* ERROR: Failed to initialize text stream processor */ + dk4app_log_1(app, dmsg, szdmsg, DK4_LL_ERROR, 5); + goto finished; + } + + /* Process input data + */ + do { + cc = 0; + res = dk4stream_c8_read_byte(&c, rstrm, NULL); + if (0 != res) { + cc = 1; + res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c); + switch (res) { + case DK4_TSP_RES_ERROR : { + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + *bptr = 0; + dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); + dk4uc2l_report_errors( + app, &ho, &er_en, &er_pr, dmsg, szdmsg + ); + dk4error_init(&er_en); + dk4error_init(&er_pr); + } break; + case DK4_TSP_RES_FATAL : { + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + *bptr = 0; + dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); + dk4uc2l_report_errors( + app, &ho, &er_en, &er_pr, dmsg, szdmsg + ); + dk4error_init(&er_en); + dk4error_init(&er_pr); + goto finished; + } break; + } + } + } while (0 < cc); + + /* Finalize text stream processor + */ + res = dk4tsp08_finish(&tsp08); + switch (res) { + case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + *bptr = 0; + dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); + dk4uc2l_report_errors( + app, &ho, &er_en, &er_pr, dmsg, szdmsg + ); + goto finished; + } break; + } + + /* Transfer ranges to global storage + */ + do { + dk4sto_it_reset(ho.i_ra); + rptr = (dk4_uc2l_range_t *)dk4sto_it_next(ho.i_ra); + if (NULL != rptr) { + dk4sto_remove(ho.s_ra, rptr, NULL); + if (0 == dk4sto_add(ulptr->s_ranges, rptr, NULL)) { + dk4uc2l_i_close_range(rptr); + *bptr = 0; + /* ERROR: Memory */ + dk4app_log_base1(app, DK4_LL_ERROR, 90); + goto finished; + } + } + } while (NULL != rptr); + + /* Release resources + */ + finished: + if (NULL != ho.s_ra) { + if (NULL != ho.i_ra) { + dk4sto_it_reset(ho.i_ra); + do { + rptr = (dk4_uc2l_range_t *)dk4sto_it_next(ho.i_ra); + if (NULL != rptr) { + dk4uc2l_i_close_range(rptr); + } + } while (NULL != rptr); + dk4sto_it_close(ho.i_ra); + } + dk4sto_close(ho.s_ra); + } + + + +#line 965 "dk4uc2la.ctr" +} + + + + +/** Process one file in pass 1 specified by absolute path name. + @param ulptr Conversion structure to set up. + @param fn Absolute file name. + @param sfn Short (relative) file name within given directory. + @param bptr Address of success variable to reset on error. + @param app Application structure for diagnostics. + @param dmsg Localized messages texts. + @param szdmsg Size of dmsg array (number of string pointers). +*/ +static +void +dk4uc2l_i_process_one_full_file_pass1( + dk4_uc2l_t *ulptr, + const dkChar *fn, + const dkChar *sfn, + int *bptr, + dk4_app_t *app, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + const dkChar *oldsourcefile; + dk4_stream_t *rstrm; + dk4_uc2l_file_t *puc2lf; + dk4_um_t oldsourceline; + int fnsi; + + +#line 997 "dk4uc2la.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); + puc2lf = (dk4_uc2l_file_t *)dk4sto_it_find_like(ulptr->i_files, sfn, 1); + if (NULL == puc2lf) { + puc2lf = dk4uc2l_i_open_file(sfn, NULL); + if (NULL != puc2lf) { + if (0 != dk4sto_add(ulptr->s_files, puc2lf, NULL)) { + fnsi = dk4uc2l_i_find_suffix_index(fn); + if (-1 < fnsi) { + if (0 != dk4uc2l_i_suffix_index_supported(fnsi)) { + rstrm = dk4stream_open_file_reader(fn, NULL); + if (NULL != rstrm) { + dk4uc2l_i_process_stream_pass1( + ulptr, rstrm, puc2lf, bptr, app, dmsg, szdmsg + ); + dk4stream_close(rstrm, NULL); + } + else { + +#line 1017 "dk4uc2la.ctr" + ulptr->had_error |= DK4_UC2L_ERROR_FOPEN; + /* ERROR: Failed to read file */ + dk4app_log_3(app,dmsg,szdmsg,DK4_LL_ERROR,6,7,fn); + *bptr = 0; + } + } + else { + +#line 1024 "dk4uc2la.ctr" + /* ERROR: Unsupported compression mechanism */ + dk4app_log_3(app,dmsg,szdmsg,DK4_LL_ERROR,6,7,fn); + ulptr->had_error |= DK4_UC2L_ERROR_FOPEN; + *bptr = 0; + } + } + else { + +#line 1031 "dk4uc2la.ctr" + /* Warning: Unsupported file type */ + dk4app_log_3(app,dmsg,szdmsg,DK4_LL_ERROR,6,7,fn); + } + } + else { + +#line 1036 "dk4uc2la.ctr" + dk4uc2l_i_close_file(puc2lf); + /* ERROR: Memory */ + dk4app_log_base1(app, DK4_LL_ERROR, 90); + } + } + else { + +#line 1042 "dk4uc2la.ctr" + /* ERROR: Memory */ + dk4app_log_base1(app, DK4_LL_ERROR, 90); + } + } + else { + +#line 1047 "dk4uc2la.ctr" + /* BUG file already processed */ + } + dk4app_set_log_source_file(app, oldsourcefile); + dk4app_set_log_source_line(app, oldsourceline); + + +#line 1052 "dk4uc2la.ctr" +} + + + +/** Process one file in pass 1. + @param ulptr Conversion structure to set up. + @param pth Directory path name, may be NULL. + @param fn Short file name within given directory. + @param bptr Address of success variable to reset on error. + @param app Application structure for diagnostics. + @param dmsg Localized messages texts. + @param szdmsg Size of dmsg array (number of string pointers). +*/ +static +void +dk4uc2l_i_process_one_file_pass1( + dk4_uc2l_t *ulptr, + const dkChar *pth, + const dkChar *fn, + int *bptr, + dk4_app_t *app, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + dkChar fnb[DK4_MAX_PATH]; + size_t szfnb = DK4_SIZEOF(fnb,dkChar); + + +#line 1080 "dk4uc2la.ctr" + if (NULL != pth) { + if (0 != dk4str_cpy_s(fnb, szfnb, pth, NULL)) { + if (0 != dk4str_cat_s(fnb, szfnb, dk4uc2l_kwnl[7], NULL)) { + if (0 != dk4str_cat_s(fnb, szfnb, fn, NULL)) { + dk4path_correct_sep(fnb); + dk4uc2l_i_process_one_full_file_pass1( + ulptr, fnb, fn, bptr, app, dmsg, szdmsg + ); + } + else { + *bptr = 0; + /* ERROR pth and/or fn too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + } + } + else { + *bptr = 0; + /* ERROR: pth too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + } + } + else { + *bptr = 0; + /* ERROR: pth too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + } + } + else { + dk4uc2l_i_process_one_full_file_pass1(ulptr,fn,fn,bptr,app,dmsg,szdmsg); + } + + +#line 1111 "dk4uc2la.ctr" +} + + + +/** First pass to gather information which Unicode position is configured + in which data file. + This function is run while creating a new conversion structure + to fill the range structures so we can later find a file for a + Unicode position. + If this function fails, the conversion structure is considered + unusable. + The function fails only on memory allocation failures. + Syntax errors in translation files are reported as errors through + app, but the function indicates success. + @param ulptr Conversion structure. + @param app Application structure for diagnostics, may be NULL. + @return 1 on success, 0 on error. +*/ +static +int +dk4uc2l_i_pass1( + dk4_uc2l_t *ulptr, + dk4_app_t *app, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + const dkChar *fn = NULL; + const dkChar *pth = NULL; + dk4_dir_t *pdir = NULL; + int back = 0; + + +#line 1143 "dk4uc2la.ctr" + pdir = dk4dir_open_app(ulptr->dname, 0, app); + if (NULL != pdir) { + pth = dk4dir_get_path(pdir); + back = 1; + do { + fn = dk4dir_next_file(pdir); + if (NULL != fn) { + if (-1 < dk4uc2l_i_find_suffix_index(fn)) { + dk4uc2l_i_process_one_file_pass1( + ulptr, pth, fn, &back, app, dmsg, szdmsg + ); + } + } + } while (NULL != fn); + dk4dir_close(pdir); + } + else { + +#line 1160 "dk4uc2la.ctr" + /* ERROR: Failed to open directory (already reported) */ + ulptr->had_error |= DK4_UC2L_ERROR_FOPEN; + } + + +#line 1164 "dk4uc2la.ctr" + return back; +} + + + +/** Handler to process a line during pass 1. + @param obj Object to use and modify during processing. + @param line Current text line to process. + @param lineno Current line number. + @param erp Error report, may be NULL. + @return DK4_TSP_RES_OK on success, DK4_TSP_RES_ERROR on recoverable + errors, DK4_TSP_RES_FATAL on fatal errors requiring an abort. +*/ +static +int +dk4uc2l_handler_pass2( + void *obj, + char *line, + dk4_um_t lineno, + dk4_er_t * DK4_ARG_UNUSED(erp) +) +{ + dk4_er_t er; + char *pkgn[16]; + handler_object_t *lho = NULL; + const char *pe = NULL; + char *p1 = NULL; + char *p2 = NULL; + char *p3 = NULL; + char *p4 = NULL; + dk4_uc2l_range_t *rptr = NULL; + dk4_uc2l_pkg_t *pptr = NULL; + size_t ind = 0; + size_t numpkg = 0; + size_t i = 0; + unsigned long ul = 0UL; + dk4_c32_t c32 = (dk4_c32_t)0UL; + int back = DK4_TSP_RES_OK; + int res = 0; + int adding = 0; + unsigned char fex = 0; + unsigned char feval = 0; + + DK4_UNUSED_ARG(erp) + + +#line 1209 "dk4uc2la.ctr" +#if TRACE_DEBUG + dk4str8_delnl(line); + + +#line 1212 "dk4uc2la.ctr" +#endif + + /* Line handler object + */ + lho = (handler_object_t *)obj; + dk4app_set_log_source_line(lho->app, lineno); + + /* Find start of line, ignore empty lines and comments + */ + p1 = dk4str8_start(line, NULL); + if (NULL == p1) { + +#line 1223 "dk4uc2la.ctr" + goto finished; + } + if ('#' == *p1) { + +#line 1226 "dk4uc2la.ctr" + goto finished; + } + + /* Retrieve character number + */ + p2 = dk4str8_next(p1, NULL); + res = dk4ma_input_c8_hex_ulong(&ul, p1, &pe, 1, NULL); + if (0 == res) { + +#line 1234 "dk4uc2la.ctr" + /* WARNING: Syntax, no number. + Already reported in pass 1. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + goto finished; + } + c32 = (dk4_c32_t)ul; + + /* Find and check range structure, attempt cached range pointer first + */ + if (NULL != lho->rpc) { + if ((lho->rpc->start <= c32) && (c32 <= lho->rpc->end)) { + rptr = lho->rpc; + } + } + if (NULL == rptr) { + rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lho->ulptr->i_ranges,&c32,1); + } + if (NULL == rptr) { + +#line 1253 "dk4uc2la.ctr" + /* ERROR: No range found. + Already reported in pass 1. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + back = DK4_TSP_RES_FATAL; + goto finished; + } + if (0 != dk4str_cmp(lho->file->fn, rptr->file->fn)) { + /* ERROR: Not owned by current file. + Already reported in pass 1. + */ + + +#line 1265 "dk4uc2la.ctr" + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + goto finished; + } + + /* Initialize range structure (allocate memory) if not yet done + */ + if (0x00 == rptr->ia) { + if (0 == dk4uc2l_i_init_range(rptr, NULL)) { + /* ERROR: Memory */ + dk4app_log_base1(lho->app, DK4_LL_ERROR, 90); + + +#line 1276 "dk4uc2la.ctr" + lho->ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + back = DK4_TSP_RES_FATAL; + goto finished; + } + rptr->ia = 0x01; + } + + /* Find index + */ + ind = (size_t)(c32 - rptr->start); + + /* Check whether character already defined + */ + if (NULL != rptr->lno) { + if ((dk4_um_t)0UL != (rptr->lno)[ind]) { + /* ERROR: Redefinition. + Already reported in pass 1. + */ + + +#line 1295 "dk4uc2la.ctr" + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + goto finished; + } + else { + (rptr->lno)[ind] = lineno; + } + } + + /* Traverse all strings in line + */ + p1 = p2; + while (NULL != p1) { + +#line 1307 "dk4uc2la.ctr" + p2 = dk4str8_next(p1, NULL); + p3 = dk4str8_chr(p1, '='); + if (NULL != p3) { + *(p3++) = '\0'; + p3 = dk4str8_start(p3, NULL); + if (NULL != p3) { + + +#line 1314 "dk4uc2la.ctr" + res = dk4uc2l_i_keyword_index(p1); + switch (res) { + case 0 : { + +#line 1317 "dk4uc2la.ctr" + if (NULL != rptr->both) { + if (NULL == (rptr->both)[ind]) { + (rptr->both)[ind] = dk4str8_dup(p3, NULL); + if (NULL == (rptr->both)[ind]) { + /* ERROR: Memory */ + dk4app_log_base1(lho->app, DK4_LL_ERROR, 90); + + +#line 1324 "dk4uc2la.ctr" + lho->ulptr->had_error |= + DK4_UC2L_ERROR_MEMORY; + } + } + else { + +#line 1329 "dk4uc2la.ctr" + /* ERROR: Already defined. + Bug: Should not happen. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + } + } + else { + +#line 1336 "dk4uc2la.ctr" + /* ERROR: Memory. + Already reported during range initialization. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + } + } break; + case 1 : { + +#line 1343 "dk4uc2la.ctr" + if (NULL != rptr->text) { + if (NULL == (rptr->text)[ind]) { + (rptr->text)[ind] = dk4str8_dup(p3, NULL); + if (NULL == (rptr->text)[ind]) { + /* ERROR: Memory */ + dk4app_log_base1(lho->app, DK4_LL_ERROR, 90); + + +#line 1350 "dk4uc2la.ctr" + lho->ulptr->had_error |= + DK4_UC2L_ERROR_MEMORY; + } + } + else { + +#line 1355 "dk4uc2la.ctr" + /* ERROR: Already defined. + Bug: Should not happen. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + } + } + else { + +#line 1362 "dk4uc2la.ctr" + /* ERROR: Memory + Already reported during range initialization. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + } + } break; + case 2 : { + +#line 1369 "dk4uc2la.ctr" + if (NULL != rptr->math) { + if (NULL == (rptr->math)[ind]) { + (rptr->math)[ind] = dk4str8_dup(p3, NULL); + if (NULL == (rptr->math)[ind]) { + /* ERROR: Memory */ + dk4app_log_base1(lho->app, DK4_LL_ERROR, 90); + + +#line 1376 "dk4uc2la.ctr" + lho->ulptr->had_error |= + DK4_UC2L_ERROR_MEMORY; + } + } + else { + +#line 1381 "dk4uc2la.ctr" + /* ERROR: Already defined. + Bug: Should not happen. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + } + } + else { + +#line 1388 "dk4uc2la.ctr" + /* ERROR: Memory. + Already reported during range initialization. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + } + } break; + case 3 : { + +#line 1395 "dk4uc2la.ctr" + if (NULL != rptr->fenc) { + adding = 1; + feval = 0x00; + if ('!' == *p3) { + adding = 0; + p3++; + feval = DK4_UC2L_FONT_ENCODING_ALL; + } + while (NULL != p3) { + p4 = dk4str8_chr(p3, ','); + if (NULL != p4) { + *(p4++) = '\0'; + } + fex = dk4uc2l_font_encoding_from_name(p3); + if (0x00 != fex) { + if (0 != adding) { + feval |= fex; + } + else { + feval &= (~(fex)); + } + } + else { + +#line 1418 "dk4uc2la.ctr" + /* ERROR: Illegal encoding name */ + dk4app_log_1( + lho->app, lho->msgs, lho->szmsgs, + DK4_LL_ERROR, 8 + ); + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + } + p3 = p4; + } + (rptr->fenc)[ind] = feval; + } + else { + /* ERROR: Memory. + Already reported during range initialization. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + } + } break; + case 4 : { + +#line 1437 "dk4uc2la.ctr" + if (NULL != rptr->pkgs) { + if (NULL == (rptr->pkgs)[ind]) { + dk4error_init(&er); + numpkg = dk4str8_tokenize( + pkgn, 16, p3, ",", &er + ); + if (0 < numpkg) { + (rptr->pkgs)[ind] = + dk4mem_new(dk4_uc2l_pkg_p,(numpkg+1),NULL); + if (NULL != (rptr->pkgs)[ind]) { + for (i = 0; i <= numpkg; i++) { + ((rptr->pkgs)[ind])[i] = NULL; + } + for (i = 0; i < numpkg; i++) { + pptr = + (dk4_uc2l_pkg_t *)dk4sto_it_find_like( + lho->ulptr->i_pkgs, pkgn[i], 1 + ); + if (NULL != pptr) { + ((rptr->pkgs)[ind])[i] = pptr; + } + else { + pptr = dk4uc2l_i_create_pkg( + lho->ulptr->s_pkgs, pkgn[i] + ); + if (NULL != pptr) { + ((rptr->pkgs)[ind])[i] = + pptr; + } + else { + +#line 1467 "dk4uc2la.ctr" + /* ERROR: Memory */ + dk4app_log_base1( + lho->app,DK4_LL_ERROR,90 + ); + lho->ulptr->had_error |= + DK4_UC2L_ERROR_MEMORY; + } + } + } + } + else { + +#line 1478 "dk4uc2la.ctr" + /* ERROR: Memory */ + dk4app_log_base1( + lho->app, DK4_LL_ERROR, 90 + ); + lho->ulptr->had_error |= + DK4_UC2L_ERROR_MEMORY; + } + } + else { + +#line 1487 "dk4uc2la.ctr" + dk4app_log_1( + lho->app, lho->msgs, lho->szmsgs, + DK4_LL_ERROR, 9 + ); + } + } + else { + +#line 1494 "dk4uc2la.ctr" + /* ERROR: Already defined. + Bug: Should not happen. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + } + } + else { + +#line 1501 "dk4uc2la.ctr" + /* ERROR: Memory. + Already reported during range initalization. + */ + lho->ulptr->had_error |= DK4_UC2L_ERROR_MEMORY; + } + } break; + default : { + +#line 1508 "dk4uc2la.ctr" + /* ERROR: Illegal key name */ + dk4app_log_1( + lho->app, lho->msgs, lho->szmsgs, DK4_LL_ERROR, 10 + ); + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + } break; + } + p1 = p2; + } + else { + +#line 1518 "dk4uc2la.ctr" + /* ERROR: Syntax, not a key=value */ + dk4app_log_1(lho->app,lho->msgs,lho->szmsgs,DK4_LL_ERROR,11); + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + p1 = NULL; + } + } + else { + +#line 1525 "dk4uc2la.ctr" + /* ERROR: Syntax, not a key=value */ + dk4app_log_1(lho->app, lho->msgs, lho->szmsgs, DK4_LL_ERROR, 11); + lho->ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX; + p1 = NULL; + } + } + + finished: + + +#line 1534 "dk4uc2la.ctr" + return back; +} + + + +/** Load one data file. + @param ulptr Conversion structure. + @param fptr File to load. + @param app Application structure for diagnostics. + @param dmsg Localized message texts. + @param szdmsg Number of elements in dmsg array. +*/ +static +void +dk4uc2l_load_data_file( + dk4_uc2l_t *ulptr, + dk4_uc2l_file_t *fptr, + dk4_app_t *app, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + dkChar fnb[DK4_MAX_PATH]; + char lnb[256]; + handler_object_t ho; + dk4_er_t er_en; + dk4_er_t er_pr; + dk4_tsp08_t tsp08; + dk4_stream_t *rstrm = NULL; + const dkChar *oldsourcefile = NULL; + dk4_um_t oldsourceline = (dk4_um_t)0UL; + size_t fnbsz = DK4_SIZEOF(fnb,dkChar); + size_t szlnb = sizeof(lnb); + int res; + int cc; + char c; + + + +#line 1572 "dk4uc2la.ctr" + + /* Save old source file and line, set new source file + */ + oldsourcefile = dk4app_get_log_source_file(app); + oldsourceline = dk4app_get_log_source_line(app); + dk4app_set_log_source_file(app, fptr->fn); + dk4app_set_log_source_line(app, (dk4_um_t)0UL); + + /* Initialize handler object + */ + ho.ulptr = ulptr; + ho.s_ra = NULL; + ho.i_ra = NULL; + ho.file = fptr; + ho.rpc = NULL; + ho.app = app; + ho.msgs = dmsg; + ho.szmsgs = szdmsg; + ho.e_d = 0; + ho.e_e = 0; + ho.e_p = 0; + dk4error_init(&er_en); + dk4error_init(&er_pr); + + /* Save source file name and line number + */ + + /* Each file should be loaded only once + */ + if (0x00 != fptr->loaded) { + goto finished; + } + fptr->loaded = 0x01; + + /* Construct full path name + */ + if (0 == dk4str_cpy_s(fnb, fnbsz, ulptr->dname, NULL)) { + /* ERROR: Directory name too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname); + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + goto finished; + } + if (0 == dk4str_cat_s(fnb, fnbsz, dk4uc2l_kwnl[7], NULL)) { + /* ERROR: Directory name too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname); + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + goto finished; + } + if (0 == dk4str_cat_s(fnb, fnbsz, fptr->fn, NULL)) { + /* ERROR: Directory name too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname); + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + goto finished; + } + dk4path_correct_sep(fnb); + dk4app_set_log_source_file(app, fnb); + + /* Open reader stream + */ + rstrm = dk4stream_open_file_reader(fnb, NULL); + if (NULL == rstrm) { + /* ERROR: Failed to read file */ + dk4app_log_3(app, dmsg, szdmsg, DK4_LL_ERROR, 6, 7, fnb); + ulptr->had_error |= DK4_UC2L_ERROR_FOPEN; + goto finished; + } + + /* Initialize text processing + */ + res = dk4tsp08_setup_line( + &tsp08, (void *)(&ho), dk4uc2l_handler_pass2, lnb, szlnb, + DK4_ENCODING_PLAIN, DK4_ENCODING_PLAIN, NULL + ); + if (0 == res) { + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + /* ERROR: Memory */ + dk4app_log_base1(app, DK4_LL_ERROR, 90); + goto finished; + } + + /* Process contents + */ + do { + cc = 0; + res = dk4stream_c8_read_byte(&c, rstrm, NULL); + if (0 < res) { + cc = 1; + res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c); + switch (res) { + case DK4_TSP_RES_ERROR : { + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); + dk4uc2l_report_errors( + app, &ho, &er_en, &er_pr, dmsg, szdmsg + ); + dk4error_init(&er_en); + dk4error_init(&er_pr); + } break; + case DK4_TSP_RES_FATAL : { + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); + dk4uc2l_report_errors( + app, &ho, &er_en, &er_pr, dmsg, szdmsg + ); + dk4error_init(&er_en); + dk4error_init(&er_pr); + goto finished; + } break; + } + } + } while (0 < cc); + + /* Finish text processing + */ + res = dk4tsp08_finish(&tsp08); + switch (res) { + case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { + ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING; + dk4tsp08_get_errors(&er_en, &er_pr, &tsp08); + dk4uc2l_report_errors( + app, &ho, &er_en, &er_pr, dmsg, szdmsg + ); + } break; + } + + /* Clean up + */ + finished: + if (NULL != rstrm) { + dk4stream_close(rstrm, NULL); + } + + /* Restore source file name and line number + */ + dk4app_set_log_source_file(app, oldsourcefile); + dk4app_set_log_source_line(app, oldsourceline); + + +#line 1709 "dk4uc2la.ctr" +} + + +/** Second pass to load all data files immediately. + @param ulptr Conversion structure. + @param app Application structure for diagnostics, may be NULL. + @param dmsg Localized message texts. + @param szdmsg Number of elements in dmsg array. + @return 1 on success, 0 on error. +*/ +static +int +dk4uc2l_i_pass2( + dk4_uc2l_t *ulptr, + dk4_app_t *app, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + dk4_sto_it_t *i_files = NULL; + dk4_uc2l_file_t *fptr; + int back = 0; + + /* Create iterator through files + */ + i_files = dk4sto_it_open(ulptr->s_files, NULL); + if (NULL == i_files) { + goto finished; + } + + back = 1; + dk4sto_it_reset(i_files); + do { + fptr = (dk4_uc2l_file_t *)dk4sto_it_next(i_files); + if (NULL != fptr) { + dk4uc2l_load_data_file( + ulptr, fptr, app, dmsg, szdmsg + ); + } + } while (NULL != fptr); + + /* Clean up + */ + finished: + if (NULL != i_files) { + dk4sto_it_close(i_files); + } + return back; +} + + + +/** Open Unicode to LaTeX conversion structure with application support. + @param dn Directory name containing the translation files. + @param app Application structure for diagnostics. + @param la Flag: Load all data files immediately. + @param dmsg Localized messages array. + @param szdmsg Localized messages array size. + @return Valid pointer on success (use dk4uc2l_close() to release + resources after use), NULL on error. +*/ +static +dk4_uc2l_t * +dk4uc2l_i_open_app( + const dkChar *dn, + dk4_app_t *app, + int la, + const dkChar * const *dmsg, + size_t szdmsg +) +{ + dk4_er_t er; + dk4_uc2l_t *back = NULL; + + +#line 1783 "dk4uc2la.ctr" + dk4error_init(&er); + back = dk4uc2l_i_new(dn, &er); + if (NULL != back) { + if (0 == dk4uc2l_i_pass1(back, app, dmsg, szdmsg)) { + dk4uc2l_close(back); + back = NULL; + } + else { + if (0 != la) { + if (0 == dk4uc2l_i_pass2(back, app, dmsg, szdmsg)) { + dk4uc2l_close(back); + back = NULL; + } + } + } + } + else { + /* ERROR: Memory */ + dk4app_log_base1(app, DK4_LL_ERROR, 90); + } + + +#line 1804 "dk4uc2la.ctr" + return back; +} + + + +dk4_uc2l_t * +dk4uc2l_open_app_ex1(const dkChar *dn, dk4_app_t *app, int la) +{ + dkChar fnb[DK4_MAX_PATH]; + const dkChar * const *dmsg = NULL; + dk4_uc2l_t *back = NULL; + size_t i; + size_t szdmsg = 0; + const size_t szfnb = DK4_SIZEOF(fnb,dkChar); + int toolo = 0; + + +#line 1820 "dk4uc2la.ctr" + if (NULL != app) { + szdmsg = dk4app_string_table_size(dk4uc2l_kw_def); + dmsg = dk4app_string_table(app, dk4uc2l_kwnl[8], dk4uc2l_kw_def); + /* + Retrieve fallback from preferences + */ + if (NULL == dn) { + if (0 != dk4app_pref_get(fnb, szfnb, app, dk4uc2l_kwnl[0], 0)) { + dk4path_correct_sep(fnb); + if (0 != dk4file_is_directory(fnb, NULL)) { + dn = fnb; + } + else { + /* ERROR: Not a directory */ + dk4app_log_base3(app, DK4_LL_ERROR, 152, 153, fnb); + } + } + } + /* Retrieve builtin fallbacks + */ + if (NULL == dn) { + for (i = 1; ((i < 4) && (NULL == dn)); i++) { + if (0 != dk4str_cpy_s(fnb, szfnb, app->dir_share, NULL)) { + if (0 != dk4str_cat_s(fnb, szfnb, dk4uc2l_kwnl[i], NULL)) { + dk4path_correct_sep(fnb); + if (0 != dk4file_is_directory(fnb, NULL)) { + dn = fnb; + } + } + else { + toolo = 1; + } + } + else { + toolo = 1; + } + } + } + if (NULL != dn) { + if (0 != dk4file_is_directory(dn, NULL)) { + back = dk4uc2l_i_open_app(dn, app, la, dmsg, szdmsg); + } + else { + /* ERROR: Not a directory */ + dk4app_log_base3(app, DK4_LL_ERROR, 152, 153, dn); + } + } + else { + if (0 != toolo) { + /* ERROR: Shared directory name too long! */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, app->dir_share); + } + else { + /* ERROR: No directory found */ + dk4app_log_1(app, dmsg, szdmsg, DK4_LL_ERROR, 15); + } + } + } + else { + back = dk4uc2l_open(dn, NULL); + } + + +#line 1882 "dk4uc2la.ctr" + return back; +} + + + +dk4_uc2l_t * +dk4uc2l_open_app(const dkChar *dn, dk4_app_t *app) +{ + return (dk4uc2l_open_app_ex1(dn, app, 0)); +} + + + +dk4_uc2l_t * +dk4uc2l_open_from_app(dk4_app_t *app) +{ + return (dk4uc2l_open_app(NULL, app)); +} + + + +dk4_uc2l_t * +dk4uc2l_open_from_app_ex1(dk4_app_t *app, int la) +{ + return (dk4uc2l_open_app_ex1(NULL, app, la)); +} + + + +static +const char * +dk4uc2l_i_find_app(dk4_uc2l_t *ulptr, dk4_c32_t c, int mm, dk4_app_t *app) +{ + dk4_uc2l_range_t *rptr; + dk4_uc2l_pkg_t **pkgpp; + dk4_uc2l_file_t *fptr; + const char *back = NULL; + const dkChar * const *dmsg; + size_t ind; + size_t szdmsg; + size_t blgt; + int res; + + +#line 1925 "dk4uc2la.ctr" +#if DK4_USE_ASSERT + assert(NULL != ulptr); +#endif + /* Attempt direct output + */ + if (0 != dk4uc2lat_direct(c)) { + ulptr->buf[0] = (char)c; + ulptr->buf[1] = '\0'; + back = &(ulptr->buf[0]); + goto finished; + } + + /* Attempt data loaded from file + */ + rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(ulptr->i_ranges, &c, 1); + if (NULL != rptr) { + fptr = rptr->file; + if (0x00 == fptr->loaded) { + szdmsg = dk4app_string_table_size(dk4uc2l_kw_def); + dmsg = dk4app_string_table(app, dk4uc2l_kwnl[8], dk4uc2l_kw_def); + dk4uc2l_load_data_file(ulptr, fptr, app, dmsg, szdmsg); + } + ind = (size_t)(c - rptr->start); + if (0 != mm) { + if (NULL != rptr->math) { + back = (rptr->math)[ind]; + } + } + else { + if (NULL != rptr->text) { + back = (rptr->text)[ind]; + } + } + if (NULL == back) { + if (NULL != rptr->both) { + back = (rptr->both)[ind]; + } + } + if (NULL != back) { + if (NULL != rptr->pkgs) { + pkgpp = (rptr->pkgs)[ind]; + if (NULL != pkgpp) { + while (NULL != *pkgpp) { + (*(pkgpp++))->used = 0x01; + } + } + } + if (NULL != rptr->fenc) { + ulptr->fallowed &= (rptr->fenc)[ind]; + } + goto finished; + } + } + + /* Attempt to use UTF-8 encoded or ASCII data directly + */ + if (0 == mm) { + if (0x00 != ulptr->utf8allowed) { + blgt = 15; + res = dk4utf8_encode( + (unsigned char *)(&(ulptr->buf[0])), &blgt, c, NULL + ); + if (0 != res) { + ulptr->buf[blgt] = '\0'; + back = &(ulptr->buf[0]); + } + else { + /* ##### ERROR: UTF-8 encoding failed */ + } + } + else { + if (dkC32(0x00000100) > c) { + ulptr->buf[0] = (char)c; + ulptr->buf[1] = '\0'; + back = &(ulptr->buf[0]); + } + } + } + + finished: + if (NULL != back) { + /* ERROR: No LaTeX encoding found for ... + The calling application should attempt to recover from this + error or report it. + */ + } + + +#line 2012 "dk4uc2la.ctr" + return back; +} + + + +const char * +dk4uc2l_find_app(dk4_uc2l_t *ulptr, dk4_c32_t c, int mm, dk4_app_t *app) +{ + + const char *back = NULL; + + +#line 2023 "dk4uc2la.ctr" +#if DK4_USE_ASSERT + assert(NULL != ulptr); +#endif + if (NULL != ulptr) { + if (NULL != app) { + back = dk4uc2l_i_find_app(ulptr, c, mm, app); + } + else { + back = dk4uc2l_find(ulptr, c, mm, NULL); + } + } + + +#line 2035 "dk4uc2la.ctr" + return back; +} + + + +/* ##### untested */ +static +void +dk4uc2l_putc32_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + dk4_c32_t c32, + int *pmm, + int *pback, + dk4_app_t *app +) +{ + dkChar nb[16*sizeof(dk4_um_t)]; + dk4_er_t er; + const dkChar * const *dmsg; + const char *le = NULL; + size_t padsz = 8; + size_t szdmsg = 0; + size_t sznb = DK4_SIZEOF(nb,dkChar); + + +#line 2060 "dk4uc2la.ctr" + le = dk4uc2l_find(ulptr, c32, 0, NULL); + if (NULL != le) { + if (0 != *pmm) { + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, dk4uc2l_mm[1], &er)) { + *pback = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + *pmm = 0; + } + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, le, &er)) { + *pback = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + } + else { + dk4error_init(&er); + le = dk4uc2l_find(ulptr, c32, 1, &er); + if (NULL != le) { + if (0 == *pmm) { + if (0 == dk4stream_write_char_string(wstrm,dk4uc2l_mm[0],&er)) { + *pback = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + *pmm = 1; + } + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, le, &er)) { + *pback = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + } + else { + *pback = 0; + /* ERROR: Not found */ + szdmsg = dk4app_string_table_size(dk4uc2l_kw_def); + dmsg = dk4app_string_table(app, dk4uc2l_kwnl[8], dk4uc2l_kw_def); + if ((dk4_c32_t)0xFFUL < c32) { + if ((dk4_c32_t)0xFFFFUL < c32) { + if ((dk4_c32_t)0xFFFFFFUL < c32) { + padsz = 8; + } + else { + padsz = 6; + } + } + else { + padsz = 4; + } + } + else { + padsz = 2; + } + if (0 != dk4ma_write_hex_unsigned(nb, sznb, c32, padsz, NULL)) { + dk4app_log_3(app, dmsg, szdmsg, DK4_LL_ERROR, 31, 32, nb); + } +#if TRACE_DEBUG + else { + +#line 2123 "dk4uc2la.ctr" + } +#endif + } + } + + +#line 2128 "dk4uc2la.ctr" +} + + + +/* ##### untested */ +int +dk4uc2l_string_c32_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + const dk4_c32_t *str, + dk4_app_t *app +) +{ + dk4_er_t er; + int back = 0; + int mm = 0; + + +#line 2145 "dk4uc2la.ctr" +#if DK4_USE_ASSERT + assert(NULL != wstrm); + assert(NULL != ulptr); + assert(NULL != str); +#endif + /* Check arguments + */ + if ((NULL == wstrm) || (NULL == ulptr) || (NULL == str)) { + goto finished; + } + + /* Process string + */ + back = 1; + while (dkC32(0) != *str) { + dk4uc2l_putc32_app(wstrm, ulptr, *(str++), &mm, &back, app); + } + + /* Finalize math mode if necessary + */ + if (0 != mm) { + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, dk4uc2l_mm[1], &er)) { + back = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + } + + finished: + + +#line 2176 "dk4uc2la.ctr" + return back; +} + + + +/* ##### untested */ +int +dk4uc2l_string_c16_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + const dk4_c16_t *str, + dk4_app_t *app +) +{ + dk4_utf16_decoder_t dec; + dk4_er_t er; + dk4_c32_t c32; + int mm = 0; + int back = 0; + int err = 0; + + +#line 2197 "dk4uc2la.ctr" +#if DK4_USE_ASSERT + assert(NULL != wstrm); + assert(NULL != ulptr); + assert(NULL != str); +#endif + /* Check arguments + */ + if ((NULL == wstrm) || (NULL == ulptr) || (NULL == str)) { + goto finished; + } + + /* Process string + */ + back = 1; + dk4utf16_init(&dec); + while ((dkC16(0) != *str) && (0 == err)) { + switch (dk4utf16_add(&dec, *(str++))) { + case DK4_EDSTM_FINISHED : { + c32 = dk4utf16_get(&dec); + dk4utf16_init(&dec); + dk4uc2l_putc32_app(wstrm, ulptr, c32, &mm, &back, app); + } break; + case DK4_EDSTM_ERROR : { + err = 1; + back = 0; + /* ##### ERROR: Decoding failed */ + } break; + } + } + if (0 == err) { + if (0 == dk4utf16_is_empty(&dec)) { + back = 0; + /* ##### ERROR: Decoding failed */ + } + } + + /* Finalize math mode if necessary + */ + if (0 != mm) { + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, dk4uc2l_mm[1], &er)) { + back = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + } + finished: + + +#line 2245 "dk4uc2la.ctr" + return back; +} + + + +/* ##### untested */ +int +dk4uc2l_string_utf8_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + const char *str, + dk4_app_t *app +) +{ + dk4_utf8_decoder_t dec; + dk4_er_t er; + dk4_c32_t c32; + int back = 0; + int mm = 0; + int err = 0; + + +#line 2266 "dk4uc2la.ctr" +#if DK4_USE_ASSERT + assert(NULL != wstrm); + assert(NULL != ulptr); + assert(NULL != str); +#endif + /* Check arguments + */ + if ((NULL == wstrm) || (NULL == ulptr) || (NULL == str)) { + goto finished; + } + + /* Process string + */ + back = 1; + dk4utf8_init(&dec); + while(('\0' != *str) && (0 == err)) { + switch (dk4utf8_add(&dec, (unsigned char)(*(str++)))) { + case DK4_EDSTM_FINISHED : { + c32 = dk4utf8_get(&dec); + dk4utf8_init(&dec); + dk4uc2l_putc32_app(wstrm, ulptr, c32, &mm, &back, app); + } break; + case DK4_EDSTM_ERROR : { + err = 1; + back = 0; + /* ##### ERROR: Decoding failed */ + } break; + } + } + if (0 == err) { + if (0 == dk4utf8_is_empty(&dec)) { + back = 0; + /* ##### ERROR: Decoding failed */ + } + } + + /* Finalize math mode if necessary + */ + if (0 != mm) { + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, dk4uc2l_mm[1], &er)) { + back = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + } + finished: + + +#line 2314 "dk4uc2la.ctr" + return back; +} + + + +/* ##### untested */ +int +dk4uc2l_string_ansi_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + const char *str, + dk4_app_t *app +) +{ + dk4_er_t er; + dk4_c32_t c32; + int back = 0; + int mm = 0; + + +#line 2333 "dk4uc2la.ctr" +#if DK4_USE_ASSERT + assert(NULL != wstrm); + assert(NULL != ulptr); + assert(NULL != str); +#endif + /* Check arguments + */ + if ((NULL == wstrm) || (NULL == ulptr) || (NULL == str)) { + goto finished; + } + + /* Process string + */ + back = 1; + while ('\0' != *str) { + if (0 != dk4ansi_decode(&c32, (unsigned char)(*(str++)))) { + dk4uc2l_putc32_app(wstrm, ulptr, c32, &mm, &back, app); + } + else { + back = 0; + /* ##### ERROR: Decoding failed */ + } + } + + /* Finalize math mode if necessary + */ + if (0 != mm) { + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, dk4uc2l_mm[1], &er)) { + back = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + } + finished: + + +#line 2369 "dk4uc2la.ctr" + return back; +} + + + +/* ##### untested */ +int +dk4uc2l_string_ascii_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + const char *str, + dk4_app_t *app +) +{ + dk4_er_t er; + dk4_c32_t c32; + int back = 0; + int mm = 0; + + +#line 2388 "dk4uc2la.ctr" +#if DK4_USE_ASSERT + assert(NULL != wstrm); + assert(NULL != ulptr); + assert(NULL != str); +#endif + /* Check arguments + */ + if ((NULL == wstrm) || (NULL == ulptr) || (NULL == str)) { + goto finished; + } + + /* Process string + */ + back = 1; + while ('\0' != *str) { + c32 = (dk4_c32_t)((unsigned char)(*(str++))); + dk4uc2l_putc32_app(wstrm, ulptr, c32, &mm, &back, app); + } + + /* Finalize math mode if necessary + */ + if (0 != mm) { + dk4error_init(&er); + if (0 == dk4stream_write_char_string(wstrm, dk4uc2l_mm[1], &er)) { + back = 0; + /* ERROR: Write failed */ + dk4app_log_base1(app, DK4_LL_ERROR, 128); + } + } + finished: + + +#line 2419 "dk4uc2la.ctr" + return back; +} + + + +int +dk4uc2l_string_c8_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + const char *str, + int ie, + dk4_app_t *app +) +{ +#if DK4_USE_ASSERT + assert(NULL != wstrm); + assert(NULL != ulptr); + assert(NULL != str); +#endif + switch (ie) { + case DK4_ENCODING_UTF8 : { + return (dk4uc2l_string_utf8_app(wstrm, ulptr, str, app)); + } break; + case DK4_ENCODING_WIN1252 : { + return (dk4uc2l_string_ansi_app(wstrm, ulptr, str, app)); + } break; + default : { + return (dk4uc2l_string_ascii_app(wstrm, ulptr, str, app)); + } break; + } +} + + + +/* ##### untested */ +int +dk4uc2l_string_dk_app( + dk4_stream_t *wstrm, + dk4_uc2l_t *ulptr, + const dkChar *str, +#if DK4_CHAR_SIZE > 1 + int DK4_ARG_UNUSED(ie), +#else + int ie, +#endif + dk4_app_t *app +) +{ +#if DK4_CHAR_SIZE > 1 + DK4_UNUSED_ARG(ie) +#endif +#if DK4_USE_ASSERT + assert(NULL != wstrm); + assert(NULL != ulptr); + assert(NULL != str); +#endif +#if DK4_CHAR_SIZE > 1 +#if DK4_CHAR_SIZE > 2 + return (dk4uc2l_string_c32_app(wstrm, ulptr, str, app)); +#else + return (dk4uc2l_string_c16_app(wstrm, ulptr, str, app)); +#endif +#else + return (dk4uc2l_string_c8_app(wstrm, ulptr, str, ie, app)); +#endif +} + + + +/* vim: set ai sw=4 ts=4 : */ + |