/*
	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-2013, 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 205 "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"
#include "dkt-version.h"



#line 222 "fig2lat.ctr"



/**	Keywords used by the module, not localized.
*/
static dkChar const * const f2l_kw[] = {
/* 0 */
dkT("dkt-3"),

/* 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 270 "fig2lat.ctr"
};



/**	Version number.
*/
static dkChar const *fig2lat_version[] = {
  dkT("fig2lat "),
  DKT_VERSION
};



/**	License conditions.
*/
static dkChar const * const fig2lat_license[] = {
dkT(""),
dkT("Copyright (c) 2013, 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 321 "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 <driver>] [<options>] [-o <key>=<value>]* <file>"),
dkT(""),
dkT("DESCRIPTION"),
dkT(""),
dkT("The program 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 <driver>"),
dkT(" \tchooses a driver, one from the following:"),
dkT(""),
dkT("\tDrivers to use a Fig file with latex or pdflatex:"),
dkT(""),
dkT("\tpdf.tex\t\tproduces 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\tproduces 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\tproduces 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\tproduces 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\tproduces a full *.tex file for use with pdflatex."),
dkT("\t\t\tThe image is embedded as a PGF image."),
dkT(""),
dkT("\teps\t\tproduces a standalone EPS file."),
dkT(""),
dkT("\tsvg\t\tproduces a standalone SVG file."),
dkT(""),
dkT("-m"),
dkT("\tactivates make-mode when running on a directory to convert"),
dkT("\tfiles only if no destination files up to date are found."),
dkT(""),
dkT("-o key=value"),
dkT("\tsets key/value options, may be used multiple times."),
dkT("\tThe following keys can be used:"),
dkT(""),
dkT(""),
dkT("\tGeneral options:"),
dkT(""),
dkT("\tlighten[=<boolean>]\tLighten look by using half linewidth only.]"),
dkT(""),
dkT(""),
dkT("\tText handling options"),
dkT(""),
dkT("\ttf=<string>\t\tText font selection for normal (non-special)"),
dkT("\t\t\t\ttext.  Either ``similar'' or ``fig''."),
dkT(""),
dkT("\tts=<size>\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("\tsmash[=<boolean>]\tUse \\smash instruction in LaTeX output."),
dkT(""),
dkT("\tmbox[=<boolean>]\tUse \\mbos instruction in LaTeX output."),
dkT(""),
dkT("\treset@font\t\tUse \\reset@font instruction in LaTeX output."),
dkT(""),
dkT(""),
dkT("\tX-Spline and Bezier-Spline options"),
dkT(""),
dkT("\txsss[=<number>]\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=<number>\t\tNumber of X-spline segments for a 90 degree"),
dkT("\t\t\t\tangle on arcs. Default: 4."),
dkT(""),
dkT("\tahss=<integer>\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=<integer>\t\tMinimum number of X-spline segments for"),
dkT("\t\t\t\teach arrowhead edge. Default: 4"),
dkT(""),
dkT("\tahip=<float>\t\tArrowhead iteration precision. Default: 0.04."),
dkT(""),
dkT(""),
dkT("\tOutput options:"),
dkT(""),
dkT("\tcodi=[<number>]\t\tNumber of digits used for colors. Default: 3."),
dkT(""),
dkT(""),
dkT("\tCompatibilty options (compatibility to fig2dev):"),
dkT(""),
dkT("\tcosp[=<boolean>]\tCompatible splines."),
dkT(""),
dkT("\tcoah[=<boolean>]\tCompatible arrowheads."),
dkT(""),
dkT("\tcols[=<boolean>]\tCompatible line styles."),
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[=<number>]\t\tFont size in pt used in the document class."),
dkT(""),
dkT(""),
dkT("\tDriver specific options (eps, eps.tex):"),
dkT(""),
dkT("\tshowpage[=<boolean>]\tUse showpage operator."),
dkT(""),
dkT("\tlevel=<integer>\t\tPS level, 2 or 3."),
dkT(""),
dkT("\tDriver specific options (svg)"),
dkT(""),
dkT("\tcss[=<boolean>]\t\tUse CSS styling."),
dkT(""),
dkT("\tgroup[=<boolean>]\tGroup arrowhead objects with the object they"),
dkT("\t\t\t\tare attached to."),
dkT(""),
dkT("\tfragment[=<boolean>]\tWrite an SVG fragment instead of a complete"),
dkT("\t\t\t\tfile."),
dkT(""),
dkT("\tfontbase[=<string>]\tSpecify source for GhostScript fonts"),
dkT("\t\t\t\tconverted to TTF, \"none\", \"local\", or \"web\"."),
dkT(""),
dkT("\treplacementfonts=[<boolean>]\tenables/disables use of replacement"),
dkT("\t\t\t\t\tfont families."),
dkT(""),
dkT("\tmiterlimit[=<boolean>]\tEnables or disables use of \"stroke-miterlimit\""),
dkT("\t\t\t\tstyle setting."),
dkT(""),
dkT(""),
dkT("RETURN VALUE"),
dkT(""),
dkT("The program returns exit status code 0 on success, any other value"),
dkT("indicates 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("Dipl.-Ing. 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"),
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 554 "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!"),

NULL


#line 704 "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 725 "fig2lat.ctr"
  dk3mem_res((void *)conf, sizeof(fig2lat_config_t));
  conf->nts = 1.0;
  conf->ntf = 0;
  

#line 729 "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(dk3sf_sscanf3(buf, dkT("%d"), &i)) {
      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 778 "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->xssbs = 8;
  job->qbs = 4;
  job->lighten = 0;
  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;
  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 836 "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 849 "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 857 "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 944 "fig2lat.ctr"
  if(dk3str_len(ifn) < DK3_SIZEOF(buf,dkChar)) {
    dk3str_cpy(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 953 "fig2lat.ctr"
      }
    } else {					

#line 955 "fig2lat.ctr"
      /* ERROR: Input file name too long! */
      job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; 

#line 957 "fig2lat.ctr"
      dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, buf);
    }
  } else {					

#line 960 "fig2lat.ctr"
    /* ERROR: Input file name too long! */
    job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; 

#line 962 "fig2lat.ctr"
    dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, ifn);
  } 

#line 964 "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 980 "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 1014 "fig2lat.ctr"
  

#line 1015 "fig2lat.ctr"
  if(!(back)) {
    f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); 

#line 1017 "fig2lat.ctr"
  }
  

#line 1019 "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 1038 "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_lighten(job->drw, job->lighten);
      dk3fig_set_options_coah(job->drw, job->coah);
      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);
      if(dk3fig_read_file_name(job->drw, fn)) {	

#line 1067 "fig2lat.ctr"
        if(dk3fig_prepare(job->drw)) {		

#line 1068 "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 1089 "fig2lat.ctr"
	  /* ERROR while preparing drawing! */
	  f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); 

#line 1091 "fig2lat.ctr"
          dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4);
        }
      } else {					

#line 1094 "fig2lat.ctr"
        /* ERROR while reading input file! */
        f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); 

#line 1096 "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 1101 "fig2lat.ctr"
    }
  }
  if(job->on1) {
    dk3_release(job->on1)
  }
  if(job->on2) {
    dk3_release(job->on2)
  }
  dk3app_set_source_file(job->app, oldsrcname);
  dk3app_set_source_line(job->app, oldsrcline);
  

#line 1112 "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 1133 "fig2lat.ctr"
  if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
    dk3str_cpy(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(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 1144 "fig2lat.ctr"
	    }
	  }
	}
      }
    }
  } 

#line 1150 "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 1166 "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 1211 "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 1227 "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 1238 "fig2lat.ctr"
      }
    }
    dk3dir_close(dir);
  } else {
    f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); 

#line 1243 "fig2lat.ctr"
  }
  

#line 1245 "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 1259 "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 1270 "fig2lat.ctr"
        dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 5);
      } break;
    }
  } else {						

#line 1274 "fig2lat.ctr"
    job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; 

#line 1275 "fig2lat.ctr"
  }
  

#line 1277 "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 1294 "fig2lat.ctr"
  if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
    dk3str_cpy(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 1305 "fig2lat.ctr"
	      found = 1;
	      fig2lat_run_for_file(job, filename);
	    } else {					

#line 1308 "fig2lat.ctr"
	    }
	  } else {					

#line 1310 "fig2lat.ctr"
	  }
	}
	if(0 == found) {
	  job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; 

#line 1314 "fig2lat.ctr"
	}
        dk3dir_close(dir);
      } else {						

#line 1317 "fig2lat.ctr"
        job->exval = FIG2LAT_EXIT_ERROR_SYSTEM; 

#line 1318 "fig2lat.ctr"
      }
    } else {
      fig2lat_run_for_file_directly(job, fnb);
    }
  } else {						

#line 1323 "fig2lat.ctr"
    /* ERROR: File name too long! */
    job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; 

#line 1325 "fig2lat.ctr"
    dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, fn);
  } 

#line 1327 "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 1340 "fig2lat.ctr"
  if(dk3sf_getcwd_app(cwdbu, DK3_SIZEOF(cwdbu,dkChar), job->app)) {
    fig2lat_run_for_file_directly(job, cwdbu);
  } else {		

#line 1343 "fig2lat.ctr"
    f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); 

#line 1344 "fig2lat.ctr"
  }
  

#line 1346 "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 1361 "fig2lat.ctr"
  if((argc = dk3opt_get_num_args(job->opt)) > 0) { 

#line 1362 "fig2lat.ctr"
    job->exval = FIG2LAT_EXIT_SUCCESS;	

#line 1363 "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 1369 "fig2lat.ctr"
      }
    }
  } else {					

#line 1372 "fig2lat.ctr"
    fig2lat_run_for_current_directory(job);
  }
  

#line 1375 "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("%lg\t%lg\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;		/* Exit status code. */
  int			 testcmd;	/* Mask for help/version/license. */
  

#line 1411 "fig2lat.ctr"
  

#line 1412 "fig2lat.ctr"
  exval = FIG2LAT_EXIT_ERROR_UNKNOWN;
  app = dk3app_open_command(
    argc, (dkChar const * const *)argv, f2l_kw[0]
  );
  if(app) {			

#line 1417 "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 1427 "fig2lat.ctr"
      if(f2lopt_process(&job)) {		

#line 1428 "fig2lat.ctr"
        testcmd = DK3_APP_CMD_HELP | DK3_APP_CMD_VERSION | DK3_APP_CMD_LICENSE;
        if((job.cmd) & testcmd) {		

#line 1430 "fig2lat.ctr"
	  if(job.cmd) {				

#line 1431 "fig2lat.ctr"
	    fig2lat_show_version(&job);
	  }
	  if((job.cmd) & DK3_APP_CMD_LICENSE) {	

#line 1434 "fig2lat.ctr"
	    fig2lat_show_license(&job);
	  }
	  if((job.cmd) & DK3_APP_CMD_HELP) {	

#line 1437 "fig2lat.ctr"
	    fig2lat_show_help(&job);
	  }
	  job.exval = FIG2LAT_EXIT_SUCCESS;
	} else {				

#line 1441 "fig2lat.ctr"
	  fig2lat_run(&job);
	}
      } else {					

#line 1444 "fig2lat.ctr"
        dk3app_log_1(job.app, DK3_LL_ERROR, job.msg, 6);
      }
    } else {					

#line 1447 "fig2lat.ctr"
    }
    exval = job.exval;
    dk3app_close(app); app = NULL;
  } else {			

#line 1451 "fig2lat.ctr"
    fputs("fig2lat: ERROR: Not enough memory (RAM/swap)!\n", stderr);
    fflush(stderr);
    exval = FIG2LAT_EXIT_ERROR_SYSTEM;
  }
  fig2lat_job_end(&job);
  

#line 1457 "fig2lat.ctr"
  

#line 1458 "fig2lat.ctr"
  exit(exval); return exval;
}


