PLplot 5.9.6
|
00001 /* $Id$ 00002 * 00003 * Copyright 1993, 1994, 1995 00004 * Maurice LeBrun mjl@dino.ph.utexas.edu 00005 * Institute for Fusion Studies University of Texas at Austin 00006 * 00007 * Copyright (C) 2004 Maurice LeBrun 00008 * Copyright (C) 2004 Andrew Ross 00009 * 00010 * This file is part of PLplot. 00011 * 00012 * PLplot is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU Library General Public License as published 00014 * by the Free Software Foundation; either version 2 of the License, or 00015 * (at your option) any later version. 00016 * 00017 * PLplot is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU Library General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU Library General Public License 00023 * along with PLplot; if not, write to the Free Software 00024 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00025 * 00026 * Some parts of this code were derived from "xterm.c" and "ParseCmd.c" of 00027 * the X-windows Version 11 distribution. The copyright notice is 00028 * reproduced here: 00029 * 00030 * Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, 00031 * and the Massachusetts Institute of Technology, Cambridge, Massachusetts. 00032 * 00033 * All Rights Reserved 00034 * 00035 * The full permission notice is given in the PLplot documentation. 00036 * 00037 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00038 * 00039 * This file contains routines to extract & process command flags. The 00040 * command flags recognized by PLplot are stored in the "ploption_table" 00041 * structure, along with strings giving the syntax, long help message, and 00042 * option handler. 00043 * 00044 * The command line parser -- plparseopts() -- removes all recognized flags 00045 * (decreasing argc accordingly), so that invalid input may be readily 00046 * detected. It can also be used to process user command line flags. The 00047 * user can merge an option table of type PLOptionTable into the internal 00048 * option table info structure using plMergeOpts(). Or, the user can 00049 * specify that ONLY the external table(s) be parsed by calling 00050 * plClearOpts() before plMergeOpts(). 00051 * 00052 * The default action taken by plparseopts() is as follows: 00053 * - Returns with an error if an unrecognized option or badly formed 00054 * option-value pair are encountered. 00055 * - Returns immediately (return code 0) when the first non-option 00056 * command line argument is found. 00057 * - Returns with the return code of the option handler, if one 00058 * was called. 00059 * - Deletes command line arguments from argv list as they are found, 00060 * and decrements argc accordingly. 00061 * - Does not show "invisible" options in usage or help messages. 00062 * - Assumes the program name is contained in argv[0]. 00063 * 00064 * These behaviors may be controlled through the "mode" argument, which can 00065 * have the following bits set: 00066 * 00067 * PL_PARSE_FULL -- Full parsing of command line and all error messages 00068 * enabled, including program exit when an error occurs. Anything on the 00069 * command line that isn't recognized as a valid option or option argument 00070 * is flagged as an error. 00071 * 00072 * PL_PARSE_QUIET -- Turns off all output except in the case of 00073 * errors. 00074 * 00075 * PL_PARSE_NODELETE -- Turns off deletion of processed arguments. 00076 * 00077 * PL_PARSE_SHOWALL -- Show invisible options 00078 * 00079 * PL_PARSE_NOPROGRAM -- Specified if argv[0] is NOT a pointer to the 00080 * program name. 00081 * 00082 * PL_PARSE_NODASH -- Set if leading dash is NOT required. 00083 * 00084 * PL_PARSE_SKIP -- Set to quietly skip over any unrecognized args. 00085 * 00086 * Note: if you want to have both your option and a PLplot option of the 00087 * same name processed (e.g. the -v option in plrender), do the following: 00088 * 1. Tag your option with PL_OPT_NODELETE 00089 * 2. Give it an option handler that uses a return code of 1. 00090 * 3. Merge your option table in. 00091 * By merging your table, your option will be processed before the PLplot 00092 * one. The PL_OPT_NODELETE ensures that the option string is not deleted 00093 * from the argv list, and the return code of 1 ensures that the parser 00094 * continues looking for it. 00095 * 00096 * See plrender.c for examples of actual usage. */ 00097 00098 #include "plplotP.h" 00099 #include <ctype.h> 00100 00101 #ifdef HAVE_CRT_EXTERNS_H 00102 /* 00103 * This include file has the declaration for _NSGetArgc(). See below. 00104 */ 00105 #include <crt_externs.h> 00106 #endif 00107 00108 /* Support functions */ 00109 00110 static int ParseOpt( int *, const char ***, int *, const char ***, PLOptionTable * ); 00111 static int ProcessOpt( const char *, PLOptionTable *, int *, const char ***, int * ); 00112 static int GetOptarg( const char **, int *, const char ***, int * ); 00113 static void Help( void ); 00114 static void Syntax( void ); 00115 00116 /* Option handlers */ 00117 00118 static int opt_h( const char *, const char *, void * ); 00119 static int opt_v( const char *, const char *, void * ); 00120 static int opt_verbose( const char *, const char *, void * ); 00121 static int opt_debug( const char *, const char *, void * ); 00122 static int opt_hack( const char *, const char *, void * ); 00123 static int opt_dev( const char *, const char *, void * ); 00124 static int opt_o( const char *, const char *, void * ); 00125 static int opt_geo( const char *, const char *, void * ); 00126 static int opt_a( const char *, const char *, void * ); 00127 static int opt_jx( const char *, const char *, void * ); 00128 static int opt_jy( const char *, const char *, void * ); 00129 static int opt_mar( const char *, const char *, void * ); 00130 static int opt_ori( const char *, const char *, void * ); 00131 static int opt_freeaspect( const char *, const char *, void * ); 00132 static int opt_portrait( const char *, const char *, void * ); 00133 static int opt_width( const char *, const char *, void * ); 00134 static int opt_bg( const char *, const char *, void * ); 00135 static int opt_ncol0( const char *, const char *, void * ); 00136 static int opt_ncol1( const char *, const char *, void * ); 00137 static int opt_fam( const char *, const char *, void * ); 00138 static int opt_fsiz( const char *, const char *, void * ); 00139 static int opt_fbeg( const char *, const char *, void * ); 00140 static int opt_finc( const char *, const char *, void * ); 00141 static int opt_fflen( const char *, const char *, void * ); 00142 static int opt_bufmax( const char *, const char *, void * ); 00143 static int opt_nopixmap( const char *, const char *, void * ); 00144 static int opt_db( const char *, const char *, void * ); 00145 static int opt_np( const char *, const char *, void * ); 00146 static int opt_px( const char *, const char *, void * ); 00147 static int opt_py( const char *, const char *, void * ); 00148 static int opt_wplt( const char *, const char *, void * ); 00149 static int opt_drvopt( const char *, const char *, void * ); 00150 00151 static int opt_plserver( const char *, const char *, void * ); 00152 static int opt_plwindow( const char *, const char *, void * ); 00153 static int opt_tcl_cmd( const char *, const char *, void * ); 00154 static int opt_auto_path( const char *, const char *, void * ); 00155 static int opt_bufmax( const char *, const char *, void * ); 00156 static int opt_server_name( const char *, const char *, void * ); 00157 static int opt_tk_file( const char *, const char *, void * ); 00158 static int opt_dpi( const char *, const char *, void * ); 00159 static int opt_dev_compression( const char *, const char *, void * ); 00160 static int opt_cmap0( const char *, const char *, void * ); 00161 static int opt_cmap1( const char *, const char *, void * ); 00162 static int opt_locale( const char *, const char *, void * ); 00163 00164 /* Global variables */ 00165 00166 static const char *program = NULL; 00167 static const char *usage = NULL; 00168 00169 static int mode_full; 00170 static int mode_quiet; 00171 static int mode_nodelete; 00172 static int mode_showall; 00173 static int mode_noprogram; 00174 static int mode_nodash; 00175 static int mode_skip; 00176 00177 /* Temporary buffer used for parsing */ 00178 00179 #define OPTMAX 1024 00180 static char opttmp[OPTMAX]; 00181 00182 /*--------------------------------------------------------------------------*\ 00183 * PLPLOT options data structure definition. 00184 * 00185 * The table is defined as follows 00186 * 00187 * typedef struct { 00188 * const char *opt; 00189 * int (*handler) (const char *, const char *, void *); 00190 * void *client_data; 00191 * void *var; 00192 * long mode; 00193 * const char *syntax; 00194 * const char *desc; 00195 * } PLOptionTable; 00196 * 00197 * where each entry has the following meaning: 00198 * 00199 * opt option string 00200 * handler pointer to function for processing the option and 00201 * (optionally) its argument 00202 * client_data pointer to data that gets passed to (*handler) 00203 * var address of variable to set based on "mode" 00204 * mode governs handling of option (see below) 00205 * syntax short syntax description 00206 * desc long syntax description 00207 * 00208 * The syntax and or desc strings can be NULL if the option is never to be 00209 * described. Usually this is only used for obsolete arguments; those we 00210 * just wish to hide from normal use are better made invisible (which are 00211 * made visible by either specifying -showall first or PL_PARSE_SHOWALL). 00212 * 00213 * The mode bits are: 00214 * 00215 * PL_OPT_ARG Option has an argment 00216 * PL_OPT_NODELETE Don't delete after processing 00217 * PL_OPT_INVISIBLE Make invisible (usually for debugging) 00218 * PL_OPT_DISABLED Ignore this option 00219 * 00220 * The following mode bits cause the option to be processed as specified: 00221 * 00222 * PL_OPT_FUNC Call function handler (opt, optarg) 00223 * PL_OPT_BOOL Set *var=1 00224 * PL_OPT_INT Set *var=atoi(optarg) 00225 * PL_OPT_FLOAT Set *var=atof(optarg) 00226 * PL_OPT_STRING Set *var=optarg 00227 * 00228 * where opt points to the option string and optarg points to the 00229 * argument string. 00230 * 00231 \*--------------------------------------------------------------------------*/ 00232 00233 static PLOptionTable ploption_table[] = { 00234 { 00235 "showall", /* Turns on invisible options */ 00236 NULL, 00237 NULL, 00238 &mode_showall, 00239 PL_OPT_BOOL | PL_OPT_INVISIBLE, 00240 "-showall", 00241 "Turns on invisible options" 00242 }, 00243 { 00244 "h", /* Help */ 00245 opt_h, 00246 NULL, 00247 NULL, 00248 PL_OPT_FUNC, 00249 "-h", 00250 "Print out this message" 00251 }, 00252 { 00253 "v", /* Version */ 00254 opt_v, 00255 NULL, 00256 NULL, 00257 PL_OPT_FUNC, 00258 "-v", 00259 "Print out the PLplot library version number" 00260 }, 00261 { 00262 "verbose", /* Be more verbose than usual */ 00263 opt_verbose, 00264 NULL, 00265 NULL, 00266 PL_OPT_FUNC, 00267 "-verbose", 00268 "Be more verbose than usual" 00269 }, 00270 { 00271 "debug", /* Print debugging info */ 00272 opt_debug, 00273 NULL, 00274 NULL, 00275 PL_OPT_FUNC, 00276 "-debug", 00277 "Print debugging info (implies -verbose)" 00278 }, 00279 { 00280 "hack", /* Enable driver-specific hack(s) */ 00281 opt_hack, 00282 NULL, 00283 NULL, 00284 PL_OPT_FUNC | PL_OPT_INVISIBLE, 00285 "-hack", 00286 "Enable driver-specific hack(s)" 00287 }, 00288 { 00289 "dev", /* Output device */ 00290 opt_dev, 00291 NULL, 00292 NULL, 00293 PL_OPT_FUNC | PL_OPT_ARG, 00294 "-dev name", 00295 "Output device name" 00296 }, 00297 { 00298 "o", /* Output filename */ 00299 opt_o, 00300 NULL, 00301 NULL, 00302 PL_OPT_FUNC | PL_OPT_ARG, 00303 "-o name", 00304 "Output filename" 00305 }, 00306 { 00307 "display", /* X server */ 00308 opt_o, 00309 NULL, 00310 NULL, 00311 PL_OPT_FUNC | PL_OPT_ARG, 00312 "-display name", 00313 "X server to contact" 00314 }, 00315 { 00316 "px", /* Plots per page in x */ 00317 opt_px, 00318 NULL, 00319 NULL, 00320 PL_OPT_FUNC | PL_OPT_ARG, 00321 "-px number", 00322 "Plots per page in x" 00323 }, 00324 { 00325 "py", /* Plots per page in y */ 00326 opt_py, 00327 NULL, 00328 NULL, 00329 PL_OPT_FUNC | PL_OPT_ARG, 00330 "-py number", 00331 "Plots per page in y" 00332 }, 00333 { 00334 "geometry", /* Geometry */ 00335 opt_geo, 00336 NULL, 00337 NULL, 00338 PL_OPT_FUNC | PL_OPT_ARG, 00339 "-geometry geom", 00340 "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc." 00341 }, 00342 { 00343 "geo", /* Geometry (alias) */ 00344 opt_geo, 00345 NULL, 00346 NULL, 00347 PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, 00348 "-geo geom", 00349 "Window size/position specified as in X, e.g., 400x300, 400x300-100+200, +100-200, etc." 00350 }, 00351 { 00352 "wplt", /* Plot window */ 00353 opt_wplt, 00354 NULL, 00355 NULL, 00356 PL_OPT_FUNC | PL_OPT_ARG, 00357 "-wplt xl,yl,xr,yr", 00358 "Relative coordinates [0-1] of window into plot" 00359 }, 00360 { 00361 "mar", /* Margin */ 00362 opt_mar, 00363 NULL, 00364 NULL, 00365 PL_OPT_FUNC | PL_OPT_ARG, 00366 "-mar margin", 00367 "Margin space in relative coordinates (0 to 0.5, def 0)" 00368 }, 00369 { 00370 "a", /* Aspect ratio */ 00371 opt_a, 00372 NULL, 00373 NULL, 00374 PL_OPT_FUNC | PL_OPT_ARG, 00375 "-a aspect", 00376 "Page aspect ratio (def: same as output device)" 00377 }, 00378 { 00379 "jx", /* Justification in x */ 00380 opt_jx, 00381 NULL, 00382 NULL, 00383 PL_OPT_FUNC | PL_OPT_ARG, 00384 "-jx justx", 00385 "Page justification in x (-0.5 to 0.5, def 0)" 00386 }, 00387 { 00388 "jy", /* Justification in y */ 00389 opt_jy, 00390 NULL, 00391 NULL, 00392 PL_OPT_FUNC | PL_OPT_ARG, 00393 "-jy justy", 00394 "Page justification in y (-0.5 to 0.5, def 0)" 00395 }, 00396 { 00397 "ori", /* Orientation */ 00398 opt_ori, 00399 NULL, 00400 NULL, 00401 PL_OPT_FUNC | PL_OPT_ARG, 00402 "-ori orient", 00403 "Plot orientation (0,1,2,3=landscape,portrait,seascape,upside-down)" 00404 }, 00405 { 00406 "freeaspect", /* floating aspect ratio */ 00407 opt_freeaspect, 00408 NULL, 00409 NULL, 00410 PL_OPT_FUNC, 00411 "-freeaspect", 00412 "Allow aspect ratio to adjust to orientation swaps" 00413 }, 00414 { 00415 "portrait", /* floating aspect ratio */ 00416 opt_portrait, 00417 NULL, 00418 NULL, 00419 PL_OPT_FUNC, 00420 "-portrait", 00421 "Sets portrait mode (both orientation and aspect ratio)" 00422 }, 00423 { 00424 "width", /* Pen width */ 00425 opt_width, 00426 NULL, 00427 NULL, 00428 PL_OPT_FUNC | PL_OPT_ARG, 00429 "-width width", 00430 "Sets pen width (0 <= width)" 00431 }, 00432 { 00433 "bg", /* Background color */ 00434 opt_bg, 00435 NULL, 00436 NULL, 00437 PL_OPT_FUNC | PL_OPT_ARG, 00438 "-bg color", 00439 "Background color (FF0000=opaque red, 0000FF_0.1=blue with alpha of 0.1)" 00440 }, 00441 { 00442 "ncol0", /* Allocated colors in cmap 0 */ 00443 opt_ncol0, 00444 NULL, 00445 NULL, 00446 PL_OPT_FUNC | PL_OPT_ARG, 00447 "-ncol0 n", 00448 "Number of colors to allocate in cmap 0 (upper bound)" 00449 }, 00450 { 00451 "ncol1", /* Allocated colors in cmap 1 */ 00452 opt_ncol1, 00453 NULL, 00454 NULL, 00455 PL_OPT_FUNC | PL_OPT_ARG, 00456 "-ncol1 n", 00457 "Number of colors to allocate in cmap 1 (upper bound)" 00458 }, 00459 { 00460 "fam", /* Familying on switch */ 00461 opt_fam, 00462 NULL, 00463 NULL, 00464 PL_OPT_FUNC, 00465 "-fam", 00466 "Create a family of output files" 00467 }, 00468 { 00469 "fsiz", /* Family file size */ 00470 opt_fsiz, 00471 NULL, 00472 NULL, 00473 PL_OPT_FUNC | PL_OPT_ARG, 00474 "-fsiz size[kKmMgG]", 00475 "Output family file size (e.g. -fsiz 0.5G, def MB)" 00476 }, 00477 { 00478 "fbeg", /* Family starting member */ 00479 opt_fbeg, 00480 NULL, 00481 NULL, 00482 PL_OPT_FUNC | PL_OPT_ARG, 00483 "-fbeg number", 00484 "First family member number on output" 00485 }, 00486 { 00487 "finc", /* Family member increment */ 00488 opt_finc, 00489 NULL, 00490 NULL, 00491 PL_OPT_FUNC | PL_OPT_ARG, 00492 "-finc number", 00493 "Increment between family members" 00494 }, 00495 { 00496 "fflen", /* Family member min field width */ 00497 opt_fflen, 00498 NULL, 00499 NULL, 00500 PL_OPT_FUNC | PL_OPT_ARG, 00501 "-fflen length", 00502 "Family member number minimum field width" 00503 }, 00504 { 00505 "nopixmap", /* Do not use pixmaps */ 00506 opt_nopixmap, 00507 NULL, 00508 NULL, 00509 PL_OPT_FUNC, 00510 "-nopixmap", 00511 "Don't use pixmaps in X-based drivers" 00512 }, 00513 { 00514 "db", /* Double buffering on switch */ 00515 opt_db, 00516 NULL, 00517 NULL, 00518 PL_OPT_FUNC, 00519 "-db", 00520 "Double buffer X window output" 00521 }, 00522 { 00523 "np", /* Page pause off switch */ 00524 opt_np, 00525 NULL, 00526 NULL, 00527 PL_OPT_FUNC, 00528 "-np", 00529 "No pause between pages" 00530 }, 00531 { 00532 "bufmax", /* # bytes sent before flushing output */ 00533 opt_bufmax, 00534 NULL, 00535 NULL, 00536 PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, 00537 "-bufmax", 00538 "bytes sent before flushing output" 00539 }, 00540 { 00541 "server_name", /* Main window name of server */ 00542 opt_server_name, 00543 NULL, 00544 NULL, 00545 PL_OPT_FUNC | PL_OPT_ARG, 00546 "-server_name name", 00547 "Main window name of PLplot server (tk driver)" 00548 }, 00549 { 00550 "plserver", /* PLplot server name */ 00551 opt_plserver, 00552 NULL, 00553 NULL, 00554 PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, 00555 "-plserver name", 00556 "Invoked name of PLplot server (tk driver)" 00557 }, 00558 { 00559 "plwindow", /* PLplot container window name */ 00560 opt_plwindow, 00561 NULL, 00562 NULL, 00563 PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, 00564 "-plwindow name", 00565 "Name of PLplot container window (tk driver)" 00566 }, 00567 { 00568 "tcl_cmd", /* TCL initialization command */ 00569 opt_tcl_cmd, 00570 NULL, 00571 NULL, 00572 PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, 00573 "-tcl_cmd command", 00574 "Depreciated - use -drvopt tcl_cmd= instead" 00575 }, 00576 { 00577 "auto_path", /* Additional directory(s) to autoload */ 00578 opt_auto_path, 00579 NULL, 00580 NULL, 00581 PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, 00582 "-auto_path dir", 00583 "Additional directory(s) to autoload (tk driver)" 00584 }, 00585 { 00586 "tk_file", /* -file option for plserver */ 00587 opt_tk_file, 00588 NULL, 00589 NULL, 00590 PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, 00591 "-tk_file file", 00592 "file for plserver (tk driver)" 00593 }, 00594 { 00595 "dpi", /* Dots per inch */ 00596 opt_dpi, 00597 NULL, 00598 NULL, 00599 PL_OPT_FUNC | PL_OPT_ARG, 00600 "-dpi dpi", 00601 "Resolution, in dots per inch (e.g. -dpi 360x360)" 00602 }, 00603 { 00604 "compression", /* compression */ 00605 opt_dev_compression, 00606 NULL, 00607 NULL, 00608 PL_OPT_FUNC | PL_OPT_ARG, 00609 "-compression num", 00610 "Sets compression level in supporting devices" 00611 }, 00612 { 00613 "cmap0", 00614 opt_cmap0, 00615 NULL, 00616 NULL, 00617 PL_OPT_ARG | PL_OPT_FUNC, 00618 "-cmap0 file name", 00619 "Initializes color table 0 from a cmap0.pal format file in one of standard PLplot paths." 00620 }, 00621 { 00622 "cmap1", 00623 opt_cmap1, 00624 NULL, 00625 NULL, 00626 PL_OPT_ARG | PL_OPT_FUNC, 00627 "-cmap1 file name", 00628 "Initializes color table 1 from a cmap1.pal format file in one of standard PLplot paths." 00629 }, 00630 { 00631 "locale", 00632 opt_locale, 00633 NULL, 00634 NULL, 00635 PL_OPT_FUNC, 00636 "-locale", 00637 "Use locale environment (e.g., LC_ALL, LC_NUMERIC, or LANG) to set LC_NUMERIC locale (which affects decimal point separator)." 00638 }, 00639 { 00640 "drvopt", /* Driver specific options */ 00641 opt_drvopt, 00642 NULL, 00643 NULL, 00644 PL_OPT_ARG | PL_OPT_FUNC, 00645 "-drvopt option[=value][,option[=value]]*", 00646 "Driver specific options" 00647 }, 00648 { 00649 NULL, /* option */ 00650 NULL, /* handler */ 00651 NULL, /* client data */ 00652 NULL, /* address of variable to set */ 00653 0, /* mode flag */ 00654 NULL, /* short syntax */ 00655 NULL 00656 } /* long syntax */ 00657 }; 00658 00659 static const char *plplot_notes[] = { 00660 "All parameters must be white-space delimited. Some options are driver", 00661 "dependent. Please see the PLplot reference document for more detail.", 00662 NULL 00663 }; 00664 00665 /*--------------------------------------------------------------------------*\ 00666 * Array of option tables and associated info. 00667 * 00668 * The user may merge up to PL_MAX_OPT_TABLES custom option tables (of type 00669 * PLOptionTable) with the internal one. The resulting treatment is simple, 00670 * powerful, and robust. The tables are parsed in the order of last added 00671 * first, to the internal table last. If multiple options of the same name 00672 * occur, only the first parsed is "seen", thus, the user can easily 00673 * override any PLplot internal option merely by providing the same option. 00674 * This same precedence is followed when printing help and usage messages, 00675 * with each set of options given separately. See example usage in 00676 * plrender.c. 00677 \*--------------------------------------------------------------------------*/ 00678 00679 typedef struct 00680 { 00681 PLOptionTable *options; 00682 const char *name; 00683 const char **notes; 00684 } PLOptionInfo; 00685 00686 PLOptionInfo ploption_info_default = { 00687 ploption_table, 00688 "PLplot options", 00689 plplot_notes 00690 }; 00691 00692 #define PL_MAX_OPT_TABLES 10 00693 PLOptionInfo ploption_info[PL_MAX_OPT_TABLES] = { 00694 { 00695 ploption_table, 00696 "PLplot options", 00697 plplot_notes 00698 } 00699 }; 00700 00701 /* The structure that hold the driver specific command line options */ 00702 00703 typedef struct DrvOptCmd 00704 { 00705 char *option; 00706 char *value; 00707 struct DrvOptCmd *next; 00708 } DrvOptCmd; 00709 00710 /* the variable where opt_drvopt() stores the driver specific command line options */ 00711 static DrvOptCmd drv_opt = { NULL, NULL, NULL }; 00712 00713 static int tables = 1; 00714 00715 /*--------------------------------------------------------------------------*\ 00716 * plSetOpt() 00717 * 00718 * Process input strings, treating them as an option and argument pair. 00719 * Returns 1 on an error. 00720 \*--------------------------------------------------------------------------*/ 00721 00722 int 00723 c_plsetopt( const char *opt, const char *optarg ) 00724 { 00725 return ( plSetOpt( opt, optarg ) ); 00726 } 00727 00728 int 00729 plSetOpt( const char *opt, const char *optarg ) 00730 { 00731 int mode = 0, argc = 2, status; 00732 const char *argv[3]; 00733 00734 argv[0] = opt; 00735 argv[1] = optarg; 00736 argv[2] = NULL; 00737 mode = 00738 PL_PARSE_QUIET | 00739 PL_PARSE_NODELETE | 00740 PL_PARSE_NOPROGRAM | 00741 PL_PARSE_NODASH; 00742 00743 status = plparseopts( &argc, argv, mode ); 00744 if ( status ) 00745 { 00746 fprintf( stderr, "plSetOpt: Unrecognized option %s\n", opt ); 00747 } 00748 return status; 00749 } 00750 00751 /*--------------------------------------------------------------------------*\ 00752 * plMergeOpts() 00753 * 00754 * Merge user option table info structure with internal one. 00755 \*--------------------------------------------------------------------------*/ 00756 00757 int 00758 plMergeOpts( PLOptionTable *options, const char *name, const char **notes ) 00759 { 00760 PLOptionTable *tab; 00761 00762 pllib_init(); 00763 00764 /* Check to make sure option table has been terminated correctly */ 00765 00766 for ( tab = (PLOptionTable *) options; tab->opt; tab++ ) 00767 ; 00768 00769 /* We've reached the last table entry. All the subentries must be NULL or 0 */ 00770 00771 if ( ( tab->handler != NULL ) || 00772 ( tab->client_data != NULL ) || 00773 ( tab->var != NULL ) || 00774 ( tab->mode != 0 ) || 00775 ( tab->syntax != NULL ) || 00776 ( tab->desc != NULL ) ) 00777 { 00778 plabort( "plMergeOpts: input table improperly terminated" ); 00779 return 1; 00780 } 00781 00782 /* No room for more tables */ 00783 00784 if ( tables++ >= PL_MAX_OPT_TABLES ) 00785 { 00786 plabort( "plMergeOpts: max tables limit exceeded, table not merged" ); 00787 return 1; 00788 } 00789 00790 ploption_info[tables - 1].options = options; 00791 ploption_info[tables - 1].name = name; 00792 ploption_info[tables - 1].notes = notes; 00793 00794 return 0; 00795 } 00796 00797 /*--------------------------------------------------------------------------*\ 00798 * plClearOpts() 00799 * 00800 * Clear internal option table info structure. 00801 \*--------------------------------------------------------------------------*/ 00802 00803 void 00804 plClearOpts( void ) 00805 { 00806 tables = 0; 00807 } 00808 00809 /*--------------------------------------------------------------------------*\ 00810 * plResetOpts() 00811 * 00812 * Reset internal option table info structure. 00813 \*--------------------------------------------------------------------------*/ 00814 00815 void 00816 plResetOpts( void ) 00817 { 00818 ploption_info[0] = ploption_info_default; 00819 tables = 1; 00820 } 00821 00822 /*--------------------------------------------------------------------------*\ 00823 * plparseopts() 00824 * 00825 * Process options list using current ploptions_info structure. 00826 * An error in parsing the argument list causes a program exit if 00827 * mode_full is set, otherwise the function returns with an error. 00828 \*--------------------------------------------------------------------------*/ 00829 00830 int 00831 c_plparseopts( int *p_argc, const char **argv, PLINT mode ) 00832 { 00833 const char **argsave, **argend; 00834 int i, myargc, status = 0; 00835 00836 pllib_init(); 00837 00838 /* Initialize */ 00839 00840 mode_full = mode & PL_PARSE_FULL; 00841 mode_quiet = mode & PL_PARSE_QUIET; 00842 mode_nodelete = mode & PL_PARSE_NODELETE; 00843 mode_showall = mode & PL_PARSE_SHOWALL; 00844 mode_noprogram = mode & PL_PARSE_NOPROGRAM; 00845 mode_nodash = mode & PL_PARSE_NODASH; 00846 mode_skip = mode & PL_PARSE_SKIP; 00847 00848 myargc = ( *p_argc ); 00849 argend = argv + myargc; 00850 00851 /* If program name is first argument, save and advance */ 00852 00853 if ( !mode_noprogram ) 00854 { 00855 program = plstrdup( argv[0] ); 00856 plsc->program = program; 00857 --myargc; ++argv; 00858 } 00859 if ( myargc == 0 ) 00860 return 0; 00861 00862 /* Process the command line */ 00863 00864 argsave = argv; 00865 for (; myargc > 0; --myargc, ++argv ) 00866 { 00867 /* Allow for "holes" in argv list */ 00868 00869 if ( *argv == NULL || *argv[0] == '\0' ) 00870 continue; 00871 00872 /* Loop over all options tables, starting with the last */ 00873 00874 for ( i = tables - 1; i >= 0; i-- ) 00875 { 00876 /* Check option table for option */ 00877 00878 status = ParseOpt( &myargc, &argv, p_argc, &argsave, 00879 ploption_info[i].options ); 00880 00881 if ( !status ) 00882 break; 00883 } 00884 00885 /* Handle error return as specified by the mode flag */ 00886 00887 if ( status == -1 ) 00888 { 00889 /* No match. Keep going if mode_skip is set, otherwise abort if 00890 * fully parsing, else return without error. */ 00891 00892 status = 0; 00893 00894 if ( mode_skip ) 00895 { 00896 if ( !mode_nodelete ) 00897 *argsave++ = *argv; 00898 continue; 00899 } 00900 if ( !mode_quiet && mode_full ) 00901 { 00902 fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] ); 00903 plOptUsage(); 00904 } 00905 if ( mode_full ) 00906 exit( 1 ); 00907 00908 break; 00909 } 00910 else if ( status == 1 ) 00911 { 00912 /* Illegal or badly formed */ 00913 00914 if ( !mode_quiet ) 00915 { 00916 fprintf( stderr, "\nBad command line option \"%s\"\n", argv[0] ); 00917 plOptUsage(); 00918 } 00919 if ( mode_full ) 00920 exit( 1 ); 00921 00922 break; 00923 } 00924 else if ( status == 2 ) 00925 { 00926 /* Informational option encountered (-h or -v) */ 00927 00928 exit( 0 ); 00929 } 00930 } 00931 00932 /* Compress and NULL-terminate argv */ 00933 00934 if ( !mode_nodelete ) 00935 { 00936 for ( i = 0; i < myargc; i++ ) 00937 *argsave++ = *argv++; 00938 00939 if ( argsave < argend ) 00940 { 00941 *argsave = NULL; 00942 #ifdef HAVE_NSGETARGC 00943 /* 00944 * Modify the global argc variable to match the shortened argv. 00945 * The global argc and argv must be kept consistent so that future 00946 * users of them (e.g. libraries loaded later with a device driver) 00947 * will not try to dereference the null pointer at the end of the 00948 * shortened argv array. 00949 */ 00950 *_NSGetArgc() = *p_argc; 00951 #endif 00952 } 00953 } 00954 00955 return status; 00956 } 00957 00958 /*--------------------------------------------------------------------------*\ 00959 * ParseOpt() 00960 * 00961 * Parses & determines appropriate action for input flag. 00962 \*--------------------------------------------------------------------------*/ 00963 00964 static int 00965 ParseOpt( int *p_myargc, const char ***p_argv, int *p_argc, const char ***p_argsave, 00966 PLOptionTable *option_table ) 00967 { 00968 PLOptionTable *tab; 00969 const char *opt; 00970 00971 /* Only handle actual flags and their arguments */ 00972 00973 if ( mode_nodash || ( *p_argv )[0][0] == '-' ) 00974 { 00975 opt = ( *p_argv )[0]; 00976 if ( *opt == '-' ) 00977 opt++; 00978 00979 for ( tab = option_table; tab->opt; tab++ ) 00980 { 00981 /* Skip if option not enabled */ 00982 00983 if ( tab->mode & PL_OPT_DISABLED ) 00984 continue; 00985 00986 /* Try to match it */ 00987 00988 if ( *opt == *tab->opt && !strcmp( opt, tab->opt ) ) 00989 { 00990 /* Option matched, so remove from argv list if applicable. */ 00991 00992 if ( !mode_nodelete ) 00993 { 00994 if ( tab->mode & PL_OPT_NODELETE ) 00995 ( *( *p_argsave )++ ) = ( **p_argv ); 00996 else 00997 --( *p_argc ); 00998 } 00999 01000 /* Process option (and argument if applicable) */ 01001 01002 return ( ProcessOpt( opt, tab, p_myargc, p_argv, p_argc ) ); 01003 } 01004 } 01005 } 01006 01007 return -1; 01008 } 01009 01010 /*--------------------------------------------------------------------------*\ 01011 * ProcessOpt() 01012 * 01013 * Process option (and argument if applicable). 01014 \*--------------------------------------------------------------------------*/ 01015 01016 static int 01017 ProcessOpt( const char *opt, PLOptionTable *tab, int *p_myargc, const char ***p_argv, 01018 int *p_argc ) 01019 { 01020 int need_arg, res; 01021 const char *optarg = NULL; 01022 01023 /* Get option argument if necessary */ 01024 01025 need_arg = PL_OPT_ARG | PL_OPT_INT | PL_OPT_FLOAT | PL_OPT_STRING; 01026 01027 if ( tab->mode & need_arg ) 01028 { 01029 if ( GetOptarg( &optarg, p_myargc, p_argv, p_argc ) ) 01030 return 1; 01031 } 01032 01033 /* Process argument */ 01034 01035 switch ( tab->mode & 0xFF00 ) 01036 { 01037 case PL_OPT_FUNC: 01038 01039 /* Call function handler to do the job */ 01040 01041 if ( tab->handler == NULL ) 01042 { 01043 fprintf( stderr, 01044 "ProcessOpt: no handler specified for option %s\n", 01045 tab->opt ); 01046 return 1; 01047 } 01048 01049 if ( mode_nodelete && optarg ) 01050 { 01051 /* Make a copy, since handler may mung optarg with strtok() */ 01052 char *copy = 01053 (char *) malloc( (size_t) ( 1 + strlen( optarg ) ) * sizeof ( char ) ); 01054 if ( copy == NULL ) 01055 { 01056 plabort( "ProcessOpt: out of memory" ); 01057 return 1; 01058 } 01059 strcpy( copy, optarg ); 01060 res = ( ( *tab->handler )( opt, copy, tab->client_data ) ); 01061 free( (void *) copy ); 01062 return res; 01063 } 01064 else 01065 { 01066 return ( ( *tab->handler )( opt, optarg, tab->client_data ) ); 01067 } 01068 01069 case PL_OPT_BOOL: 01070 01071 /* Set *var as a boolean */ 01072 01073 if ( tab->var == NULL ) 01074 { 01075 fprintf( stderr, 01076 "ProcessOpt: no variable specified for option %s\n", 01077 tab->opt ); 01078 return 1; 01079 } 01080 *(int *) tab->var = 1; 01081 break; 01082 01083 case PL_OPT_INT: 01084 01085 /* Set *var as an int */ 01086 01087 if ( tab->var == NULL ) 01088 { 01089 fprintf( stderr, 01090 "ProcessOpt: no variable specified for option %s\n", 01091 tab->opt ); 01092 return 1; 01093 } 01094 *(int *) tab->var = atoi( optarg ); 01095 break; 01096 01097 case PL_OPT_FLOAT: 01098 01099 /* Set *var as a float */ 01100 01101 if ( tab->var == NULL ) 01102 { 01103 fprintf( stderr, 01104 "ProcessOpt: no variable specified for option %s\n", 01105 tab->opt ); 01106 return 1; 01107 } 01108 *(PLFLT *) tab->var = atof( optarg ); 01109 break; 01110 01111 case PL_OPT_STRING: 01112 01113 /* Set var (can be NULL initially) to point to optarg string */ 01114 01115 *(char **) tab->var = (char *) optarg; 01116 break; 01117 01118 default: 01119 01120 /* Somebody messed up.. */ 01121 01122 fprintf( stderr, 01123 "ProcessOpt: invalid processing mode for option %s\n", 01124 tab->opt ); 01125 return 1; 01126 } 01127 return 0; 01128 } 01129 01130 /*--------------------------------------------------------------------------*\ 01131 * GetOptarg() 01132 * 01133 * Retrieves an option argument. 01134 * If an error occurs here it is a true syntax error. 01135 \*--------------------------------------------------------------------------*/ 01136 01137 static int 01138 GetOptarg( const char **poptarg, int *p_myargc, const char ***p_argv, int *p_argc ) 01139 { 01140 int result = 0; 01141 01142 --( *p_myargc ); 01143 01144 if ( ( *p_myargc ) <= 0 ) /* oops, no more arguments */ 01145 result = 1; 01146 01147 if ( !result ) 01148 { 01149 ( *p_argv )++; 01150 if ( ( *p_argv )[0][0] == '-' && isalpha( ( *p_argv )[0][1] ) ) 01151 { 01152 ( *p_argv )--; /* oops, next arg is a flag */ 01153 result = 1; 01154 } 01155 } 01156 01157 if ( !result ) /* yeah, the user got it right */ 01158 { 01159 ( *p_argc )--; 01160 *poptarg = ( *p_argv )[0]; 01161 } 01162 else 01163 { 01164 if ( !mode_quiet ) 01165 { 01166 fprintf( stderr, "Argument missing for %s option.\n", ( *p_argv )[0] ); 01167 plOptUsage(); 01168 } 01169 } 01170 return result; 01171 } 01172 01173 /*--------------------------------------------------------------------------*\ 01174 * plSetUsage() 01175 * 01176 * Set the strings used in usage and syntax messages. 01177 \*--------------------------------------------------------------------------*/ 01178 01179 void 01180 plSetUsage( const char *program_string, const char *usage_string ) 01181 { 01182 if ( program_string != NULL ) 01183 program = program_string; 01184 01185 if ( usage_string != NULL ) 01186 usage = usage_string; 01187 } 01188 01189 /*--------------------------------------------------------------------------*\ 01190 * plOptUsage() 01191 * 01192 * Print usage & syntax message. 01193 \*--------------------------------------------------------------------------*/ 01194 01195 void 01196 plOptUsage( void ) 01197 { 01198 if ( usage == NULL ) 01199 fprintf( stderr, "\nUsage:\n %s [options]\n", program ); 01200 else 01201 fputs( usage, stderr ); 01202 01203 Syntax(); 01204 01205 fprintf( stderr, "\n\nType %s -h for a full description.\n\n", 01206 program ); 01207 } 01208 01209 /*--------------------------------------------------------------------------*\ 01210 * Syntax() 01211 * 01212 * Print short syntax message. 01213 \*--------------------------------------------------------------------------*/ 01214 01215 static void 01216 Syntax( void ) 01217 { 01218 PLOptionTable *tab; 01219 int i, col, len; 01220 01221 /* Loop over all options tables */ 01222 01223 for ( i = tables - 1; i >= 0; i-- ) 01224 { 01225 /* Introducer */ 01226 01227 if ( ploption_info[i].name ) 01228 fprintf( stderr, "\n%s:", ploption_info[i].name ); 01229 else 01230 fputs( "\nUser options:", stderr ); 01231 01232 /* Print syntax for each option */ 01233 01234 col = 80; 01235 for ( tab = ploption_info[i].options; tab->opt; tab++ ) 01236 { 01237 if ( tab->mode & PL_OPT_DISABLED ) 01238 continue; 01239 01240 if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) ) 01241 continue; 01242 01243 if ( tab->syntax == NULL ) 01244 continue; 01245 01246 len = 3 + strlen( tab->syntax ); /* space [ string ] */ 01247 if ( col + len > 79 ) 01248 { 01249 fprintf( stderr, "\n " ); /* 3 spaces */ 01250 col = 3; 01251 } 01252 fprintf( stderr, " [%s]", tab->syntax ); 01253 col += len; 01254 } 01255 fprintf( stderr, "\n" ); 01256 } 01257 } 01258 01259 /*--------------------------------------------------------------------------*\ 01260 * Help() 01261 * 01262 * Print long help message. 01263 \*--------------------------------------------------------------------------*/ 01264 01265 static void 01266 Help( void ) 01267 { 01268 PLOptionTable *tab; 01269 const char **note; 01270 int i; 01271 FILE *outfile = stderr; 01272 01273 #ifdef HAVE_POPEN 01274 FILE *pager = NULL; 01275 if ( getenv( "PAGER" ) != NULL ) 01276 pager = (FILE *) popen( "$PAGER", "w" ); 01277 if ( pager == NULL ) 01278 pager = (FILE *) popen( "more", "w" ); 01279 if ( pager != NULL ) 01280 outfile = pager; 01281 #endif 01282 01283 /* Usage line */ 01284 01285 if ( usage == NULL ) 01286 fprintf( outfile, "\nUsage:\n %s [options]\n", program ); 01287 else 01288 fputs( usage, outfile ); 01289 01290 /* Loop over all options tables */ 01291 01292 for ( i = tables - 1; i >= 0; i-- ) 01293 { 01294 /* Introducer */ 01295 01296 if ( ploption_info[i].name ) 01297 fprintf( outfile, "\n%s:\n", ploption_info[i].name ); 01298 else 01299 fputs( "\nUser options:\n", outfile ); 01300 01301 /* Print description for each option */ 01302 01303 for ( tab = ploption_info[i].options; tab->opt; tab++ ) 01304 { 01305 if ( tab->mode & PL_OPT_DISABLED ) 01306 continue; 01307 01308 if ( !mode_showall && ( tab->mode & PL_OPT_INVISIBLE ) ) 01309 continue; 01310 01311 if ( tab->desc == NULL ) 01312 continue; 01313 01314 if ( tab->mode & PL_OPT_INVISIBLE ) 01315 fprintf( outfile, " * %-20s %s\n", tab->syntax, tab->desc ); 01316 else 01317 fprintf( outfile, " %-20s %s\n", tab->syntax, tab->desc ); 01318 } 01319 01320 /* Usage notes */ 01321 01322 if ( ploption_info[i].notes ) 01323 { 01324 putc( '\n', outfile ); 01325 for ( note = ploption_info[i].notes; *note; note++ ) 01326 { 01327 fputs( *note, outfile ); 01328 putc( '\n', outfile ); 01329 } 01330 } 01331 } 01332 01333 #ifdef HAVE_POPEN 01334 if ( pager != NULL ) 01335 pclose( pager ); 01336 #endif 01337 } 01338 01339 /*--------------------------------------------------------------------------*\ 01340 * plParseDrvOpts 01341 * 01342 * Parse driver specific options 01343 \*--------------------------------------------------------------------------*/ 01344 01345 int 01346 plParseDrvOpts( DrvOpt *acc_opt ) 01347 { 01348 DrvOptCmd *drvp; 01349 DrvOpt *t; 01350 int fl; 01351 char msg[80]; 01352 memset( msg, '\0', sizeof ( msg ) ); 01353 01354 if ( !drv_opt.option ) 01355 return 1; 01356 01357 drvp = &drv_opt; 01358 do 01359 { 01360 t = acc_opt; fl = 0; 01361 while ( t->opt ) 01362 { 01363 if ( strcmp( drvp->option, t->opt ) == 0 ) 01364 { 01365 fl = 1; 01366 switch ( t->type ) 01367 { 01368 case DRV_STR: 01369 *(char **) ( t->var_ptr ) = ( drvp->value ); 01370 #ifdef DEBUG 01371 fprintf( stderr, "plParseDrvOpts: %s %s\n", t->opt, *(char**) t->var_ptr ); 01372 #endif 01373 break; 01374 01375 case DRV_INT: 01376 if ( sscanf( drvp->value, "%d", (int *) t->var_ptr ) != 1 ) 01377 { 01378 snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option ); 01379 plexit( msg ); 01380 } 01381 #ifdef DEBUG 01382 fprintf( stderr, "plParseDrvOpts: %s %d\n", t->opt, *(int *) t->var_ptr ); 01383 #endif 01384 break; 01385 01386 case DRV_FLT: 01387 if ( sscanf( drvp->value, "%f", (float *) t->var_ptr ) != 1 ) 01388 { 01389 snprintf( msg, sizeof ( msg ) - 1, "Incorrect argument to '%s' option", drvp->option ); 01390 plexit( msg ); 01391 } 01392 #ifdef DEBUG 01393 fprintf( stderr, "plParseDrvOpts: %s %f\n", t->opt, *(float *) t->var_ptr ); 01394 #endif 01395 break; 01396 } 01397 } 01398 t++; 01399 } 01400 01401 if ( !fl ) 01402 { 01403 snprintf( msg, sizeof ( msg ) - 1, "Option '%s' not recognized.\n\nRecognized options for this driver are:\n", drvp->option ); 01404 plwarn( msg ); 01405 plHelpDrvOpts( acc_opt ); 01406 plexit( "" ); 01407 } 01408 } 01409 while ( ( drvp = drvp->next ) ) 01410 ; 01411 01412 return 0; 01413 } 01414 01415 /*--------------------------------------------------------------------------*\ 01416 * plHelpDrvOpts 01417 * 01418 * Give driver specific help 01419 \*--------------------------------------------------------------------------*/ 01420 01421 void 01422 plHelpDrvOpts( DrvOpt *acc_opt ) 01423 { 01424 DrvOpt *t; 01425 01426 t = acc_opt; 01427 while ( t->opt ) 01428 { 01429 fprintf( stderr, "%s:\t%s\n", t->opt, t->hlp_msg ); 01430 t++; 01431 } 01432 } 01433 01434 /*--------------------------------------------------------------------------*\ 01435 * tidyDrvOpts 01436 * 01437 * Tidy up and free memory associated with driver options 01438 \*--------------------------------------------------------------------------*/ 01439 01440 void 01441 plP_FreeDrvOpts() 01442 { 01443 DrvOptCmd *drvp, *drvpl; 01444 01445 drvp = &drv_opt; 01446 do 01447 { 01448 drvpl = drvp; 01449 drvp = drvpl->next; 01450 01451 free( drvpl->option ); 01452 free( drvpl->value ); 01453 /* Free additional DrvOptCmd variables - 01454 * first entry in list is a static global variable */ 01455 if ( drvpl != &drv_opt ) 01456 free( drvpl ); 01457 } while ( drvp != NULL ); 01458 01459 /* initialize drv_opt if it's used again */ 01460 drv_opt.option = NULL; 01461 drv_opt.value = NULL; 01462 drv_opt.next = NULL; 01463 } 01464 01465 01466 /*--------------------------------------------------------------------------*\ 01467 * Option handlers 01468 \*--------------------------------------------------------------------------*/ 01469 01470 /*--------------------------------------------------------------------------*\ 01471 * opt_h() 01472 * 01473 * Performs appropriate action for option "h": 01474 * Issues help message 01475 \*--------------------------------------------------------------------------*/ 01476 01477 static int 01478 opt_h( const char *opt, const char *optarg, void *client_data ) 01479 { 01480 if ( !mode_quiet ) 01481 Help(); 01482 01483 return 2; 01484 } 01485 01486 /*--------------------------------------------------------------------------*\ 01487 * opt_v() 01488 * 01489 * Performs appropriate action for option "v": 01490 * Issues version message 01491 \*--------------------------------------------------------------------------*/ 01492 01493 static int 01494 opt_v( const char *opt, const char *optarg, void *client_data ) 01495 { 01496 if ( !mode_quiet ) 01497 fprintf( stderr, "PLplot library version: %s\n", VERSION ); 01498 01499 return 2; 01500 } 01501 01502 /*--------------------------------------------------------------------------*\ 01503 * opt_verbose() 01504 * 01505 * Performs appropriate action for option "verbose": 01506 * Turn on verbosity flag 01507 \*--------------------------------------------------------------------------*/ 01508 01509 static int 01510 opt_verbose( const char *opt, const char *optarg, void *client_data ) 01511 { 01512 plsc->verbose = 1; 01513 return 0; 01514 } 01515 01516 /*--------------------------------------------------------------------------*\ 01517 * opt_debug() 01518 * 01519 * Performs appropriate action for option "debug": 01520 * Turn on debugging flag 01521 \*--------------------------------------------------------------------------*/ 01522 01523 static int 01524 opt_debug( const char *opt, const char *optarg, void *client_data ) 01525 { 01526 plsc->debug = 1; 01527 plsc->verbose = 1; 01528 return 0; 01529 } 01530 01531 /*--------------------------------------------------------------------------*\ 01532 * opt_hack() 01533 * 01534 * Performs appropriate action for option "hack": 01535 * Enables driver-specific hack(s) 01536 \*--------------------------------------------------------------------------*/ 01537 01538 static int 01539 opt_hack( const char *opt, const char *optarg, void *client_data ) 01540 { 01541 plsc->hack = 1; 01542 return 0; 01543 } 01544 01545 /*--------------------------------------------------------------------------*\ 01546 * opt_dev() 01547 * 01548 * Performs appropriate action for option "dev": 01549 * Sets output device keyword 01550 \*--------------------------------------------------------------------------*/ 01551 01552 static int 01553 opt_dev( const char *opt, const char *optarg, void *client_data ) 01554 { 01555 plsdev( optarg ); 01556 return 0; 01557 } 01558 01559 /*--------------------------------------------------------------------------*\ 01560 * opt_o() 01561 * 01562 * Performs appropriate action for option "o": 01563 * Sets output file name 01564 \*--------------------------------------------------------------------------*/ 01565 01566 static int 01567 opt_o( const char *opt, const char *optarg, void *client_data ) 01568 { 01569 plsfnam( optarg ); 01570 return 0; 01571 } 01572 01573 /*--------------------------------------------------------------------------*\ 01574 * opt_mar() 01575 * 01576 * Performs appropriate action for option "mar": 01577 * Sets relative margin width 01578 \*--------------------------------------------------------------------------*/ 01579 01580 static int 01581 opt_mar( const char *opt, const char *optarg, void *client_data ) 01582 { 01583 plsdidev( atof( optarg ), PL_NOTSET, PL_NOTSET, PL_NOTSET ); 01584 return 0; 01585 } 01586 01587 /*--------------------------------------------------------------------------*\ 01588 * opt_a() 01589 * 01590 * Performs appropriate action for option "a": 01591 * Sets plot aspect ratio on page 01592 \*--------------------------------------------------------------------------*/ 01593 01594 static int 01595 opt_a( const char *opt, const char *optarg, void *client_data ) 01596 { 01597 plsdidev( PL_NOTSET, atof( optarg ), PL_NOTSET, PL_NOTSET ); 01598 return 0; 01599 } 01600 01601 /*--------------------------------------------------------------------------*\ 01602 * opt_jx() 01603 * 01604 * Performs appropriate action for option "jx": 01605 * Sets relative justification in x 01606 \*--------------------------------------------------------------------------*/ 01607 01608 static int 01609 opt_jx( const char *opt, const char *optarg, void *client_data ) 01610 { 01611 plsdidev( PL_NOTSET, PL_NOTSET, atof( optarg ), PL_NOTSET ); 01612 return 0; 01613 } 01614 01615 /*--------------------------------------------------------------------------*\ 01616 * opt_jy() 01617 * 01618 * Performs appropriate action for option "jy": 01619 * Sets relative justification in y 01620 \*--------------------------------------------------------------------------*/ 01621 01622 static int 01623 opt_jy( const char *opt, const char *optarg, void *client_data ) 01624 { 01625 plsdidev( PL_NOTSET, PL_NOTSET, PL_NOTSET, atof( optarg ) ); 01626 return 0; 01627 } 01628 01629 /*--------------------------------------------------------------------------*\ 01630 * opt_ori() 01631 * 01632 * Performs appropriate action for option "ori": 01633 * Sets orientation 01634 \*--------------------------------------------------------------------------*/ 01635 01636 static int 01637 opt_ori( const char *opt, const char *optarg, void *client_data ) 01638 { 01639 plsdiori( atof( optarg ) ); 01640 return 0; 01641 } 01642 01643 /*--------------------------------------------------------------------------*\ 01644 * opt_freeaspect() 01645 * 01646 * Performs appropriate action for option "freeaspect": 01647 * Allow aspect ratio to adjust to orientation swaps. 01648 \*--------------------------------------------------------------------------*/ 01649 01650 static int 01651 opt_freeaspect( const char *opt, const char *optarg, void *client_data ) 01652 { 01653 plsc->freeaspect = 1; 01654 return 0; 01655 } 01656 01657 /*--------------------------------------------------------------------------*\ 01658 * opt_portrait() 01659 * 01660 * Performs appropriate action for option "portrait": 01661 * Set portrait mode. If plsc->portrait = 1, then the orientation for certain 01662 * drivers is changed by 90 deg to portrait orientation from the default 01663 * landscape orientation used by PLplot while the aspect ratio allowed to 01664 * adjust using freeaspect. 01665 * N.B. the driver list where this flag is honored is currently limited 01666 * to ljii, ljiip, psc, ps, and pstex. A 90 deg rotation is just not 01667 * appropriate for certain other drivers. These drivers where portrait 01668 * mode is ignored include display drivers (e.g., xwin, tk), drivers 01669 * which are subequently going to be transformed to another form 01670 * (e.g., meta or pbm), or drivers which are normally used for web 01671 * publishing (e.g., png, jpeg). That said, the case is not entirely clear 01672 * for all drivers so the list of drivers where portrait mode is honored 01673 * may increase in the future. To add to the list simply copy the small 01674 * bit of code from ps.c that has to do with pls->portrait to the 01675 * appropriate driver file. 01676 \*--------------------------------------------------------------------------*/ 01677 01678 static int 01679 opt_portrait( const char *opt, const char *optarg, void *client_data ) 01680 { 01681 plsc->portrait = 1; 01682 return 0; 01683 } 01684 01685 /*--------------------------------------------------------------------------*\ 01686 * opt_width() 01687 * 01688 * Performs appropriate action for option "width": 01689 * Sets pen width 01690 \*--------------------------------------------------------------------------*/ 01691 01692 static int 01693 opt_width( const char *opt, const char *optarg, void *client_data ) 01694 { 01695 int width; 01696 01697 width = atoi( optarg ); 01698 if ( width < 0 ) 01699 { 01700 fprintf( stderr, "?invalid width\n" ); 01701 return 1; 01702 } 01703 else 01704 { 01705 plwid( width ); 01706 plsc->widthlock = 1; 01707 } 01708 return 0; 01709 } 01710 01711 /*--------------------------------------------------------------------------*\ 01712 * opt_bg() 01713 * 01714 * Performs appropriate action for option "bg": 01715 * Sets background color (rgb represented in hex on command line) and alpha 01716 * (represented as floating point on the command line with underscore 01717 * delimiter), e.g., 01718 * -bg ff0000 (set background to red with an alpha value of 1.0) 01719 * -bg ff0000_0.1 (set background to red with an alpha value of 0.1 01720 \*--------------------------------------------------------------------------*/ 01721 01722 static int 01723 opt_bg( const char *opt, const char *optarg, void *client_data ) 01724 { 01725 const char *rgb; 01726 char *color_field, *alpha_field; 01727 long bgcolor, r, g, b; 01728 PLFLT a; 01729 01730 /* Strip off leading "#" (TK-ism) if present. */ 01731 01732 if ( *optarg == '#' ) 01733 rgb = optarg + 1; 01734 else 01735 rgb = optarg; 01736 01737 strncpy( opttmp, optarg, OPTMAX - 1 ); 01738 opttmp[OPTMAX - 1] = '\0'; 01739 01740 if ( strchr( opttmp, '_' ) ) 01741 { 01742 /* e.g., -bg ff0000_0.1 */ 01743 color_field = strtok( opttmp, "_" ); 01744 alpha_field = strtok( NULL, "_" ); 01745 } 01746 else 01747 { 01748 color_field = opttmp; 01749 alpha_field = NULL; 01750 } 01751 01752 bgcolor = strtol( color_field, NULL, 16 ); 01753 01754 /* Must be either a 3 or 6 digit hex number */ 01755 /* If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC). */ 01756 01757 switch ( strlen( color_field ) ) 01758 { 01759 case 3: 01760 r = ( bgcolor & 0xF00 ) >> 8; 01761 g = ( bgcolor & 0x0F0 ) >> 4; 01762 b = ( bgcolor & 0x00F ); 01763 01764 r = r | ( r << 4 ); 01765 g = g | ( g << 4 ); /* doubling */ 01766 b = b | ( b << 4 ); 01767 break; 01768 01769 case 6: 01770 r = ( bgcolor & 0xFF0000 ) >> 16; 01771 g = ( bgcolor & 0x00FF00 ) >> 8; 01772 b = ( bgcolor & 0x0000FF ); 01773 break; 01774 01775 default: 01776 fprintf( stderr, "Unrecognized background color value %s\n", color_field ); 01777 return 1; 01778 } 01779 01780 if ( alpha_field ) 01781 a = atof( alpha_field ); 01782 else 01783 a = 1.; 01784 01785 plscolbga( r, g, b, a ); 01786 01787 return 0; 01788 } 01789 01790 /*--------------------------------------------------------------------------*\ 01791 * opt_ncol0() 01792 * 01793 * Performs appropriate action for option "ncol0": 01794 * Sets number of colors to allocate in cmap 0 (upper bound). 01795 \*--------------------------------------------------------------------------*/ 01796 01797 static int 01798 opt_ncol0( const char *opt, const char *optarg, void *client_data ) 01799 { 01800 plsc->ncol0 = atoi( optarg ); 01801 return 0; 01802 } 01803 01804 /*--------------------------------------------------------------------------*\ 01805 * opt_ncol1() 01806 * 01807 * Performs appropriate action for option "ncol1": 01808 * Sets number of colors to allocate in cmap 1 (upper bound). 01809 \*--------------------------------------------------------------------------*/ 01810 01811 static int 01812 opt_ncol1( const char *opt, const char *optarg, void *client_data ) 01813 { 01814 plsc->ncol1 = atoi( optarg ); 01815 return 0; 01816 } 01817 01818 /*--------------------------------------------------------------------------*\ 01819 * opt_wplt() 01820 * 01821 * Performs appropriate action for option "wplt": 01822 * Sets (zoom) window into plot (e.g. "0,0,0.5,0.5") 01823 \*--------------------------------------------------------------------------*/ 01824 01825 static int 01826 opt_wplt( const char *opt, const char *optarg, void *client_data ) 01827 { 01828 char *field; 01829 PLFLT xl, yl, xr, yr; 01830 01831 strncpy( opttmp, optarg, OPTMAX - 1 ); 01832 opttmp[OPTMAX - 1] = '\0'; 01833 01834 if ( ( field = strtok( opttmp, "," ) ) == NULL ) 01835 return 1; 01836 01837 xl = atof( field ); 01838 01839 if ( ( field = strtok( NULL, "," ) ) == NULL ) 01840 return 1; 01841 01842 yl = atof( field ); 01843 01844 if ( ( field = strtok( NULL, "," ) ) == NULL ) 01845 return 1; 01846 01847 xr = atof( field ); 01848 01849 if ( ( field = strtok( NULL, "," ) ) == NULL ) 01850 return 1; 01851 01852 yr = atof( field ); 01853 01854 plsdiplt( xl, yl, xr, yr ); 01855 return 0; 01856 } 01857 01858 /*--------------------------------------------------------------------------*\ 01859 * opt_drvopt() 01860 * 01861 * Get driver specific options in the form <option[=value]>[,option[=value]]* 01862 * If "value" is not specified, it defaults to "1". 01863 \*--------------------------------------------------------------------------*/ 01864 01865 static int 01866 opt_drvopt( const char *opt, const char *optarg, void *client_data ) 01867 { 01868 char t, *tt, *option, *value; 01869 int fl = 0; 01870 DrvOptCmd *drvp; 01871 01872 option = (char *) malloc( (size_t) ( 1 + strlen( optarg ) ) * sizeof ( char ) ); 01873 if ( option == NULL ) 01874 plexit( "opt_drvopt: Out of memory!?" ); 01875 01876 value = (char *) malloc( (size_t) ( 1 + strlen( optarg ) ) * sizeof ( char ) ); 01877 if ( value == NULL ) 01878 plexit( "opt_drvopt: Out of memory!?" ); 01879 01880 drvp = &drv_opt; 01881 *option = *value = '\0'; 01882 tt = option; 01883 while ( ( t = *optarg++ ) ) 01884 { 01885 switch ( t ) 01886 { 01887 case ',': 01888 if ( fl ) 01889 fl = 0; 01890 else 01891 { 01892 value[0] = '1'; 01893 value[1] = '\0'; 01894 } 01895 01896 *tt = '\0'; tt = option; 01897 drvp->option = plstrdup( option ); /* it should not be release, because of familying */ 01898 drvp->value = plstrdup( value ); /* don't release */ 01899 drvp->next = (DrvOptCmd *) malloc( sizeof ( DrvOptCmd ) ); /* don't release */ 01900 if ( drvp->next == NULL ) 01901 plexit( "opt_drvopt: Out of memory!?\n" ); 01902 01903 drvp = drvp->next; 01904 break; 01905 01906 case '=': 01907 fl = 1; 01908 *tt = '\0'; tt = value; 01909 break; 01910 01911 default: 01912 *tt++ = t; 01913 } 01914 } 01915 01916 *tt = '\0'; 01917 if ( !fl ) 01918 { 01919 value[0] = '1'; 01920 value[1] = '\0'; 01921 } 01922 01923 drvp->option = plstrdup( option ); /* don't release */ 01924 drvp->value = plstrdup( value ); /* don't release */ 01925 drvp->next = NULL; 01926 01927 #ifdef DEBUG 01928 fprintf( stderr, "\nopt_drvopt: -drvopt parsed options:\n" ); 01929 drvp = &drv_opt; 01930 do 01931 fprintf( stderr, "%s %s\n", drvp->option, drvp->value ); 01932 while ( drvp = drvp->next ); 01933 fprintf( stderr, "\n" ); 01934 #endif 01935 01936 free( option ); free( value ); 01937 01938 return 0; 01939 } 01940 01941 /*--------------------------------------------------------------------------*\ 01942 * opt_fam() 01943 * 01944 * Performs appropriate action for option "fam": 01945 * Enables family output files 01946 \*--------------------------------------------------------------------------*/ 01947 01948 static int 01949 opt_fam( const char *opt, const char *optarg, void *client_data ) 01950 { 01951 plsfam( 1, -1, -1 ); 01952 return 0; 01953 } 01954 01955 /*--------------------------------------------------------------------------*\ 01956 * opt_fsiz() 01957 * 01958 * Performs appropriate action for option "fsiz": 01959 * Sets size of a family member file (may be somewhat larger since eof must 01960 * occur at a page break). Also turns on familying. Example usage: 01961 * 01962 * -fsiz 5M (5 MB) 01963 * -fsiz 300K (300 KB) 01964 * -fsiz .3M (same) 01965 * -fsiz .5G (half a GB) 01966 * 01967 * Note case of the trailing suffix doesn't matter. 01968 * If no suffix, defaults to MB. 01969 \*--------------------------------------------------------------------------*/ 01970 01971 static int 01972 opt_fsiz( const char *opt, const char *optarg, void *client_data ) 01973 { 01974 PLINT bytemax; 01975 int len = strlen( optarg ); 01976 char lastchar = optarg[len - 1]; 01977 PLFLT multiplier = 1.0e6; 01978 char *spec = (char*) malloc( len + 1 ); 01979 01980 if ( spec == NULL ) 01981 plexit( "opt_fsiz: Insufficient memory" ); 01982 01983 /* Interpret optional suffix */ 01984 01985 switch ( lastchar ) 01986 { 01987 case 'k': 01988 case 'K': 01989 multiplier = 1.0e3; len--; 01990 break; 01991 case 'm': 01992 case 'M': 01993 multiplier = 1.0e6; len--; 01994 break; 01995 case 'g': 01996 case 'G': 01997 multiplier = 1.0e9; len--; 01998 break; 01999 } 02000 strncpy( spec, optarg, len ); 02001 spec[len] = '\0'; 02002 02003 bytemax = (PLINT) ( multiplier * atof( spec ) ); 02004 if ( bytemax <= 0 ) 02005 { 02006 fprintf( stderr, "?invalid file size %d. 2.14G is the maximum.\n", bytemax ); 02007 return 1; 02008 } 02009 plsfam( 1, -1, bytemax ); 02010 02011 free( spec ); 02012 return 0; 02013 } 02014 02015 /*--------------------------------------------------------------------------*\ 02016 * opt_fbeg() 02017 * 02018 * Performs appropriate action for option "fbeg": 02019 * Starts with the specified family member number. 02020 \*--------------------------------------------------------------------------*/ 02021 02022 static int 02023 opt_fbeg( const char *opt, const char *optarg, void *client_data ) 02024 { 02025 plsc->member = atoi( optarg ); 02026 02027 return 0; 02028 } 02029 02030 /*--------------------------------------------------------------------------*\ 02031 * opt_finc() 02032 * 02033 * Performs appropriate action for option "finc": 02034 * Specify increment between family members. 02035 \*--------------------------------------------------------------------------*/ 02036 02037 static int 02038 opt_finc( const char *opt, const char *optarg, void *client_data ) 02039 { 02040 plsc->finc = atoi( optarg ); 02041 02042 return 0; 02043 } 02044 02045 /*--------------------------------------------------------------------------*\ 02046 * opt_fflen() 02047 * 02048 * Performs appropriate action for option "fflen": 02049 * Specify minimum field length for family member number. 02050 \*--------------------------------------------------------------------------*/ 02051 02052 static int 02053 opt_fflen( const char *opt, const char *optarg, void *client_data ) 02054 { 02055 plsc->fflen = atoi( optarg ); 02056 02057 return 0; 02058 } 02059 02060 /*--------------------------------------------------------------------------*\ 02061 * opt_np() 02062 * 02063 * Performs appropriate action for option "np": 02064 * Disables pause between pages 02065 \*--------------------------------------------------------------------------*/ 02066 02067 static int 02068 opt_np( const char *opt, const char *optarg, void *client_data ) 02069 { 02070 plspause( 0 ); 02071 return 0; 02072 } 02073 02074 /*--------------------------------------------------------------------------*\ 02075 * opt_nopixmap() 02076 * 02077 * Performs appropriate action for option "nopixmap": 02078 * Disables use of pixmaps in X drivers 02079 \*--------------------------------------------------------------------------*/ 02080 02081 static int 02082 opt_nopixmap( const char *opt, const char *optarg, void *client_data ) 02083 { 02084 plsc->nopixmap = 1; 02085 return 0; 02086 } 02087 02088 /*--------------------------------------------------------------------------*\ 02089 * opt_db() 02090 * 02091 * Performs appropriate action for option "db": 02092 * Double buffer X output (update only done on eop or Expose) 02093 \*--------------------------------------------------------------------------*/ 02094 02095 static int 02096 opt_db( const char *opt, const char *optarg, void *client_data ) 02097 { 02098 plsc->db = 1; 02099 return 0; 02100 } 02101 02102 /*--------------------------------------------------------------------------*\ 02103 * opt_bufmax() 02104 * 02105 * Performs appropriate action for option "bufmax": 02106 * Sets size of data buffer for tk driver 02107 \*--------------------------------------------------------------------------*/ 02108 02109 static int 02110 opt_bufmax( const char *opt, const char *optarg, void *client_data ) 02111 { 02112 plsc->bufmax = atoi( optarg ); 02113 return 0; 02114 } 02115 02116 /*--------------------------------------------------------------------------*\ 02117 * opt_server_name() 02118 * 02119 * Performs appropriate action for option "server_name": 02120 * Sets main window name of server (Tcl/TK driver only) 02121 \*--------------------------------------------------------------------------*/ 02122 02123 static int 02124 opt_server_name( const char *opt, const char *optarg, void *client_data ) 02125 { 02126 plsc->server_name = plstrdup( optarg ); 02127 return 0; 02128 } 02129 02130 /*--------------------------------------------------------------------------*\ 02131 * opt_plserver() 02132 * 02133 * Performs appropriate action for option "plserver": 02134 * Sets name to use when invoking server (Tcl/TK driver only) 02135 \*--------------------------------------------------------------------------*/ 02136 02137 static int 02138 opt_plserver( const char *opt, const char *optarg, void *client_data ) 02139 { 02140 plsc->plserver = plstrdup( optarg ); 02141 return 0; 02142 } 02143 02144 /*--------------------------------------------------------------------------*\ 02145 * opt_plwindow() 02146 * 02147 * Performs appropriate action for option "plwindow": 02148 * Sets PLplot window name 02149 \*--------------------------------------------------------------------------*/ 02150 02151 static int 02152 opt_plwindow( const char *opt, const char *optarg, void *client_data ) 02153 { 02154 if ( ( plsc->plwindow = (char *) malloc( (size_t) ( 1 + strlen( optarg ) ) * sizeof ( char ) ) ) == NULL ) 02155 { 02156 plexit( "opt_plwindow: Insufficient memory" ); 02157 } 02158 strcpy( plsc->plwindow, optarg ); 02159 return 0; 02160 } 02161 02162 /*--------------------------------------------------------------------------*\ 02163 * opt_tcl_cmd() 02164 * 02165 * Performs appropriate action for option "tcl_cmd": 02166 * Sets TCL command(s) to eval on startup 02167 * Depreciated - just bounce on to -drvopt tcl_cmd= 02168 \*--------------------------------------------------------------------------*/ 02169 02170 static int 02171 opt_tcl_cmd( const char *opt, const char *optarg, void *client_data ) 02172 { 02173 char *newcmd; 02174 02175 if ( ( newcmd = (char *) malloc( (size_t) ( strlen( optarg ) + 9 ) * sizeof ( char ) ) ) == NULL ) 02176 { 02177 plexit( "opt_tcl_cmd: Insufficient memory" ); 02178 } 02179 02180 strcpy( newcmd, "tcl_cmd=" ); 02181 strcat( newcmd, optarg ); 02182 02183 fprintf( stderr, "-tcl_cmd <cmd> is obsolete. Please use -drvopt tcl_cmd=<cmd> instead\n" ); 02184 02185 opt_drvopt( "drvopt", newcmd, NULL ); 02186 free( newcmd ); 02187 02188 return 0; 02189 } 02190 02191 /*--------------------------------------------------------------------------*\ 02192 * opt_auto_path() 02193 * 02194 * Performs appropriate action for option "auto_path": 02195 * Sets additional directories to autoload 02196 \*--------------------------------------------------------------------------*/ 02197 02198 static int 02199 opt_auto_path( const char *opt, const char *optarg, void *client_data ) 02200 { 02201 plsc->auto_path = plstrdup( optarg ); 02202 return 0; 02203 } 02204 02205 /*--------------------------------------------------------------------------*\ 02206 * opt_px() 02207 * 02208 * Performs appropriate action for option "px": 02209 * Set packing in x 02210 \*--------------------------------------------------------------------------*/ 02211 02212 static int 02213 opt_px( const char *opt, const char *optarg, void *client_data ) 02214 { 02215 plssub( atoi( optarg ), -1 ); 02216 return 0; 02217 } 02218 02219 /*--------------------------------------------------------------------------*\ 02220 * opt_py() 02221 * 02222 * Performs appropriate action for option "py": 02223 * Set packing in y 02224 \*--------------------------------------------------------------------------*/ 02225 02226 static int 02227 opt_py( const char *opt, const char *optarg, void *client_data ) 02228 { 02229 plssub( -1, atoi( optarg ) ); 02230 return 0; 02231 } 02232 02233 /*--------------------------------------------------------------------------*\ 02234 * opt_geo() 02235 * 02236 * Performs appropriate action for option "geo": Set geometry for 02237 * output window, i.e., "-geometry WIDTHxHEIGHT+XOFF+YOFF" where 02238 * WIDTHxHEIGHT, +XOFF+YOFF, or both must be present, and +XOFF+YOFF 02239 * stands for one of the four combinations +XOFF+YOFF, +XOFF-YOFF, 02240 * -XOFF+YOFF, and -XOFF-YOFF. Some examples are the following: 02241 * -geometry 400x300, -geometry -100+200, and -geometry 400x300-100+200. 02242 \*--------------------------------------------------------------------------*/ 02243 02244 static int 02245 opt_geo( const char *opt, const char *optarg, void *client_data ) 02246 { 02247 int numargs; 02248 PLFLT xdpi = 0., ydpi = 0.; 02249 PLINT xwid, ywid, xoff, yoff; 02250 02251 /* The TK driver uses the geometry string directly */ 02252 02253 if ( ( plsc->geometry = (char *) malloc( (size_t) ( 1 + strlen( optarg ) ) * sizeof ( char ) ) ) == NULL ) 02254 { 02255 plexit( "opt_geo: Insufficient memory" ); 02256 } 02257 02258 strcpy( plsc->geometry, optarg ); 02259 02260 numargs = sscanf( optarg, "%dx%d%d%d", &xwid, &ywid, &xoff, &yoff ); 02261 if ( numargs == 2 ) 02262 { 02263 xoff = 0; 02264 yoff = 0; 02265 if ( xwid == 0 ) 02266 fprintf( stderr, "?invalid xwid in -geometry %s\n", optarg ); 02267 if ( ywid == 0 ) 02268 fprintf( stderr, "?invalid ywid in -geometry %s\n", optarg ); 02269 if ( xwid < 0 ) 02270 { 02271 fprintf( stderr, "?invalid xwid in -geometry %s\n", optarg ); 02272 return 1; 02273 } 02274 if ( ywid < 0 ) 02275 { 02276 fprintf( stderr, "?invalid ywid in -geometry %s\n", optarg ); 02277 return 1; 02278 } 02279 } 02280 else if ( numargs == 4 ) 02281 { 02282 if ( xwid == 0 ) 02283 fprintf( stderr, "?invalid xwid in -geometry %s\n", optarg ); 02284 if ( ywid == 0 ) 02285 fprintf( stderr, "?invalid ywid in -geometry %s\n", optarg ); 02286 if ( xwid < 0 ) 02287 { 02288 fprintf( stderr, "?invalid xwid in -geometry %s\n", optarg ); 02289 return 1; 02290 } 02291 if ( ywid < 0 ) 02292 { 02293 fprintf( stderr, "?invalid ywid in -geometry %s\n", optarg ); 02294 return 1; 02295 } 02296 if ( abs( xoff ) == 0 ) 02297 fprintf( stderr, "?invalid xoff in -geometry %s\n", optarg ); 02298 if ( abs( yoff ) == 0 ) 02299 fprintf( stderr, "?invalid yoff in -geometry %s\n", optarg ); 02300 } 02301 else 02302 { 02303 numargs = sscanf( optarg, "%d%d", &xoff, &yoff ); 02304 if ( numargs == 2 ) 02305 { 02306 xwid = 0; 02307 ywid = 0; 02308 if ( abs( xoff ) == 0 ) 02309 fprintf( stderr, "?invalid xoff in -geometry %s\n", optarg ); 02310 if ( abs( yoff ) == 0 ) 02311 fprintf( stderr, "?invalid yoff in -geometry %s\n", optarg ); 02312 } 02313 else 02314 { 02315 fprintf( stderr, "?invalid -geometry %s\n", optarg ); 02316 return 1; 02317 } 02318 } 02319 /*fprintf( stderr, "xwid, ywid, xoff, yoff = %d, %d, %d, %d\n", xwid, ywid, xoff, yoff );*/ 02320 plspage( xdpi, ydpi, xwid, ywid, xoff, yoff ); 02321 return 0; 02322 } 02323 02324 /*--------------------------------------------------------------------------*\ 02325 * opt_tk_file() 02326 * 02327 * File name for plserver tk_file option 02328 \*--------------------------------------------------------------------------*/ 02329 02330 static int 02331 opt_tk_file( const char *opt, const char *optarg, void *client_data ) 02332 { 02333 if ( ( plsc->tk_file = (char *) malloc( (size_t) ( 1 + strlen( optarg ) ) * sizeof ( char ) ) ) == NULL ) 02334 { 02335 plexit( "opt_tk_file: Insufficient memory" ); 02336 } 02337 02338 strcpy( plsc->tk_file, optarg ); 02339 return 0; 02340 } 02341 02342 /*--------------------------------------------------------------------------*\ 02343 * opt_dpi() 02344 * 02345 * Performs appropriate action for option "dpi": 02346 * Set dpi resolution for output device 02347 * e.g., "-dpi 600x300", will set X dpi to 600 and Y dpi to 300 02348 * or 02349 * e.g., "-dpi 1200" 02350 * Will set both X and Y dpi to 1200 dpi 02351 \*--------------------------------------------------------------------------*/ 02352 02353 static int 02354 opt_dpi( const char *opt, const char *optarg, void *client_data ) 02355 { 02356 char *field; 02357 PLFLT xdpi = 0., ydpi = 0.; 02358 PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0; 02359 02360 strncpy( opttmp, optarg, OPTMAX - 1 ); 02361 opttmp[OPTMAX - 1] = '\0'; 02362 if ( strchr( opttmp, 'x' ) ) 02363 { 02364 field = strtok( opttmp, "x" ); 02365 xdpi = atof( field ); 02366 if ( xdpi == 0 ) 02367 fprintf( stderr, "?invalid xdpi\n" ); 02368 02369 if ( ( field = strtok( NULL, " " ) ) == NULL ) 02370 return 1; 02371 02372 ydpi = atof( field ); 02373 if ( ydpi == 0 ) 02374 fprintf( stderr, "?invalid ydpi\n" ); 02375 } 02376 else 02377 { 02378 xdpi = atof( opttmp ); 02379 ydpi = xdpi; 02380 if ( xdpi == 0 ) 02381 return 1; 02382 } 02383 02384 plspage( xdpi, ydpi, xwid, ywid, xoff, yoff ); 02385 return 0; 02386 } 02387 02388 /*--------------------------------------------------------------------------*\ 02389 * opt_dev_compression() 02390 * 02391 * Sets device compression 02392 \*--------------------------------------------------------------------------*/ 02393 02394 static int 02395 opt_dev_compression( const char *opt, const char *optarg, void *client_data ) 02396 { 02397 PLINT comp = 0; 02398 02399 comp = atoi( optarg ); 02400 if ( comp == 0 ) 02401 { 02402 fprintf( stderr, "?invalid compression\n" ); 02403 return 1; 02404 } 02405 plscompression( comp ); 02406 02407 return 0; 02408 } 02409 02410 /*--------------------------------------------------------------------------*\ 02411 * opt_cmap0() 02412 * 02413 * Sets color table 0 based on a cmap0.pal file. 02414 \*--------------------------------------------------------------------------*/ 02415 02416 static int 02417 opt_cmap0( const char *opt, const char *optarg, void *client_data ) 02418 { 02419 plspal0( optarg ); 02420 return 0; 02421 } 02422 02423 /*--------------------------------------------------------------------------*\ 02424 * opt_cmap1() 02425 * 02426 * Sets color table 1 based on a cmap1.pal file. 02427 \*--------------------------------------------------------------------------*/ 02428 02429 static int 02430 opt_cmap1( const char *opt, const char *optarg, void *client_data ) 02431 { 02432 plspal1( optarg, TRUE ); 02433 return 0; 02434 } 02435 02436 /*--------------------------------------------------------------------------*\ 02437 * opt_locale() 02438 * 02439 * Make PLplot portable to all LC_NUMERIC locales. 02440 \*--------------------------------------------------------------------------*/ 02441 02442 static int 02443 opt_locale( const char *opt, const char *optarg, void *client_data ) 02444 { 02445 char *locale; 02446 if ( locale = setlocale( LC_NUMERIC, "" ) ) 02447 { 02448 printf( "LC_NUMERIC locale set to \"%s\"\n", locale ); 02449 } 02450 else 02451 { 02452 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" ); 02453 if ( !( locale = setlocale( LC_NUMERIC, "C" ) ) ) 02454 { 02455 plexit( "Your platform is seriously broken. Not even a \"C\" locale could be set." ); 02456 } 02457 } 02458 return 0; 02459 } 02460