/* 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: fig2lat.ctr */ /* Copyright (C) 2012-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 fig2lat.c The fig2lat module. */ #line 209 "fig2lat.ctr" /** Test flag to show Beziervalues. */ #define FIG2LAT_TEST_BEZIER 0 #include "dk3all.h" #include "dk3bezcu.h" #include "fig2lat.h" #include "f2lud.h" #include "f2lsvg.h" #include "dk3figto.h" #if 0 #include "dkt-version.h" #endif #include "dk4vers.h" #line 230 "fig2lat.ctr" /** Keywords used by the module, not localized. */ static dkChar const * const f2l_kw[] = { /* 0 */ dkT("dktools"), /* 1 */ dkT("fig2lat.str"), /* 2 */ dkT("fig2lat.txt"), /* 3 */ dkT(".fig"), /* 4 */ dkT(".pgf"), /* 5 */ dkT(".svg"), /* 6 */ dkT(".eps"), /* 7 */ dkT(".tex"), /* 8 */ dkT(".pdf"), /* 9 */ dkT("-i.pdf"), NULL #line 278 "fig2lat.ctr" }; /** Version number. */ static dkChar const *fig2lat_version[] = { dkT("fig2lat "), DKT_VERSION_DK }; /** License conditions. */ static dkChar const * const fig2lat_license[] = { dkT(""), dkT("Copyright (c) 2013-2016, Dirk Krause"), dkT("All rights reserved."), dkT(""), dkT("Redistribution and use in source and binary forms,"), dkT("with or without modification, are permitted provided"), dkT("that the following conditions are met:"), dkT(""), dkT("* Redistributions of source code must retain the above"), dkT(" copyright notice, this list of conditions and the"), dkT(" following disclaimer."), dkT("* Redistributions in binary form must reproduce the above "), dkT(" copyright notice, this list of conditions and the following"), dkT(" disclaimer in the documentation and/or other materials"), dkT(" 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"), dkT(" products derived from this software without specific"), dkT(" prior written permission."), dkT(""), dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""), dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"), dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"), dkT("ARE DISCLAIMED."), dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"), dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES"), dkT("(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR"), dkT("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER"), dkT("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 329 "fig2lat.ctr" }; /** Default help text, shown if no help file is found. */ static dkChar const * const fig2lat_help_text[] = { dkT(""), dkT("NAME"), dkT(""), dkT("fig2lat - Fig to LaTeX conversion"), dkT(""), dkT("SYNOPSIS"), dkT(""), dkT(" fig2lat [-l ] [] [-o =]* "), dkT(""), dkT("DESCRIPTION"), dkT(""), dkT("Fig2lat converts *.fig drawings created using XFig or jFig"), dkT("to other graphics formats, mainly for use with the LaTeX typesetting"), dkT("system."), dkT(""), dkT("OPTIONS"), dkT(""), dkT("-l "), dkT(" \tDriver, one from the following:"), dkT(""), dkT("\tDrivers to use a Fig file with latex or pdflatex:"), dkT(""), dkT("\tpdf.tex\t\tProduce a *.tex/*.pdf file pair."), dkT("\t\t\tInclude the *.tex file in your LaTeX source, the"), dkT("\t\t\t*.tex file includes the *.pdf file."), dkT(""), dkT("\teps.tex\t\tProduce a *.tex/*.eps file pair."), dkT("\t\t\tInclude the *.tex file in your LaTeX source, the"), dkT("\t\t\t*.tex file includes the *.eps file."), dkT(""), dkT("\tpgf\t\tProduce a *.pgf file for inclusion in a *.tex"), dkT("\t\t\tsource."), dkT(""), dkT("\tDrivers to produce a standalone image:"), dkT(""), dkT("\ttex.pdf\t\tProduce a full *.tex file for use with pdflatex."), dkT("\t\t\tA file file-i.pdf is produced additionally,"), dkT("\t\t\tthis file is included by the *.tex file."), dkT(""), dkT("\ttex\t\tProduce a full *.tex file for use with pdflatex."), dkT("\t\t\tThe image is embedded as a PGF image."), dkT(""), dkT("\teps\t\tProduce a standalone EPS file."), dkT(""), dkT("\tsvg\t\tProduce a standalone SVG file."), dkT(""), dkT("-m"), dkT("\tMake mode when running on a directory: Convert"), dkT("\tfiles only if no destination files up to date are found."), dkT(""), dkT("-o key=value"), dkT("\tKey/value options, may be used multiple times."), dkT("\tThe following keys can be used:"), dkT(""), dkT(""), dkT("\tGeneral options:"), dkT(""), dkT("\tlw=\t\tLine width base."), dkT("\t\t\t\tThe default for Fig files is 1/80 inch."), dkT("\t\t\t\tWidth can be one of the following:"), dkT("\t\t\t\tbp\tPS points"), dkT("\t\t\t\tpt\tWidth in pt"), dkT("\t\t\t\tin\tWidth in inch"), dkT("\t\t\t\tcm\tWidth in cm"), dkT("\t\t\t\tmm\tWidth in mm"), dkT("\t\t\t\tlighten\t\tUse 1/160 inch"), dkT("\t\t\t\tauto\t\t0.4pt * textsize / 10"), dkT(""), dkT("\tText handling options"), dkT(""), dkT("\ttf=\t\tText font selection for normal (non-special)"), dkT("\t\t\t\ttext. Either ``similar'' or ``fig''."), dkT(""), dkT("\tts=\t\tFont size factor for normal (non-special) text."), dkT("\t\t\t\tEither the keyword ``none'' or a scale factor"), dkT("\t\t\t\t(typically in the range 0.95 ... 1.0)."), dkT(""), dkT("\tbbts[=]\tUse text size in bounding box calculaion."), dkT(""), dkT("\tsmash[=]\tUse \\smash instruction in LaTeX output."), dkT(""), dkT("\tmbox[=]\tUse \\mbos instruction in LaTeX output."), dkT(""), dkT("\treset@font[=]\tUse \\reset@font instruction in LaTeX output."), dkT(""), dkT("\tste[=]\tEncoding used when writing special text"), dkT("\t\t\t\tto output file. Either ``plain'' or"), dkT("\t\t\t\t``utf-8''."), dkT(""), dkT(""), dkT("\tX-Spline and Bezier-Spline options"), dkT(""), dkT("\txsss[=]\t\tNumber of Bezier-Spline subsegments per"), dkT("\t\t\t\tX-spline segment. Default: 8, minimum: 2."), dkT(""), dkT(""), dkT("\tArrowhead options:"), dkT(""), dkT("\tahas=\t\tNumber of X-spline segments for a 90 degree"), dkT("\t\t\t\tangle on arcs. Default: 4."), dkT(""), dkT("\tahss=\t\tNumber of arrowhead X-spline segments"), dkT("\t\t\t\tfor each original X-spline segment for"), dkT("\t\t\t\tarrowheads on splines. Default: 4."), dkT(""), dkT("\tahms=\t\tMinimum number of X-spline segments for"), dkT("\t\t\t\teach arrowhead edge. Default: 4"), dkT(""), dkT("\tahip=\t\tArrowhead iteration precision. Default: 0.04."), dkT(""), dkT(""), dkT("\tOutput options:"), dkT(""), dkT("\tcodi=[]\t\tNumber of digits used for colors. Default: 3."), dkT(""), dkT(""), dkT("\tCompatibilty options (compatibility to fig2dev):"), dkT(""), dkT("\tcosp[=]\tCompatible splines."), dkT(""), dkT("\tcoah[=]\tCompatible arrowheads."), dkT(""), dkT("\txsah[=]\tX-spline arrowheads (not together with coah)."), dkT(""), dkT("\tcols[=]\tCompatible line styles."), dkT(""), dkT("\tcofop[=]\tCompatible fill for open paths."), dkT(""), dkT(""), dkT("\tSource type (mutually exclusive):"), dkT(""), dkT("\txfig\t\t\tFile produced by XFig"), dkT(""), dkT("\tjfig\t\t\tFile produced by jFig."), dkT(""), dkT("\twinfig\t\t\tFile produced by WinFIG."), dkT(""), dkT(""), dkT("\tDriver specific options (tex, tex.pdf):"), dkT(""), dkT("\tdcts[=]\t\tFont size in pt used in the document class."), dkT(""), dkT(""), dkT("\tDriver specific options (eps, eps.tex):"), dkT(""), dkT("\tshowpage[=]\tUse showpage operator."), dkT(""), dkT("\tlevel=\t\tPS level, 2 or 3."), dkT(""), dkT("\tDriver specific options (svg)"), dkT(""), dkT("\tcss[=]\t\tUse CSS styling."), dkT(""), dkT("\tgroup[=]\tGroup arrowhead objects with the object they"), dkT("\t\t\t\tare attached to."), dkT(""), dkT("\tfragment[=]\tWrite an SVG fragment instead of a complete"), dkT("\t\t\t\tfile."), dkT(""), dkT("\tfontbase[=]\tSpecify source for GhostScript fonts"), dkT("\t\t\t\tconverted to TTF, \"none\", \"local\", or \"web\"."), dkT(""), dkT("\treplacementfonts=[]\tenables/disables use of replacement"), dkT("\t\t\t\t\tfont families."), dkT(""), dkT("\tmiterlimit[=]\tEnables or disables use of \"stroke-miterlimit\""), dkT("\t\t\t\tstyle setting."), dkT(""), dkT(""), dkT("EXIT STATUS"), dkT(""), dkT("0 on success, all other exit status codes indicate an error."), dkT(""), dkT("FILES"), dkT(""), dkT("Fig2lat uses the following files from the current working directory:"), dkT(""), dkT("f2lfonts.tex\tis used in the preamble of tex and tex.pdf output, the file"), dkT("\t\tcontents replaces the font selection packages."), dkT(""), dkT("f2lother.tex\tis used in the preamble of tex and tex.pdf output, the file"), dkT("\t\tcontents replaces the packages for \"other setup\"."), dkT(""), dkT("NOTES"), dkT(""), dkT("There are differences between the output from fig2lat and the output"), dkT("from fig2dev. This is intended, otherwise we would not need an additional"), dkT("program."), dkT(""), dkT("* Interpolated X-splines: Fig2lat uses the correct formula q=-0.5*s"), dkT(" as described in [BS1995]."), dkT(""), dkT("* Arrowheads: All arrowhead types introduced in xfig 3.2.5 are supported."), dkT(" On splines and arcs we have curved arrowheads. The same line width as"), dkT(" for the original line is used for the arrowhead too, the arrowhead"), dkT(" linewidth specified in the Fig file is ignored."), dkT(""), dkT("* Text: When using LaTeX/pdfLaTeX related drivers (tex, tex.pdf, pdf.tex,"), dkT(" eps.tex, pgf) all text is handled by LaTeX/pdfLaTeX. The tf setting"), dkT(" controls whether to use PS fonts or similar feature LaTeX fonts for"), dkT(" normal text. For special text no font selection instructions are written"), dkT(" at all, so document default fonts are used."), dkT(""), dkT("* Fill patterns: Fill patterns are vector graphics in fig2lat."), dkT(""), dkT("* Splines: X-splines are converted to a sequence of Bezier splines instead"), dkT(" of polylines."), dkT(""), dkT("KNOWN ISSUES"), dkT(""), dkT("* The curved arrowheads on arcs and splines are implemented as sequences"), dkT(" of short - sometimes very short - Bezier curves."), dkT(" At least for my arrowtest.fig test file I saw malformed arrowheads"), dkT(" in some renderers although the same graphics were shown fine in other"), dkT(" renderers."), dkT(" You can avoid the problem by using the coah option (compatible arrowheads)."), dkT(" For Batik 1.7 Squiggle you can also attempt the miterlimit=no option."), dkT(""), dkT("AUTHOR"), dkT(""), dkT("Dirk Krause"), dkT(""), dkT("HISTORY"), dkT(""), dkT("This program replaces the fig2vect program seen in previous versions"), dkT("of dktools."), dkT(""), dkT("COPYRIGHT AND LICENSE"), dkT(""), dkT("Run"), dkT(" fig2lat --license-terms"), dkT("to see the license conditions."), dkT(""), dkT("SEE ALSO"), dkT(""), dkT("[BS1995]\tCarole Blanc, Christophe Schlick:"), dkT("\t\tX-Splines: A Spline Model Designed for the End-User"), dkT("\t\tProceedings of the SIGGRAPH 1995"), dkT(""), dkT("[fig2lat]\thttp://dktools.sourceforge.net"), dkT(""), NULL #line 579 "fig2lat.ctr" }; /** Default texts, used if localized texts are not found. */ static dkChar const * const f2l_default_messages[] = { /* 0 */ dkT("Invalid PS level preference value \""), /* 1 */ dkT("\"!"), /* 2 */ dkT("Input file name too long:\n"), /* 3 */ dkT("Failed to read input file!"), /* 4 */ dkT("Failed to process input file!"), /* 5 */ dkT("Not a regular file, not a directory!"), /* 6 */ dkT("Command line options processing failed!"), /* 7 */ dkT("Unknown driver \""), /* 8 */ dkT("\"!"), /* 9 */ dkT("Invalid value \""), /* 10 */ dkT("\" for tf, use \"fig\" or \"similar\"!"), /* 11 */ dkT("Invalid font size specification \""), /* 12 */ dkT("\"!"), /* 13 */ dkT("Invalid size specification \""), /* 14 */ dkT("\" (overflow)!"), /* 15 */ dkT("Value \""), /* 16 */ dkT("\" is below the required minimum \""), /* 17 */ dkT("\"!"), /* 18 */ dkT("\" is above the required maximum \""), /* 19 */ dkT("Option \""), /* 20 */ dkT("\" requires a positive argument!"), /* 21 */ dkT("Option \""), /* 22 */ dkT("\" requires a numeric argument!"), /* 23 */ dkT("Source type already set!"), /* 24 */ dkT("Option \""), /* 25 */ dkT("\" requires an unsigned numeric argument!"), /* 26 */ dkT("Can not handle negative font size!"), /* 27 */ dkT("Illegal option/key name \""), /* 28 */ dkT("\"!"), /* 29 */ dkT("Option too long:\n\""), /* 30 */ dkT("\""), /* 31 */ dkT("Option argument too long:\n\""), /* 32 */ dkT("Option -l requires an argument!"), /* 33 */ dkT("PS level must be 2 or 3!"), /* 34 */ dkT("Minimum of arrowhead segments corrected to 2!"), /* 35 */ dkT("Mathematical problem (coordinates transformation)!"), /* 36 */ dkT("Mathematical problem (spline calculation)!"), /* 37 */ dkT("Arrowhead too long for spline!"), /* 38 */ dkT("Mathematical problem (path construction)!"), /* 39 */ dkT("Arrowheads in summary too long for spline!"), /* 40 */ dkT("Failed to calculate graphics state transformation!"), /* 41 */ dkT("Failed to add instructions to PDF graphics!"), /* 42 */ dkT("Skipping special text!"), /* 43 */ dkT("Unknown object type!"), /* 44 */ dkT("Special text found!"), /* 45 */ dkT("Not a line width: \""), /* 46 */ dkT("\"!"), NULL #line 734 "fig2lat.ctr" }; /** PS level preference name. */ static dkChar const fig2lat_pref_psl[] = { dkT("/print/ps/level") }; #if 0 /** Initialize a configuration structure. @param conf Structure to initialize. */ static void fig2lat_config_init(fig2lat_config_t *conf) { #line 755 "fig2lat.ctr" dk3mem_res((void *)conf, sizeof(fig2lat_config_t)); conf->nts = 1.0; conf->ntf = 0; #line 759 "fig2lat.ctr" } #endif /** Set PS level from preferences. @param job Job structure. */ static void fig2lat_set_ps_level_from_preferences(f2l_job_t *job) { dkChar buf[256]; /* Buffer to retrieve preference value. */ int i; /* Conversion result. */ if(dk3app_get_pref(job->app,fig2lat_pref_psl,buf,DK3_SIZEOF(buf,dkChar))) { #if VERSION_BEFORE_20140716 if(dk3sf_sscanf3(buf, dkT("%d"), &i)) #else if (0 != dk3ma_i_from_string(&i, buf, NULL)) #endif { if((i >= 2) && (i <= 3)) { job->pslevel = i; } else { /* Warning: Preference value is not a number! */ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 0, 1, buf); } } else { /* Warning: Preference value is not a number! */ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 0, 1, buf); } } } /** Initialize job structure. @param job Job structure to initialize. @param app Application structure for diagnostics. @param msg Localized message texts. @param figmsg Localized message texts for the dk3fig module. @return 1 on success, 0 on error. */ static int fig2lat_job_init( f2l_job_t *job, dk3_app_t *app, dkChar const * const *msg, dkChar const * const *figmsg ) { int back = 0; #line 813 "fig2lat.ctr" dk3mem_res((void*)job, sizeof(f2l_job_t)); dk3fig_gs_init(&(job->gs)); job->app = app; job->msg = msg; job->figmsg = figmsg; job->opt = NULL; job->drw = NULL; job->on1 = NULL; job->on2 = NULL; job->of1 = NULL; job->of2 = NULL; job->nts = 1.0; job->tts = 12.0; #if 0 fig2lat_config_init(&(job->confProgram)); fig2lat_config_init(&(job->confFile)); fig2lat_config_init(&(job->confObject)); #endif job->dr = FIG2LAT_DRIVER_PDF_WITH_TEX; job->exval = FIG2LAT_EXIT_ERROR_UNKNOWN; job->mm = 0; job->cmd = 0; job->cosp = 0; job->coah = 0; job->xsah = 0; job->xssbs = 8; job->qbs = 4; job->debug = 0; job->showpage = 0; job->pslevel = 3; job->dsc = 0; job->arcspp = 8.0; job->splspp = 8.0; job->minspp = 4; job->xsprec = 0.04; /* originally 1200 / 25400 */ job->srctype = DK3_FIG_SRCTYPE_UNKNOWN; job->smash = 1; job->mbox = 0; job->resfont = 1; job->codi = 3; job->css = 1; job->fragment = 0; job->svgfontbase = 0; job->group = 0; job->miterlim = 1; job->cols = 0; job->otherfonts = 1; job->bbts = 0; job->stu8 = 0; job->cofop = 1; job->lwbp = 0.9; /* 1/80 inch */ job->lwauto = 0; if(dk3app_get_encoding(app) == DK3_ENCODING_UTF8) { job->stu8 = 1; } fig2lat_set_ps_level_from_preferences(job); (job->ct2d).mx = (job->ct2d).my = (job->ct2d).nx = (job->ct2d).ny = 0.0; job->width = job->height = job->w2 = job->h2 = 0.0; job->lwidth = job->lheight = 0L; /* @DRIVER@ If you added components to the f2l_job_t structure, initialize them to default values here. */ back = 1; #line 878 "fig2lat.ctr" return back; } /** Clean up job structure. @param job Job structure to clean up. */ static void fig2lat_job_end(f2l_job_t *job) { #line 891 "fig2lat.ctr" /* @DRIVER@ If you added components to the f2l_job_t structure make sure to release resources here. */ if(job->opt) { dk3opt_close(job->opt); job->opt = NULL; } #line 899 "fig2lat.ctr" } /** Show version information. @param job Job structure. */ static void fig2lat_show_version(f2l_job_t *job) { dk3sf_initialize_stdout(); dk3sf_fputs(fig2lat_version[0], stdout); dk3sf_fputs(fig2lat_version[1], stdout); dk3sf_fputc(dkT('\n'), stdout); } /** Show license terms. @param job Job structure. */ static void fig2lat_show_license(f2l_job_t *job) { dkChar const * const *ptr; /* Pointer to traverse all text lines. */ ptr = fig2lat_license; dk3sf_initialize_stdout(); while(*ptr) { dk3sf_fputs(*(ptr++), stdout); dk3sf_fputc(dkT('\n'), stdout); } } /** Show help text. @param job Job structure. */ static void fig2lat_show_help(f2l_job_t *job) { dk3app_help(job->app, f2l_kw[2], fig2lat_help_text); } /** Check whether a file has a fig suffix. @param fn File name. @return 1 for fig files, 0 for other or no suffix. */ static int fig2lat_is_fig_file(dkChar const *fn) { dkChar const *sp; /* Suffix found in file name. */ int back = 0; sp = dk3str_get_suffix(fn); if(sp) { if(0 == dk3str_cmp(sp, f2l_kw[3])) { back = 1; } } return back; } /** Create output file name. @param job Job structure. @param ifn Input file name. @param osf Output suffix. @return Valid pointer to new output name on success, NULL on error. */ static dkChar const * fig2lat_set_one_output_name( f2l_job_t *job, dkChar const *ifn, dkChar const *osf ) { dkChar buf[DK3_MAX_PATH]; /* Buffer for modification. */ dkChar *sp; /* File name suffix in buffer. */ dkChar const *back = NULL; #line 986 "fig2lat.ctr" if(dk3str_len(ifn) < DK3_SIZEOF(buf,dkChar)) { dk3str_cpy_not_overlapped(buf, ifn); sp = dk3str_get_suffix(buf); if(sp) { *sp = dkT('\0'); } if((dk3str_len(buf) + dk3str_len(osf)) < DK3_SIZEOF(buf,dkChar)) { dk3str_cat(buf, osf); back = dk3str_dup_app(buf, job->app); if(!(back)) { job->exval = FIG2LAT_EXIT_ERROR_SYSTEM; #line 995 "fig2lat.ctr" } } else { #line 997 "fig2lat.ctr" /* ERROR: Input file name too long! */ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; #line 999 "fig2lat.ctr" dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, buf); } } else { #line 1002 "fig2lat.ctr" /* ERROR: Input file name too long! */ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; #line 1004 "fig2lat.ctr" dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, ifn); } #line 1006 "fig2lat.ctr" return back; } /** Set output file name(s) depending on input name and output driver. @param job Job structure. @param ifn Input file name. @return 1 on success, 0 on error. */ static int fig2lat_set_output_names(f2l_job_t *job, dkChar const *ifn) { int back = 0; #line 1022 "fig2lat.ctr" switch(job->dr) { case FIG2LAT_DRIVER_TEX_FULL_PGF: { job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]); if(job->on1) { back = 1; } } break; case FIG2LAT_DRIVER_TEX_FULL_PDF: { job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]); job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[9]); if((job->on1) && (job->on2)) { back = 1; } } break; case FIG2LAT_DRIVER_EPS_WITH_TEX: { job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]); job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[6]); if((job->on1) && (job->on2)) { back = 1; } } break; case FIG2LAT_DRIVER_PDF_WITH_TEX: { job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]); job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[8]); if((job->on1) && (job->on2)) { back = 1; } } break; case FIG2LAT_DRIVER_EPS_STANDALONE: { job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[6]); if(job->on1) { back = 1; } } break; case FIG2LAT_DRIVER_SVG_STANDALONE: { job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[5]); if(job->on1) { back = 1; } } break; default: { /* PGF */ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[4]); if(job->on1) { back = 1; } } break; } #line 1056 "fig2lat.ctr" #line 1057 "fig2lat.ctr" if(!(back)) { f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); #line 1059 "fig2lat.ctr" } #line 1061 "fig2lat.ctr" return back; } /** Run for one file. @param job Job structure. @param fn File name (no wildcards contained). */ static void fig2lat_run_for_file(f2l_job_t *job, dkChar const *fn) { dkChar const *oldsrcname; /* Saved source file name. */ #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H char *oldlocale; /* Old locale setting. */ #endif unsigned long oldsrcline; /* Saved source file line number. */ #line 1080 "fig2lat.ctr" oldsrcname = dk3app_get_source_file(job->app); oldsrcline = dk3app_get_source_line(job->app); dk3app_set_source_file(job->app, fn); dk3app_set_source_line(job->app, 0UL); #if 0 /* Copy program configuration to file configuration. */ dk3mem_cpy( (void *)(&(job->confFile)), (void *)(&(job->confProgram)), sizeof(fig2lat_config_t) ); #endif job->on1 = NULL; job->on2 = NULL; if(fig2lat_set_output_names(job, fn)) { job->drw = dk3fig_drawing_new(job->app, job->figmsg); if(job->drw) { dk3fig_set_options_bsegs(job->drw, job->xssbs, job->qbs); dk3fig_set_options_lwbp(job->drw, job->lwbp); dk3fig_set_options_coah(job->drw, job->coah); dk3fig_set_options_xsah(job->drw, job->xsah); dk3fig_set_options_cosp(job->drw, job->cosp); dk3fig_set_options_bbts(job->drw, job->bbts); dk3fig_set_options_srctype(job->drw, job->srctype); dk3fig_set_options_arrows(job->drw,job->arcspp,job->splspp,job->minspp); dk3fig_set_options_iteration_precision(job->drw, job->xsprec); dk3fig_set_options_codi(job->drw, job->codi); dk3fig_set_options_cofop(job->drw, job->cofop); if(dk3fig_read_file_name(job->drw, fn)) { #line 1111 "fig2lat.ctr" if(dk3fig_prepare(job->drw)) { #line 1112 "fig2lat.ctr" #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H oldlocale = setlocale(LC_NUMERIC, "C"); #endif dk3fig_gs_init(&(job->gs)); switch(job->dr) { case FIG2LAT_DRIVER_SVG_STANDALONE: { f2lsvg_output(job); } break; /* @DRIVER@ Add a case branch to call your output driver here. If any error occurs in the driver function, set job->exval to indicate the error. */ default: { f2lud_output(job); } break; } #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H setlocale(LC_NUMERIC, oldlocale); #endif } else { #line 1133 "fig2lat.ctr" /* ERROR while preparing drawing! */ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); #line 1135 "fig2lat.ctr" dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4); } } else { #line 1138 "fig2lat.ctr" /* ERROR while reading input file! */ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); #line 1140 "fig2lat.ctr" dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 3); } dk3fig_drawing_delete(job->drw); job->drw = NULL; } else { f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); #line 1145 "fig2lat.ctr" } } dk3_release(job->on1); dk3_release(job->on2); dk3app_set_source_file(job->app, oldsrcname); dk3app_set_source_line(job->app, oldsrcline); #line 1152 "fig2lat.ctr" } /** Check whether there is an up-to-date output file for the given file name and output suffix. @param job Job structure. @param fn Source file name. @param sn Suffix for output file name. @return 1 if output file is available, 0 otherwise. */ static int fig2lat_up_to_date_output(f2l_job_t *job, dkChar const *fn, dkChar const *sn) { dk3_stat_t stbs; /* Source file information. */ dk3_stat_t stbd; /* Destination file information. */ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */ dkChar *sp; /* File name suffix in buffer. */ int back = 0; #line 1173 "fig2lat.ctr" if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, fn); sp = dk3str_get_suffix(fnb); if(sp) { *sp = dkT('\0'); if((dk3str_len(fnb) + dk3str_len(sn)) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(sp, sn); if(dk3sf_stat_app(&stbs, fn, job->app)) { if(dk3sf_stat_app(&stbd, fnb, NULL)) { if(stbd.mod > stbs.mod) { back = 1; #line 1184 "fig2lat.ctr" } } } } } } #line 1190 "fig2lat.ctr" return back; } /** Check whether we need to process a fig file found in a directory. @param job Job structure. @param fn File name to check. @return 1 to process the file, 0 to skip processing. */ static int fig2lat_must_process_file(f2l_job_t *job, dkChar const *fn) { int back = 1; #line 1206 "fig2lat.ctr" if(job->mm) { switch(job->dr) { case FIG2LAT_DRIVER_TEX_FULL_PGF: { if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) { back = 0; } } break; case FIG2LAT_DRIVER_TEX_FULL_PDF: { if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) { if(fig2lat_up_to_date_output(job, fn, f2l_kw[9])) { back = 0; } } } break; case FIG2LAT_DRIVER_EPS_WITH_TEX: { if(fig2lat_up_to_date_output(job, fn, f2l_kw[6])) { if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) { back = 0; } } } break; case FIG2LAT_DRIVER_PDF_WITH_TEX: { if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) { if(fig2lat_up_to_date_output(job, fn, f2l_kw[8])) { back = 0; } } } break; case FIG2LAT_DRIVER_EPS_STANDALONE: { if(fig2lat_up_to_date_output(job, fn, f2l_kw[6])) { back = 0; } } break; case FIG2LAT_DRIVER_SVG_STANDALONE: { if(fig2lat_up_to_date_output(job, fn, f2l_kw[5])) { back = 0; } } break; default: { /* PGF */ if(fig2lat_up_to_date_output(job, fn, f2l_kw[4])) { back = 0; } } break; } } #line 1251 "fig2lat.ctr" return back; } /** Process a directory. @param job Job structure. @param fn Directory name. */ static void fig2lat_run_for_directory(f2l_job_t *job, dkChar const *fn) { dk3_dir_t *dir; /* Directory traversal. */ dkChar const *filename; /* Found file name. */ #line 1267 "fig2lat.ctr" dir = dk3dir_open_app(fn, job->app); if(dir) { while(dk3dir_get_next_file(dir)) { filename = dk3dir_get_fullname(dir); if(filename) { if(fig2lat_is_fig_file(filename)) { if(fig2lat_must_process_file(job, filename)) { fig2lat_run_for_file(job, filename); } } } else { #line 1278 "fig2lat.ctr" } } dk3dir_close(dir); } else { f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); #line 1283 "fig2lat.ctr" } #line 1285 "fig2lat.ctr" } /** Run for file or directory name directly (no wildcards). @param job Job structure. @param fn File name (wildcards already resolved). */ static void fig2lat_run_for_file_directly(f2l_job_t *job, dkChar const *fn) { dk3_stat_t stb; /* File information. */ #line 1299 "fig2lat.ctr" if(dk3sf_stat_app(&stb, fn, job->app)) { switch((stb.ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { fig2lat_run_for_file(job, fn); } break; case DK3_FT_DIRECTORY: { fig2lat_run_for_directory(job, fn); } break; default: { /* ERROR: Neither directory nor regular file! */ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; #line 1310 "fig2lat.ctr" dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 5); } break; } } else { #line 1314 "fig2lat.ctr" job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; #line 1315 "fig2lat.ctr" } #line 1317 "fig2lat.ctr" } /** Run for file or directory name (may contain wildcards). @param job Job structure. @param fn File name (may contain wildcards). */ static void fig2lat_run_for_name(f2l_job_t *job, dkChar const *fn) { dkChar fnb[DK3_MAX_PATH]; /* Name buffer for modification. */ dkChar const *filename; /* File name found. */ dk3_dir_t *dir; /* Expander for wildcards. */ int found; /* Flag: Source file found. */ #line 1334 "fig2lat.ctr" if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, fn); dk3str_correct_filename(fnb); if(dk3sf_must_expand(fnb)) { dir = dk3dir_fne_open_app(fnb, job->app); if(dir) { found = 0; while(dk3dir_get_next_file(dir)) { filename = dk3dir_get_fullname(dir); if(filename) { if(fig2lat_is_fig_file(filename)) { #line 1345 "fig2lat.ctr" found = 1; fig2lat_run_for_file(job, filename); } else { #line 1348 "fig2lat.ctr" } } else { #line 1350 "fig2lat.ctr" } } if(0 == found) { job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; #line 1354 "fig2lat.ctr" } dk3dir_close(dir); } else { #line 1357 "fig2lat.ctr" job->exval = FIG2LAT_EXIT_ERROR_SYSTEM; #line 1358 "fig2lat.ctr" } } else { fig2lat_run_for_file_directly(job, fnb); } } else { #line 1363 "fig2lat.ctr" /* ERROR: File name too long! */ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; #line 1365 "fig2lat.ctr" dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, fn); } #line 1367 "fig2lat.ctr" } /** Run for current directory. @param job Job structure. */ static void fig2lat_run_for_current_directory(f2l_job_t *job) { dkChar cwdbu[DK3_MAX_PATH]; /* Buffer for current working directory. */ #line 1380 "fig2lat.ctr" if(dk3sf_getcwd_app(cwdbu, DK3_SIZEOF(cwdbu,dkChar), job->app)) { fig2lat_run_for_file_directly(job, cwdbu); } else { #line 1383 "fig2lat.ctr" f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); #line 1384 "fig2lat.ctr" } #line 1386 "fig2lat.ctr" } /** Run conversion as indicated by command line arguments. @param job Job structure. */ static void fig2lat_run(f2l_job_t *job) { dkChar const *fn; /* File name. */ int argc; /* Number of command line arguments. */ int i; /* Current command line argument processed. */ #line 1401 "fig2lat.ctr" if((argc = dk3opt_get_num_args(job->opt)) > 0) { #line 1402 "fig2lat.ctr" job->exval = FIG2LAT_EXIT_SUCCESS; #line 1403 "fig2lat.ctr" for(i = 0; i < argc; i++) { fn = dk3opt_get_arg(job->opt, i); if(fn) { fig2lat_run_for_name(job, fn); } else { job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; #line 1409 "fig2lat.ctr" } } } else { #line 1412 "fig2lat.ctr" fig2lat_run_for_current_directory(job); } #line 1415 "fig2lat.ctr" } #if TRACE_DEBUG #if FIG2LAT_TEST_BEZIER static void fig2lat_test_bezier(void) { double t; size_t i; t = 0.0; for(i = 0; i <= 10; i++) { printf("%g\t%g\n",t,dk3bezier_value(0.0,1.0,9.0,10.0,t,NULL)); t += 0.1; } } #endif #endif /** 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 { f2l_job_t job; /* Job structure. */ dk3_app_t *app = NULL; /* Application structure. */ dkChar const * const *msg = NULL; /* Localized texts. */ dkChar const * const *figmsg = NULL; /* dk3fig module localized texts. */ int exval = FIG2LAT_EXIT_ERROR_UNKNOWN; /* Exit code. */ int testcmd; /* Mask for help/version/license. */ #line 1451 "fig2lat.ctr" #line 1452 "fig2lat.ctr" #if VERSION_BEFORE_20150821 exval = FIG2LAT_EXIT_ERROR_UNKNOWN; #endif job.opt = NULL; app = dk3app_open_command( argc, (dkChar const * const *)argv, f2l_kw[0] ); if(app) { #line 1460 "fig2lat.ctr" msg = dk3app_messages( app, f2l_kw[1], (dkChar const **)f2l_default_messages ); figmsg = dk3fig_get_localized_messages(app); #if TRACE_DEBUG #if FIG2LAT_TEST_BEZIER fig2lat_test_bezier(); #endif #endif if(fig2lat_job_init(&job,app,msg,figmsg)) { #line 1470 "fig2lat.ctr" if(f2lopt_process(&job)) { #line 1471 "fig2lat.ctr" testcmd = DK3_APP_CMD_HELP | DK3_APP_CMD_VERSION | DK3_APP_CMD_LICENSE; if((job.cmd) & testcmd) { #line 1473 "fig2lat.ctr" if(job.cmd) { #line 1474 "fig2lat.ctr" fig2lat_show_version(&job); } if((job.cmd) & DK3_APP_CMD_LICENSE) { #line 1477 "fig2lat.ctr" fig2lat_show_license(&job); } if((job.cmd) & DK3_APP_CMD_HELP) { #line 1480 "fig2lat.ctr" fig2lat_show_help(&job); } job.exval = FIG2LAT_EXIT_SUCCESS; } else { #line 1484 "fig2lat.ctr" fig2lat_run(&job); } } else { #line 1487 "fig2lat.ctr" dk3app_log_1(job.app, DK3_LL_ERROR, job.msg, 6); } } else { #line 1490 "fig2lat.ctr" } exval = job.exval; dk3app_close(app); app = NULL; } else { #line 1494 "fig2lat.ctr" fputs("fig2lat: ERROR: Not enough memory (RAM/swap)!\n", stderr); fflush(stderr); exval = FIG2LAT_EXIT_ERROR_SYSTEM; } fig2lat_job_end(&job); #line 1500 "fig2lat.ctr" #line 1501 "fig2lat.ctr" fflush(stdout); exit(exval); return exval; }