PLplot  5.11.0
 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, status = 0;
881 
882  pllib_init();
883 
884 // Initialize
885 
886  mode_full = mode & PL_PARSE_FULL;
887  mode_quiet = mode & PL_PARSE_QUIET;
891  mode_nodash = mode & PL_PARSE_NODASH;
892  mode_skip = mode & PL_PARSE_SKIP;
893 
894  myargc = ( *p_argc );
895  argend = argv + myargc;
896 
897 // If program name is first argument, save and advance
898 
899  if ( !mode_noprogram )
900  {
901  plsc->program = plstrdup( argv[0] );
902  program = (const char *) plsc->program;
903  --myargc; ++argv;
904  }
905  if ( myargc == 0 )
906  return 0;
907 
908 // Process the command line
909 
910  argsave = argv;
911  for (; myargc > 0; --myargc, ++argv )
912  {
913  // Allow for "holes" in argv list
914 
915  if ( *argv == NULL || *argv[0] == '\0' )
916  continue;
917 
918  // Loop over all options tables, starting with the last
919 
920  for ( i = tables - 1; i >= 0; i-- )
921  {
922  // Check option table for option
923 
924  status = ParseOpt( &myargc, &argv, p_argc, &argsave,
925  ploption_info[i].options );
926 
927  if ( !status )
928  break;
929  }
930 
931  // Handle error return as specified by the mode flag
932 
933  if ( status == -1 )
934  {
935  // No match. Keep going if mode_skip is set, otherwise abort if
936  // fully parsing, else return without error.
937 
938  status = 0;
939 
940  if ( mode_skip )
941  {
942  if ( !mode_nodelete )
943  *argsave++ = *argv;
944  continue;
945  }
946  if ( !mode_quiet && mode_full )
947  {
948  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
949  plOptUsage();
950  }
951  if ( mode_full )
952  exit( 1 );
953 
954  break;
955  }
956  else if ( status == 1 )
957  {
958  // Illegal or badly formed
959 
960  if ( !mode_quiet )
961  {
962  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
963  plOptUsage();
964  }
965  if ( mode_full )
966  exit( 1 );
967 
968  break;
969  }
970  else if ( status == 2 )
971  {
972  // Informational option encountered (-h or -v)
973 
974  exit( 0 );
975  }
976  }
977 
978 // Compress and NULL-terminate argv
979 
980  if ( !mode_nodelete )
981  {
982  for ( i = 0; i < myargc; i++ )
983  *argsave++ = *argv++;
984 
985  if ( argsave < argend )
986  {
987  *argsave = NULL;
988 #ifdef HAVE_NSGETARGC
989  //
990  // Modify the global argc variable to match the shortened argv.
991  // The global argc and argv must be kept consistent so that future
992  // users of them (e.g. libraries loaded later with a device driver)
993  // will not try to dereference the null pointer at the end of the
994  // shortened argv array.
995  //
996  *_NSGetArgc() = *p_argc;
997 #endif
998  }
999  }
1000 
1001  return status;
1002 }
1003 
1004 //--------------------------------------------------------------------------
1005 // ParseOpt()
1006 //
1017 //--------------------------------------------------------------------------
1018 
1019 static int
1020 ParseOpt( int *p_myargc, const char ***p_argv, int *p_argc, const char ***p_argsave,
1021  PLOptionTable *option_table )
1022 {
1023  PLOptionTable *tab;
1024  const char *opt;
1025 
1026 // Only handle actual flags and their arguments
1027 
1028  if ( mode_nodash || ( *p_argv )[0][0] == '-' )
1029  {
1030  opt = ( *p_argv )[0];
1031  if ( *opt == '-' )
1032  opt++;
1033 
1034  for ( tab = option_table; tab->opt; tab++ )
1035  {
1036  // Skip if option not enabled
1037 
1038  if ( tab->mode & PL_OPT_DISABLED )
1039  continue;
1040 
1041  // Try to match it
1042 
1043  if ( *opt == *tab->opt && !strcmp( opt, tab->opt ) )
1044  {
1045  // Option matched, so remove from argv list if applicable.
1046 
1047  if ( !mode_nodelete )
1048  {
1049  if ( tab->mode & PL_OPT_NODELETE )
1050  ( *( *p_argsave )++ ) = ( **p_argv );
1051  else
1052  --( *p_argc );
1053  }
1054 
1055  // Process option (and argument if applicable)
1056 
1057  return ( ProcessOpt( opt, tab, p_myargc, p_argv, p_argc ) );
1058  }
1059  }
1060  }
1061 
1062  return -1;
1063 }
1064 
1065 //--------------------------------------------------------------------------
1066 // ProcessOpt()
1067 //
1077 //--------------------------------------------------------------------------
1078 
1079 static int
1080 ProcessOpt( const char * opt, PLOptionTable *tab, int *p_myargc, const char ***p_argv,
1081  int *p_argc )
1082 {
1083  int need_arg, res;
1084  const char *opt_arg = NULL;
1085 
1086 // Get option argument if necessary
1087 
1089 
1090  if ( tab->mode & need_arg )
1091  {
1092  if ( GetOptarg( &opt_arg, p_myargc, p_argv, p_argc ) )
1093  return 1;
1094  }
1095 
1096 // Process argument
1097 
1098  switch ( tab->mode & 0xFF00 )
1099  {
1100  case PL_OPT_FUNC:
1101 
1102  // Call function handler to do the job
1103 
1104  if ( tab->handler == NULL )
1105  {
1106  fprintf( stderr,
1107  "ProcessOpt: no handler specified for option %s\n",
1108  tab->opt );
1109  return 1;
1110  }
1111 
1112  if ( mode_nodelete && opt_arg )
1113  {
1114  // Make a copy, since handler may mung opt_arg with strtok()
1115  char *copy =
1116  (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
1117  if ( copy == NULL )
1118  {
1119  plabort( "ProcessOpt: out of memory" );
1120  return 1;
1121  }
1122  strcpy( copy, opt_arg );
1123  res = ( ( *tab->handler )( opt, copy, tab->client_data ) );
1124  free( (void *) copy );
1125  return res;
1126  }
1127  else
1128  {
1129  return ( ( *tab->handler )( opt, opt_arg, tab->client_data ) );
1130  }
1131 
1132  case PL_OPT_BOOL:
1133 
1134  // Set *var as a boolean
1135 
1136  if ( tab->var == NULL )
1137  {
1138  fprintf( stderr,
1139  "ProcessOpt: no variable specified for option %s\n",
1140  tab->opt );
1141  return 1;
1142  }
1143  *(int *) tab->var = 1;
1144  break;
1145 
1146  case PL_OPT_INT:
1147 
1148  // Set *var as an int
1149 
1150  if ( tab->var == NULL )
1151  {
1152  fprintf( stderr,
1153  "ProcessOpt: no variable specified for option %s\n",
1154  tab->opt );
1155  return 1;
1156  }
1157  *(int *) tab->var = atoi( opt_arg );
1158  break;
1159 
1160  case PL_OPT_FLOAT:
1161 
1162  // Set *var as a float
1163 
1164  if ( tab->var == NULL )
1165  {
1166  fprintf( stderr,
1167  "ProcessOpt: no variable specified for option %s\n",
1168  tab->opt );
1169  return 1;
1170  }
1171  *(PLFLT *) tab->var = atof( opt_arg );
1172  break;
1173 
1174  case PL_OPT_STRING:
1175 
1176  // Set var (can be NULL initially) to point to opt_arg string
1177 
1178  *(const char **) tab->var = opt_arg;
1179  break;
1180 
1181  default:
1182 
1183  // Somebody messed up..
1184 
1185  fprintf( stderr,
1186  "ProcessOpt: invalid processing mode for option %s\n",
1187  tab->opt );
1188  return 1;
1189  }
1190  return 0;
1191 }
1192 
1193 //--------------------------------------------------------------------------
1194 // GetOptarg()
1195 //
1206 //--------------------------------------------------------------------------
1207 
1208 static int
1209 GetOptarg( const char **popt_arg, int *p_myargc, const char ***p_argv, int *p_argc )
1210 {
1211  int result = 0;
1212 
1213  --( *p_myargc );
1214 
1215  if ( ( *p_myargc ) <= 0 ) // oops, no more arguments
1216  result = 1;
1217 
1218  if ( !result )
1219  {
1220  ( *p_argv )++;
1221  if ( ( *p_argv )[0][0] == '-' && isalpha( ( *p_argv )[0][1] ) )
1222  {
1223  ( *p_argv )--; // oops, next arg is a flag
1224  result = 1;
1225  }
1226  }
1227 
1228  if ( !result ) // yeah, the user got it right
1229  {
1230  ( *p_argc )--;
1231  *popt_arg = ( *p_argv )[0];
1232  }
1233  else
1234  {
1235  if ( !mode_quiet )
1236  {
1237  fprintf( stderr, "Argument missing for %s option.\n", ( *p_argv )[0] );
1238  plOptUsage();
1239  }
1240  }
1241  return result;
1242 }
1243 
1244 //--------------------------------------------------------------------------
1245 // plSetUsage()
1246 //
1252 //--------------------------------------------------------------------------
1253 
1254 void
1255 plSetUsage( const char *program_string, const char *usage_string )
1256 {
1257  if ( program_string != NULL )
1258  program = program_string;
1259 
1260  if ( usage_string != NULL )
1261  usage = usage_string;
1262 }
1263 
1264 //--------------------------------------------------------------------------
1265 // plOptUsage()
1266 //
1269 //--------------------------------------------------------------------------
1270 
1271 void
1272 plOptUsage( void )
1273 {
1274  if ( usage == NULL )
1275  fprintf( stderr, "\nUsage:\n %s [options]\n", program );
1276  else
1277  fputs( usage, stderr );
1278 
1279  Syntax();
1280 
1281  fprintf( stderr, "\n\nType %s -h for a full description.\n\n",
1282  program );
1283 }
1284 
1285 //--------------------------------------------------------------------------
1286 // Syntax()
1287 //
1290 //--------------------------------------------------------------------------
1291 
1292 static void
1293 Syntax( void )
1294 {
1295  PLOptionTable *tab;
1296  int i, col, len;
1297 
1298 // Loop over all options tables
1299 
1300  for ( i = tables - 1; i >= 0; i-- )
1301  {
1302  // Introducer
1303 
1304  if ( ploption_info[i].name )
1305  fprintf( stderr, "\n%s:", ploption_info[i].name );
1306  else
1307  fputs( "\nUser options:", stderr );
1308 
1309  // Print syntax for each option
1310 
1311  col = 80;
1312  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1313  {
1314  if ( tab->mode & PL_OPT_DISABLED )
1315  continue;
1316 
1317  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1318  continue;
1319 
1320  if ( tab->syntax == NULL )
1321  continue;
1322 
1323  len = 3 + (int) strlen( tab->syntax ); // space [ string ]
1324  if ( col + len > 79 )
1325  {
1326  fprintf( stderr, "\n " ); // 3 spaces
1327  col = 3;
1328  }
1329  fprintf( stderr, " [%s]", tab->syntax );
1330  col += len;
1331  }
1332  fprintf( stderr, "\n" );
1333  }
1334 }
1335 
1336 //--------------------------------------------------------------------------
1337 // Help()
1338 //
1341 //--------------------------------------------------------------------------
1342 
1343 static void
1344 Help( void )
1345 {
1346  PLOptionTable *tab;
1347  const char **note;
1348  int i;
1349  FILE *outfile = stderr;
1350 
1351 #ifdef HAVE_POPEN
1352  FILE *pager = NULL;
1353  if ( getenv( "PAGER" ) != NULL )
1354  pager = (FILE *) popen( "$PAGER", "w" );
1355  if ( pager == NULL )
1356  pager = (FILE *) popen( "more", "w" );
1357  if ( pager != NULL )
1358  outfile = pager;
1359 #endif
1360 
1361 // Usage line
1362 
1363  if ( usage == NULL )
1364  fprintf( outfile, "\nUsage:\n %s [options]\n", program );
1365  else
1366  fputs( usage, outfile );
1367 
1368 // Loop over all options tables
1369 
1370  for ( i = tables - 1; i >= 0; i-- )
1371  {
1372  // Introducer
1373 
1374  if ( ploption_info[i].name )
1375  fprintf( outfile, "\n%s:\n", ploption_info[i].name );
1376  else
1377  fputs( "\nUser options:\n", outfile );
1378 
1379  // Print description for each option
1380 
1381  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1382  {
1383  if ( tab->mode & PL_OPT_DISABLED )
1384  continue;
1385 
1386  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1387  continue;
1388 
1389  if ( tab->desc == NULL )
1390  continue;
1391 
1392  if ( tab->mode & PL_OPT_INVISIBLE )
1393  fprintf( outfile, " * %-20s %s\n", tab->syntax, tab->desc );
1394  else
1395  fprintf( outfile, " %-20s %s\n", tab->syntax, tab->desc );
1396  }
1397 
1398  // Usage notes
1399 
1400  if ( ploption_info[i].notes )
1401  {
1402  putc( '\n', outfile );
1403  for ( note = ploption_info[i].notes; *note; note++ )
1404  {
1405  fputs( *note, outfile );
1406  putc( '\n', outfile );
1407  }
1408  }
1409  }
1410 
1411 #ifdef HAVE_POPEN
1412  if ( pager != NULL )
1413  pclose( pager );
1414 #endif
1415 }
1416 
1417 //--------------------------------------------------------------------------
1418 // plParseDrvOpts
1419 //
1426 //--------------------------------------------------------------------------
1427 
1428 int
1430 {
1431  DrvOptCmd *drvp;
1432  DrvOpt *t;
1433  int fl;
1434  char msg[80];
1435  memset( msg, '\0', sizeof ( msg ) );
1436 
1437  if ( !drv_opt.option )
1438  return 1;
1439 
1440  drvp = &drv_opt;
1441  do
1442  {
1443  t = acc_opt; fl = 0;
1444  while ( t->opt )
1445  {
1446  if ( strcmp( drvp->option, t->opt ) == 0 )
1447  {
1448  fl = 1;
1449  switch ( t->type )
1450  {
1451  case DRV_STR:
1452  *(char **) ( t->var_ptr ) = ( drvp->value );
1453 #ifdef DEBUG
1454  fprintf( stderr, "plParseDrvOpts: %s %s\n", t->opt, *(char **) t->var_ptr );
1455 #endif
1456  break;
1457 
1458  case DRV_INT:
1459  if ( sscanf( drvp->value, "%d", (int *) t->var_ptr ) != 1 )
1460  {
1461  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1462  plexit( msg );
1463  }
1464 #ifdef DEBUG
1465  fprintf( stderr, "plParseDrvOpts: %s %d\n", t->opt, *(int *) t->var_ptr );
1466 #endif
1467  break;
1468 
1469  case DRV_FLT:
1470  if ( sscanf( drvp->value, "%f", (float *) t->var_ptr ) != 1 )
1471  {
1472  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1473  plexit( msg );
1474  }
1475 #ifdef DEBUG
1476  fprintf( stderr, "plParseDrvOpts: %s %f\n", t->opt, *(float *) t->var_ptr );
1477 #endif
1478  break;
1479  }
1480  }
1481  t++;
1482  }
1483 
1484  if ( !fl )
1485  {
1486  snprintf( msg, sizeof ( msg ) - 1, "Option '%s' not recognized.\n\nRecognized options for this driver are:\n", drvp->option );
1487  plwarn( msg );
1488  plHelpDrvOpts( acc_opt );
1489  plexit( "" );
1490  }
1491  }
1492  while ( ( drvp = drvp->next ) )
1493  ;
1494 
1495  return 0;
1496 }
1497 
1498 //--------------------------------------------------------------------------
1499 // plHelpDrvOpts
1500 //
1505 //--------------------------------------------------------------------------
1506 
1507 void
1509 {
1510  DrvOpt *t;
1511 
1512  t = acc_opt;
1513  while ( t->opt )
1514  {
1515  fprintf( stderr, "%s:\t%s\n", t->opt, t->hlp_msg );
1516  t++;
1517  }
1518 }
1519 
1520 //--------------------------------------------------------------------------
1521 // tidyDrvOpts
1522 //
1525 //--------------------------------------------------------------------------
1526 
1527 void
1529 {
1530  DrvOptCmd *drvp, *drvpl;
1531 
1532  drvp = &drv_opt;
1533  do
1534  {
1535  drvpl = drvp;
1536  drvp = drvpl->next;
1537 
1538  free( drvpl->option );
1539  free( drvpl->value );
1540  // Free additional DrvOptCmd variables -
1541  // first entry in list is a static global variable
1542  if ( drvpl != &drv_opt )
1543  free( drvpl );
1544  } while ( drvp != NULL );
1545 
1546  // initialize drv_opt if it's used again
1547  drv_opt.option = NULL;
1548  drv_opt.value = NULL;
1549  drv_opt.next = NULL;
1550 }
1551 
1552 
1553 //--------------------------------------------------------------------------
1554 // Option handlers
1555 //--------------------------------------------------------------------------
1556 
1557 //--------------------------------------------------------------------------
1558 // opt_h()
1559 //
1569 //--------------------------------------------------------------------------
1570 
1571 static int
1572 opt_h( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1573 {
1574  if ( !mode_quiet )
1575  Help();
1576 
1577  return 2;
1578 }
1579 
1580 //--------------------------------------------------------------------------
1581 // opt_v()
1582 //
1592 //--------------------------------------------------------------------------
1593 
1594 static int
1595 opt_v( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1596 {
1597  if ( !mode_quiet )
1598  fprintf( stderr, "PLplot library version: %s\n", PLPLOT_VERSION );
1599 
1600  return 2;
1601 }
1602 
1603 //--------------------------------------------------------------------------
1604 // opt_verbose()
1605 //
1615 //--------------------------------------------------------------------------
1616 
1617 static int
1618 opt_verbose( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1619 {
1620  plsc->verbose = 1;
1621  return 0;
1622 }
1623 
1624 //--------------------------------------------------------------------------
1625 // opt_debug()
1626 //
1636 //--------------------------------------------------------------------------
1637 
1638 static int
1639 opt_debug( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1640 {
1641  plsc->debug = 1;
1642  plsc->verbose = 1;
1643  return 0;
1644 }
1645 
1646 //--------------------------------------------------------------------------
1647 // opt_hack()
1648 //
1658 //--------------------------------------------------------------------------
1659 
1660 static int
1661 opt_hack( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1662 {
1663  plsc->hack = 1;
1664  return 0;
1665 }
1666 
1667 //--------------------------------------------------------------------------
1668 // opt_dev()
1669 //
1679 //--------------------------------------------------------------------------
1680 
1681 static int
1682 opt_dev( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1683 {
1684  plsdev( opt_arg );
1685  return 0;
1686 }
1687 
1688 //--------------------------------------------------------------------------
1689 // opt_o()
1690 //
1700 //--------------------------------------------------------------------------
1701 
1702 static int
1703 opt_o( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1704 {
1705  plsfnam( opt_arg );
1706  return 0;
1707 }
1708 
1709 //--------------------------------------------------------------------------
1710 // opt_mar()
1711 //
1721 //--------------------------------------------------------------------------
1722 
1723 static int
1724 opt_mar( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1725 {
1726  plsdidev( atof( opt_arg ), PL_NOTSET, PL_NOTSET, PL_NOTSET );
1727  return 0;
1728 }
1729 
1730 //--------------------------------------------------------------------------
1731 // opt_a()
1732 //
1742 //--------------------------------------------------------------------------
1743 
1744 static int
1745 opt_a( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1746 {
1747  plsdidev( PL_NOTSET, atof( opt_arg ), PL_NOTSET, PL_NOTSET );
1748  return 0;
1749 }
1750 
1751 //--------------------------------------------------------------------------
1752 // opt_jx()
1753 //
1763 //--------------------------------------------------------------------------
1764 
1765 static int
1766 opt_jx( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1767 {
1768  plsdidev( PL_NOTSET, PL_NOTSET, atof( opt_arg ), PL_NOTSET );
1769  return 0;
1770 }
1771 
1772 //--------------------------------------------------------------------------
1773 // opt_jy()
1774 //
1784 //--------------------------------------------------------------------------
1785 
1786 static int
1787 opt_jy( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1788 {
1789  plsdidev( PL_NOTSET, PL_NOTSET, PL_NOTSET, atof( opt_arg ) );
1790  return 0;
1791 }
1792 
1793 //--------------------------------------------------------------------------
1794 // opt_ori()
1795 //
1805 //--------------------------------------------------------------------------
1806 
1807 static int
1808 opt_ori( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1809 {
1810  plsdiori( atof( opt_arg ) );
1811  return 0;
1812 }
1813 
1814 //--------------------------------------------------------------------------
1815 // opt_freeaspect()
1816 //
1826 //--------------------------------------------------------------------------
1827 
1828 static int
1829 opt_freeaspect( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1830 {
1831  plsc->freeaspect = 1;
1832  return 0;
1833 }
1834 
1835 //--------------------------------------------------------------------------
1836 // opt_portrait()
1837 //
1861 //--------------------------------------------------------------------------
1862 
1863 static int
1864 opt_portrait( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1865 {
1866  plsc->portrait = 1;
1867  return 0;
1868 }
1869 
1870 //--------------------------------------------------------------------------
1871 // opt_width()
1872 //
1882 //--------------------------------------------------------------------------
1883 
1884 static int
1885 opt_width( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1886 {
1887  double width;
1888 
1889  width = atof( opt_arg );
1890  if ( width < 0. )
1891  {
1892  fprintf( stderr, "?invalid width\n" );
1893  return 1;
1894  }
1895  else
1896  {
1897  plwidth( width );
1898  plsc->widthlock = 1;
1899  }
1900  return 0;
1901 }
1902 
1903 //--------------------------------------------------------------------------
1904 // opt_bg()
1905 //
1919 //--------------------------------------------------------------------------
1920 
1921 static int
1922 opt_bg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1923 {
1924  const char *rgb;
1925  char *color_field, *alpha_field;
1926  long bgcolor;
1927  PLINT r, g, b;
1928  PLFLT a;
1929 
1930 // Strip off leading "#" (TK-ism) if present.
1931 
1932  if ( *opt_arg == '#' )
1933  rgb = opt_arg + 1;
1934  else
1935  rgb = opt_arg;
1936 
1937  strncpy( opttmp, rgb, OPTMAX - 1 );
1938  opttmp[OPTMAX - 1] = '\0';
1939 
1940  if ( strchr( opttmp, '_' ) )
1941  {
1942  // e.g., -bg ff0000_0.1
1943  color_field = strtok( opttmp, "_" );
1944  alpha_field = strtok( NULL, "_" );
1945  }
1946  else
1947  {
1948  color_field = opttmp;
1949  alpha_field = NULL;
1950  }
1951 
1952  bgcolor = strtol( color_field, NULL, 16 );
1953 
1954 // Must be either a 3 or 6 digit hex number
1955 // If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC).
1956 
1957  switch ( strlen( color_field ) )
1958  {
1959  case 3:
1960  r = (PLINT) ( ( bgcolor & 0xF00 ) >> 8 );
1961  g = (PLINT) ( ( bgcolor & 0x0F0 ) >> 4 );
1962  b = (PLINT) ( bgcolor & 0x00F );
1963 
1964  r = r | ( r << 4 );
1965  g = g | ( g << 4 ); // doubling
1966  b = b | ( b << 4 );
1967  break;
1968 
1969  case 6:
1970  r = (PLINT) ( ( bgcolor & 0xFF0000 ) >> 16 );
1971  g = (PLINT) ( ( bgcolor & 0x00FF00 ) >> 8 );
1972  b = (PLINT) ( bgcolor & 0x0000FF );
1973  break;
1974 
1975  default:
1976  fprintf( stderr, "Unrecognized background color value %s\n", color_field );
1977  return 1;
1978  }
1979 
1980  if ( alpha_field )
1981  a = atof( alpha_field );
1982  else
1983  a = 1.;
1984 
1985  plscolbga( r, g, b, a );
1986 
1987  return 0;
1988 }
1989 
1990 //--------------------------------------------------------------------------
1991 // opt_ncol0()
1992 //
2002 //--------------------------------------------------------------------------
2003 
2004 static int
2005 opt_ncol0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2006 {
2007  plsc->ncol0 = atoi( opt_arg );
2008  return 0;
2009 }
2010 
2011 //--------------------------------------------------------------------------
2012 // opt_ncol1()
2013 //
2023 //--------------------------------------------------------------------------
2024 
2025 static int
2026 opt_ncol1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2027 {
2028  plsc->ncol1 = atoi( opt_arg );
2029  return 0;
2030 }
2031 
2032 //--------------------------------------------------------------------------
2033 // opt_wplt()
2034 //
2044 //--------------------------------------------------------------------------
2045 
2046 static int
2047 opt_wplt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2048 {
2049  char *field;
2050  PLFLT xl, yl, xr, yr;
2051 
2052  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2053  opttmp[OPTMAX - 1] = '\0';
2054 
2055  if ( ( field = strtok( opttmp, "," ) ) == NULL )
2056  return 1;
2057 
2058  xl = atof( field );
2059 
2060  if ( ( field = strtok( NULL, "," ) ) == NULL )
2061  return 1;
2062 
2063  yl = atof( field );
2064 
2065  if ( ( field = strtok( NULL, "," ) ) == NULL )
2066  return 1;
2067 
2068  xr = atof( field );
2069 
2070  if ( ( field = strtok( NULL, "," ) ) == NULL )
2071  return 1;
2072 
2073  yr = atof( field );
2074 
2075  plsdiplt( xl, yl, xr, yr );
2076  return 0;
2077 }
2078 
2079 //--------------------------------------------------------------------------
2080 // opt_drvopt()
2081 //
2091 //--------------------------------------------------------------------------
2092 
2093 static int
2094 opt_drvopt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2095 {
2096  char t, *tt, *option, *value;
2097  int fl = 0;
2098  DrvOptCmd *drvp;
2099 
2100  option = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2101  if ( option == NULL )
2102  plexit( "opt_drvopt: Out of memory!?" );
2103 
2104  value = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2105  if ( value == NULL )
2106  plexit( "opt_drvopt: Out of memory!?" );
2107 
2108  drvp = &drv_opt;
2109  *option = *value = '\0';
2110  tt = option;
2111  while ( ( t = *opt_arg++ ) )
2112  {
2113  switch ( t )
2114  {
2115  case ',':
2116  if ( fl )
2117  fl = 0;
2118  else
2119  {
2120  value[0] = '1';
2121  value[1] = '\0';
2122  }
2123 
2124  *tt = '\0'; tt = option;
2125  drvp->option = plstrdup( option ); // it should not be release, because of familying
2126  drvp->value = plstrdup( value ); // don't release
2127  drvp->next = (DrvOptCmd *) malloc( sizeof ( DrvOptCmd ) ); // don't release
2128  if ( drvp->next == NULL )
2129  plexit( "opt_drvopt: Out of memory!?\n" );
2130 
2131  drvp = drvp->next;
2132  break;
2133 
2134  case '=':
2135  fl = 1;
2136  *tt = '\0'; tt = value;
2137  break;
2138 
2139  default:
2140  *tt++ = t;
2141  }
2142  }
2143 
2144  *tt = '\0';
2145  if ( !fl )
2146  {
2147  value[0] = '1';
2148  value[1] = '\0';
2149  }
2150 
2151  drvp->option = plstrdup( option ); // don't release
2152  drvp->value = plstrdup( value ); // don't release
2153  drvp->next = NULL;
2154 
2155 #ifdef DEBUG
2156  fprintf( stderr, "\nopt_drvopt: -drvopt parsed options:\n" );
2157  drvp = &drv_opt;
2158  do
2159  fprintf( stderr, "%s %s\n", drvp->option, drvp->value );
2160  while ( drvp = drvp->next );
2161  fprintf( stderr, "\n" );
2162 #endif
2163 
2164  free( option ); free( value );
2165 
2166  return 0;
2167 }
2168 
2169 //--------------------------------------------------------------------------
2170 // opt_fam()
2171 //
2181 //--------------------------------------------------------------------------
2182 
2183 static int
2184 opt_fam( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2185 {
2186  plsfam( 1, -1, -1 );
2187  return 0;
2188 }
2189 
2190 //--------------------------------------------------------------------------
2191 // opt_fsiz()
2192 //
2211 //--------------------------------------------------------------------------
2212 
2213 static int
2214 opt_fsiz( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2215 {
2216  PLINT bytemax;
2217  size_t len = strlen( opt_arg );
2218  char lastchar = opt_arg[len - 1];
2219  PLFLT multiplier = 1.0e6;
2220  char *spec = (char *) malloc( len + 1 );
2221 
2222  if ( spec == NULL )
2223  plexit( "opt_fsiz: Insufficient memory" );
2224 
2225 // Interpret optional suffix
2226 
2227  switch ( lastchar )
2228  {
2229  case 'k':
2230  case 'K':
2231  multiplier = 1.0e3; len--;
2232  break;
2233  case 'm':
2234  case 'M':
2235  multiplier = 1.0e6; len--;
2236  break;
2237  case 'g':
2238  case 'G':
2239  multiplier = 1.0e9; len--;
2240  break;
2241  }
2242  strncpy( spec, opt_arg, len );
2243  spec[len] = '\0';
2244 
2245  bytemax = (PLINT) ( multiplier * atof( spec ) );
2246  if ( bytemax <= 0 )
2247  {
2248  fprintf( stderr, "?invalid file size %d. 2.14G is the maximum.\n", bytemax );
2249  return 1;
2250  }
2251  plsfam( 1, -1, bytemax );
2252 
2253  free( spec );
2254  return 0;
2255 }
2256 
2257 //--------------------------------------------------------------------------
2258 // opt_fbeg()
2259 //
2269 //--------------------------------------------------------------------------
2270 
2271 static int
2272 opt_fbeg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2273 {
2274  plsc->member = atoi( opt_arg );
2275 
2276  return 0;
2277 }
2278 
2279 //--------------------------------------------------------------------------
2280 // opt_finc()
2281 //
2291 //--------------------------------------------------------------------------
2292 
2293 static int
2294 opt_finc( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2295 {
2296  plsc->finc = atoi( opt_arg );
2297 
2298  return 0;
2299 }
2300 
2301 //--------------------------------------------------------------------------
2302 // opt_fflen()
2303 //
2313 //--------------------------------------------------------------------------
2314 
2315 static int
2316 opt_fflen( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2317 {
2318  plsc->fflen = atoi( opt_arg );
2319 
2320  return 0;
2321 }
2322 
2323 //--------------------------------------------------------------------------
2324 // opt_np()
2325 //
2335 //--------------------------------------------------------------------------
2336 
2337 static int
2338 opt_np( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2339 {
2340  plspause( 0 );
2341  return 0;
2342 }
2343 
2344 //--------------------------------------------------------------------------
2345 // opt_nopixmap()
2346 //
2356 //--------------------------------------------------------------------------
2357 
2358 static int
2359 opt_nopixmap( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2360 {
2361  plsc->nopixmap = 1;
2362  return 0;
2363 }
2364 
2365 //--------------------------------------------------------------------------
2366 // opt_db()
2367 //
2377 //--------------------------------------------------------------------------
2378 
2379 static int
2380 opt_db( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2381 {
2382  plsc->db = 1;
2383  return 0;
2384 }
2385 
2386 //--------------------------------------------------------------------------
2387 // opt_bufmax()
2388 //
2398 //--------------------------------------------------------------------------
2399 
2400 static int
2401 opt_bufmax( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2402 {
2403  plsc->bufmax = atoi( opt_arg );
2404  return 0;
2405 }
2406 
2407 //--------------------------------------------------------------------------
2408 // opt_server_name()
2409 //
2419 //--------------------------------------------------------------------------
2420 
2421 static int
2422 opt_server_name( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2423 {
2424  plsc->server_name = plstrdup( opt_arg );
2425  return 0;
2426 }
2427 
2428 //--------------------------------------------------------------------------
2429 // opt_plserver()
2430 //
2440 //--------------------------------------------------------------------------
2441 
2442 static int
2443 opt_plserver( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2444 {
2445  plsc->plserver = plstrdup( opt_arg );
2446  return 0;
2447 }
2448 
2449 //--------------------------------------------------------------------------
2450 // opt_plwindow()
2451 //
2461 //--------------------------------------------------------------------------
2462 
2463 static int
2464 opt_plwindow( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2465 {
2466  if ( ( plsc->plwindow = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2467  {
2468  plexit( "opt_plwindow: Insufficient memory" );
2469  }
2470  strcpy( plsc->plwindow, opt_arg );
2471  return 0;
2472 }
2473 
2474 //--------------------------------------------------------------------------
2475 // opt_auto_path()
2476 //
2486 //--------------------------------------------------------------------------
2487 
2488 static int
2489 opt_auto_path( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2490 {
2491  plsc->auto_path = plstrdup( opt_arg );
2492  return 0;
2493 }
2494 
2495 //--------------------------------------------------------------------------
2496 // opt_px()
2497 //
2507 //--------------------------------------------------------------------------
2508 
2509 static int
2510 opt_px( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2511 {
2512  plssub( atoi( opt_arg ), -1 );
2513  return 0;
2514 }
2515 
2516 //--------------------------------------------------------------------------
2517 // opt_py()
2518 //
2528 //--------------------------------------------------------------------------
2529 
2530 static int
2531 opt_py( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2532 {
2533  plssub( -1, atoi( opt_arg ) );
2534  return 0;
2535 }
2536 
2537 //--------------------------------------------------------------------------
2538 // opt_geo()
2539 //
2553 //--------------------------------------------------------------------------
2554 
2555 static int
2556 opt_geo( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2557 {
2558  int numargs;
2559  PLFLT xdpi = 0., ydpi = 0.;
2560  PLINT xwid, ywid, xoff, yoff;
2561 
2562 // The TK driver uses the geometry string directly
2563 
2564  if ( ( plsc->geometry = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2565  {
2566  plexit( "opt_geo: Insufficient memory" );
2567  }
2568 
2569  strcpy( plsc->geometry, opt_arg );
2570 
2571  numargs = sscanf( opt_arg, "%dx%d%d%d", &xwid, &ywid, &xoff, &yoff );
2572  if ( numargs == 2 )
2573  {
2574  xoff = 0;
2575  yoff = 0;
2576  if ( xwid == 0 )
2577  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2578  if ( ywid == 0 )
2579  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2580  if ( xwid < 0 )
2581  {
2582  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2583  return 1;
2584  }
2585  if ( ywid < 0 )
2586  {
2587  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2588  return 1;
2589  }
2590  }
2591  else if ( numargs == 4 )
2592  {
2593  if ( xwid == 0 )
2594  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2595  if ( ywid == 0 )
2596  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2597  if ( xwid < 0 )
2598  {
2599  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2600  return 1;
2601  }
2602  if ( ywid < 0 )
2603  {
2604  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2605  return 1;
2606  }
2607  if ( abs( xoff ) == 0 )
2608  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2609  if ( abs( yoff ) == 0 )
2610  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2611  }
2612  else
2613  {
2614  numargs = sscanf( opt_arg, "%d%d", &xoff, &yoff );
2615  if ( numargs == 2 )
2616  {
2617  xwid = 0;
2618  ywid = 0;
2619  if ( abs( xoff ) == 0 )
2620  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2621  if ( abs( yoff ) == 0 )
2622  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2623  }
2624  else
2625  {
2626  fprintf( stderr, "?invalid -geometry %s\n", opt_arg );
2627  return 1;
2628  }
2629  }
2630  //fprintf( stderr, "xwid, ywid, xoff, yoff = %d, %d, %d, %d\n", xwid, ywid, xoff, yoff );
2631  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2632  return 0;
2633 }
2634 
2635 //--------------------------------------------------------------------------
2636 // opt_tk_file()
2637 //
2646 //--------------------------------------------------------------------------
2647 
2648 static int
2649 opt_tk_file( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2650 {
2651  if ( ( plsc->tk_file = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2652  {
2653  plexit( "opt_tk_file: Insufficient memory" );
2654  }
2655 
2656  strcpy( plsc->tk_file, opt_arg );
2657  return 0;
2658 }
2659 
2660 //--------------------------------------------------------------------------
2661 // opt_dpi()
2662 //
2676 //--------------------------------------------------------------------------
2677 
2678 static int
2679 opt_dpi( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2680 {
2681  char *field;
2682  PLFLT xdpi = 0., ydpi = 0.;
2683  PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0;
2684 
2685  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2686  opttmp[OPTMAX - 1] = '\0';
2687  if ( strchr( opttmp, 'x' ) )
2688  {
2689  field = strtok( opttmp, "x" );
2690  xdpi = atof( field );
2691  if ( xdpi == 0 )
2692  fprintf( stderr, "?invalid xdpi\n" );
2693 
2694  if ( ( field = strtok( NULL, " " ) ) == NULL )
2695  return 1;
2696 
2697  ydpi = atof( field );
2698  if ( ydpi == 0 )
2699  fprintf( stderr, "?invalid ydpi\n" );
2700  }
2701  else
2702  {
2703  xdpi = atof( opttmp );
2704  ydpi = xdpi;
2705  if ( xdpi == 0 )
2706  return 1;
2707  }
2708 
2709  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2710  return 0;
2711 }
2712 
2713 //--------------------------------------------------------------------------
2714 // opt_dev_compression()
2715 //
2724 //--------------------------------------------------------------------------
2725 
2726 static int
2727 opt_dev_compression( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2728 {
2729  PLINT comp = 0;
2730 
2731  comp = atoi( opt_arg );
2732  if ( comp == 0 )
2733  {
2734  fprintf( stderr, "?invalid compression\n" );
2735  return 1;
2736  }
2737  plscompression( comp );
2738 
2739  return 0;
2740 }
2741 
2742 //--------------------------------------------------------------------------
2743 // opt_cmap0()
2744 //
2753 //--------------------------------------------------------------------------
2754 
2755 static int
2756 opt_cmap0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2757 {
2758  plspal0( opt_arg );
2759  return 0;
2760 }
2761 
2762 //--------------------------------------------------------------------------
2763 // opt_cmap1()
2764 //
2773 //--------------------------------------------------------------------------
2774 
2775 static int
2776 opt_cmap1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2777 {
2778  plspal1( opt_arg, TRUE );
2779  return 0;
2780 }
2781 
2782 //--------------------------------------------------------------------------
2783 // opt_locale()
2784 //
2793 //--------------------------------------------------------------------------
2794 
2795 static int
2796 opt_locale( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2797 {
2798  char *locale;
2799  if ( ( locale = setlocale( LC_NUMERIC, "" ) ) )
2800  {
2801  printf( "LC_NUMERIC locale set to \"%s\"\n", locale );
2802  }
2803  else
2804  {
2805  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" );
2806  if ( !( locale = setlocale( LC_NUMERIC, "C" ) ) )
2807  {
2808  plexit( "Your platform is seriously broken. Not even a \"C\" locale could be set." );
2809  }
2810  }
2811  return 0;
2812 }
2813 
2814 //--------------------------------------------------------------------------
2815 // opt_eofill()
2816 //
2827 //--------------------------------------------------------------------------
2828 
2829 static int
2830 opt_eofill( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2831 {
2832  plsc->dev_eofill = 1;
2833  return 0;
2834 }
2835 
2836 //--------------------------------------------------------------------------
2837 // opt_mfo()
2838 //
2847 //--------------------------------------------------------------------------
2848 
2849 static int
2850 opt_mfo( const char * PL_UNUSED( opt ), const char * opt_arg, void * PL_UNUSED( client_data ) )
2851 {
2852  if ( ( plsc->mf_outfile = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2853  {
2854  plexit( "opt_mfo: Insufficient memory" );
2855  }
2856 
2857  strcpy( plsc->mf_outfile, opt_arg );
2858  return 0;
2859 }
2860 
2861 //--------------------------------------------------------------------------
2862 // opt_mfi()
2863 //
2872 //--------------------------------------------------------------------------
2873 
2874 static int
2875 opt_mfi( const char * PL_UNUSED( opt ), const char * opt_arg, void * PL_UNUSED( client_data ) )
2876 {
2877  if ( ( plsc->mf_infile = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2878  {
2879  plexit( "opt_mfi: Insufficient memory" );
2880  }
2881 
2882  strcpy( plsc->mf_infile, opt_arg );
2883  return 0;
2884 }