/* 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 #if DK4_HAVE_STRING_H #ifndef STRING_H_INCLUDED #include #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 #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 : */