PLplot  5.10.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 //
7 // This file is part of PLplot.
8 //
9 // PLplot is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as published
11 // by the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // PLplot is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with PLplot; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // Some parts of this code were derived from "xterm.c" and "ParseCmd.c" of
24 // the X-windows Version 11 distribution. The copyright notice is
25 // reproduced here:
26 //
27 // Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
28 // and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
29 //
30 // All Rights Reserved
31 //
32 // The full permission notice is given in the PLplot documentation.
33 //
34 //--------------------------------------------------------------------------
35 //
96 
97 #include "plplotP.h"
98 #include <ctype.h>
99 
100 #ifdef HAVE_CRT_EXTERNS_H
101 //
102 // This include file has the declaration for _NSGetArgc(). See below.
103 //
104 #include <crt_externs.h>
105 #endif
106 
107 // Support functions
108 
109 static int ParseOpt( int *, const char ***, int *, const char ***, PLOptionTable * );
110 static int ProcessOpt( const char *, PLOptionTable *, int *, const char ***, int * );
111 static int GetOptarg( const char **, int *, const char ***, int * );
112 static void Help( void );
113 static void Syntax( void );
114 
115 #ifndef PL_DEPRECATED
116 int plSetOpt( const char * opt, const char *opt_arg );
117 #endif
118 
119 // Option handlers
120 
121 static int opt_h( const char *, const char *, void * );
122 static int opt_v( const char *, const char *, void * );
123 static int opt_verbose( const char *, const char *, void * );
124 static int opt_debug( const char *, const char *, void * );
125 static int opt_hack( const char *, const char *, void * );
126 static int opt_dev( const char *, const char *, void * );
127 static int opt_o( const char *, const char *, void * );
128 static int opt_geo( const char *, const char *, void * );
129 static int opt_a( const char *, const char *, void * );
130 static int opt_jx( const char *, const char *, void * );
131 static int opt_jy( const char *, const char *, void * );
132 static int opt_mar( const char *, const char *, void * );
133 static int opt_ori( const char *, const char *, void * );
134 static int opt_freeaspect( const char *, const char *, void * );
135 static int opt_portrait( const char *, const char *, void * );
136 static int opt_width( const char *, const char *, void * );
137 static int opt_bg( const char *, const char *, void * );
138 static int opt_ncol0( const char *, const char *, void * );
139 static int opt_ncol1( const char *, const char *, void * );
140 static int opt_fam( const char *, const char *, void * );
141 static int opt_fsiz( const char *, const char *, void * );
142 static int opt_fbeg( const char *, const char *, void * );
143 static int opt_finc( const char *, const char *, void * );
144 static int opt_fflen( const char *, const char *, void * );
145 static int opt_bufmax( const char *, const char *, void * );
146 static int opt_nopixmap( const char *, const char *, void * );
147 static int opt_db( const char *, const char *, void * );
148 static int opt_np( const char *, const char *, void * );
149 static int opt_px( const char *, const char *, void * );
150 static int opt_py( const char *, const char *, void * );
151 static int opt_wplt( const char *, const char *, void * );
152 static int opt_drvopt( const char *, const char *, void * );
153 
154 static int opt_plserver( const char *, const char *, void * );
155 static int opt_plwindow( const char *, const char *, void * );
156 static int opt_auto_path( const char *, const char *, void * );
157 static int opt_bufmax( const char *, const char *, void * );
158 static int opt_server_name( const char *, const char *, void * );
159 static int opt_tk_file( const char *, const char *, void * );
160 static int opt_dpi( const char *, const char *, void * );
161 static int opt_dev_compression( const char *, const char *, void * );
162 static int opt_cmap0( const char *, const char *, void * );
163 static int opt_cmap1( const char *, const char *, void * );
164 static int opt_locale( const char *, const char *, void * );
165 static int opt_eofill( 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  NULL, // option
654  NULL, // handler
655  NULL, // client data
656  NULL, // address of variable to set
657  0, // mode flag
658  NULL, // short syntax
659  NULL
660  } // long syntax
661 };
662 
663 static const char *plplot_notes[] = {
664  "All parameters must be white-space delimited. Some options are driver",
665  "dependent. Please see the PLplot reference document for more detail.",
666  NULL
667 };
668 
669 //--------------------------------------------------------------------------
683 //--------------------------------------------------------------------------
684 
685 typedef struct
686 {
688  const char *name;
689  const char **notes;
690 } PLOptionInfo;
691 
694  "PLplot options",
696 };
697 
698 #define PL_MAX_OPT_TABLES 10
700  {
702  "PLplot options",
704  }
705 };
706 
707 // The structure that hold the driver specific command line options
708 
709 typedef struct DrvOptCmd
710 {
711  char *option;
712  char *value;
713  struct DrvOptCmd *next;
714 } DrvOptCmd;
715 
716 // the variable where opt_drvopt() stores the driver specific command line options
717 static DrvOptCmd drv_opt = { NULL, NULL, NULL };
718 
719 static int tables = 1;
720 
721 //--------------------------------------------------------------------------
722 // plSetOpt()
723 //
732 //--------------------------------------------------------------------------
733 
734 int
735 plSetOpt( const char * opt, const char *opt_arg )
736 {
737  return ( c_plsetopt( opt, opt_arg ) );
738 }
739 
740 int
741 c_plsetopt( const char * opt, const char *opt_arg )
742 {
743  int mode = 0, argc = 2, status;
744  const char *argv[3];
745 
746  argv[0] = opt;
747  argv[1] = opt_arg;
748  argv[2] = NULL;
749  mode =
754 
755  status = plparseopts( &argc, argv, mode );
756  if ( status )
757  {
758  fprintf( stderr, "plSetOpt: Unrecognized option %s\n", opt );
759  }
760  return status;
761 }
762 
763 //--------------------------------------------------------------------------
764 // plMergeOpts()
765 //
772 //--------------------------------------------------------------------------
773 
774 int
775 plMergeOpts( PLOptionTable *options, const char *name, const char **notes )
776 {
777  PLOptionTable *tab;
778 
779  pllib_init();
780 
781 // Check to make sure option table has been terminated correctly
782 
783  for ( tab = (PLOptionTable *) options; tab->opt; tab++ )
784  ;
785 
786 // We've reached the last table entry. All the subentries must be NULL or 0
787 
788  if ( ( tab->handler != NULL ) ||
789  ( tab->client_data != NULL ) ||
790  ( tab->var != NULL ) ||
791  ( tab->mode != 0 ) ||
792  ( tab->syntax != NULL ) ||
793  ( tab->desc != NULL ) )
794  {
795  plabort( "plMergeOpts: input table improperly terminated" );
796  return 1;
797  }
798 
799 // No room for more tables
800 
801  if ( tables++ >= PL_MAX_OPT_TABLES )
802  {
803  plabort( "plMergeOpts: max tables limit exceeded, table not merged" );
804  return 1;
805  }
806 
807  ploption_info[tables - 1].options = options;
808  ploption_info[tables - 1].name = name;
809  ploption_info[tables - 1].notes = notes;
810 
811  return 0;
812 }
813 
814 //--------------------------------------------------------------------------
815 // plClearOpts()
816 //
819 //--------------------------------------------------------------------------
820 
821 void
822 plClearOpts( void )
823 {
824  tables = 0;
825 }
826 
827 //--------------------------------------------------------------------------
828 // plResetOpts()
829 //
832 //--------------------------------------------------------------------------
833 
834 void
835 plResetOpts( void )
836 {
837  ploption_info[0] = ploption_info_default;
838  tables = 1;
839 }
840 
841 //--------------------------------------------------------------------------
842 // plparseopts()
843 //
854 //--------------------------------------------------------------------------
855 
856 int
857 c_plparseopts( int *p_argc, const char **argv, PLINT mode )
858 {
859  const char **argsave, **argend;
860  int i, myargc, status = 0;
861 
862  pllib_init();
863 
864 // Initialize
865 
866  mode_full = mode & PL_PARSE_FULL;
867  mode_quiet = mode & PL_PARSE_QUIET;
871  mode_nodash = mode & PL_PARSE_NODASH;
872  mode_skip = mode & PL_PARSE_SKIP;
873 
874  myargc = ( *p_argc );
875  argend = argv + myargc;
876 
877 // If program name is first argument, save and advance
878 
879  if ( !mode_noprogram )
880  {
881  plsc->program = plstrdup( argv[0] );
882  program = (const char *) plsc->program;
883  --myargc; ++argv;
884  }
885  if ( myargc == 0 )
886  return 0;
887 
888 // Process the command line
889 
890  argsave = argv;
891  for (; myargc > 0; --myargc, ++argv )
892  {
893  // Allow for "holes" in argv list
894 
895  if ( *argv == NULL || *argv[0] == '\0' )
896  continue;
897 
898  // Loop over all options tables, starting with the last
899 
900  for ( i = tables - 1; i >= 0; i-- )
901  {
902  // Check option table for option
903 
904  status = ParseOpt( &myargc, &argv, p_argc, &argsave,
905  ploption_info[i].options );
906 
907  if ( !status )
908  break;
909  }
910 
911  // Handle error return as specified by the mode flag
912 
913  if ( status == -1 )
914  {
915  // No match. Keep going if mode_skip is set, otherwise abort if
916  // fully parsing, else return without error.
917 
918  status = 0;
919 
920  if ( mode_skip )
921  {
922  if ( !mode_nodelete )
923  *argsave++ = *argv;
924  continue;
925  }
926  if ( !mode_quiet && mode_full )
927  {
928  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
929  plOptUsage();
930  }
931  if ( mode_full )
932  exit( 1 );
933 
934  break;
935  }
936  else if ( status == 1 )
937  {
938  // Illegal or badly formed
939 
940  if ( !mode_quiet )
941  {
942  fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
943  plOptUsage();
944  }
945  if ( mode_full )
946  exit( 1 );
947 
948  break;
949  }
950  else if ( status == 2 )
951  {
952  // Informational option encountered (-h or -v)
953 
954  exit( 0 );
955  }
956  }
957 
958 // Compress and NULL-terminate argv
959 
960  if ( !mode_nodelete )
961  {
962  for ( i = 0; i < myargc; i++ )
963  *argsave++ = *argv++;
964 
965  if ( argsave < argend )
966  {
967  *argsave = NULL;
968 #ifdef HAVE_NSGETARGC
969  //
970  // Modify the global argc variable to match the shortened argv.
971  // The global argc and argv must be kept consistent so that future
972  // users of them (e.g. libraries loaded later with a device driver)
973  // will not try to dereference the null pointer at the end of the
974  // shortened argv array.
975  //
976  *_NSGetArgc() = *p_argc;
977 #endif
978  }
979  }
980 
981  return status;
982 }
983 
984 //--------------------------------------------------------------------------
985 // ParseOpt()
986 //
997 //--------------------------------------------------------------------------
998 
999 static int
1000 ParseOpt( int *p_myargc, const char ***p_argv, int *p_argc, const char ***p_argsave,
1001  PLOptionTable *option_table )
1002 {
1003  PLOptionTable *tab;
1004  const char *opt;
1005 
1006 // Only handle actual flags and their arguments
1007 
1008  if ( mode_nodash || ( *p_argv )[0][0] == '-' )
1009  {
1010  opt = ( *p_argv )[0];
1011  if ( *opt == '-' )
1012  opt++;
1013 
1014  for ( tab = option_table; tab->opt; tab++ )
1015  {
1016  // Skip if option not enabled
1017 
1018  if ( tab->mode & PL_OPT_DISABLED )
1019  continue;
1020 
1021  // Try to match it
1022 
1023  if ( *opt == *tab->opt && !strcmp( opt, tab->opt ) )
1024  {
1025  // Option matched, so remove from argv list if applicable.
1026 
1027  if ( !mode_nodelete )
1028  {
1029  if ( tab->mode & PL_OPT_NODELETE )
1030  ( *( *p_argsave )++ ) = ( **p_argv );
1031  else
1032  --( *p_argc );
1033  }
1034 
1035  // Process option (and argument if applicable)
1036 
1037  return ( ProcessOpt( opt, tab, p_myargc, p_argv, p_argc ) );
1038  }
1039  }
1040  }
1041 
1042  return -1;
1043 }
1044 
1045 //--------------------------------------------------------------------------
1046 // ProcessOpt()
1047 //
1057 //--------------------------------------------------------------------------
1058 
1059 static int
1060 ProcessOpt( const char * opt, PLOptionTable *tab, int *p_myargc, const char ***p_argv,
1061  int *p_argc )
1062 {
1063  int need_arg, res;
1064  const char *opt_arg = NULL;
1065 
1066 // Get option argument if necessary
1067 
1069 
1070  if ( tab->mode & need_arg )
1071  {
1072  if ( GetOptarg( &opt_arg, p_myargc, p_argv, p_argc ) )
1073  return 1;
1074  }
1075 
1076 // Process argument
1077 
1078  switch ( tab->mode & 0xFF00 )
1079  {
1080  case PL_OPT_FUNC:
1081 
1082  // Call function handler to do the job
1083 
1084  if ( tab->handler == NULL )
1085  {
1086  fprintf( stderr,
1087  "ProcessOpt: no handler specified for option %s\n",
1088  tab->opt );
1089  return 1;
1090  }
1091 
1092  if ( mode_nodelete && opt_arg )
1093  {
1094  // Make a copy, since handler may mung opt_arg with strtok()
1095  char *copy =
1096  (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
1097  if ( copy == NULL )
1098  {
1099  plabort( "ProcessOpt: out of memory" );
1100  return 1;
1101  }
1102  strcpy( copy, opt_arg );
1103  res = ( ( *tab->handler )( opt, copy, tab->client_data ) );
1104  free( (void *) copy );
1105  return res;
1106  }
1107  else
1108  {
1109  return ( ( *tab->handler )( opt, opt_arg, tab->client_data ) );
1110  }
1111 
1112  case PL_OPT_BOOL:
1113 
1114  // Set *var as a boolean
1115 
1116  if ( tab->var == NULL )
1117  {
1118  fprintf( stderr,
1119  "ProcessOpt: no variable specified for option %s\n",
1120  tab->opt );
1121  return 1;
1122  }
1123  *(int *) tab->var = 1;
1124  break;
1125 
1126  case PL_OPT_INT:
1127 
1128  // Set *var as an int
1129 
1130  if ( tab->var == NULL )
1131  {
1132  fprintf( stderr,
1133  "ProcessOpt: no variable specified for option %s\n",
1134  tab->opt );
1135  return 1;
1136  }
1137  *(int *) tab->var = atoi( opt_arg );
1138  break;
1139 
1140  case PL_OPT_FLOAT:
1141 
1142  // Set *var as a float
1143 
1144  if ( tab->var == NULL )
1145  {
1146  fprintf( stderr,
1147  "ProcessOpt: no variable specified for option %s\n",
1148  tab->opt );
1149  return 1;
1150  }
1151  *(PLFLT *) tab->var = atof( opt_arg );
1152  break;
1153 
1154  case PL_OPT_STRING:
1155 
1156  // Set var (can be NULL initially) to point to opt_arg string
1157 
1158  *(const char **) tab->var = opt_arg;
1159  break;
1160 
1161  default:
1162 
1163  // Somebody messed up..
1164 
1165  fprintf( stderr,
1166  "ProcessOpt: invalid processing mode for option %s\n",
1167  tab->opt );
1168  return 1;
1169  }
1170  return 0;
1171 }
1172 
1173 //--------------------------------------------------------------------------
1174 // GetOptarg()
1175 //
1186 //--------------------------------------------------------------------------
1187 
1188 static int
1189 GetOptarg( const char **popt_arg, int *p_myargc, const char ***p_argv, int *p_argc )
1190 {
1191  int result = 0;
1192 
1193  --( *p_myargc );
1194 
1195  if ( ( *p_myargc ) <= 0 ) // oops, no more arguments
1196  result = 1;
1197 
1198  if ( !result )
1199  {
1200  ( *p_argv )++;
1201  if ( ( *p_argv )[0][0] == '-' && isalpha( ( *p_argv )[0][1] ) )
1202  {
1203  ( *p_argv )--; // oops, next arg is a flag
1204  result = 1;
1205  }
1206  }
1207 
1208  if ( !result ) // yeah, the user got it right
1209  {
1210  ( *p_argc )--;
1211  *popt_arg = ( *p_argv )[0];
1212  }
1213  else
1214  {
1215  if ( !mode_quiet )
1216  {
1217  fprintf( stderr, "Argument missing for %s option.\n", ( *p_argv )[0] );
1218  plOptUsage();
1219  }
1220  }
1221  return result;
1222 }
1223 
1224 //--------------------------------------------------------------------------
1225 // plSetUsage()
1226 //
1232 //--------------------------------------------------------------------------
1233 
1234 void
1235 plSetUsage( const char *program_string, const char *usage_string )
1236 {
1237  if ( program_string != NULL )
1238  program = program_string;
1239 
1240  if ( usage_string != NULL )
1241  usage = usage_string;
1242 }
1243 
1244 //--------------------------------------------------------------------------
1245 // plOptUsage()
1246 //
1249 //--------------------------------------------------------------------------
1250 
1251 void
1252 plOptUsage( void )
1253 {
1254  if ( usage == NULL )
1255  fprintf( stderr, "\nUsage:\n %s [options]\n", program );
1256  else
1257  fputs( usage, stderr );
1258 
1259  Syntax();
1260 
1261  fprintf( stderr, "\n\nType %s -h for a full description.\n\n",
1262  program );
1263 }
1264 
1265 //--------------------------------------------------------------------------
1266 // Syntax()
1267 //
1270 //--------------------------------------------------------------------------
1271 
1272 static void
1273 Syntax( void )
1274 {
1275  PLOptionTable *tab;
1276  int i, col, len;
1277 
1278 // Loop over all options tables
1279 
1280  for ( i = tables - 1; i >= 0; i-- )
1281  {
1282  // Introducer
1283 
1284  if ( ploption_info[i].name )
1285  fprintf( stderr, "\n%s:", ploption_info[i].name );
1286  else
1287  fputs( "\nUser options:", stderr );
1288 
1289  // Print syntax for each option
1290 
1291  col = 80;
1292  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1293  {
1294  if ( tab->mode & PL_OPT_DISABLED )
1295  continue;
1296 
1297  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1298  continue;
1299 
1300  if ( tab->syntax == NULL )
1301  continue;
1302 
1303  len = 3 + (int) strlen( tab->syntax ); // space [ string ]
1304  if ( col + len > 79 )
1305  {
1306  fprintf( stderr, "\n " ); // 3 spaces
1307  col = 3;
1308  }
1309  fprintf( stderr, " [%s]", tab->syntax );
1310  col += len;
1311  }
1312  fprintf( stderr, "\n" );
1313  }
1314 }
1315 
1316 //--------------------------------------------------------------------------
1317 // Help()
1318 //
1321 //--------------------------------------------------------------------------
1322 
1323 static void
1324 Help( void )
1325 {
1326  PLOptionTable *tab;
1327  const char **note;
1328  int i;
1329  FILE *outfile = stderr;
1330 
1331 #ifdef HAVE_POPEN
1332  FILE *pager = NULL;
1333  if ( getenv( "PAGER" ) != NULL )
1334  pager = (FILE *) popen( "$PAGER", "w" );
1335  if ( pager == NULL )
1336  pager = (FILE *) popen( "more", "w" );
1337  if ( pager != NULL )
1338  outfile = pager;
1339 #endif
1340 
1341 // Usage line
1342 
1343  if ( usage == NULL )
1344  fprintf( outfile, "\nUsage:\n %s [options]\n", program );
1345  else
1346  fputs( usage, outfile );
1347 
1348 // Loop over all options tables
1349 
1350  for ( i = tables - 1; i >= 0; i-- )
1351  {
1352  // Introducer
1353 
1354  if ( ploption_info[i].name )
1355  fprintf( outfile, "\n%s:\n", ploption_info[i].name );
1356  else
1357  fputs( "\nUser options:\n", outfile );
1358 
1359  // Print description for each option
1360 
1361  for ( tab = ploption_info[i].options; tab->opt; tab++ )
1362  {
1363  if ( tab->mode & PL_OPT_DISABLED )
1364  continue;
1365 
1366  if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
1367  continue;
1368 
1369  if ( tab->desc == NULL )
1370  continue;
1371 
1372  if ( tab->mode & PL_OPT_INVISIBLE )
1373  fprintf( outfile, " * %-20s %s\n", tab->syntax, tab->desc );
1374  else
1375  fprintf( outfile, " %-20s %s\n", tab->syntax, tab->desc );
1376  }
1377 
1378  // Usage notes
1379 
1380  if ( ploption_info[i].notes )
1381  {
1382  putc( '\n', outfile );
1383  for ( note = ploption_info[i].notes; *note; note++ )
1384  {
1385  fputs( *note, outfile );
1386  putc( '\n', outfile );
1387  }
1388  }
1389  }
1390 
1391 #ifdef HAVE_POPEN
1392  if ( pager != NULL )
1393  pclose( pager );
1394 #endif
1395 }
1396 
1397 //--------------------------------------------------------------------------
1398 // plParseDrvOpts
1399 //
1406 //--------------------------------------------------------------------------
1407 
1408 int
1410 {
1411  DrvOptCmd *drvp;
1412  DrvOpt *t;
1413  int fl;
1414  char msg[80];
1415  memset( msg, '\0', sizeof ( msg ) );
1416 
1417  if ( !drv_opt.option )
1418  return 1;
1419 
1420  drvp = &drv_opt;
1421  do
1422  {
1423  t = acc_opt; fl = 0;
1424  while ( t->opt )
1425  {
1426  if ( strcmp( drvp->option, t->opt ) == 0 )
1427  {
1428  fl = 1;
1429  switch ( t->type )
1430  {
1431  case DRV_STR:
1432  *(char **) ( t->var_ptr ) = ( drvp->value );
1433 #ifdef DEBUG
1434  fprintf( stderr, "plParseDrvOpts: %s %s\n", t->opt, *(char **) t->var_ptr );
1435 #endif
1436  break;
1437 
1438  case DRV_INT:
1439  if ( sscanf( drvp->value, "%d", (int *) t->var_ptr ) != 1 )
1440  {
1441  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1442  plexit( msg );
1443  }
1444 #ifdef DEBUG
1445  fprintf( stderr, "plParseDrvOpts: %s %d\n", t->opt, *(int *) t->var_ptr );
1446 #endif
1447  break;
1448 
1449  case DRV_FLT:
1450  if ( sscanf( drvp->value, "%f", (float *) t->var_ptr ) != 1 )
1451  {
1452  snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
1453  plexit( msg );
1454  }
1455 #ifdef DEBUG
1456  fprintf( stderr, "plParseDrvOpts: %s %f\n", t->opt, *(float *) t->var_ptr );
1457 #endif
1458  break;
1459  }
1460  }
1461  t++;
1462  }
1463 
1464  if ( !fl )
1465  {
1466  snprintf( msg, sizeof ( msg ) - 1, "Option '%s' not recognized.\n\nRecognized options for this driver are:\n", drvp->option );
1467  plwarn( msg );
1468  plHelpDrvOpts( acc_opt );
1469  plexit( "" );
1470  }
1471  }
1472  while ( ( drvp = drvp->next ) )
1473  ;
1474 
1475  return 0;
1476 }
1477 
1478 //--------------------------------------------------------------------------
1479 // plHelpDrvOpts
1480 //
1485 //--------------------------------------------------------------------------
1486 
1487 void
1489 {
1490  DrvOpt *t;
1491 
1492  t = acc_opt;
1493  while ( t->opt )
1494  {
1495  fprintf( stderr, "%s:\t%s\n", t->opt, t->hlp_msg );
1496  t++;
1497  }
1498 }
1499 
1500 //--------------------------------------------------------------------------
1501 // tidyDrvOpts
1502 //
1505 //--------------------------------------------------------------------------
1506 
1507 void
1509 {
1510  DrvOptCmd *drvp, *drvpl;
1511 
1512  drvp = &drv_opt;
1513  do
1514  {
1515  drvpl = drvp;
1516  drvp = drvpl->next;
1517 
1518  free( drvpl->option );
1519  free( drvpl->value );
1520  // Free additional DrvOptCmd variables -
1521  // first entry in list is a static global variable
1522  if ( drvpl != &drv_opt )
1523  free( drvpl );
1524  } while ( drvp != NULL );
1525 
1526  // initialize drv_opt if it's used again
1527  drv_opt.option = NULL;
1528  drv_opt.value = NULL;
1529  drv_opt.next = NULL;
1530 }
1531 
1532 
1533 //--------------------------------------------------------------------------
1534 // Option handlers
1535 //--------------------------------------------------------------------------
1536 
1537 //--------------------------------------------------------------------------
1538 // opt_h()
1539 //
1549 //--------------------------------------------------------------------------
1550 
1551 static int
1552 opt_h( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1553 {
1554  if ( !mode_quiet )
1555  Help();
1556 
1557  return 2;
1558 }
1559 
1560 //--------------------------------------------------------------------------
1561 // opt_v()
1562 //
1572 //--------------------------------------------------------------------------
1573 
1574 static int
1575 opt_v( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1576 {
1577  if ( !mode_quiet )
1578  fprintf( stderr, "PLplot library version: %s\n", PLPLOT_VERSION );
1579 
1580  return 2;
1581 }
1582 
1583 //--------------------------------------------------------------------------
1584 // opt_verbose()
1585 //
1595 //--------------------------------------------------------------------------
1596 
1597 static int
1598 opt_verbose( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1599 {
1600  plsc->verbose = 1;
1601  return 0;
1602 }
1603 
1604 //--------------------------------------------------------------------------
1605 // opt_debug()
1606 //
1616 //--------------------------------------------------------------------------
1617 
1618 static int
1619 opt_debug( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1620 {
1621  plsc->debug = 1;
1622  plsc->verbose = 1;
1623  return 0;
1624 }
1625 
1626 //--------------------------------------------------------------------------
1627 // opt_hack()
1628 //
1638 //--------------------------------------------------------------------------
1639 
1640 static int
1641 opt_hack( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1642 {
1643  plsc->hack = 1;
1644  return 0;
1645 }
1646 
1647 //--------------------------------------------------------------------------
1648 // opt_dev()
1649 //
1659 //--------------------------------------------------------------------------
1660 
1661 static int
1662 opt_dev( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1663 {
1664  plsdev( opt_arg );
1665  return 0;
1666 }
1667 
1668 //--------------------------------------------------------------------------
1669 // opt_o()
1670 //
1680 //--------------------------------------------------------------------------
1681 
1682 static int
1683 opt_o( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1684 {
1685  plsfnam( opt_arg );
1686  return 0;
1687 }
1688 
1689 //--------------------------------------------------------------------------
1690 // opt_mar()
1691 //
1701 //--------------------------------------------------------------------------
1702 
1703 static int
1704 opt_mar( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1705 {
1706  plsdidev( atof( opt_arg ), PL_NOTSET, PL_NOTSET, PL_NOTSET );
1707  return 0;
1708 }
1709 
1710 //--------------------------------------------------------------------------
1711 // opt_a()
1712 //
1722 //--------------------------------------------------------------------------
1723 
1724 static int
1725 opt_a( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1726 {
1727  plsdidev( PL_NOTSET, atof( opt_arg ), PL_NOTSET, PL_NOTSET );
1728  return 0;
1729 }
1730 
1731 //--------------------------------------------------------------------------
1732 // opt_jx()
1733 //
1743 //--------------------------------------------------------------------------
1744 
1745 static int
1746 opt_jx( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1747 {
1748  plsdidev( PL_NOTSET, PL_NOTSET, atof( opt_arg ), PL_NOTSET );
1749  return 0;
1750 }
1751 
1752 //--------------------------------------------------------------------------
1753 // opt_jy()
1754 //
1764 //--------------------------------------------------------------------------
1765 
1766 static int
1767 opt_jy( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1768 {
1769  plsdidev( PL_NOTSET, PL_NOTSET, PL_NOTSET, atof( opt_arg ) );
1770  return 0;
1771 }
1772 
1773 //--------------------------------------------------------------------------
1774 // opt_ori()
1775 //
1785 //--------------------------------------------------------------------------
1786 
1787 static int
1788 opt_ori( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1789 {
1790  plsdiori( atof( opt_arg ) );
1791  return 0;
1792 }
1793 
1794 //--------------------------------------------------------------------------
1795 // opt_freeaspect()
1796 //
1806 //--------------------------------------------------------------------------
1807 
1808 static int
1809 opt_freeaspect( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1810 {
1811  plsc->freeaspect = 1;
1812  return 0;
1813 }
1814 
1815 //--------------------------------------------------------------------------
1816 // opt_portrait()
1817 //
1841 //--------------------------------------------------------------------------
1842 
1843 static int
1844 opt_portrait( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
1845 {
1846  plsc->portrait = 1;
1847  return 0;
1848 }
1849 
1850 //--------------------------------------------------------------------------
1851 // opt_width()
1852 //
1862 //--------------------------------------------------------------------------
1863 
1864 static int
1865 opt_width( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1866 {
1867  double width;
1868 
1869  width = atof( opt_arg );
1870  if ( width < 0. )
1871  {
1872  fprintf( stderr, "?invalid width\n" );
1873  return 1;
1874  }
1875  else
1876  {
1877  plwidth( width );
1878  plsc->widthlock = 1;
1879  }
1880  return 0;
1881 }
1882 
1883 //--------------------------------------------------------------------------
1884 // opt_bg()
1885 //
1899 //--------------------------------------------------------------------------
1900 
1901 static int
1902 opt_bg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1903 {
1904  const char *rgb;
1905  char *color_field, *alpha_field;
1906  long bgcolor;
1907  PLINT r, g, b;
1908  PLFLT a;
1909 
1910 // Strip off leading "#" (TK-ism) if present.
1911 
1912  if ( *opt_arg == '#' )
1913  rgb = opt_arg + 1;
1914  else
1915  rgb = opt_arg;
1916 
1917  strncpy( opttmp, rgb, OPTMAX - 1 );
1918  opttmp[OPTMAX - 1] = '\0';
1919 
1920  if ( strchr( opttmp, '_' ) )
1921  {
1922  // e.g., -bg ff0000_0.1
1923  color_field = strtok( opttmp, "_" );
1924  alpha_field = strtok( NULL, "_" );
1925  }
1926  else
1927  {
1928  color_field = opttmp;
1929  alpha_field = NULL;
1930  }
1931 
1932  bgcolor = strtol( color_field, NULL, 16 );
1933 
1934 // Must be either a 3 or 6 digit hex number
1935 // If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC).
1936 
1937  switch ( strlen( color_field ) )
1938  {
1939  case 3:
1940  r = (PLINT) ( ( bgcolor & 0xF00 ) >> 8 );
1941  g = (PLINT) ( ( bgcolor & 0x0F0 ) >> 4 );
1942  b = (PLINT) ( bgcolor & 0x00F );
1943 
1944  r = r | ( r << 4 );
1945  g = g | ( g << 4 ); // doubling
1946  b = b | ( b << 4 );
1947  break;
1948 
1949  case 6:
1950  r = (PLINT) ( ( bgcolor & 0xFF0000 ) >> 16 );
1951  g = (PLINT) ( ( bgcolor & 0x00FF00 ) >> 8 );
1952  b = (PLINT) ( bgcolor & 0x0000FF );
1953  break;
1954 
1955  default:
1956  fprintf( stderr, "Unrecognized background color value %s\n", color_field );
1957  return 1;
1958  }
1959 
1960  if ( alpha_field )
1961  a = atof( alpha_field );
1962  else
1963  a = 1.;
1964 
1965  plscolbga( r, g, b, a );
1966 
1967  return 0;
1968 }
1969 
1970 //--------------------------------------------------------------------------
1971 // opt_ncol0()
1972 //
1982 //--------------------------------------------------------------------------
1983 
1984 static int
1985 opt_ncol0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
1986 {
1987  plsc->ncol0 = atoi( opt_arg );
1988  return 0;
1989 }
1990 
1991 //--------------------------------------------------------------------------
1992 // opt_ncol1()
1993 //
2003 //--------------------------------------------------------------------------
2004 
2005 static int
2006 opt_ncol1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2007 {
2008  plsc->ncol1 = atoi( opt_arg );
2009  return 0;
2010 }
2011 
2012 //--------------------------------------------------------------------------
2013 // opt_wplt()
2014 //
2024 //--------------------------------------------------------------------------
2025 
2026 static int
2027 opt_wplt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2028 {
2029  char *field;
2030  PLFLT xl, yl, xr, yr;
2031 
2032  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2033  opttmp[OPTMAX - 1] = '\0';
2034 
2035  if ( ( field = strtok( opttmp, "," ) ) == NULL )
2036  return 1;
2037 
2038  xl = atof( field );
2039 
2040  if ( ( field = strtok( NULL, "," ) ) == NULL )
2041  return 1;
2042 
2043  yl = atof( field );
2044 
2045  if ( ( field = strtok( NULL, "," ) ) == NULL )
2046  return 1;
2047 
2048  xr = atof( field );
2049 
2050  if ( ( field = strtok( NULL, "," ) ) == NULL )
2051  return 1;
2052 
2053  yr = atof( field );
2054 
2055  plsdiplt( xl, yl, xr, yr );
2056  return 0;
2057 }
2058 
2059 //--------------------------------------------------------------------------
2060 // opt_drvopt()
2061 //
2071 //--------------------------------------------------------------------------
2072 
2073 static int
2074 opt_drvopt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2075 {
2076  char t, *tt, *option, *value;
2077  int fl = 0;
2078  DrvOptCmd *drvp;
2079 
2080  option = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2081  if ( option == NULL )
2082  plexit( "opt_drvopt: Out of memory!?" );
2083 
2084  value = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
2085  if ( value == NULL )
2086  plexit( "opt_drvopt: Out of memory!?" );
2087 
2088  drvp = &drv_opt;
2089  *option = *value = '\0';
2090  tt = option;
2091  while ( ( t = *opt_arg++ ) )
2092  {
2093  switch ( t )
2094  {
2095  case ',':
2096  if ( fl )
2097  fl = 0;
2098  else
2099  {
2100  value[0] = '1';
2101  value[1] = '\0';
2102  }
2103 
2104  *tt = '\0'; tt = option;
2105  drvp->option = plstrdup( option ); // it should not be release, because of familying
2106  drvp->value = plstrdup( value ); // don't release
2107  drvp->next = (DrvOptCmd *) malloc( sizeof ( DrvOptCmd ) ); // don't release
2108  if ( drvp->next == NULL )
2109  plexit( "opt_drvopt: Out of memory!?\n" );
2110 
2111  drvp = drvp->next;
2112  break;
2113 
2114  case '=':
2115  fl = 1;
2116  *tt = '\0'; tt = value;
2117  break;
2118 
2119  default:
2120  *tt++ = t;
2121  }
2122  }
2123 
2124  *tt = '\0';
2125  if ( !fl )
2126  {
2127  value[0] = '1';
2128  value[1] = '\0';
2129  }
2130 
2131  drvp->option = plstrdup( option ); // don't release
2132  drvp->value = plstrdup( value ); // don't release
2133  drvp->next = NULL;
2134 
2135 #ifdef DEBUG
2136  fprintf( stderr, "\nopt_drvopt: -drvopt parsed options:\n" );
2137  drvp = &drv_opt;
2138  do
2139  fprintf( stderr, "%s %s\n", drvp->option, drvp->value );
2140  while ( drvp = drvp->next );
2141  fprintf( stderr, "\n" );
2142 #endif
2143 
2144  free( option ); free( value );
2145 
2146  return 0;
2147 }
2148 
2149 //--------------------------------------------------------------------------
2150 // opt_fam()
2151 //
2161 //--------------------------------------------------------------------------
2162 
2163 static int
2164 opt_fam( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2165 {
2166  plsfam( 1, -1, -1 );
2167  return 0;
2168 }
2169 
2170 //--------------------------------------------------------------------------
2171 // opt_fsiz()
2172 //
2191 //--------------------------------------------------------------------------
2192 
2193 static int
2194 opt_fsiz( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2195 {
2196  PLINT bytemax;
2197  size_t len = strlen( opt_arg );
2198  char lastchar = opt_arg[len - 1];
2199  PLFLT multiplier = 1.0e6;
2200  char *spec = (char *) malloc( len + 1 );
2201 
2202  if ( spec == NULL )
2203  plexit( "opt_fsiz: Insufficient memory" );
2204 
2205 // Interpret optional suffix
2206 
2207  switch ( lastchar )
2208  {
2209  case 'k':
2210  case 'K':
2211  multiplier = 1.0e3; len--;
2212  break;
2213  case 'm':
2214  case 'M':
2215  multiplier = 1.0e6; len--;
2216  break;
2217  case 'g':
2218  case 'G':
2219  multiplier = 1.0e9; len--;
2220  break;
2221  }
2222  strncpy( spec, opt_arg, len );
2223  spec[len] = '\0';
2224 
2225  bytemax = (PLINT) ( multiplier * atof( spec ) );
2226  if ( bytemax <= 0 )
2227  {
2228  fprintf( stderr, "?invalid file size %d. 2.14G is the maximum.\n", bytemax );
2229  return 1;
2230  }
2231  plsfam( 1, -1, bytemax );
2232 
2233  free( spec );
2234  return 0;
2235 }
2236 
2237 //--------------------------------------------------------------------------
2238 // opt_fbeg()
2239 //
2249 //--------------------------------------------------------------------------
2250 
2251 static int
2252 opt_fbeg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2253 {
2254  plsc->member = atoi( opt_arg );
2255 
2256  return 0;
2257 }
2258 
2259 //--------------------------------------------------------------------------
2260 // opt_finc()
2261 //
2271 //--------------------------------------------------------------------------
2272 
2273 static int
2274 opt_finc( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2275 {
2276  plsc->finc = atoi( opt_arg );
2277 
2278  return 0;
2279 }
2280 
2281 //--------------------------------------------------------------------------
2282 // opt_fflen()
2283 //
2293 //--------------------------------------------------------------------------
2294 
2295 static int
2296 opt_fflen( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2297 {
2298  plsc->fflen = atoi( opt_arg );
2299 
2300  return 0;
2301 }
2302 
2303 //--------------------------------------------------------------------------
2304 // opt_np()
2305 //
2315 //--------------------------------------------------------------------------
2316 
2317 static int
2318 opt_np( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2319 {
2320  plspause( 0 );
2321  return 0;
2322 }
2323 
2324 //--------------------------------------------------------------------------
2325 // opt_nopixmap()
2326 //
2336 //--------------------------------------------------------------------------
2337 
2338 static int
2339 opt_nopixmap( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2340 {
2341  plsc->nopixmap = 1;
2342  return 0;
2343 }
2344 
2345 //--------------------------------------------------------------------------
2346 // opt_db()
2347 //
2357 //--------------------------------------------------------------------------
2358 
2359 static int
2360 opt_db( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2361 {
2362  plsc->db = 1;
2363  return 0;
2364 }
2365 
2366 //--------------------------------------------------------------------------
2367 // opt_bufmax()
2368 //
2378 //--------------------------------------------------------------------------
2379 
2380 static int
2381 opt_bufmax( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2382 {
2383  plsc->bufmax = atoi( opt_arg );
2384  return 0;
2385 }
2386 
2387 //--------------------------------------------------------------------------
2388 // opt_server_name()
2389 //
2399 //--------------------------------------------------------------------------
2400 
2401 static int
2402 opt_server_name( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2403 {
2404  plsc->server_name = plstrdup( opt_arg );
2405  return 0;
2406 }
2407 
2408 //--------------------------------------------------------------------------
2409 // opt_plserver()
2410 //
2420 //--------------------------------------------------------------------------
2421 
2422 static int
2423 opt_plserver( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2424 {
2425  plsc->plserver = plstrdup( opt_arg );
2426  return 0;
2427 }
2428 
2429 //--------------------------------------------------------------------------
2430 // opt_plwindow()
2431 //
2441 //--------------------------------------------------------------------------
2442 
2443 static int
2444 opt_plwindow( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2445 {
2446  if ( ( plsc->plwindow = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2447  {
2448  plexit( "opt_plwindow: Insufficient memory" );
2449  }
2450  strcpy( plsc->plwindow, opt_arg );
2451  return 0;
2452 }
2453 
2454 //--------------------------------------------------------------------------
2455 // opt_auto_path()
2456 //
2466 //--------------------------------------------------------------------------
2467 
2468 static int
2469 opt_auto_path( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2470 {
2471  plsc->auto_path = plstrdup( opt_arg );
2472  return 0;
2473 }
2474 
2475 //--------------------------------------------------------------------------
2476 // opt_px()
2477 //
2487 //--------------------------------------------------------------------------
2488 
2489 static int
2490 opt_px( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2491 {
2492  plssub( atoi( opt_arg ), -1 );
2493  return 0;
2494 }
2495 
2496 //--------------------------------------------------------------------------
2497 // opt_py()
2498 //
2508 //--------------------------------------------------------------------------
2509 
2510 static int
2511 opt_py( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2512 {
2513  plssub( -1, atoi( opt_arg ) );
2514  return 0;
2515 }
2516 
2517 //--------------------------------------------------------------------------
2518 // opt_geo()
2519 //
2533 //--------------------------------------------------------------------------
2534 
2535 static int
2536 opt_geo( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2537 {
2538  int numargs;
2539  PLFLT xdpi = 0., ydpi = 0.;
2540  PLINT xwid, ywid, xoff, yoff;
2541 
2542 // The TK driver uses the geometry string directly
2543 
2544  if ( ( plsc->geometry = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2545  {
2546  plexit( "opt_geo: Insufficient memory" );
2547  }
2548 
2549  strcpy( plsc->geometry, opt_arg );
2550 
2551  numargs = sscanf( opt_arg, "%dx%d%d%d", &xwid, &ywid, &xoff, &yoff );
2552  if ( numargs == 2 )
2553  {
2554  xoff = 0;
2555  yoff = 0;
2556  if ( xwid == 0 )
2557  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2558  if ( ywid == 0 )
2559  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2560  if ( xwid < 0 )
2561  {
2562  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2563  return 1;
2564  }
2565  if ( ywid < 0 )
2566  {
2567  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2568  return 1;
2569  }
2570  }
2571  else if ( numargs == 4 )
2572  {
2573  if ( xwid == 0 )
2574  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2575  if ( ywid == 0 )
2576  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2577  if ( xwid < 0 )
2578  {
2579  fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
2580  return 1;
2581  }
2582  if ( ywid < 0 )
2583  {
2584  fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
2585  return 1;
2586  }
2587  if ( abs( xoff ) == 0 )
2588  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2589  if ( abs( yoff ) == 0 )
2590  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2591  }
2592  else
2593  {
2594  numargs = sscanf( opt_arg, "%d%d", &xoff, &yoff );
2595  if ( numargs == 2 )
2596  {
2597  xwid = 0;
2598  ywid = 0;
2599  if ( abs( xoff ) == 0 )
2600  fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
2601  if ( abs( yoff ) == 0 )
2602  fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
2603  }
2604  else
2605  {
2606  fprintf( stderr, "?invalid -geometry %s\n", opt_arg );
2607  return 1;
2608  }
2609  }
2610  //fprintf( stderr, "xwid, ywid, xoff, yoff = %d, %d, %d, %d\n", xwid, ywid, xoff, yoff );
2611  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2612  return 0;
2613 }
2614 
2615 //--------------------------------------------------------------------------
2616 // opt_tk_file()
2617 //
2626 //--------------------------------------------------------------------------
2627 
2628 static int
2629 opt_tk_file( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2630 {
2631  if ( ( plsc->tk_file = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
2632  {
2633  plexit( "opt_tk_file: Insufficient memory" );
2634  }
2635 
2636  strcpy( plsc->tk_file, opt_arg );
2637  return 0;
2638 }
2639 
2640 //--------------------------------------------------------------------------
2641 // opt_dpi()
2642 //
2656 //--------------------------------------------------------------------------
2657 
2658 static int
2659 opt_dpi( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2660 {
2661  char *field;
2662  PLFLT xdpi = 0., ydpi = 0.;
2663  PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0;
2664 
2665  strncpy( opttmp, opt_arg, OPTMAX - 1 );
2666  opttmp[OPTMAX - 1] = '\0';
2667  if ( strchr( opttmp, 'x' ) )
2668  {
2669  field = strtok( opttmp, "x" );
2670  xdpi = atof( field );
2671  if ( xdpi == 0 )
2672  fprintf( stderr, "?invalid xdpi\n" );
2673 
2674  if ( ( field = strtok( NULL, " " ) ) == NULL )
2675  return 1;
2676 
2677  ydpi = atof( field );
2678  if ( ydpi == 0 )
2679  fprintf( stderr, "?invalid ydpi\n" );
2680  }
2681  else
2682  {
2683  xdpi = atof( opttmp );
2684  ydpi = xdpi;
2685  if ( xdpi == 0 )
2686  return 1;
2687  }
2688 
2689  plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
2690  return 0;
2691 }
2692 
2693 //--------------------------------------------------------------------------
2694 // opt_dev_compression()
2695 //
2704 //--------------------------------------------------------------------------
2705 
2706 static int
2707 opt_dev_compression( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2708 {
2709  PLINT comp = 0;
2710 
2711  comp = atoi( opt_arg );
2712  if ( comp == 0 )
2713  {
2714  fprintf( stderr, "?invalid compression\n" );
2715  return 1;
2716  }
2717  plscompression( comp );
2718 
2719  return 0;
2720 }
2721 
2722 //--------------------------------------------------------------------------
2723 // opt_cmap0()
2724 //
2733 //--------------------------------------------------------------------------
2734 
2735 static int
2736 opt_cmap0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2737 {
2738  plspal0( opt_arg );
2739  return 0;
2740 }
2741 
2742 //--------------------------------------------------------------------------
2743 // opt_cmap1()
2744 //
2753 //--------------------------------------------------------------------------
2754 
2755 static int
2756 opt_cmap1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
2757 {
2758  plspal1( opt_arg, TRUE );
2759  return 0;
2760 }
2761 
2762 //--------------------------------------------------------------------------
2763 // opt_locale()
2764 //
2773 //--------------------------------------------------------------------------
2774 
2775 static int
2776 opt_locale( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2777 {
2778  char *locale;
2779  if ( ( locale = setlocale( LC_NUMERIC, "" ) ) )
2780  {
2781  printf( "LC_NUMERIC locale set to \"%s\"\n", locale );
2782  }
2783  else
2784  {
2785  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" );
2786  if ( !( locale = setlocale( LC_NUMERIC, "C" ) ) )
2787  {
2788  plexit( "Your platform is seriously broken. Not even a \"C\" locale could be set." );
2789  }
2790  }
2791  return 0;
2792 }
2793 
2794 //--------------------------------------------------------------------------
2795 // opt_eofill()
2796 //
2807 //--------------------------------------------------------------------------
2808 
2809 static int
2810 opt_eofill( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
2811 {
2812  plsc->dev_eofill = 1;
2813  return 0;
2814 }