PLplot  5.11.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plargs.c
Go to the documentation of this file.
1 // Maurice LeBrun mjl@dino.ph.utexas.edu
2 // Institute for Fusion Studies University of Texas at Austin
3 //
4 // Copyright (C) 1993-2004 Maurice LeBrun
5 // Copyright (C) 2004 Andrew Ross
6 // Copyright (C) 2015 Alan W. Irwin
7 //
8 // This file is part of PLplot.
9 //
10 // PLplot is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Library General Public License as published
12 // by the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14 //
15 // PLplot is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Library General Public License for more details.
19 //
20 // You should have received a copy of the GNU Library General Public License
21 // along with PLplot; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // Some parts of this code were derived from "xterm.c" and "ParseCmd.c" of
25 // the X-windows Version 11 distribution. The copyright notice is
26 // reproduced here:
27 //
28 // Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
29 // and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
30 //
31 // All Rights Reserved
32 //
33 // The full permission notice is given in the PLplot documentation.
34 //
35 //--------------------------------------------------------------------------
36 //
97 
98 #include "plplotP.h"
99 #include <ctype.h>
100 
101 #ifdef HAVE_CRT_EXTERNS_H
102 //
103 // This include file has the declaration for _NSGetArgc(). See below.
104 //
105 #include <crt_externs.h>
106 #endif
107 
108 // Support functions
109 
110 static int ParseOpt( int *, const char ***, int *, const char ***, PLOptionTable * );
111 static int ProcessOpt( const char *, PLOptionTable *, int *, const char ***, int * );
112 static int GetOptarg( const char **, int *, const char ***, int * );
113 static void Help( void );
114 static void Syntax( void );
115 
116 // Option handlers
117 
118 static int opt_h( const char *, const char *, void * );
119 static int opt_v( const char *, const char *, void * );
120 static int opt_verbose( const char *, const char *, void * );
121 static int opt_debug( const char *, const char *, void * );
122 static int opt_hack( const char *, const char *, void * );
123 static int opt_dev( const char *, const char *, void * );
124 static int opt_o( const char *, const char *, void * );
125 static int opt_geo( const char *, const char *, void * );
126 static int opt_a( const char *, const char *, void * );
127 static int opt_jx( const char *, const char *, void * );
128 static int opt_jy( const char *, const char *, void * );
129 static int opt_mar( const char *, const char *, void * );
130 static int opt_ori( const char *, const char *, void * );
131 static int opt_freeaspect( const char *, const char *, void * );
132 static int opt_portrait( const char *, const char *, void * );
133 static int opt_width( const char *, const char *, void * );
134 static int opt_bg( const char *, const char *, void * );
135 static int opt_ncol0( const char *, const char *, void * );
136 static int opt_ncol1( const char *, const char *, void * );
137 static int opt_fam( const char *, const char *, void * );
138 static int opt_fsiz( const char *, const char *, void * );
139 static int opt_fbeg( const char *, const char *, void * );
140 static int opt_finc( const char *, const char *, void * );
141 static int opt_fflen( const char *, const char *, void * );
142 static int opt_bufmax( const char *, const char *, void * );
143 static int opt_nopixmap( const char *, const char *, void * );
144 static int opt_db( const char *, const char *, void * );
145 static int opt_np( const char *, const char *, void * );
146 static int opt_px( const char *, const char *, void * );
147 static int opt_py( const char *, const char *, void * );
148 static int opt_wplt( const char *, const char *, void * );
149 static int opt_drvopt( const char *, const char *, void * );
150 
151 static int opt_plserver( const char *, const char *, void * );
152 static int opt_plwindow( const char *, const char *, void * );
153 static int opt_auto_path( const char *, const char *, void * );
154 static int opt_bufmax( const char *, const char *, void * );
155 static int opt_server_name( const char *, const char *, void * );
156 static int opt_tk_file( const char *, const char *, void * );
157 static int opt_dpi( const char *, const char *, void * );
158 static int opt_dev_compression( const char *, const char *, void * );
159 static int opt_cmap0( const char *, const char *, void * );
160 static int opt_cmap1( const char *, const char *, void * );
161 static int opt_locale( const char *, const char *, void * );
162 static int opt_eofill( const char *, const char *, void * );
163 
164 static int opt_mfo( const char *, const char *, void * );
165 static int opt_mfi( const char *, const char *, void * );
166 
167 // Global variables
168 
169 static const char *program = NULL;
170 static const char *usage = NULL;
171 
172 static int mode_full;
173 static int mode_quiet;
174 static int mode_nodelete;
175 static int mode_showall;
176 static int mode_noprogram;
177 static int mode_nodash;
178 static int mode_skip;
179 
180 // Temporary buffer used for parsing
181 
182 #define OPTMAX 1024
183 static char opttmp[OPTMAX];
184 
185 //--------------------------------------------------------------------------
235 //--------------------------------------------------------------------------
236 
238  {
239  "showall", // Turns on invisible options
240  NULL,
241  NULL,
242  &mode_showall,
244  "-showall",
245  "Turns on invisible options"
246  },
247  {
248  "h", // Help
249  opt_h,
250  NULL,
251  NULL,
252  PL_OPT_FUNC,
253  "-h",
254  "Print out this message"
255  },
256  {
257  "v", // Version
258  opt_v,
259  NULL,
260  NULL,
261  PL_OPT_FUNC,
262  "-v",
263  "Print out the PLplot library version number"
264  },
265  {
266  "verbose", // Be more verbose than usual
267  opt_verbose,
268  NULL,
269  NULL,
270  PL_OPT_FUNC,
271  "-verbose",
272  "Be more verbose than usual"
273  },
274  {
275  "debug", // Print debugging info
276  opt_debug,
277  NULL,
278  NULL,
279  PL_OPT_FUNC,
280  "-debug",
281  "Print debugging info (implies -verbose)"
282  },
283  {
284  "hack", // Enable driver-specific hack(s)
285  opt_hack,
286  NULL,
287  NULL,
289  "-hack",
290  "Enable driver-specific hack(s)"
291  },
292  {
293  "dev", // Output device
294  opt_dev,
295  NULL,
296  NULL,
298  "-dev name",
299  "Output device name"
300  },
301  {
302  "o", // Output filename
303  opt_o,
304  NULL,
305  NULL,
307  "-o name",
308  "Output filename"
309  },
310  {
311  "display", // X server
312  opt_o,
313  NULL,
314  NULL,
316  "-display name",
317  "X server to contact"
318  },
319  {
320  "px", // Plots per page in x
321  opt_px,
322  NULL,
323  NULL,
325  "-px number",
326  "Plots per page in x"
327  },
328  {
329  "py", // Plots per page in y
330  opt_py,
331  NULL,
332  NULL,
334  "-py number",
335  "Plots per page in y"
336  },
337  {
338  "geometry", // Geometry
339  opt_geo,
340  NULL,
341  NULL,
343  "-geometry geom",
344  "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc."
345  },
346  {
347  "geo", // Geometry (alias)
348  opt_geo,
349  NULL,
350  NULL,
352  "-geo geom",
353  "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc."
354  },
355  {
356  "wplt", // Plot window
357  opt_wplt,
358  NULL,
359  NULL,
361  "-wplt xl,yl,xr,yr",
362  "Relative coordinates [0-1] of window into plot"
363  },
364  {
365  "mar", // Margin
366  opt_mar,
367  NULL,
368  NULL,
370  "-mar margin",
371  "Margin space in relative coordinates (0 to 0.5, def 0)"
372  },
373  {
374  "a", // Aspect ratio
375  opt_a,
376  NULL,
377  NULL,
379  "-a aspect",
380  "Page aspect ratio (def: same as output device)"
381  },
382  {
383  "jx", // Justification in x
384  opt_jx,
385  NULL,
386  NULL,
388  "-jx justx",
389  "Page justification in x (-0.5 to 0.5, def 0)"
390  },
391  {
392  "jy", // Justification in y
393  opt_jy,
394  NULL,
395  NULL,
397  "-jy justy",
398  "Page justification in y (-0.5 to 0.5, def 0)"
399  },
400  {
401  "ori", // Orientation
402  opt_ori,
403  NULL,
404  NULL,
406  "-ori orient",
407  "Plot orientation (0,1,2,3=landscape,portrait,seascape,upside-down)"
408  },
409  {
410  "freeaspect", // floating aspect ratio
412  NULL,
413  NULL,
414  PL_OPT_FUNC,
415  "-freeaspect",
416  "Allow aspect ratio to adjust to orientation swaps"
417  },
418  {
419  "portrait", // floating aspect ratio
420  opt_portrait,
421  NULL,
422  NULL,
423  PL_OPT_FUNC,
424  "-portrait",
425  "Sets portrait mode (both orientation and aspect ratio)"
426  },
427  {
428  "width", // Pen width
429  opt_width,
430  NULL,
431  NULL,
433  "-width width",
434  "Sets pen width (0 <= width)"
435  },
436  {
437  "bg", // Background color
438  opt_bg,
439  NULL,
440  NULL,
442  "-bg color",
443  "Background color (FF0000=opaque red, 0000FF_0.1=blue with alpha of 0.1)"
444  },
445  {
446  "ncol0", // Allocated colors in cmap 0
447  opt_ncol0,
448  NULL,
449  NULL,
451  "-ncol0 n",
452  "Number of colors to allocate in cmap 0 (upper bound)"
453  },
454  {
455  "ncol1", // Allocated colors in cmap 1
456  opt_ncol1,
457  NULL,
458  NULL,
460  "-ncol1 n",
461  "Number of colors to allocate in cmap 1 (upper bound)"
462  },
463  {
464  "fam", // Familying on switch
465  opt_fam,
466  NULL,
467  NULL,
468  PL_OPT_FUNC,
469  "-fam",
470  "Create a family of output files"
471  },
472  {
473  "fsiz", // Family file size
474  opt_fsiz,
475  NULL,
476  NULL,
478  "-fsiz size[kKmMgG]",
479  "Output family file size (e.g. -fsiz 0.5G, def MB)"
480  },
481  {
482  "fbeg", // Family starting member
483  opt_fbeg,
484  NULL,
485  NULL,
487  "-fbeg number",
488  "First family member number on output"
489  },
490  {
491  "finc", // Family member increment
492  opt_finc,
493  NULL,
494  NULL,
496  "-finc number",
497  "Increment between family members"
498  },
499  {
500  "fflen", // Family member min field width
501  opt_fflen,
502  NULL,
503  NULL,
505  "-fflen length",
506  "Family member number minimum field width"
507  },
508  {
509  "nopixmap", // Do not use pixmaps
510  opt_nopixmap,
511  NULL,
512  NULL,
513  PL_OPT_FUNC,
514  "-nopixmap",
515  "Don't use pixmaps in X-based drivers"
516  },
517  {
518  "db", // Double buffering on switch
519  opt_db,
520  NULL,
521  NULL,
522  PL_OPT_FUNC,
523  "-db",
524  "Double buffer X window output"
525  },
526  {
527  "np", // Page pause off switch
528  opt_np,
529  NULL,
530  NULL,
531  PL_OPT_FUNC,
532  "-np",
533  "No pause between pages"
534  },
535  {
536  "bufmax", // # bytes sent before flushing output
537  opt_bufmax,
538  NULL,
539  NULL,
541  "-bufmax",
542  "bytes sent before flushing output"
543  },
544  {
545  "server_name", // Main window name of server
547  NULL,
548  NULL,
550  "-server_name name",
551  "Main window name of PLplot server (tk driver)"
552  },
553  {
554  "plserver", // PLplot server name
555  opt_plserver,
556  NULL,
557  NULL,
559  "-plserver name",
560  "Invoked name of PLplot server (tk driver)"
561  },
562  {
563  "plwindow", // PLplot container window name
564  opt_plwindow,
565  NULL,
566  NULL,
568  "-plwindow name",
569  "Name of PLplot container window (tk driver)"
570  },
571  {
572  "auto_path", // Additional directory(s) to autoload
574  NULL,
575  NULL,
577  "-auto_path dir",
578  "Additional directory(s) to autoload (tk driver)"
579  },
580  {
581  "tk_file", // -file option for plserver
582  opt_tk_file,
583  NULL,
584  NULL,
586  "-tk_file file",
587  "file for plserver (tk driver)"
588  },
589  {
590  "dpi", // Dots per inch
591  opt_dpi,
592  NULL,
593  NULL,
595  "-dpi dpi",
596  "Resolution, in dots per inch (e.g. -dpi 360x360)"
597  },
598  {
599  "compression", // compression
601  NULL,
602  NULL,
604  "-compression num",
605  "Sets compression level in supporting devices"
606  },
607  {
608  "cmap0",
609  opt_cmap0,
610  NULL,
611  NULL,
613  "-cmap0 file name",
614  "Initializes color table 0 from a cmap0.pal format file in one of standard PLplot paths."
615  },
616  {
617  "cmap1",
618  opt_cmap1,
619  NULL,
620  NULL,
622  "-cmap1 file name",
623  "Initializes color table 1 from a cmap1.pal format file in one of standard PLplot paths."
624  },
625  {
626  "locale",
627  opt_locale,
628  NULL,
629  NULL,
630  PL_OPT_FUNC,
631  "-locale",
632  "Use locale environment (e.g., LC_ALL, LC_NUMERIC, or LANG) to set LC_NUMERIC locale (which affects decimal point separator)."
633  },
634  {
635  "eofill",
636  opt_eofill,
637  NULL,
638  NULL,
639  PL_OPT_FUNC,
640  "-eofill",
641  "For the case where the boundary of the filled region is self-intersecting, use the even-odd fill rule rather than the default nonzero fill rule."
642  },
643  {
644  "drvopt", // Driver specific options
645  opt_drvopt,
646  NULL,
647  NULL,
649  "-drvopt option[=value][,option[=value]]*",
650  "Driver specific options"
651  },
652  {
653  "mfo", // Metafile output option
654  opt_mfo,
655  NULL,
656  NULL,
658  "-mfo PLplot metafile name",
659  "Write the plot to the specified PLplot metafile"
660  },
661  {
662  "mfi", // Metafile output option
663  opt_mfi,
664  NULL,
665  NULL,
667  "-mfi PLplot metafile name",
668  "Read the specified PLplot metafile"
669  },
670  {
671  NULL, // option
672  NULL, // handler
673  NULL, // client data
674  NULL, // address of variable to set
675  0, // mode flag
676  NULL, // short syntax
677  NULL
678  } // long syntax
679 };
680 
681 static const char *plplot_notes[] = {
682  "All parameters must be white-space delimited. Some options are driver",
683  "dependent. Please see the PLplot reference document for more detail.",
684  NULL
685 };
686 
687 //--------------------------------------------------------------------------
701 //--------------------------------------------------------------------------
702 
703 typedef struct
704 {
706  const char *name;
707  const char **notes;
708 } PLOptionInfo;
709 
712  "PLplot options",
714 };
715 
716 #define PL_MAX_OPT_TABLES 10
718  {
720  "PLplot options",
722  }
723 };
724 
725 // The structure that hold the driver specific command line options
726 
727 typedef struct DrvOptCmd
728 {
729  char *option;
730  char *value;
731  struct DrvOptCmd *next;
732 } DrvOptCmd;
733 
734 // the variable where opt_drvopt() stores the driver specific command line options
735 static DrvOptCmd drv_opt = { NULL, NULL, NULL };
736 
737 static int tables = 1;
738 
739 #ifdef PL_DEPRECATED
740 //--------------------------------------------------------------------------
741 // plSetOpt()
742 //
751 //--------------------------------------------------------------------------
752 
753 int
754 plSetOpt( const char * opt, const char *opt_arg )
755 {
756  return ( c_plsetopt( opt, opt_arg ) );
757 }
758 #endif //#ifdef PL_DEPRECATED
759 
760 int
761 c_plsetopt( const char * opt, const char *opt_arg )
762 {
763  int mode = 0, argc = 2, status;
764  const char *argv[3];
765 
766  argv[0] = opt;
767  argv[1] = opt_arg;
768  argv[2] = NULL;
769  mode =
774 
775  status = plparseopts( &argc, argv, mode );
776  if ( status )
777  {
778  fprintf( stderr, "plSetOpt: Unrecognized option %s\n", opt );
779  }
780  return status;
781 }
782 
783 //--------------------------------------------------------------------------
784 // plMergeOpts()
785 //
792 //--------------------------------------------------------------------------
793 
794 int
795 plMergeOpts( PLOptionTable *options, const char *name, const char **notes )
796 {
797  PLOptionTable *tab;
798 
799  pllib_init();
800 
801 // Check to make sure option table has been terminated correctly
802 
803  for ( tab = (PLOptionTable *) options; tab->opt; tab++ )
804  ;
805 
806 // We've reached the last table entry. All the subentries must be NULL or 0
807 
808  if ( ( tab->handler != NULL ) ||
809  ( tab->client_data != NULL ) ||
810  ( tab->var != NULL ) ||
811  ( tab->mode != 0 ) ||
812  ( tab->syntax != NULL ) ||
813  ( tab->desc != NULL ) )
814  {
815  plabort( "plMergeOpts: input table improperly terminated" );
816  return 1;
817  }
818 
819 // No room for more tables
820 
821  if ( tables++ >= PL_MAX_OPT_TABLES )
822  {
823  plabort( "plMergeOpts: max tables limit exceeded, table not merged" );
824  return 1;
825  }
826 
827  ploption_info[tables - 1].options = options;
828  ploption_info[tables - 1].name = name;
829  ploption_info[tables - 1].notes = notes;
830 
831  return 0;
832 }
833 
834 //--------------------------------------------------------------------------
835 // plClearOpts()
836 //
839 //--------------------------------------------------------------------------
840 
841 void
842 plClearOpts( void )
843 {
844  tables = 0;
845 }
846 
847 //--------------------------------------------------------------------------
848 // plResetOpts()
849 //
852 //--------------------------------------------------------------------------
853 
854 void
855 plResetOpts( void )
856 {
857  ploption_info[0] = ploption_info_default;
858  tables = 1;
859 }
860 
861 //--------------------------------------------------------------------------
862 // plparseopts()
863 //
874 //--------------------------------------------------------------------------
875 
876 int
877 c_plparseopts( int *p_argc, const char **argv, PLINT mode )
878 {
879  const char **argsave, **argend;
880  int i, myargc, myargcsave, status = 0;
881 
882 
883 // Initialize
884 
885  mode_full = mode & PL_PARSE_FULL;
886  mode_quiet = mode & PL_PARSE_QUIET;
890  mode_nodash = mode & PL_PARSE_NODASH;
891  mode_skip = mode & PL_PARSE_SKIP;
892 
893  myargc = ( *p_argc );
894  argend = argv + myargc;
895 
896 // If program name is first argument, save and advance
897 
898  if ( !mode_noprogram )
899  {
900  plsc->program = plstrdup( argv[0] );
901  program = (const char *) plsc->program;
902  --myargc; ++argv;
903  }
904  if ( myargc == 0 )
905  return 0;
906 
907  // Process the command line
908 
909  // Special hack to deal with -debug option before
910  // pllib_init() is called.
911  argsave = argv;
912  myargcsave = myargc;
913  for (; myargc > 0; --myargc, ++argv )
914  {
915  // Allow for "holes" in argv list
916  if ( *argv == NULL || *argv[0] == '\0' )
917  continue;
918 
919  if ( ( !mode_nodash && !strcmp( *argv, "-debug" ) ) || ( mode_nodash && !strcmp( *argv, "debug" ) ) )
920  {
921  //fprintf(stderr, "Found debug option in argv\n");
922  // Loop over all options tables, starting with the last
923  for ( i = tables - 1; i >= 0; i-- )
924  {
925  // Check option table for option
926 
927  status = ParseOpt( &myargc, &argv, p_argc, &argsave,
928  ploption_info[i].options );
929 
930  if ( !status )
931  break;
932  }
933  break;
934  }
935  }
936  // Restore pointers to condition before the above loop
937  // Although array length and content stored in those pointers
938  // is likely changed.
939  myargc = myargcsave;
940  argv = argsave;
941 
942  pllib_init();
943 
944  argsave = argv;
945  for (; myargc > 0; --myargc, ++argv )
946  {
947  // Allow for "holes" in argv list
948  if ( *argv == NULL || *argv[0] == '\0' )
949  continue;
950 
951  // Loop over all options tables, starting with the last
952  for ( i = tables - 1; i >= 0; i-- )
953  {
954  // Check option table for option
955 
956  status = ParseOpt( &myargc, &argv, p_argc, &argsave,
957  ploption_info[i].options );
958 
959  if ( !status )
960  break;
961  }
962 
963  // Handle error return as specified by the mode flag
964 
965  if ( status == -1 )
966  {
967  // No match. Keep going if mode_skip is set, otherwise abort if
968  // fully parsing, else return without error.
969 
970  status = 0;
971 
972  if ( mode_skip )
973  {
974  if ( !mode_nodelete )
975  *argsave++ = *argv;
976  continue;
977  }
978  if ( !mode_quiet && mode_full )
979  {
980  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
981  plOptUsage();
982  }
983  if ( mode_full )
984  exit( 1 );
985 
986  break;
987  }
988  else if ( status == 1 )
989  {
990  // Illegal or badly formed
991 
992  if ( !mode_quiet )
993  {
994  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
995  plOptUsage();
996  }
997  if ( mode_full )
998  exit( 1 );
999 
1000  break;
1001  }
1002  else if ( status == 2 )
1003  {
1004  // Informational option encountered (-h or -v)
1005 
1006  exit( 0 );
1007  }
1008  }
1009 
1010 // Compress and NULL-terminate argv
1011 
1012  if ( !mode_nodelete )
1013  {
1014  for ( i = 0; i < myargc; i++ )
1015  *argsave++ = *argv++;
1016 
1017  if ( argsave < argend )
1018  {
1019  *argsave = NULL;
1020 #ifdef HAVE_NSGETARGC
1021  //
1022  // Modify the global argc variable to match the shortened argv.
1023  // The global argc and argv must be kept consistent so that future
1024  // users of them (e.g. libraries loaded later with a device driver)
1025  // will not try to dereference the null pointer at the end of the
1026  // shortened argv array.
1027  //
1028  *_NSGetArgc() = *p_argc;
1029 #endif
1030  }
1031  }
1032 
1033  return status;
1034 }
1035 
1036 //--------------------------------------------------------------------------
1037 // ParseOpt()
1038 //
1049 //--------------------------------------------------------------------------
1050 
1051 static int
1052 ParseOpt( int *p_myargc, const char ***p_argv, int *p_argc, const char ***p_argsave,
1053  PLOptionTable *option_table )
1054 {
1055  PLOptionTable *tab;
1056  const char *opt;
1057 
1058 // Only handle actual flags and their arguments
1059 
1060  if ( mode_nodash || ( *p_argv )[0][0] == '-' )
1061  {
1062  opt = ( *p_argv )[0];
1063  if ( *opt == '-' )
1064  opt++;
1065 
1066  for ( tab = option_table; tab->opt; tab++ )
1067  {
1068  // Skip if option not enabled
1069 
1070  if ( tab->mode & PL_OPT_DISABLED )
1071  continue;
1072 
1073  // Try to match it
1074 
1075  if ( *opt == *tab->opt && !strcmp( opt, tab->opt ) )
1076  {
1077  // Option matched, so remove from argv list if applicable.
1078 
1079  if ( !mode_nodelete )
1080  {
1081  if ( tab->mode & PL_OPT_NODELETE )
1082  ( *( *p_argsave )++ ) = ( **p_argv );
1083  else
1084  --( *p_argc );
1085  }
1086 
1087  // Process option (and argument if applicable)
1088 
1089  return ( ProcessOpt( opt, tab, p_myargc, p_argv, p_argc ) );
1090  }
1091  }
1092  }
1093 
1094  return -1;
1095 }
1096 
1097 //--------------------------------------------------------------------------
1098 // ProcessOpt()
1099 //
1109 //--------------------------------------------------------------------------
1110 
1111 static int
1112 ProcessOpt( const char * opt, PLOptionTable *tab, int *p_myargc, const char ***p_argv,
1113  int *p_argc )
1114 {
1115  int need_arg, res;
1116  const char *opt_arg = NULL;
1117 
1118 // Get option argument if necessary
1119 
1121 
1122  if ( tab->mode & need_arg )
1123  {
1124  if ( GetOptarg( &opt_arg, p_myargc, p_argv, p_argc ) )
1125  return 1;
1126  }
1127 
1128 // Process argument
1129 
1130  switch ( tab->mode & 0xFF00 )
1131  {
1132  case PL_OPT_FUNC:
1133 
1134  // Call function handler to do the job
1135 
1136  if ( tab->handler == NULL )
1137  {
1138  fprintf( stderr,
1139  "ProcessOpt: no handler specified for option %s\n",
1140  tab->opt );
1141  return 1;
1142  }
1143 
1144  if ( mode_nodelete && opt_arg )
1145  {
1146  // Make a copy, since handler may mung opt_arg with strtok()
1147  char *copy =
1148  (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
1149  if ( copy == NULL )
1150  {
1151  plabort( "ProcessOpt: out of memory" );
1152  return 1;
1153  }
1154  strcpy( copy, opt_arg );
1155  res = ( ( *tab->handler )( opt, copy, tab->client_data ) );
1156  free( (void *) copy );
1157  return res;
1158  }
1159  else
1160  {
1161  return ( ( *tab->handler )( opt, opt_arg, tab->client_data ) );
1162  }
1163 
1164  case PL_OPT_BOOL:
1165 
1166  // Set *var as a boolean
1167 
1168  if ( tab->var == NULL )
1169  {
1170  fprintf( stderr,
1171  "ProcessOpt: no variable specified for option %s\n",
1172  tab->opt );
1173  return 1;
1174  }
1175  *(int *) tab->var = 1;
1176  break;
1177 
1178  case PL_OPT_INT:
1179 
1180  // Set *var as an int
1181 
1182  if ( tab->var == NULL )
1183  {
1184  fprintf( stderr,
1185  "ProcessOpt: no variable specified for option %s\n",
1186  tab->opt );
1187  return 1;
1188  }
1189  *(int *) tab->var = atoi( opt_arg );
1190  break;
1191 
1192  case PL_OPT_FLOAT:
1193 
1194  // Set *var as a float
1195 
1196  if ( tab->var == NULL )
1197  {
1198  fprintf( stderr,
1199  "ProcessOpt: no variable specified for option %s\n",
1200  tab->opt );
1201  return 1;
1202  }
1203  *(PLFLT *) tab->var = atof( opt_arg );
1204  break;
1205 
1206  case PL_OPT_STRING:
1207 
1208  // Set var (can be NULL initially) to point to opt_arg string
1209 
1210  *(const char **) tab->var = opt_arg;
1211  break;
1212 
1213  default:
1214 
1215  // Somebody messed up..
1216 
1217  fprintf( stderr,
1218  "ProcessOpt: invalid processing mode for option %s\n",
1219  tab->opt );
1220  return 1;
1221  }
1222  return 0;
1223 }
1224 
1225 //--------------------------------------------------------------------------
1226 // GetOptarg()
1227 //
1238 //--------------------------------------------------------------------------
1239 
1240 static int
1241 GetOptarg( const char **popt_arg, int *p_myargc, const char ***p_argv, int *p_argc )
1242 {
1243  int result = 0;
1244 
1245  --( *p_myargc );
1246 
1247  if ( ( *p_myargc ) <= 0 ) // oops, no more arguments
1248  result = 1;
1249 
1250  if ( !result )
1251  {
1252  ( *p_argv )++;
1253  if ( ( *p_argv )[0][0] == '-' && isalpha( ( *p_argv )[0][1] ) )
1254  {
1255  ( *p_argv )--; // oops, next arg is a flag
1256  result = 1;
1257  }
1258  }
1259 
1260  if ( !result ) // yeah, the user got it right
1261  {
1262  ( *p_argc )--;
1263  *popt_arg = ( *p_argv )[0];
1264  }
1265  else
1266  {
1267  if ( !mode_quiet )
1268  {
1269  fprintf( stderr, "Argument missing for %s option.\n", ( *p_argv )[0] );
1270  plOptUsage();
1271  }
1272  }
1273  return result;
1274 }
1275 
1276 //--------------------------------------------------------------------------
1277 // plSetUsage()
1278 //
1284 //--------------------------------------------------------------------------
1285 
1286 void
1287 plSetUsage( const char *program_string, const char *usage_string )
1288 {
1289  if ( program_string != NULL )
1290  program = program_string;
1291 
1292  if ( usage_string != NULL )
1293  usage = usage_string;
1294 }
1295 
1296 //--------------------------------------------------------------------------
1297 // plOptUsage()
1298 //
1301 //--------------------------------------------------------------------------
1302 
1303 void
1304 plOptUsage( void )
1305 {
1306  if ( usage == NULL )
1307  fprintf( stderr, "\nUsage:\n %s [options]\n", program );
1308  else
1309  fputs( usage, stderr );
1310 
1311  Syntax();
1312 
1313  fprintf( stderr, "\n\nType %s -h for a full description.\n\n",
1314  program );
1315 }
1316 
1317 //--------------------------------------------------------------------------
1318 // Syntax()
1319 //
1322 //--------------------------------------------------------------------------
1323 
1324 static void
1325 Syntax( void )
1326 {
1327  PLOptionTable *tab;
1328  int i, col, len;
1329 
1330 // Loop over all options tables
1331 
1332  for ( i = tables - 1; i >= 0; i-- )
1333  {
1334  // Introducer
1335 
1336  if ( ploption_info[i].name )
1337  fprintf( stderr, "\n%s:", ploption_info[i].name );
1338  else
1339  fputs( "\nUser options:", stderr );
1340 
1341  // Print syntax for each option
1342 
1343  col = 80;
1344  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1345  {
1346  if ( tab->mode & PL_OPT_DISABLED )
1347  continue;
1348 
1349  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1350  continue;
1351 
1352  if ( tab->syntax == NULL )
1353  continue;
1354 
1355  len = 3 + (int) strlen( tab->syntax ); // space [ string ]
1356  if ( col + len > 79 )
1357  {
1358  fprintf( stderr, "\n " ); // 3 spaces
1359  col = 3;
1360  }
1361  fprintf( stderr, " [%s]", tab->syntax );
1362  col += len;
1363  }
1364  fprintf( stderr, "\n" );
1365  }
1366 }
1367 
1368 //--------------------------------------------------------------------------
1369 // Help()
1370 //
1373 //--------------------------------------------------------------------------
1374 
1375 static void
1376 Help( void )
1377 {
1378  PLOptionTable *tab;
1379  const char **note;
1380  int i;
1381  FILE *outfile = stderr;
1382 
1383 #ifdef HAVE_POPEN
1384  FILE *pager = NULL;
1385  if ( getenv( "PAGER" ) != NULL )
1386  pager = (FILE *) popen( "$PAGER", "w" );
1387  if ( pager == NULL )
1388  pager = (FILE *) popen( "more", "w" );
1389  if ( pager != NULL )
1390  outfile = pager;
1391 #endif
1392 
1393 // Usage line
1394 
1395  if ( usage == NULL )
1396  fprintf( outfile, "\nUsage:\n %s [options]\n", program );
1397  else
1398  fputs( usage, outfile );
1399 
1400 // Loop over all options tables
1401 
1402  for ( i = tables - 1; i >= 0; i-- )
1403  {
1404  // Introducer
1405 
1406  if ( ploption_info[i].name )
1407  fprintf( outfile, "\n%s:\n", ploption_info[i].name );
1408  else
1409  fputs( "\nUser options:\n", outfile );
1410 
1411  // Print description for each option
1412 
1413  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1414  {
1415  if ( tab->mode & PL_OPT_DISABLED )
1416  continue;
1417 
1418  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1419  continue;
1420 
1421  if ( tab->desc == NULL )
1422  continue;
1423 
1424  if ( tab->mode & PL_OPT_INVISIBLE )
1425  fprintf( outfile, " * %-20s %s\n", tab->syntax, tab->desc );
1426  else
1427  fprintf( outfile, " %-20s %s\n", tab->syntax, tab->desc );
1428  }
1429 
1430  // Usage notes
1431 
1432  if ( ploption_info[i].notes )
1433  {
1434  putc( '\n', outfile );
1435  for ( note = ploption_info[i].notes; *note; note++ )
1436  {
1437  fputs( *note, outfile );
1438  putc( '\n', outfile );
1439  }
1440  }
1441  }
1442 
1443 #ifdef HAVE_POPEN
1444  if ( pager != NULL )
1445  pclose( pager );
1446 #endif
1447 }
1448 
1449 //--------------------------------------------------------------------------
1450 // plParseDrvOpts
1451 //
1458 //--------------------------------------------------------------------------
1459 
1460 int
1462 {
1463  DrvOptCmd *drvp;
1464  DrvOpt *t;
1465  int fl;
1466  char msg[80];
1467  memset( msg, '\0', sizeof ( msg ) );
1468 
1469  if ( !drv_opt.option )
1470  return 1;
1471 
1472  drvp = &drv_opt;
1473  do
1474  {
1475  t = acc_opt; fl = 0;
1476  while ( t->opt )
1477  {
1478  if ( strcmp( drvp->option, t->opt ) == 0 )
1479  {
1480  fl = 1;
1481  switch ( t->type )
1482  {
1483  case DRV_STR:
1484  *(char **) ( t->var_ptr ) = ( drvp->value );
1485 #ifdef DEBUG
1486  fprintf( stderr, "plParseDrvOpts: %s %s\n", t->opt, *(char **) t->var_ptr );
1487 #endif
1488  break;
1489 
1490  case DRV_INT:
1491  if ( sscanf( drvp->value, "%d", (int *) t->var_ptr ) != 1 )
1492  {
1493  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1494  plexit( msg );
1495  }
1496 #ifdef DEBUG
1497  fprintf( stderr, "plParseDrvOpts: %s %d\n", t->opt, *(int *) t->var_ptr );
1498 #endif
1499  break;
1500 
1501  case DRV_FLT:
1502  if ( sscanf( drvp->value, "%f", (float *) t->var_ptr ) != 1 )
1503  {
1504  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1505  plexit( msg );
1506  }
1507 #ifdef DEBUG
1508  fprintf( stderr, "plParseDrvOpts: %s %f\n", t->opt, *(float *) t->var_ptr );
1509 #endif
1510  break;
1511  }
1512  }
1513  t++;
1514  }
1515 
1516  if ( !fl )
1517  {
1518  snprintf( msg, sizeof ( msg ) - 1, "Option '%s' not recognized.\n\nRecognized options for this driver are:\n", drvp->option );
1519  plwarn( msg );
1520  plHelpDrvOpts( acc_opt );
1521  plexit( "" );
1522  }
1523  }
1524  while ( ( drvp = drvp->next ) )
1525  ;
1526 
1527  return 0;
1528 }
1529 
1530 //--------------------------------------------------------------------------
1531 // plHelpDrvOpts
1532 //
1537 //--------------------------------------------------------------------------
1538 
1539 void
1541 {
1542  DrvOpt *t;
1543 
1544  t = acc_opt;
1545  while ( t->opt )
1546  {
1547  fprintf( stderr, "%s:\t%s\n", t->opt, t->hlp_msg );
1548  t++;
1549  }
1550 }
1551 
1552 //--------------------------------------------------------------------------
1553 // tidyDrvOpts
1554 //
1557 //--------------------------------------------------------------------------
1558 
1559 void
1561 {
1562  DrvOptCmd *drvp, *drvpl;
1563 
1564  drvp = &drv_opt;
1565  do
1566  {
1567  drvpl = drvp;
1568  drvp = drvpl->next;
1569 
1570  free( drvpl->option );
1571  free( drvpl->value );
1572  // Free additional DrvOptCmd variables -
1573  // first entry in list is a static global variable
1574  if ( drvpl != &drv_opt )
1575  free( drvpl );
1576  } while ( drvp != NULL );
1577 
1578  // initialize drv_opt if it's used again
1579  drv_opt.option = NULL;
1580  drv_opt.value = NULL;
1581  drv_opt.next = NULL;
1582 }
1583 
1584 
1585 //--------------------------------------------------------------------------
1586 // Option handlers
1587 //--------------------------------------------------------------------------
1588 
1589 //--------------------------------------------------------------------------
1590 // opt_h()
1591 //
1601 //--------------------------------------------------------------------------
1602 
1603 static int
1604 opt_h( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1605 {
1606  if ( !mode_quiet )
1607  Help();
1608 
1609  return 2;
1610 }
1611 
1612 //--------------------------------------------------------------------------
1613 // opt_v()
1614 //
1624 //--------------------------------------------------------------------------
1625 
1626 static int
1627 opt_v( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1628 {
1629  if ( !mode_quiet )
1630  fprintf( stderr, "PLplot library version: %s\n", PLPLOT_VERSION );
1631 
1632  return 2;
1633 }
1634 
1635 //--------------------------------------------------------------------------
1636 // opt_verbose()
1637 //
1647 //--------------------------------------------------------------------------
1648 
1649 static int
1650 opt_verbose( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1651 {
1652  plsc->verbose = 1;
1653  return 0;
1654 }
1655 
1656 //--------------------------------------------------------------------------
1657 // opt_debug()
1658 //
1668 //--------------------------------------------------------------------------
1669 
1670 static int
1671 opt_debug( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1672 {
1673  plsc->debug = 1;
1674  plsc->verbose = 1;
1675  return 0;
1676 }
1677 
1678 //--------------------------------------------------------------------------
1679 // opt_hack()
1680 //
1690 //--------------------------------------------------------------------------
1691 
1692 static int
1693 opt_hack( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1694 {
1695  plsc->hack = 1;
1696  return 0;
1697 }
1698 
1699 //--------------------------------------------------------------------------
1700 // opt_dev()
1701 //
1711 //--------------------------------------------------------------------------
1712 
1713 static int
1714 opt_dev( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1715 {
1716  plsdev( opt_arg );
1717  return 0;
1718 }
1719 
1720 //--------------------------------------------------------------------------
1721 // opt_o()
1722 //
1732 //--------------------------------------------------------------------------
1733 
1734 static int
1735 opt_o( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1736 {
1737  plsfnam( opt_arg );
1738  return 0;
1739 }
1740 
1741 //--------------------------------------------------------------------------
1742 // opt_mar()
1743 //
1753 //--------------------------------------------------------------------------
1754 
1755 static int
1756 opt_mar( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1757 {
1758  plsdidev( atof( opt_arg ), PL_NOTSET, PL_NOTSET, PL_NOTSET );
1759  return 0;
1760 }
1761 
1762 //--------------------------------------------------------------------------
1763 // opt_a()
1764 //
1774 //--------------------------------------------------------------------------
1775 
1776 static int
1777 opt_a( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1778 {
1779  plsdidev( PL_NOTSET, atof( opt_arg ), PL_NOTSET, PL_NOTSET );
1780  return 0;
1781 }
1782 
1783 //--------------------------------------------------------------------------
1784 // opt_jx()
1785 //
1795 //--------------------------------------------------------------------------
1796 
1797 static int
1798 opt_jx( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1799 {
1800  plsdidev( PL_NOTSET, PL_NOTSET, atof( opt_arg ), PL_NOTSET );
1801  return 0;
1802 }
1803 
1804 //--------------------------------------------------------------------------
1805 // opt_jy()
1806 //
1816 //--------------------------------------------------------------------------
1817 
1818 static int
1819 opt_jy( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1820 {
1821  plsdidev( PL_NOTSET, PL_NOTSET, PL_NOTSET, atof( opt_arg ) );
1822  return 0;
1823 }
1824 
1825 //--------------------------------------------------------------------------
1826 // opt_ori()
1827 //
1837 //--------------------------------------------------------------------------
1838 
1839 static int
1840 opt_ori( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1841 {
1842  plsdiori( atof( opt_arg ) );
1843  return 0;
1844 }
1845 
1846 //--------------------------------------------------------------------------
1847 // opt_freeaspect()
1848 //
1858 //--------------------------------------------------------------------------
1859 
1860 static int
1861 opt_freeaspect( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1862 {
1863  plsc->freeaspect = 1;
1864  return 0;
1865 }
1866 
1867 //--------------------------------------------------------------------------
1868 // opt_portrait()
1869 //
1893 //--------------------------------------------------------------------------
1894 
1895 static int
1896 opt_portrait( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1897 {
1898  plsc->portrait = 1;
1899  return 0;
1900 }
1901 
1902 //--------------------------------------------------------------------------
1903 // opt_width()
1904 //
1914 //--------------------------------------------------------------------------
1915 
1916 static int
1917 opt_width( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1918 {
1919  double width;
1920 
1921  width = atof( opt_arg );
1922  if ( width < 0. )
1923  {
1924  fprintf( stderr, "?invalid width\n" );
1925  return 1;
1926  }
1927  else
1928  {
1929  plwidth( width );
1930  plsc->widthlock = 1;
1931  }
1932  return 0;
1933 }
1934 
1935 //--------------------------------------------------------------------------
1936 // opt_bg()
1937 //
1951 //--------------------------------------------------------------------------
1952 
1953 static int
1954 opt_bg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1955 {
1956  const char *rgb;
1957  char *color_field, *alpha_field;
1958  long bgcolor;
1959  PLINT r, g, b;
1960  PLFLT a;
1961 
1962 // Strip off leading "#" (TK-ism) if present.
1963 
1964  if ( *opt_arg == '#' )
1965  rgb = opt_arg + 1;
1966  else
1967  rgb = opt_arg;
1968 
1969  strncpy( opttmp, rgb, OPTMAX - 1 );
1970  opttmp[OPTMAX - 1] = '\0';
1971 
1972  if ( strchr( opttmp, '_' ) )
1973  {
1974  // e.g., -bg ff0000_0.1
1975  color_field = strtok( opttmp, "_" );
1976  alpha_field = strtok( NULL, "_" );
1977  }
1978  else
1979  {
1980  color_field = opttmp;
1981  alpha_field = NULL;
1982  }
1983 
1984  bgcolor = strtol( color_field, NULL, 16 );
1985 
1986 // Must be either a 3 or 6 digit hex number
1987 // If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC).
1988 
1989  switch ( strlen( color_field ) )
1990  {
1991  case 3:
1992  r = (PLINT) ( ( bgcolor & 0xF00 ) >> 8 );
1993  g = (PLINT) ( ( bgcolor & 0x0F0 ) >> 4 );
1994  b = (PLINT) ( bgcolor & 0x00F );
1995 
1996  r = r | ( r << 4 );
1997  g = g | ( g << 4 ); // doubling
1998  b = b | ( b << 4 );
1999  break;
2000 
2001  case 6:
2002  r = (PLINT) ( ( bgcolor & 0xFF0000 ) >> 16 );
2003  g = (PLINT) ( ( bgcolor & 0x00FF00 ) >> 8 );
2004  b = (PLINT) ( bgcolor & 0x0000FF );
2005  break;
2006 
2007  default:
2008  fprintf( stderr, "Unrecognized background color value %s\n", color_field );
2009  return 1;
2010  }
2011 
2012  if ( alpha_field )
2013  a = atof( alpha_field );
2014  else
2015  a = 1.;
2016 
2017  plscolbga( r, g, b, a );
2018 
2019  return 0;
2020 }
2021 
2022 //--------------------------------------------------------------------------
2023 // opt_ncol0()
2024 //
2034 //--------------------------------------------------------------------------
2035 
2036 static int
2037 opt_ncol0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2038 {
2039  plsc->ncol0 = atoi( opt_arg );
2040  return 0;
2041 }
2042 
2043 //--------------------------------------------------------------------------
2044 // opt_ncol1()
2045 //
2055 //--------------------------------------------------------------------------
2056 
2057 static int
2058 opt_ncol1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2059 {
2060  plsc->ncol1 = atoi( opt_arg );
2061  return 0;
2062 }
2063 
2064 //--------------------------------------------------------------------------
2065 // opt_wplt()
2066 //
2076 //--------------------------------------------------------------------------
2077 
2078 static int
2079 opt_wplt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2080 {
2081  char *field;
2082  PLFLT xl, yl, xr, yr;
2083 
2084  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2085  opttmp[OPTMAX - 1] = '\0';
2086 
2087  if ( ( field = strtok( opttmp, "," ) ) == NULL )
2088  return 1;
2089 
2090  xl = atof( field );
2091 
2092  if ( ( field = strtok( NULL, "," ) ) == NULL )
2093  return 1;
2094 
2095  yl = atof( field );
2096 
2097  if ( ( field = strtok( NULL, "," ) ) == NULL )
2098  return 1;
2099 
2100  xr = atof( field );
2101 
2102  if ( ( field = strtok( NULL, "," ) ) == NULL )
2103  return 1;
2104 
2105  yr = atof( field );
2106 
2107  plsdiplt( xl, yl, xr, yr );
2108  return 0;
2109 }
2110 
2111 //--------------------------------------------------------------------------
2112 // opt_drvopt()
2113 //
2123 //--------------------------------------------------------------------------
2124 
2125 static int
2126 opt_drvopt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2127 {
2128  char t, *tt, *option, *value;
2129  int fl = 0;
2130  DrvOptCmd *drvp;
2131 
2132  option = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2133  if ( option == NULL )
2134  plexit( "opt_drvopt: Out of memory!?" );
2135 
2136  value = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2137  if ( value == NULL )
2138  plexit( "opt_drvopt: Out of memory!?" );
2139 
2140  drvp = &drv_opt;
2141  *option = *value = '\0';
2142  tt = option;
2143  while ( ( t = *opt_arg++ ) )
2144  {
2145  switch ( t )
2146  {
2147  case ',':
2148  if ( fl )
2149  fl = 0;
2150  else
2151  {
2152  value[0] = '1';
2153  value[1] = '\0';
2154  }
2155 
2156  *tt = '\0'; tt = option;
2157  drvp->option = plstrdup( option ); // it should not be release, because of familying
2158  drvp->value = plstrdup( value ); // don't release
2159  drvp->next = (DrvOptCmd *) malloc( sizeof ( DrvOptCmd ) ); // don't release
2160  if ( drvp->next == NULL )
2161  plexit( "opt_drvopt: Out of memory!?\n" );
2162 
2163  drvp = drvp->next;
2164  break;
2165 
2166  case '=':
2167  fl = 1;
2168  *tt = '\0'; tt = value;
2169  break;
2170 
2171  default:
2172  *tt++ = t;
2173  }
2174  }
2175 
2176  *tt = '\0';
2177  if ( !fl )
2178  {
2179  value[0] = '1';
2180  value[1] = '\0';
2181  }
2182 
2183  drvp->option = plstrdup( option ); // don't release
2184  drvp->value = plstrdup( value ); // don't release
2185  drvp->next = NULL;
2186 
2187 #ifdef DEBUG
2188  fprintf( stderr, "\nopt_drvopt: -drvopt parsed options:\n" );
2189  drvp = &drv_opt;
2190  do
2191  fprintf( stderr, "%s %s\n", drvp->option, drvp->value );
2192  while ( drvp = drvp->next );
2193  fprintf( stderr, "\n" );
2194 #endif
2195 
2196  free( option ); free( value );
2197 
2198  return 0;
2199 }
2200 
2201 //--------------------------------------------------------------------------
2202 // opt_fam()
2203 //
2213 //--------------------------------------------------------------------------
2214 
2215 static int
2216 opt_fam( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2217 {
2218  plsfam( 1, -1, -1 );
2219  return 0;
2220 }
2221 
2222 //--------------------------------------------------------------------------
2223 // opt_fsiz()
2224 //
2243 //--------------------------------------------------------------------------
2244 
2245 static int
2246 opt_fsiz( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2247 {
2248  PLINT bytemax;
2249  size_t len = strlen( opt_arg );
2250  char lastchar = opt_arg[len - 1];
2251  PLFLT multiplier = 1.0e6;
2252  char *spec = (char *) malloc( len + 1 );
2253 
2254  if ( spec == NULL )
2255  plexit( "opt_fsiz: Insufficient memory" );
2256 
2257 // Interpret optional suffix
2258 
2259  switch ( lastchar )
2260  {
2261  case 'k':
2262  case 'K':
2263  multiplier = 1.0e3; len--;
2264  break;
2265  case 'm':
2266  case 'M':
2267  multiplier = 1.0e6; len--;
2268  break;
2269  case 'g':
2270  case 'G':
2271  multiplier = 1.0e9; len--;
2272  break;
2273  }
2274  strncpy( spec, opt_arg, len );
2275  spec[len] = '\0';
2276 
2277  bytemax = (PLINT) ( multiplier * atof( spec ) );
2278  if ( bytemax <= 0 )
2279  {
2280  fprintf( stderr, "?invalid file size %d. 2.14G is the maximum.\n", bytemax );
2281  return 1;
2282  }
2283  plsfam( 1, -1, bytemax );
2284 
2285  free( spec );
2286  return 0;
2287 }
2288 
2289 //--------------------------------------------------------------------------
2290 // opt_fbeg()
2291 //
2301 //--------------------------------------------------------------------------
2302 
2303 static int
2304 opt_fbeg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2305 {
2306  plsc->member = atoi( opt_arg );
2307 
2308  return 0;
2309 }
2310 
2311 //--------------------------------------------------------------------------
2312 // opt_finc()
2313 //
2323 //--------------------------------------------------------------------------
2324 
2325 static int
2326 opt_finc( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2327 {
2328  plsc->finc = atoi( opt_arg );
2329 
2330  return 0;
2331 }
2332 
2333 //--------------------------------------------------------------------------
2334 // opt_fflen()
2335 //
2345 //--------------------------------------------------------------------------
2346 
2347 static int
2348 opt_fflen( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2349 {
2350  plsc->fflen = atoi( opt_arg );
2351 
2352  return 0;
2353 }
2354 
2355 //--------------------------------------------------------------------------
2356 // opt_np()
2357 //
2367 //--------------------------------------------------------------------------
2368 
2369 static int
2370 opt_np( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2371 {
2372  plspause( 0 );
2373  return 0;
2374 }
2375 
2376 //--------------------------------------------------------------------------
2377 // opt_nopixmap()
2378 //
2388 //--------------------------------------------------------------------------
2389 
2390 static int
2391 opt_nopixmap( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2392 {
2393  plsc->nopixmap = 1;
2394  return 0;
2395 }
2396 
2397 //--------------------------------------------------------------------------
2398 // opt_db()
2399 //
2409 //--------------------------------------------------------------------------
2410 
2411 static int
2412 opt_db( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2413 {
2414  plsc->db = 1;
2415  return 0;
2416 }
2417 
2418 //--------------------------------------------------------------------------
2419 // opt_bufmax()
2420 //
2430 //--------------------------------------------------------------------------
2431 
2432 static int
2433 opt_bufmax( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2434 {
2435  plsc->bufmax = atoi( opt_arg );
2436  return 0;
2437 }
2438 
2439 //--------------------------------------------------------------------------
2440 // opt_server_name()
2441 //
2451 //--------------------------------------------------------------------------
2452 
2453 static int
2454 opt_server_name( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2455 {
2456  plsc->server_name = plstrdup( opt_arg );
2457  return 0;
2458 }
2459 
2460 //--------------------------------------------------------------------------
2461 // opt_plserver()
2462 //
2472 //--------------------------------------------------------------------------
2473 
2474 static int
2475 opt_plserver( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2476 {
2477  plsc->plserver = plstrdup( opt_arg );
2478  return 0;
2479 }
2480 
2481 //--------------------------------------------------------------------------
2482 // opt_plwindow()
2483 //
2493 //--------------------------------------------------------------------------
2494 
2495 static int
2496 opt_plwindow( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2497 {
2498  if ( ( plsc->plwindow = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2499  {
2500  plexit( "opt_plwindow: Insufficient memory" );
2501  }
2502  strcpy( plsc->plwindow, opt_arg );
2503  return 0;
2504 }
2505 
2506 //--------------------------------------------------------------------------
2507 // opt_auto_path()
2508 //
2518 //--------------------------------------------------------------------------
2519 
2520 static int
2521 opt_auto_path( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2522 {
2523  plsc->auto_path = plstrdup( opt_arg );
2524  return 0;
2525 }
2526 
2527 //--------------------------------------------------------------------------
2528 // opt_px()
2529 //
2539 //--------------------------------------------------------------------------
2540 
2541 static int
2542 opt_px( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2543 {
2544  plssub( atoi( opt_arg ), -1 );
2545  return 0;
2546 }
2547 
2548 //--------------------------------------------------------------------------
2549 // opt_py()
2550 //
2560 //--------------------------------------------------------------------------
2561 
2562 static int
2563 opt_py( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2564 {
2565  plssub( -1, atoi( opt_arg ) );
2566  return 0;
2567 }
2568 
2569 //--------------------------------------------------------------------------
2570 // opt_geo()
2571 //
2585 //--------------------------------------------------------------------------
2586 
2587 static int
2588 opt_geo( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2589 {
2590  int numargs;
2591  PLFLT xdpi = 0., ydpi = 0.;
2592  PLINT xwid, ywid, xoff, yoff;
2593 
2594 // The TK driver uses the geometry string directly
2595 
2596  if ( ( plsc->geometry = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2597  {
2598  plexit( "opt_geo: Insufficient memory" );
2599  }
2600 
2601  strcpy( plsc->geometry, opt_arg );
2602 
2603  numargs = sscanf( opt_arg, "%dx%d%d%d", &xwid, &ywid, &xoff, &yoff );
2604  if ( numargs == 2 )
2605  {
2606  xoff = 0;
2607  yoff = 0;
2608  if ( xwid == 0 )
2609  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2610  if ( ywid == 0 )
2611  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2612  if ( xwid < 0 )
2613  {
2614  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2615  return 1;
2616  }
2617  if ( ywid < 0 )
2618  {
2619  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2620  return 1;
2621  }
2622  }
2623  else if ( numargs == 4 )
2624  {
2625  if ( xwid == 0 )
2626  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2627  if ( ywid == 0 )
2628  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2629  if ( xwid < 0 )
2630  {
2631  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2632  return 1;
2633  }
2634  if ( ywid < 0 )
2635  {
2636  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2637  return 1;
2638  }
2639  if ( abs( xoff ) == 0 )
2640  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2641  if ( abs( yoff ) == 0 )
2642  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2643  }
2644  else
2645  {
2646  numargs = sscanf( opt_arg, "%d%d", &xoff, &yoff );
2647  if ( numargs == 2 )
2648  {
2649  xwid = 0;
2650  ywid = 0;
2651  if ( abs( xoff ) == 0 )
2652  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2653  if ( abs( yoff ) == 0 )
2654  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2655  }
2656  else
2657  {
2658  fprintf( stderr, "?invalid -geometry %s\n", opt_arg );
2659  return 1;
2660  }
2661  }
2662  //fprintf( stderr, "xwid, ywid, xoff, yoff = %d, %d, %d, %d\n", xwid, ywid, xoff, yoff );
2663  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2664  return 0;
2665 }
2666 
2667 //--------------------------------------------------------------------------
2668 // opt_tk_file()
2669 //
2678 //--------------------------------------------------------------------------
2679 
2680 static int
2681 opt_tk_file( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2682 {
2683  if ( ( plsc->tk_file = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2684  {
2685  plexit( "opt_tk_file: Insufficient memory" );
2686  }
2687 
2688  strcpy( plsc->tk_file, opt_arg );
2689  return 0;
2690 }
2691 
2692 //--------------------------------------------------------------------------
2693 // opt_dpi()
2694 //
2708 //--------------------------------------------------------------------------
2709 
2710 static int
2711 opt_dpi( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2712 {
2713  char *field;
2714  PLFLT xdpi = 0., ydpi = 0.;
2715  PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0;
2716 
2717  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2718  opttmp[OPTMAX - 1] = '\0';
2719  if ( strchr( opttmp, 'x' ) )
2720  {
2721  field = strtok( opttmp, "x" );
2722  xdpi = atof( field );
2723  if ( xdpi == 0 )
2724  fprintf( stderr, "?invalid xdpi\n" );
2725 
2726  if ( ( field = strtok( NULL, " " ) ) == NULL )
2727  return 1;
2728 
2729  ydpi = atof( field );
2730  if ( ydpi == 0 )
2731  fprintf( stderr, "?invalid ydpi\n" );
2732  }
2733  else
2734  {
2735  xdpi = atof( opttmp );
2736  ydpi = xdpi;
2737  if ( xdpi == 0 )
2738  return 1;
2739  }
2740 
2741  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2742  return 0;
2743 }
2744 
2745 //--------------------------------------------------------------------------
2746 // opt_dev_compression()
2747 //
2756 //--------------------------------------------------------------------------
2757 
2758 static int
2759 opt_dev_compression( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2760 {
2761  PLINT comp = 0;
2762 
2763  comp = atoi( opt_arg );
2764  if ( comp == 0 )
2765  {
2766  fprintf( stderr, "?invalid compression\n" );
2767  return 1;
2768  }
2769  plscompression( comp );
2770 
2771  return 0;
2772 }
2773 
2774 //--------------------------------------------------------------------------
2775 // opt_cmap0()
2776 //
2785 //--------------------------------------------------------------------------
2786 
2787 static int
2788 opt_cmap0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2789 {
2790  plspal0( opt_arg );
2791  return 0;
2792 }
2793 
2794 //--------------------------------------------------------------------------
2795 // opt_cmap1()
2796 //
2805 //--------------------------------------------------------------------------
2806 
2807 static int
2808 opt_cmap1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2809 {
2810  plspal1( opt_arg, TRUE );
2811  return 0;
2812 }
2813 
2814 //--------------------------------------------------------------------------
2815 // opt_locale()
2816 //
2825 //--------------------------------------------------------------------------
2826 
2827 static int
2828 opt_locale( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2829 {
2830  char *locale;
2831  if ( ( locale = setlocale( LC_NUMERIC, "" ) ) )
2832  {
2833  printf( "LC_NUMERIC locale set to \"%s\"\n", locale );
2834  }
2835  else
2836  {
2837  plwarn( "Could not use invalid environment (e.g., LC_ALL, LC_NUMERIC, or LANG) to set LC_NUMERIC locale. Falling back to LC_NUMERIC \"C\" locale instead.\n" );
2838  if ( !( locale = setlocale( LC_NUMERIC, "C" ) ) )
2839  {
2840  plexit( "Your platform is seriously broken. Not even a \"C\" locale could be set." );
2841  }
2842  }
2843  return 0;
2844 }
2845 
2846 //--------------------------------------------------------------------------
2847 // opt_eofill()
2848 //
2859 //--------------------------------------------------------------------------
2860 
2861 static int
2862 opt_eofill( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2863 {
2864  plsc->dev_eofill = 1;
2865  return 0;
2866 }
2867 
2868 //--------------------------------------------------------------------------
2869 // opt_mfo()
2870 //
2879 //--------------------------------------------------------------------------
2880 
2881 static int
2882 opt_mfo( const char * PL_UNUSED( opt ), const char * opt_arg, void * PL_UNUSED( client_data ) )
2883 {
2884  if ( ( plsc->mf_outfile = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2885  {
2886  plexit( "opt_mfo: Insufficient memory" );
2887  }
2888 
2889  strcpy( plsc->mf_outfile, opt_arg );
2890  return 0;
2891 }
2892 
2893 //--------------------------------------------------------------------------
2894 // opt_mfi()
2895 //
2904 //--------------------------------------------------------------------------
2905 
2906 static int
2907 opt_mfi( const char * PL_UNUSED( opt ), const char * opt_arg, void * PL_UNUSED( client_data ) )
2908 {
2909  if ( ( plsc->mf_infile = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2910  {
2911  plexit( "opt_mfi: Insufficient memory" );
2912  }
2913 
2914  strcpy( plsc->mf_infile, opt_arg );
2915  return 0;
2916 }