/* 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: dk4stt.ctr */ /** @file dk4stt.c The dk4stt module. */ #line 113 "dk4stt.ctr" #include "dk4conf.h" #include "dk4error.h" #include "dk4mem.h" #include "dk4strd.h" #include "dk4strm.h" #include "dk4stt.h" #include "dk4tspdk.h" #include "dk4enc.h" #include "dk4unused.h" #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #line 133 "dk4stt.ctr" void dk4stt_close(dk4_string_table_t *ptr) { dkChar **stptr; size_t nstrings; #line 142 "dk4stt.ctr" #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { if (NULL != ptr->strings) { stptr = ptr->strings; nstrings = ptr->nstrings; while (0 < nstrings--) { dk4mem_release(*stptr); stptr++; } dk4mem_release(ptr->strings); } dk4mem_release(ptr->shrtfn); ptr->nstrings = 0; dk4mem_free(ptr); } #line 159 "dk4stt.ctr" } dk4_string_table_t * dk4stt_open(const dkChar *fn, size_t sz, dk4_er_t *erp) { dk4_string_table_t *back = NULL; dkChar **stptr = NULL; int ok = 0; #line 170 "dk4stt.ctr" #if DK4_USE_ASSERT assert(NULL != fn); assert(0 < sz); #endif if ((NULL != fn) && (0 < sz)) { back = dk4mem_new(dk4_string_table_t,1,erp); if (NULL != back) { back->strings = NULL; back->nstrings = 0; back->shrtfn = dk4str_dup(fn, erp); if (NULL != back->shrtfn) { back->nstrings = sz; back->strings = dk4mem_new(DK4_PDKCHAR,sz,erp); if (NULL != back->strings) { stptr = back->strings; while (0 < sz--) { *(stptr++) = NULL; } ok = 1; } } if (1 > ok) { dk4stt_close(back); back = NULL; } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 197 "dk4stt.ctr" return back; } int dk4stt_compare(const void *l, const void *r, int cr) { int back = 0; const dk4_string_table_t *pl; const dk4_string_table_t *pr; if (NULL != l) { if (NULL != r) { pl = (const dk4_string_table_t *)l; switch (cr) { case 1: { if (NULL != pl->shrtfn) { back = dk4str_cmp(pl->shrtfn, (const dkChar *)r); } else { back = -1; } } break; default: { pr = (const dk4_string_table_t *)r; if (NULL != pl->shrtfn) { if (NULL != pr->shrtfn) { back = dk4str_cmp(pl->shrtfn, pr->shrtfn); } else { back = 1; } } else { if (NULL != pr->shrtfn) { back = -1; } } } break; } } else { back = 1; } } else { if (NULL != r) { back = -1; } } return back; } /** Structure to read a string table from stream. */ typedef struct { dk4_string_table_t *dptr; /**< String table to configure. */ size_t curpos; /**< Current line number. */ } dk4_string_table_reader_t; /** Handler function for text lines. @param obj Object to modify while processing the character. @param line Text line to process. @param lineno Current line number. @param erp Error report, may be NULL. @return DK4_TSP_RES_OK if the character was processed successfully, DK4_TSP_RES_ERROR if there was an error but we can continue, DK4_TSP_RES_FATAL if there was a fatal error so we should abort processing. */ static int dk4stt_line_handler( void *obj, dkChar *line, dk4_um_t DK4_ARG_UNUSED(lineno), dk4_er_t * DK4_ARG_UNUSED(erp) ) { dk4_string_table_reader_t *reader; /* Reader structure */ #if TRACE_DEBUG dkChar *olcp; /* Original pointer */ #endif dkChar *linecp; /* Copy of line */ int back = DK4_TSP_RES_ERROR; #line 285 "dk4stt.ctr" DK4_UNUSED_ARG(lineno) DK4_UNUSED_ARG(erp) reader = (dk4_string_table_reader_t *)obj; if (dkT('#') != line[0]) { #line 289 "dk4stt.ctr" if (reader->curpos < reader->dptr->nstrings) { #line 290 "dk4stt.ctr" linecp = dk4str_dup(line, NULL); if (NULL != linecp) { #line 292 "dk4stt.ctr" #if TRACE_DEBUG olcp = linecp; #endif /* Save copy of line to string table */ (reader->dptr->strings)[reader->curpos] = linecp; reader->curpos += 1; back = DK4_TSP_RES_OK; /* Handle backslash escape sequences, remove trailing newline */ while (dkT('\0') != *linecp) { if (dkT('\\') == *linecp) { if (dkT('r') == linecp[1]) { *linecp = dkT('\r'); dk4str_cpy_to_left(&(linecp[1]), &(linecp[2])); } else { if (dkT('n') == linecp[1]) { *linecp = dkT('\n'); dk4str_cpy_to_left(&(linecp[1]), &(linecp[2])); } else { if (dkT('t') == linecp[1]) { *linecp = dkT('\t'); dk4str_cpy_to_left(&(linecp[1]), &(linecp[2])); } else { dk4str_cpy_to_left(linecp, &(linecp[1])); if (dkT('\0') == *linecp) { linecp--; } } } } } else { if (dkT('\n') == *linecp) { *linecp = dkT('\0'); linecp--; } else { if ((dkT('\r') == *linecp) && (dkT('\n') == linecp[1])) { *linecp = dkT('\0'); linecp--; } } } linecp++; } #line 332 "dk4stt.ctr" } else { #line 333 "dk4stt.ctr" /* Not enough memory. */ back = DK4_TSP_RES_FATAL; } } else { #line 337 "dk4stt.ctr" /* More lines than expected, ignore additional lines. */ back = DK4_TSP_RES_OK; } } else { #line 341 "dk4stt.ctr" /* Comment line, no processing required. */ back = DK4_TSP_RES_OK; } #line 344 "dk4stt.ctr" return back; } int dk4stt_apply_stream( dk4_string_table_t *tptr, dk4_stream_t *strm, int pre, dk4_er_t *erp2 ) { dkChar line[1024]; /* Input line buffer */ char buf[4096]; /* Buffer for stream input */ dk4_string_table_reader_t reader; /* Reader structure */ dk4_tspdk_t tspdk; /* Text stream processor */ dk4_er_t e1; /* Error report f decoding */ dk4_er_t e2; /* Error report f processing */ size_t rdb; /* Bytes read */ int cc; /* Flag: Can continue */ int back = 0; #line 367 "dk4stt.ctr" #if DK4_USE_ASSERT assert(NULL != tptr); assert(NULL != strm); #endif if ((NULL != tptr) && (NULL != strm)) { #line 372 "dk4stt.ctr" dk4error_init(&e1); dk4error_init(&e2); reader.dptr = tptr; reader.curpos = 0; back = dk4tspdk_setup_line( &tspdk, (void *)(&reader), dk4stt_line_handler, line, DK4_SIZEOF(line,dkChar), pre, DK4_FILE_ENCODING_UTF8, &e2 ); if (0 < back) { #line 382 "dk4stt.ctr" #if VERSION_BEFORE_20150821 cc = 1; #endif do { cc = 0; rdb = sizeof(buf); if (0 < dk4stream_read(buf, &rdb, strm, NULL)) { if (0 < rdb) { #line 390 "dk4stt.ctr" switch (dk4tspdk_add_bytes(&tspdk, (unsigned char *)buf, rdb)) { case DK4_TSP_RES_OK: { #line 392 "dk4stt.ctr" cc = 1; } break; case DK4_TSP_RES_ERROR: { #line 395 "dk4stt.ctr" cc = 1; } break; default: { #line 398 "dk4stt.ctr" back = 0; } break; } } else { #line 402 "dk4stt.ctr" } } else { #line 404 "dk4stt.ctr" } } while (cc); if (0 < back) { #line 407 "dk4stt.ctr" if (DK4_TSP_RES_FATAL == dk4tspdk_finish(&tspdk)) { back = 0; #line 409 "dk4stt.ctr" } if (0 < back) { #line 411 "dk4stt.ctr" if (reader.curpos < (reader.dptr)->nstrings) { back = 0; #line 413 "dk4stt.ctr" #line 414 "dk4stt.ctr" #line 415 "dk4stt.ctr" } } } } else { #line 419 "dk4stt.ctr" } } else { #line 421 "dk4stt.ctr" dk4error_set_simple_error_code(erp2, DK4_E_INVALID_ARGUMENTS); } #line 423 "dk4stt.ctr" return back; }