C   8

cmdline.c

Guest on 20th July 2021 03:04:09 PM

  1. /* cmdline.c
  2.    Copyright (C)  Eugene K. Ressler, Jr.
  3.  
  4. This file is part of Sketch, a small, simple system for making
  5. 3d drawings with LaTeX and the PSTricks or TikZ package.
  6.  
  7. Sketch is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 3, or (at your option)
  10. any later version.
  11.  
  12. Sketch is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Sketch; see the file COPYING.txt.  If not, see
  19. http://www.gnu.org/copyleft */
  20.  
  21. #include <stdlib.h>
  22. #include "cmdline.h"
  23. #include "emit.h"
  24. #include "memutil.h"
  25. #include "parse.h"
  26. #include "symbol.h"
  27. #include "version.h"
  28.  
  29. void
  30. usage (int exit_code)
  31. {
  32.   fprintf (stderr, "\n"
  33.            "sketch [options] file1 [-D tag][-U tag] file2...\n"
  34.            "-h                 Print this message to standard error\n"
  35.            "-v                 Print version info to standard output\n"
  36.            "-V x.y             Tell Sketch your PSTricks version is x.y\n"
  37.            "-d                 Debug parser (for developers)\n"
  38.            "-b                 Use BSP rather than Painters algorithm for HSR\n"
  39.            "-T[u|e][p[P|T]]    Produce a complete LaTeX document\n"
  40.            "  u                U.S. paper size (8.5 x 11 inches) (default)\n"
  41.            "  e                European A4 paper size (297 x 210 mm)\n"
  42.            "  p                Print document template to stdout\n"
  43.            "    P              Print PSTricks version of doc template (default)\n"
  44.            "    T              Print TikZ version of doc template\n"
  45.            "      L            Print LaTeX version of template (default)\n"
  46.            "      C            Print ConTeXt version of template\n"
  47.            "-t templatefile    Load user document template\n"
  48.            "                     (any text file with escape %%SKETCH_OUTPUT%%)\n"
  49.            "-o outfile         Put output in outfile (default is stdout)\n"
  50.            "-D tag             Define given tag\n"
  51.            "-U tag             Undefine given tag\n");
  52.   exit (exit_code);
  53. }
  54.  
  55. static int
  56. is_doc_template_file_name (char *s)
  57. {
  58.   return s[0] != '-' || s[1] == '\0';
  59. }
  60.  
  61. // process argv[1..argc-1] to fill in env and prepare it for wrapping
  62. void
  63. process_global_options (CMD_LINE_OPT_ENV * env, int argc, char **argv,
  64.                         SYMBOL_TABLE * sym_tab)
  65. {
  66.   int i, j;
  67.   unsigned lang, set;
  68.  
  69.   // i = 0
  70.   // argc = 0;
  71.   // argv = NULL;
  72.   // sym_tab = NULL;
  73.   // bsp_only_p = false
  74.   // doc_template_file_name = NULL
  75.   // out_file_name = NULL
  76.   // skip_input_p = false
  77.   // n_files = 0
  78.   SET_STRUCT_ZERO (env);
  79.   env->sym_tab = sym_tab;
  80.   parse_pst_version(env->pst_version, STRINGIFY(ASSUMED_PST_VERSION), no_line);
  81.  
  82.   // we'll copy args that need to be processed in order with filenames here.
  83.   // the convention will be that args with paramaters like -Dfoo will be
  84.   // separated into -D and foo, so we could end up doubling the number of args.
  85.   env->argv = safe_malloc (2 * (argc - 1) * sizeof (char *));
  86.  
  87.   for (i = 1; i < argc; i++)
  88.     {
  89.       if (argv[i][0] == '-')
  90.         {
  91.           switch (argv[i][1])
  92.             {
  93.             case 'b':
  94.               env->bsp_only_p = 1;
  95.               break;
  96.             case 'd':
  97.               yydebug = 1;
  98.               break;
  99.             case 'h':
  100.               usage (0);
  101.               break;
  102.             case 'D':
  103.             case 'U':
  104.               env->argv[env->argc++] = argv[i];
  105.               if (argv[i][2])
  106.                 env->argv[env->argc++] = &argv[i][2];
  107.               else if (i + 1 < argc)
  108.                 env->argv[env->argc++] = argv[++i];
  109.               else
  110.                 err (no_line, "missing tag after %s", argv[i]);
  111.               break;
  112.             case 'o':
  113.               if (env->out_file_name)
  114.                 err (no_line, "only one use of -o is allowed");
  115.               if (argv[i][2])
  116.                 env->out_file_name = &argv[i][2];
  117.               else
  118.                 {
  119.                   if (i + 1 < argc)
  120.                     env->out_file_name = &argv[++i][0];
  121.                   else
  122.                     err (no_line, "missing file name after -o");
  123.                 }
  124.               break;
  125.             case 't':
  126.               if (argv[i][2])
  127.                 env->doc_template_file_name = &argv[i][2];
  128.               else if (i + 1 < argc
  129.                        && is_doc_template_file_name (argv[i + 1]))
  130.                 env->doc_template_file_name = argv[++i];
  131.               else
  132.                 err (no_line, "missing document template file name after -t");
  133.               break;
  134.             case 'T':
  135.               j = 2;
  136.               if (argv[i][j] == 'e')
  137.                 {
  138.                   env->doc_template_file_name =
  139.                     standard_euro_doc_template_file_name_flag;
  140.                   ++j;
  141.                 }
  142.               else if (argv[i][j] == 'u')
  143.                 {
  144.                   env->doc_template_file_name =
  145.                     standard_us_doc_template_file_name_flag;
  146.                   ++j;
  147.                 }
  148.               else
  149.                 {
  150.                   env->doc_template_file_name =
  151.                     standard_us_doc_template_file_name_flag;
  152.                 }
  153.               if (argv[i][j] == 'p')
  154.                 {
  155.                   lang = set = 0;
  156.                   for (++j; argv[i][j]; ++j)
  157.                     {
  158.                       switch (argv[i][j])
  159.                         {
  160.                         case 'P':
  161.                           if (set & GEOL_GRAPHICS_BIT)
  162.                             err (no_line, "-tP with two graphics package specs");
  163.                           lang |= GEOL_PSTRICKS;
  164.                           set  |= GEOL_GRAPHICS_BIT;
  165.                           break;
  166.                         case 'T':
  167.                           if (set & GEOL_GRAPHICS_BIT)
  168.                             err (no_line, "-tP with two graphics package specs");
  169.                           lang |= GEOL_TIKZ;
  170.                           set  |= GEOL_GRAPHICS_BIT;
  171.                           break;
  172.                         case 'L':
  173.                           if (set & GEOL_TEX_MACROS_BIT)
  174.                             err (no_line, "-tP with two macro package specs");
  175.                           lang |= GEOL_LATEX;
  176.                           set  |= GEOL_TEX_MACROS_BIT;
  177.                           break;
  178.                         case 'C':
  179.                           if (set & GEOL_TEX_MACROS_BIT)
  180.                             err (no_line, "-tP with two macro package specs");
  181.                           lang |= GEOL_CONTEXT;
  182.                           set  |= GEOL_TEX_MACROS_BIT;
  183.                           break;
  184.                         default:
  185.                           err (no_line, "unrecognized language spec after -Tp, '%c'",
  186.                                argv[i][j]);
  187.                         }
  188.                     }
  189.                   printf ("%% %s document template:\n%s",
  190.                           output_language_str[lang],
  191.                           doc_template_from_file (env->doc_template_file_name, lang));
  192.                   env->skip_input_p = 1;
  193.                 }
  194.               else if (argv[i][j] != '\0')
  195.                 {
  196.                   err (no_line, "unrecognized modifier of option '-T%c'",
  197.                        argv[i][j]);
  198.                 }
  199.               break;
  200.             case 'V':
  201.               if (argv[i][2] != '\0')
  202.                 {
  203.                   parse_pst_version(env->pst_version, &argv[i][2], no_line);
  204.                 }
  205.               else
  206.                 {
  207.                   if (i + 1 < argc)
  208.                     parse_pst_version(env->pst_version, &argv[++i][0], no_line);
  209.                   else
  210.                     err (no_line, "missing PSTricks version");
  211.                 }
  212.               break;
  213.             case 'v':
  214.               fprintf (stdout, "%% sketch version %s\n", VER_STRING);
  215.               fprintf (stdout, "%% assumes PSTricks version %s (change with -V)\n",
  216.                        env->pst_version->str);
  217.               env->skip_input_p = 1;
  218.               break;
  219.             default:
  220.               err (no_line, "unrecognized option '%s'", argv[i]);
  221.               break;
  222.             }
  223.         }
  224.       else
  225.         {
  226.           // no leading -
  227.           ++env->n_files;
  228.           env->argv[env->argc++] = argv[i];
  229.         }
  230.     }
  231.   env->argv = safe_realloc (env->argv, env->argc * sizeof (char *));
  232. }
  233.  
  234. // advance the environment initialized above until the next filename
  235. // has been found, processing non-global arguments
  236. char *
  237. advance_to_next_file_name (CMD_LINE_OPT_ENV * env)
  238. {
  239.   for (; env->i < env->argc; env->i++)
  240.     {
  241.       if (env->argv[env->i][0] == '-')
  242.         {
  243.           switch (env->argv[env->i][1])
  244.             {
  245.             case 'D':
  246.               ++env->i;
  247.               (void) new_symbol (env->sym_tab, env->argv[env->i], NULL,
  248.                                  new_tag_def (), no_line);
  249.               break;
  250.             case 'U':
  251.               // this will produce an error message if tag doesn't exist
  252.               ++env->i;
  253.               if (tag_exists_p (env->sym_tab, env->argv[env->i]))
  254.                 remove_symbol (env->sym_tab, env->argv[env->i], no_line);
  255.               break;
  256.             default:
  257.               die (no_line, "advance_to_next_file_name: unexpected option %c",
  258.                    env->argv[env->i][1]);
  259.               break;
  260.             }
  261.         }
  262.       else
  263.         {
  264.           return env->argv[env->i++];
  265.         }
  266.     }
  267.   return NULL;
  268. }

Raw Paste


Login or Register to edit or fork this paste. It's free.