/* cmdline.c
Copyright (C) 2005,2006,2007 Eugene K. Ressler, Jr.
This file is part of Sketch, a small, simple system for making
3d drawings with LaTeX and the PSTricks or TikZ package.
Sketch is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
Sketch is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Sketch; see the file COPYING.txt. If not, see
http://www.gnu.org/copyleft */
#include <stdlib.h>
#include "cmdline.h"
#include "emit.h"
#include "memutil.h"
#include "parse.h"
#include "symbol.h"
#include "version.h"
void
usage (int exit_code)
{
fprintf (stderr, "\n"
"sketch [options] file1 [-D tag][-U tag] file2...\n"
"-h Print this message to standard error\n"
"-v Print version info to standard output\n"
"-V x.y Tell Sketch your PSTricks version is x.y\n"
"-d Debug parser (for developers)\n"
"-b Use BSP rather than Painters algorithm for HSR\n"
"-T[u|e][p[P|T]] Produce a complete LaTeX document\n"
" u U.S. paper size (8.5 x 11 inches) (default)\n"
" e European A4 paper size (297 x 210 mm)\n"
" p Print document template to stdout\n"
" P Print PSTricks version of doc template (default)\n"
" T Print TikZ version of doc template\n"
" L Print LaTeX version of template (default)\n"
" C Print ConTeXt version of template\n"
"-t templatefile Load user document template\n"
" (any text file with escape %%SKETCH_OUTPUT%%)\n"
"-o outfile Put output in outfile (default is stdout)\n"
"-D tag Define given tag\n"
"-U tag Undefine given tag\n");
exit (exit_code);
}
static int
is_doc_template_file_name (char *s)
{
return s[0] != '-' || s[1] == '\0';
}
// process argv[1..argc-1] to fill in env and prepare it for wrapping
void
process_global_options (CMD_LINE_OPT_ENV * env, int argc, char **argv,
SYMBOL_TABLE * sym_tab)
{
int i, j;
unsigned lang, set;
// i = 0
// argc = 0;
// argv = NULL;
// sym_tab = NULL;
// bsp_only_p = false
// doc_template_file_name = NULL
// out_file_name = NULL
// skip_input_p = false
// n_files = 0
SET_STRUCT_ZERO (env);
env->sym_tab = sym_tab;
parse_pst_version(env->pst_version, STRINGIFY(ASSUMED_PST_VERSION), no_line);
// we'll copy args that need to be processed in order with filenames here.
// the convention will be that args with paramaters like -Dfoo will be
// separated into -D and foo, so we could end up doubling the number of args.
env->argv = safe_malloc (2 * (argc - 1) * sizeof (char *));
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 'b':
env->bsp_only_p = 1;
break;
case 'd':
yydebug = 1;
break;
case 'h':
usage (0);
break;
case 'D':
case 'U':
env->argv[env->argc++] = argv[i];
if (argv[i][2])
env->argv[env->argc++] = &argv[i][2];
else if (i + 1 < argc)
env->argv[env->argc++] = argv[++i];
else
err (no_line, "missing tag after %s", argv[i]);
break;
case 'o':
if (env->out_file_name)
err (no_line, "only one use of -o is allowed");
if (argv[i][2])
env->out_file_name = &argv[i][2];
else
{
if (i + 1 < argc)
env->out_file_name = &argv[++i][0];
else
err (no_line, "missing file name after -o");
}
break;
case 't':
if (argv[i][2])
env->doc_template_file_name = &argv[i][2];
else if (i + 1 < argc
&& is_doc_template_file_name (argv[i + 1]))
env->doc_template_file_name = argv[++i];
else
err (no_line, "missing document template file name after -t");
break;
case 'T':
j = 2;
if (argv[i][j] == 'e')
{
env->doc_template_file_name =
standard_euro_doc_template_file_name_flag;
++j;
}
else if (argv[i][j] == 'u')
{
env->doc_template_file_name =
standard_us_doc_template_file_name_flag;
++j;
}
else
{
env->doc_template_file_name =
standard_us_doc_template_file_name_flag;
}
if (argv[i][j] == 'p')
{
lang = set = 0;
for (++j; argv[i][j]; ++j)
{
switch (argv[i][j])
{
case 'P':
if (set & GEOL_GRAPHICS_BIT)
err (no_line, "-tP with two graphics package specs");
lang |= GEOL_PSTRICKS;
set |= GEOL_GRAPHICS_BIT;
break;
case 'T':
if (set & GEOL_GRAPHICS_BIT)
err (no_line, "-tP with two graphics package specs");
lang |= GEOL_TIKZ;
set |= GEOL_GRAPHICS_BIT;
break;
case 'L':
if (set & GEOL_TEX_MACROS_BIT)
err (no_line, "-tP with two macro package specs");
lang |= GEOL_LATEX;
set |= GEOL_TEX_MACROS_BIT;
break;
case 'C':
if (set & GEOL_TEX_MACROS_BIT)
err (no_line, "-tP with two macro package specs");
lang |= GEOL_CONTEXT;
set |= GEOL_TEX_MACROS_BIT;
break;
default:
err (no_line, "unrecognized language spec after -Tp, '%c'",
argv[i][j]);
}
}
printf ("%% %s document template:\n%s",
output_language_str[lang],
doc_template_from_file (env->doc_template_file_name, lang));
env->skip_input_p = 1;
}
else if (argv[i][j] != '\0')
{
err (no_line, "unrecognized modifier of option '-T%c'",
argv[i][j]);
}
break;
case 'V':
if (argv[i][2] != '\0')
{
parse_pst_version(env->pst_version, &argv[i][2], no_line);
}
else
{
if (i + 1 < argc)
parse_pst_version(env->pst_version, &argv[++i][0], no_line);
else
err (no_line, "missing PSTricks version");
}
break;
case 'v':
fprintf (stdout, "%% sketch version %s\n", VER_STRING);
fprintf (stdout, "%% assumes PSTricks version %s (change with -V)\n",
env->pst_version->str);
env->skip_input_p = 1;
break;
default:
err (no_line, "unrecognized option '%s'", argv[i]);
break;
}
}
else
{
// no leading -
++env->n_files;
env->argv[env->argc++] = argv[i];
}
}
env->argv = safe_realloc (env->argv, env->argc * sizeof (char *));
}
// advance the environment initialized above until the next filename
// has been found, processing non-global arguments
char *
advance_to_next_file_name (CMD_LINE_OPT_ENV * env)
{
for (; env->i < env->argc; env->i++)
{
if (env->argv[env->i][0] == '-')
{
switch (env->argv[env->i][1])
{
case 'D':
++env->i;
(void) new_symbol (env->sym_tab, env->argv[env->i], NULL,
new_tag_def (), no_line);
break;
case 'U':
// this will produce an error message if tag doesn't exist
++env->i;
if (tag_exists_p (env->sym_tab, env->argv[env->i]))
remove_symbol (env->sym_tab, env->argv[env->i], no_line);
break;
default:
die (no_line, "advance_to_next_file_name: unexpected option %c",
env->argv[env->i][1]);
break;
}
}
else
{
return env->argv[env->i++];
}
}
return NULL;
}