summaryrefslogtreecommitdiff
path: root/support/dktools/dk4tsp32.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4tsp32.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk4tsp32.ctr')
-rw-r--r--support/dktools/dk4tsp32.ctr790
1 files changed, 790 insertions, 0 deletions
diff --git a/support/dktools/dk4tsp32.ctr b/support/dktools/dk4tsp32.ctr
new file mode 100644
index 0000000000..3c1211c62c
--- /dev/null
+++ b/support/dktools/dk4tsp32.ctr
@@ -0,0 +1,790 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Text stream processing for 32 bit characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4BOM_H_INCLUDED
+#include "dk4bom.h"
+#endif
+
+#ifndef DK4TSP_H_INCLUDED
+#include "dk4tsp.h"
+#endif
+
+#ifndef DK4UTF8_H_INCLUDED
+#include "dk4utf8.h"
+#endif
+
+#ifndef DK4UTF16_H_INCLUDED
+#include "dk4utf16.h"
+#endif
+
+#ifndef DK4C32_H_INCLUDED
+#include "dk4c32.h"
+#endif
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @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.
+*/
+typedef int dk4_c32_handler_t(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+);
+
+/** 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 fata error so we
+ should abort processing.
+*/
+typedef int dk4_c32_line_handler_t(
+ void *obj,
+ dk4_c32_t *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+);
+
+/** Structure for 32 bit character processing.
+*/
+typedef struct {
+ union {
+ dk4_utf8_decoder_t u08; /**< UTF-8 decoder. */
+ dk4_utf16_byte_decoder_t u16; /**< UTF-16 decoder. */
+ dk4_c32_byte_decoder_t c32; /**< 32 bit char decoder. */
+ } dec; /**< Input decoder. */
+ dk4_bom_detector_t bomd; /**< BOM detector. */
+ dk4_text_stream_position_t pos; /**< Current position. */
+ dk4_er_t er_en; /**< Errors in input decoding. */
+ dk4_er_t er_pr; /**< Errors in processing. */
+ union {
+ dk4_c32_line_handler_t *lh; /**< Handler function for lines. */
+ dk4_c32_handler_t *ch; /**< Handler function for char. */
+ } fct; /**< Handler function. */
+ dk4_c32_t *inbuf; /**< Buffer for input line. */
+ void *obj; /**< Object to modify in processing. */
+ size_t in_sz; /**< Size of input line buffer. */
+ size_t in_us; /**< Used bytes in input line buffer. */
+ int ief; /**< Input encoding found. */
+ int iee; /**< Input encoding expected. */
+ int pst; /**< Processing stage. */
+} dk4_tsp32_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for byte by byte processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp32_setup_char(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer (number of dk4_c32_t).
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp32_setup_line(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_line_handler_t *fct,
+ dk4_c32_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @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 fata error so we
+ should abort processing.
+*/
+int
+dk4tsp32_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @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 fata error so we
+ should abort processing.
+*/
+int
+dk4tsp32_add_bytes(
+ dk4_tsp32_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tsp32_finish(dk4_tsp32_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tsp32_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp32_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4tsp32.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4c32.h"
+
+
+
+$!trace-include
+
+
+
+/** Initialize text stream processing structure.
+ @param tsp Text stream processor.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk4tsp32_init(dk4_tsp32_t *tsp, int eie)
+{
+ DK4_MEMRES(tsp, sizeof(dk4_tsp32_t));
+ dk4bom_detect_init(&(tsp->bomd), eie);
+ dk4error_init(&(tsp->er_en));
+ dk4error_init(&(tsp->er_pr));
+ tsp->inbuf = NULL;
+ tsp->obj = NULL;
+ tsp->in_sz = 0;
+ tsp->in_us = 0;
+ tsp->ief = eie;
+ tsp->iee = eie;
+ tsp->pst = 0;
+ (tsp->pos).bytes = (dk4_um_t)0UL;
+ (tsp->pos).chars = (dk4_um_t)1UL;
+ (tsp->pos).lineno = (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+}
+
+
+
+/** Process a 32 bit character.
+ @param tsp Text stream processor.
+ @param chr Character to process.
+ @return DK4_TSP_RES_OK if the characters were 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
+dk4tsp32_process_character(
+ dk4_tsp32_t *tsp,
+ dk4_c32_t chr
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk4tsp32_process_character"
+ /* Increase position */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Check for line buffering or direct processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ $? ". line buffering %lu %lu", (unsigned long)(tsp->in_us), (unsigned long)(tsp->in_sz)
+ if (tsp->in_us < tsp->in_sz) { $? ". used size < buffer size"
+ (tsp->inbuf)[tsp->in_us] = chr;
+ tsp->in_us += 1;
+ back = DK4_TSP_RES_OK;
+ if ((dk4_c32_t)'\n' == chr) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c32_t)0UL;
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ /* 2015-07-18
+ Bugfix: We must reset the number of used characters to 0
+ after processing and flushing the line buffer.
+ */
+ tsp->in_us = 0;
+ }
+ } else { $? "! line buffer full"
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ $? ". direct char processing"
+ if (NULL != (tsp->fct).ch) {
+ back = (*((tsp->fct).ch))(tsp->obj, chr, &(tsp->pos), &(tsp->er_pr));
+ }
+ }
+ if ((dk4_c32_t)('\n') == chr) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+ $? "- dk4tsp32_process_character %d", back
+ return back;
+}
+
+
+
+/** Normal processing for one byte.
+ Retrieve a 32 bit character first, either by decoding directly
+ or by adding to a decoder.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp32_process_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ dk4_c32_t c32 = (dk4_c32_t)0UL; /* 32 bit character */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int cuc32 = 0; /* Flag: Have 32 bit char */
+ int res = 0; /* Operation result */
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_ASCII: {
+ c32 = (dk4_c32_t)inbyte;
+ cuc32 = 1;
+ } break;
+ case DK4_FILE_ENCODING_ANSI: {
+ if (0 != dk4ansi_decode(&c32, inbyte)) {
+ cuc32 = 1;
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: {
+ res = dk4utf8_add(&((tsp->dec).u08), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&((tsp->dec).u08));
+ cuc32 = 1;
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ }
+ if (0 != cuc32) {
+ back = dk4tsp32_process_character(tsp, c32);
+ }
+ if (DK4_TSP_RES_FATAL == back) {
+ tsp->pst = 2;
+ }
+ return back;
+}
+
+
+
+/** Initialize decoder for found input encoding.
+ @param tsp Text stream processor.
+*/
+static
+void
+dk4tsp32_initialize_decoder(dk4_tsp32_t *tsp)
+{
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_UTF8: {
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ }
+}
+
+
+
+#if TRACE_DEBUG
+static unsigned long byte_number = 0UL;
+#endif
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @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 fata error so we
+ should abort processing.
+*/
+static
+int
+dk4tsp32_i_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ size_t nrej; /* Number of unused bytes */
+ size_t i; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+ $? "+ dk4tsp32_i_add_one_byte index=%lu '%!8c' 0x%02x", byte_number++, inbyte, (unsigned)inbyte
+ (tsp->pos).bytes += (dk4_um_t)1UL;
+ switch (tsp->pst) {
+ case 0: {
+ res = dk4bom_detect_add(&(tsp->bomd), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ case DK4_EDSTM_FINISHED: case DK4_EDSTM_FINISHED_WITH_UNUSED: {
+ back = DK4_TSP_RES_OK;
+ tsp->ief = dk4bom_detect_get_encoding(&(tsp->bomd));
+ dk4tsp32_initialize_decoder(tsp);
+ tsp->pst = 1;
+ if (DK4_EDSTM_FINISHED_WITH_UNUSED == res) {
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ for (i = 0; ((i < nrej) && (DK4_TSP_RES_FATAL != back)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp32_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ } break;
+ case 1: {
+ back = dk4tsp32_process_byte(tsp, inbyte);
+ } break;
+ /*
+ Processing stage 2 indicates there was a serious error
+ before, we must skip further processing.
+ This situation is covered by the initialization value
+ DK4_TSP_RES_FATAL, so we do not need a case branch here.
+ */
+ }
+ $? "- dk4tsp32_i_add_one_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp32_setup_char(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp32_init(tsp, eie);
+ if (NULL != fct) {
+ tsp->obj = obj;
+ (tsp->fct).ch = fct;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp32_setup_line(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_line_handler_t *fct,
+ dk4_c32_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp32_init(tsp, eie);
+ if ((NULL != fct) && (NULL != inbuf) && (0 < szin)) {
+ tsp->obj = obj;
+ (tsp->fct).lh = fct;
+ tsp->inbuf = inbuf;
+ tsp->in_sz = szin;
+ tsp->in_us = 0;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp32_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk4tsp32_add_one_byte"
+ if (NULL != tsp) {
+ if (2 > tsp->pst) {
+ back = dk4tsp32_i_add_one_byte(tsp, inbyte);
+ }
+ }
+ $? "- dk4tsp32_add_one_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp32_add_bytes(
+ dk4_tsp32_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Processing result */
+ $? "+ dk4tsp32_add_bytes"
+ if ((NULL != tsp) && (NULL != buffer) && (0 < sz)) {
+ if (2 > tsp->pst) {
+ back = DK4_TSP_RES_OK;
+ while ((sz--) && (2 > tsp->pst)) {
+ res = dk4tsp32_i_add_one_byte(tsp, *(buffer++));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ $? "- dk4tsp32_add_bytes %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp32_finish(dk4_tsp32_t *tsp)
+{
+ size_t nrej = 0; /* Number of unused bytes */
+ size_t i = 0; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+ $? "+ dk4tsp32_finish"
+ if (NULL != tsp) {
+ /* Flush all unprocessed output
+ 1. If there are unprocessed bytes in the BOM detector as BOM
+ detection was not completed, process these bytes.
+ 2. If there are characters in the line buffer,
+ finalize the line buffer text and process it.
+ */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve an process bytes stored in BOM detector */
+ if (0 == tsp->pst) {
+ tsp->pst = 1;
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ dk4tsp32_initialize_decoder(tsp);
+ for (i = 0; ((i < nrej) && (2 > tsp->pst)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp32_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ }
+ }
+ /* Process final line */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ if (0 < tsp->in_us) {
+ if (2 > tsp->pst) {
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c32_t)0UL;
+ res =
+ (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ } else {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ }
+ }
+ }
+ $? "- dk4tsp32_finish %d", back
+ return back;
+}
+
+
+
+void
+dk4tsp32_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp32_t *tsp)
+{
+ if (NULL != tsp) {
+ if (NULL != er_en) {
+ DK4_MEMCPY(er_en, &(tsp->er_en), sizeof(dk4_er_t));
+ }
+ if (NULL != er_pr) {
+ DK4_MEMCPY(er_pr, &(tsp->er_pr), sizeof(dk4_er_t));
+ }
+ }
+}
+
+
+