%% options copyright owner = Dirk Krause copyright year = 2011-2014 license = bsd %% module #if DK3_USE_WX #include "dkwxtrace.h" #else #include "dkct.h" #endif $!trace-include $!trace-off /** Dkct user function. */ typedef int dkct_tr_fct(DKCT_SRC *psrc, char *args); /** Table entry to connect a function to a name. */ typedef struct { char const *name; /**< Function name. */ dkct_tr_fct *fct; /**< Function to execute. */ } dkct_tr_fct_table_entry; /** Indicate that current character is trace control character. */ #define TRACE_CONTROL 512 /** Operation: Do nothing. */ #define DKCT_O_NOOP 0 /** Operation: Print current character. */ #define DKCT_O_PRINT 1 /** Operation: Print dollar and current character. */ #define DKCT_O_DOLLAR_AND_CHAR 2 /** Operation: Print slash and current character. */ #define DKCT_O_SLASH_AND_CHAR 3 /** Operation: Reset buffer. */ #define DKCT_O_RESET_BUFFER 4 /** Operation: Add current character to buffer. */ #define DKCT_O_ADD_BUFFER 5 /** Operation: Write buffer as trace output. */ #define DKCT_O_TRACE_OUTPUT 6 /** Operation: Execute command in buffer. */ #define DKCT_O_EXEC_CMD 7 /** Operation: Start C++ style comment. */ #define DKCT_O_START_CPP_COMMENT 8 /** Operation: End C++ style comment. */ #define DKCT_O_END_CPP_COMMENT 9 /** Operation: Open file to save data for a box comment. */ #define DKCT_O_START_BOX 10 /** Operation: Add normal character for box comment. */ #define DKCT_O_ADD_BOX 11 /** Operation: Add newline to box comment file. */ #define DKCT_O_ADD_BOX_NL 12 /** Operation: Add dollar and current character to box comment file. */ #define DKCT_O_ADD_BOX_DOLLAR_CHAR 13 /** Operation: Print box comment file in box comment. */ #define DKCT_O_END_BOX 14 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH /** Separator character. */ #define DKCT_TR_SEP '\\' #else /** Separator character. */ #define DKCT_TR_SEP '/' #endif /** Section names. */ static char const * const dkct_tr_section_headers[] = { /* 0 */ "options", /* 1 */ "header", /* 2 */ "header start", /* 3 */ "header end", /* 4 */ "class start", /* 5 */ "class end", /* 6 */ "module", /* 7 */ "module start", /* 8 */ "module end", /* 9 */ "constructor start", /* 10 */ "constructor end", /* 11 */ "wx-gui", /* 12 */ "state machine", NULL }; /** Keywords for option processing. */ static char const * const dkct_option_keywords[] = { /* 0 */ "copyright-owner", /* 1 */ "copyright-year", /* 2 */ "license", /* 3 */ "splint-comment-character", NULL }; /** License type names. */ static char const * const dkct_license_names[] = { /* 0 */ "BSD", /* 1 */ "GPL", /* 2 */ "LGPL", /* 5 */ "wxWidgets", /* 4 */ "commercial", NULL }; /** File name suffixes for output files. */ static dkChar const * const dkct_tr_out_suffixes[] = { /* 0 */ dkT(".h"), /* 1 */ dkT(".c"), /* 2 */ dkT(".cpp"), /* 3 */ dkT(".m"), /* 4 */ dkT(".java"), NULL }; /** Warning at start of output files, do not modify! */ static char const * const dkct_tr_mod_warning_start[] = { "/*", " WARNING: This file was generated by dkct.", " Changes you make here will be lost if dkct is run again!", " You should modify the original source and run dkct on it.", NULL }; /** End of modification warning. */ static char const * const dkct_tr_mod_warning_end[] = { "*/", "", NULL }; /** Keywords to use when producing output. */ static char const * const dkct_tr_kw8[] = { /* 0 */ "\n", /* 1 */ " ", /* 2 */ "/*", /* 3 */ "*/", /* 4 */ "Copyright (C) ", /* 5 */ ", ", /* 6 */ "#ifndef ", /* 7 */ "_INCLUDED", /* 8 */ "/** Avoid multiple inclusions. */\n#define ", /* 9 */ " 1", /* 10 */ "#endif", /* 11 */ "/**\t@file ", /* 12 */ " Header file for the ", /* 13 */ " module.", /* 14 */ " The ", /* 15 */ "KrTrace.printMessage(", /* 16 */ " + ", /* 17 */ ":", /* 18 */ "\"", /* 19 */ "trace ", /* 20 */ "#line %lu \"%s\"\n", /* 21 */ "#if TRACE_WIDE\n", /* 22 */ "#else\n", /* 23 */ "#endif\n", /* 24 */ "\n/* TRACE BEGIN */\n", /* 25 */ "/* TRACE END */\n", /* 26 */ "//", /* 27 */ " */", /* 28 */ "stdout", /* 29 */ "dktrace_file()", /* 30 */ "if(dktrace_file()) {\n", /* 31 */ "}\n", /* 32 */ "dktrace_time();\n", /* 33 */ "fputs(", /* 34 */ ");\n", /* 35 */ ", ", /* 36 */ "fprintf(", /* 37 */ "fflush(", /* 38 */ "dkct-tmp-%lu", /* 39 */ "w+", /* 40 */ "/* * ", /* 41 */ " * */\n", /* 42 */ "/* **", /* 43 */ "** */\n", /* 44 */ "#include \n", /* 45 */ "dktrace_init(\"", /* 46 */ "\");\n", /* 47 */ "dktrace_end();\n", /* 48 */ "fputc('\\n', ", /* 49 */ "r", /* 50 */ "w", /* 51 */ "$!end", /* 52 */ "(", /* 53 */ ")", /* 54 */ ",\n\n", /* 55 */ "\"", /* 56 */ "if(dktrace_file()) {\n", /* 57 */ " _setmode(_fileno(dktrace_file()), _O_U16TEXT);\n", /* 58 */ " fputwc(0xFEFF, dktrace_file());\n", /* 59 */ "}\n", /* 60 */ "_setmode(_fileno(stdout), _O_U16TEXT);\n", /* 61 */ "fputws(L", /* 62 */ "fwprintf(", /* 63 */ ", L", /* 64 */ "fputwc(L'\\n', ", /* 65 */ "NULL\n", /* 66 */ "/* %lu */\n", /* 67 */ "/* TRACE BEGIN */\n", /* 68 */ "#include \n", /* 69 */ ",\n", /* 70 */ "dktrace_stdout_time();\n", /* 71 */ "dktrace_wtime();\n", /* 72 */ "dktrace_stdout_wtime();\n", /* 73 */ "\"! ", /* 74 */ "\\n\"", /* 75 */ "contents panel", /* 76 */ "\". ", /* 77 */ "\tOriginal source: ", #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH /* 78 */ "\\", #else /* 78 */ "/", #endif /* 79 */ "#ifndef TRACE_DEBUG\n#define TRACE_DEBUG 1\n#endif\n", /* 80 */ "/*@-nullassign@*/\n", /* 81 */ "/*@=nullassign@*/\n", NULL }; /** Keywords used by the module. */ static dkChar const * const dkct_tr_kw[] = { $!string-table macro=dkT # # 0: Suffix for header files # .h # # 1: Suffix for *.dox files # .dox $!end }; /** Arguments for the string-table command. */ static char const * const dkct_tr_string_table_args[] = { /* 0 */ "file", /* 1 */ "macro", /* 2 */ "prefix", NULL }; /** Text to include in GPL-licensed sources. */ static char const * const dkct_tr_gpl_text[] = { $!text This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . $!end }; /** Text to include in LGPL licensed sources. */ static char const * const dkct_tr_lgpl_text[] = { $!text This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this software. If not, see . $!end }; /** Text to include in BSD licensed sources. */ static char const * const dkct_tr_bsd_text[] = { $!text Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. $!end }; /** Text to include in commercially licensed sources. */ static char const * const dkct_tr_commercial_text[] = { $!text All rights reserved. $!end }; #if DK3_USE_WX #else #endif /** Compare two stored lines by line number. @param l Left DKCT_LINE object. @param r Right DKCT_LINE object. @param cr Comparison criteria (ignored). @return Comparison result. */ static int dkct_tr_line_compare(void const *l, void const *r, int cr) { int back = 0; DKCT_LINE const *pl; /* Left line. */ DKCT_LINE const *pr; /* Right line. */ if(l) { if(r) { pl = (DKCT_LINE const *)l; pr = (DKCT_LINE const *)r; if(pl->l > pr->l) { back = 1; } else { if(pl->l < pr->l) { back = -1; } } } else back = 1; } else { if(r) back = -1; } return back; } void dkct_tr_line_delete(DKCT_LINE *p) { $? "+ dkct_tr_line_delete" if(p) { $? ". text \"%s\"", TR_STR(p->t) dk3_release(p->t); p->l = 0UL; dk3_delete(p); } $? "- dkct_tr_line_delete" } DKCT_LINE * dkct_tr_line_new(char const *t, unsigned long l, dk3_app_t *app) { DKCT_LINE *back = NULL; $? "+ dkct_tr_line_new %lu \"%s\"", l, t if((t) && (l)) { back = dk3_new_app(DKCT_LINE,1,app); if(back) { back->t = NULL; back->l = l; back->t = dk3str_c8_dup_app(t,app); if(!(back->t)) { dkct_tr_line_delete(back); back = NULL; } } } $? "- dkct_tr_line_new %s", TR_PTR(back) return back; } /** Compare two state machine descriptions. @param l Left state machine. @param r Right state machine. @param cr Comparison criteria (ignored). @return Comparison result. */ static int dkct_tr_stm_compare(void const *l, void const *r, int cr) { int back = 0; DKCT_STM const *sl; /* Left state machine. */ DKCT_STM const *sr; /* Right state machine. */ if(l) { if(r) { sl = (DKCT_STM const *)l; sr = (DKCT_STM const *)r; if(sl->lineno > sr->lineno) { back = 1; } else { if(sl->lineno < sr->lineno) { back = -1; } } } else { back = 1; } } else { if(r) { back = -1; } } return back; } /** Clean up a storage and it's iterator containing DKCT_LINE data. @param s Storage. @param i Iterator. */ static void dkct_tr_cleanup_storage_and_iterator(dk3_sto_t *s, dk3_sto_it_t *i) { DKCT_LINE *l; /* Current line to clean up. */ $? "+ dkct_tr_cleanup_storage_and_iterator %s %s", TR_PTR(s), TR_PTR(i) if(s) { if(i) { dk3sto_it_reset(i); while((l = (DKCT_LINE *)dk3sto_it_next(i)) != NULL) { $? ". line found" dkct_tr_line_delete(l); } dk3sto_it_close(i); } dk3sto_close(s); } $? "- dkct_tr_cleanup_storage_and_iterator" } void dkct_tr_delete(DKCT_SRC *p) { DKCT_STM *stmptr; /* Current state machine to clean up. */ $? "+ dkct_tr_delete %s", TR_PTR(p) if(p) { if(p->gui) { dkct_gui_delete((DKCT_GUI *)(p->gui)); } p->gui = NULL; p->app = NULL; dkct_tr_cleanup_storage_and_iterator(p->hss, p->hsi); dkct_tr_cleanup_storage_and_iterator(p->hes, p->hei); dkct_tr_cleanup_storage_and_iterator(p->clss, p->clsi); dkct_tr_cleanup_storage_and_iterator(p->cles, p->clei); dkct_tr_cleanup_storage_and_iterator(p->mss, p->msi); dkct_tr_cleanup_storage_and_iterator(p->mes, p->mei); dkct_tr_cleanup_storage_and_iterator(p->coss, p->cosi); dkct_tr_cleanup_storage_and_iterator(p->coes, p->coei); p->hss = p->hes = p->clss = p->cles = p->mss = p->mes = p->coss = p->coes = NULL; p->hsi = p->hei = p->clsi = p->clei = p->msi = p->mei = p->cosi = p->coei = NULL; if(p->s_stm) { if(p->i_stm) { dk3sto_it_reset(p->i_stm); while((stmptr = (DKCT_STM *)dk3sto_it_next(p->i_stm)) != NULL) { dkct_au_stm_delete(stmptr); } dk3sto_it_close(p->i_stm); } dk3sto_close(p->s_stm); } p->s_stm = NULL; p->i_stm = NULL; p->cstm = NULL; if(p->crn) { $? ". copyright owner \"%s\"", p->crn } if(p->cry) { $? ". copyright year \"%s\"", p->cry } if(p->lict > -1) { $? ". license type %d", p->lict } p->ffn = NULL; dk3_release(p->crn); dk3_release(p->cry); dk3_release(p->sfn); dk3_release(p->cmdb); p->szcmd = 0; p->ucmd = 0; p->fipo = NULL; p->msg = NULL; dk3_delete(p); } $? "- dkct_tr_delete" } DKCT_SRC * dkct_tr_new( DKCT_OPTION_SET *o, char const *fn, int ai, dk3_app_t *app, dkChar const *ffn ) { DKCT_SRC *back = NULL; int ok = 0; /* Flag: Successfully initialized. */ char const *fnptrsfn; /* Pointer to short file name. */ $? "+ dkct_tr_new" if((o) && (fn)) { back = dk3_new_app(DKCT_SRC,1,app); if(back) { dk3mem_cpy(&(back->dkcto), o, sizeof(DKCT_OPTION_SET)); (back->dkcto).deben = 1; back->ffn = ffn; back->app = app; back->msg = NULL; back->type = ai; back->ec = 0; back->hss = back->hes = back->clss = back->cles = back->mss = back->mes = back->coss = back->coes = NULL; back->hsi = back->hei = back->clsi = back->clei = back->msi = back->mei = back->cosi = back->coei = NULL; back->s_stm = NULL; back->i_stm = NULL; back->sfn = NULL; back->crn = NULL; back->cry = NULL; back->cmdb = NULL; back->lict = -1; back->st = 0; back->szcmd = 0; back->ucmd = 0; back->sufi = 0; back->fipo = NULL; back->cbfip = NULL; back->cbfn = NULL; back->cbmx = 0; back->cbcp = 0; back->cursr = NULL; back->cstm = NULL; back->curdi = 0; back->hss = dk3sto_open_app(app); back->hes = dk3sto_open_app(app); back->clss = dk3sto_open_app(app); back->cles = dk3sto_open_app(app); back->mss = dk3sto_open_app(app); back->mes = dk3sto_open_app(app); back->coss = dk3sto_open_app(app); back->coes = dk3sto_open_app(app); back->s_stm = dk3sto_open_app(app); back->gui = NULL; #if DK3_USE_WX back->pComm = NULL; #endif if((back->hss) && (back->hes) && (back->clss) && (back->cles)) { if((back->mss) && (back->mes) && (back->coss) && (back->coes)) { if(back->s_stm) { back->hsi = dk3sto_it_open(back->hss); back->hei = dk3sto_it_open(back->hes); back->clsi = dk3sto_it_open(back->clss); back->clei = dk3sto_it_open(back->cles); back->msi = dk3sto_it_open(back->mss); back->mei = dk3sto_it_open(back->mes); back->cosi = dk3sto_it_open(back->coss); back->coei = dk3sto_it_open(back->coes); back->i_stm = dk3sto_it_open(back->s_stm); if((back->hsi) && (back->hei) && (back->clsi) && (back->clei)) { if((back->msi) && (back->mei) && (back->cosi) && (back->coei)) { if(back->i_stm) { dk3sto_set_comp(back->hss , dkct_tr_line_compare, 0); dk3sto_set_comp(back->hes , dkct_tr_line_compare, 0); dk3sto_set_comp(back->clss, dkct_tr_line_compare, 0); dk3sto_set_comp(back->cles, dkct_tr_line_compare, 0); dk3sto_set_comp(back->mss , dkct_tr_line_compare, 0); dk3sto_set_comp(back->mes , dkct_tr_line_compare, 0); dk3sto_set_comp(back->coss, dkct_tr_line_compare, 0); dk3sto_set_comp(back->coes, dkct_tr_line_compare, 0); dk3sto_set_comp(back->s_stm, dkct_tr_stm_compare, 0); fnptrsfn = dk3str_c8_rchr(fn, DKCT_TR_SEP); if(fnptrsfn) { fnptrsfn++; } else { fnptrsfn = fn; } back->sfn = dk3str_c8_dup_app(fnptrsfn, app); if(back->sfn) { $? ". ok" back->cmdb = dk3_new_app(char,DKCT_LINE_SIZE,app); if(back->cmdb) { back->szcmd = DKCT_LINE_SIZE; ok = 1; } } } } } } } } if(!ok) { dkct_tr_delete(back); back = NULL; } } } $? "- dkct_tr_new %s", TR_PTR(back) return back; } /** Check whether or not an input line is a section header. @param inputline Line to check. @return 1 for section header, 0 otherwise. */ static int dkct_tr_is_section_header(char *inputline) { int back = 0; char *p1; /* Start of text. */ if(inputline) { p1 = dk3str_c8_start(inputline, NULL); if(p1) { if(*p1 == '%') { if(p1[1] == '%') { back = 1; } } } } return back; } /** Find section number for input line. @param psrc Source structure. @param inputline Input line to process. @param sufi File suffix index of input file. @return The section number (index in dkct_tr_section_headers). */ static int dkct_tr_find_section_number(DKCT_SRC *psrc, char *inputline, int sufi) { int back = -1; int ai; /* Array index of section name. */ char *p1; /* Section name. */ p1 = dk3str_c8_start(inputline, NULL); if(p1) { if(*p1 == '%') { if(p1[1] == '%') { p1++; p1++; p1 = dk3str_c8_start(p1, NULL); if(p1) { dk3str_c8_normalize(p1, NULL, ' '); ai = dk3str_c8_array_index(dkct_tr_section_headers, p1, 0); switch(sufi) { case 4: { switch(ai) { case 0: { back = DKCT_SECTION_OPTIONS; } break; case 1: case 2: { back = DKCT_SECTION_HEADER_START; } break; case 3: { back = DKCT_SECTION_HEADER_END; } break; case 4: { back = DKCT_SECTION_CLASS_START; } break; case 5: { back = DKCT_SECTION_CLASS_END; } break; case 6: case 7: { back = DKCT_SECTION_MODULE_START; } break; case 8: { back = DKCT_SECTION_MODULE_END; } break; case 9: { back = DKCT_SECTION_CONSTRUCTOR_START; } break; case 10: { back = DKCT_SECTION_CONSTRUCTOR_END; } break; case 11: { back = DKCT_SECTION_GUI; } break; case 12: { back = DKCT_SECTION_STATE_MACHINE; } break; } } break; case 3: { switch(ai) { case 0: { back = DKCT_SECTION_OPTIONS; } break; case 6: { back = DKCT_SECTION_MODULE_START; } break; } } break; default: { switch(ai) { case 0: { back = DKCT_SECTION_OPTIONS; } break; case 1: { back = DKCT_SECTION_HEADER_START; } break; case 6: { back = DKCT_SECTION_MODULE_START; } break; case 12: { back = DKCT_SECTION_STATE_MACHINE; } break; } } break; } if(back == -1) { dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 43, 44, p1); } } } } } return back; } /** Process an option (key/value pair). @param psrc Source structure. @param key Key (option name). @param val Value. @param sufi Source file type. @return 1 on success, 0 on error. */ static int dkct_tr_process_option(DKCT_SRC *psrc, char *key, char *val, int sufi) { int back = 0; $? "+ dkct_tr_process_option \"%s\"=\"%s\"", key, val switch(dk3str_c8_array_index(dkct_option_keywords, key, 0)) { case 0: { $? ". copyright owner" if(psrc->crn) { /* Warning: Redefinition of copyright owner */ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 4); dk3_release(psrc->crn); } psrc->crn = dk3str_c8_dup_app(val, psrc->app); if(psrc->crn) { back = 1; } else { psrc->ec = DK3_ERROR_MEMORY; /* ERROR: Memory */ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); } } break; case 1: { $? ". copyright year" if(psrc->cry) { /* Warning: Redefinition of copyright year(s)! */ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 5); dk3_release(psrc->cry); } psrc->cry = dk3str_c8_dup_app(val, psrc->app); if(psrc->cry) { back = 1; } else { psrc->ec = DK3_ERROR_MEMORY; /* ERROR: Memory */ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); } } break; case 2: { $? ". license type" if(psrc->lict >= 0) { /* Warning: Redefinition of license! */ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 6); } psrc->lict = dk3str_c8_array_index(dkct_license_names, val, 0); if(psrc->lict >= 0) { back = 1; } else { /* ERROR: Unknown license! */ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 7, 8, val); psrc->ec = DK3_ERROR_SYNTAX; } } break; case 3: { $? ". splint comment character" if (val) { (psrc->dkcto).spls = *val; } else { (psrc->dkcto).spls = '@'; } back = 1; } break; default: { dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 10, 11, key); back = 0; } break; } $? "- dkct_tr_process_option %d", back return back; } int dkct_tr_read(DKCT_SRC *psrc, dkChar const *fn, int sufi) { int back = 0; dk3_sto_t *stp = NULL; /* Current storage to save lines. */ FILE *fipo = NULL; /* Input file. */ DKCT_LINE *pline = NULL; /* Input line to store. */ unsigned long lineno = 0UL; /* Input line number. */ int cc = 1; /* Flag: Can continue processing. */ int section = DKCT_SECTION_MODULE_START; /* Current section. */ char inputline[DKCT_LINE_SIZE]; /* Input line buffer. */ char *p1; /* Option name. */ char *p2; /* Option value. */ $? "+ dkct_tr_read" if((psrc) && (fn)) { $? ". args ok" fipo = dk3sf_fopen_app(fn, dk3app_not_localized(22), psrc->app); if(fipo) { $? ". fipo ok" back = 1; switch(sufi) { case 4: { section = DKCT_SECTION_GUI; } break; default: { stp = psrc->mss; } break; } do { cc = 0; if(fgets(inputline, sizeof(inputline), fipo)) { cc = 1; lineno++; psrc->lineno = lineno; dk3app_set_source_line(psrc->app, lineno); dk3str_c8_delnl(inputline); $? ". process line \"%s\"", inputline if(dkct_tr_is_section_header(inputline)) { /* Start of new section. */ stp = NULL; psrc->cstm = NULL; section = dkct_tr_find_section_number(psrc, inputline, sufi); if(section == -1) { psrc->ec = DK3_ERROR_SYNTAX; $? "! wrong section" cc = 0; } else { switch(section) { case DKCT_SECTION_MODULE_START: stp = psrc->mss; break; case DKCT_SECTION_MODULE_END: stp = psrc->mes; break; case DKCT_SECTION_CONSTRUCTOR_START: stp = psrc->coss; break; case DKCT_SECTION_CONSTRUCTOR_END: stp = psrc->coes; break; case DKCT_SECTION_HEADER_START: stp = psrc->hss; break; case DKCT_SECTION_HEADER_END: stp = psrc->hes; break; case DKCT_SECTION_CLASS_START: stp = psrc->clss; break; case DKCT_SECTION_CLASS_END: stp = psrc->cles; break; case DKCT_SECTION_STATE_MACHINE: { psrc->cstm = dkct_au_stm_new(lineno, psrc->app); if(psrc->cstm) { $? ". stm ok" if(!dk3sto_add(psrc->s_stm, (void *)(psrc->cstm))) { $? "! failed to add" dkct_au_stm_delete(psrc->cstm); psrc->cstm = NULL; } } else { /* ERROR: Memory! */ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); } } break; case DKCT_SECTION_GUI: { if(!(psrc->gui)) { psrc->gui = (void *)dkct_gui_new(psrc); } if(!(psrc->gui)) { back = 0; psrc->ec = DK3_ERROR_MEMORY; /* ERROR: Memory! */ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); } } break; } } } else { /* Apply line to current section. */ switch(section) { case DKCT_SECTION_OPTIONS: { p1 = dk3str_c8_start(inputline, NULL); if(p1) { if(*p1 != '#') { p2 = dk3str_c8_chr(p1, '='); if(p2) { *(p2++) = '\0'; p2 = dk3str_c8_start(p2, NULL); if(p2) { dk3str_c8_normalize(p1, NULL, '-'); dk3str_c8_chomp(p2, NULL); if(!dkct_tr_process_option(psrc, p1, p2, sufi)) { cc = 0; psrc->ec = DK3_ERROR_SYNTAX; } } else { /* ERROR: Syntax */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9); psrc->ec = DK3_ERROR_SYNTAX; cc = 0; } } else { /* ERROR: Syntax */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9); psrc->ec = DK3_ERROR_SYNTAX; cc = 0; } } } } break; case DKCT_SECTION_GUI: { if(psrc->gui) { if(back) { if(!dkct_gui_add_line((DKCT_GUI *)(psrc->gui), inputline)) { back = 0; $? "! error in GUI section line" if(psrc->ec == 0) { psrc->ec = DK3_ERROR_MEMORY; } } } } else { back = 0; psrc->ec = DK3_ERROR_MEMORY; } } break; case DKCT_SECTION_STATE_MACHINE: { if(!dkct_au_add_line(psrc->cstm, psrc, inputline, lineno)) { back = 0; $? "! failed to add line to state machine" } } break; default: { if(section > -1) { if(stp) { pline = dkct_tr_line_new(inputline, lineno, psrc->app); if(pline) { if(!dk3sto_add(stp, pline)) { dkct_tr_line_delete(pline); pline = NULL; psrc->ec = DK3_ERROR_MEMORY; cc = 0; } } else { psrc->ec = DK3_ERROR_MEMORY; cc = 0; /* ERROR: Memory! */ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); } } else { psrc->ec = DK3_ERROR_MEMORY; cc = 0; } } else { psrc->ec = DK3_ERROR_SYNTAX; cc = 0; } } break; } } } #if DK3_USE_WX #endif } while((cc) && (!(psrc->ec))); /* On error we can not return success. */ if(psrc->ec) { $? "! ec indicates error" back = 0; } fclose(fipo); } else { /* ERROR: Failed to open file! */ dkct_to_log_dk_3(psrc, 0, DK3_LL_ERROR, 20, 21, fn); } } $? "- dkct_tr_read %d", back return back; } int dkct_tr_check(DKCT_SRC *psrc, dkChar const *fn, int sufi) { int back = 0; DKCT_STM *pstm; /* Current state machine to check. */ unsigned long stmno; /* Index of current state machine. */ $? "+ dkct_tr_check" switch(sufi) { case 4: { back = dkct_gui_check(psrc); } break; default: { back = 1; } break; } if(back) { $? ". OK so far" /* Check state machines consistency */ dk3sto_it_reset(psrc->i_stm); stmno = 0UL; while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) { pstm->stmno = stmno++; if(!dkct_au_stm_check(psrc, pstm)) { back = 0; $? "! state machine check failed" } } } $? "- dkct_tr_check %d", back return back; } /** Check whether data for a header file is available. @param psrc Source structure. @return 1 if header data is available, 0 otherwise. */ static int dkct_tr_have_header_data(DKCT_SRC *psrc) { int back = 0; DKCT_STM *pstm; /* Current state machine to check for header data. */ $? "+ dkct_tr_have_header_data" if(psrc->hsi) { if(dk3sto_it_next(psrc->hsi)) { back = 1; } } if(psrc->hei) { if(dk3sto_it_next(psrc->hei)) { back = 1; } } if(psrc->clsi) { if(dk3sto_it_next(psrc->clsi)) { back = 1; } } if(psrc->clei) { if(dk3sto_it_next(psrc->clei)) { back = 1; } } if(psrc->i_stm) { dk3sto_it_reset(psrc->i_stm); while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) { if(pstm->wrh) { back = 1; } } } $? "- dkct_tr_have_header_data %d", back return back; } /** Check whether data for a module file is available. @param psrc Source structure. @return 1 if module data is available, 0 otherwise. */ static int dkct_tr_have_module_data(DKCT_SRC *psrc) { int back = 0; $? "+ dkct_tr_have_module_data" if(psrc->msi) { if(dk3sto_it_next(psrc->msi)) { back = 1; } } if(psrc->mei) { if(dk3sto_it_next(psrc->mei)) { back = 1; } } if(psrc->cosi) { if(dk3sto_it_next(psrc->cosi)) { back = 1; } } if(psrc->coei) { if(dk3sto_it_next(psrc->coei)) { back = 1; } } if(psrc->i_stm) { dk3sto_it_reset(psrc->i_stm); while(dk3sto_it_next(psrc->i_stm) != NULL) { back = 1; } } $? "- dkct_tr_have_module_data %d", back return back; } /** Write one text paragraph to output file. @param fipo Output file. @param tptr Pointer to text. */ static void dkct_tr_write_text(FILE *fipo, char const * const *tptr) { char const * const *ptr; /* Write a text to file. */ $? "= dkct_tr_write_text" ptr = tptr; while(*ptr) { fputs(*(ptr++), fipo); fputc('\n', fipo); } } /** Write copyright and license information for a known license name. @param psrc Source structure. @param license_text License text to print to file. */ static void dkct_tr_write_copyright_and_license_internal( DKCT_SRC *psrc, char const * const *license_text ) { $? "+ dkct_tr_write_copyright_and_license_internal" fputs(dkct_tr_kw8[2], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); if(psrc->crn) { $? ". copyright name ok" fputs(dkct_tr_kw8[4], psrc->fipo); if(psrc->cry) { fputs(psrc->cry, psrc->fipo); fputs(dkct_tr_kw8[5], psrc->fipo); } fputs(psrc->crn, psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); } dkct_tr_write_text(psrc->fipo, license_text); fputs(dkct_tr_kw8[3], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); $? "- dkct_tr_write_copyright_and_license_internal" } /** Check whether we need to add a short description line to the doxygen file tag. If the output file is *.h and there is a *.dox file we can leave the doxygen file tag in the header file empty as the *.dox file contains the detailed description. @param psrc Source structure. @param ofn Output file name. @return 1 to add description, 0 for empty tag. */ static int dkct_tr_need_file_description(DKCT_SRC *psrc, dkChar const *ofn) { dkChar fnb[DK3_MAX_PATH]; dk3_stat_t st; dkChar *fns; int back = 1; if(dk3str_len(ofn) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb,ofn); fns = dk3str_get_suffix(fnb); if(fns) { #if DK3_HAVE_FNCASEINS if(dk3str_casecmp(dkct_tr_kw[0], fns) == 0) #else if(dk3str_cmp(dkct_tr_kw[0], fns) == 0) #endif { *fns = dkT('\0'); if( (dk3str_len(fnb) + dk3str_len(dkct_tr_kw[1])) < DK3_SIZEOF(fnb,dkChar) ) { dk3str_cat(fnb, dkct_tr_kw[1]); if(dk3sf_stat_app(&st, fnb, NULL)) { switch((st.ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { back = 0; } break; } } } } } } return back; } /** Write start of output file. @param psrc Source structure. @param ofn Output file name. @param sfn Source file name. @param f_hdr Flag: Output is a header file. */ static void dkct_tr_write_file_start( DKCT_SRC *psrc, dkChar const *ofn, dkChar const *sfn, int f_hdr ) { char const * const *license_text_ptr = NULL; /* Text pointer. */ char myfn[DK3_MAX_PATH]; /* Short file name. */ char *ptr; /* Text pointer. */ char *myshortfn; $? "+ dkct_tr_write_file_start \"%s\"", ofn dkct_tr_write_text(psrc->fipo, dkct_tr_mod_warning_start); if(psrc->sfn) { fputs(dkct_tr_kw8[77], psrc->fipo); fputs(psrc->sfn, psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); } dkct_tr_write_text(psrc->fipo, dkct_tr_mod_warning_end); if((psrc->crn) || (psrc->cry) || (psrc->lict > -1)) { switch(psrc->lict) { case 0: { license_text_ptr = dkct_tr_bsd_text; } break; case 1: { license_text_ptr = dkct_tr_gpl_text; } break; case 2: { license_text_ptr = dkct_tr_lgpl_text; } break; case 3: { } break; case 4: { license_text_ptr = dkct_tr_commercial_text; } break; } if(license_text_ptr) { $? ". license terms internally known" dkct_tr_write_copyright_and_license_internal(psrc,license_text_ptr); } else { $? "! License not found" /* ##### OTHER LICENSE */ } } if(dk3str_string_to_c8_simple_app(myfn, sizeof(myfn), ofn, psrc->app)) { fputs(dkct_tr_kw8[11], psrc->fipo); if(dkct_tr_need_file_description(psrc, ofn)) { myshortfn = dk3str_c8_rchr(myfn, DKCT_TR_SEP); if(myshortfn) { myshortfn++; } else { myshortfn = myfn; } fputs(myshortfn, psrc->fipo); fputs(dkct_tr_kw8[(f_hdr) ? 12 : 14], psrc->fipo); ptr = dk3str_c8_get_suffix(myfn); if(ptr) { *ptr = '\0'; } myshortfn = dk3str_c8_rchr(myfn, DKCT_TR_SEP); if(myshortfn) { myshortfn++; } else { myshortfn = myfn; } fputs(myshortfn, psrc->fipo); fputs(dkct_tr_kw8[13], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); } fputs(dkct_tr_kw8[3], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); } else { /* ERROR: Not a simple file name! */ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 12, 13, ofn); } $? "- dkct_tr_write_file_start" } /** Print file name char in upper cases. Characters are printed upper-case, numbers ``as is'', all other characters are replaced by underscore. @param psrc Source structure. @param c Character to print. */ static void dkct_tr_char_filename_to_upper(DKCT_SRC *psrc, char c) { char oc; /* Output character. */ oc = '_'; if((c >= 'A') && (c <= 'Z')) { oc = c; } else { if((c >= 'a') && (c <= 'z')) { oc = (char)toupper(c); } else { if((c >= '0') && (c <= '9')) { oc = c; } } } fputc(oc, psrc->fipo); } /** Print file name upper-case to avoid multiple inclusions. @param psrc Source structure. @param ofn Output file name. */ static void dkct_tr_filename_to_upper(DKCT_SRC *psrc, dkChar const *ofn) { char b[DK3_MAX_PATH]; /* Temporary file name buffer. */ char *ptr; /* Current character to process. */ dkChar const *shortofn; shortofn = dk3str_rchr(ofn, DK3_CHAR_SEP); if(shortofn) { shortofn++; } else { shortofn = ofn; } if(dk3str_string_to_c8_simple_app(b, sizeof(b), shortofn, psrc->app)) { ptr = b; while(*ptr) { dkct_tr_char_filename_to_upper(psrc, *ptr); ptr++; } } else { /* ERROR: Illegal file name! */ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 12, 13, ofn); } } void dkct_tr_show_source_line(DKCT_SRC *psrc, size_t newlines) { size_t i; if(psrc->sufi != 3) { if(newlines > 0) { for(i = 0; i < newlines; i++) { fputc('\n', psrc->fipo); } } fprintf(psrc->fipo, dkct_tr_kw8[20], psrc->lineno, psrc->sfn); } } #if 0 /** Process header lines from storage iterator. @param psrc Source structure, @param iterator Iterator for source line storage. */ static void dkct_tr_header_lines(DKCT_SRC *psrc, dk3_sto_it_t *iterator) { DKCT_LINE *lp; /* Current line to process. */ if(iterator) { dk3sto_it_reset(iterator); while((lp = (DKCT_LINE *)dk3sto_it_next(iterator)) != NULL) { $? ". just another line" if(lp->t) { $? ". line contains text" psrc->lineno = lp->l; if(psrc->shln) { psrc->shln = 0; dkct_tr_show_source_line(psrc, 1); } fputs(lp->t, psrc->fipo); fputc('\n', psrc->fipo); } else { $? "! no text in line" } } } } #endif /** Find action to process current input character. @param st Pointer to state variable. @param input Current input character. @return Action identifier. */ static int dkct_tr_state_machine_transition(int *st, int input) { int back = 0; int ns = 0; /* New state. */ $? "+ dkct_tr_state_machine_transition %d %d %c", *st, input, (char)input switch(*st) { case 0: { /* Initial state. */ switch(input) { case '\\': { ns = 1; back = DKCT_O_PRINT; } break; case '"': { ns = 2; back = DKCT_O_PRINT; } break; case '\'': { ns = 4; back = DKCT_O_PRINT; } break; case '/': { ns = 6; back = DKCT_O_NOOP; } break; case TRACE_CONTROL: { ns = 10; back = DKCT_O_RESET_BUFFER; } break; default: { ns = 0; back = DKCT_O_PRINT; } break; } } break; case 1: { /* After backslash. */ ns = 0; back = DKCT_O_PRINT; } break; case 2: { /* In a string. */ back = DKCT_O_PRINT; switch(input) { case '"': { ns = 0; } break; case '\\': { ns = 3; } break; default: { ns = 2; } break; } } break; case 3: { /* After backslash in string. */ ns = 2; back = DKCT_O_PRINT; } break; case 4: { /* Single character literal. */ back = DKCT_O_PRINT; switch(input) { case '\'': { ns = 0; } break; case '\\': { ns = 5; } break; default: { ns = 4; } break; } } break; case 5: { /* After backslash in character literal. */ ns = 4; back = DKCT_O_PRINT; } break; case 6: { /* After slash. */ switch(input) { case '/': { ns = 7; back = DKCT_O_START_CPP_COMMENT; } break; case '*': { ns = 8; back = DKCT_O_SLASH_AND_CHAR; } break; default: { ns = 0; back = DKCT_O_SLASH_AND_CHAR; } break; } } break; case 7: { /* In C++ style comment. */ switch(input) { case '\n': { ns = 0; back = DKCT_O_END_CPP_COMMENT; } break; default: { ns = 7; back = DKCT_O_PRINT; } break; } } break; case 8: { /* In normal comment. */ back = DKCT_O_PRINT; switch(input) { case '*': { ns = 9; } break; default: { ns = 8; } break; } } break; case 9: { /* After * in normal comment. */ back = DKCT_O_PRINT; switch(input) { case '*': { ns = 9; } break; case '/': { ns = 0; } break; default: { ns = 8; } break; } } break; case 10: { /* After TRACE_CONTROL. */ switch(input) { case '(': { ns = 15; back = DKCT_O_RESET_BUFFER; } break; case '!': { ns = 12; back = DKCT_O_RESET_BUFFER; } break; case '?': { ns = 11; back = DKCT_O_RESET_BUFFER; } break; case '*': { ns = 17; back = DKCT_O_START_BOX; } break; default: { ns = 0; back = DKCT_O_DOLLAR_AND_CHAR; } break; } } break; case 11: { /* After TRACE_CONTROL, ?. */ switch(input) { case '\n': { ns = 0; back = DKCT_O_TRACE_OUTPUT; } break; case ' ': case '\t': { ns = 11; back = DKCT_O_NOOP; } break; default: { ns = 13; back = DKCT_O_ADD_BUFFER; } break; } } break; case 12: { /* After TRACE_CONTROL, !. */ switch(input) { case '\n': { ns = 0; back = DKCT_O_EXEC_CMD; } break; case ' ': case '\t': { ns = 12; back = DKCT_O_NOOP; } break; default: { ns = 14; back = DKCT_O_ADD_BUFFER; } break; } } break; case 13: { /* In debug output. */ switch(input) { case '\n': { ns = 0; back = DKCT_O_TRACE_OUTPUT; } break; default: { ns = 13; back = DKCT_O_ADD_BUFFER; } break; } } break; case 14: { /* In interprete context. */ switch(input) { case '\n': { ns = 0; back = DKCT_O_EXEC_CMD; } break; default: { ns = 14; back = DKCT_O_ADD_BUFFER; } break; } } break; case 15: { /* In brackets in interprete context. */ switch(input) { case '\n': { ns = 0; back = DKCT_O_PRINT; } break; case ')': { ns = 1; back = DKCT_O_NOOP; } break; case ' ': case '\t': { ns = 15; back = DKCT_O_NOOP; } break; default: { ns = 16; back = DKCT_O_ADD_BUFFER; } break; } } break; case 16: { switch(input) { case ')': { ns = 0; back = DKCT_O_EXEC_CMD; } break; default: { ns = 16; back = DKCT_O_ADD_BUFFER; } break; } } break; case 17: { /* In comment box. */ switch(input) { case '\n': { ns = 17; back = DKCT_O_ADD_BOX_NL; } break; case TRACE_CONTROL: { ns = 18; back = DKCT_O_NOOP; } break; default: { ns = 17; back = DKCT_O_ADD_BOX; } break; } } break; case 18: { /* In comment box, found TRACE_CONTROL. */ switch(input) { case '*': { ns = 0; back = DKCT_O_END_BOX; } break; default: { ns = 17; back = DKCT_O_ADD_BOX_DOLLAR_CHAR; } break; } } break; } *st = ns; $? "- dkct_tr_state_machine_transition %d (new state %d)", back, ns return back; } void dkct_tr_show_filename_and_lineno(DKCT_SRC *psrc) { $? "+ dkct_tr_show_filename_and_lineno" fputs(dkct_tr_kw8[18], psrc->fipo); fputs(psrc->sfn, psrc->fipo); fputs(dkct_tr_kw8[17], psrc->fipo); fprintf(psrc->fipo, "%lu", psrc->lineno); fputs(dkct_tr_kw8[17], psrc->fipo); fputs(dkct_tr_kw8[1], psrc->fipo); if((psrc->dkcto).tkw) { fputs(dkct_tr_kw8[19], psrc->fipo); } fputs(dkct_tr_kw8[18], psrc->fipo); $? "- dkct_tr_show_filename_and_lineno" } /** Mark buffer as completely empty. @param psrc Source structure. */ static void dkct_tr_reset_buffer(DKCT_SRC *psrc) { dk3mem_res(psrc->cmdb, psrc->szcmd); psrc->ucmd = 0; } /** Write trace information instructions to output. @param psrc Source structure. */ static void dkct_tr_trace_output(DKCT_SRC *psrc) { char const *fnptr = NULL; /* File to use for debug output. */ if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) { switch(psrc->sufi) { case 3: { /* Java */ fputs(dkct_tr_kw8[15], psrc->fipo); dkct_tr_show_filename_and_lineno(psrc); fputs(dkct_tr_kw8[16], psrc->fipo); if(psrc->ucmd > 0) { fputs(psrc->cmdb, psrc->fipo); } else { fputs(dkct_tr_kw8[1], psrc->fipo); } fputs(dkct_tr_kw8[0], psrc->fipo); } break; /* C/C++ */ default: { fnptr = dkct_tr_kw8[((psrc->dkcto).deb == 2) ? 28 : 29]; fputs(dkct_tr_kw8[24], psrc->fipo); /* TRACE BEGIN */ if((psrc->dkcto).win) { /* Mit wide char Code. */ fputs(dkct_tr_kw8[21], psrc->fipo); if((psrc->dkcto).deb != 2) { fputs(dkct_tr_kw8[30], psrc->fipo); /* if(dktrace_file()) */ } if((psrc->dkcto).ts) { if((psrc->dkcto).deb == 2) { fputs(dkct_tr_kw8[72], psrc->fipo); /* dktrace_time(); */ } else { fputs(dkct_tr_kw8[71], psrc->fipo); } } fputs(dkct_tr_kw8[61], psrc->fipo); /* fputs( */ dkct_tr_show_filename_and_lineno(psrc); fputs(dkct_tr_kw8[35], psrc->fipo); /* , */ fputs(fnptr, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */ if(psrc->ucmd > 0) { fputs(dkct_tr_kw8[62], psrc->fipo); /* fprintf( */ fputs(fnptr, psrc->fipo); /* file name or stdout */ fputs(dkct_tr_kw8[63], psrc->fipo); fputs(psrc->cmdb, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */ fputs(dkct_tr_kw8[64], psrc->fipo); fputs(fnptr, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); fputs(dkct_tr_kw8[37], psrc->fipo); fputs(fnptr, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); } if((psrc->dkcto).deb != 2) { fputs(dkct_tr_kw8[31], psrc->fipo); } fputs(dkct_tr_kw8[22], psrc->fipo); } /* Mit oder ohne wide char */ if((psrc->dkcto).deb != 2) { fputs(dkct_tr_kw8[30], psrc->fipo); /* if(dktrace_file()) */ } if((psrc->dkcto).ts) { if((psrc->dkcto).deb == 2) { fputs(dkct_tr_kw8[70], psrc->fipo); /* dktrace_time(); */ } else { fputs(dkct_tr_kw8[32], psrc->fipo); } } fputs(dkct_tr_kw8[33], psrc->fipo); /* fputs( */ dkct_tr_show_filename_and_lineno(psrc); fputs(dkct_tr_kw8[35], psrc->fipo); /* , */ fputs(fnptr, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */ if(psrc->ucmd > 0) { fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */ fputs(fnptr, psrc->fipo); /* file name or stdout */ fputs(dkct_tr_kw8[35], psrc->fipo); fputs(psrc->cmdb, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */ fputs(dkct_tr_kw8[48], psrc->fipo); fputs(fnptr, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); fputs(dkct_tr_kw8[37], psrc->fipo); fputs(fnptr, psrc->fipo); fputs(dkct_tr_kw8[34], psrc->fipo); } if((psrc->dkcto).deb != 2) { fputs(dkct_tr_kw8[31], psrc->fipo); } if((psrc->dkcto).win) { /* Closing endif for wide char code. */ fputs(dkct_tr_kw8[23], psrc->fipo); } fputs(dkct_tr_kw8[25], psrc->fipo); } break; } } else { fputs(dkct_tr_kw8[0], psrc->fipo); } } $!trace-on /** Create full path name from relative file name. @param psrc Source structure. @param fn Short file name. @param fnb Buffer for full path name. @param szfnb Size of \a fnb. @return Pointer to buffer with full path name on success, NULL on error. */ static char * dkct_tr_function_filename( DKCT_SRC *psrc, char *fn, char *fnb, size_t szfnb ) { char *back = NULL; char *ptr; size_t sz; int ie; $? "+ dkct_tr_function_filename %s", TR_STR(fn) if(dk3str_c8_is_abs_path(fn) || (psrc->curdi)) { $? ". abs or cur" back = fn; } else { $? ". must check" ie = dk3app_get_encoding(psrc->app); if(dk3str_to_c8p_app(fnb, szfnb, psrc->ffn, ie, psrc->app)) { ptr = dk3str_c8_rchr(fnb, (dkct_tr_kw8[78])[0]); $? ". converted" if(ptr) { $? ". directory part" *ptr = '\0'; $? ". dir = \"%s\"", fnb sz = dk3str_c8_len(fnb); sz += 1; sz += dk3str_c8_len(fn); if(sz < szfnb) { $? ". size ok" strcat(fnb, dkct_tr_kw8[78]); strcat(fnb, fn); back = fnb; } else { $? "! too large" /* ERROR: Resulting file name too long! 101 */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 101); } } else { $? ". no separator" back = fn; } } else { $? "! failed to convert source name" /* ERROR: Non-ASCII characters in source file name! */ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 102, 103, psrc->ffn); } } $? "- dkct_tr_function_filename \"%s\"", TR_STR(back) return back; } $!trace-off /** Disable debugging. @param psrc Source structure. @param args Arguments (ignored). @return 1 on success, 0 on error. */ static int dkct_tr_fct_trace_off(DKCT_SRC *psrc, char *args) { (psrc->dkcto).deben = 0; return 1; } /** Enable debugging. @param psrc Source structure. @param args Arguments (ignored). @return 1 on success, 0 on error. */ static int dkct_tr_fct_trace_on(DKCT_SRC *psrc, char *args) { (psrc->dkcto).deben = 1; return 1; } /** Initialize tracing for source. @param psrc Source structure. @param args Debug output file name. @return 1 on success, 0 on error. */ static int dkct_tr_fct_trace_init(DKCT_SRC *psrc, char *args) { int back = 0; if((psrc->dkcto).deb == 1) { if(args) { fputs(dkct_tr_kw8[45], psrc->fipo); fputs(args, psrc->fipo); fputs(dkct_tr_kw8[46], psrc->fipo); if((psrc->dkcto).win) { fputs(dkct_tr_kw8[21], psrc->fipo); fputs(dkct_tr_kw8[56], psrc->fipo); fputs(dkct_tr_kw8[57], psrc->fipo); fputs(dkct_tr_kw8[58], psrc->fipo); fputs(dkct_tr_kw8[59], psrc->fipo); fputs(dkct_tr_kw8[23], psrc->fipo); } back = 1; } else { /* ERROR: Missing file name! */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 14); } } else { back = 1; if((psrc->dkcto).deb == 2) { fputs(dkct_tr_kw8[0], psrc->fipo); if((psrc->dkcto).win) { fputs(dkct_tr_kw8[21], psrc->fipo); fputs(dkct_tr_kw8[60], psrc->fipo); fputs(dkct_tr_kw8[23], psrc->fipo); } } } return back; } /** End tracing for a source. @param psrc Source structure. @param args Ignored. @return 1 on success always. */ static int dkct_tr_fct_trace_end(DKCT_SRC *psrc, char *args) { int back = 1; if((psrc->dkcto).deb == 1) { fputs(dkct_tr_kw8[47], psrc->fipo); } return back; } /** Write "#include " to output. @param psrc Source structure. @param args Ignored. @return 1 to indicate success always. */ static int dkct_tr_fct_trace_include(DKCT_SRC *psrc, char *args) { int back = 0; if((psrc->dkcto).deb) { if(!((psrc->dkcto).tip)) { if((psrc->dkcto).deb == 2) { fputs(dkct_tr_kw8[68], psrc->fipo); } fputs(dkct_tr_kw8[44], psrc->fipo); fputs(dkct_tr_kw8[79], psrc->fipo); } } return back; } /** Write trace code to output. @param psrc Source structure. @param args Code for debug mode. @return 1 on success, 0 on error. */ static int dkct_tr_fct_trace_code(DKCT_SRC *psrc, char *args) { int back = 0; if(args) { if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) { fputs(args, psrc->fipo); } back = 1; } return back; } /** Pipe command output. @param psrc Source structure. @param args Command to execute. @return 1 on success, 0 on error. */ static int dkct_tr_fct_trace_pipe(DKCT_SRC *psrc, char *args) { int back = 0; FILE *fipo = NULL; /* File pointer to read from pipe. */ char buffer[4096]; /* Input buffer. */ size_t rdbytes; /* Number of bytes read from pipe. */ int wrbytes; /* Result from write operation. */ if(args) { if(psrc->curdi) { #if DK3_ON_WINDOWS || (DK3_HAVE__POPEN && (!(DK3_HAVE_POPEN))) fipo = _popen(args, dkct_tr_kw8[49]); if(!(fipo)) { /* ERROR: Failed to open pipe! */ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 15, 16, args); } #else #if DK3_HAVE_POPEN fipo = popen(args, dkct_tr_kw8[49]); if(!(fipo)) { /* ERROR: Failed to open pipe! */ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 15, 16, args); } #else /* ERROR: No popen() function available! */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 17); #endif #endif if(fipo) { back = 1; while( (rdbytes = dk3sf_fread_app(buffer, 1, sizeof(buffer), fipo, psrc->app)) > 0 ) { wrbytes = dk3sf_fwrite_app(buffer, 1, rdbytes, psrc->fipo, psrc->app); if(wrbytes != 1) { back = 0; /* ERROR: Not all bytes written! */ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 18); } } #if DK3_ON_WINDOWS || (DK3_HAVE__POPEN && (!(DK3_HAVE_POPEN))) _pclose(fipo); #else #if DK3_HAVE_POPEN pclose(fipo); #endif #endif } } else { /* ERROR: Not in the current directory! 104 */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 104); } } return back; } /** Check whether a line contains the dollar exclam end at start @param textline Line to test. @return 1 for line contains pattern, 0 otherwise. */ static int dkct_tr_is_end_command(char const *textline) { int back = 0; char *p1; /* Text start in line. */ size_t ltext; /* Text length. */ size_t lpat; /* Pattern length. */ $? "+ dkct_tr_is_end_command \"%s\"", textline if(textline) { p1 = dk3str_c8_start(textline, NULL); if(p1) { ltext = dk3str_c8_len(p1); lpat = dk3str_c8_len(dkct_tr_kw8[51]); if(ltext >= lpat) { if(dk3str_c8_ncmp(p1, dkct_tr_kw8[51], lpat) == 0) { back = 1; } } } } $? "- dkct_tr_is_end_command %d", back return back; } /** Write splint tag, replace special character. @param psrc Source structure. @param splt Splint tag text. @return 1 on success, 0 on error. */ static int dkct_tr_write_splint_tag(DKCT_SRC *psrc, char const *splt) { int back = 1; char const *p1; $? "+ dkct_tr_write_splint_tag" if ((psrc->dkcto).spls) { $? ". char %c\n", (psrc->dkcto).spls p1 = splt; while (*p1) { if ('@' == *p1) { if (EOF == fputc((psrc->dkcto).spls, psrc->fipo)) { back = 0; } } else { if (EOF == fputc(*p1, psrc->fipo)) { back = 0; } } p1++; } } else { $? ". no char" } $? "- dkct_tr_write_splint_tag" return back; } /** Generate string table from the following lines. @param psrc Source structure. @param args Command to execute. @return 1 on success, 0 on error. */ static int dkct_tr_fct_string_table(DKCT_SRC *psrc, char *args) { char fnb[DK3_MAX_PATH]; /* Buffer for file name. */ int back = 1; char *pfile = NULL; /* String table file name. */ char *pmacro = NULL; /* Macro around strings. */ char *pprefix = NULL; /* Prefix for strings. */ char *pc; /* Pointer to current setting. */ char *pn; /* Pointer to next setting. */ char *pk; /* Setting key. */ char *pv; /* Setting value. */ FILE *fipo = NULL; /* String table output file. */ int cc = 1; /* Flag: Can continue. */ DKCT_LINE *lp; /* Current line to process. */ char lb[DKCT_LINE_SIZE]; /* Private copy of line. */ char *ptr; /* Current character to process. */ unsigned long lineno = 0UL; /* Line number of current line. */ if(args) { pc = dk3str_c8_start(args, NULL); while(pc) { pk = pv = NULL; pn = dk3str_c8_chr(pc, ','); if(pn) { *(pn++) = '\0'; pn = dk3str_c8_start(pn, NULL); } pk = dk3str_c8_start(pc, NULL); if(pk) { pv = dk3str_c8_chr(pk, '='); if(pv) { *(pv++) = '\0'; pv = dk3str_c8_start(pv, NULL); } switch(dk3str_c8_array_index(dkct_tr_string_table_args, pk, 0)) { case 0: { /* file */ pfile = pv; } break; case 1: { /* macro */ pmacro = pv; } break; case 2: { /* prefix */ pprefix = pv; } break; default: { /* ERROR: Unknown key! */ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 76, 77, pk); } break; } } else { /* ERROR: No key */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33); } pc = pn; } } if((pmacro) && (pprefix)) { /* Warning: Either macro or prefix allowed! */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 19); } if(pfile) { pfile = dkct_tr_function_filename(psrc, pfile, fnb, sizeof(fnb)); } if(pfile) { fipo = dk3sf_c8_fopen_app(pfile, dkct_tr_kw8[50], psrc->app); if(!(fipo)) { /* ERROR: Failed to open file! */ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, pfile); } } if(psrc->cursr) { do { cc = 0; lp = (DKCT_LINE *)dk3sto_it_next(psrc->cursr); if(lp) { if(lp->t) { cc = 1; if(dkct_tr_is_end_command(lp->t)) { cc = 0; } else { if(dk3str_c8_len(lp->t) < sizeof(lb)) { dk3str_c8_cpy(lb, lp->t); /* Write line to output file as is. */ dk3str_c8_delnl(lb); if(fipo) { fputs(lb, fipo); fputc('\n', fipo); } /* Generate source string. */ if(*(lb) != '#') { fprintf(psrc->fipo, dkct_tr_kw8[66], lineno++); if(pmacro) { fputs(pmacro, psrc->fipo); fputs(dkct_tr_kw8[52], psrc->fipo); } if(pprefix) { fputs(pprefix, psrc->fipo); } fputs(dkct_tr_kw8[55], psrc->fipo); dk3app_squeeze_line(lb); ptr = lb; while(*ptr) { switch(*ptr) { case '\\': { fputc('\\', psrc->fipo); fputc('\\', psrc->fipo); } break; case '"': { fputc('\\', psrc->fipo); fputc('"', psrc->fipo); } break; case '\n': { fputc('\\', psrc->fipo); fputc('n', psrc->fipo); } break; case '\r': { fputc('\\', psrc->fipo); fputc('r', psrc->fipo); } break; case '\t': { fputc('\\', psrc->fipo); fputc('t', psrc->fipo); } break; default: { fputc(*ptr, psrc->fipo); } break; } ptr++; } fputs(dkct_tr_kw8[55], psrc->fipo); if(pmacro) { fputs(dkct_tr_kw8[53], psrc->fipo); } fputs(dkct_tr_kw8[54], psrc->fipo); } } else { /* ERROR: Source line too large. */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 22); } } } } } while(cc); dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[80]); fputs(dkct_tr_kw8[65], psrc->fipo); dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[81]); } if(fipo) { #if DK3_CHAR_SIZE == 1 if(!dk3sf_fclose_fn_app(fipo, pfile, psrc->app)) { back = 0; } #else if(!dk3sf_fclose_fn_app(fipo, NULL, psrc->app)) { back = 0; } #endif fipo = NULL; } return back; } /** Generate text from the following lines. @param psrc Source structure. @param args Command to execute. @return 1 on success, 0 on error. */ static int dkct_tr_fct_text(DKCT_SRC *psrc, char *args) { int back = 1; char fnb[DK3_MAX_PATH]; /* Buffer for output file name. */ char lb[DKCT_LINE_SIZE]; /* Line buffer. */ char *pfile = NULL; /* Output file name. */ char *pmacro = NULL; /* Macro name. */ char *pprefix = NULL; /* Prefix name. */ char *pc; /* Current arg to process. */ char *pn; /* Next arg to process. */ char *pv; /* Value pointer. */ char *ptr; /* Current character to process. */ FILE *fipo = NULL; /* Output file. */ DKCT_LINE *lp; /* Current line to process. */ int cc; /* Flag: Can continue. */ pc = dk3str_c8_start(args, NULL); while(pc) { pn = dk3str_c8_chr(pc, ','); if(pn) { *(pn++) = '\0'; pn = dk3str_c8_start(pn, NULL); } pv = dk3str_c8_chr(pc, '='); if(pv) { *(pv++) = '\0'; pv = dk3str_c8_start(pv, NULL); if(pv) { switch(dk3str_c8_array_index(dkct_tr_string_table_args, pc, 0)) { case 0: { pfile = pv; } break; case 1: { pmacro = pv; } break; case 2: { pprefix = pv; } break; default: { /* ERROR: Unknown key! */ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 76, 77, pc); } break; } } } else { /* ERROR: Not key=value pair */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33); } pc = pn; } if(pfile) { pfile = dkct_tr_function_filename(psrc, pfile, fnb, sizeof(fnb)); } if(pfile) { fipo = dk3sf_c8_fopen_app(pfile, dkct_tr_kw8[50], psrc->app); if(!(fipo)) { /* ERROR: Failed to open file! */ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, pfile); } } if(psrc->cursr) { do { cc = 0; lp = (DKCT_LINE *)dk3sto_it_next(psrc->cursr); if(lp) { if(lp->t) { cc = 1; if(dkct_tr_is_end_command(lp->t)) { cc = 0; } else { if(fipo) { if(lp->t) { fputs(lp->t, fipo); fputc('\n', fipo); } } if(dk3str_c8_len(lp->t) < sizeof(lb)) { dk3str_c8_cpy(lb, lp->t); dk3str_c8_delnl(lb); if(pmacro) { fputs(pmacro, psrc->fipo); fputs(dkct_tr_kw8[52], psrc->fipo); } else { if(pprefix) { fputs(pprefix, psrc->fipo); } } fputs(dkct_tr_kw8[55], psrc->fipo); #if VERSION_BEFORE_20120214 /* No need to handle backslash escape sequences. */ dk3app_squeeze_line(lb); #endif ptr = lb; while(*ptr) { switch(*ptr) { case '\\': { switch(ptr[1]) { case '%': { /* Just ignore the backslash, it is used to escape the percent character. */ } break; default: { fputc('\\', psrc->fipo); fputc('\\', psrc->fipo); } break; } } break; case '"': { fputc('\\', psrc->fipo); fputc('"', psrc->fipo); } break; case '\n': { fputc('\\', psrc->fipo); fputc('n', psrc->fipo); } break; case '\r': { fputc('\\', psrc->fipo); fputc('r', psrc->fipo); } break; case '\t': { fputc('\\', psrc->fipo); fputc('t', psrc->fipo); } break; default: { fputc(*ptr, psrc->fipo); } break; } ptr++; } fputs(dkct_tr_kw8[55], psrc->fipo); if(pmacro) { fputs(dkct_tr_kw8[53], psrc->fipo); } fputs(dkct_tr_kw8[69], psrc->fipo); } else { /* ERROR: Source line too large. */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 22); } } } } } while(cc); dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[80]); fputs(dkct_tr_kw8[65], psrc->fipo); dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[81]); } if(fipo) { #if DK3_CHAR_SIZE == 1 if(!dk3sf_fclose_fn_app(fipo, pfile, psrc->app)) { back = 0; } #else if(!dk3sf_fclose_fn_app(fipo, NULL, psrc->app)) { back = 0; } #endif fipo = NULL; } return back; } /** Function table connecting functions to names. */ dkct_tr_fct_table_entry const dkct_tr_fct_table[] = { { "trace-init", dkct_tr_fct_trace_init }, { "trace-end", dkct_tr_fct_trace_end }, { "trace-include", dkct_tr_fct_trace_include }, { "trace-code", dkct_tr_fct_trace_code }, { "!", dkct_tr_fct_trace_code }, { "pipe", dkct_tr_fct_trace_pipe }, { "|", dkct_tr_fct_trace_pipe }, { "string-table", dkct_tr_fct_string_table }, { "text", dkct_tr_fct_text }, { "trace-on", dkct_tr_fct_trace_on }, { "trace-off", dkct_tr_fct_trace_off }, { NULL, NULL } }; /** Execute command stored in psrc->cmdb. @param psrc Source structure. @return 1 on success, 0 on error. */ static int dkct_tr_exec_command(DKCT_SRC *psrc) { int back = 0; dkct_tr_fct *fctptr = NULL; /* Function to execute. */ dkct_tr_fct_table_entry const *pte; /* Current entry to inspect. */ char *cmdname; /* Command name. */ char *args; /* Command arguments. */ if(psrc->ucmd > 0) { cmdname = dk3str_c8_start(psrc->cmdb, NULL); if(cmdname) { args = dk3str_c8_next(cmdname, NULL); pte = dkct_tr_fct_table; fctptr = NULL; while((pte->name) && (pte->fct) && (!(fctptr))) { if(dk3str_c8_cmp(pte->name, cmdname) == 0) { fctptr = pte->fct; } pte++; } if(fctptr) { back = (*fctptr)(psrc, args); fputc('\n', psrc->fipo); if((psrc->dkcto).lnn) { psrc->shln = 1; } } else { /* ERROR: No such function! */ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 23, 24, cmdname); } } else { /* ERROR: No function name! */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 25); } } return back; } /** Create comment box border line (top or bottom). @param psrc Source structure. @param max Maximum line length. */ static void dkct_tr_comment_box_border(DKCT_SRC *psrc, size_t max) { size_t lgt; /* Length of asterisk line so far. */ fputs(dkct_tr_kw8[42], psrc->fipo); lgt = 0; while(lgt++ < max) { fputc('*', psrc->fipo); } fputs(dkct_tr_kw8[43], psrc->fipo); } #if 0 static void dkct_tr_comment_box_empty_line(DKCT_SRC *psrc, size_t max) { size_t lgt; /* Length of line so far. */ fputs(dkct_tr_kw8[40], psrc->fipo); lgt = 0; while(lgt++ < max) { fputc(' ', psrc->fipo); } fputs(dkct_tr_kw8[41], psrc->fipo); } #endif /** Add text line to comment box. @param psrc Source structure. @param max Maximum line length. @param inl Input line to add. */ static void dkct_tr_comment_box_text_line(DKCT_SRC *psrc, size_t max, char const *inl) { size_t lgt; /* Length of line so far. */ fputs(dkct_tr_kw8[40], psrc->fipo); fputs(inl, psrc->fipo); lgt = dk3str_c8_len(inl); while(lgt++ < max) { fputc(' ', psrc->fipo); } fputs(dkct_tr_kw8[41], psrc->fipo); } /** Add comment box to output. @param psrc Source structure. */ static void dkct_tr_print_comment_box(DKCT_SRC *psrc) { char inl[DKCT_LINE_SIZE]; /* Current input line to process. */ size_t max; /* Box width. */ $? "+ dkct_tr_print_comment_box" max = psrc->cbmx; if((size_t)((psrc->dkcto).bw) > (max + 10)) { max = (size_t)((psrc->dkcto).bw) - 10; } fflush(psrc->cbfip); rewind(psrc->cbfip); dkct_tr_comment_box_border(psrc, max); /* dkct_tr_comment_box_empty_line(psrc, max); */ while(fgets(inl, sizeof(inl), psrc->cbfip)) { dk3str_c8_delnl(inl); dkct_tr_comment_box_text_line(psrc, max, inl); } /* dkct_tr_comment_box_empty_line(psrc, max); */ dkct_tr_comment_box_border(psrc, max); $? "- dkct_tr_print_comment_box" } /** Process one character in psrc->cchr. @param psrc Source structure. */ static int dkct_tr_process_character(DKCT_SRC *psrc) { int back = 0; int input; /* State machine input. */ int action; /* State machine output. */ $? "+ dkct_tr_process_character" input = psrc->cchr; if(psrc->cchr == '$') { input = TRACE_CONTROL; } action = dkct_tr_state_machine_transition(&(psrc->st), input); switch(action) { case DKCT_O_NOOP: { /* Nothing to do. */ back = 1; } break; case DKCT_O_PRINT: { /* Print current character. */ fputc(psrc->cchr, psrc->fipo); back = 1; } break; case DKCT_O_DOLLAR_AND_CHAR: { fputc('$', psrc->fipo); fputc(psrc->cchr, psrc->fipo); back = 1; } break; case DKCT_O_SLASH_AND_CHAR: { fputc('/', psrc->fipo); fputc(psrc->cchr, psrc->fipo); back = 1; } break; case DKCT_O_RESET_BUFFER: { dkct_tr_reset_buffer(psrc); back = 1; } break; case DKCT_O_ADD_BUFFER: { if(psrc->ucmd < psrc->szcmd) { (psrc->cmdb)[psrc->ucmd] = psrc->cchr; psrc->ucmd += 1; back = 1; } else { /* ERROR: Buffer full */ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 98); } } break; case DKCT_O_TRACE_OUTPUT: { if(psrc->ucmd < psrc->szcmd) { (psrc->cmdb)[psrc->ucmd] = '\0'; } else { (psrc->cmdb)[psrc->szcmd - 1] = '\0'; } dkct_tr_trace_output(psrc); dkct_tr_reset_buffer(psrc); back = 1; if((psrc->dkcto).lnn) { psrc->shln = 1; } } break; case DKCT_O_EXEC_CMD: { if(psrc->ucmd < psrc->szcmd) { (psrc->cmdb)[psrc->ucmd] = '\0'; } else { (psrc->cmdb)[psrc->szcmd - 1] = '\0'; } dkct_tr_exec_command(psrc); dkct_tr_reset_buffer(psrc); back = 1; if((psrc->dkcto).lnn) { psrc->shln = 1; } } break; case DKCT_O_START_CPP_COMMENT: { switch(psrc->sufi) { case 1: case 3: case 4: { fputs(dkct_tr_kw8[26], psrc->fipo); } break; default: { fputs(dkct_tr_kw8[2], psrc->fipo); } break; } back = 1; } break; case DKCT_O_END_CPP_COMMENT: { switch(psrc->sufi) { case 1: case 3: case 4: { fputs(dkct_tr_kw8[0], psrc->fipo); } break; default: { fputs(dkct_tr_kw8[27], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); } break; } back = 1; } break; case DKCT_O_START_BOX: { $? ". open box file" if(psrc->cbfip) { fclose(psrc->cbfip); psrc->cbfip = NULL; } psrc->cbfip = dk3sf_c8_fopen_app(psrc->cbfn, dkct_tr_kw8[39], psrc->app); psrc->cbcp = 0; psrc->cbmx = 0; if(psrc->cbfip) { back = 1; } else { $? "! failed to open box file" /* ERROR: Failed to open file */ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, psrc->cbfn); } } break; case DKCT_O_ADD_BOX: { $? ". add character" if(psrc->cbfip) { if(psrc->cchr == '\t') { fputc(' ', psrc->cbfip); psrc->cbcp += 1; while((psrc->cbcp) % 8) { fputc(' ', psrc->cbfip); psrc->cbcp += 1; } } else { fputc(psrc->cchr, psrc->cbfip); psrc->cbcp += 1; } if(psrc->cbcp > psrc->cbmx) { psrc->cbmx = psrc->cbcp; } back = 1; } } break; case DKCT_O_ADD_BOX_NL: { $? ". add newline" if(psrc->cbfip) { fputc('\n', psrc->cbfip); psrc->cbcp = 0; back = 1; } } break; case DKCT_O_ADD_BOX_DOLLAR_CHAR: { $? ". add dollar and char" if(psrc->cbfip) { fputc('$', psrc->cbfip); psrc->cbcp += 1; if(psrc->cchr == '\t') { fputc(' ', psrc->cbfip); psrc->cbcp += 1; while((psrc->cbcp) % 8) { fputc(' ', psrc->cbfip); psrc->cbcp += 1; } } else { fputc(psrc->cchr, psrc->cbfip); psrc->cbcp += 1; } if(psrc->cbcp > psrc->cbmx) { psrc->cbmx = psrc->cbcp; } back = 1; } } break; case DKCT_O_END_BOX: { $? ". end box" if(psrc->cbfip) { fputc('\n', psrc->cbfip); dkct_tr_print_comment_box(psrc); fclose(psrc->cbfip); psrc->cbfip = NULL; back = 1; } if((psrc->dkcto).lnn) { psrc->shln = 1; } } break; } $? "- dkct_tr_process_character %d", back return back; } /** Process all source lines from a storage. @param psrc Source structure. @param iterator Storage iterator. */ static int dkct_tr_module_lines(DKCT_SRC *psrc, dk3_sto_it_t *iterator) { int back = 1; DKCT_LINE *lp; /* Current line to process. */ char const *ptr; /* Current character to process. */ $? "+ dkct_tr_module_lines" if(iterator) { psrc->cursr = iterator; dk3sto_it_reset(iterator); while((lp = (DKCT_LINE *)dk3sto_it_next(iterator)) != NULL) { if(lp->t) { $? ". line=\"%s\"", lp->t psrc->lineno = lp->l; if(psrc->app) { dk3app_set_source_line(psrc->app, lp->l); } if(psrc->shln) { psrc->shln = 0; dkct_tr_show_source_line(psrc, 1); } ptr = lp->t; while(*ptr) { psrc->cchr = *(ptr++); if(!dkct_tr_process_character(psrc)) { back = 0; } } psrc->cchr = '\n'; if(!dkct_tr_process_character(psrc)) { back = 0; } } } psrc->cursr = NULL; } $? "- dkct_tr_module_lines %d", back return back; } /** Attempt to write one output file. @param psrc Source structure. @param sfn Source file name. @param osf Output file name suffix. @param f_hdr Flag: This is the header file. */ static int dkct_tr_attempt_to_write_file( DKCT_SRC *psrc, dkChar const *sfn, dkChar const *osf, int f_hdr ) { int back = 1; dkChar ofn[DK3_MAX_PATH]; /* Output file name. */ dkChar *sofn = NULL; /* Short output name. */ dkChar *ps = NULL; /* Output suffix. */ int f_must_run = 1; /* Flag: Must run. */ int first_state_machine = 1; /* Flag: First stm. */ DKCT_STM *pstm; /* State machine. */ $? "+ dkct_tr_attempt_to_write_file %d \"%s\"", psrc->sufi, osf if(dk3str_len(sfn) < DK3_SIZEOF(ofn,dkChar)) { dk3str_cpy_not_overlapped(ofn, sfn); ps = dk3str_get_suffix(ofn); if(ps) { *ps = dkT('\0'); } if((dk3str_len(ofn) + dk3str_len(osf)) < DK3_SIZEOF(ofn,dkChar)) { dk3str_cat(ofn, osf); $? ". output file name \"%s\"", ofn if((psrc->dkcto).mak) { $? ". make mode" f_must_run = dk3sf_must_rebuild(ofn, sfn); } sofn = dk3str_rchr(ofn, DK3_CHAR_SEP); if(sofn) { sofn++; } else { sofn = ofn; } dk3app_set_source_line(psrc->app, 0UL); if(f_must_run) { $? ". must run" /* Progress: Writing output file. */ dk3app_log_3(psrc->app, DK3_LL_PROGRESS, psrc->msg, 108, 109, sofn); psrc->fipo = dk3sf_fopen_app(ofn, dk3app_not_localized(24), psrc->app); if(psrc->fipo) { $? ". file opened" dkct_tr_write_file_start(psrc, ofn, sfn, f_hdr); if((psrc->dkcto).lnn) { psrc->shln = 1; } if(f_hdr) { /* Protect against multiple inclusion (file start) */ fputs(dkct_tr_kw8[6], psrc->fipo); dkct_tr_filename_to_upper(psrc, ofn); fputs(dkct_tr_kw8[7], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); fputs(dkct_tr_kw8[8], psrc->fipo); dkct_tr_filename_to_upper(psrc, ofn); fputs(dkct_tr_kw8[7], psrc->fipo); fputs(dkct_tr_kw8[9], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); /* Header start and class start. */ if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->hsi)) { back = 0; } if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->clsi)) { back = 0; } /* wxWindows GUI output. */ if(psrc->sufi == 4) { dkct_gui_class_variables(psrc); } /* Class end and header end. */ if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->clei)) { back = 0; } if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->hei)) { back = 0; } /* State machine constants, if any. */ dk3sto_it_reset(psrc->i_stm); while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) { if(pstm->wrh) { psrc->lineno = pstm->lineno; dk3app_set_source_line(psrc->app, pstm->lineno); dkct_au_write_entries(psrc, pstm); dkct_au_write_prototypes(psrc, pstm); } } /* Protect against multiple inclusion (file end) */ fputs(dkct_tr_kw8[0], psrc->fipo); fputs(dkct_tr_kw8[10], psrc->fipo); fputs(dkct_tr_kw8[0], psrc->fipo); } else { /* State machine constants and functions if any. */ dk3sto_it_reset(psrc->i_stm); while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) { if(first_state_machine) { first_state_machine = 0; if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) { if((psrc->dkcto).deb == 2) { fputs(dkct_tr_kw8[68], psrc->fipo); } else { fputs(dkct_tr_kw8[44], psrc->fipo); } (psrc->dkcto).tip = 1; } } psrc->lineno = pstm->lineno; dk3app_set_source_line(psrc->app, pstm->lineno); if(!(pstm->wrh)) { dkct_au_write_entries(psrc, pstm); dkct_au_write_functions(psrc, pstm, 1); } else { dkct_au_write_functions(psrc, pstm, 0); } } /* Start of module. */ psrc->st = 0; if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->msi)) { back = 0; } if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->cosi)) { back = 0; } /* GUI setup. */ if(psrc->sufi == 4) { dkct_gui_write_constructor(psrc); } /* End of module. */ if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->coei)) { back = 0; } if((psrc->dkcto).lnn) { psrc->shln = 1; } if(!dkct_tr_module_lines(psrc, psrc->mei)) { back = 0; } } if(!dk3sf_fclose_fn_app(psrc->fipo, ofn, psrc->app)) { back = 0; } } else { $? "! failed to open file" /* ERROR: Failed to open file! */ dkct_to_log_dk_3(psrc, 0, DK3_LL_ERROR, 20, 21, ofn); back = 0; } } else { /* Progress: Output file is up to date. */ dk3app_log_3(psrc->app, DK3_LL_PROGRESS, psrc->msg, 110, 111, sofn); } } else { $? "! output file name too long" /* ERROR: File name too long! */ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 26, 27, ofn); back = 0; } } else { $? "! input file name too long" /* File name too long! */ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 26, 27, sfn); back = 0; } $? "- dkct_tr_attempt_to_write_file %d", back return back; } int dkct_tr_write(DKCT_SRC *psrc, dkChar const *fn, int sufi) { int back = 1; char fnb[128]; /* File name for temporary box file. */ $? "+ dkct_tr_write %d", sufi psrc->cbfip = NULL; psrc->sufi = sufi; psrc->shln = 0; sprintf(fnb, dkct_tr_kw8[38], (unsigned long)dk3sf_getpid()); psrc->cbfn = fnb; psrc->lineno = 1UL; dk3app_set_source_line(psrc->app, 1UL); switch(sufi) { case 4: { /* .h .cpp */ if(dkct_tr_have_header_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1)) { back = 0; } } if(dkct_tr_have_module_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[2],0)) { back = 0; } } } break; case 3: { /* .java */ if(dkct_tr_have_module_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[4],0)) { back = 0; } } } break; case 2: { /* .h .m */ if(dkct_tr_have_header_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1)) { back = 0; } } if(dkct_tr_have_module_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[3],0)) { back = 0; } } } break; case 1: { /* .h .cpp */ if(dkct_tr_have_header_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1)) { back = 0; } } if(dkct_tr_have_module_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[2],0)) { back = 0; } } } break; case 0: { /* .h .c */ if(dkct_tr_have_header_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1)) { back = 0; } } if(dkct_tr_have_module_data(psrc)) { if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[1],0)) { back = 0; } } } break; } if(psrc->cbfip) { fclose(psrc->cbfip); psrc->cbfip = NULL; } dk3sf_c8_remove_file_app(psrc->cbfn, NULL); psrc->cbfn = NULL; $? "- dkct_tr_write %d", back return back; } /** Pointer to a constant string. */ typedef char const *DKCT_TR_CONST_CHAR_PTR; char const * dkct_tr_get_kw8(size_t sz) { char const *back = NULL; if(sz < (sizeof(dkct_tr_kw8)/sizeof(DKCT_TR_CONST_CHAR_PTR))) { back = dkct_tr_kw8[sz]; } return back; } /* vim: set ai sw=2 : */