PLplot  5.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plargs.c
Go to the documentation of this file.
1 // $Id: plargs.c 12677 2013-11-12 00:54:54Z airwin $
2 //
3 // Copyright 1993, 1994, 1995
4 // Maurice LeBrun mjl@dino.ph.utexas.edu
5 // Institute for Fusion Studies University of Texas at Austin
6 //
7 // Copyright (C) 2004 Maurice LeBrun
8 // Copyright (C) 2004 Andrew Ross
9 //
10 // This file is part of PLplot.
11 //
12 // PLplot is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU Library General Public License as published
14 // by the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16 //
17 // PLplot is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Library General Public License for more details.
21 //
22 // You should have received a copy of the GNU Library General Public License
23 // along with PLplot; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 //
26 // Some parts of this code were derived from "xterm.c" and "ParseCmd.c" of
27 // the X-windows Version 11 distribution. The copyright notice is
28 // reproduced here:
29 //
30 // Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
31 // and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
32 //
33 // All Rights Reserved
34 //
35 // The full permission notice is given in the PLplot documentation.
36 //
37 //--------------------------------------------------------------------------
38 //
99 
100 #include "plplotP.h"
101 #include <ctype.h>
102 
103 #ifdef HAVE_CRT_EXTERNS_H
104 //
105 // This include file has the declaration for _NSGetArgc(). See below.
106 //
107 #include <crt_externs.h>
108 #endif
109 
110 // Support functions
111 
112 static int ParseOpt( int *, const char ***, int *, const char ***, PLOptionTable * );
113 static int ProcessOpt( const char *, PLOptionTable *, int *, const char ***, int * );
114 static int GetOptarg( const char **, int *, const char ***, int * );
115 static void Help( void );
116 static void Syntax( void );
117 
118 #ifndef PL_DEPRECATED
119 int plSetOpt( const char * opt, const char *opt_arg );
120 #endif
121 
122 // Option handlers
123 
124 static int opt_h( const char *, const char *, void * );
125 static int opt_v( const char *, const char *, void * );
126 static int opt_verbose( const char *, const char *, void * );
127 static int opt_debug( const char *, const char *, void * );
128 static int opt_hack( const char *, const char *, void * );
129 static int opt_dev( const char *, const char *, void * );
130 static int opt_o( const char *, const char *, void * );
131 static int opt_geo( const char *, const char *, void * );
132 static int opt_a( const char *, const char *, void * );
133 static int opt_jx( const char *, const char *, void * );
134 static int opt_jy( const char *, const char *, void * );
135 static int opt_mar( const char *, const char *, void * );
136 static int opt_ori( const char *, const char *, void * );
137 static int opt_freeaspect( const char *, const char *, void * );
138 static int opt_portrait( const char *, const char *, void * );
139 static int opt_width( const char *, const char *, void * );
140 static int opt_bg( const char *, const char *, void * );
141 static int opt_ncol0( const char *, const char *, void * );
142 static int opt_ncol1( const char *, const char *, void * );
143 static int opt_fam( const char *, const char *, void * );
144 static int opt_fsiz( const char *, const char *, void * );
145 static int opt_fbeg( const char *, const char *, void * );
146 static int opt_finc( const char *, const char *, void * );
147 static int opt_fflen( const char *, const char *, void * );
148 static int opt_bufmax( const char *, const char *, void * );
149 static int opt_nopixmap( const char *, const char *, void * );
150 static int opt_db( const char *, const char *, void * );
151 static int opt_np( const char *, const char *, void * );
152 static int opt_px( const char *, const char *, void * );
153 static int opt_py( const char *, const char *, void * );
154 static int opt_wplt( const char *, const char *, void * );
155 static int opt_drvopt( const char *, const char *, void * );
156 
157 static int opt_plserver( const char *, const char *, void * );
158 static int opt_plwindow( const char *, const char *, void * );
159 static int opt_auto_path( const char *, const char *, void * );
160 static int opt_bufmax( const char *, const char *, void * );
161 static int opt_server_name( const char *, const char *, void * );
162 static int opt_tk_file( const char *, const char *, void * );
163 static int opt_dpi( const char *, const char *, void * );
164 static int opt_dev_compression( const char *, const char *, void * );
165 static int opt_cmap0( const char *, const char *, void * );
166 static int opt_cmap1( const char *, const char *, void * );
167 static int opt_locale( const char *, const char *, void * );
168 static int opt_eofill( const char *, const char *, void * );
169 
170 // Global variables
171 
172 static const char *program = NULL;
173 static const char *usage = NULL;
174 
175 static int mode_full;
176 static int mode_quiet;
177 static int mode_nodelete;
178 static int mode_showall;
179 static int mode_noprogram;
180 static int mode_nodash;
181 static int mode_skip;
182 
183 // Temporary buffer used for parsing
184 
185 #define OPTMAX 1024
186 static char opttmp[OPTMAX];
187 
188 //--------------------------------------------------------------------------
238 //--------------------------------------------------------------------------
239 
241  {
242  "showall", // Turns on invisible options
243  NULL,
244  NULL,
245  &mode_showall,
247  "-showall",
248  "Turns on invisible options"
249  },
250  {
251  "h", // Help
252  opt_h,
253  NULL,
254  NULL,
255  PL_OPT_FUNC,
256  "-h",
257  "Print out this message"
258  },
259  {
260  "v", // Version
261  opt_v,
262  NULL,
263  NULL,
264  PL_OPT_FUNC,
265  "-v",
266  "Print out the PLplot library version number"
267  },
268  {
269  "verbose", // Be more verbose than usual
270  opt_verbose,
271  NULL,
272  NULL,
273  PL_OPT_FUNC,
274  "-verbose",
275  "Be more verbose than usual"
276  },
277  {
278  "debug", // Print debugging info
279  opt_debug,
280  NULL,
281  NULL,
282  PL_OPT_FUNC,
283  "-debug",
284  "Print debugging info (implies -verbose)"
285  },
286  {
287  "hack", // Enable driver-specific hack(s)
288  opt_hack,
289  NULL,
290  NULL,
292  "-hack",
293  "Enable driver-specific hack(s)"
294  },
295  {
296  "dev", // Output device
297  opt_dev,
298  NULL,
299  NULL,
301  "-dev name",
302  "Output device name"
303  },
304  {
305  "o", // Output filename
306  opt_o,
307  NULL,
308  NULL,
310  "-o name",
311  "Output filename"
312  },
313  {
314  "display", // X server
315  opt_o,
316  NULL,
317  NULL,
319  "-display name",
320  "X server to contact"
321  },
322  {
323  "px", // Plots per page in x
324  opt_px,
325  NULL,
326  NULL,
328  "-px number",
329  "Plots per page in x"
330  },
331  {
332  "py", // Plots per page in y
333  opt_py,
334  NULL,
335  NULL,
337  "-py number",
338  "Plots per page in y"
339  },
340  {
341  "geometry", // Geometry
342  opt_geo,
343  NULL,
344  NULL,
346  "-geometry geom",
347  "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc."
348  },
349  {
350  "geo", // Geometry (alias)
351  opt_geo,
352  NULL,
353  NULL,
355  "-geo geom",
356  "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc."
357  },
358  {
359  "wplt", // Plot window
360  opt_wplt,
361  NULL,
362  NULL,
364  "-wplt xl,yl,xr,yr",
365  "Relative coordinates [0-1] of window into plot"
366  },
367  {
368  "mar", // Margin
369  opt_mar,
370  NULL,
371  NULL,
373  "-mar margin",
374  "Margin space in relative coordinates (0 to 0.5, def 0)"
375  },
376  {
377  "a", // Aspect ratio
378  opt_a,
379  NULL,
380  NULL,
382  "-a aspect",
383  "Page aspect ratio (def: same as output device)"
384  },
385  {
386  "jx", // Justification in x
387  opt_jx,
388  NULL,
389  NULL,
391  "-jx justx",
392  "Page justification in x (-0.5 to 0.5, def 0)"
393  },
394  {
395  "jy", // Justification in y
396  opt_jy,
397  NULL,
398  NULL,
400  "-jy justy",
401  "Page justification in y (-0.5 to 0.5, def 0)"
402  },
403  {
404  "ori", // Orientation
405  opt_ori,
406  NULL,
407  NULL,
409  "-ori orient",
410  "Plot orientation (0,1,2,3=landscape,portrait,seascape,upside-down)"
411  },
412  {
413  "freeaspect", // floating aspect ratio
415  NULL,
416  NULL,
417  PL_OPT_FUNC,
418  "-freeaspect",
419  "Allow aspect ratio to adjust to orientation swaps"
420  },
421  {
422  "portrait", // floating aspect ratio
423  opt_portrait,
424  NULL,
425  NULL,
426  PL_OPT_FUNC,
427  "-portrait",
428  "Sets portrait mode (both orientation and aspect ratio)"
429  },
430  {
431  "width", // Pen width
432  opt_width,
433  NULL,
434  NULL,
436  "-width width",
437  "Sets pen width (0 <= width)"
438  },
439  {
440  "bg", // Background color
441  opt_bg,
442  NULL,
443  NULL,
445  "-bg color",
446  "Background color (FF0000=opaque red, 0000FF_0.1=blue with alpha of 0.1)"
447  },
448  {
449  "ncol0", // Allocated colors in cmap 0
450  opt_ncol0,
451  NULL,
452  NULL,
454  "-ncol0 n",
455  "Number of colors to allocate in cmap 0 (upper bound)"
456  },
457  {
458  "ncol1", // Allocated colors in cmap 1
459  opt_ncol1,
460  NULL,
461  NULL,
463  "-ncol1 n",
464  "Number of colors to allocate in cmap 1 (upper bound)"
465  },
466  {
467  "fam", // Familying on switch
468  opt_fam,
469  NULL,
470  NULL,
471  PL_OPT_FUNC,
472  "-fam",
473  "Create a family of output files"
474  },
475  {
476  "fsiz", // Family file size
477  opt_fsiz,
478  NULL,
479  NULL,
481  "-fsiz size[kKmMgG]",
482  "Output family file size (e.g. -fsiz 0.5G, def MB)"
483  },
484  {
485  "fbeg", // Family starting member
486  opt_fbeg,
487  NULL,
488  NULL,
490  "-fbeg number",
491  "First family member number on output"
492  },
493  {
494  "finc", // Family member increment
495  opt_finc,
496  NULL,
497  NULL,
499  "-finc number",
500  "Increment between family members"
501  },
502  {
503  "fflen", // Family member min field width
504  opt_fflen,
505  NULL,
506  NULL,
508  "-fflen length",
509  "Family member number minimum field width"
510  },
511  {
512  "nopixmap", // Do not use pixmaps
513  opt_nopixmap,
514  NULL,
515  NULL,
516  PL_OPT_FUNC,
517  "-nopixmap",
518  "Don't use pixmaps in X-based drivers"
519  },
520  {
521  "db", // Double buffering on switch
522  opt_db,
523  NULL,
524  NULL,
525  PL_OPT_FUNC,
526  "-db",
527  "Double buffer X window output"
528  },
529  {
530  "np", // Page pause off switch
531  opt_np,
532  NULL,
533  NULL,
534  PL_OPT_FUNC,
535  "-np",
536  "No pause between pages"
537  },
538  {
539  "bufmax", // # bytes sent before flushing output
540  opt_bufmax,
541  NULL,
542  NULL,
544  "-bufmax",
545  "bytes sent before flushing output"
546  },
547  {
548  "server_name", // Main window name of server
550  NULL,
551  NULL,
553  "-server_name name",
554  "Main window name of PLplot server (tk driver)"
555  },
556  {
557  "plserver", // PLplot server name
558  opt_plserver,
559  NULL,
560  NULL,
562  "-plserver name",
563  "Invoked name of PLplot server (tk driver)"
564  },
565  {
566  "plwindow", // PLplot container window name
567  opt_plwindow,
568  NULL,
569  NULL,
571  "-plwindow name",
572  "Name of PLplot container window (tk driver)"
573  },
574  {
575  "auto_path", // Additional directory(s) to autoload
577  NULL,
578  NULL,
580  "-auto_path dir",
581  "Additional directory(s) to autoload (tk driver)"
582  },
583  {
584  "tk_file", // -file option for plserver
585  opt_tk_file,
586  NULL,
587  NULL,
589  "-tk_file file",
590  "file for plserver (tk driver)"
591  },
592  {
593  "dpi", // Dots per inch
594  opt_dpi,
595  NULL,
596  NULL,
598  "-dpi dpi",
599  "Resolution, in dots per inch (e.g. -dpi 360x360)"
600  },
601  {
602  "compression", // compression
604  NULL,
605  NULL,
607  "-compression num",
608  "Sets compression level in supporting devices"
609  },
610  {
611  "cmap0",
612  opt_cmap0,
613  NULL,
614  NULL,
616  "-cmap0 file name",
617  "Initializes color table 0 from a cmap0.pal format file in one of standard PLplot paths."
618  },
619  {
620  "cmap1",
621  opt_cmap1,
622  NULL,
623  NULL,
625  "-cmap1 file name",
626  "Initializes color table 1 from a cmap1.pal format file in one of standard PLplot paths."
627  },
628  {
629  "locale",
630  opt_locale,
631  NULL,
632  NULL,
633  PL_OPT_FUNC,
634  "-locale",
635  "Use locale environment (e.g., LC_ALL, LC_NUMERIC, or LANG) to set LC_NUMERIC locale (which affects decimal point separator)."
636  },
637  {
638  "eofill",
639  opt_eofill,
640  NULL,
641  NULL,
642  PL_OPT_FUNC,
643  "-eofill",
644  "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."
645  },
646  {
647  "drvopt", // Driver specific options
648  opt_drvopt,
649  NULL,
650  NULL,
652  "-drvopt option[=value][,option[=value]]*",
653  "Driver specific options"
654  },
655  {
656  NULL, // option
657  NULL, // handler
658  NULL, // client data
659  NULL, // address of variable to set
660  0, // mode flag
661  NULL, // short syntax
662  NULL
663  } // long syntax
664 };
665 
666 static const char *plplot_notes[] = {
667  "All parameters must be white-space delimited. Some options are driver",
668  "dependent. Please see the PLplot reference document for more detail.",
669  NULL
670 };
671 
672 //--------------------------------------------------------------------------
686 //--------------------------------------------------------------------------
687 
688 typedef struct
689 {
691  const char *name;
692  const char **notes;
693 } PLOptionInfo;
694 
697  "PLplot options",
699 };
700 
701 #define PL_MAX_OPT_TABLES 10
703  {
705  "PLplot options",
707  }
708 };
709 
710 // The structure that hold the driver specific command line options
711 
712 typedef struct DrvOptCmd
713 {
714  char *option;
715  char *value;
716  struct DrvOptCmd *next;
717 } DrvOptCmd;
718 
719 // the variable where opt_drvopt() stores the driver specific command line options
720 static DrvOptCmd drv_opt = { NULL, NULL, NULL };
721 
722 static int tables = 1;
723 
724 //--------------------------------------------------------------------------
725 // plSetOpt()
726 //
735 //--------------------------------------------------------------------------
736 
737 int
738 plSetOpt( const char * opt, const char *opt_arg )
739 {
740  return ( c_plsetopt( opt, opt_arg ) );
741 }
742 
743 int
744 c_plsetopt( const char * opt, const char *opt_arg )
745 {
746  int mode = 0, argc = 2, status;
747  const char *argv[3];
748 
749  argv[0] = opt;
750  argv[1] = opt_arg;
751  argv[2] = NULL;
752  mode =
757 
758  status = plparseopts( &argc, argv, mode );
759  if ( status )
760  {
761  fprintf( stderr, "plSetOpt: Unrecognized option %s\n", opt );
762  }
763  return status;
764 }
765 
766 //--------------------------------------------------------------------------
767 // plMergeOpts()
768 //
775 //--------------------------------------------------------------------------
776 
777 int
778 plMergeOpts( PLOptionTable *options, const char *name, const char **notes )
779 {
780  PLOptionTable *tab;
781 
782  pllib_init();
783 
784 // Check to make sure option table has been terminated correctly
785 
786  for ( tab = (PLOptionTable *) options; tab->opt; tab++ )
787  ;
788 
789 // We've reached the last table entry. All the subentries must be NULL or 0
790 
791  if ( ( tab->handler != NULL ) ||
792  ( tab->client_data != NULL ) ||
793  ( tab->var != NULL ) ||
794  ( tab->mode != 0 ) ||
795  ( tab->syntax != NULL ) ||
796  ( tab->desc != NULL ) )
797  {
798  plabort( "plMergeOpts: input table improperly terminated" );
799  return 1;
800  }
801 
802 // No room for more tables
803 
804  if ( tables++ >= PL_MAX_OPT_TABLES )
805  {
806  plabort( "plMergeOpts: max tables limit exceeded, table not merged" );
807  return 1;
808  }
809 
810  ploption_info[tables - 1].options = options;
811  ploption_info[tables - 1].name = name;
812  ploption_info[tables - 1].notes = notes;
813 
814  return 0;
815 }
816 
817 //--------------------------------------------------------------------------
818 // plClearOpts()
819 //
822 //--------------------------------------------------------------------------
823 
824 void
825 plClearOpts( void )
826 {
827  tables = 0;
828 }
829 
830 //--------------------------------------------------------------------------
831 // plResetOpts()
832 //
835 //--------------------------------------------------------------------------
836 
837 void
838 plResetOpts( void )
839 {
840  ploption_info[0] = ploption_info_default;
841  tables = 1;
842 }
843 
844 //--------------------------------------------------------------------------
845 // plparseopts()
846 //
857 //--------------------------------------------------------------------------
858 
859 int
860 c_plparseopts( int *p_argc, const char **argv, PLINT mode )
861 {
862  const char **argsave, **argend;
863  int i, myargc, status = 0;
864 
865  pllib_init();
866 
867 // Initialize
868 
869  mode_full = mode & PL_PARSE_FULL;
870  mode_quiet = mode & PL_PARSE_QUIET;
874  mode_nodash = mode & PL_PARSE_NODASH;
875  mode_skip = mode & PL_PARSE_SKIP;
876 
877  myargc = ( *p_argc );
878  argend = argv + myargc;
879 
880 // If program name is first argument, save and advance
881 
882  if ( !mode_noprogram )
883  {
884  plsc->program = plstrdup( argv[0] );
885  program = (const char *) plsc->program;
886  --myargc; ++argv;
887  }
888  if ( myargc == 0 )
889  return 0;
890 
891 // Process the command line
892 
893  argsave = argv;
894  for (; myargc > 0; --myargc, ++argv )
895  {
896  // Allow for "holes" in argv list
897 
898  if ( *argv == NULL || *argv[0] == '\0' )
899  continue;
900 
901  // Loop over all options tables, starting with the last
902 
903  for ( i = tables - 1; i >= 0; i-- )
904  {
905  // Check option table for option
906 
907  status = ParseOpt( &myargc, &argv, p_argc, &argsave,
908  ploption_info[i].options );
909 
910  if ( !status )
911  break;
912  }
913 
914  // Handle error return as specified by the mode flag
915 
916  if ( status == -1 )
917  {
918  // No match. Keep going if mode_skip is set, otherwise abort if
919  // fully parsing, else return without error.
920 
921  status = 0;
922 
923  if ( mode_skip )
924  {
925  if ( !mode_nodelete )
926  *argsave++ = *argv;
927  continue;
928  }
929  if ( !mode_quiet && mode_full )
930  {
931  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
932  plOptUsage();
933  }
934  if ( mode_full )
935  exit( 1 );
936 
937  break;
938  }
939  else if ( status == 1 )
940  {
941  // Illegal or badly formed
942 
943  if ( !mode_quiet )
944  {
945  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
946  plOptUsage();
947  }
948  if ( mode_full )
949  exit( 1 );
950 
951  break;
952  }
953  else if ( status == 2 )
954  {
955  // Informational option encountered (-h or -v)
956 
957  exit( 0 );
958  }
959  }
960 
961 // Compress and NULL-terminate argv
962 
963  if ( !mode_nodelete )
964  {
965  for ( i = 0; i < myargc; i++ )
966  *argsave++ = *argv++;
967 
968  if ( argsave < argend )
969  {
970  *argsave = NULL;
971 #ifdef HAVE_NSGETARGC
972  //
973  // Modify the global argc variable to match the shortened argv.
974  // The global argc and argv must be kept consistent so that future
975  // users of them (e.g. libraries loaded later with a device driver)
976  // will not try to dereference the null pointer at the end of the
977  // shortened argv array.
978  //
979  *_NSGetArgc() = *p_argc;
980 #endif
981  }
982  }
983 
984  return status;
985 }
986 
987 //--------------------------------------------------------------------------
988 // ParseOpt()
989 //
1000 //--------------------------------------------------------------------------
1001 
1002 static int
1003 ParseOpt( int *p_myargc, const char ***p_argv, int *p_argc, const char ***p_argsave,
1004  PLOptionTable *option_table )
1005 {
1006  PLOptionTable *tab;
1007  const char *opt;
1008 
1009 // Only handle actual flags and their arguments
1010 
1011  if ( mode_nodash || ( *p_argv )[0][0] == '-' )
1012  {
1013  opt = ( *p_argv )[0];
1014  if ( *opt == '-' )
1015  opt++;
1016 
1017  for ( tab = option_table; tab->opt; tab++ )
1018  {
1019  // Skip if option not enabled
1020 
1021  if ( tab->mode & PL_OPT_DISABLED )
1022  continue;
1023 
1024  // Try to match it
1025 
1026  if ( *opt == *tab->opt && !strcmp( opt, tab->opt ) )
1027  {
1028  // Option matched, so remove from argv list if applicable.
1029 
1030  if ( !mode_nodelete )
1031  {
1032  if ( tab->mode & PL_OPT_NODELETE )
1033  ( *( *p_argsave )++ ) = ( **p_argv );
1034  else
1035  --( *p_argc );
1036  }
1037 
1038  // Process option (and argument if applicable)
1039 
1040  return ( ProcessOpt( opt, tab, p_myargc, p_argv, p_argc ) );
1041  }
1042  }
1043  }
1044 
1045  return -1;
1046 }
1047 
1048 //--------------------------------------------------------------------------
1049 // ProcessOpt()
1050 //
1060 //--------------------------------------------------------------------------
1061 
1062 static int
1063 ProcessOpt( const char * opt, PLOptionTable *tab, int *p_myargc, const char ***p_argv,
1064  int *p_argc )
1065 {
1066  int need_arg, res;
1067  const char *opt_arg = NULL;
1068 
1069 // Get option argument if necessary
1070 
1072 
1073  if ( tab->mode & need_arg )
1074  {
1075  if ( GetOptarg( &opt_arg, p_myargc, p_argv, p_argc ) )
1076  return 1;
1077  }
1078 
1079 // Process argument
1080 
1081  switch ( tab->mode & 0xFF00 )
1082  {
1083  case PL_OPT_FUNC:
1084 
1085  // Call function handler to do the job
1086 
1087  if ( tab->handler == NULL )
1088  {
1089  fprintf( stderr,
1090  "ProcessOpt: no handler specified for option %s\n",
1091  tab->opt );
1092  return 1;
1093  }
1094 
1095  if ( mode_nodelete && opt_arg )
1096  {
1097  // Make a copy, since handler may mung opt_arg with strtok()
1098  char *copy =
1099  (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
1100  if ( copy == NULL )
1101  {
1102  plabort( "ProcessOpt: out of memory" );
1103  return 1;
1104  }
1105  strcpy( copy, opt_arg );
1106  res = ( ( *tab->handler )( opt, copy, tab->client_data ) );
1107  free( (void *) copy );
1108  return res;
1109  }
1110  else
1111  {
1112  return ( ( *tab->handler )( opt, opt_arg, tab->client_data ) );
1113  }
1114 
1115  case PL_OPT_BOOL:
1116 
1117  // Set *var as a boolean
1118 
1119  if ( tab->var == NULL )
1120  {
1121  fprintf( stderr,
1122  "ProcessOpt: no variable specified for option %s\n",
1123  tab->opt );
1124  return 1;
1125  }
1126  *(int *) tab->var = 1;
1127  break;
1128 
1129  case PL_OPT_INT:
1130 
1131  // Set *var as an int
1132 
1133  if ( tab->var == NULL )
1134  {
1135  fprintf( stderr,
1136  "ProcessOpt: no variable specified for option %s\n",
1137  tab->opt );
1138  return 1;
1139  }
1140  *(int *) tab->var = atoi( opt_arg );
1141  break;
1142 
1143  case PL_OPT_FLOAT:
1144 
1145  // Set *var as a float
1146 
1147  if ( tab->var == NULL )
1148  {
1149  fprintf( stderr,
1150  "ProcessOpt: no variable specified for option %s\n",
1151  tab->opt );
1152  return 1;
1153  }
1154  *(PLFLT *) tab->var = atof( opt_arg );
1155  break;
1156 
1157  case PL_OPT_STRING:
1158 
1159  // Set var (can be NULL initially) to point to opt_arg string
1160 
1161  *(const char **) tab->var = opt_arg;
1162  break;
1163 
1164  default:
1165 
1166  // Somebody messed up..
1167 
1168  fprintf( stderr,
1169  "ProcessOpt: invalid processing mode for option %s\n",
1170  tab->opt );
1171  return 1;
1172  }
1173  return 0;
1174 }
1175 
1176 //--------------------------------------------------------------------------
1177 // GetOptarg()
1178 //
1189 //--------------------------------------------------------------------------
1190 
1191 static int
1192 GetOptarg( const char **popt_arg, int *p_myargc, const char ***p_argv, int *p_argc )
1193 {
1194  int result = 0;
1195 
1196  --( *p_myargc );
1197 
1198  if ( ( *p_myargc ) <= 0 ) // oops, no more arguments
1199  result = 1;
1200 
1201  if ( !result )
1202  {
1203  ( *p_argv )++;
1204  if ( ( *p_argv )[0][0] == '-' && isalpha( ( *p_argv )[0][1] ) )
1205  {
1206  ( *p_argv )--; // oops, next arg is a flag
1207  result = 1;
1208  }
1209  }
1210 
1211  if ( !result ) // yeah, the user got it right
1212  {
1213  ( *p_argc )--;
1214  *popt_arg = ( *p_argv )[0];
1215  }
1216  else
1217  {
1218  if ( !mode_quiet )
1219  {
1220  fprintf( stderr, "Argument missing for %s option.\n", ( *p_argv )[0] );
1221  plOptUsage();
1222  }
1223  }
1224  return result;
1225 }
1226 
1227 //--------------------------------------------------------------------------
1228 // plSetUsage()
1229 //
1235 //--------------------------------------------------------------------------
1236 
1237 void
1238 plSetUsage( const char *program_string, const char *usage_string )
1239 {
1240  if ( program_string != NULL )
1241  program = program_string;
1242 
1243  if ( usage_string != NULL )
1244  usage = usage_string;
1245 }
1246 
1247 //--------------------------------------------------------------------------
1248 // plOptUsage()
1249 //
1252 //--------------------------------------------------------------------------
1253 
1254 void
1255 plOptUsage( void )
1256 {
1257  if ( usage == NULL )
1258  fprintf( stderr, "\nUsage:\n %s [options]\n", program );
1259  else
1260  fputs( usage, stderr );
1261 
1262  Syntax();
1263 
1264  fprintf( stderr, "\n\nType %s -h for a full description.\n\n",
1265  program );
1266 }
1267 
1268 //--------------------------------------------------------------------------
1269 // Syntax()
1270 //
1273 //--------------------------------------------------------------------------
1274 
1275 static void
1276 Syntax( void )
1277 {
1278  PLOptionTable *tab;
1279  int i, col, len;
1280 
1281 // Loop over all options tables
1282 
1283  for ( i = tables - 1; i >= 0; i-- )
1284  {
1285  // Introducer
1286 
1287  if ( ploption_info[i].name )
1288  fprintf( stderr, "\n%s:", ploption_info[i].name );
1289  else
1290  fputs( "\nUser options:", stderr );
1291 
1292  // Print syntax for each option
1293 
1294  col = 80;
1295  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1296  {
1297  if ( tab->mode & PL_OPT_DISABLED )
1298  continue;
1299 
1300  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1301  continue;
1302 
1303  if ( tab->syntax == NULL )
1304  continue;
1305 
1306  len = 3 + (int) strlen( tab->syntax ); // space [ string ]
1307  if ( col + len > 79 )
1308  {
1309  fprintf( stderr, "\n " ); // 3 spaces
1310  col = 3;
1311  }
1312  fprintf( stderr, " [%s]", tab->syntax );
1313  col += len;
1314  }
1315  fprintf( stderr, "\n" );
1316  }
1317 }
1318 
1319 //--------------------------------------------------------------------------
1320 // Help()
1321 //
1324 //--------------------------------------------------------------------------
1325 
1326 static void
1327 Help( void )
1328 {
1329  PLOptionTable *tab;
1330  const char **note;
1331  int i;
1332  FILE *outfile = stderr;
1333 
1334 #ifdef HAVE_POPEN
1335  FILE *pager = NULL;
1336  if ( getenv( "PAGER" ) != NULL )
1337  pager = (FILE *) popen( "$PAGER", "w" );
1338  if ( pager == NULL )
1339  pager = (FILE *) popen( "more", "w" );
1340  if ( pager != NULL )
1341  outfile = pager;
1342 #endif
1343 
1344 // Usage line
1345 
1346  if ( usage == NULL )
1347  fprintf( outfile, "\nUsage:\n %s [options]\n", program );
1348  else
1349  fputs( usage, outfile );
1350 
1351 // Loop over all options tables
1352 
1353  for ( i = tables - 1; i >= 0; i-- )
1354  {
1355  // Introducer
1356 
1357  if ( ploption_info[i].name )
1358  fprintf( outfile, "\n%s:\n", ploption_info[i].name );
1359  else
1360  fputs( "\nUser options:\n", outfile );
1361 
1362  // Print description for each option
1363 
1364  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1365  {
1366  if ( tab->mode & PL_OPT_DISABLED )
1367  continue;
1368 
1369  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1370  continue;
1371 
1372  if ( tab->desc == NULL )
1373  continue;
1374 
1375  if ( tab->mode & PL_OPT_INVISIBLE )
1376  fprintf( outfile, " * %-20s %s\n", tab->syntax, tab->desc );
1377  else
1378  fprintf( outfile, " %-20s %s\n", tab->syntax, tab->desc );
1379  }
1380 
1381  // Usage notes
1382 
1383  if ( ploption_info[i].notes )
1384  {
1385  putc( '\n', outfile );
1386  for ( note = ploption_info[i].notes; *note; note++ )
1387  {
1388  fputs( *note, outfile );
1389  putc( '\n', outfile );
1390  }
1391  }
1392  }
1393 
1394 #ifdef HAVE_POPEN
1395  if ( pager != NULL )
1396  pclose( pager );
1397 #endif
1398 }
1399 
1400 //--------------------------------------------------------------------------
1401 // plParseDrvOpts
1402 //
1409 //--------------------------------------------------------------------------
1410 
1411 int
1413 {
1414  DrvOptCmd *drvp;
1415  DrvOpt *t;
1416  int fl;
1417  char msg[80];
1418  memset( msg, '\0', sizeof ( msg ) );
1419 
1420  if ( !drv_opt.option )
1421  return 1;
1422 
1423  drvp = &drv_opt;
1424  do
1425  {
1426  t = acc_opt; fl = 0;
1427  while ( t->opt )
1428  {
1429  if ( strcmp( drvp->option, t->opt ) == 0 )
1430  {
1431  fl = 1;
1432  switch ( t->type )
1433  {
1434  case DRV_STR:
1435  *(char **) ( t->var_ptr ) = ( drvp->value );
1436 #ifdef DEBUG
1437  fprintf( stderr, "plParseDrvOpts: %s %s\n", t->opt, *(char **) t->var_ptr );
1438 #endif
1439  break;
1440 
1441  case DRV_INT:
1442  if ( sscanf( drvp->value, "%d", (int *) t->var_ptr ) != 1 )
1443  {
1444  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1445  plexit( msg );
1446  }
1447 #ifdef DEBUG
1448  fprintf( stderr, "plParseDrvOpts: %s %d\n", t->opt, *(int *) t->var_ptr );
1449 #endif
1450  break;
1451 
1452  case DRV_FLT:
1453  if ( sscanf( drvp->value, "%f", (float *) t->var_ptr ) != 1 )
1454  {
1455  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1456  plexit( msg );
1457  }
1458 #ifdef DEBUG
1459  fprintf( stderr, "plParseDrvOpts: %s %f\n", t->opt, *(float *) t->var_ptr );
1460 #endif
1461  break;
1462  }
1463  }
1464  t++;
1465  }
1466 
1467  if ( !fl )
1468  {
1469  snprintf( msg, sizeof ( msg ) - 1, "Option '%s' not recognized.\n\nRecognized options for this driver are:\n", drvp->option );
1470  plwarn( msg );
1471  plHelpDrvOpts( acc_opt );
1472  plexit( "" );
1473  }
1474  }
1475  while ( ( drvp = drvp->next ) )
1476  ;
1477 
1478  return 0;
1479 }
1480 
1481 //--------------------------------------------------------------------------
1482 // plHelpDrvOpts
1483 //
1488 //--------------------------------------------------------------------------
1489 
1490 void
1492 {
1493  DrvOpt *t;
1494 
1495  t = acc_opt;
1496  while ( t->opt )
1497  {
1498  fprintf( stderr, "%s:\t%s\n", t->opt, t->hlp_msg );
1499  t++;
1500  }
1501 }
1502 
1503 //--------------------------------------------------------------------------
1504 // tidyDrvOpts
1505 //
1508 //--------------------------------------------------------------------------
1509 
1510 void
1512 {
1513  DrvOptCmd *drvp, *drvpl;
1514 
1515  drvp = &drv_opt;
1516  do
1517  {
1518  drvpl = drvp;
1519  drvp = drvpl->next;
1520 
1521  free( drvpl->option );
1522  free( drvpl->value );
1523  // Free additional DrvOptCmd variables -
1524  // first entry in list is a static global variable
1525  if ( drvpl != &drv_opt )
1526  free( drvpl );
1527  } while ( drvp != NULL );
1528 
1529  // initialize drv_opt if it's used again
1530  drv_opt.option = NULL;
1531  drv_opt.value = NULL;
1532  drv_opt.next = NULL;
1533 }
1534 
1535 
1536 //--------------------------------------------------------------------------
1537 // Option handlers
1538 //--------------------------------------------------------------------------
1539 
1540 //--------------------------------------------------------------------------
1541 // opt_h()
1542 //
1552 //--------------------------------------------------------------------------
1553 
1554 static int
1555 opt_h( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1556 {
1557  if ( !mode_quiet )
1558  Help();
1559 
1560  return 2;
1561 }
1562 
1563 //--------------------------------------------------------------------------
1564 // opt_v()
1565 //
1575 //--------------------------------------------------------------------------
1576 
1577 static int
1578 opt_v( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1579 {
1580  if ( !mode_quiet )
1581  fprintf( stderr, "PLplot library version: %s\n", PLPLOT_VERSION );
1582 
1583  return 2;
1584 }
1585 
1586 //--------------------------------------------------------------------------
1587 // opt_verbose()
1588 //
1598 //--------------------------------------------------------------------------
1599 
1600 static int
1601 opt_verbose( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1602 {
1603  plsc->verbose = 1;
1604  return 0;
1605 }
1606 
1607 //--------------------------------------------------------------------------
1608 // opt_debug()
1609 //
1619 //--------------------------------------------------------------------------
1620 
1621 static int
1622 opt_debug( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1623 {
1624  plsc->debug = 1;
1625  plsc->verbose = 1;
1626  return 0;
1627 }
1628 
1629 //--------------------------------------------------------------------------
1630 // opt_hack()
1631 //
1641 //--------------------------------------------------------------------------
1642 
1643 static int
1644 opt_hack( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1645 {
1646  plsc->hack = 1;
1647  return 0;
1648 }
1649 
1650 //--------------------------------------------------------------------------
1651 // opt_dev()
1652 //
1662 //--------------------------------------------------------------------------
1663 
1664 static int
1665 opt_dev( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1666 {
1667  plsdev( opt_arg );
1668  return 0;
1669 }
1670 
1671 //--------------------------------------------------------------------------
1672 // opt_o()
1673 //
1683 //--------------------------------------------------------------------------
1684 
1685 static int
1686 opt_o( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1687 {
1688  plsfnam( opt_arg );
1689  return 0;
1690 }
1691 
1692 //--------------------------------------------------------------------------
1693 // opt_mar()
1694 //
1704 //--------------------------------------------------------------------------
1705 
1706 static int
1707 opt_mar( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1708 {
1709  plsdidev( atof( opt_arg ), PL_NOTSET, PL_NOTSET, PL_NOTSET );
1710  return 0;
1711 }
1712 
1713 //--------------------------------------------------------------------------
1714 // opt_a()
1715 //
1725 //--------------------------------------------------------------------------
1726 
1727 static int
1728 opt_a( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1729 {
1730  plsdidev( PL_NOTSET, atof( opt_arg ), PL_NOTSET, PL_NOTSET );
1731  return 0;
1732 }
1733 
1734 //--------------------------------------------------------------------------
1735 // opt_jx()
1736 //
1746 //--------------------------------------------------------------------------
1747 
1748 static int
1749 opt_jx( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1750 {
1751  plsdidev( PL_NOTSET, PL_NOTSET, atof( opt_arg ), PL_NOTSET );
1752  return 0;
1753 }
1754 
1755 //--------------------------------------------------------------------------
1756 // opt_jy()
1757 //
1767 //--------------------------------------------------------------------------
1768 
1769 static int
1770 opt_jy( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1771 {
1772  plsdidev( PL_NOTSET, PL_NOTSET, PL_NOTSET, atof( opt_arg ) );
1773  return 0;
1774 }
1775 
1776 //--------------------------------------------------------------------------
1777 // opt_ori()
1778 //
1788 //--------------------------------------------------------------------------
1789 
1790 static int
1791 opt_ori( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1792 {
1793  plsdiori( atof( opt_arg ) );
1794  return 0;
1795 }
1796 
1797 //--------------------------------------------------------------------------
1798 // opt_freeaspect()
1799 //
1809 //--------------------------------------------------------------------------
1810 
1811 static int
1812 opt_freeaspect( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1813 {
1814  plsc->freeaspect = 1;
1815  return 0;
1816 }
1817 
1818 //--------------------------------------------------------------------------
1819 // opt_portrait()
1820 //
1844 //--------------------------------------------------------------------------
1845 
1846 static int
1847 opt_portrait( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1848 {
1849  plsc->portrait = 1;
1850  return 0;
1851 }
1852 
1853 //--------------------------------------------------------------------------
1854 // opt_width()
1855 //
1865 //--------------------------------------------------------------------------
1866 
1867 static int
1868 opt_width( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1869 {
1870  double width;
1871 
1872  width = atof( opt_arg );
1873  if ( width < 0. )
1874  {
1875  fprintf( stderr, "?invalid width\n" );
1876  return 1;
1877  }
1878  else
1879  {
1880  plwidth( width );
1881  plsc->widthlock = 1;
1882  }
1883  return 0;
1884 }
1885 
1886 //--------------------------------------------------------------------------
1887 // opt_bg()
1888 //
1902 //--------------------------------------------------------------------------
1903 
1904 static int
1905 opt_bg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1906 {
1907  const char *rgb;
1908  char *color_field, *alpha_field;
1909  long bgcolor;
1910  PLINT r, g, b;
1911  PLFLT a;
1912 
1913 // Strip off leading "#" (TK-ism) if present.
1914 
1915  if ( *opt_arg == '#' )
1916  rgb = opt_arg + 1;
1917  else
1918  rgb = opt_arg;
1919 
1920  strncpy( opttmp, rgb, OPTMAX - 1 );
1921  opttmp[OPTMAX - 1] = '\0';
1922 
1923  if ( strchr( opttmp, '_' ) )
1924  {
1925  // e.g., -bg ff0000_0.1
1926  color_field = strtok( opttmp, "_" );
1927  alpha_field = strtok( NULL, "_" );
1928  }
1929  else
1930  {
1931  color_field = opttmp;
1932  alpha_field = NULL;
1933  }
1934 
1935  bgcolor = strtol( color_field, NULL, 16 );
1936 
1937 // Must be either a 3 or 6 digit hex number
1938 // If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC).
1939 
1940  switch ( strlen( color_field ) )
1941  {
1942  case 3:
1943  r = (PLINT) ( ( bgcolor & 0xF00 ) >> 8 );
1944  g = (PLINT) ( ( bgcolor & 0x0F0 ) >> 4 );
1945  b = (PLINT) ( bgcolor & 0x00F );
1946 
1947  r = r | ( r << 4 );
1948  g = g | ( g << 4 ); // doubling
1949  b = b | ( b << 4 );
1950  break;
1951 
1952  case 6:
1953  r = (PLINT) ( ( bgcolor & 0xFF0000 ) >> 16 );
1954  g = (PLINT) ( ( bgcolor & 0x00FF00 ) >> 8 );
1955  b = (PLINT) ( bgcolor & 0x0000FF );
1956  break;
1957 
1958  default:
1959  fprintf( stderr, "Unrecognized background color value %s\n", color_field );
1960  return 1;
1961  }
1962 
1963  if ( alpha_field )
1964  a = atof( alpha_field );
1965  else
1966  a = 1.;
1967 
1968  plscolbga( r, g, b, a );
1969 
1970  return 0;
1971 }
1972 
1973 //--------------------------------------------------------------------------
1974 // opt_ncol0()
1975 //
1985 //--------------------------------------------------------------------------
1986 
1987 static int
1988 opt_ncol0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1989 {
1990  plsc->ncol0 = atoi( opt_arg );
1991  return 0;
1992 }
1993 
1994 //--------------------------------------------------------------------------
1995 // opt_ncol1()
1996 //
2006 //--------------------------------------------------------------------------
2007 
2008 static int
2009 opt_ncol1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2010 {
2011  plsc->ncol1 = atoi( opt_arg );
2012  return 0;
2013 }
2014 
2015 //--------------------------------------------------------------------------
2016 // opt_wplt()
2017 //
2027 //--------------------------------------------------------------------------
2028 
2029 static int
2030 opt_wplt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2031 {
2032  char *field;
2033  PLFLT xl, yl, xr, yr;
2034 
2035  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2036  opttmp[OPTMAX - 1] = '\0';
2037 
2038  if ( ( field = strtok( opttmp, "," ) ) == NULL )
2039  return 1;
2040 
2041  xl = atof( field );
2042 
2043  if ( ( field = strtok( NULL, "," ) ) == NULL )
2044  return 1;
2045 
2046  yl = atof( field );
2047 
2048  if ( ( field = strtok( NULL, "," ) ) == NULL )
2049  return 1;
2050 
2051  xr = atof( field );
2052 
2053  if ( ( field = strtok( NULL, "," ) ) == NULL )
2054  return 1;
2055 
2056  yr = atof( field );
2057 
2058  plsdiplt( xl, yl, xr, yr );
2059  return 0;
2060 }
2061 
2062 //--------------------------------------------------------------------------
2063 // opt_drvopt()
2064 //
2074 //--------------------------------------------------------------------------
2075 
2076 static int
2077 opt_drvopt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2078 {
2079  char t, *tt, *option, *value;
2080  int fl = 0;
2081  DrvOptCmd *drvp;
2082 
2083  option = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2084  if ( option == NULL )
2085  plexit( "opt_drvopt: Out of memory!?" );
2086 
2087  value = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2088  if ( value == NULL )
2089  plexit( "opt_drvopt: Out of memory!?" );
2090 
2091  drvp = &drv_opt;
2092  *option = *value = '\0';
2093  tt = option;
2094  while ( ( t = *opt_arg++ ) )
2095  {
2096  switch ( t )
2097  {
2098  case ',':
2099  if ( fl )
2100  fl = 0;
2101  else
2102  {
2103  value[0] = '1';
2104  value[1] = '\0';
2105  }
2106 
2107  *tt = '\0'; tt = option;
2108  drvp->option = plstrdup( option ); // it should not be release, because of familying
2109  drvp->value = plstrdup( value ); // don't release
2110  drvp->next = (DrvOptCmd *) malloc( sizeof ( DrvOptCmd ) ); // don't release
2111  if ( drvp->next == NULL )
2112  plexit( "opt_drvopt: Out of memory!?\n" );
2113 
2114  drvp = drvp->next;
2115  break;
2116 
2117  case '=':
2118  fl = 1;
2119  *tt = '\0'; tt = value;
2120  break;
2121 
2122  default:
2123  *tt++ = t;
2124  }
2125  }
2126 
2127  *tt = '\0';
2128  if ( !fl )
2129  {
2130  value[0] = '1';
2131  value[1] = '\0';
2132  }
2133 
2134  drvp->option = plstrdup( option ); // don't release
2135  drvp->value = plstrdup( value ); // don't release
2136  drvp->next = NULL;
2137 
2138 #ifdef DEBUG
2139  fprintf( stderr, "\nopt_drvopt: -drvopt parsed options:\n" );
2140  drvp = &drv_opt;
2141  do
2142  fprintf( stderr, "%s %s\n", drvp->option, drvp->value );
2143  while ( drvp = drvp->next );
2144  fprintf( stderr, "\n" );
2145 #endif
2146 
2147  free( option ); free( value );
2148 
2149  return 0;
2150 }
2151 
2152 //--------------------------------------------------------------------------
2153 // opt_fam()
2154 //
2164 //--------------------------------------------------------------------------
2165 
2166 static int
2167 opt_fam( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2168 {
2169  plsfam( 1, -1, -1 );
2170  return 0;
2171 }
2172 
2173 //--------------------------------------------------------------------------
2174 // opt_fsiz()
2175 //
2194 //--------------------------------------------------------------------------
2195 
2196 static int
2197 opt_fsiz( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2198 {
2199  PLINT bytemax;
2200  size_t len = strlen( opt_arg );
2201  char lastchar = opt_arg[len - 1];
2202  PLFLT multiplier = 1.0e6;
2203  char *spec = (char *) malloc( len + 1 );
2204 
2205  if ( spec == NULL )
2206  plexit( "opt_fsiz: Insufficient memory" );
2207 
2208 // Interpret optional suffix
2209 
2210  switch ( lastchar )
2211  {
2212  case 'k':
2213  case 'K':
2214  multiplier = 1.0e3; len--;
2215  break;
2216  case 'm':
2217  case 'M':
2218  multiplier = 1.0e6; len--;
2219  break;
2220  case 'g':
2221  case 'G':
2222  multiplier = 1.0e9; len--;
2223  break;
2224  }
2225  strncpy( spec, opt_arg, len );
2226  spec[len] = '\0';
2227 
2228  bytemax = (PLINT) ( multiplier * atof( spec ) );
2229  if ( bytemax <= 0 )
2230  {
2231  fprintf( stderr, "?invalid file size %d. 2.14G is the maximum.\n", bytemax );
2232  return 1;
2233  }
2234  plsfam( 1, -1, bytemax );
2235 
2236  free( spec );
2237  return 0;
2238 }
2239 
2240 //--------------------------------------------------------------------------
2241 // opt_fbeg()
2242 //
2252 //--------------------------------------------------------------------------
2253 
2254 static int
2255 opt_fbeg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2256 {
2257  plsc->member = atoi( opt_arg );
2258 
2259  return 0;
2260 }
2261 
2262 //--------------------------------------------------------------------------
2263 // opt_finc()
2264 //
2274 //--------------------------------------------------------------------------
2275 
2276 static int
2277 opt_finc( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2278 {
2279  plsc->finc = atoi( opt_arg );
2280 
2281  return 0;
2282 }
2283 
2284 //--------------------------------------------------------------------------
2285 // opt_fflen()
2286 //
2296 //--------------------------------------------------------------------------
2297 
2298 static int
2299 opt_fflen( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2300 {
2301  plsc->fflen = atoi( opt_arg );
2302 
2303  return 0;
2304 }
2305 
2306 //--------------------------------------------------------------------------
2307 // opt_np()
2308 //
2318 //--------------------------------------------------------------------------
2319 
2320 static int
2321 opt_np( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2322 {
2323  plspause( 0 );
2324  return 0;
2325 }
2326 
2327 //--------------------------------------------------------------------------
2328 // opt_nopixmap()
2329 //
2339 //--------------------------------------------------------------------------
2340 
2341 static int
2342 opt_nopixmap( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2343 {
2344  plsc->nopixmap = 1;
2345  return 0;
2346 }
2347 
2348 //--------------------------------------------------------------------------
2349 // opt_db()
2350 //
2360 //--------------------------------------------------------------------------
2361 
2362 static int
2363 opt_db( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2364 {
2365  plsc->db = 1;
2366  return 0;
2367 }
2368 
2369 //--------------------------------------------------------------------------
2370 // opt_bufmax()
2371 //
2381 //--------------------------------------------------------------------------
2382 
2383 static int
2384 opt_bufmax( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2385 {
2386  plsc->bufmax = atoi( opt_arg );
2387  return 0;
2388 }
2389 
2390 //--------------------------------------------------------------------------
2391 // opt_server_name()
2392 //
2402 //--------------------------------------------------------------------------
2403 
2404 static int
2405 opt_server_name( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2406 {
2407  plsc->server_name = plstrdup( opt_arg );
2408  return 0;
2409 }
2410 
2411 //--------------------------------------------------------------------------
2412 // opt_plserver()
2413 //
2423 //--------------------------------------------------------------------------
2424 
2425 static int
2426 opt_plserver( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2427 {
2428  plsc->plserver = plstrdup( opt_arg );
2429  return 0;
2430 }
2431 
2432 //--------------------------------------------------------------------------
2433 // opt_plwindow()
2434 //
2444 //--------------------------------------------------------------------------
2445 
2446 static int
2447 opt_plwindow( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2448 {
2449  if ( ( plsc->plwindow = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2450  {
2451  plexit( "opt_plwindow: Insufficient memory" );
2452  }
2453  strcpy( plsc->plwindow, opt_arg );
2454  return 0;
2455 }
2456 
2457 //--------------------------------------------------------------------------
2458 // opt_auto_path()
2459 //
2469 //--------------------------------------------------------------------------
2470 
2471 static int
2472 opt_auto_path( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2473 {
2474  plsc->auto_path = plstrdup( opt_arg );
2475  return 0;
2476 }
2477 
2478 //--------------------------------------------------------------------------
2479 // opt_px()
2480 //
2490 //--------------------------------------------------------------------------
2491 
2492 static int
2493 opt_px( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2494 {
2495  plssub( atoi( opt_arg ), -1 );
2496  return 0;
2497 }
2498 
2499 //--------------------------------------------------------------------------
2500 // opt_py()
2501 //
2511 //--------------------------------------------------------------------------
2512 
2513 static int
2514 opt_py( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2515 {
2516  plssub( -1, atoi( opt_arg ) );
2517  return 0;
2518 }
2519 
2520 //--------------------------------------------------------------------------
2521 // opt_geo()
2522 //
2536 //--------------------------------------------------------------------------
2537 
2538 static int
2539 opt_geo( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2540 {
2541  int numargs;
2542  PLFLT xdpi = 0., ydpi = 0.;
2543  PLINT xwid, ywid, xoff, yoff;
2544 
2545 // The TK driver uses the geometry string directly
2546 
2547  if ( ( plsc->geometry = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2548  {
2549  plexit( "opt_geo: Insufficient memory" );
2550  }
2551 
2552  strcpy( plsc->geometry, opt_arg );
2553 
2554  numargs = sscanf( opt_arg, "%dx%d%d%d", &xwid, &ywid, &xoff, &yoff );
2555  if ( numargs == 2 )
2556  {
2557  xoff = 0;
2558  yoff = 0;
2559  if ( xwid == 0 )
2560  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2561  if ( ywid == 0 )
2562  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2563  if ( xwid < 0 )
2564  {
2565  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2566  return 1;
2567  }
2568  if ( ywid < 0 )
2569  {
2570  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2571  return 1;
2572  }
2573  }
2574  else if ( numargs == 4 )
2575  {
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  if ( abs( xoff ) == 0 )
2591  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2592  if ( abs( yoff ) == 0 )
2593  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2594  }
2595  else
2596  {
2597  numargs = sscanf( opt_arg, "%d%d", &xoff, &yoff );
2598  if ( numargs == 2 )
2599  {
2600  xwid = 0;
2601  ywid = 0;
2602  if ( abs( xoff ) == 0 )
2603  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2604  if ( abs( yoff ) == 0 )
2605  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2606  }
2607  else
2608  {
2609  fprintf( stderr, "?invalid -geometry %s\n", opt_arg );
2610  return 1;
2611  }
2612  }
2613  //fprintf( stderr, "xwid, ywid, xoff, yoff = %d, %d, %d, %d\n", xwid, ywid, xoff, yoff );
2614  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2615  return 0;
2616 }
2617 
2618 //--------------------------------------------------------------------------
2619 // opt_tk_file()
2620 //
2629 //--------------------------------------------------------------------------
2630 
2631 static int
2632 opt_tk_file( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2633 {
2634  if ( ( plsc->tk_file = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2635  {
2636  plexit( "opt_tk_file: Insufficient memory" );
2637  }
2638 
2639  strcpy( plsc->tk_file, opt_arg );
2640  return 0;
2641 }
2642 
2643 //--------------------------------------------------------------------------
2644 // opt_dpi()
2645 //
2659 //--------------------------------------------------------------------------
2660 
2661 static int
2662 opt_dpi( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2663 {
2664  char *field;
2665  PLFLT xdpi = 0., ydpi = 0.;
2666  PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0;
2667 
2668  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2669  opttmp[OPTMAX - 1] = '\0';
2670  if ( strchr( opttmp, 'x' ) )
2671  {
2672  field = strtok( opttmp, "x" );
2673  xdpi = atof( field );
2674  if ( xdpi == 0 )
2675  fprintf( stderr, "?invalid xdpi\n" );
2676 
2677  if ( ( field = strtok( NULL, " " ) ) == NULL )
2678  return 1;
2679 
2680  ydpi = atof( field );
2681  if ( ydpi == 0 )
2682  fprintf( stderr, "?invalid ydpi\n" );
2683  }
2684  else
2685  {
2686  xdpi = atof( opttmp );
2687  ydpi = xdpi;
2688  if ( xdpi == 0 )
2689  return 1;
2690  }
2691 
2692  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2693  return 0;
2694 }
2695 
2696 //--------------------------------------------------------------------------
2697 // opt_dev_compression()
2698 //
2707 //--------------------------------------------------------------------------
2708 
2709 static int
2710 opt_dev_compression( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2711 {
2712  PLINT comp = 0;
2713 
2714  comp = atoi( opt_arg );
2715  if ( comp == 0 )
2716  {
2717  fprintf( stderr, "?invalid compression\n" );
2718  return 1;
2719  }
2720  plscompression( comp );
2721 
2722  return 0;
2723 }
2724 
2725 //--------------------------------------------------------------------------
2726 // opt_cmap0()
2727 //
2736 //--------------------------------------------------------------------------
2737 
2738 static int
2739 opt_cmap0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2740 {
2741  plspal0( opt_arg );
2742  return 0;
2743 }
2744 
2745 //--------------------------------------------------------------------------
2746 // opt_cmap1()
2747 //
2756 //--------------------------------------------------------------------------
2757 
2758 static int
2759 opt_cmap1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2760 {
2761  plspal1( opt_arg, TRUE );
2762  return 0;
2763 }
2764 
2765 //--------------------------------------------------------------------------
2766 // opt_locale()
2767 //
2776 //--------------------------------------------------------------------------
2777 
2778 static int
2779 opt_locale( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2780 {
2781  char *locale;
2782  if ( ( locale = setlocale( LC_NUMERIC, "" ) ) )
2783  {
2784  printf( "LC_NUMERIC locale set to \"%s\"\n", locale );
2785  }
2786  else
2787  {
2788  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" );
2789  if ( !( locale = setlocale( LC_NUMERIC, "C" ) ) )
2790  {
2791  plexit( "Your platform is seriously broken. Not even a \"C\" locale could be set." );
2792  }
2793  }
2794  return 0;
2795 }
2796 
2797 //--------------------------------------------------------------------------
2798 // opt_eofill()
2799 //
2810 //--------------------------------------------------------------------------
2811 
2812 static int
2813 opt_eofill( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2814 {
2815  plsc->dev_eofill = 1;
2816  return 0;
2817 }