PLplot
5.10.0
|
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 }