PLplot  5.10.0
plargs.c
Go to the documentation of this file.
00001 //  Maurice LeBrun                      mjl@dino.ph.utexas.edu
00002 //  Institute for Fusion Studies        University of Texas at Austin
00003 //
00004 //  Copyright (C) 1993-2004  Maurice LeBrun
00005 //  Copyright (C) 2004  Andrew Ross
00006 //
00007 //  This file is part of PLplot.
00008 //
00009 //  PLplot is free software; you can redistribute it and/or modify
00010 //  it under the terms of the GNU Library General Public License as published
00011 //  by the Free Software Foundation; either version 2 of the License, or
00012 //  (at your option) any later version.
00013 //
00014 //  PLplot is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU Library General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Library General Public License
00020 //  along with PLplot; if not, write to the Free Software
00021 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00022 //
00023 //  Some parts of this code were derived from "xterm.c" and "ParseCmd.c" of
00024 //  the X-windows Version 11 distribution.  The copyright notice is
00025 //  reproduced here:
00026 //
00027 // Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
00028 // and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
00029 //
00030 //                      All Rights Reserved
00031 //
00032 //  The full permission notice is given in the PLplot documentation.
00033 //
00034 //--------------------------------------------------------------------------
00035 //
00096 
00097 #include "plplotP.h"
00098 #include <ctype.h>
00099 
00100 #ifdef HAVE_CRT_EXTERNS_H
00101 //
00102 // This include file has the declaration for _NSGetArgc().  See below.
00103 //
00104 #include <crt_externs.h>
00105 #endif
00106 
00107 // Support functions
00108 
00109 static int  ParseOpt( int *, const char ***, int *, const char ***, PLOptionTable * );
00110 static int  ProcessOpt( const char *, PLOptionTable *, int *, const char ***, int * );
00111 static int  GetOptarg( const char **, int *, const char ***, int * );
00112 static void Help( void );
00113 static void Syntax( void );
00114 
00115 #ifndef PL_DEPRECATED
00116 int plSetOpt( const char * opt, const char *opt_arg );
00117 #endif
00118 
00119 // Option handlers
00120 
00121 static int opt_h( const char *, const char *, void * );
00122 static int opt_v( const char *, const char *, void * );
00123 static int opt_verbose( const char *, const char *, void * );
00124 static int opt_debug( const char *, const char *, void * );
00125 static int opt_hack( const char *, const char *, void * );
00126 static int opt_dev( const char *, const char *, void * );
00127 static int opt_o( const char *, const char *, void * );
00128 static int opt_geo( const char *, const char *, void * );
00129 static int opt_a( const char *, const char *, void * );
00130 static int opt_jx( const char *, const char *, void * );
00131 static int opt_jy( const char *, const char *, void * );
00132 static int opt_mar( const char *, const char *, void * );
00133 static int opt_ori( const char *, const char *, void * );
00134 static int opt_freeaspect( const char *, const char *, void * );
00135 static int opt_portrait( const char *, const char *, void * );
00136 static int opt_width( const char *, const char *, void * );
00137 static int opt_bg( const char *, const char *, void * );
00138 static int opt_ncol0( const char *, const char *, void * );
00139 static int opt_ncol1( const char *, const char *, void * );
00140 static int opt_fam( const char *, const char *, void * );
00141 static int opt_fsiz( const char *, const char *, void * );
00142 static int opt_fbeg( const char *, const char *, void * );
00143 static int opt_finc( const char *, const char *, void * );
00144 static int opt_fflen( const char *, const char *, void * );
00145 static int opt_bufmax( const char *, const char *, void * );
00146 static int opt_nopixmap( const char *, const char *, void * );
00147 static int opt_db( const char *, const char *, void * );
00148 static int opt_np( const char *, const char *, void * );
00149 static int opt_px( const char *, const char *, void * );
00150 static int opt_py( const char *, const char *, void * );
00151 static int opt_wplt( const char *, const char *, void * );
00152 static int opt_drvopt( const char *, const char *, void * );
00153 
00154 static int opt_plserver( const char *, const char *, void * );
00155 static int opt_plwindow( const char *, const char *, void * );
00156 static int opt_auto_path( const char *, const char *, void * );
00157 static int opt_bufmax( const char *, const char *, void * );
00158 static int opt_server_name( const char *, const char *, void * );
00159 static int opt_tk_file( const char *, const char *, void * );
00160 static int opt_dpi( const char *, const char *, void * );
00161 static int opt_dev_compression( const char *, const char *, void * );
00162 static int opt_cmap0( const char *, const char *, void * );
00163 static int opt_cmap1( const char *, const char *, void * );
00164 static int opt_locale( const char *, const char *, void * );
00165 static int opt_eofill( const char *, const char *, void * );
00166 
00167 // Global variables
00168 
00169 static const char *program = NULL;
00170 static const char *usage   = NULL;
00171 
00172 static int        mode_full;
00173 static int        mode_quiet;
00174 static int        mode_nodelete;
00175 static int        mode_showall;
00176 static int        mode_noprogram;
00177 static int        mode_nodash;
00178 static int        mode_skip;
00179 
00180 // Temporary buffer used for parsing
00181 
00182 #define OPTMAX    1024
00183 static char opttmp[OPTMAX];
00184 
00185 //--------------------------------------------------------------------------
00235 //--------------------------------------------------------------------------
00236 
00237 static PLOptionTable ploption_table[] = {
00238     {
00239         "showall",              // Turns on invisible options
00240         NULL,
00241         NULL,
00242         &mode_showall,
00243         PL_OPT_BOOL | PL_OPT_INVISIBLE,
00244         "-showall",
00245         "Turns on invisible options"
00246     },
00247     {
00248         "h",                    // Help
00249         opt_h,
00250         NULL,
00251         NULL,
00252         PL_OPT_FUNC,
00253         "-h",
00254         "Print out this message"
00255     },
00256     {
00257         "v",                    // Version
00258         opt_v,
00259         NULL,
00260         NULL,
00261         PL_OPT_FUNC,
00262         "-v",
00263         "Print out the PLplot library version number"
00264     },
00265     {
00266         "verbose",              // Be more verbose than usual
00267         opt_verbose,
00268         NULL,
00269         NULL,
00270         PL_OPT_FUNC,
00271         "-verbose",
00272         "Be more verbose than usual"
00273     },
00274     {
00275         "debug",                // Print debugging info
00276         opt_debug,
00277         NULL,
00278         NULL,
00279         PL_OPT_FUNC,
00280         "-debug",
00281         "Print debugging info (implies -verbose)"
00282     },
00283     {
00284         "hack",                 // Enable driver-specific hack(s)
00285         opt_hack,
00286         NULL,
00287         NULL,
00288         PL_OPT_FUNC | PL_OPT_INVISIBLE,
00289         "-hack",
00290         "Enable driver-specific hack(s)"
00291     },
00292     {
00293         "dev",                  // Output device
00294         opt_dev,
00295         NULL,
00296         NULL,
00297         PL_OPT_FUNC | PL_OPT_ARG,
00298         "-dev name",
00299         "Output device name"
00300     },
00301     {
00302         "o",                    // Output filename
00303         opt_o,
00304         NULL,
00305         NULL,
00306         PL_OPT_FUNC | PL_OPT_ARG,
00307         "-o name",
00308         "Output filename"
00309     },
00310     {
00311         "display",              // X server
00312         opt_o,
00313         NULL,
00314         NULL,
00315         PL_OPT_FUNC | PL_OPT_ARG,
00316         "-display name",
00317         "X server to contact"
00318     },
00319     {
00320         "px",                   // Plots per page in x
00321         opt_px,
00322         NULL,
00323         NULL,
00324         PL_OPT_FUNC | PL_OPT_ARG,
00325         "-px number",
00326         "Plots per page in x"
00327     },
00328     {
00329         "py",                   // Plots per page in y
00330         opt_py,
00331         NULL,
00332         NULL,
00333         PL_OPT_FUNC | PL_OPT_ARG,
00334         "-py number",
00335         "Plots per page in y"
00336     },
00337     {
00338         "geometry",             // Geometry
00339         opt_geo,
00340         NULL,
00341         NULL,
00342         PL_OPT_FUNC | PL_OPT_ARG,
00343         "-geometry geom",
00344         "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc."
00345     },
00346     {
00347         "geo",                  // Geometry (alias)
00348         opt_geo,
00349         NULL,
00350         NULL,
00351         PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE,
00352         "-geo geom",
00353         "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc."
00354     },
00355     {
00356         "wplt",                 // Plot window
00357         opt_wplt,
00358         NULL,
00359         NULL,
00360         PL_OPT_FUNC | PL_OPT_ARG,
00361         "-wplt xl,yl,xr,yr",
00362         "Relative coordinates [0-1] of window into plot"
00363     },
00364     {
00365         "mar",                  // Margin
00366         opt_mar,
00367         NULL,
00368         NULL,
00369         PL_OPT_FUNC | PL_OPT_ARG,
00370         "-mar margin",
00371         "Margin space in relative coordinates (0 to 0.5, def 0)"
00372     },
00373     {
00374         "a",                    // Aspect ratio
00375         opt_a,
00376         NULL,
00377         NULL,
00378         PL_OPT_FUNC | PL_OPT_ARG,
00379         "-a aspect",
00380         "Page aspect ratio (def: same as output device)"
00381     },
00382     {
00383         "jx",                   // Justification in x
00384         opt_jx,
00385         NULL,
00386         NULL,
00387         PL_OPT_FUNC | PL_OPT_ARG,
00388         "-jx justx",
00389         "Page justification in x (-0.5 to 0.5, def 0)"
00390     },
00391     {
00392         "jy",                   // Justification in y
00393         opt_jy,
00394         NULL,
00395         NULL,
00396         PL_OPT_FUNC | PL_OPT_ARG,
00397         "-jy justy",
00398         "Page justification in y (-0.5 to 0.5, def 0)"
00399     },
00400     {
00401         "ori",                  // Orientation
00402         opt_ori,
00403         NULL,
00404         NULL,
00405         PL_OPT_FUNC | PL_OPT_ARG,
00406         "-ori orient",
00407         "Plot orientation (0,1,2,3=landscape,portrait,seascape,upside-down)"
00408     },
00409     {
00410         "freeaspect",           // floating aspect ratio
00411         opt_freeaspect,
00412         NULL,
00413         NULL,
00414         PL_OPT_FUNC,
00415         "-freeaspect",
00416         "Allow aspect ratio to adjust to orientation swaps"
00417     },
00418     {
00419         "portrait",             // floating aspect ratio
00420         opt_portrait,
00421         NULL,
00422         NULL,
00423         PL_OPT_FUNC,
00424         "-portrait",
00425         "Sets portrait mode (both orientation and aspect ratio)"
00426     },
00427     {
00428         "width",                // Pen width
00429         opt_width,
00430         NULL,
00431         NULL,
00432         PL_OPT_FUNC | PL_OPT_ARG,
00433         "-width width",
00434         "Sets pen width (0 <= width)"
00435     },
00436     {
00437         "bg",                   // Background color
00438         opt_bg,
00439         NULL,
00440         NULL,
00441         PL_OPT_FUNC | PL_OPT_ARG,
00442         "-bg color",
00443         "Background color (FF0000=opaque red, 0000FF_0.1=blue with alpha of 0.1)"
00444     },
00445     {
00446         "ncol0",                // Allocated colors in cmap 0
00447         opt_ncol0,
00448         NULL,
00449         NULL,
00450         PL_OPT_FUNC | PL_OPT_ARG,
00451         "-ncol0 n",
00452         "Number of colors to allocate in cmap 0 (upper bound)"
00453     },
00454     {
00455         "ncol1",                // Allocated colors in cmap 1
00456         opt_ncol1,
00457         NULL,
00458         NULL,
00459         PL_OPT_FUNC | PL_OPT_ARG,
00460         "-ncol1 n",
00461         "Number of colors to allocate in cmap 1 (upper bound)"
00462     },
00463     {
00464         "fam",                  // Familying on switch
00465         opt_fam,
00466         NULL,
00467         NULL,
00468         PL_OPT_FUNC,
00469         "-fam",
00470         "Create a family of output files"
00471     },
00472     {
00473         "fsiz",                 // Family file size
00474         opt_fsiz,
00475         NULL,
00476         NULL,
00477         PL_OPT_FUNC | PL_OPT_ARG,
00478         "-fsiz size[kKmMgG]",
00479         "Output family file size (e.g. -fsiz 0.5G, def MB)"
00480     },
00481     {
00482         "fbeg",                 // Family starting member
00483         opt_fbeg,
00484         NULL,
00485         NULL,
00486         PL_OPT_FUNC | PL_OPT_ARG,
00487         "-fbeg number",
00488         "First family member number on output"
00489     },
00490     {
00491         "finc",                 // Family member increment
00492         opt_finc,
00493         NULL,
00494         NULL,
00495         PL_OPT_FUNC | PL_OPT_ARG,
00496         "-finc number",
00497         "Increment between family members"
00498     },
00499     {
00500         "fflen",                // Family member min field width
00501         opt_fflen,
00502         NULL,
00503         NULL,
00504         PL_OPT_FUNC | PL_OPT_ARG,
00505         "-fflen length",
00506         "Family member number minimum field width"
00507     },
00508     {
00509         "nopixmap",             // Do not use pixmaps
00510         opt_nopixmap,
00511         NULL,
00512         NULL,
00513         PL_OPT_FUNC,
00514         "-nopixmap",
00515         "Don't use pixmaps in X-based drivers"
00516     },
00517     {
00518         "db",                   // Double buffering on switch
00519         opt_db,
00520         NULL,
00521         NULL,
00522         PL_OPT_FUNC,
00523         "-db",
00524         "Double buffer X window output"
00525     },
00526     {
00527         "np",                   // Page pause off switch
00528         opt_np,
00529         NULL,
00530         NULL,
00531         PL_OPT_FUNC,
00532         "-np",
00533         "No pause between pages"
00534     },
00535     {
00536         "bufmax",               // # bytes sent before flushing output
00537         opt_bufmax,
00538         NULL,
00539         NULL,
00540         PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE,
00541         "-bufmax",
00542         "bytes sent before flushing output"
00543     },
00544     {
00545         "server_name",          // Main window name of server
00546         opt_server_name,
00547         NULL,
00548         NULL,
00549         PL_OPT_FUNC | PL_OPT_ARG,
00550         "-server_name name",
00551         "Main window name of PLplot server (tk driver)"
00552     },
00553     {
00554         "plserver",             // PLplot server name
00555         opt_plserver,
00556         NULL,
00557         NULL,
00558         PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE,
00559         "-plserver name",
00560         "Invoked name of PLplot server (tk driver)"
00561     },
00562     {
00563         "plwindow",             // PLplot container window name
00564         opt_plwindow,
00565         NULL,
00566         NULL,
00567         PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE,
00568         "-plwindow name",
00569         "Name of PLplot container window (tk driver)"
00570     },
00571     {
00572         "auto_path",            // Additional directory(s) to autoload
00573         opt_auto_path,
00574         NULL,
00575         NULL,
00576         PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE,
00577         "-auto_path dir",
00578         "Additional directory(s) to autoload (tk driver)"
00579     },
00580     {
00581         "tk_file",  // -file option for plserver
00582         opt_tk_file,
00583         NULL,
00584         NULL,
00585         PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE,
00586         "-tk_file file",
00587         "file for plserver (tk driver)"
00588     },
00589     {
00590         "dpi",                  // Dots per inch
00591         opt_dpi,
00592         NULL,
00593         NULL,
00594         PL_OPT_FUNC | PL_OPT_ARG,
00595         "-dpi dpi",
00596         "Resolution, in dots per inch (e.g. -dpi 360x360)"
00597     },
00598     {
00599         "compression",                  // compression
00600         opt_dev_compression,
00601         NULL,
00602         NULL,
00603         PL_OPT_FUNC | PL_OPT_ARG,
00604         "-compression num",
00605         "Sets compression level in supporting devices"
00606     },
00607     {
00608         "cmap0",
00609         opt_cmap0,
00610         NULL,
00611         NULL,
00612         PL_OPT_ARG | PL_OPT_FUNC,
00613         "-cmap0 file name",
00614         "Initializes color table 0 from a cmap0.pal format file in one of standard PLplot paths."
00615     },
00616     {
00617         "cmap1",
00618         opt_cmap1,
00619         NULL,
00620         NULL,
00621         PL_OPT_ARG | PL_OPT_FUNC,
00622         "-cmap1 file name",
00623         "Initializes color table 1 from a cmap1.pal format file in one of standard PLplot paths."
00624     },
00625     {
00626         "locale",
00627         opt_locale,
00628         NULL,
00629         NULL,
00630         PL_OPT_FUNC,
00631         "-locale",
00632         "Use locale environment (e.g., LC_ALL, LC_NUMERIC, or LANG) to set LC_NUMERIC locale (which affects decimal point separator)."
00633     },
00634     {
00635         "eofill",
00636         opt_eofill,
00637         NULL,
00638         NULL,
00639         PL_OPT_FUNC,
00640         "-eofill",
00641         "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."
00642     },
00643     {
00644         "drvopt",               // Driver specific options
00645         opt_drvopt,
00646         NULL,
00647         NULL,
00648         PL_OPT_ARG | PL_OPT_FUNC,
00649         "-drvopt option[=value][,option[=value]]*",
00650         "Driver specific options"
00651     },
00652     {
00653         NULL,                   // option
00654         NULL,                   // handler
00655         NULL,                   // client data
00656         NULL,                   // address of variable to set
00657         0,                      // mode flag
00658         NULL,                   // short syntax
00659         NULL
00660     }                           // long syntax
00661 };
00662 
00663 static const char    *plplot_notes[] = {
00664     "All parameters must be white-space delimited.  Some options are driver",
00665     "dependent.  Please see the PLplot reference document for more detail.",
00666     NULL
00667 };
00668 
00669 //--------------------------------------------------------------------------
00683 //--------------------------------------------------------------------------
00684 
00685 typedef struct
00686 {
00687     PLOptionTable *options;
00688     const char    *name;
00689     const char    **notes;
00690 } PLOptionInfo;
00691 
00692 PLOptionInfo ploption_info_default = {
00693     ploption_table,
00694     "PLplot options",
00695     plplot_notes
00696 };
00697 
00698 #define PL_MAX_OPT_TABLES    10
00699 PLOptionInfo ploption_info[PL_MAX_OPT_TABLES] = {
00700     {
00701         ploption_table,
00702         "PLplot options",
00703         plplot_notes
00704     }
00705 };
00706 
00707 // The structure that hold the driver specific command line options
00708 
00709 typedef struct DrvOptCmd
00710 {
00711     char *option;
00712     char *value;
00713     struct DrvOptCmd *next;
00714 } DrvOptCmd;
00715 
00716 // the variable where opt_drvopt() stores the driver specific command line options
00717 static DrvOptCmd drv_opt = { NULL, NULL, NULL };
00718 
00719 static int       tables = 1;
00720 
00721 //--------------------------------------------------------------------------
00722 // plSetOpt()
00723 //
00732 //--------------------------------------------------------------------------
00733 
00734 int
00735 plSetOpt( const char * opt, const char *opt_arg )
00736 {
00737     return ( c_plsetopt( opt, opt_arg ) );
00738 }
00739 
00740 int
00741 c_plsetopt( const char * opt, const char *opt_arg )
00742 {
00743     int        mode = 0, argc = 2, status;
00744     const char *argv[3];
00745 
00746     argv[0] = opt;
00747     argv[1] = opt_arg;
00748     argv[2] = NULL;
00749     mode    =
00750         PL_PARSE_QUIET |
00751         PL_PARSE_NODELETE |
00752         PL_PARSE_NOPROGRAM |
00753         PL_PARSE_NODASH;
00754 
00755     status = plparseopts( &argc, argv, mode );
00756     if ( status )
00757     {
00758         fprintf( stderr, "plSetOpt: Unrecognized option %s\n", opt );
00759     }
00760     return status;
00761 }
00762 
00763 //--------------------------------------------------------------------------
00764 // plMergeOpts()
00765 //
00772 //--------------------------------------------------------------------------
00773 
00774 int
00775 plMergeOpts( PLOptionTable *options, const char *name, const char **notes )
00776 {
00777     PLOptionTable *tab;
00778 
00779     pllib_init();
00780 
00781 // Check to make sure option table has been terminated correctly
00782 
00783     for ( tab = (PLOptionTable *) options; tab->opt; tab++ )
00784         ;
00785 
00786 // We've reached the last table entry.  All the subentries must be NULL or 0
00787 
00788     if ( ( tab->handler != NULL ) ||
00789          ( tab->client_data != NULL ) ||
00790          ( tab->var != NULL ) ||
00791          ( tab->mode != 0 ) ||
00792          ( tab->syntax != NULL ) ||
00793          ( tab->desc != NULL ) )
00794     {
00795         plabort( "plMergeOpts: input table improperly terminated" );
00796         return 1;
00797     }
00798 
00799 // No room for more tables
00800 
00801     if ( tables++ >= PL_MAX_OPT_TABLES )
00802     {
00803         plabort( "plMergeOpts: max tables limit exceeded, table not merged" );
00804         return 1;
00805     }
00806 
00807     ploption_info[tables - 1].options = options;
00808     ploption_info[tables - 1].name    = name;
00809     ploption_info[tables - 1].notes   = notes;
00810 
00811     return 0;
00812 }
00813 
00814 //--------------------------------------------------------------------------
00815 // plClearOpts()
00816 //
00819 //--------------------------------------------------------------------------
00820 
00821 void
00822 plClearOpts( void )
00823 {
00824     tables = 0;
00825 }
00826 
00827 //--------------------------------------------------------------------------
00828 // plResetOpts()
00829 //
00832 //--------------------------------------------------------------------------
00833 
00834 void
00835 plResetOpts( void )
00836 {
00837     ploption_info[0] = ploption_info_default;
00838     tables           = 1;
00839 }
00840 
00841 //--------------------------------------------------------------------------
00842 // plparseopts()
00843 //
00854 //--------------------------------------------------------------------------
00855 
00856 int
00857 c_plparseopts( int *p_argc, const char **argv, PLINT mode )
00858 {
00859     const char **argsave, **argend;
00860     int        i, myargc, status = 0;
00861 
00862     pllib_init();
00863 
00864 // Initialize
00865 
00866     mode_full      = mode & PL_PARSE_FULL;
00867     mode_quiet     = mode & PL_PARSE_QUIET;
00868     mode_nodelete  = mode & PL_PARSE_NODELETE;
00869     mode_showall   = mode & PL_PARSE_SHOWALL;
00870     mode_noprogram = mode & PL_PARSE_NOPROGRAM;
00871     mode_nodash    = mode & PL_PARSE_NODASH;
00872     mode_skip      = mode & PL_PARSE_SKIP;
00873 
00874     myargc = ( *p_argc );
00875     argend = argv + myargc;
00876 
00877 // If program name is first argument, save and advance
00878 
00879     if ( !mode_noprogram )
00880     {
00881         plsc->program = plstrdup( argv[0] );
00882         program       = (const char *) plsc->program;
00883         --myargc; ++argv;
00884     }
00885     if ( myargc == 0 )
00886         return 0;
00887 
00888 // Process the command line
00889 
00890     argsave = argv;
00891     for (; myargc > 0; --myargc, ++argv )
00892     {
00893         // Allow for "holes" in argv list
00894 
00895         if ( *argv == NULL || *argv[0] == '\0' )
00896             continue;
00897 
00898         // Loop over all options tables, starting with the last
00899 
00900         for ( i = tables - 1; i >= 0; i-- )
00901         {
00902             // Check option table for option
00903 
00904             status = ParseOpt( &myargc, &argv, p_argc, &argsave,
00905                 ploption_info[i].options );
00906 
00907             if ( !status )
00908                 break;
00909         }
00910 
00911         // Handle error return as specified by the mode flag
00912 
00913         if ( status == -1 )
00914         {
00915             // No match.  Keep going if mode_skip is set, otherwise abort if
00916             // fully parsing, else return without error.
00917 
00918             status = 0;
00919 
00920             if ( mode_skip )
00921             {
00922                 if ( !mode_nodelete )
00923                     *argsave++ = *argv;
00924                 continue;
00925             }
00926             if ( !mode_quiet && mode_full )
00927             {
00928                 fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
00929                 plOptUsage();
00930             }
00931             if ( mode_full )
00932                 exit( 1 );
00933 
00934             break;
00935         }
00936         else if ( status == 1 )
00937         {
00938             // Illegal or badly formed
00939 
00940             if ( !mode_quiet )
00941             {
00942                 fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] );
00943                 plOptUsage();
00944             }
00945             if ( mode_full )
00946                 exit( 1 );
00947 
00948             break;
00949         }
00950         else if ( status == 2 )
00951         {
00952             // Informational option encountered (-h or -v)
00953 
00954             exit( 0 );
00955         }
00956     }
00957 
00958 // Compress and NULL-terminate argv
00959 
00960     if ( !mode_nodelete )
00961     {
00962         for ( i = 0; i < myargc; i++ )
00963             *argsave++ = *argv++;
00964 
00965         if ( argsave < argend )
00966         {
00967             *argsave = NULL;
00968 #ifdef HAVE_NSGETARGC
00969             //
00970             // Modify the global argc variable to match the shortened argv.
00971             // The global argc and argv must be kept consistent so that future
00972             // users of them (e.g. libraries loaded later with a device driver)
00973             // will not try to dereference the null pointer at the end of the
00974             // shortened argv array.
00975             //
00976             *_NSGetArgc() = *p_argc;
00977 #endif
00978         }
00979     }
00980 
00981     return status;
00982 }
00983 
00984 //--------------------------------------------------------------------------
00985 // ParseOpt()
00986 //
00997 //--------------------------------------------------------------------------
00998 
00999 static int
01000 ParseOpt( int *p_myargc, const char ***p_argv, int *p_argc, const char ***p_argsave,
01001           PLOptionTable *option_table )
01002 {
01003     PLOptionTable *tab;
01004     const char    *opt;
01005 
01006 // Only handle actual flags and their arguments
01007 
01008     if ( mode_nodash || ( *p_argv )[0][0] == '-' )
01009     {
01010         opt = ( *p_argv )[0];
01011         if ( *opt == '-' )
01012             opt++;
01013 
01014         for ( tab = option_table; tab->opt; tab++ )
01015         {
01016             // Skip if option not enabled
01017 
01018             if ( tab->mode & PL_OPT_DISABLED )
01019                 continue;
01020 
01021             // Try to match it
01022 
01023             if ( *opt == *tab->opt && !strcmp( opt, tab->opt ) )
01024             {
01025                 // Option matched, so remove from argv list if applicable.
01026 
01027                 if ( !mode_nodelete )
01028                 {
01029                     if ( tab->mode & PL_OPT_NODELETE )
01030                         ( *( *p_argsave )++ ) = ( **p_argv );
01031                     else
01032                         --( *p_argc );
01033                 }
01034 
01035                 // Process option (and argument if applicable)
01036 
01037                 return ( ProcessOpt( opt, tab, p_myargc, p_argv, p_argc ) );
01038             }
01039         }
01040     }
01041 
01042     return -1;
01043 }
01044 
01045 //--------------------------------------------------------------------------
01046 // ProcessOpt()
01047 //
01057 //--------------------------------------------------------------------------
01058 
01059 static int
01060 ProcessOpt( const char * opt, PLOptionTable *tab, int *p_myargc, const char ***p_argv,
01061             int *p_argc )
01062 {
01063     int        need_arg, res;
01064     const char *opt_arg = NULL;
01065 
01066 // Get option argument if necessary
01067 
01068     need_arg = PL_OPT_ARG | PL_OPT_INT | PL_OPT_FLOAT | PL_OPT_STRING;
01069 
01070     if ( tab->mode & need_arg )
01071     {
01072         if ( GetOptarg( &opt_arg, p_myargc, p_argv, p_argc ) )
01073             return 1;
01074     }
01075 
01076 // Process argument
01077 
01078     switch ( tab->mode & 0xFF00 )
01079     {
01080     case PL_OPT_FUNC:
01081 
01082         // Call function handler to do the job
01083 
01084         if ( tab->handler == NULL )
01085         {
01086             fprintf( stderr,
01087                 "ProcessOpt: no handler specified for option %s\n",
01088                 tab->opt );
01089             return 1;
01090         }
01091 
01092         if ( mode_nodelete && opt_arg )
01093         {
01094             // Make a copy, since handler may mung opt_arg with strtok()
01095             char *copy =
01096                 (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
01097             if ( copy == NULL )
01098             {
01099                 plabort( "ProcessOpt: out of memory" );
01100                 return 1;
01101             }
01102             strcpy( copy, opt_arg );
01103             res = ( ( *tab->handler )( opt, copy, tab->client_data ) );
01104             free( (void *) copy );
01105             return res;
01106         }
01107         else
01108         {
01109             return ( ( *tab->handler )( opt, opt_arg, tab->client_data ) );
01110         }
01111 
01112     case PL_OPT_BOOL:
01113 
01114         // Set *var as a boolean
01115 
01116         if ( tab->var == NULL )
01117         {
01118             fprintf( stderr,
01119                 "ProcessOpt: no variable specified for option %s\n",
01120                 tab->opt );
01121             return 1;
01122         }
01123         *(int *) tab->var = 1;
01124         break;
01125 
01126     case PL_OPT_INT:
01127 
01128         // Set *var as an int
01129 
01130         if ( tab->var == NULL )
01131         {
01132             fprintf( stderr,
01133                 "ProcessOpt: no variable specified for option %s\n",
01134                 tab->opt );
01135             return 1;
01136         }
01137         *(int *) tab->var = atoi( opt_arg );
01138         break;
01139 
01140     case PL_OPT_FLOAT:
01141 
01142         // Set *var as a float
01143 
01144         if ( tab->var == NULL )
01145         {
01146             fprintf( stderr,
01147                 "ProcessOpt: no variable specified for option %s\n",
01148                 tab->opt );
01149             return 1;
01150         }
01151         *(PLFLT *) tab->var = atof( opt_arg );
01152         break;
01153 
01154     case PL_OPT_STRING:
01155 
01156         // Set var (can be NULL initially) to point to opt_arg string
01157 
01158         *(const char **) tab->var = opt_arg;
01159         break;
01160 
01161     default:
01162 
01163         // Somebody messed up..
01164 
01165         fprintf( stderr,
01166             "ProcessOpt: invalid processing mode for option %s\n",
01167             tab->opt );
01168         return 1;
01169     }
01170     return 0;
01171 }
01172 
01173 //--------------------------------------------------------------------------
01174 // GetOptarg()
01175 //
01186 //--------------------------------------------------------------------------
01187 
01188 static int
01189 GetOptarg( const char **popt_arg, int *p_myargc, const char ***p_argv, int *p_argc )
01190 {
01191     int result = 0;
01192 
01193     --( *p_myargc );
01194 
01195     if ( ( *p_myargc ) <= 0 )           // oops, no more arguments
01196         result = 1;
01197 
01198     if ( !result )
01199     {
01200         ( *p_argv )++;
01201         if ( ( *p_argv )[0][0] == '-' && isalpha( ( *p_argv )[0][1] ) )
01202         {
01203             ( *p_argv )--;                // oops, next arg is a flag
01204             result = 1;
01205         }
01206     }
01207 
01208     if ( !result )                      // yeah, the user got it right
01209     {
01210         ( *p_argc )--;
01211         *popt_arg = ( *p_argv )[0];
01212     }
01213     else
01214     {
01215         if ( !mode_quiet )
01216         {
01217             fprintf( stderr, "Argument missing for %s option.\n", ( *p_argv )[0] );
01218             plOptUsage();
01219         }
01220     }
01221     return result;
01222 }
01223 
01224 //--------------------------------------------------------------------------
01225 // plSetUsage()
01226 //
01232 //--------------------------------------------------------------------------
01233 
01234 void
01235 plSetUsage( const char *program_string, const char *usage_string )
01236 {
01237     if ( program_string != NULL )
01238         program = program_string;
01239 
01240     if ( usage_string != NULL )
01241         usage = usage_string;
01242 }
01243 
01244 //--------------------------------------------------------------------------
01245 // plOptUsage()
01246 //
01249 //--------------------------------------------------------------------------
01250 
01251 void
01252 plOptUsage( void )
01253 {
01254     if ( usage == NULL )
01255         fprintf( stderr, "\nUsage:\n        %s [options]\n", program );
01256     else
01257         fputs( usage, stderr );
01258 
01259     Syntax();
01260 
01261     fprintf( stderr, "\n\nType %s -h for a full description.\n\n",
01262         program );
01263 }
01264 
01265 //--------------------------------------------------------------------------
01266 // Syntax()
01267 //
01270 //--------------------------------------------------------------------------
01271 
01272 static void
01273 Syntax( void )
01274 {
01275     PLOptionTable *tab;
01276     int           i, col, len;
01277 
01278 // Loop over all options tables
01279 
01280     for ( i = tables - 1; i >= 0; i-- )
01281     {
01282         // Introducer
01283 
01284         if ( ploption_info[i].name )
01285             fprintf( stderr, "\n%s:", ploption_info[i].name );
01286         else
01287             fputs( "\nUser options:", stderr );
01288 
01289         // Print syntax for each option
01290 
01291         col = 80;
01292         for ( tab = ploption_info[i].options; tab->opt; tab++ )
01293         {
01294             if ( tab->mode & PL_OPT_DISABLED )
01295                 continue;
01296 
01297             if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
01298                 continue;
01299 
01300             if ( tab->syntax == NULL )
01301                 continue;
01302 
01303             len = 3 + (int) strlen( tab->syntax );              // space [ string ]
01304             if ( col + len > 79 )
01305             {
01306                 fprintf( stderr, "\n   " );               // 3 spaces
01307                 col = 3;
01308             }
01309             fprintf( stderr, " [%s]", tab->syntax );
01310             col += len;
01311         }
01312         fprintf( stderr, "\n" );
01313     }
01314 }
01315 
01316 //--------------------------------------------------------------------------
01317 // Help()
01318 //
01321 //--------------------------------------------------------------------------
01322 
01323 static void
01324 Help( void )
01325 {
01326     PLOptionTable *tab;
01327     const char    **note;
01328     int           i;
01329     FILE          *outfile = stderr;
01330 
01331 #ifdef HAVE_POPEN
01332     FILE *pager = NULL;
01333     if ( getenv( "PAGER" ) != NULL )
01334         pager = (FILE *) popen( "$PAGER", "w" );
01335     if ( pager == NULL )
01336         pager = (FILE *) popen( "more", "w" );
01337     if ( pager != NULL )
01338         outfile = pager;
01339 #endif
01340 
01341 // Usage line
01342 
01343     if ( usage == NULL )
01344         fprintf( outfile, "\nUsage:\n        %s [options]\n", program );
01345     else
01346         fputs( usage, outfile );
01347 
01348 // Loop over all options tables
01349 
01350     for ( i = tables - 1; i >= 0; i-- )
01351     {
01352         // Introducer
01353 
01354         if ( ploption_info[i].name )
01355             fprintf( outfile, "\n%s:\n", ploption_info[i].name );
01356         else
01357             fputs( "\nUser options:\n", outfile );
01358 
01359         // Print description for each option
01360 
01361         for ( tab = ploption_info[i].options; tab->opt; tab++ )
01362         {
01363             if ( tab->mode & PL_OPT_DISABLED )
01364                 continue;
01365 
01366             if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) )
01367                 continue;
01368 
01369             if ( tab->desc == NULL )
01370                 continue;
01371 
01372             if ( tab->mode & PL_OPT_INVISIBLE )
01373                 fprintf( outfile, " *  %-20s %s\n", tab->syntax, tab->desc );
01374             else
01375                 fprintf( outfile, "    %-20s %s\n", tab->syntax, tab->desc );
01376         }
01377 
01378         // Usage notes
01379 
01380         if ( ploption_info[i].notes )
01381         {
01382             putc( '\n', outfile );
01383             for ( note = ploption_info[i].notes; *note; note++ )
01384             {
01385                 fputs( *note, outfile );
01386                 putc( '\n', outfile );
01387             }
01388         }
01389     }
01390 
01391 #ifdef HAVE_POPEN
01392     if ( pager != NULL )
01393         pclose( pager );
01394 #endif
01395 }
01396 
01397 //--------------------------------------------------------------------------
01398 // plParseDrvOpts
01399 //
01406 //--------------------------------------------------------------------------
01407 
01408 int
01409 plParseDrvOpts( DrvOpt *acc_opt )
01410 {
01411     DrvOptCmd *drvp;
01412     DrvOpt    *t;
01413     int       fl;
01414     char      msg[80];
01415     memset( msg, '\0', sizeof ( msg ) );
01416 
01417     if ( !drv_opt.option )
01418         return 1;
01419 
01420     drvp = &drv_opt;
01421     do
01422     {
01423         t = acc_opt; fl = 0;
01424         while ( t->opt )
01425         {
01426             if ( strcmp( drvp->option, t->opt ) == 0 )
01427             {
01428                 fl = 1;
01429                 switch ( t->type )
01430                 {
01431                 case DRV_STR:
01432                     *(char **) ( t->var_ptr ) = ( drvp->value );
01433 #ifdef DEBUG
01434                     fprintf( stderr, "plParseDrvOpts: %s %s\n", t->opt, *(char **) t->var_ptr );
01435 #endif
01436                     break;
01437 
01438                 case DRV_INT:
01439                     if ( sscanf( drvp->value, "%d", (int *) t->var_ptr ) != 1 )
01440                     {
01441                         snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
01442                         plexit( msg );
01443                     }
01444 #ifdef DEBUG
01445                     fprintf( stderr, "plParseDrvOpts: %s %d\n", t->opt, *(int *) t->var_ptr );
01446 #endif
01447                     break;
01448 
01449                 case DRV_FLT:
01450                     if ( sscanf( drvp->value, "%f", (float *) t->var_ptr ) != 1 )
01451                     {
01452                         snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option );
01453                         plexit( msg );
01454                     }
01455 #ifdef DEBUG
01456                     fprintf( stderr, "plParseDrvOpts: %s %f\n", t->opt, *(float *) t->var_ptr );
01457 #endif
01458                     break;
01459                 }
01460             }
01461             t++;
01462         }
01463 
01464         if ( !fl )
01465         {
01466             snprintf( msg, sizeof ( msg ) - 1, "Option '%s' not recognized.\n\nRecognized options for this driver are:\n", drvp->option );
01467             plwarn( msg );
01468             plHelpDrvOpts( acc_opt );
01469             plexit( "" );
01470         }
01471     }
01472     while ( ( drvp = drvp->next ) )
01473     ;
01474 
01475     return 0;
01476 }
01477 
01478 //--------------------------------------------------------------------------
01479 // plHelpDrvOpts
01480 //
01485 //--------------------------------------------------------------------------
01486 
01487 void
01488 plHelpDrvOpts( DrvOpt *acc_opt )
01489 {
01490     DrvOpt *t;
01491 
01492     t = acc_opt;
01493     while ( t->opt )
01494     {
01495         fprintf( stderr, "%s:\t%s\n", t->opt, t->hlp_msg );
01496         t++;
01497     }
01498 }
01499 
01500 //--------------------------------------------------------------------------
01501 // tidyDrvOpts
01502 //
01505 //--------------------------------------------------------------------------
01506 
01507 void
01508 plP_FreeDrvOpts()
01509 {
01510     DrvOptCmd *drvp, *drvpl;
01511 
01512     drvp = &drv_opt;
01513     do
01514     {
01515         drvpl = drvp;
01516         drvp  = drvpl->next;
01517 
01518         free( drvpl->option );
01519         free( drvpl->value );
01520         // Free additional DrvOptCmd variables -
01521         // first entry in list is a static global variable
01522         if ( drvpl != &drv_opt )
01523             free( drvpl );
01524     } while ( drvp != NULL );
01525 
01526     // initialize drv_opt if it's used again
01527     drv_opt.option = NULL;
01528     drv_opt.value  = NULL;
01529     drv_opt.next   = NULL;
01530 }
01531 
01532 
01533 //--------------------------------------------------------------------------
01534 // Option handlers
01535 //--------------------------------------------------------------------------
01536 
01537 //--------------------------------------------------------------------------
01538 // opt_h()
01539 //
01549 //--------------------------------------------------------------------------
01550 
01551 static int
01552 opt_h( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
01553 {
01554     if ( !mode_quiet )
01555         Help();
01556 
01557     return 2;
01558 }
01559 
01560 //--------------------------------------------------------------------------
01561 // opt_v()
01562 //
01572 //--------------------------------------------------------------------------
01573 
01574 static int
01575 opt_v( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
01576 {
01577     if ( !mode_quiet )
01578         fprintf( stderr, "PLplot library version: %s\n", PLPLOT_VERSION );
01579 
01580     return 2;
01581 }
01582 
01583 //--------------------------------------------------------------------------
01584 // opt_verbose()
01585 //
01595 //--------------------------------------------------------------------------
01596 
01597 static int
01598 opt_verbose( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
01599 {
01600     plsc->verbose = 1;
01601     return 0;
01602 }
01603 
01604 //--------------------------------------------------------------------------
01605 // opt_debug()
01606 //
01616 //--------------------------------------------------------------------------
01617 
01618 static int
01619 opt_debug( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
01620 {
01621     plsc->debug   = 1;
01622     plsc->verbose = 1;
01623     return 0;
01624 }
01625 
01626 //--------------------------------------------------------------------------
01627 // opt_hack()
01628 //
01638 //--------------------------------------------------------------------------
01639 
01640 static int
01641 opt_hack( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
01642 {
01643     plsc->hack = 1;
01644     return 0;
01645 }
01646 
01647 //--------------------------------------------------------------------------
01648 // opt_dev()
01649 //
01659 //--------------------------------------------------------------------------
01660 
01661 static int
01662 opt_dev( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01663 {
01664     plsdev( opt_arg );
01665     return 0;
01666 }
01667 
01668 //--------------------------------------------------------------------------
01669 // opt_o()
01670 //
01680 //--------------------------------------------------------------------------
01681 
01682 static int
01683 opt_o( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01684 {
01685     plsfnam( opt_arg );
01686     return 0;
01687 }
01688 
01689 //--------------------------------------------------------------------------
01690 // opt_mar()
01691 //
01701 //--------------------------------------------------------------------------
01702 
01703 static int
01704 opt_mar( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01705 {
01706     plsdidev( atof( opt_arg ), PL_NOTSET, PL_NOTSET, PL_NOTSET );
01707     return 0;
01708 }
01709 
01710 //--------------------------------------------------------------------------
01711 // opt_a()
01712 //
01722 //--------------------------------------------------------------------------
01723 
01724 static int
01725 opt_a( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01726 {
01727     plsdidev( PL_NOTSET, atof( opt_arg ), PL_NOTSET, PL_NOTSET );
01728     return 0;
01729 }
01730 
01731 //--------------------------------------------------------------------------
01732 // opt_jx()
01733 //
01743 //--------------------------------------------------------------------------
01744 
01745 static int
01746 opt_jx( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01747 {
01748     plsdidev( PL_NOTSET, PL_NOTSET, atof( opt_arg ), PL_NOTSET );
01749     return 0;
01750 }
01751 
01752 //--------------------------------------------------------------------------
01753 // opt_jy()
01754 //
01764 //--------------------------------------------------------------------------
01765 
01766 static int
01767 opt_jy( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01768 {
01769     plsdidev( PL_NOTSET, PL_NOTSET, PL_NOTSET, atof( opt_arg ) );
01770     return 0;
01771 }
01772 
01773 //--------------------------------------------------------------------------
01774 // opt_ori()
01775 //
01785 //--------------------------------------------------------------------------
01786 
01787 static int
01788 opt_ori( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01789 {
01790     plsdiori( atof( opt_arg ) );
01791     return 0;
01792 }
01793 
01794 //--------------------------------------------------------------------------
01795 // opt_freeaspect()
01796 //
01806 //--------------------------------------------------------------------------
01807 
01808 static int
01809 opt_freeaspect( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
01810 {
01811     plsc->freeaspect = 1;
01812     return 0;
01813 }
01814 
01815 //--------------------------------------------------------------------------
01816 // opt_portrait()
01817 //
01841 //--------------------------------------------------------------------------
01842 
01843 static int
01844 opt_portrait( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
01845 {
01846     plsc->portrait = 1;
01847     return 0;
01848 }
01849 
01850 //--------------------------------------------------------------------------
01851 // opt_width()
01852 //
01862 //--------------------------------------------------------------------------
01863 
01864 static int
01865 opt_width( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01866 {
01867     double width;
01868 
01869     width = atof( opt_arg );
01870     if ( width < 0. )
01871     {
01872         fprintf( stderr, "?invalid width\n" );
01873         return 1;
01874     }
01875     else
01876     {
01877         plwidth( width );
01878         plsc->widthlock = 1;
01879     }
01880     return 0;
01881 }
01882 
01883 //--------------------------------------------------------------------------
01884 // opt_bg()
01885 //
01899 //--------------------------------------------------------------------------
01900 
01901 static int
01902 opt_bg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01903 {
01904     const char *rgb;
01905     char       *color_field, *alpha_field;
01906     long       bgcolor;
01907     PLINT      r, g, b;
01908     PLFLT      a;
01909 
01910 // Strip off leading "#" (TK-ism) if present.
01911 
01912     if ( *opt_arg == '#' )
01913         rgb = opt_arg + 1;
01914     else
01915         rgb = opt_arg;
01916 
01917     strncpy( opttmp, rgb, OPTMAX - 1 );
01918     opttmp[OPTMAX - 1] = '\0';
01919 
01920     if ( strchr( opttmp, '_' ) )
01921     {
01922         // e.g., -bg ff0000_0.1
01923         color_field = strtok( opttmp, "_" );
01924         alpha_field = strtok( NULL, "_" );
01925     }
01926     else
01927     {
01928         color_field = opttmp;
01929         alpha_field = NULL;
01930     }
01931 
01932     bgcolor = strtol( color_field, NULL, 16 );
01933 
01934 // Must be either a 3 or 6 digit hex number
01935 // If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC).
01936 
01937     switch ( strlen( color_field ) )
01938     {
01939     case 3:
01940         r = (PLINT) ( ( bgcolor & 0xF00 ) >> 8 );
01941         g = (PLINT) ( ( bgcolor & 0x0F0 ) >> 4 );
01942         b = (PLINT) ( bgcolor & 0x00F );
01943 
01944         r = r | ( r << 4 );
01945         g = g | ( g << 4 );       // doubling
01946         b = b | ( b << 4 );
01947         break;
01948 
01949     case 6:
01950         r = (PLINT) ( ( bgcolor & 0xFF0000 ) >> 16 );
01951         g = (PLINT) ( ( bgcolor & 0x00FF00 ) >> 8 );
01952         b = (PLINT) ( bgcolor & 0x0000FF );
01953         break;
01954 
01955     default:
01956         fprintf( stderr, "Unrecognized background color value %s\n", color_field );
01957         return 1;
01958     }
01959 
01960     if ( alpha_field )
01961         a = atof( alpha_field );
01962     else
01963         a = 1.;
01964 
01965     plscolbga( r, g, b, a );
01966 
01967     return 0;
01968 }
01969 
01970 //--------------------------------------------------------------------------
01971 // opt_ncol0()
01972 //
01982 //--------------------------------------------------------------------------
01983 
01984 static int
01985 opt_ncol0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
01986 {
01987     plsc->ncol0 = atoi( opt_arg );
01988     return 0;
01989 }
01990 
01991 //--------------------------------------------------------------------------
01992 // opt_ncol1()
01993 //
02003 //--------------------------------------------------------------------------
02004 
02005 static int
02006 opt_ncol1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02007 {
02008     plsc->ncol1 = atoi( opt_arg );
02009     return 0;
02010 }
02011 
02012 //--------------------------------------------------------------------------
02013 // opt_wplt()
02014 //
02024 //--------------------------------------------------------------------------
02025 
02026 static int
02027 opt_wplt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02028 {
02029     char  *field;
02030     PLFLT xl, yl, xr, yr;
02031 
02032     strncpy( opttmp, opt_arg, OPTMAX - 1 );
02033     opttmp[OPTMAX - 1] = '\0';
02034 
02035     if ( ( field = strtok( opttmp, "," ) ) == NULL )
02036         return 1;
02037 
02038     xl = atof( field );
02039 
02040     if ( ( field = strtok( NULL, "," ) ) == NULL )
02041         return 1;
02042 
02043     yl = atof( field );
02044 
02045     if ( ( field = strtok( NULL, "," ) ) == NULL )
02046         return 1;
02047 
02048     xr = atof( field );
02049 
02050     if ( ( field = strtok( NULL, "," ) ) == NULL )
02051         return 1;
02052 
02053     yr = atof( field );
02054 
02055     plsdiplt( xl, yl, xr, yr );
02056     return 0;
02057 }
02058 
02059 //--------------------------------------------------------------------------
02060 // opt_drvopt()
02061 //
02071 //--------------------------------------------------------------------------
02072 
02073 static int
02074 opt_drvopt( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02075 {
02076     char      t, *tt, *option, *value;
02077     int       fl = 0;
02078     DrvOptCmd *drvp;
02079 
02080     option = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
02081     if ( option == NULL )
02082         plexit( "opt_drvopt: Out of memory!?" );
02083 
02084     value = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) );
02085     if ( value == NULL )
02086         plexit( "opt_drvopt: Out of memory!?" );
02087 
02088     drvp    = &drv_opt;
02089     *option = *value = '\0';
02090     tt      = option;
02091     while ( ( t = *opt_arg++ ) )
02092     {
02093         switch ( t )
02094         {
02095         case ',':
02096             if ( fl )
02097                 fl = 0;
02098             else
02099             {
02100                 value[0] = '1';
02101                 value[1] = '\0';
02102             }
02103 
02104             *tt          = '\0'; tt = option;
02105             drvp->option = plstrdup( option );                           // it should not be release, because of familying
02106             drvp->value  = plstrdup( value );                            // don't release
02107             drvp->next   = (DrvOptCmd *) malloc( sizeof ( DrvOptCmd ) ); // don't release
02108             if ( drvp->next == NULL )
02109                 plexit( "opt_drvopt: Out of memory!?\n" );
02110 
02111             drvp = drvp->next;
02112             break;
02113 
02114         case '=':
02115             fl  = 1;
02116             *tt = '\0'; tt = value;
02117             break;
02118 
02119         default:
02120             *tt++ = t;
02121         }
02122     }
02123 
02124     *tt = '\0';
02125     if ( !fl )
02126     {
02127         value[0] = '1';
02128         value[1] = '\0';
02129     }
02130 
02131     drvp->option = plstrdup( option ); // don't release
02132     drvp->value  = plstrdup( value );  // don't release
02133     drvp->next   = NULL;
02134 
02135 #ifdef DEBUG
02136     fprintf( stderr, "\nopt_drvopt: -drvopt parsed options:\n" );
02137     drvp = &drv_opt;
02138     do
02139         fprintf( stderr, "%s %s\n", drvp->option, drvp->value );
02140     while ( drvp = drvp->next );
02141     fprintf( stderr, "\n" );
02142 #endif
02143 
02144     free( option ); free( value );
02145 
02146     return 0;
02147 }
02148 
02149 //--------------------------------------------------------------------------
02150 // opt_fam()
02151 //
02161 //--------------------------------------------------------------------------
02162 
02163 static int
02164 opt_fam( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
02165 {
02166     plsfam( 1, -1, -1 );
02167     return 0;
02168 }
02169 
02170 //--------------------------------------------------------------------------
02171 // opt_fsiz()
02172 //
02191 //--------------------------------------------------------------------------
02192 
02193 static int
02194 opt_fsiz( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02195 {
02196     PLINT  bytemax;
02197     size_t len        = strlen( opt_arg );
02198     char   lastchar   = opt_arg[len - 1];
02199     PLFLT  multiplier = 1.0e6;
02200     char   *spec      = (char *) malloc( len + 1 );
02201 
02202     if ( spec == NULL )
02203         plexit( "opt_fsiz: Insufficient memory" );
02204 
02205 // Interpret optional suffix
02206 
02207     switch ( lastchar )
02208     {
02209     case 'k':
02210     case 'K':
02211         multiplier = 1.0e3; len--;
02212         break;
02213     case 'm':
02214     case 'M':
02215         multiplier = 1.0e6; len--;
02216         break;
02217     case 'g':
02218     case 'G':
02219         multiplier = 1.0e9; len--;
02220         break;
02221     }
02222     strncpy( spec, opt_arg, len );
02223     spec[len] = '\0';
02224 
02225     bytemax = (PLINT) ( multiplier * atof( spec ) );
02226     if ( bytemax <= 0 )
02227     {
02228         fprintf( stderr, "?invalid file size %d. 2.14G is the maximum.\n", bytemax );
02229         return 1;
02230     }
02231     plsfam( 1, -1, bytemax );
02232 
02233     free( spec );
02234     return 0;
02235 }
02236 
02237 //--------------------------------------------------------------------------
02238 // opt_fbeg()
02239 //
02249 //--------------------------------------------------------------------------
02250 
02251 static int
02252 opt_fbeg( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02253 {
02254     plsc->member = atoi( opt_arg );
02255 
02256     return 0;
02257 }
02258 
02259 //--------------------------------------------------------------------------
02260 // opt_finc()
02261 //
02271 //--------------------------------------------------------------------------
02272 
02273 static int
02274 opt_finc( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02275 {
02276     plsc->finc = atoi( opt_arg );
02277 
02278     return 0;
02279 }
02280 
02281 //--------------------------------------------------------------------------
02282 // opt_fflen()
02283 //
02293 //--------------------------------------------------------------------------
02294 
02295 static int
02296 opt_fflen( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02297 {
02298     plsc->fflen = atoi( opt_arg );
02299 
02300     return 0;
02301 }
02302 
02303 //--------------------------------------------------------------------------
02304 // opt_np()
02305 //
02315 //--------------------------------------------------------------------------
02316 
02317 static int
02318 opt_np( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
02319 {
02320     plspause( 0 );
02321     return 0;
02322 }
02323 
02324 //--------------------------------------------------------------------------
02325 // opt_nopixmap()
02326 //
02336 //--------------------------------------------------------------------------
02337 
02338 static int
02339 opt_nopixmap( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
02340 {
02341     plsc->nopixmap = 1;
02342     return 0;
02343 }
02344 
02345 //--------------------------------------------------------------------------
02346 // opt_db()
02347 //
02357 //--------------------------------------------------------------------------
02358 
02359 static int
02360 opt_db( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
02361 {
02362     plsc->db = 1;
02363     return 0;
02364 }
02365 
02366 //--------------------------------------------------------------------------
02367 // opt_bufmax()
02368 //
02378 //--------------------------------------------------------------------------
02379 
02380 static int
02381 opt_bufmax( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02382 {
02383     plsc->bufmax = atoi( opt_arg );
02384     return 0;
02385 }
02386 
02387 //--------------------------------------------------------------------------
02388 // opt_server_name()
02389 //
02399 //--------------------------------------------------------------------------
02400 
02401 static int
02402 opt_server_name( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02403 {
02404     plsc->server_name = plstrdup( opt_arg );
02405     return 0;
02406 }
02407 
02408 //--------------------------------------------------------------------------
02409 // opt_plserver()
02410 //
02420 //--------------------------------------------------------------------------
02421 
02422 static int
02423 opt_plserver( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02424 {
02425     plsc->plserver = plstrdup( opt_arg );
02426     return 0;
02427 }
02428 
02429 //--------------------------------------------------------------------------
02430 // opt_plwindow()
02431 //
02441 //--------------------------------------------------------------------------
02442 
02443 static int
02444 opt_plwindow( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02445 {
02446     if ( ( plsc->plwindow = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
02447     {
02448         plexit( "opt_plwindow: Insufficient memory" );
02449     }
02450     strcpy( plsc->plwindow, opt_arg );
02451     return 0;
02452 }
02453 
02454 //--------------------------------------------------------------------------
02455 // opt_auto_path()
02456 //
02466 //--------------------------------------------------------------------------
02467 
02468 static int
02469 opt_auto_path( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02470 {
02471     plsc->auto_path = plstrdup( opt_arg );
02472     return 0;
02473 }
02474 
02475 //--------------------------------------------------------------------------
02476 // opt_px()
02477 //
02487 //--------------------------------------------------------------------------
02488 
02489 static int
02490 opt_px( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02491 {
02492     plssub( atoi( opt_arg ), -1 );
02493     return 0;
02494 }
02495 
02496 //--------------------------------------------------------------------------
02497 // opt_py()
02498 //
02508 //--------------------------------------------------------------------------
02509 
02510 static int
02511 opt_py( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02512 {
02513     plssub( -1, atoi( opt_arg ) );
02514     return 0;
02515 }
02516 
02517 //--------------------------------------------------------------------------
02518 // opt_geo()
02519 //
02533 //--------------------------------------------------------------------------
02534 
02535 static int
02536 opt_geo( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02537 {
02538     int   numargs;
02539     PLFLT xdpi = 0., ydpi = 0.;
02540     PLINT xwid, ywid, xoff, yoff;
02541 
02542 // The TK driver uses the geometry string directly
02543 
02544     if ( ( plsc->geometry = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
02545     {
02546         plexit( "opt_geo: Insufficient memory" );
02547     }
02548 
02549     strcpy( plsc->geometry, opt_arg );
02550 
02551     numargs = sscanf( opt_arg, "%dx%d%d%d", &xwid, &ywid, &xoff, &yoff );
02552     if ( numargs == 2 )
02553     {
02554         xoff = 0;
02555         yoff = 0;
02556         if ( xwid == 0 )
02557             fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
02558         if ( ywid == 0 )
02559             fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
02560         if ( xwid < 0 )
02561         {
02562             fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
02563             return 1;
02564         }
02565         if ( ywid < 0 )
02566         {
02567             fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
02568             return 1;
02569         }
02570     }
02571     else if ( numargs == 4 )
02572     {
02573         if ( xwid == 0 )
02574             fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
02575         if ( ywid == 0 )
02576             fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
02577         if ( xwid < 0 )
02578         {
02579             fprintf( stderr, "?invalid xwid in -geometry %s\n", opt_arg );
02580             return 1;
02581         }
02582         if ( ywid < 0 )
02583         {
02584             fprintf( stderr, "?invalid ywid in -geometry %s\n", opt_arg );
02585             return 1;
02586         }
02587         if ( abs( xoff ) == 0 )
02588             fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
02589         if ( abs( yoff ) == 0 )
02590             fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
02591     }
02592     else
02593     {
02594         numargs = sscanf( opt_arg, "%d%d", &xoff, &yoff );
02595         if ( numargs == 2 )
02596         {
02597             xwid = 0;
02598             ywid = 0;
02599             if ( abs( xoff ) == 0 )
02600                 fprintf( stderr, "?invalid xoff in -geometry %s\n", opt_arg );
02601             if ( abs( yoff ) == 0 )
02602                 fprintf( stderr, "?invalid yoff in -geometry %s\n", opt_arg );
02603         }
02604         else
02605         {
02606             fprintf( stderr, "?invalid -geometry %s\n", opt_arg );
02607             return 1;
02608         }
02609     }
02610     //fprintf( stderr, "xwid, ywid, xoff, yoff = %d, %d, %d, %d\n", xwid, ywid, xoff, yoff );
02611     plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
02612     return 0;
02613 }
02614 
02615 //--------------------------------------------------------------------------
02616 // opt_tk_file()
02617 //
02626 //--------------------------------------------------------------------------
02627 
02628 static int
02629 opt_tk_file( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02630 {
02631     if ( ( plsc->tk_file = (char *) malloc( (size_t) ( 1 + strlen( opt_arg ) ) * sizeof ( char ) ) ) == NULL )
02632     {
02633         plexit( "opt_tk_file: Insufficient memory" );
02634     }
02635 
02636     strcpy( plsc->tk_file, opt_arg );
02637     return 0;
02638 }
02639 
02640 //--------------------------------------------------------------------------
02641 // opt_dpi()
02642 //
02656 //--------------------------------------------------------------------------
02657 
02658 static int
02659 opt_dpi( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02660 {
02661     char  *field;
02662     PLFLT xdpi = 0., ydpi = 0.;
02663     PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0;
02664 
02665     strncpy( opttmp, opt_arg, OPTMAX - 1 );
02666     opttmp[OPTMAX - 1] = '\0';
02667     if ( strchr( opttmp, 'x' ) )
02668     {
02669         field = strtok( opttmp, "x" );
02670         xdpi  = atof( field );
02671         if ( xdpi == 0 )
02672             fprintf( stderr, "?invalid xdpi\n" );
02673 
02674         if ( ( field = strtok( NULL, " " ) ) == NULL )
02675             return 1;
02676 
02677         ydpi = atof( field );
02678         if ( ydpi == 0 )
02679             fprintf( stderr, "?invalid ydpi\n" );
02680     }
02681     else
02682     {
02683         xdpi = atof( opttmp );
02684         ydpi = xdpi;
02685         if ( xdpi == 0 )
02686             return 1;
02687     }
02688 
02689     plspage( xdpi, ydpi, xwid, ywid, xoff, yoff );
02690     return 0;
02691 }
02692 
02693 //--------------------------------------------------------------------------
02694 // opt_dev_compression()
02695 //
02704 //--------------------------------------------------------------------------
02705 
02706 static int
02707 opt_dev_compression( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02708 {
02709     PLINT comp = 0;
02710 
02711     comp = atoi( opt_arg );
02712     if ( comp == 0 )
02713     {
02714         fprintf( stderr, "?invalid compression\n" );
02715         return 1;
02716     }
02717     plscompression( comp );
02718 
02719     return 0;
02720 }
02721 
02722 //--------------------------------------------------------------------------
02723 // opt_cmap0()
02724 //
02733 //--------------------------------------------------------------------------
02734 
02735 static int
02736 opt_cmap0( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02737 {
02738     plspal0( opt_arg );
02739     return 0;
02740 }
02741 
02742 //--------------------------------------------------------------------------
02743 // opt_cmap1()
02744 //
02753 //--------------------------------------------------------------------------
02754 
02755 static int
02756 opt_cmap1( const char * PL_UNUSED( opt ), const char *opt_arg, void * PL_UNUSED( client_data ) )
02757 {
02758     plspal1( opt_arg, TRUE );
02759     return 0;
02760 }
02761 
02762 //--------------------------------------------------------------------------
02763 // opt_locale()
02764 //
02773 //--------------------------------------------------------------------------
02774 
02775 static int
02776 opt_locale( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
02777 {
02778     char *locale;
02779     if ( ( locale = setlocale( LC_NUMERIC, "" ) ) )
02780     {
02781         printf( "LC_NUMERIC locale set to \"%s\"\n", locale );
02782     }
02783     else
02784     {
02785         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" );
02786         if ( !( locale = setlocale( LC_NUMERIC, "C" ) ) )
02787         {
02788             plexit( "Your platform is seriously broken.  Not even a \"C\" locale could be set." );
02789         }
02790     }
02791     return 0;
02792 }
02793 
02794 //--------------------------------------------------------------------------
02795 // opt_eofill()
02796 //
02807 //--------------------------------------------------------------------------
02808 
02809 static int
02810 opt_eofill( const char * PL_UNUSED( opt ), const char * PL_UNUSED( opt_arg ), void * PL_UNUSED( client_data ) )
02811 {
02812     plsc->dev_eofill = 1;
02813     return 0;
02814 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines