%% options copyright owner = Dirk Krause copyright year = 2017-xxxx SPDX-License-Identifier: BSD-3-Clause %% header #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #if DK4_HAVE_MATH_H #ifndef MATH_H_INCLUDED #define _USE_MATH_DEFINES #include #define MATH_H_INCLUDED 1 #endif #endif #ifndef DK4TYPES_H_INCLUDED #include "dk4types.h" #endif #ifndef DK4NUMCO_H_INCLUDED #include "dk4numco.h" #endif #ifndef DK4MEM_H_INCLUDED #include "dk4mem.h" #endif #ifndef DK4STR8_H_INCLUDED #include "dk4str8.h" #endif #ifndef DK4STRD_H_INCLUDED #include "dk4strd.h" #endif #ifndef DK4REC27_H_INCLUDED #include "dk4rec27.h" #endif #ifndef DK4VERS_H_INCLUDED #include "dk4vers.h" #endif #ifndef DK4MATH_H_INCLUDED #include "dk4math.h" #endif #ifndef DK4ITER_H_INCLUDED #include "dk4iter.h" #endif #ifndef DK4MAAI32_H_INCLUDED #include "dk4maai32.h" #endif #ifndef DK4MAADI_H_INCLUDED #include "dk4maadi.h" #endif #ifndef DK4MAASZ_H_INCLUDED #include "dk4maasz.h" #endif #ifndef DK4MAI8DBL_H_INCLUDED #include "dk4mai8dbl.h" #endif #ifndef DK4MAIDDBL_H_INCLUDED #include "dk4maiddbl.h" #endif #ifndef DK4MAI8DU8_H_INCLUDED #include "dk4mai8du8.h" #endif #ifndef DK4MAI8DI8_H_INCLUDED #include "dk4mai8di8.h" #endif #ifndef DK4MAI8DU16_H_INCLUDED #include "dk4mai8du16.h" #endif #ifndef DK4MAI8DI16_H_INCLUDED #include "dk4mai8di16.h" #endif #ifndef DK4MAI8DU32_H_INCLUDED #include "dk4mai8du32.h" #endif #ifndef DK4MAI8DI32_H_INCLUDED #include "dk4mai8di32.h" #endif #ifndef DK4APP_H_INCLUDED #include "dk4app.h" #endif #ifndef DK4AOPT_H_INCLUDED #include "dk4aopt.h" #endif #ifndef DK4XSP_H_INCLUDED #include "dk4xsp.h" #endif #ifndef DK4UC2LA_H_INCLUDED #include "dk4uc2la.h" #endif #ifndef DK4GRCO_H_INCLUDED #include "dk4grco.h" #endif #ifndef DK4GRCOA_H_INCLUDED #include "dk4grcoa.h" #endif #ifndef DK4BIF_H_INCLUDED #include "dk4bif.h" #endif #ifndef DK4BIFAP_H_INCLUDED #include "dk4bifap.h" #endif #ifndef DK4GRA_H_INCLUDED #include "dk4gra.h" #endif #ifndef DK4GRAT_H_INCLUDED #include "dk4grat.h" #endif #ifndef DK4FILED_H_INCLUDED #include "dk4filed.h" #endif #ifndef DK4PATHD_H_INCLUDED #include "dk4pathd.h" #endif #ifndef DK4DIR_H_INCLUDED #include "dk4dir.h" #endif #ifndef DK4DIRA_H_INCLUDED #include "dk4dira.h" #endif #ifndef DK4FOPDA_H_INCLUDED #include "dk4fopda.h" #endif #ifndef DK4STO_H_INCLUDED #include "dk4sto.h" #endif #ifndef DK4CS_H_INCLUDED #include "dk4cs.h" #endif #ifndef DK4MPL_H_INCLUDED #include "dk4mpl.h" #endif #ifndef DK4MM_H_INCLUDED #include "dk4mm.h" #endif #ifndef DK4FPUT_H_INCLUDED #include "dk4fput.h" #endif #ifndef DK4PPPT_H_INCLUDED #include "dk4pppt.h" #endif #ifndef DK4UNUSED_H_INCLUDED #include "dk4unused.h" #endif #ifndef WXDTYPES_H_INCLUDED #include "wxdtypes.h" #endif #ifndef WXDENUM_H_INCLUDED #include "wxdenum.h" #endif /** Conversion job structure. */ typedef struct { dk4_gra_conf_t grco; /**< Graphics conversion options. */ dk4_pppt_t *ppp; /**< Output structure. */ dkChar *fnb; /**< File name buffer. */ dkChar *fno1; /**< Output file name 1. */ dkChar *fno2; /**< Output file name 2. */ dk4_app_t *app; /**< Application structure. */ dk4_uc2l_t *uc2l; /**< Unicode to LaTeX structure. */ const dkChar * const *msg; /**< Localized or default texts. */ double baselw; /**< Base line width in bp. */ double patlw; /**< Pattern line width in bp. */ double shiftx; /**< X shift value. */ double shifty; /**< Y shift value. */ double xsprec; /**< Precision X-spl iteration. */ double xslprec; /**< Precision length iteration. */ size_t szwidth; /**< Width in bp. */ size_t szheight; /**< Height in bp. */ size_t sz_msg; /**< Number of texts in msg. */ size_t szfnb; /**< Size of file name buffer. */ int exval; /**< Exit status code. */ int make; /**< Flag: Behave like make. */ int use_prefs; /**< Flag: Use preferences. */ int whitebg; /**< Flag: White background. */ } wxd2lat_job_t; #ifndef F2LLIC_H_INCLUDED #include "w2llic.h" #endif #ifndef WXDSTR_H_INCLUDED #include "wxdstr.h" #endif #ifndef WXDCOMP_H_INCLUDED #include "wxdcomp.h" #endif #ifndef WXDOBJ_H_INCLUDED #include "wxdobj.h" #endif #ifndef WXDRD_H_INCLUDED #include "wxdrd.h" #endif #ifndef WXD2LAH_H_INCLUDED #include "wxd2lah.h" #endif #ifndef WXD2LXS_H_INCLUDED #include "wxd2lxs.h" #endif #ifndef WXDARC_H_INCLUDED #include "wxdarc.h" #endif #ifndef WXD2LOUT_H_INCLUDED #include "wxd2lout.h" #endif /** Output types. */ enum { /** PGF instructions. */ OUTPUT_PGF = 0 , /** PDF+TeX file pair. */ OUTPUT_PDF , /** EPS+TeX file pair. */ OUTPUT_EPS }; /* vim: set ai sw=4 ts=4 : */ %% module #ifndef FIG2LAT_H_INCLUDED #include "wxd2lat.h" #endif #ifndef DK4GETCWDD_H_INCLUDED #include "dk4getcwdd.h" #endif #ifndef DK4CHDIRD_H_INCLUDED #include "dk4chdird.h" #endif #ifndef DK4UNUSED_H_INCLUDED #include "dk4unused.h" #endif #ifndef DK4WMAIN_H_INCLUDED #include "dk4wmain.h" #endif $!trace-include /** Default help text, shown if help text file is not found. */ static const dkChar * const wxd2lat_help_text[] = { $!text macro=dkT Convert *.wxd to PDF+TeX/EPS+TeX/PGF wxd2lat -l ,=... [-d] [-m] Driver: eps EPS+TeX file pair. pdf PDF+TeX file pair. tex TeX file containing PGF graphics instructions. Options: -d Produce document instead of object. -m Check file modification times when processing directories. -b Base line width in bp, pt, mm, cm or in. -p Pattern line width in bp, pt, mm, cm or in. -w Explicitly create white background. --help Show this short help text. --version Show version information. --manual *** SHOW FULL MANUAL. *** --license Show license information. $!end }; #if 0 /** Output language names. */ static const dkChar * const output_language_names[] = { $!string-table macro=dkT pgf pdf eps $!end }; #endif /** Constant text fragments, not localized. */ static const dkChar * const wxd2lat_kwnl[] = { $!string-table macro=dkT # # 0 Program group name # dktools # # 1 Help file name (full manual) # wxd2lat.txt # # 2 String table file name # wxd2lat.str # # 3 File name suffix for files to process # .wxd # # 4 File name suffix for tex output file # .tex # # 5 File name suffix for pdf output file # .pdf # # 6 File name suffix for pdf include file # -i.pdf # # 7 File name suffix for eps output file # .eps # # 8 File name suffix for pgf output file # .pgf # # 9 Dot to mark current directory # . # # # $!end }; /** Text fragments, replaced by localized versions if available. */ static const dkChar * const wxd2lat_kw_def[] = { $!string-table macro=dkT # # 0 Newline # \n # # 1-2 Signal handling # Failed to set up signal handlers! Failed to restore signal handlers! # # 3 Info: Destination files are up to date. # Destination files are up to date. # # 4 Error: Not a wxd file! # Not a wxd file! # # 5 Progress: Start processing directory. # Start processing directory. # # 6 Progress: Finished processing directory. # Finished processing directory. # # 7 Error: Failed to chdir into directory! # Failed to chdir into directory! # # 8 Error: Failed to find current directory! # Failed to find current directory! # # 9 Progress: Destination files are up to date. # Destination files are up to date. # # 10 Progress: Skipping non-wxd file. # Skipping non-wxd file. # # 11 Error: Failed to construct full path name! # Failed to construct full path name! # # 12 Error: Failed to change back to original directory! # Failed to change back to original directory! # # 13 Error: Failed to construct absolute path! # Failed to construct absolute path! # # 14 Error: Not a regular file! # Not a regular file! # # 15 Error: No such file! # No such file! # # 16 Progress: Start processing file name pattern. # Start processing file name pattern. # # 17 Progress: Finished processing file name pattern. # Finished processing file name pattern. # # 18 19 Error: Unknown unit name! # Unknown unit name " "! # # 20 21 Error: Failed to read number! # Failed to read number from " "! # # 22 23 Error: Not a floating point number # Syntax, not a floating point number: " "! # # 24 Error: Positive length required for arrowhead! # Positive length required for arrowhead! # # 25 Error: Positive width required for arrowhead! # Positive width required for arrowhead! # # 26 Error: Positive length and width required for arrowhead! # Positive length and width required for arrowhead! # # 27 Error: Positive line width required for arrowhead! # Positive line width required for arrowhead! # # 28 Error: Failed to calculate arrowhead angle! # Failed to calculate arrowhead angle! # # 29 Error: Illegal arrow type! # Illegal arrow type! # # 30 Error: Mathematical overflow in arrow calculation! # Mathematical overflow in arrow calculation! # # 31 Error: Iteration failed in arrow calculation! # Iteration failed in arrow calculation! # # 32 Error: Memory allocation failed in arrow calculation! # Memory allocation failed in arrow calculation! # # 33 Error: Failed to calculate number of points for arrow! # Failed to calculate number of points for arrow! # # 34 Error: Mathematical error in arrow calculation! # Mathematical error in arrow calculation! # # 35 Error: Arrowhead calculation on spline failed! # Arrowhead calculation on spline failed! # # 36 Error: Mathematical overflow in width/height calculation # Mathematical overflow in width/height calculation! # # 37 Error: File name too long! # File name too long! # # 38 Error: Failed to clip region! # Failed to clip region! # # 39 Error: X-spline calculation failed! # X-spline calculation failed! # # 40 Error: Failed to write text! # Failed to write text! # # 41 Error: Failed to set fill colour! # Failed to set fill colour! # # 42 Error: UTF-8 decoding failed! # UTF-8 decoding failed! # # 43 Error: Failed to create graphics object! # Failed to create graphics object! # # 44 Error: Failed to create forward arrowhead! # Failed to create forward arrowhead! # # 45 Error: Failed to create backward arrowhead! # Failed to create backward arrowhead! # # 46 Info: Line width 0, skipping object. # Line width 0, skipping object. # # 47 Error: Failed to create filled circle! # Failed to create filled circle! # # 48 Error: Failed to set up filling! # Failed to set up filling! # # 49 Error: Failed to set up filling and stroking! # Failed to set up filling and stroking! # # 50 Error: Failed to stroke path! # Failed to stroke path! # # 51 Error: Failed to set up stroking! # Failed to set up stroking! # # 52 Error: Failed to add bitmap image! # Failed to add bitmap image! # # 53 Error: Not a supported bitmap image type! # Not a supported bitmap image type! # # 54 Error: Failed to UTF-8 decode file name! # Failed to UTF-8 decode file name! # # 55 Error: Font size 0! # Font size 0! # # 56 Error: No text available! # No text available! # # 57 Error: First segment too short for arrowhead! # First segment too short for arrowhead! # # 58 Error: Final segment too short for arrowhead! # Final segment too short for arrowhead! # # 59 Error: Too few points! # Too few points! # # 60 Error: No points for object! # No points for object! # # 61 Error: Spline too short for arrowheads! # Spline too short for arrowheads! # # 62 Error: Forward arrowhead too long! # Forward arrowhead too long! # # 63 Error: Backward arrowhead too long! # Backward arrowhead too long! # # 64 Error: Arc too short for arrowheads! # Arc too short for arrowheads! # # 65 Error: Radius must not be 0! # Radius must not be 0! # # 66 Error: Box radius too large! # Box radius too large! # # 67 Error: Diameter must not be 0! # Diameter must not be 0! # # 68 Error: Positive width and height required! # Positive width and height required! # # 69 Error: File name for image required! # File name for image required! # # 70 Error: Illegal object type! # Illegal object type! # # 71 Error: Object check failed! # Object check failed! # # 72 Error: Failed to write graphics object! # Failed to write graphics object! # # 73 Error: Forward arrowhead calculation failed! # Forward arrowhead calculation failed! # # 74 Error: Backward arrowhead calculation failed! # Backward arrowhead calculation failed! # # 75 Error: Spline segment calculation failed! # Spline segment calculation failed! # # 76 Error: Failed to open output file(s)! # Failed to open output file(s)! # # 77 Error: Failed to write output! # Failed to write output! # # 78 Error: Skipping output due to previous errors! # Skipping output due to previous errors! # # 79 Error: Segment length calculation failed! # Segment length calculation failed! # # 80 Error: Cut calculation for arrowhead failed! # Cut calculation for arrowhead failed! # # 81 Error: Memory allocation failed! # Memory allocation failed! # # 82 83 Error: Not an 8-bit unsigned number! # Not an 8-bit unsigned number: " "! # # 84 85 Error: Not an 8-bit number! # Not an 8-bit number: " "! # # 86 87 Error: Not a 16-bit unsigned number! # Not a 16-bit unsigned number: " "! # # 88 89 Error: Not a 16-bit number! # Not a 16-bit number: " "! # # 90 91 Error: Not a 32-bit unsigned number! # Not a 32-bit unsigned number: " "! # # 92 93 Error: Not a 32-bit number! # Not a 32-bit number: " "! # # 94 Warning: File format version newer than reader module! # File format version newer than reader module! # # 95 Error: Illegal bounding box! # Syntax, bounding box width or height is 0! # # 96 Error: Invalid number of texts in line! # Syntax, invalid number of texts in line! # # 97 Error: Base line width must be positive! # Syntax, base line width must be positive! # # 98 Error: Too few numbers in line! # Syntax, too few numbers in line! # # 99 Warning: Line style corrected. # Syntax, line style corrected. # # 100 Warning: Style length corrected. # Syntax, style length corrected. # # 101 Warning: Cap style corrected. # Syntax, cap style corrected. # # 102 Warning: Join style corrected. # Syntax, join style corrected. # # 103 Warning: Miter limit corrected. # Syntax, miter limit corrected. # # 104 105 Warning: Arrow type corrected. # Syntax, forward arrow type corrected. Syntax, backward arrow type corrected. # # 106 107 Warning: Arrow length corrected. # Syntax, forward arrow length corrected. Syntax, backward arrow length corrected. # # 108 109 Warning: Arrow width corrected. # Syntax, forward arrow width corrected. Syntax, backward arrow width corrected. # # 110 Warning: Fill style corrected. # Syntax, fill style corrected. # # 111 Error: Closing too many groups! # Syntax, closing too many groups! # # 112 Error: Opening too many groups! # Syntax, opening too many groups! # # 113 Warning: Skipping object! # Skipping object! # # 114 Error: Illegal object type! # Syntax, illegal object type! # # 115 Error: Missing object type! # Syntax, missing object type! # # 116 Warning: Font index corrected. # Syntax, font index corrected. # # 117 Warning: Text align corrected. # Syntax, text align corrected. # # 118 Warning: s parameter corrected. # Syntax, s parameter corrected. # # 119 Warning: Radius corrected. # Syntax, radius corrected. # # 120 Warning: Very small radius. # Syntax, very small radius. # # 121 Warning: RGB to gray conversion method corrected. # Syntax, RGB to gray conversion method corrected. # # 122 Error: Invalid image dimensions! # Syntax, invalid image dimensions! # # 123 Warning: Dot diameter corrected. # Syntax, dot diameter corrected. # # 124 Warning: Dot line width corrected. # Syntax, dot line width corrected. # # 125 Error: Empty export text! # Syntax, empty export text! # # 126 Error: Empty file name! # Syntax, empty file name! # # 127 Error: Object start line expected! # Syntax, object start line expected! # # 128 Error: Details line expected! # Syntax, details line expected! # # 129 Warning: Screen text expected! # Syntax, screen text expected! # # 130 Error: Unexpected end of file! # Syntax, unexpected end of file! $!end }; /** Unit names usable in base line width specifications. */ static const dkChar *unit_names[] = { $!string-table macro=dkT bp pt mm cm in inch inches mil um $!end }; /** Options to use with the program. */ static const dk4_option_specification_t wxd2lat_options[] = { /* Output language: tex (PGF), pdf (PDF+TeX), eps (EPS+TeX). */ { dkT('l'), dkT("language"), DK4_OPT_ARG_STRING }, /* Make mode, only convert if necessary. */ { dkT('m'), dkT("make"), DK4_OPT_ARG_NONE }, /* Reset (do not use configuration files or preferences). */ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE }, /* Produce document instead of object. */ { dkT('d'), dkT("document"), DK4_OPT_ARG_NONE }, /* Base line width. */ { dkT('b'), dkT("base-linewidth"), DK4_OPT_ARG_STRING }, /* Line width for pattern drawing (default: base linewidth). */ { dkT('p'), dkT("pattern-linewidth"), DK4_OPT_ARG_STRING }, { dkT('w'), dkT("white-background"), DK4_OPT_ARG_NONE } }; /** Number of options in wxd2lat_options array. */ static const size_t sz_wxd2lat_options = sizeof(wxd2lat_options) / sizeof(dk4_option_specification_t); #ifdef SIGPIPE /** Indicator: SIGPIPE signal received. */ static DK4_VOLATILE dk4_sig_atomic_t sig_had_pipe = 0; #endif /** Indicator: SIGINT signal received. */ static DK4_VOLATILE dk4_sig_atomic_t sig_had_int = 0; /** Indicator: SIGTERM signal received. */ static DK4_VOLATILE dk4_sig_atomic_t sig_had_term = 0; /** Pass a volatile pointer to an atomic integer. This function is necessary as some compilers mis-optimize direct access to volatile variables (at least if you believe one of the coding standards). @param ptr Address of atomic integer variable. @return The unmodified pointer. */ static DK4_VOLATILE dk4_sig_atomic_t * sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr) { return ptr; } #ifdef SIGPIPE /** Handler for SIGPIPE signal. @param signo Signal number (always SIGPIPE, ignored). */ static void sig_handler_pipe(int DK4_ARG_UNUSED(signo) ) { DK4_UNUSED_ARG(signo) *sig_pass_pointer(&sig_had_pipe) = 1; } #endif /** Handler for SIGINT signal. @param signo Signal number (always SIGINT, ignored). */ static void sig_handler_int(int DK4_ARG_UNUSED(signo) ) { DK4_UNUSED_ARG(signo) *sig_pass_pointer(&sig_had_int) = 1; } /** Handler for SIGTERM signal. @param signo Signal number (always SIGTERM, ignored). */ static void sig_handler_term(int DK4_ARG_UNUSED(signo) ) { DK4_UNUSED_ARG(signo) *sig_pass_pointer(&sig_had_term) = 1; } /** Read value from volatile atomic type. This function is necessary as some compilers mis-optimize direct access to volatile variables (at least if you believe one of the coding standards). @param ap Pointer to volatile atomic variable. @return Contents of the variable. */ static dk4_sig_atomic_t sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap) { return (*ap); } /** Check whether we can continue or if a signal was received. @param check_pipe Flag: Check for occured SIGPIPE signal too. @return 1 if the program can continue, 0 if a signal was received. */ static int sig_can_continue( #ifdef SIGPIPE int check_pipe #else int DK4_ARG_UNUSED(check_pipe) #endif ) { int back = 1; #ifndef SIGPIPE DK4_UNUSED_ARG(check_pipe) #else if (0 != check_pipe) { if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; } } #endif if (0 != sig_read_atomic(&sig_had_int )) { back = 0; } if (0 != sig_read_atomic(&sig_had_term)) { back = 0; } return back; } /** Initialize job structure at start of program. @param job Structure to initialize. */ static void job_init(wxd2lat_job_t *job) { dk4gra_conf_init(&(job->grco)); job->ppp = NULL; job->app = NULL; job->msg = wxd2lat_kw_def; job->sz_msg = (sizeof(wxd2lat_kw_def)/sizeof(DK4_PDKCHAR) - 1); job->exval = EXIT_FAILURE; job->make = 0; job->uc2l = NULL; job->baselw = -1.0; /* Use default from file or 0.45bp */ job->patlw = -1.0; /* Use default */ job->xsprec = 1.0 / 512.0; job->xslprec = job->xsprec / 4.0; job->use_prefs = 1; job->fnb = NULL; job->fno1 = NULL; job->fno2 = NULL; job->szfnb = 0; job->whitebg = 0; job->szwidth = 0; job->szheight = 0; job->shiftx = 0.0; job->shifty = 0.0; } /** Check whether the file name ends on wxd. @param filename File name to check. @return 1 on success, 0 on error. */ static int is_wxd_file(const dkChar *filename) { const dkChar *ptr; int back = 0; $? "+ is_wxd_file \"%!ds\"", filename if (NULL != filename) { ptr = dk4path_get_suffix(filename, NULL); if (NULL != ptr) { $? ". ptr = \"%!ds\"", ptr if (0 == dk4str_casecmp(ptr, wxd2lat_kwnl[3])) { back = 1; } } } $? "- is_wxd_file %d", back return back; } /** Check whether we must produce one output file. @param fno Buffer for output file name, containing base name. @param szfno Size of fno buffer. @param fn Source file name. @param su Suffix to add to buffer. @return 1 to run conversion, 0 to skip. */ static int check_one(dkChar *fno, size_t szfno, const dkChar *fn, const dkChar *su) { int back = 1; $? "+ check_one" if (0 != dk4str_cat_s(fno, szfno, su, NULL)) { $? ". source file \"%!ds\"", fn $? ". destination file \"%!ds\"", fno back = dk4makemode_must_rebuild(fno, fn); } $? "- check_one %d", back return back; } /** Check whether we really must run a conversion. @param job Job structure. @param fn Source file name. @return 1 to run conversion, 0 to skip. */ static int check_make(wxd2lat_job_t *job, const dkChar *fn) { dkChar *pso = NULL; int back = 1; int res = 0; $? "+ check_make \"%!ds\"", fn if (0 != job->make) { if (0 != dk4str_cpy_s(job->fno1, job->szfnb, fn, NULL)) { if (0 != dk4str_cpy_s(job->fno2, job->szfnb, fn, NULL)) { pso = dk4path_get_suffix(job->fno1, NULL); if (NULL != pso) { *pso = dkT('\0'); } pso = dk4path_get_suffix(job->fno2, NULL); if (NULL != pso) { *pso = dkT('\0'); } switch (job->grco.driver) { case DK4_GRA_DRIVER_PGF : { back = check_one( job->fno1, job->szfnb, fn, wxd2lat_kwnl[8] ); } break; case DK4_GRA_DRIVER_PS: case DK4_GRA_DRIVER_EPS : { res = check_one( job->fno1, job->szfnb, fn, wxd2lat_kwnl[7] ); if (0 == res) { back = check_one( job->fno2, job->szfnb, fn, wxd2lat_kwnl[4] ); } } break; case DK4_GRA_DRIVER_PDF : { res = check_one( job->fno1, job->szfnb, fn, wxd2lat_kwnl[ (DK4_GRA_PURPOSE_DOCUMENT == job->grco.purpose) ? (6) : (5) ] ); if (0 == res) { back = check_one( job->fno2, job->szfnb, fn, wxd2lat_kwnl[4] ); } } break; } } } } $? "- check_make %d", back return back; } /** Process one regular file. @param job Job structure. @param xargv Name of file to process. */ static void process_one_file(wxd2lat_job_t *job, const dkChar *xargv) { wxd_drawing_t *drw = NULL; /* Drawing to convert */ const dkChar *osf = NULL; /* Original source file */ dk4_um_t osl = 0UL; /* Original source line */ $? "+ process_one_file \"%!ds\"", xargv osf = dk4app_get_log_source_file(job->app); osl = dk4app_get_log_source_line(job->app); dk4app_set_log_source_file(job->app, xargv); dk4app_set_log_source_line(job->app, 0UL); if (0 != is_wxd_file(xargv)) { if (0 != check_make(job, xargv)) { drw = wxdrd_open_from_file(xargv,job); if (NULL != drw) { $? ". success, have structure" wxd2lat_output(drw, job, xargv); wxdrd_close(drw); } else { /* ERROR: Failed to read drawing, already reported */ job->exval = EXIT_FAILURE; } } else { /* INFO: Destination files up to date */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_INFO, 3); } } else { /* ERROR: Not a wxd file */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 4); job->exval = EXIT_FAILURE; } dk4app_set_log_source_file(job->app, osf); dk4app_set_log_source_line(job->app, osl); $? "- process_one_file" } #if 0 /** Process a directory. @param job Job structure. @param xargv Directory name. @param docd Flag: chdir to specified directory. */ static void process_one_directory(wxd2lat_job_t *job, const dkChar *xargv, int docd) { dkChar cdbuf[DK4_MAX_PATH]; /* Current directory */ dk4_er_t er; /* Error report */ dk4_dir_t *dir = NULL; /* Directory structure */ const dkChar *osf = NULL; /* Original source file */ const dkChar *shn = NULL; /* Short file name */ dk4_um_t osl = 0UL; /* Original source line */ int cc = 1; /* Flag: Can continue */ int res = 0; /* Operation result */ int canrun = 1; /* Flag: Can run */ $? "+ process_one_directory \"%!ds\"", xargv osf = dk4app_get_log_source_file(job->app); osl = dk4app_get_log_source_line(job->app); dk4app_set_log_source_file(job->app, xargv); dk4app_set_log_source_line(job->app, 0UL); /* PROGRESS: Start processing directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 5); dk4error_init(&er); if (0 != docd) { canrun = 0; if (0 != dk4getcwd(cdbuf, DK4_SIZEOF(cdbuf,dkChar), &er)) { #if 0 if (0 != dk4chdir(xargv, &er)) { canrun = 1; } else { /* ##### ERROR: Failed to change directory */ job->exval = EXIT_FAILURE; } #endif } else { /* ##### ERROR: Failed to find current directory */ job->exval = EXIT_FAILURE; } } if (0 != canrun) { dir = dk4dir_open_app(xargv, DK4_DIR_OPEN_SORTED, job->app); if (NULL != dir) { while ((1 == cc) && (0 != sig_can_continue(0))) { shn = dk4dir_next_file(dir); if (NULL != shn) { dk4error_init(&er); res = dk4dir_full_name_buffer( job->fnb, job->szfnb, dir, shn, &er ); if (0 != res) { if (0 != is_wxd_file(job->fnb)) { if (0 != check_make(job, job->fnb)) { process_one_file(job, job->fnb); } else { /* ##### PROGRESS: Destination files up to date */ } } else { /* ##### PROGRESS: Skipping non-wxd file */ } } else { cc = 0; job->exval = EXIT_FAILURE; /* ##### ERROR: Failed to construct full path name */ } } else { cc = 0; } } dk4dir_close(dir); } else { job->exval = EXIT_FAILURE; } } if (0 != docd) { if (0 == dk4chdir(cdbuf, &er)) { /* ##### ERROR: Failed to return to directory */ job->exval = EXIT_FAILURE; } } /* PROGRESS: Finished processing directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 6); dk4app_set_log_source_file(job->app, osf); dk4app_set_log_source_line(job->app, osl); $? "- process_one_directory" } #endif /** Process a directory specified by absolute path. @param job Job structure. @param xargv Directory name. @param docd Flag: chdir to specified directory. */ static void process_absolute_directory(wxd2lat_job_t *job, const dkChar *dn, int docd) { dk4_er_t er; /* Error report */ dkChar *cdbuf = NULL; /* Current directory */ dk4_dir_t *dir = NULL; /* Directory structure */ const dkChar *osf = NULL; /* Original source file */ const dkChar *shn = NULL; /* Short file name */ dk4_um_t osl = 0UL; /* Original source line */ int canrun = 1; /* Flag: Can run */ int cc = 1; /* Flag: Can continue */ int res = 0; /* Operation result */ $? "+ process_absolute_directory" osf = dk4app_get_log_source_file(job->app); osl = dk4app_get_log_source_line(job->app); dk4app_set_log_source_file(job->app, dn); dk4app_set_log_source_line(job->app, 0UL); /* PROGRESS: Start processing directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 5); if (0 != docd) { cdbuf = dk4getcwd_dup(NULL); if (NULL != cdbuf) { if (0 == dk4chdir(dn, NULL)) { /* ERROR: Failed to change into directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 7); job->exval = EXIT_FAILURE; canrun = 0; } } else { /* ERROR: Failed to find current directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 8); job->exval = EXIT_FAILURE; canrun = 0; } } if (0 != canrun) { dir = dk4dir_open_app(dn, DK4_DIR_OPEN_SORTED, job->app); if (NULL != dir) { while ((1 == cc) && (0 != sig_can_continue(0))) { shn = dk4dir_next_file(dir); if (NULL != shn) { dk4error_init(&er); res = dk4dir_full_name_buffer( job->fnb, job->szfnb, dir, shn, &er ); if (0 != res) { if (0 != is_wxd_file(job->fnb)) { if (0 != check_make(job, job->fnb)) { process_one_file(job, job->fnb); } else { /* PROGRESS: Destination files are up to date */ dk4app_log_1( job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 9 ); } } else { /* PROGRESS: Skipping non-wxd file */ dk4app_log_1( job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 10 ); } } else { cc = 0; job->exval = EXIT_FAILURE; /* ERROR: Failed to construct full path name */ dk4app_log_1( job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 11 ); } } else { cc = 0; } } dk4dir_close(dir); } else { job->exval = EXIT_FAILURE; } } if (NULL != cdbuf) { if (docd) { if (0 == dk4chdir(cdbuf, NULL)) { /* ERROR: Failed to change back to original directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 12); job->exval = EXIT_FAILURE; } } dk4mem_free(cdbuf); cdbuf = NULL; } /* PROGRESS: Finished processing directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 6); dk4app_set_log_source_file(job->app, osf); dk4app_set_log_source_line(job->app, osl); $? "- process_absolute_directory" } /** Process a directory specified by relative path. @param job Job structure. @param xargv Directory name. @param docd Flag: chdir to specified directory. */ static void process_relative_directory(wxd2lat_job_t *job, const dkChar *dn, int docd) { dkChar cdbuf[DK4_MAX_PATH]; if (0 != dk4getcwd(cdbuf, DK4_SIZEOF(cdbuf,dkChar), NULL)) { if (0 != dk4path_append(cdbuf, DK4_SIZEOF(cdbuf,dkChar), dn, NULL)) { process_absolute_directory(job, cdbuf, docd); } else { /* ERROR: Failed to construct absolute path */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 13); job->exval = EXIT_FAILURE; } } else { /* ERROR: Failed to find current working directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 8); job->exval = EXIT_FAILURE; } } /** Process a directory. @param job Job structure. @param xargv Directory name. @param docd Flag: chdir to specified directory. */ static void process_one_directory(wxd2lat_job_t *job, const dkChar *dn, int docd) { if (0 != dk4path_is_absolute(dn)) { process_absolute_directory(job, dn, docd); } else { process_relative_directory(job, dn, docd); } } /** Process one command line argument. @param job Job structure. @param xargv Command line argument to process. */ static void process_one_name(wxd2lat_job_t *job, const dkChar *xargv) { const dkChar *osf = NULL; /* Original source file */ dk4_um_t osl = 0UL; /* Original source line */ $? "+ process_one_name \"%!ds\"", xargv osf = dk4app_get_log_source_file(job->app); osl = dk4app_get_log_source_line(job->app); dk4app_set_log_source_file(job->app, xargv); dk4app_set_log_source_line(job->app, 0UL); if (0 != dk4file_is_directory(xargv, NULL)) { $? ". directory" process_one_directory(job, xargv, 1); } else { if (0 != dk4file_is_regular(xargv, NULL)) { $? ". file" process_one_file(job, xargv); } else { if (0 != dk4file_exists(xargv, NULL)) { $? "! not regular" /* ERROR: Not a reglar file */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 14); } else { $? "! not exist" /* ERROR: No such file */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 15); } job->exval = EXIT_FAILURE; } } dk4app_set_log_source_file(job->app, osf); dk4app_set_log_source_line(job->app, osl); $? "- process_one_name" } #if DK4_ON_WINDOWS static void expand_and_process(wxd2lat_job_t *job, const dkChar *xargv) { dkChar fnb[DK4_MAX_PATH]; /* Buffer for full path name */ dk4_er_t er; /* Error report */ dk4_dir_t *fne; /* File name expander */ const dkChar *osf = NULL; /* Original source file */ const dkChar *shn = NULL; /* Short file name */ dk4_um_t osl = 0UL; /* Original source line */ int anyfound = 0; /* Flag: Any matching file found */ int cc = 1; /* Flag: Can continue */ int res = 0; /* Operation result */ $? "+ expand_and_process \"%!ds\"", xargv osf = dk4app_get_log_source_file(job->app); osl = dk4app_get_log_source_line(job->app); dk4app_set_log_source_file(job->app, xargv); dk4app_set_log_source_line(job->app, 0UL); /* PROGRESS: Start processing file name pattern */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 16); fne = dk4app_fne_open(xargv, job->app); if (NULL != fne) { cc = 1; dk4error_init(&er); while ((1 == cc) && (0 != sig_can_continue(0))) { shn = dk4dir_next_dir(fne); if (NULL != shn) { res = dk4dir_full_name_buffer( fnb, DK4_SIZEOF(fnb,dkChar), fne, shn, &er ); if (0 != res) { process_one_directory(job, fnb, 1); } else { cc = 0; job->exval = EXIT_FAILURE; /* ERROR: Failed to construct full path name */ dk4app_log_1( job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 11 ); } } else { cc = 0; } } cc = 1; while ((1 == cc) && (0 != sig_can_continue(0))) { shn = dk4dir_next_file(fne); if (NULL != shn) { res = dk4dir_full_name_buffer( fnb, DK4_SIZEOF(fnb,dkChar), fne, shn, &er ); if (0 != res) { process_one_file(job, fnb); } else { cc = 0; job->exval = EXIT_FAILURE; /* ERROR: Failed to construct full path name */ dk4app_log_1( job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 11 ); } } else { cc = 0; } } dk4dir_close(fne); if ((0 != sig_can_continue(0)) && (0 == anyfound)) { job->exval = EXIT_FAILURE; /* ERROR: No such file */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 15); } } else { job->exval = EXIT_FAILURE; } /* PROGRESS: Finished processing file name pattern */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_PROGRESS, 17); dk4app_set_log_source_file(job->app, osf); dk4app_set_log_source_line(job->app, osl); $? "- expand_and_process" } #endif static void process_current_directory(wxd2lat_job_t *job) { dkChar dnb[DK4_MAX_PATH]; if (0 != dk4getcwd(dnb, DK4_SIZEOF(dnb,dkChar), NULL)) { process_one_directory(job, dnb, 0); } else { /* ERROR: Failed to find current directory */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 8); } } /** Run for file specified on the command line. If no file on command line specified, run on current directory. @param job Job structure. */ static void process_all_input_files(wxd2lat_job_t *job) { dkChar const *xargv; /* Current cmd line arg to process */ int xargc; /* Number of command line arguments */ int i; /* Index of current cmd line arg */ $? "+ process_all_input_files" xargc = dk4app_get_argc(job->app); if (0 < xargc) { for (i = 0; ((i < xargc) && (0 != sig_can_continue(0))); i++) { xargv = dk4app_get_argv(job->app, i); if (NULL != xargv) { #if DK4_ON_WINDOWS if (0 != dk4path_must_expand(xargv)) { expand_and_process(job, xargv); } else { process_one_name(job, xargv); } #else process_one_name(job, xargv); #endif } else { } } } else { /* No names specified, process current directory */ process_current_directory(job); } $? "- process_all_input_files" } /** Get base line width from string. @param job Job structure to modify. @param src Source text. @return 1 on success, 0 on error. */ static int get_line_width_from_text(wxd2lat_job_t *job, double *dptr, dkChar const *src) { dk4_er_t er; const dkChar *ep = NULL; double v; int back = 0; int res = 0; dk4error_init(&er); $? "+ get_line_width_from_text" if ((NULL != job) && (NULL != src)) { back = dk4ma_input_dk_double(&v, src, &ep, 2, &er); if (1 == back) { if ((NULL != ep) && (0U != dk4str_len(ep))) { res = dk4str_array_index(unit_names, ep, 0); if (0 <= res) { switch (res) { case 0: { /* bp */ } break; case 1: { /* pt */ v *= (72.0 / 72.27); } break; case 2: { /* mm */ v *= (72.0 / 25.4); } break; case 3: { /* cm */ v *= (72.0 / 2.54); } break; case 4: case 5: case 6: { /* in */ v *= 72.0; } break; case 7: { /* mil */ v *= (72.0 / 1000.0); } break; case 8: { /* um */ v *= (72.0 / 25400.0); } break; } } else { $? "! illegal unit name %s", ep back = 0; /* ERROR: Unknown unit name */ dk4app_log_3( job->app, job->msg, job->sz_msg, DK4_LL_INFO, 18,19,ep ); } } } else { /* ERROR: Failed to read number */ dk4app_log_3( job->app, job->msg, job->sz_msg, DK4_LL_INFO, 20, 21, src ); } if (1 == back) { *dptr = v; } } $? "- get_line_width_from_text %d %g", back, v return back; } /** Run normally after applying signal handlers. @param job Job structure. */ static void w2l_normal_run(wxd2lat_job_t *job) { const dkChar *lpo; int ok = 1; $? "+ w2l_normal_run" if (0 != dk4app_opt_is_set_short(job->app, dkT('R'), NULL)) { job->use_prefs = 0; } if (0 != dk4app_opt_is_set_short(job->app, dkT('m'), NULL)) { job->make = 1; $? ". make mode" } if (0 != dk4app_opt_is_set_short(job->app, dkT('d'), NULL)) { (job->grco).purpose = DK4_GRA_PURPOSE_DOCUMENT; } if (0 != dk4app_opt_is_set_short(job->app, dkT('b'), NULL)) { lpo = dk4app_opt_get_string_ptr_short(job->app, dkT('b'), NULL); if (NULL != lpo) { if (0 == get_line_width_from_text(job, &(job->baselw), lpo)) { ok = 0; } } } if (0 != dk4app_opt_is_set_short(job->app, dkT('p'), NULL)) { lpo = dk4app_opt_get_string_ptr_short(job->app, dkT('p'), NULL); if (NULL != lpo) { if (0 == get_line_width_from_text(job, &(job->patlw), lpo)) { ok = 0; } } } if (0 != dk4app_opt_is_set_short(job->app, dkT('w'), NULL)) { job->whitebg = 1; } if (0 != dk4app_opt_is_set_short(job->app, dkT('l'), NULL)) { lpo = dk4app_opt_get_string_ptr_short(job->app, dkT('l'), NULL); if (NULL != lpo) { #if 0 job->ot = dk4str_array_index(output_language_names, lpo, 0); if (0 > job->ot) { $? "! illegal output language name" ok = 0; /* ##### ERROR: Illegal output language name */ } #endif ok = dk4gra_conf_setup( &(job->grco), lpo, job->use_prefs, DK4_GRA_CONF_SCOPE_FIG2LAT, job->app ); } #if TRACE_DEBUG else { $? "! no argument to -l" } #endif } if (0 != ok) { job->uc2l = dk4uc2l_open_from_app(job->app); if (NULL != job->uc2l) { job->exval = EXIT_SUCCESS; process_all_input_files(job); dk4uc2l_close(job->uc2l); job->uc2l = NULL; } else { $? "! failed to open job->uc2l" /* ERROR: No Unicode to LaTeX structure, already reported */ } } #if TRACE_DEBUG else { $? "! cannot recover from previous errors" } #endif $? "- w2l_normal_run" } #if DK4_HAVE_SIGACTION /** Set signal handlers and run. @param job Job structure. */ static void w2l_run_with_signal_handlers(wxd2lat_job_t *job) { #ifdef SIGPIPE struct sigaction opipe; #endif struct sigaction oint; #ifdef SIGPIPE struct sigaction npipe; #endif struct sigaction nint; struct sigaction oterm; struct sigaction nterm; int success = 0; #ifdef SIGPIPE /* Set up signal handling for SIGPIPE. */ DK4_MEMRES(&npipe, sizeof(npipe)); npipe.sa_handler = sig_handler_pipe; npipe.sa_flags = 0; if (0 != sigemptyset(&npipe.sa_mask)) { /* ERROR: Failed to set up masked signal set for SIGPIPE */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto finished; } if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { /* ERROR: Failed to set up masked signal set for SIGPIPE */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto finished; } if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { /* ERROR: Failed to set up signal handler for SIGPIPE */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto finished; } #endif /* Set up signal handling for SIGINT. */ DK4_MEMRES(&nint, sizeof(nint)); nint.sa_handler = sig_handler_int; nint.sa_flags = 0; if (0 != sigemptyset(&nint.sa_mask)) { /* ERROR: Failed to set up masked signal set for SIGINT */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto restore_old_pipe; } if (0 != sigaddset(&nint.sa_mask, SIGINT)) { /* ERROR: Failed to set up masked signal set for SIGINT */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto restore_old_pipe; } if (0 != sigaction(SIGINT, &nint, &oint)) { /* ERROR: Failed to set up signal handler for SIGINT */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto restore_old_pipe; } /* Set up signal handling for SIGTERM */ DK4_MEMRES(&nterm, sizeof(nterm)); nterm.sa_handler = sig_handler_term; nterm.sa_flags = 0; if (0 != sigemptyset(&nterm.sa_mask)) { /* ERROR: Failed to set up masked signal set for SIGTERM */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto restore_old_int; } if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { /* ERROR: Failed to set up masked signal set for SIGTERM */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto restore_old_int; } if (0 != sigaction(SIGTERM, &nterm, &oterm)) { /* ERROR: Failed to set up signal handler for SIGTERM */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 1); goto restore_old_int; } success = 1; w2l_normal_run(job); /* Restore signal handling for SIGTERM. */ if (0 != sigaction(SIGTERM, &oterm, NULL)) { /* ERROR: Failed to restore old SIGTERM settings */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 2); success = 0; } /* Restore signal handling for SIGINT. */ restore_old_int: if (0 != sigaction(SIGINT, &oint, NULL)) { /* ERROR: Failed to restore old SIGPIPE settings */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 2); success = 0; } #ifdef SIGPIPE /* Restore signal handling for SIGPIPE. */ restore_old_pipe: if (0 != sigaction(SIGPIPE, &opipe, NULL)) { /* ERROR: Failed to restore old SIGPIPE settings */ dk4app_log_1(job->app, job->msg, job->sz_msg, DK4_LL_ERROR, 2); success = 0; } #endif /* Set exit status code if error occured. */ finished: if (0 == success) { job->exval = EXIT_FAILURE; } } #else #if DK4_HAVE_SIGSET /** Set signal handlers and run. @param job Job structure. */ static void w2l_run_with_signal_handlers(wxd2lat_job_t *job) { #ifdef SIGPIPE dk4_sig_handler_t *oldpipe = NULL; #endif dk4_sig_handler_t *oldint = NULL; dk4_sig_handler_t *oldterm = NULL; #ifdef SIGPIPE oldpipe = sigset(SIGPIPE, sig_handler_pipe); #endif oldint = sigset(SIGINT, sig_handler_int); oldterm = sigset(SIGTERM, sig_handler_term); w2l_normal_run(job); sigset(SIGTERM, oldterm); sigset(SIGINT, oldint); #ifdef SIGPIPE sigset(SIGPIPE, oldpipe); #endif } #else #if DK4_HAVE_SIGNAL /** Set signal handlers and run. @param job Job structure. */ static void w2l_run_with_signal_handlers(wxd2lat_job_t *job) { #ifdef SIGPIPE dk4_sig_handler_t *oldpipe = NULL; #endif dk4_sig_handler_t *oldint = NULL; dk4_sig_handler_t *oldterm = NULL; #ifdef SIGPIPE oldpipe = signal(SIGPIPE, sig_handler_pipe); #endif oldint = signal(SIGINT, sig_handler_int); oldterm = signal(SIGTERM, sig_handler_term); w2l_normal_run(job); signal(SIGTERM, oldterm); signal(SIGINT, oldint); #ifdef SIGPIPE signal(SIGPIPE, oldpipe); #endif } #else /** Set signal handlers and run. */ static void w2l_run_with_signal_handlers(void) { w2l_normal_run(); } #endif #endif #endif /** Buffer for full file name. */ static dkChar wxd2lat_filename_buffer[DK4_MAX_PATH]; /** Buffer for output file name. */ static dkChar wxd2lat_filename_o1[ DK4_SIZEOF(wxd2lat_filename_buffer,dkChar) ]; /** Buffer for second output file name. */ static dkChar wxd2lat_filename_o2[ DK4_SIZEOF(wxd2lat_filename_buffer,dkChar) ]; /** Main function. @param argc Number of command line arguments. @param argv Command line arguments array. @return 0 on success, all other values indicate errors. */ #if DK4_CHAR_SIZE > 1 int wmain(int argc, wchar_t *argv[]) #else int main(int argc, char *argv[]) #endif { wxd2lat_job_t job; $!trace-init wxd2lat.deb $? "+ main" dk4fput_initialize_stderr(); job_init(&job); job.fnb = wxd2lat_filename_buffer; job.fno1 = wxd2lat_filename_o1; job.fno2 = wxd2lat_filename_o2; job.szfnb = DK4_SIZEOF(wxd2lat_filename_buffer,dkChar); job.app = dk4app_open_cmd( argc, argv, wxd2lat_options, sz_wxd2lat_options, wxd2lat_kwnl[0], DKT_VERSION_DK, wxd2lat_kwnl[1], wxd2lat_help_text, w2llic_get_text() ); if (NULL != job.app) { job.sz_msg = dk4app_string_table_size(wxd2lat_kw_def); job.msg = dk4app_string_table( job.app, wxd2lat_kwnl[2], wxd2lat_kw_def ); if (0 != dk4app_can_run_normally(job.app)) { w2l_run_with_signal_handlers(&job); } else { if (0 != dk4app_help_version_license(job.app)) { job.exval = EXIT_SUCCESS; } } dk4app_close(job.app); } else { } fflush(stderr); dk4fput_cleanup_stderr(); $? "- main %d", job.exval $!trace-end exit(job.exval); return job.exval; } /* vim: set ai sw=4 ts=4 : */