/* 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 #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; }