summaryrefslogtreecommitdiff
path: root/support/dktools/dkwxwiz.c
diff options
context:
space:
mode:
Diffstat (limited to 'support/dktools/dkwxwiz.c')
-rw-r--r--support/dktools/dkwxwiz.c1393
1 files changed, 1393 insertions, 0 deletions
diff --git a/support/dktools/dkwxwiz.c b/support/dktools/dkwxwiz.c
new file mode 100644
index 0000000000..2c1ae67791
--- /dev/null
+++ b/support/dktools/dkwxwiz.c
@@ -0,0 +1,1393 @@
+/*
+ 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.
+ Original source: dkwxwiz.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+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.
+*/
+
+/** @file dkwxwiz.c The dkwxwiz module.
+*/
+
+
+#line 9 "dkwxwiz.ctr"
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+
+
+#line 18 "dkwxwiz.ctr"
+
+
+
+/** @defgroup dkwxwizcmd Commands for dkwxwiz.
+*/
+/**@{*/
+
+/** Show help text.
+*/
+#define DKWXWIZ_CMD_HELP 1
+
+/** Show version information.
+*/
+#define DKWXWIZ_CMD_VERSION 2
+
+/** Show license terms.
+*/
+#define DKWXWIZ_CMD_LICENSE 4
+
+/**@}*/
+
+
+/** Job structure for dkwxwiz.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages texts. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ dkChar const *con; /**< Copyright holder name. */
+ dkChar const *lin; /**< License name. */
+ dkChar const *pName; /**< Program name. */
+ dkChar const *aName; /**< Application class name. */
+ dkChar const *fName; /**< Frame class name. */
+ dkChar const *xfn; /**< XPM file name (allocated). */
+ dkChar const *pfn; /**< Program header file name. */
+ dkChar const *afn; /**< Application class file name. */
+ dkChar const *ffn; /**< Frame class file name. */
+ dkChar const *ifn; /**< Icon file name. */
+ dkChar const *rfn; /**< RC file name. */
+ int exv; /**< Exit value. */
+ int cmd; /**< Command to execute. */
+ int frc; /**< Force overwriting existing files. */
+ int obj; /**< Flag: Use object modules, not libs. */
+} DKWXWIZ_JOB;
+
+
+
+/** Macros like $program$ are allowed in the templates.
+*/
+static char const * const dkwxwiz_macros[] = {
+/* 0 */
+"program",
+
+/* 1 */
+"application",
+
+/* 2 */
+"frame",
+
+/* 3 */
+"year",
+
+/* 4 */
+"copyrightowner",
+
+/* 5 */
+"licensetype",
+
+NULL
+
+
+#line 94 "dkwxwiz.ctr"
+};
+
+
+
+/** Constant dkChar strings, not localized.
+*/
+static dkChar const * const dkwxwiz_nl[] = {
+/* 0 */
+dkT(".h"),
+
+/* 1 */
+dkT(".cpt"),
+
+/* 2 */
+dkT(".wxc"),
+
+/* 3 */
+dkT("dkwxwizh.txt"),
+
+/* 4 */
+dkT("dkwxwiza.txt"),
+
+/* 5 */
+dkT("dkwxwizf.txt"),
+
+/* 6 */
+dkT("r"),
+
+/* 7 */
+dkT("w"),
+
+/* 8 */
+dkT("Makefile.in"),
+
+/* 9 */
+dkT("configure.ac"),
+
+/* 10 */
+dkT("dkwxwizm.txt"),
+
+/* 11 */
+dkT("dkwxwizc.txt"),
+
+/* 12 */
+dkT("wb"),
+
+/* 13 */
+dkT("\r\n"),
+
+/* 14 */
+dkT("\n"),
+
+/* 15 */
+dkT(".xpm"),
+
+/* 16 */
+dkT("dkwxwizx.txt"),
+
+/* 17 */
+dkT(".ico"),
+
+/* 18 */
+dkT("dkwxwiz.ico"),
+
+/* 19 */
+dkT("rb"),
+
+/* 20 */
+dkT(".rc"),
+
+/* 21 */
+dkT("dkwxwizr.txt"),
+
+/* 22 */
+dkT("makefile.vc"),
+
+/* 23 */
+dkT("dkwxwizv.txt"),
+
+NULL
+
+
+#line 199 "dkwxwiz.ctr"
+};
+
+
+
+/** Constant dkChar strings, localized versions are used if found.
+*/
+static dkChar const * const dkwxwiz_msg[] = {
+/* 0 */
+dkT("dkwxwiz"),
+
+/* 1 */
+dkT("dktools"),
+
+/* 2 */
+dkT("dkwxwiz.str"),
+
+/* 3 */
+dkT("dkwxwiz.txt"),
+
+/* 4 */
+dkT("__CHANGE__ 001:\tCopyright owner"),
+
+/* 5 */
+dkT("bsd"),
+
+/* 6 */
+dkT("File base name \""),
+
+/* 7 */
+dkT("\" too long!"),
+
+/* 8 */
+dkT("File \""),
+
+/* 9 */
+dkT("\" already exists!"),
+
+/* 10 */
+dkT("Unknown macro in line!"),
+
+/* 11 */
+dkT("Too few command line arguments!"),
+
+/* 12 */
+dkT("You should create/modify the following files:"),
+
+/* 13 */
+dkT("Windows help file: \""),
+
+/* 14 */
+dkT("non-Windows help file: \""),
+
+/* 15 */
+dkT("Windows icon file: \""),
+
+/* 16 */
+dkT("non-Windows icon file: \""),
+
+/* 17 */
+dkT("\"."),
+
+/* 18 */
+dkT(".chm"),
+
+/* 19 */
+dkT(".htb"),
+
+/* 20 */
+dkT(".ico"),
+
+/* 21 */
+dkT(".xpm"),
+
+/* 22 */
+dkT("Text too long or not ASCII: \""),
+
+/* 23 */
+dkT("\"!"),
+
+/* 24 */
+dkT("Not a C/C++ identifier: \""),
+
+/* 25 */
+dkT("\"!"),
+
+NULL
+
+
+#line 279 "dkwxwiz.ctr"
+};
+
+
+
+/** License conditions shown for dkwxwiz --license-terms.
+*/
+static dkChar const * const dkwxwiz_license[] = {
+dkT(""),
+dkT("Copyright (c) 2013-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote products derived from"),
+dkT(" this software without specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A"),
+dkT("PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 317 "dkwxwiz.ctr"
+};
+
+
+/** Options allowed for dkwxwiz.
+*/
+static dk3_option_t const dkwxwiz_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('f'), dkT("force"), 0},
+ { dkT('l'), dkT("license"), 1 },
+ { dkT('c'), dkT("copyright-owner"), 1 },
+ { dkT('o'), dkT("object-modules"), 0 },
+};
+
+
+/** Number of options in the dkwxwiz_options array.
+*/
+static size_t dkwxwiz_sz_options =
+sizeof(dkwxwiz_options)/sizeof(dk3_option_t);
+
+
+
+/** Default help text, shown if no help file is found.
+*/
+static dkChar const * dkwxwiz_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwxwiz - Wizard to create a wxWidgets + dkct based project."),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwxwiz [<options>] <program> <application> <window>"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program creates source code skeletons for a new GUI application based"),
+dkT("on wxWidgets assuming you use the dktools libraries and the dkct program"),
+dkT("during development."),
+dkT("As arguments you have to specify:"),
+dkT(""),
+dkT("* Name of the final program (i.e. \"myprog\")."),
+dkT(""),
+dkT("* Name of the application class derived from wxApp (i.e, \"MyProgApp\")."),
+dkT(""),
+dkT("* Name of the main window class (i.e. \"MyProgFrame\")."),
+dkT(""),
+dkT("Valid C/C++ identifiers are required for all three names."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-h\t--help"),
+dkT(" Show a help text."),
+dkT(""),
+dkT("-v\t--version"),
+dkT(" Show the program version."),
+dkT(""),
+dkT("-L\t--license-terms"),
+dkT(" Show the license conditions."),
+dkT(""),
+dkT("-f\t--force"),
+dkT(" Force the program to overwrite existing files."),
+dkT(""),
+dkT("-c <copyright owner name>"),
+dkT(" Name of the copyright owner."),
+dkT(""),
+dkT("-l <license type>"),
+dkT(" License type (i.e. \"bsd\")."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("EXAMPLES"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwxwiz testprog TestApp TestFrame"),
+dkT("in an empty directory to create a new project."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("The following files from the dktools resource directory are used:"),
+dkT(""),
+dkT("dkwxwizh.txt\tTemplate for project header file *.h."),
+dkT(""),
+dkT("dkwxwiza.txt\tTemplate for application class source *.cpt"),
+dkT(""),
+dkT("dkwxwizf.txt\tTemplate for top-level window class source *.wxc."),
+dkT(""),
+dkT("dkwxwizc.txt\tTemplate for configure.ac file for autoconf."),
+dkT(""),
+dkT("dkwxwizm.txt\tTemplate for the Makefile.in file."),
+dkT(""),
+dkT("dkwxwizx.txt\tTemplate for the *.xpm icon file."),
+dkT(""),
+dkT("You can create copies of these files in dkt-3-site and modify them"),
+dkT("i.e. to set a default copyright owner and a default license type."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("LICENSE"),
+dkT(""),
+dkT("Use"),
+dkT(" dkwxwiz --license-terms"),
+dkT("to view the license conditions."),
+NULL
+
+
+#line 431 "dkwxwiz.ctr"
+};
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure.
+ @param msg Localized message texts.
+*/
+static
+void
+dkwxwiz_job_init(DKWXWIZ_JOB *job, dk3_app_t *app, dkChar const * const *msg)
+{
+ job->app = app;
+ job->msg = msg;
+ job->opt = NULL;
+ job->pName = NULL;
+ job->aName = NULL;
+ job->fName = NULL;
+ job->xfn = NULL;
+ job->pfn = NULL;
+ job->afn = NULL;
+ job->ffn = NULL;
+ job->ifn = NULL;
+ job->rfn = NULL;
+ job->exv = 1;
+ job->cmd = 0;
+ job->frc = 0;
+ job->obj = 0;
+ job->con = NULL;
+ job->lin = NULL;
+}
+
+
+
+/** Concatenate base name and file suffix.
+ @param job Job structure.
+ @param bn Base file name.
+ @param sf File name suffix.
+ @return Pointer to new allocated file name on success, NULL on error.
+*/
+static
+dkChar const *
+dkwxwiz_concatenate(DKWXWIZ_JOB *job, dkChar const *bn, dkChar const *sf)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Temporary name buffer. */
+ dkChar const *back = NULL;
+
+
+#line 478 "dkwxwiz.ctr"
+ if(DK3_SIZEOF(buf,dkChar) > (dk3str_len(bn) + dk3str_len(sf))) {
+ dk3str_cpy_not_overlapped(buf, bn);
+ dk3str_cat(buf, sf);
+ back = (dkChar const *)dk3str_dup_app(buf, job->app);
+ } else {
+ /* ERROR: Base name too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 6, 7, bn);
+ }
+
+#line 486 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Build file names for output files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_build_file_names(DKWXWIZ_JOB *job)
+{
+ int back = 0;
+
+
+#line 501 "dkwxwiz.ctr"
+ job->pfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[0]);
+ job->afn = dkwxwiz_concatenate(job, job->aName, dkwxwiz_nl[1]);
+ job->ffn = dkwxwiz_concatenate(job, job->fName, dkwxwiz_nl[2]);
+ job->xfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[15]);
+ job->ifn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[17]);
+ job->rfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[20]);
+ if((job->pfn) && (job->afn) && (job->ffn) && (job->xfn) && (job->ifn)) {
+ if(job->rfn) {
+ back = 1;
+ }
+ }
+
+#line 512 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Check one file name whether we can write the file.
+ @param job Job structure.
+ @param fn Output file name.
+ @return 1 if allowed to write the file, 0 otherwise.
+*/
+static
+int
+dkwxwiz_check_one_filename(DKWXWIZ_JOB *job, dkChar const *fn)
+{
+ dk3_stat_t stb; /* File information. */
+ int back = 0;
+
+
+#line 529 "dkwxwiz.ctr"
+ if(0 == dk3sf_stat_app(&stb, fn, NULL)) {
+ back = 1;
+ } else {
+ /* ERROR: File already exists! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 8, 9, fn);
+ }
+
+#line 535 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Check whether we can write all files.
+ @param job Job structure.
+ @return 1 if we are allowed to write/overwrite the files, 0 otherwise.
+*/
+static
+int
+dkwxwiz_check_filenames(DKWXWIZ_JOB *job)
+{
+ int back = 0;
+
+
+#line 550 "dkwxwiz.ctr"
+ if(job->frc) {
+ back = 1;
+ } else {
+ back = 1;
+ if(!dkwxwiz_check_one_filename(job, job->pfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->afn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->ffn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->xfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[8])) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[9])) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->ifn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->rfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[22])) {
+ back = 0;
+ }
+ }
+
+#line 582 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Write one string as 8-bit character text to output.
+ @param job Job structure.
+ @param dfile Destination file.
+ @param txt Text to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_write_c8_string(DKWXWIZ_JOB *job, FILE *dfile, dkChar const *txt)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[1024]; /* Temporary buffer for output. */
+#endif
+ int back = 0;
+#if DK3_CHAR_SIZE > 1
+ int res = 0;
+
+
+#line 604 "dkwxwiz.ctr"
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), txt, dk3app_get_encoding(job->app), job->app
+ );
+ if(res) {
+ fputs(buf, dfile);
+ back = 1;
+ }
+
+#line 611 "dkwxwiz.ctr"
+#else
+
+
+#line 613 "dkwxwiz.ctr"
+ fputs(txt, dfile);
+ back = 1;
+
+#line 615 "dkwxwiz.ctr"
+#endif
+ return back;
+}
+
+
+
+/** Process one macro.
+ @param job Job structure.
+ @param dfile Output (destination) file.
+ @param sfile Input (source) file.
+ @param cptr Start of text.
+ @param p1 First '$' character.
+ @param p2 Second '$' character.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_one_macro(
+ DKWXWIZ_JOB *job,
+ FILE *dfile,
+ FILE *sfile,
+ char *cptr,
+ char *p1,
+ char *p2
+)
+{
+ dk3_tm_t tm; /* Local time. */
+ dkChar const *vptr; /* Pointer to value text. */
+ dk3_time_t timer; /* Current time. */
+ int action; /* Macro action to perform. */
+ int back = 1;
+ *p1 = '\0';
+ fputs(cptr, dfile);
+ *p2 = '\0';
+#if VERSION_BEFORE_20150821
+ cptr = &(p2[1]);
+#endif
+ p1++;
+ action = dk3str_c8_array_index(dkwxwiz_macros, p1, 0);
+ switch(action) {
+ case 0: { /* program */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->pName)) {
+ back = 0;
+ }
+ } break;
+ case 1: { /* application */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->aName)) {
+ back = 0;
+ }
+ } break;
+ case 2: { /* frame */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->fName)) {
+ back = 0;
+ }
+ } break;
+ case 3: { /* year */
+ if(dk3sf_time(&timer)) {
+ if(dk3sf_localtime_app(&tm, &timer, job->app)) {
+ fprintf(dfile, "%04d", tm.Y);
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to obtain current time. */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 80);
+ back = 0;
+ }
+ } break;
+ case 4: { /* copyrightowner */
+ vptr = job->con;
+ if(!(vptr)) { vptr = (job->msg)[4]; }
+ if(!dkwxwiz_write_c8_string(job, dfile, vptr)) {
+ back = 0;
+ }
+ } break;
+ case 5: { /* licensetype */
+ vptr = job->lin;
+ if(!(vptr)) { vptr = (job->msg)[5]; }
+ if(!dkwxwiz_write_c8_string(job, dfile, vptr)) {
+ back = 0;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown macro */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ fputc('$', dfile);
+ fputs(p1, dfile);
+ fputc('$', dfile);
+ back = 0;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Find '$' character starting a dkwxwiz macro.
+ @param txt Text to search for macro.
+ @return Pointer to first macro found on success, NULL if no macro found.
+*/
+static
+char *
+dkwxwiz_find_macro_start(char *txt)
+{
+ char *p1; /* Probably start of new macro. */
+ char *back = NULL;
+ p1 = dk3str_c8_chr(txt, '$');
+ while((p1) && (!(back))) {
+ switch(p1[1]) {
+ case '!': case '?':
+ case '(': case '{':
+ case '@': case '*':
+ case '<': case '>':{
+ p1 = dk3str_c8_chr(&(p1[1]), '$');
+ } break;
+ default: {
+ back = p1;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Transfer one source file contents to destination file.
+ @param job Job structure.
+ @param dfile Destination file.
+ @param sfile Template file.
+ @param iswin Flag: Insist on Windows line ends.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_transfer_file(DKWXWIZ_JOB *job, FILE *dfile, FILE *sfile, int iswin)
+{
+ char buf[4096]; /* Line buffer. */
+ char *cptr; /* Remaining line to process. */
+ char *p1; /* Start of macro. */
+ char *p2; /* End of macro. */
+ unsigned long oldsourceline; /* Old source line number. */
+ unsigned long lineno = 0UL; /* Current source line. */
+ int back = 1;
+
+
+#line 759 "dkwxwiz.ctr"
+ oldsourceline = dk3app_get_source_line(job->app);
+ while(fgets(buf, sizeof(buf), sfile)) {
+ lineno++;
+ dk3app_set_source_line(job->app, lineno);
+ dk3str_c8_delnl(buf);
+ cptr = buf;
+#if 0
+ while(cptr) {
+ p1 = dk3str_c8_chr(cptr, '$');
+ if(p1) {
+ switch(p1[1]) {
+ case '!': case '?': case '(': case '{': {
+ p1 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p1) {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = ++p2;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } break;
+ default: {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = ++p2;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } break;
+ }
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ }
+#else
+ while(cptr) {
+ p1 = dkwxwiz_find_macro_start(cptr);
+ if(p1) {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = p2;
+ cptr++;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } else {
+ fputs(cptr, dfile),
+ cptr = NULL;
+ }
+ }
+#endif
+ /* fputs(dkwxwiz_nl[(iswin) ? 13 : 14], dfile); */
+ if(iswin) {
+ fputc(0x0d, dfile);
+ }
+ fputc(0x0a, dfile);
+ }
+ dk3app_set_source_line(job->app, oldsourceline);
+
+
+#line 835 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Produce one output file.
+ @param job Job structure.
+ @param dn Destination file name.
+ @param sn Source file name (template).
+ @param isbin Flag: Open output for binary writing.
+ @param iswin Flag: Use Windows line ends.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_one_output_file(
+ DKWXWIZ_JOB *job,
+ dkChar const *dn,
+ dkChar const *sn,
+ int isbin,
+ int iswin
+)
+{
+ dk3_search_t *sres; /* Search result set. */
+ FILE *sfile; /* Source file. */
+ FILE *dfile; /* Destination file. */
+ dkChar const *srcname; /* Source file name. */
+ dkChar const *oldsourcename; /* Old source file name. */
+ int back = 0;
+
+
+#line 865 "dkwxwiz.ctr"
+ oldsourcename = dk3app_get_source_file(job->app);
+ sres = dk3app_find_config_file_revers(job->app, sn, 0);
+ if(sres) {
+
+#line 868 "dkwxwiz.ctr"
+ dk3search_reset(sres);
+ srcname = dk3search_next(sres);
+ if(srcname) {
+
+#line 871 "dkwxwiz.ctr"
+ sfile = dk3sf_fopen_app(srcname, dkwxwiz_nl[6], job->app);
+ if(sfile) {
+
+#line 873 "dkwxwiz.ctr"
+ dfile = dk3sf_fopen_app(dn, dkwxwiz_nl[(isbin) ? 12 : 7], job->app);
+ if(dfile) {
+
+#line 875 "dkwxwiz.ctr"
+ dk3app_set_source_file(job->app, sn);
+ back = dkwxwiz_transfer_file(job, dfile, sfile, iswin);
+ if(!dk3sf_fclose_fn_app(dfile, dn, job->app)) {
+ back = 0;
+ }
+ } else {
+
+#line 881 "dkwxwiz.ctr"
+ }
+ fclose(sfile);
+ } else {
+
+#line 884 "dkwxwiz.ctr"
+ }
+ } else {
+
+#line 886 "dkwxwiz.ctr"
+ /* ERROR: File sn not found! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 150, 151, sn);
+ }
+ dk3search_close(sres);
+ } else {
+
+#line 891 "dkwxwiz.ctr"
+ }
+ dk3app_set_source_file(job->app, oldsourcename);
+
+
+#line 894 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Copy a binary file directly.
+ @param job Job structure.
+ @param dn Destination file name.
+ @param sn Source file name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_copy_binary(DKWXWIZ_JOB *job, dkChar const *dn, dkChar const *sn)
+{
+ char buf[4096]; /* Data buffer for copying. */
+ dk3_search_t *sres; /* Search result set. */
+ dkChar const *srcname; /* Source file name. */
+ FILE *sfile; /* Source file. */
+ FILE *dfile; /* Destination file. */
+ size_t rdbytes; /* Number of bytes read. */
+ size_t wrbytes; /* Number of bytes written. */
+ int back = 0;
+
+ sres = dk3app_find_config_file_revers(job->app, sn, 0);
+ if(sres) {
+ dk3search_reset(sres);
+ srcname = dk3search_next(sres);
+ if(srcname) {
+ sfile = dk3sf_fopen_app(srcname, dkwxwiz_nl[19], job->app);
+ if(sfile) {
+ dfile = dk3sf_fopen_app(dn, dkwxwiz_nl[12], job->app);
+ if(dfile) {
+ back = 1;
+ do {
+ rdbytes = fread(buf, 1, sizeof(buf), sfile);
+ if(rdbytes > 0) {
+ wrbytes = fwrite(buf, 1, rdbytes, dfile);
+ if(wrbytes != rdbytes) {
+ back = 0;
+ /* ERROR: Write operation failed! */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 120);
+ }
+ }
+ } while((rdbytes > 0) && (1 == back));
+ if(!dk3sf_fclose_fn_app(dfile, dn, job->app)) {
+ back = 0;
+ }
+ }
+ fclose(sfile);
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 150, 151, sn);
+ }
+ dk3search_close(sres);
+ }
+ return back;
+}
+
+
+
+/** Produce output files.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_produce_output(DKWXWIZ_JOB *job)
+{
+
+
+#line 963 "dkwxwiz.ctr"
+ if(dkwxwiz_one_output_file(job, job->pfn, dkwxwiz_nl[3], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, job->afn, dkwxwiz_nl[4], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, job->ffn, dkwxwiz_nl[5], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, dkwxwiz_nl[8], dkwxwiz_nl[10], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, dkwxwiz_nl[9], dkwxwiz_nl[11],0,0))
+ {
+ if(dkwxwiz_one_output_file(job, job->xfn, dkwxwiz_nl[16], 1, 0))
+ {
+ if(dkwxwiz_copy_binary(job, job->ifn, dkwxwiz_nl[18])) {
+ if(dkwxwiz_one_output_file(job,dkwxwiz_nl[22],dkwxwiz_nl[23],1,1))
+ {
+ if(dkwxwiz_one_output_file(job,job->rfn,dkwxwiz_nl[21],1,1)) {
+ job->exv = 0;
+ /* You should provide the following files: */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs((job->msg)[12], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Windows help file: */
+ dk3sf_fputs((job->msg)[13], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[18], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* non-Windows help file: */
+ dk3sf_fputs((job->msg)[14], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[19], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Windows icon file (ico) */
+ dk3sf_fputs((job->msg)[15], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[20], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* non-Windows icon file (xpm) */
+ dk3sf_fputs((job->msg)[16], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[21], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 1017 "dkwxwiz.ctr"
+}
+
+
+
+
+/** Check whether character starts or continues an identifier.
+ @param c Character to process.
+ @param isfirst Flag: Is start of string.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_valid_identifier_char(char c, int isfirst)
+{
+ int back = 0;
+ if('_' == c) {
+ back = 1;
+ } else {
+ if(('a' <= c) && ('z' >= c)) {
+ back = 1;
+ } else {
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 1;
+ } else {
+ if(!(isfirst)) {
+ if('0' == c) {
+ back = 1;
+ } else {
+ if(('1' <= c) && ('9' >= c)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check ASCII string whether it contains a C/C++ identifier
+ @param job Job structure.
+ @param txt Text to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_check_ascii_c_identifier(DKWXWIZ_JOB *job, char const *txt)
+{
+ char const *cptr; /* Current character to process. */
+ int isfirst = 1; /* Flag: Is first character. */
+ int back = 1;
+
+ cptr = txt;
+ while((*cptr) && (back)) {
+ if(!dkwxwiz_valid_identifier_char(*cptr, isfirst)) {
+ back = 0;
+ }
+ isfirst = 0;
+ cptr++;
+ }
+ return back;
+}
+
+
+
+/** Check one name whether or not it is a C/C++ identifier.
+ @param job Job structure.
+ @param txt Text to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_check_one_c_identifier(DKWXWIZ_JOB *job, dkChar const *txt)
+{
+ char buf[DK3_MAX_PATH]; /* Conversion buffer. */
+ int res; /* Conversion result. */
+ int back = 0;
+
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), txt, dk3app_get_encoding(job->app), NULL
+ );
+ if(res) {
+ if(dkwxwiz_check_ascii_c_identifier(job, buf)) {
+ back = 1;
+ } else {
+ /* ERROR: Not a C/C++ identifier! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 24, 25, txt);
+ }
+ } else {
+ /* ERROR: Text is too long or contains non-ASCII characters! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 22, 23, txt);
+ }
+ return back;
+}
+
+
+
+/** Check program name, application class name, window class name.
+ @param job Job structure.
+ @return 1 on success (all names are valid C/C++ identifiers),
+ 0 on error.
+*/
+static
+int
+dkwxwiz_check_c_identifiers(DKWXWIZ_JOB *job)
+{
+ int back = 1;
+ if(!dkwxwiz_check_one_c_identifier(job, job->pName)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_c_identifier(job, job->aName)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_c_identifier(job, job->fName)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Run with known program, application and frame name.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run_with_names(DKWXWIZ_JOB *job)
+{
+
+
+#line 1148 "dkwxwiz.ctr"
+ if(dkwxwiz_build_file_names(job)) {
+ if(dkwxwiz_check_filenames(job)) {
+ if(dkwxwiz_check_c_identifiers(job)) {
+ dkwxwiz_produce_output(job);
+ }
+ }
+ }
+ dk3_release(job->ffn);
+ dk3_release(job->afn);
+ dk3_release(job->pfn);
+ dk3_release(job->xfn);
+ dk3_release(job->ifn);
+ dk3_release(job->rfn);
+
+
+#line 1162 "dkwxwiz.ctr"
+}
+
+
+
+/** Run the program normally (no help/version/license).
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run_normally(DKWXWIZ_JOB *job)
+{
+ int nargs; /* Number of command line arguments. */
+
+
+#line 1175 "dkwxwiz.ctr"
+ nargs = dk3opt_get_num_args(job->opt);
+ if(3 <= nargs) {
+ job->pName = dk3opt_get_arg(job->opt, 0);
+ job->aName = dk3opt_get_arg(job->opt, 1);
+ job->fName = dk3opt_get_arg(job->opt, 2);
+ if((job->pName) && (job->aName) && (job->fName)) {
+ if(dk3opt_is_set(job->opt, dkT('f'))) {
+ job->frc = 1;
+ }
+ if(dk3opt_is_set(job->opt, dkT('o'))) {
+ job->obj = 1;
+ }
+ job->con = dk3opt_get_short_arg(job->opt, dkT('c'));
+ job->lin = dk3opt_get_short_arg(job->opt, dkT('l'));
+ dkwxwiz_run_with_names(job);
+ } else {
+ /* ERROR: Too few arguments. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+ } else {
+ /* ERROR: Too few arguments. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+
+#line 1200 "dkwxwiz.ctr"
+}
+
+
+
+/** Run the program.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run(DKWXWIZ_JOB *job)
+{
+ dkChar const * const *sptr; /* Pointer to traverse text. */
+
+
+#line 1213 "dkwxwiz.ctr"
+ job->opt = dk3opt_open_from_app(
+ dkwxwiz_options,
+ dkwxwiz_sz_options,
+ 0x00,
+ NULL,
+ job->app
+ );
+ if(job->opt) {
+ if(dk3opt_get_error_code(job->opt) == 0) {
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= DKWXWIZ_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= DKWXWIZ_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= DKWXWIZ_CMD_LICENSE;
+ }
+ if(job->cmd) {
+ /* Version.
+ */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkwxwiz_msg[0], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs( DKT_VERSION_DK , stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Help text.
+ */
+ if(DKWXWIZ_CMD_HELP & (job->cmd)) {
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+ /* License.
+ */
+ if(DKWXWIZ_CMD_LICENSE & (job->cmd)) {
+ sptr = dkwxwiz_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } else {
+ dkwxwiz_run_normally(job);
+ }
+ }
+ dk3opt_close(job->opt);
+ job->opt = NULL;
+ }
+
+#line 1260 "dkwxwiz.ctr"
+}
+
+
+
+/** Program entry point.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ DKWXWIZ_JOB job; /* Job structure. */
+ dk3_app_t *app = NULL; /* Application structure. */
+ dkChar const * const *msg = NULL; /* Localized messages. */
+ int exval; /* No success yet. */
+
+
+
+#line 1277 "dkwxwiz.ctr"
+
+
+#line 1278 "dkwxwiz.ctr"
+#if DK3_HAVE_TZSET
+ tzset();
+#endif
+ job.exv = 1;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkwxwiz_msg[1]
+ );
+ if(app) {
+ msg = dk3app_messages(app, dkwxwiz_msg[2], (dkChar const **)dkwxwiz_msg);
+ dkwxwiz_job_init(&job, app, msg);
+ dkwxwiz_run(&job);
+ dk3app_close(app);
+ } else {
+ fputs("dkwxwiz: ERROR: Not enough memory!\n", stderr);
+ fflush(stderr);
+ }
+ exval = job.exv;
+
+
+#line 1296 "dkwxwiz.ctr"
+
+
+#line 1297 "dkwxwiz.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+