home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / gmt_os2.zip / src / gmt_init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-24  |  77.6 KB  |  2,040 lines

  1. /*--------------------------------------------------------------------
  2.  *    The GMT-system:    @(#)gmt_init.c    2.56  24 Jul 1995
  3.  *
  4.  *    Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
  5.  *    See README file for copying and redistribution conditions.
  6.  *--------------------------------------------------------------------*/
  7. /*                                    *
  8.  *            G M T _ I N I T . C   V.  2 . 0
  9.  *                                    *
  10.  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  11.  * gmt_init.c contains code which is used by all GMT programs
  12.  *
  13.  * Author:    Paul Wessel
  14.  * Date:    27-MAY-1991-1995
  15.  * Version:    2.0, based in part on v1.0
  16.  *
  17.  *
  18.  * The functions are:
  19.  *
  20.  *    explain_option ()      :    Prints explanations for the options below
  21.  *    get_common_args ()    :    Interprets -B -H -J -K -O -P -R -U -V -X -Y -: -c
  22.  *    get_gmtdefaults ()    :    Initializes the GMT global parameters
  23.  *    gmt_loaddefaults ()    :    Reads the GMT global parameters from .gmtdefaults
  24.  *    gmt_savedefaults ()    :    Writes the GMT global parameters to .gmtdefaults
  25.  *    gmt_setparameter ()    :    Sets a default value given keyord,value-pair
  26.  *    gmt_hash (v)           :     Hash functions
  27.  *    init_gmt_hash (v)      :          -"-
  28.  *    gmt_hash_entry (key)    :         -"-
  29.  *    get_ellipse()           :         -"-
  30.  *    gmt_begin ()           :    Gets history and init parameters
  31.  *    gmt_end ()               :    Updates history and exits
  32.  *    map_getframe ()        :    Scans the -Bstring to set tickinfo
  33.  *    map_getproject ()       :    Scans the -Jstring to set projection
  34.  *    prepare_three_D ()    :    Initialize 3-D parameters
  35.  *
  36.  */
  37.  
  38. #include "gmt.h"
  39. #include "gmt_init.h"
  40.  
  41. struct HASH hashnode[HASH_SIZE];
  42.  
  43. int use_points[3];
  44. double pen_width[3];
  45.  
  46. int explain_option (option)
  47. char option; {
  48.     /* The function print to stderr a short explanation for the option indicated by
  49.      * the variable <option>.  Only the common parameter options are covered
  50.      */
  51.      
  52.     switch (option) {
  53.     
  54.         case 'B':    /* Tickmark option */
  55.         
  56.             fprintf (stderr, "    -B specifies Boundary info.  <tickinfo> is a textstring made up of one or\n");
  57.             fprintf (stderr, "       more substrings of the form [t]<tick>[m|c].  The optional [t] can be\n");
  58.             fprintf (stderr, "       either: a for anotation interval, f for frame interval, or g for\n");
  59.             fprintf (stderr, "       gridline interval.  If the [t] is not given, a<tick> AND f<tick>\n");
  60.             fprintf (stderr, "       (but no g<tick>) are set.  The frame interval = anotation interval\n");
  61.             fprintf (stderr, "       if no separate f<tick> is given.  <tick> is the desired tick-interval.\n");
  62.             fprintf (stderr, "       The optional [m|s] indicates minutes or seconds.  To specify separate x and y tick-.\n");
  63.             fprintf (stderr, "       info, separate the strings with a slash [/].  E.g., 5 degree ticks for\n");
  64.             fprintf (stderr, "       frame AND anotation, 30 minutes grid lines, use\n");
  65.             fprintf (stderr, "            -B5g30m.   For different y ticks try -B5g30m/2g15m\n");
  66.             fprintf (stderr, "       [If -Jz is selected, use slashes to separate x, y, and z-tickinfo.]\n");
  67.             fprintf (stderr, "       Add labels by surrounding them with colons.  If first character is a\n");
  68.             fprintf (stderr, "       period, then the text is used as the plot title (e.g. :.Plot_Title:).\n");
  69.             fprintf (stderr, "       Append any combination of w, e, s, n to plot those axes\n");
  70.             fprintf (stderr, "       only [Default is all].  Append l to anotate log10 (value), p for\n");
  71.             fprintf (stderr, "       10^(log10(value)).  (See -J for log10 scaling).  For -Jx with power\n");
  72.             fprintf (stderr, "       scaling, append p to annotate value at equidistant pow increments\n");
  73.             fprintf (stderr, "       See psbasemap man pages for more details and examples.\n");
  74.             break;
  75.             
  76.         case 'b':    /* Condensed tickmark option */
  77.         
  78.             fprintf (stderr, "    -B Boundary anotation, give -B<xinfo>[/<yinfo>[/<zinfo>]][.:\"title\":][wesnzWESNZ+]\n");
  79.             fprintf (stderr, "       <?info> is 1-3 substring(s) of form [a|f|g]<tick>[m][l|p] and optionally :\"label\":\n");
  80.             fprintf (stderr, "       (See psbasemap man pages for more details and examples.)\n");
  81.             break;
  82.             
  83.         case 'H':    /* Header */
  84.         
  85.             fprintf (stderr, "    -H means input/output file has %d Header record(s) [%s]\n",
  86.                 gmtdefs.n_header_recs, gmt_choice[gmtdefs.io_header]);
  87.             fprintf (stderr, "       Optionally, append number of header records\n");
  88.             break;
  89.             
  90.         case 'J':    /* Map projection option */
  91.         
  92.             fprintf (stderr, "    -J Selects the map proJection system. (<mapwidth> is in %s)\n", gmt_unit_names[gmtdefs.measure_unit]);
  93.             
  94.             fprintf (stderr, "       -Ja<lon0><lat0><scale> OR -JA<lon0><lat0><mapwidth> (Lambert Azimuthal Equal Area)\n");
  95.             fprintf (stderr, "         lon0/lat0 is the center or the projection.\n");
  96.             fprintf (stderr, "         Scale is either <1:xxxx> or <radius>/<lat>, where <radius> distance\n");
  97.             fprintf (stderr, "         is in %s to the oblique parallel <lat>.\n", gmt_unit_names[gmtdefs.measure_unit]);
  98.             
  99.             fprintf (stderr, "       -Jb<lon0>/<lat0>/<lat1>/<lat2>/<scale> OR -JB<lon0>/<lat0>/<lat1>/<lat2>/<mapwidth> (Albers Equal-Area Conic)\n");
  100.             fprintf (stderr, "         Give origin, 2 standard parallels, and true scale in %s/degree\n",
  101.                 gmt_unit_names[gmtdefs.measure_unit]);
  102.                 
  103.             fprintf (stderr, "       -Jc<lon0>/<lat0><scale> OR -JC<lon0>/<lat0><mapwidth> (Cassini)\n");
  104.             fprintf (stderr, "         Give central point and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  105.             
  106.             fprintf (stderr, "       -Je<lon0><lat0><scale> OR -JE<lon0><lat0><mapwidth> (Azimuthal Equidistant)\n");
  107.             fprintf (stderr, "         lon0/lat0 is the center or the projection.\n");
  108.             fprintf (stderr, "         Scale is either <1:xxxx> or <radius>/<lat>, where <radius> is distance\n");
  109.             fprintf (stderr, "         in %s to the oblique parallel <lat>. \n", gmt_unit_names[gmtdefs.measure_unit]);
  110.             
  111.             fprintf (stderr, "       -Jg<lon0><lat0><scale> OR -JG<lon0><lat0><mapwidth> (Orthographic)\n");
  112.             fprintf (stderr, "         lon0/lat0 is the center or the projection.\n");
  113.             fprintf (stderr, "         Scale is either <1:xxxx> or <radius>/<lat>, where <radius> is distance\n");
  114.             fprintf (stderr, "         in %s to the oblique parallel <lat>. \n", gmt_unit_names[gmtdefs.measure_unit]);
  115.             
  116.             fprintf (stderr, "       -Jh<lon0>/<scale> OR -JH<lon0>/<mapwidth> (Hammer-Aitoff)\n");
  117.             fprintf (stderr, "         Give central meridian and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  118.             
  119.             fprintf (stderr, "       -Ji<lon0>/<scale> OR -JI<lon0>/<mapwidth> (Sinusoidal)\n");
  120.             fprintf (stderr, "         Give central meridian and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  121.  
  122.             fprintf (stderr, "       -Jk<lon0>/<scale> OR -JK<lon0>/<mapwidth> (Eckert IV)\n");
  123.             fprintf (stderr, "         Give central meridian and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  124.  
  125.             fprintf (stderr, "       -Jl<lon0>/<lat0>/<lat1>/<lat2>/<scale> OR -JL<lon0>/<lat0>/<lat1>/<lat2>/<mapwidth> (Lambert Conformal Conic)\n");
  126.             fprintf (stderr, "         Give origin, 2 standard parallels,  and true scale in %s/degree\n",
  127.                 gmt_unit_names[gmtdefs.measure_unit]);
  128.                 
  129.             fprintf (stderr, "       -Jm<scale> OR -JM<mapwidth> (Mercator projection)\n");
  130.             fprintf (stderr, "         Give true scale at Equator in %s/degree\n",
  131.                 gmt_unit_names[gmtdefs.measure_unit]);
  132.                 
  133.             fprintf (stderr, "       -Jn<lon0>/<scale> OR -JN<lon0>/<mapwidth> (Robinson projection)\n");
  134.             fprintf (stderr, "         Give central meridian and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  135.  
  136.             fprintf (stderr, "       -Jo | -JO (Oblique Mercator).  Specify one of three definitions:\n");
  137.             fprintf (stderr, "          -Joa<orig_lon>/<orig_lat>/<azimuth>/<scale> OR -JOa<orig_lon>/<orig_lat>/<azimuth>/<mapwidth>\n");
  138.             fprintf (stderr, "                  Give origin and azimuth of oblique equator\n");
  139.             fprintf (stderr, "          -Job<orig_lon>/<orig_lat>/<b_lon>/<b_lat>/<scale> OR -JOb<orig_lon>/<orig_lat>/<b_lon>/<b_lat>/<mapwidth>\n");
  140.             fprintf (stderr, "                  Give origin and second point on oblique equator\n");
  141.             fprintf (stderr, "          -Joc<orig_lon>/<orig_lat>/<pole_lon>/<pole_lat>/<scale> OR -JOc<orig_lon>/<orig_lat>/<pole_lon>/<pole_lat>/<mapwidth>\n");
  142.             fprintf (stderr, "                  Give origin and pole of projection\n");
  143.             fprintf (stderr, "            Scale is true scale at oblique equator in %s/degree\n",
  144.                 gmt_unit_names[gmtdefs.measure_unit]);
  145.             fprintf (stderr, "            Specify region in oblique degrees OR use -R<>r\n");
  146.             
  147.             fprintf (stderr, "       -Jq<lon0>/<scale> OR -JQ<lon0>/<mapwidth> (Equidistant Cylindrical)\n");
  148.             fprintf (stderr, "         Give central meridian and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  149.             
  150.             fprintf (stderr, "       -Jr<lon0>/<scale> OR -JR<lon0>/<mapwidth> (Winkel Tripel)\n");
  151.             fprintf (stderr, "         Give central meridian and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  152.  
  153.             fprintf (stderr, "       -Js<lon0><lat0><scale> OR -JS<lon0><lat0><mapwidth> (Stereographic)\n");
  154.             fprintf (stderr, "         lon0/lat0 is the center or the projection.\n");
  155.             fprintf (stderr, "         Scale is either <1:xxxx> or <radius>/<lat>, where <radius> distance\n");
  156.             fprintf (stderr, "         is in %s to the oblique parallel <lat>.\n", gmt_unit_names[gmtdefs.measure_unit]);
  157.             
  158.             fprintf (stderr, "       -Jt<lon0>/<scale> OR -JT<lon0>/<mapwidth> (Transverse Mercator)\n");
  159.             fprintf (stderr, "          Give central meridian and scale as 1:xxxx or %s/degree\n",
  160.                 gmt_unit_names[gmtdefs.measure_unit]);
  161.                 
  162.             fprintf (stderr, "       -Ju<zone>/<scale> OR -JU<zone>/<mapwidth> (UTM)\n");
  163.             fprintf (stderr, "         Give zone (negative for S hemisphere) and scale as 1:xxxx or %s/degree\n",
  164.                 gmt_unit_names[gmtdefs.measure_unit]);
  165.                 
  166.             fprintf (stderr, "       -Jw<lon0>/<scale> OR -JW<lon0>/<mapwidth> (Mollweide)\n");
  167.             fprintf (stderr, "         Give central meridian and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  168.             
  169.             fprintf (stderr, "       -Jy<lon0>/<lats>/<scale> OR -JY<lon0>/<lats>/<mapwidth> (Cylindrical Equal-area)\n");
  170.             fprintf (stderr, "         Give central meridian, standard parallel and scale as 1:xxxx or %s/degree\n", gmt_unit_names[gmtdefs.measure_unit]);
  171.             fprintf (stderr, "         <slat> = 45 (Peters), 37.4 (Trystan Edwards), 30 (Behrmann), 0 (Lambert)\n");
  172.  
  173.             fprintf (stderr, "       -Jp<scale> OR -JP<mapwidth> (Polar (theta,radius))\n");
  174.             fprintf (stderr, "         Linear scaling for polar coordinates.  Give scale in %s/units\n",
  175.                 gmt_unit_names[gmtdefs.measure_unit]);
  176.                 
  177.             fprintf (stderr, "       -Jx OR -JX for non-map projections.  Scale in %s/units.  Specify one:\n",
  178.                 gmt_unit_names[gmtdefs.measure_unit]);
  179.             fprintf (stderr, "          -Jx<x-scale>        Linear projection\n");
  180.             fprintf (stderr, "          -Jx<x-scale>l        Log10 projection\n");
  181.             fprintf (stderr, "          -Jx<x-scale>p<power>    x^power projection\n");
  182.             fprintf (stderr, "          Use / to specify separate x/y scaling (e.g., -Jx0.5/0.3.)\n");
  183.             fprintf (stderr, "          If -JX is used then give axes lengths rather than scales\n");
  184.             break;
  185.             
  186.         case 'j':    /* Condensed version of J */
  187.         
  188.             fprintf (stderr, "    -J Selects map proJection. (<scale> in %s/degree, <mapwidth> in %s)\n", gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  189.             
  190.             fprintf (stderr, "       -Ja|A<lon0><lat0><scale (or radius/lat)|mapwidth> (Lambert Azimuthal Equal Area)\n");
  191.             
  192.             fprintf (stderr, "       -Jb|B<lon0>/<lat0>/<lat1>/<lat2>/<scale|mapwidth> (Albers Equal-Area Conic)\n");
  193.             fprintf (stderr, "       -Jc|C<lon0>/<lat0><scale|mapwidth> (Cassini)\n");
  194.             
  195.             fprintf (stderr, "       -Je|E<lon0><lat0><scale (or radius/lat)|mapwidth>  (Azimuthal Equidistant)\n");
  196.             
  197.             fprintf (stderr, "       -Jg|G<lon0><lat0><scale (or radius/lat)|mapwidth>  (Orthographic)\n");
  198.             
  199.             fprintf (stderr, "       -Jh|H<lon0>/<scale|mapwidth> (Hammer-Aitoff)\n");
  200.             
  201.             fprintf (stderr, "       -Ji|I<lon0>/<scale|mapwidth> (Sinusoidal)\n");
  202.  
  203.             fprintf (stderr, "       -Jk|K<lon0>/<scale|mapwidth> (Eckert IV)\n");
  204.  
  205.             fprintf (stderr, "       -Jl|L<lon0>/<lat0>/<lat1>/<lat2>/<scale|mapwidth> (Lambert Conformal Conic)\n");
  206.                 
  207.             fprintf (stderr, "       -Jm|M<scale|mapwidth> (Mercator projection)\n");
  208.                 
  209.             fprintf (stderr, "       -Jn|N<lon0>/<scale|mapwidth> (Robinson projection)\n");
  210.  
  211.             fprintf (stderr, "       -Jo|O (Oblique Mercator).  Specify one of three definitions:\n");
  212.             fprintf (stderr, "          -Jo|Oa<orig_lon>/<orig_lat>/<azimuth>/<scale|mapwidth>\n");
  213.             fprintf (stderr, "          -Jo|Ob<orig_lon>/<orig_lat>/<b_lon>/<b_lat>/<scale|mapwidth>\n");
  214.             fprintf (stderr, "          -Jo|Oc<orig_lon>/<orig_lat>/<pole_lon>/<pole_lat>/<scale|mapwidth>\n");
  215.             
  216.             fprintf (stderr, "       -Jq|Q<lon0>/<scale|mapwidth> (Equidistant Cylindrical)\n");
  217.             
  218.             fprintf (stderr, "       -Jr|R<lon0>/<scale|mapwidth> (Winkel Tripel)\n");
  219.  
  220.             fprintf (stderr, "       -Js|S<lon0><lat0><scale (or radius/lat)|mapwidth> (Stereographic)\n");
  221.             
  222.             fprintf (stderr, "       -Jt|T<lon0>/<scale|mapwidth> (Transverse Mercator)\n");
  223.                 
  224.             fprintf (stderr, "       -Ju|U<zone>/<scale|mapwidth> (UTM)\n");
  225.                 
  226.             fprintf (stderr, "       -Jw|W<lon0>/<scale|mapwidth> (Mollweide)\n");
  227.             
  228.             fprintf (stderr, "       -Jy|Y<lon0>/<lats>/<scale|mapwidth> (Cylindrical Equal-area)\n");
  229.  
  230.             fprintf (stderr, "       -Jp|P<scale|mapwidth> (Polar (theta,radius))\n");
  231.                 
  232.             fprintf (stderr, "       -Jx|X<x-scale|mapwidth>[l|p<power>][/<y-scale|mapheight>[l|p<power>]] (Linear projections)\n");
  233.             fprintf (stderr, "       (See psbasemap for more details on projection syntax)\n");
  234.             break;
  235.             
  236.         case 'K':    /* Append-more-PostScript-later */
  237.  
  238.             fprintf (stderr, "    -K means allow for more plot code to be appended later [%s].\n",
  239.                 gmt_choice[!gmtdefs.last_page]);
  240.             break;
  241.             
  242.         case 'O':    /* Overlay plot */
  243.  
  244.             fprintf (stderr, "    -O means Overlay plot mode [%s].\n",
  245.                 gmt_choice[gmtdefs.overlay]);
  246.             break;
  247.             
  248.         case 'P':    /* Portrait or landscape */
  249.         
  250.             fprintf (stderr, "    -P means Portrait page orientation [%s].\n",
  251.                 gmt_choice[(gmtdefs.page_orientation & 1)]);
  252.             break;
  253.             
  254.         case 'R':    /* Region option */
  255.         
  256.             fprintf (stderr, "    -R specifies the min/max coordinates of data region in user units.\n");
  257.             fprintf (stderr, "       Use dd:mm[:ss] format for regions given in degrees and minutes [and seconds].\n");
  258.             fprintf (stderr, "       Append r if -R specifies the longitudes/latitudes of the lower left\n");
  259.             fprintf (stderr, "       and upper right corners of a rectangular area\n");
  260.             break;
  261.             
  262.         case 'r':    /* Region option for 3-D */
  263.         
  264.             fprintf (stderr, "    -R specifies the xyz min/max coordinates of the plot window in user units.\n");
  265.             fprintf (stderr, "       Use dd:mm[:ss] format for regions given in degrees and minutes [and seconds].\n");
  266.             fprintf (stderr, "       Append r if first 4 arguments to -R specifies the longitudes/latitudes\n");
  267.             fprintf (stderr, "       of the lower left and upper right corners of a rectangular area\n");
  268.             break;
  269.             
  270.         case 'U':    /* Plot time mark and [optionally] command line */
  271.         
  272.             fprintf (stderr, "    -U to plot Unix System Time stamp [and optionally appended text].\n");
  273.             fprintf (stderr, "       You may also set the lower left corner position of stamp [%lg/%lg].\n",
  274.                 gmtdefs.unix_time_pos[0], gmtdefs.unix_time_pos[1]);
  275.             fprintf (stderr, "       Give -Uc to have the command line plotted [%s].\n",
  276.                 gmt_choice[gmtdefs.unix_time]);
  277.             break;
  278.             
  279.         case 'V':    /* Verbose */
  280.         
  281.             fprintf (stderr, "    -V Run in verbose mode [%s].\n", gmt_choice[gmtdefs.verbose]);
  282.             break;
  283.             
  284.         case 'X':
  285.         case 'Y':    /* Reset plot origin option */
  286.         
  287.             fprintf (stderr, "    -X -Y to shift origin of plot to (<xshift>, <yshift>) [%lg,%lg].\n",
  288.                 gmtdefs.x_origin, gmtdefs.y_origin);
  289.             fprintf (stderr, "       (Note that for overlays (-O), the default is [0,0].)\n");
  290.             break;
  291.             
  292.         case 'Z':    /* Vertical scaling for 3-D plots */
  293.         
  294.             fprintf (stderr, "       -Jz for z component of 3-D projections.  Same syntax as -Jx.\n");
  295.             break;
  296.             
  297.         case 'c':    /* Set number of plot copies option */
  298.         
  299.             fprintf (stderr, "    -c specifies the number of copies [%d].\n", gmtdefs.n_copies);
  300.             break;
  301.  
  302.         case ':':    /* lon/lat or lat/lon */
  303.  
  304.             fprintf (stderr, "    -: Expect lat/lon input rather than lon/lat [%s].\n",
  305.                 gmt_choice[gmtdefs.xy_toggle]);
  306.             break;
  307.             
  308.         case '.':    /* Trailer message */
  309.         
  310.             fprintf (stderr, "    (See man page for gmtdefaults to set these and other defaults to ON or OFF)\n");
  311.             break;
  312.  
  313.         default:
  314.             break;
  315.     }
  316. }
  317.  
  318. int gmt_fill_syntax (option)
  319. char option; {
  320.     fprintf (stderr, "%s: GMT SYNTAX ERROR -%c option.  Correct syntax:\n", gmt_program, option);
  321.     fprintf (stderr, "\t-%cP|p<size>/<pattern>, size of tile (in inch), pattern from 1-32 or a filename\n", option);
  322.     fprintf (stderr, "\t-%c<red>/<green>/<blue> or -%c<gray>, all in the 0-255 range\n", option, option);
  323. }
  324.  
  325. int gmt_pen_syntax (option)
  326. char option; {
  327.     fprintf (stderr, "%s: GMT SYNTAX ERROR -%c option.  Correct syntax:\n", gmt_program, option);
  328.     fprintf (stderr, "\t-%c[<width>][/<red>/<green>/<blue> | <gray>][to | ta | t<texture>:<offset>][p]\n", option);
  329.     fprintf (stderr, "\t  <width> >= 0, <red>/<green>/<blue> or <gray> all in the 0-255 range\n");
  330. }
  331.  
  332. int gmt_rgb_syntax (option)
  333. char option; {
  334.     fprintf (stderr, "%s: GMT SYNTAX ERROR -%c option.  Correct syntax:\n", gmt_program, option);
  335.     fprintf (stderr, "\t-%c<red>/<green>/<blue> or -%c<gray>, all in the 0-255 range\n", option, option);
  336. }
  337.  
  338. int gmt_syntax (option)
  339. char option; {
  340.     /* The function print to stderr the syntax for the option indicated by
  341.      * the variable <option>.  Only the common parameter options are covered
  342.      */
  343.      
  344.     fprintf (stderr, "%s: GMT SYNTAX ERROR -%c option.  Correct syntax:\n", gmt_program, option);
  345.  
  346.     switch (option) {
  347.     
  348.         case 'B':    /* Tickmark option */
  349.         
  350.             fprintf (stderr, "\t-B[a|f|g]<tick>[m][l|p]:\"label\":[/.../...]:.\"Title\":[W|w|E|e|S|s|N|n][Z|z]\n");
  351.             break;
  352.             
  353.         case 'H':    /* Header */
  354.         
  355.             fprintf (stderr, "\t-H[n-header-records]\n");
  356.             break;
  357.             
  358.         case 'J':    /* Map projection option */
  359.         
  360.             switch (project_info.projection) {
  361.                 case LAMB_AZ_EQ:
  362.                     fprintf (stderr, "\t-Ja<lon0><lat0><scale> OR -Ja<lon0><lat0><mapwidth>\n");
  363.                     fprintf (stderr, "\t  <scale is <1:xxxx> or <radius> (in %s)/<lat>, or use <mapwidth> in %s\n",
  364.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  365.                     break;
  366.                 case ALBERS:
  367.                     fprintf (stderr, "\t-Jb<lon0>/<lat0>/<lat1>/<lat2>/<scale> OR -Jb<lon0>/<lat0>/<lat1>/<lat2>/<mapwidth>\n");
  368.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  369.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  370.                     break;
  371.                 case CASSINI:
  372.                     fprintf (stderr, "\t-Jc<lon0>/<lat0><scale> OR -JC<lon0>/<lat0><mapwidth>\n");
  373.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree ,or use <mapwidth> in %s\n",
  374.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  375.                     break;
  376.                 case ORTHO:
  377.                     fprintf (stderr, "\t-Jg<lon0><lat0><scale> OR -JG<lon0><lat0><mapwidth>\n");
  378.                     fprintf (stderr, "\t  <scale is <1:xxxx> or <radius> (in %s)/<lat>, or use <mapwidth> in %s\n",
  379.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  380.                     break;
  381.                 case HAMMER:
  382.                     fprintf (stderr, "\t-Jh<lon0>/<scale> OR -JH<lon0>/<mapwidth\n");
  383.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  384.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  385.                     break;
  386.                 case SINUSOIDAL:
  387.                     fprintf (stderr, "\t-Ji<lon0>/<scale> OR -JI<lon0>/<mapwidth>\n");
  388.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  389.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  390.                     break;
  391.                 case LAMBERT:
  392.                     fprintf (stderr, "\t-Jl<lon0>/<lat0>/<lat1>/<lat2>/<scale> OR -JL<lon0>/<lat0>/<lat1>/<lat2>/<mapwidth>\n");
  393.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  394.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  395.                     break;
  396.                 case MERCATOR:
  397.                     fprintf (stderr, "\t-Jm<scale> OR -JM<mapwidth>\n");
  398.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  399.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  400.                     break;
  401.                 case ROBINSON:
  402.                     fprintf (stderr, "\t-Jn<lon0>/<scale> OR -JN<lon0>/<mapwidth>\n");
  403.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  404.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  405.                     break;
  406.                 case OBLIQUE_MERC:
  407.                     fprintf (stderr, "\t-JOa<lon0>/<lat0>/<azimuth>/<scale> OR -JOa<lon0>/<lat0>/<azimuth>/<mapwidth>\n");
  408.                     fprintf (stderr, "\t-Job<lon0>/<lat0>/<b_lon>/<b_lat>/<scale> OR -JOb<lon0>/<lat0>/<b_lon>/<b_lat>/<mapwidth>\n");
  409.                     fprintf (stderr, "\t-Joc<lon0>/<lat0>/<lonp>/<latp>/<scale> OR -JOc<lon0>/<lat0>/<lonp>/<latp>/<mapwidth>\n");
  410.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/oblique degree, or use <mapwidth> in %s\n",
  411.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  412.                     break;
  413.                 case WINKEL:
  414.                     fprintf (stderr, "\t-Jr<lon0>/<scale> OR -JR<lon0><mapwidth>\n");
  415.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  416.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  417.                     break;
  418.                 case CYL_EQDIST:
  419.                     fprintf (stderr, "\t-Jq<lon0>/<scale> OR -JQ<lon0><mapwidth>\n");
  420.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  421.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  422.                     break;
  423.                 case STEREO:
  424.                     fprintf (stderr, "\t-Js<lon0><lat0><scale> OR -JS<lon0><lat0><mapwidth>\n"); 
  425.                     fprintf (stderr, "\t  <scale is <1:xxxx> or <radius> (in %s)/<lat>, or use <mapwidth> in %s\n",
  426.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  427.                     break;
  428.                 case TM:
  429.                     fprintf (stderr, "\t-Jt<lon0>/<scale> OR -JT<lon0>/<mapwidth>\n");
  430.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  431.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  432.                     break;
  433.                 case UTM:
  434.                     fprintf (stderr, "\t-Ju<zone>/<scale> OR -JU<zone>/<mapwidth>\n");
  435.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  436.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  437.                     break;
  438.                 case MOLLWEIDE:
  439.                     fprintf (stderr, "\t-Jw<lon0>/<scale> OR -JW<lon0>/<mapwidth>\n");
  440.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  441.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  442.                     break;
  443.                 case ECKERT:
  444.                     fprintf (stderr, "\t-Jk<lon0>/<scale> OR -JK<lon0>/<mapwidth>\n");
  445.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  446.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  447.                     break;
  448.                 case CYL_EQ:
  449.                     fprintf (stderr, "\t-Jy<lon0>/<lats>/<scale> OR -JY<lon0>/<lats>/<mapwidth>\n");
  450.                     fprintf (stderr, "\t  <scale is <1:xxxx> or %s/degree, or use <mapwidth> in %s\n",
  451.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  452.                     break;
  453.                 case POLAR:
  454.                     fprintf (stderr, "\t-Jp<scale> OR -JP<mapwidth>\n");
  455.                     fprintf (stderr, "\t  <scale is %s/units, or use <mapwidth> in %s\n",
  456.                         gmt_unit_names[gmtdefs.measure_unit], gmt_unit_names[gmtdefs.measure_unit]);
  457.                 case LINEAR:
  458.                     fprintf (stderr, "\t-Jx<x-scale>[l|p<power>][/<y-scale>[l|p<power>]], scale in %s/units\n",
  459.                         gmt_unit_names[gmtdefs.measure_unit]);
  460.                     fprintf (stderr, "\t-Jz<z-scale>[l|p<power>], scale in %s/units\n",
  461.                         gmt_unit_names[gmtdefs.measure_unit]);
  462.                     fprintf (stderr, "\tUse -JX (and/or -JZ) to give axes lengths rather than scales\n");
  463.                     break;
  464.                 default:
  465.                     fprintf (stderr, "\tProjection not recognized!\n");
  466.                     break;
  467.             }
  468.             break;
  469.     
  470.         case 'R':    /* Region option */
  471.         
  472.             fprintf (stderr, "\t-R<xmin>/<xmax>/<ymin>/<ymax>[/<zmin>/<zmax>], dd:mm format ok\n");
  473.             fprintf (stderr, "\tAppend r if giving lower left and upper right coordinates\n");
  474.             break;
  475.             
  476.         case 'U':    /* Set time stamp option */
  477.         
  478.             fprintf (stderr, "\t-U[/<dx>/<dy>/][<string> | c], c will plot command line.\n");
  479.             break;
  480.             
  481.         case 'c':    /* Set number of plot copies option */
  482.         
  483.             fprintf (stderr, "\t-c<copies>, copies is number of copies\n");
  484.             break;
  485.  
  486.         default:
  487.             break;
  488.     }
  489. }
  490.  
  491. int gmt_default_error (option)
  492. char option; {
  493.     fprintf (stderr, "%s: GMT SYNTAX ERROR:  Unrecognized option -%c\n", gmt_program, option);
  494. }
  495.  
  496. int get_common_args (item, w, e, s, n)
  497. char *item;
  498. double *w, *e, *s, *n; {
  499.     char *text, string[100];
  500.     
  501.     /* get_common_args interprets the command line for the common, unique options
  502.      * -B, -H, -J, -K, -O, -P, -R, -U, -V, -X, -Y, -c, -:, -
  503.      */
  504.      
  505.     int i, j, nn, n_slashes, error = 0;
  506.     double *p[6];
  507.     
  508.     switch (item[1]) {
  509.         case '\0':
  510.             gmt_quick = TRUE;
  511.             break;
  512.         case 'B':
  513.             error += (i = map_getframe (&item[2]));
  514.             if (i) gmt_syntax ('B');
  515.             break;
  516.         case 'H':
  517.             if (item[2]) {
  518.                 i = atoi (&item[2]);
  519.                 if (i < 0) {
  520.                     gmt_syntax ('H');
  521.                     error++;
  522.                 }
  523.                 else
  524.                     gmtdefs.n_header_recs = i;
  525.             }
  526.             gmtdefs.io_header = (gmtdefs.n_header_recs > 0);
  527.             break;
  528.         case 'J':
  529.             error += (i = map_getproject (&item[2]));
  530.             if (i) gmt_syntax ('J');
  531.             break;
  532.         case 'K':
  533.             gmtdefs.last_page = FALSE;
  534.             break;
  535.         case 'O':
  536.             gmtdefs.overlay = TRUE;
  537.             break;
  538.         case 'P':
  539.             gmtdefs.page_orientation |= 1;    /* Bit arith because eurofont bit may be set */
  540.             break;
  541.         case 'R':
  542.             p[0] = w;    p[1] = e;    p[2] = s;    p[3] = n;
  543.             p[4] = &project_info.z_bottom;    p[5] = &project_info.z_top;
  544.              if (item[strlen(item)-1] == 'r') project_info.region = FALSE; /* Rectangular box given */
  545.              project_info.region_supplied = TRUE;
  546.             
  547.             i = 0;
  548.             strcpy (string, &item[2]);
  549.             text = strtok (string, "/");
  550.             while (text) {
  551.                 *p[i] = ddmmss_to_degree (text);
  552.                 i++;
  553.                 text = strtok (CNULL, "/");
  554.             }
  555.             if ((i < 4 || i > 6) || (check_region (*p[0], *p[1], *p[2], *p[3]) || (i == 6 && *p[4] >= *p[5]))) {
  556.                 error++;
  557.                 gmt_syntax ('R');
  558.             }
  559.             break;
  560.         case 'U':
  561.             gmtdefs.unix_time = TRUE;
  562.             for (i = n_slashes = 0; item[i]; i++) if (item[i] == '/') {
  563.                 n_slashes++;
  564.                 if (n_slashes < 4) j = i;
  565.             }
  566.             if (item[2] == '/' && n_slashes == 2)    /* Gave -U/<dx>/<dy> */
  567.                 nn = sscanf (&item[3], "%lf/%lf", &gmtdefs.unix_time_pos[0], &gmtdefs.unix_time_pos[1]);
  568.             else if (item[2] == '/' && n_slashes > 2) {    /* Gave -U<dx>/<dy>/<string> */
  569.                 nn = sscanf (&item[3], "%lf/%lf", &gmtdefs.unix_time_pos[0], &gmtdefs.unix_time_pos[1]);
  570.                 strcpy (gmtdefs.unix_time_label, &item[j+1]);
  571.             }
  572.             else if (item[2] && item[2] != '/')    /* Gave -U<string> */
  573.                 strcpy (gmtdefs.unix_time_label, &item[2]);
  574.             if ((item[2] == '/' && n_slashes == 1) || (item[2] == '/' && n_slashes >= 2 && nn != 2)) {
  575.                 error++;
  576.                 gmt_syntax ('U');
  577.             }
  578.             break;
  579.         case 'V':
  580.             gmtdefs.verbose = TRUE;
  581.             break;
  582.         case 'X':
  583.         case 'x':
  584.             gmtdefs.x_origin = atof (&item[2]);
  585.             project_info.x_off_supplied = TRUE;
  586.             break;
  587.         case 'Y':
  588.         case 'y':
  589.             gmtdefs.y_origin = atof (&item[2]);
  590.             project_info.y_off_supplied = TRUE;
  591.             break;
  592.         case 'c':
  593.             i = atoi (&item[2]);
  594.             if (i < 1) {
  595.                 error++;
  596.                 gmt_syntax ('c');
  597.             }
  598.             else
  599.                 gmtdefs.n_copies = i;
  600.             break;
  601.         case ':':    /* Toggle lon/lat - lat/lon */
  602.             gmtdefs.xy_toggle = TRUE;
  603.             break;
  604.         default:    /* Should never get here, but... */
  605.             error++;
  606.             fprintf (stderr, "GMT: Warning: bad case in get_common_args\n");
  607.             break;
  608.     }
  609.     
  610.     return (error);
  611. }
  612.  
  613. double ddmmss_to_degree (text)
  614. char *text; {
  615.     int i, colons = 0;
  616.     double degree, minute, degfrac, second;
  617.  
  618.     for (i = 0; text[i]; i++) if (text[i] == ':') colons++;
  619.     if (colons == 2) {    /* dd:mm:ss format */
  620.         sscanf (text, "%lf:%lf:%lf", °ree, &minute, &second);
  621.         degfrac = degree + copysign (minute / 60.0, degree) + copysign (second / 3600.0, degree);
  622.     }
  623.     else if (colons == 1) {    /* dd:mm format */
  624.         sscanf (text, "%lf:%lf", °ree, &minute);
  625.         degfrac = degree + copysign (minute / 60.0, degree);
  626.     }
  627.     else
  628.         degfrac = atof (text);
  629.     return (degfrac);
  630. }
  631.  
  632. int gmt_loaddefaults (file)
  633. char *file; {
  634.     int i, error = 0, entry;
  635.     char line[512], keyword[40], value[80];
  636.     FILE *fp = NULL;
  637.     struct HASH *this;
  638.     
  639.     if ((fp = fopen (file, "r")) == NULL) return (-1);
  640.             
  641.     /* Set up hash table */
  642.     
  643.     init_gmt_hash (hashnode, gmt_keywords, HASH_SIZE, N_KEYS);
  644.  
  645.     while (fgets (line, 512, fp)) {
  646.         if (line[0] == '#') continue;    /* Skip comments */
  647.         sscanf (line, "%s = %s", keyword, value);
  648.         
  649.         error += gmt_setparameter (keyword, value);
  650.     }
  651.     
  652.     fclose (fp);
  653.     if (gmtdefs.want_euro_font) gmtdefs.page_orientation += 2;
  654.     if (gmtdefs.ps_heximage) gmtdefs.page_orientation += 4;
  655.     if (use_points[0]) gmtdefs.frame_pen = rint (pen_width[0] * gmtdefs.dpi / 72.0), use_points[0] = 2;
  656.     if (use_points[1]) gmtdefs.grid_pen = rint (pen_width[1] * gmtdefs.dpi / 72.0), use_points[1] = 2;
  657.     if (use_points[2]) gmtdefs.tick_pen = rint (pen_width[2] * gmtdefs.dpi / 72.0), use_points[2] = 2;
  658.  
  659.     if (error) fprintf (stderr, "GMT:  %d conversion errors in file %s!\n", error, file);
  660.     
  661.     return (0);
  662. }
  663.  
  664. int gmt_setdefaults (argc, argv)
  665. int argc;
  666. char **argv; {
  667.     int i, j, error = 0, entry;
  668.     struct HASH *this;
  669.     
  670.     /* Set up hash table */
  671.     
  672.     init_gmt_hash (hashnode, gmt_keywords, HASH_SIZE, N_KEYS);
  673.  
  674.     for (j = 1; j < argc; j += 2) error += gmt_setparameter (argv[j], argv[j+1]);
  675.  
  676.     if (gmtdefs.want_euro_font) gmtdefs.page_orientation += 2;
  677.     if (gmtdefs.ps_heximage) gmtdefs.page_orientation += 4;
  678.     if (use_points[0] == 1) gmtdefs.frame_pen = rint (pen_width[0] * gmtdefs.dpi / 72.0), use_points[0] = 2;
  679.     if (use_points[1] == 1) gmtdefs.grid_pen = rint (pen_width[1] * gmtdefs.dpi / 72.0), use_points[1] = 2;
  680.     if (use_points[2] == 1) gmtdefs.tick_pen = rint (pen_width[2] * gmtdefs.dpi / 72.0), use_points[2] = 2;
  681.     
  682.     if (error) fprintf (stderr, "gmtset:  %d conversion errors\n", error);
  683. }
  684.  
  685. int gmt_setparameter (keyword, value)
  686. char *keyword, *value; {
  687.     int i, error = FALSE;
  688.     
  689.     switch (gmt_hash_entry (keyword, hashnode, HASH_SIZE)) {
  690.         case 0:
  691.             gmtdefs.anot_min_angle = atof (value);
  692.             break;
  693.         case 1:
  694.             gmtdefs.anot_font = get_entry (value, font_name, N_FONTS);
  695.             break;
  696.         case 2:
  697.             gmtdefs.anot_font_size = atoi (value);
  698.             break;
  699.         case 3:
  700.             gmtdefs.anot_offset = atof (value);
  701.             break;
  702.         case 4:
  703.             strcpy (gmtdefs.basemap_axes, value);
  704.             for (i = 0; value[i]; i++) {
  705.                 switch (value[i]) {
  706.                     case 'W':    /* Upper case: Draw axis/ticks AND anotate */
  707.                         frame_info.side[3] = 2;
  708.                         break;
  709.                     case 'w':    /* Lower case: Draw axis/ticks only */
  710.                         frame_info.side[3] = 1;
  711.                         break;
  712.                     case 'E':
  713.                         frame_info.side[1] = 2;
  714.                         break;
  715.                     case 'e':
  716.                         frame_info.side[1] = 1;
  717.                         break;
  718.                     case 'S':
  719.                         frame_info.side[0] = 2;
  720.                         break;
  721.                     case 's':
  722.                         frame_info.side[0] = 1;
  723.                         break;
  724.                     case 'N':
  725.                         frame_info.side[2] = 2;
  726.                         break;
  727.                     case 'n':
  728.                         frame_info.side[2] = 1;
  729.                         break;
  730.                     default:
  731.                         error = TRUE;
  732.                         fprintf (stderr, "%s: GMT SYNTAX ERROR in gmt_setparameter:  Unrecognized modifier for %s: %c\n", gmt_program, keyword, value[i]);
  733.                         break;
  734.                 }
  735.             }
  736.             break;
  737.         case 5:
  738.             sscanf (value, "%d/%d/%d", &gmtdefs.basemap_frame_rgb[0],
  739.                 &gmtdefs.basemap_frame_rgb[1],  &gmtdefs.basemap_frame_rgb[2]);
  740.             break;
  741.         case 6:
  742.             gmtdefs.basemap_type = (strcmp (value, "PLAIN")) ? 0 : 1;
  743.             break;
  744.         case 7:
  745.             sscanf (value, "%d/%d/%d", &gmtdefs.background_rgb[0],
  746.                 &gmtdefs.background_rgb[1],  &gmtdefs.background_rgb[2]);
  747.             break;
  748.         case 8:
  749.             sscanf (value, "%d/%d/%d", &gmtdefs.foreground_rgb[0],
  750.                 &gmtdefs.foreground_rgb[1],  &gmtdefs.foreground_rgb[2]);
  751.             break;
  752.         case 9:
  753.             sscanf (value, "%d/%d/%d", &gmtdefs.nan_rgb[0],
  754.                 &gmtdefs.nan_rgb[1],  &gmtdefs.nan_rgb[2]);
  755.             break;
  756.         case 10:
  757.             if (!strcmp (value, "ADOBE"))
  758.                 gmtdefs.color_image = 0;
  759.             else if (!strcmp (value, "TILES"))
  760.                 gmtdefs.color_image = 1;
  761.             else if (!strcmp (value, "SEPARATION"))
  762.                 gmtdefs.color_image = 2;
  763.             else
  764.                 error = TRUE;
  765.             break;
  766.         case 11:
  767.             gmtdefs.color_model = (!strcmp (value, "HSV")) ? 1 : 0;
  768.             break;
  769.         case 12:
  770.             strcpy (gmtdefs.d_format, value);
  771.             break;
  772.         case 13:
  773.             gmtdefs.degree_format = atoi (value);
  774.             break;
  775.         case 14:
  776.             gmtdefs.dpi = atoi (value);
  777.             break;
  778.         case 15:
  779.             gmtdefs.ellipsoid = get_ellipse (value);
  780.             break;
  781.         case 16:
  782.             if (value[strlen(value)-1] == 'p') {
  783.                 use_points[0] = 1;
  784.                 pen_width[0] = atof (value);
  785.             }
  786.             else {
  787.                 use_points[0] = 0;
  788.                 gmtdefs.frame_pen = atoi (value);
  789.             }
  790.             break;
  791.         case 17:
  792.             gmtdefs.frame_width = atof (value);
  793.             break;
  794.         case 18:
  795.             gmtdefs.global_x_scale = atof (value);
  796.             break;
  797.         case 19:
  798.             gmtdefs.global_y_scale = atof (value);
  799.             break;
  800.         case 20:
  801.             gmtdefs.grid_cross_size = atof (value);
  802.             break;
  803.         case 21:
  804.             if (value[strlen(value)-1] == 'p') {
  805.                 use_points[1] = 1;
  806.                 pen_width[1] = atof (value);
  807.             }
  808.             else {
  809.                 use_points[1] = 0;
  810.                 gmtdefs.grid_pen = atoi (value);
  811.             }
  812.             break;
  813.         case 22:
  814.             gmtdefs.header_font = get_entry (value, font_name, N_FONTS);
  815.             break;
  816.         case 23:
  817.             gmtdefs.header_font_size = atoi (value);
  818.             break;
  819.         case 24:
  820.             gmtdefs.hsv_min_saturation = atof (value);
  821.             break;
  822.         case 25:
  823.             gmtdefs.hsv_max_saturation = atof (value);
  824.             break;
  825.         case 26:
  826.             gmtdefs.hsv_min_value = atof (value);
  827.             break;
  828.         case 27:
  829.             gmtdefs.hsv_max_value = atof (value);
  830.             break;
  831.         case 28:
  832.             if (!strcmp (value, "LINEAR"))
  833.                 gmtdefs.interpolant = 0;
  834.             else if (!strcmp (value, "AKIMA"))
  835.                 gmtdefs.interpolant = 1;
  836.             else if (!strcmp (value, "CUBIC"))
  837.                 gmtdefs.interpolant = 2;
  838.             else
  839.                 error = TRUE;
  840.             break;
  841.         case 29:
  842.             gmtdefs.io_header = (strcmp (value, "TRUE")) ? 0 : 1;
  843.             break;
  844.         case 30:
  845.             gmtdefs.n_header_recs = atoi (value);
  846.             break;
  847.         case 31:
  848.             gmtdefs.label_font = get_entry (value, font_name, N_FONTS);
  849.             break;
  850.         case 32:
  851.             gmtdefs.label_font_size = atoi (value);
  852.             break;
  853.         case 33:
  854.             if ((gmtdefs.line_step = atof (value)) <= 0.0) {
  855. #ifdef SI
  856.                 gmtdefs.line_step = 0.25;
  857. #else
  858.                 gmtdefs.line_step = 0.1;
  859. #endif
  860.                 fprintf (stderr, "%s: GMT WARNING in gmt_setparameter: %s given as 0, reset to %lg\n", 
  861.                 gmt_program, keyword, gmtdefs.line_step);
  862.             }
  863.             break;
  864.         case 34:
  865.             gmtdefs.map_scale_factor = atof (value);
  866.             break;
  867.         case 35:
  868.             if (!(strcmp (value, "CM") && strcmp (value, "cm"))) 
  869.                 gmtdefs.measure_unit = 0;
  870.             else if (!(strcmp (value, "INCH") && strcmp (value, "inch"))) 
  871.                 gmtdefs.measure_unit = 1;
  872.             else if (!(strcmp (value, "M") && strcmp (value, "m"))) 
  873.                 gmtdefs.measure_unit = 2;
  874.             else
  875. #ifdef SI
  876.                 gmtdefs.measure_unit = 0;    /* Let cm be default */
  877. #else
  878.                 gmtdefs.measure_unit = 1;    /* Let inch be default */
  879. #endif
  880.             break;
  881.         case 36:
  882.             gmtdefs.n_copies = atoi (value);
  883.             break;
  884.         case 37:
  885.             gmtdefs.oblique_anotation = atoi (value);
  886.             break;
  887.         case 38:
  888.             sscanf (value, "%d/%d/%d", &gmtdefs.page_rgb[0],
  889.                 &gmtdefs.page_rgb[1],  &gmtdefs.page_rgb[2]);
  890.             break;
  891.         case 39:
  892.             gmtdefs.page_orientation = (value[0] == 'L' || value[0] == 'l') ? 0 : 1;
  893.             break;
  894.         case 40:
  895.             gmtdefs.paper_width = atof (value);
  896.             break;
  897.         case 41:
  898.             gmtdefs.ps_heximage = (strcmp (value, "HEX")) ? 0 : 1;
  899.             break;
  900.         case 42:
  901.             gmtdefs.tick_length = atof (value);
  902.             break;
  903.         case 43:
  904.             if (value[strlen(value)-1] == 'p') {
  905.                 use_points[2] = 1;
  906.                 pen_width[2] = atof (value);
  907.             }
  908.             else {
  909.                 use_points[2] = 0;
  910.                 gmtdefs.tick_pen = atoi (value);
  911.             }
  912.             break;
  913.         case 44:
  914.             gmtdefs.unix_time = (strcmp (value, "TRUE")) ? 0 : 1;
  915.             break;
  916.         case 45:
  917.             sscanf (value, "%lf/%lf", &gmtdefs.unix_time_pos[0], &gmtdefs.unix_time_pos[1]);
  918.             break;
  919.         case 46:
  920.             gmtdefs.vector_shape = atof (value);
  921.             break;
  922.         case 47:
  923.             gmtdefs.verbose = (strcmp (value, "TRUE")) ? 0 : 1;
  924.             break;
  925.         case 48:
  926.             gmtdefs.want_euro_font = (strcmp (value, "TRUE")) ? 0 : 1;
  927.             break;
  928.         case 49:
  929.             gmtdefs.x_axis_length = atof (value);
  930.             break;
  931.         case 50:
  932.             gmtdefs.y_axis_length = atof (value);
  933.             break;
  934.         case 51:
  935.             gmtdefs.x_origin = atof (value);
  936.             break;
  937.         case 52:
  938.             gmtdefs.y_origin = atof (value);
  939.             break;
  940.         case 53:
  941.             gmtdefs.xy_toggle = (strcmp (value, "TRUE")) ? 0 : 1;
  942.             break;
  943.         case 54:
  944.             gmtdefs.y_axis_type = (strcmp (value, "VER_TEXT")) ? 0 : 1;
  945.             break;
  946.         default:
  947.             error = TRUE;
  948.             fprintf (stderr, "%s: GMT SYNTAX ERROR in gmt_setparameter:  Unrecognized keyword %s\n", 
  949.                 gmt_program, keyword);
  950.             break;
  951.     }
  952.     
  953.     return (error);
  954. }
  955.  
  956. int gmt_savedefaults (file)
  957. char *file; {
  958.     FILE *fp;
  959.     double pen;
  960.     
  961.     if (!file)
  962.         fp = stdout;
  963.     else if ((fp = fopen (file, "w")) == NULL) {
  964.         fprintf (stderr, "GMT: Could not create file %s\n", file);
  965.         return (-1);
  966.     }
  967.     
  968.     fprintf (fp, "#\n#    GMT-SYSTEM %s Default file\n#\n", GMT_VERSION);
  969.     fprintf (fp, "ANOT_MIN_ANGLE        = %lg\n", gmtdefs.anot_min_angle);
  970.     fprintf (fp, "ANOT_FONT        = %s\n", font_name[gmtdefs.anot_font]);
  971.     fprintf (fp, "ANOT_FONT_SIZE        = %d\n", gmtdefs.anot_font_size);
  972.     fprintf (fp, "ANOT_OFFSET        = %lg\n", gmtdefs.anot_offset);
  973.     fprintf (fp, "BASEMAP_AXES        = %s\n", gmtdefs.basemap_axes);
  974.     fprintf (fp, "BASEMAP_FRAME_RGB    = %d/%d/%d\n", gmtdefs.basemap_frame_rgb[0],
  975.         gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
  976.     (gmtdefs.basemap_type) ? fprintf (fp, "BASEMAP_TYPE        = PLAIN\n") : fprintf (fp, "BASEMAP_TYPE        = FANCY\n");
  977.     fprintf (fp, "COLOR_BACKGROUND    = %d/%d/%d\n", gmtdefs.background_rgb[0], gmtdefs.background_rgb[1], gmtdefs.background_rgb[2]);
  978.     fprintf (fp, "COLOR_FOREGROUND    = %d/%d/%d\n", gmtdefs.foreground_rgb[0], gmtdefs.foreground_rgb[1], gmtdefs.foreground_rgb[2]);
  979.     fprintf (fp, "COLOR_NAN        = %d/%d/%d\n", gmtdefs.nan_rgb[0], gmtdefs.nan_rgb[1], gmtdefs.nan_rgb[2]);
  980.     fprintf (fp, "COLOR_IMAGE        = ");
  981.     if (gmtdefs.color_image == 0)
  982.         fprintf (fp, "ADOBE\n");
  983.     else if (gmtdefs.color_image == 1)
  984.         fprintf (fp, "TILES\n");
  985.     else if (gmtdefs.color_image == 2)
  986.         fprintf (fp, "SEPARATION\n");
  987.     (gmtdefs.color_model) ? fprintf (fp, "COLOR_MODEL        = HSV\n") : fprintf (fp, "COLOR_MODEL        = RGB\n");
  988.     fprintf (fp, "D_FORMAT        = %s\n", gmtdefs.d_format);
  989.     fprintf (fp, "DEGREE_FORMAT        = %d\n", gmtdefs.degree_format);
  990.     fprintf (fp, "DOTS_PR_INCH        = %d\n", gmtdefs.dpi);
  991.     fprintf (fp, "ELLIPSOID        = %s\n", gmtdefs.ellipse[gmtdefs.ellipsoid].name);
  992.     if (use_points[0] == 2)
  993.         fprintf (fp, "FRAME_PEN        = %.2lfp\n", pen_width[0]);
  994.     else
  995.         fprintf (fp, "FRAME_PEN        = %d\n", gmtdefs.frame_pen);
  996.     fprintf (fp, "FRAME_WIDTH        = %lg\n", gmtdefs.frame_width);
  997.     fprintf (fp, "GLOBAL_X_SCALE        = %lg\n", gmtdefs.global_x_scale);
  998.     fprintf (fp, "GLOBAL_Y_SCALE        = %lg\n", gmtdefs.global_y_scale);
  999.     fprintf (fp, "GRID_CROSS_SIZE        = %lg\n", gmtdefs.grid_cross_size);
  1000.     if (use_points[1] == 2)
  1001.         fprintf (fp, "GRID_PEN        = %.2lfp\n", pen_width[1]);
  1002.     else
  1003.         fprintf (fp, "GRID_PEN        = %d\n", gmtdefs.grid_pen);
  1004.     fprintf (fp, "HEADER_FONT        = %s\n", font_name[gmtdefs.header_font]);
  1005.     fprintf (fp, "HEADER_FONT_SIZE    = %d\n", gmtdefs.header_font_size);
  1006.     fprintf (fp, "HSV_MIN_SATURATION    = %lg\n", gmtdefs.hsv_min_saturation);
  1007.     fprintf (fp, "HSV_MAX_SATURATION    = %lg\n", gmtdefs.hsv_max_saturation);
  1008.     fprintf (fp, "HSV_MIN_VALUE        = %lg\n", gmtdefs.hsv_min_value);
  1009.     fprintf (fp, "HSV_MAX_VALUE        = %lg\n", gmtdefs.hsv_max_value);
  1010.     fprintf (fp, "INTERPOLANT        = ");
  1011.     if (gmtdefs.interpolant == 0)
  1012.         fprintf (fp, "LINEAR\n");
  1013.     else if (gmtdefs.interpolant == 1)
  1014.         fprintf (fp, "AKIMA\n");
  1015.     else if (gmtdefs.interpolant == 2)
  1016.         fprintf (fp, "CUBIC\n");
  1017.     (gmtdefs.io_header) ? fprintf (fp, "IO_HEADER        = TRUE\n") : fprintf (fp, "IO_HEADER        = FALSE\n");
  1018.     fprintf (fp, "N_HEADER_RECS        = %d\n", gmtdefs.n_header_recs);
  1019.     fprintf (fp, "LABEL_FONT        = %s\n", font_name[gmtdefs.label_font]);
  1020.     fprintf (fp, "LABEL_FONT_SIZE        = %d\n", gmtdefs.label_font_size);
  1021.     fprintf (fp, "LINE_STEP        = %lg\n", gmtdefs.line_step);
  1022.     fprintf (fp, "MAP_SCALE_FACTOR    = %lg\n", gmtdefs.map_scale_factor);
  1023.     fprintf (fp, "MEASURE_UNIT        = %s\n", gmt_unit_names[gmtdefs.measure_unit]);
  1024.     fprintf (fp, "N_COPIES        = %d\n", gmtdefs.n_copies);
  1025.     fprintf (fp, "OBLIQUE_ANOTATION    = %d\n", gmtdefs.oblique_anotation);
  1026.     fprintf (fp, "PAGE_COLOR        = %d/%d/%d\n", gmtdefs.page_rgb[0], gmtdefs.page_rgb[1], gmtdefs.page_rgb[2]);
  1027.     (gmtdefs.page_orientation & 1) ? fprintf (fp, "PAGE_ORIENTATION    = PORTRAIT\n") : fprintf (fp, "PAGE_ORIENTATION    = LANDSCAPE\n");
  1028.     fprintf (fp, "PAPER_WIDTH        = %lg\n", gmtdefs.paper_width);
  1029.     (gmtdefs.ps_heximage) ? fprintf (fp, "PSIMAGE_FORMAT        = HEX\n") : fprintf (fp, "PSIMAGE_FORMAT        = BIN\n");
  1030.     fprintf (fp, "TICK_LENGTH        = %lg\n", gmtdefs.tick_length);
  1031.     if (use_points[2] == 2)
  1032.         fprintf (fp, "TICK_PEN        = %.2lfp\n", pen_width[2]);
  1033.     else
  1034.         fprintf (fp, "TICK_PEN        = %d\n", gmtdefs.tick_pen);
  1035.     (gmtdefs.unix_time) ? fprintf (fp, "UNIX_TIME        = TRUE\n") : fprintf (fp, "UNIX_TIME        = FALSE\n");
  1036.     fprintf (fp, "UNIX_TIME_POS        = %lg/%lg\n", gmtdefs.unix_time_pos[0], gmtdefs.unix_time_pos[1]);
  1037.     fprintf (fp, "VECTOR_SHAPE        = %lg\n", gmtdefs.vector_shape);
  1038.     (gmtdefs.verbose) ? fprintf (fp, "VERBOSE            = TRUE\n") : fprintf (fp, "VERBOSE            = FALSE\n");
  1039.     (gmtdefs.want_euro_font) ? fprintf (fp, "WANT_EURO_FONT        = TRUE\n") : fprintf (fp, "WANT_EURO_FONT        = FALSE\n");
  1040.     fprintf (fp, "X_AXIS_LENGTH        = %lg\n", gmtdefs.x_axis_length);
  1041.     fprintf (fp, "Y_AXIS_LENGTH        = %lg\n", gmtdefs.y_axis_length);
  1042.     fprintf (fp, "X_ORIGIN        = %lg\n", gmtdefs.x_origin);
  1043.     fprintf (fp, "Y_ORIGIN        = %lg\n", gmtdefs.y_origin);
  1044.     (gmtdefs.xy_toggle) ? fprintf (fp, "XY_TOGGLE    = TRUE\n") : fprintf (fp, "XY_TOGGLE        = FALSE\n");
  1045.     (gmtdefs.y_axis_type == 1) ? fprintf (fp, "Y_AXIS_TYPE        = VER_TEXT\n") : fprintf (fp, "Y_AXIS_TYPE        = HOR_TEXT\n");
  1046.  
  1047.     if (fp != stdout) fclose (fp);
  1048.     
  1049.     return (0);
  1050. }
  1051.  
  1052. int get_gmtdefaults (this_file)    /* Read user's .gmtdefaults file and initialize parameters */
  1053. char *this_file; {
  1054.     int i;
  1055.     char file[512], *homedir;
  1056. /*         static char home [] = "HOME";    */
  1057. /* Environmental variable "GMTDIR" must be set to point to the
  1058.  * directory where the file ".gmtdefaults" is stored (including drive letter)   */
  1059.    static char home [] = "GMTDIR";
  1060.     
  1061.      /* Default is to draw AND annotate all sides */
  1062.     for (i = 0; i < 5; i++) frame_info.side[i] = 2;
  1063.     
  1064.     if (!this_file) {    /* Must figure out which file to use */
  1065.     
  1066.         /* First see if a .gmtdefaults file is present in the current directory */
  1067.     
  1068.         if (!access (".gmtdefaults", R_OK)) /* Use cwd */
  1069.             strcpy (file, ".gmtdefaults");
  1070.         else { /* Then look in home directory */
  1071.     
  1072.             if ((homedir = getenv (home)) == NULL) {
  1073.                 fprintf (stderr, "GMT Warning: Could not determine home directory!\n");
  1074.                 return;
  1075.             }
  1076.             sprintf (file, "%s/.gmtdefaults\0", homedir);
  1077.             if (access (file, R_OK)) {    /* No defaults file present, use GMT defaults*/
  1078.                 if (gmtdefs.want_euro_font) gmtdefs.page_orientation += 2;
  1079.                 if (gmtdefs.ps_heximage) gmtdefs.page_orientation += 4;
  1080.                 return;
  1081.             }
  1082.         }
  1083.     }
  1084.     else
  1085.         strcpy (file, this_file);
  1086.     
  1087.     gmt_loaddefaults (file);
  1088.     
  1089.     /* dpi is ALWAYS in dots per inch, so adjust if CM or M is used as unit */
  1090.     
  1091.     if (gmtdefs.measure_unit == 0) gmtdefs.dpi /= 2.54;
  1092.     if (gmtdefs.measure_unit == 2) gmtdefs.dpi /= 0.0254;
  1093. }
  1094.  
  1095. int gmt_hash (v)
  1096. char *v; {
  1097.     int h;
  1098.     for (h = 0; *v != '\0'; v++) h = (64 * h + (*v)) % HASH_SIZE;
  1099.     return (h);
  1100. }
  1101.  
  1102. int gmt_hash_entry (key, hashnode, n)
  1103. char *key;
  1104. struct HASH hashnode[];
  1105. int n; {
  1106.     int i;
  1107.     struct HASH *this;
  1108.     
  1109.     i = gmt_hash (key);
  1110.     
  1111.     if (i >= n || i < 0 || !hashnode[i].next) return (-1);    /* Bad key */
  1112.     this = hashnode[i].next;
  1113.     while (this && strcmp (this->key, key)) this = this->next;
  1114.     
  1115.     return ((this) ? this->id : -1);
  1116. }
  1117.  
  1118. int init_gmt_hash (hashnode, keys, n_hash, n_keys)
  1119. struct HASH hashnode[];
  1120. char *keys[];
  1121. int n_hash, n_keys; {
  1122.     int i, entry;
  1123.     struct HASH *this;
  1124.  
  1125.     /* Set up hash table */
  1126.     
  1127.     for (i = 0; i < n_hash; i++) hashnode[i].next = (struct HASH *)0;
  1128.     for (i = 0; i < n_keys; i++) {
  1129.         entry = gmt_hash (keys[i]);
  1130.         this = &hashnode[entry];
  1131.         while (this->next) this = this->next;
  1132.         this->next = (struct HASH *)memory (CNULL, 1, sizeof (struct HASH), gmt_program);
  1133.         this->next->key = keys[i];
  1134.         this->next->id = i;
  1135.     }
  1136. }
  1137.  
  1138. int get_ellipse (name)
  1139. char *name; {
  1140.     int i;
  1141.     
  1142.     for (i = 0; i < N_ELLIPSOIDS && strcmp (name, gmtdefs.ellipse[i].name); i++);
  1143.     if (i == N_ELLIPSOIDS) {    /* Try to open as file */
  1144.         FILE *fp;
  1145.         char line[512];
  1146.             
  1147.         if ((fp = fopen (name, "r")) == NULL)
  1148.             i = 0;    /* Default is GRS-80 */
  1149.         else {    /* Found file, now get parameters */
  1150.             i = N_ELLIPSOIDS - 1;
  1151.             fgets (line, 512, fp);
  1152.             fclose (fp);
  1153.             sscanf (line, "%s %d %lf %lf %lf", gmtdefs.ellipse[i].name, 
  1154.                 &gmtdefs.ellipse[i].date, &gmtdefs.ellipse[i].eq_radius,
  1155.                 &gmtdefs.ellipse[i].pol_radius, &gmtdefs.ellipse[i].flattening);
  1156.         }
  1157.     }
  1158.             
  1159.     return (i);
  1160. }
  1161.  
  1162. int get_entry (name, list, n)
  1163. char *name, *list[];
  1164. int n; {
  1165.     int i;
  1166.     
  1167.     for (i = 0; i < n && strcmp (name, list[i]); i++);
  1168.     return (i);
  1169. }
  1170.  
  1171. int gmt_begin (argc, argv)
  1172. int argc;
  1173. char **argv; {
  1174.     /* gmt_begin will merge the command line arguments with the arguments
  1175.      * that were used the last time this programs was called (if any).  This
  1176.      * way one only have to give -R -J to repeat previous map projection instead
  1177.      * of spelling out the wesn and projection parameters every time.
  1178.      * The information is stored in the first line of the file .gmtcommands
  1179.      * in the current directory [or optionally a provided filename] and will
  1180.      * contain the last arguments to the common parameters like
  1181.      * -B, -H, -J, -K, -O, -P, -R, -U, -V, -X, -Y, -c
  1182.      * Since the meaning of -X/-Y depends on weather we have an overlay or not
  1183.      * we maintain -X -Y for absolute shifts and -x -y for relative shifts.
  1184.      * If the argument +file is encountered then file is used in lieu of the
  1185.      * usual .gmtdefaults file and this argument is chopped from argv
  1186.      */
  1187.        
  1188.     int found = FALSE, need_xy = FALSE, overlay = FALSE;
  1189.     int i, j;
  1190.     char line[512], *this = CNULL;
  1191.     FILE *fp = NULL;
  1192.  
  1193.     /* Initialize parameters */
  1194.     
  1195.     mknan (gmt_NaN);
  1196.     oldargc = 0;
  1197.     frame_info.plot = FALSE;
  1198.     project_info.projection = -1;
  1199.     project_info.gave_map_width = FALSE;
  1200.     project_info.region = TRUE;
  1201.     project_info.compute_scale[0] =  project_info.compute_scale[1] = project_info.compute_scale[2] = FALSE;
  1202.     project_info.x_off_supplied = project_info.y_off_supplied = FALSE;
  1203.     project_info.region_supplied = FALSE;
  1204.     for (j = 0; j < 10; j++) project_info.pars[j] = 0.0;
  1205.     project_info.xmin = project_info.ymin = 0.0;
  1206.     project_info.z_level = MAXDOUBLE;    /* Will be set in map_setup */
  1207.     project_info.xyz_pos[0] = project_info.xyz_pos[1] = TRUE;
  1208.     prepare_three_D ();
  1209.     gmtdefs.dlon = (project_info.e - project_info.w) / gmtdefs.n_lon_nodes;
  1210.     gmtdefs.dlat = (project_info.n - project_info.s) / gmtdefs.n_lat_nodes;
  1211.     for (i = 0; i < 4; i++) project_info.edge[i] = TRUE;
  1212.     grdio_init ();
  1213.     for (i = 0; i < N_UNIQUE; i++) oldargv[i] = CNULL;
  1214.     gmt_program = argv[0];
  1215.     gmt_input = ascii_input;
  1216.     gmt_output = ascii_output;
  1217.     grd_in_nan_value = grd_out_nan_value = gmt_NaN;
  1218.     use_points[0] = use_points[1] = use_points[2] = 0;
  1219.     
  1220.     /* Set the gmtdefault parameters from the $HOME/.gmtdefaults (if any) */
  1221.     
  1222.         /* See if user specified +optional_defaults_file */
  1223.         
  1224.     for (i = j = 1; i < argc; i++) {
  1225.         argv[j] = argv[i];
  1226.         if (argv[j][0] == '+' && argv[i][1])
  1227.             this = &argv[i][1];
  1228.         else
  1229.             j++;
  1230.     }
  1231.     argc = j;
  1232.  
  1233.     get_gmtdefaults(this);
  1234.     
  1235.     /* Open .gmtcommands file and retrive old argv (if any) */
  1236.  
  1237.     if ((fp = fopen (".gmtcommands", "r")) == NULL) return (argc);     /* No .gmtcommands file in current directory */
  1238.       
  1239.     /* Get the common arguments and copy them to array oldargv */
  1240.       
  1241.     while (fgets (line, 512, fp)) {
  1242.         if (line[0] == '#') continue;    /* Skip comments */
  1243.         if (line[0] != '-') continue;    /* Possibly reading old .gmtcommands format */
  1244.         line[strlen(line)-1] = 0;
  1245.         oldargv[oldargc] = (char *) memory (CNULL, strlen (line) + 1, 1, "GMT");
  1246.         strcpy (oldargv[oldargc], line);
  1247.         oldargc++;
  1248.         if (oldargc > N_UNIQUE) {
  1249.             fprintf (stderr, "GMT Fatal Error: Failed while decoding common arguments\n");
  1250.             exit (-1);
  1251.         }
  1252.     }
  1253.     fclose (fp);
  1254.                     
  1255.     /* See if (1) We need abs/rel shift and (2) if we have an overlay */
  1256.       
  1257.     for (i = 1; i < argc; i++) {
  1258.         if (argv[i][0] != '-') continue;
  1259.         if (argv[i][1] == 'X' || argv[i][1] == 'Y' || argv[i][1] == 'x' || argv[i][1] == 'y') need_xy = TRUE;
  1260.         if (argv[i][1] == 'O' || argv[i][1] == 'o') overlay = TRUE;
  1261.     }
  1262.       
  1263.     overlay = (need_xy && overlay); /* -O means overlay only if -X or -Y has been specified */
  1264.       
  1265.     /* Change x/y to upper case if no overlay and change X/Y to lower case if overlay */
  1266.  
  1267.     for (i = 1; i < argc; i++) {
  1268.         if (argv[i][0] != '-') continue;
  1269.         if (overlay) {
  1270.             if (argv[i][1] == 'X') argv[i][1] = 'x';
  1271.             if (argv[i][1] == 'Y') argv[i][1] = 'y';
  1272.         }
  1273.         else {
  1274.             if (argv[i][1] == 'x') argv[i][1] = 'X';
  1275.             if (argv[i][1] == 'y') argv[i][1] = 'Y';
  1276.         }
  1277.     }
  1278.  
  1279.     /* Loop over argv and merge argv and oldargv */
  1280.       
  1281.     for (i = 1; i < argc; i++) {
  1282.  
  1283.         /* Skip if filename or option has modifiers */
  1284.               
  1285.         if (argv[i][0] != '-') continue;
  1286.         if (argv[i][1] != 'J' && argv[i][2] != 0) continue;
  1287.         if (argv[i][1] == 'J' && argv[i][3] != 0) continue;
  1288.  
  1289.         for (j = 0, found = FALSE; !found && j < oldargc; j++) {
  1290.             if (argv[i][1] == 'J')
  1291.                 found = (oldargv[j][1] == argv[i][1] && oldargv[j][2] == argv[i][2]);
  1292.             else
  1293.                 found = (oldargv[j][1] == argv[i][1]);
  1294.         }
  1295.         j--;
  1296.                               
  1297.         /* Skip if not found or oldargv has no modifiers */
  1298.               
  1299.         if (!found) continue;
  1300.         if (argv[i][1] != 'J' && oldargv[j][2] == 0) continue;
  1301.         if (argv[i][1] == 'J' && oldargv[j][3] == 0) continue;
  1302.       
  1303.         /* Here, oldargv has modifiers and argv dont, set pointer */
  1304.               
  1305.         argv[i] = oldargv[j];
  1306.     }
  1307.     return (argc);
  1308. }
  1309.       
  1310. int gmt_end (argc, argv)
  1311. int argc;
  1312. char **argv; {
  1313.     /* gmt_end will update (or create) the specified projectfile OR .gmtcommands
  1314.      * file and write out the common parameters.
  1315.      */
  1316.        
  1317.     int i, j, k, found_new, found_old;
  1318.     char hfile[512];
  1319.     FILE *fp_new = NULL;
  1320.  
  1321.     hfile[0] = 0;
  1322.     for (i = 1; i < argc; i++) {
  1323.         if (argv[i][0] == '+' && argv[i][1]) strcpy (hfile, &argv[i][1]);    /* Alternate commands file */
  1324.     }
  1325.         
  1326.     if (hfile[0] == 0) strcpy (hfile, ".gmtcommands");
  1327.  
  1328.     if ((fp_new = fopen (hfile, "w")) == NULL) {
  1329.         fprintf (stderr, "GMT Fatal Error: Could not update .gmtcommands file\n");
  1330.         exit (-1);
  1331.     }
  1332.     
  1333.     fprintf (fp_new, "# GMT common arguments shelf\n");
  1334.  
  1335.     for (i = 0; i < N_UNIQUE; i++) {        /* Loop over unique_option parameters */
  1336.  
  1337.         /* First see if an updated value exist for this common parameter */
  1338.  
  1339.         for (j = 1, found_new = FALSE; !found_new && j < argc; j++) {
  1340.             if (unique_option[i][0] == 'J') /* Range of -J? options */
  1341.                 found_new = !strncmp (&argv[j][1], unique_option[i], 2);
  1342.             else
  1343.                 found_new = (argv[j][1] == unique_option[i][0]);
  1344.         }
  1345.  
  1346.         if (found_new) { /* Need to store this updated value */
  1347.             fprintf (fp_new, "%s\n", argv[j-1]);
  1348.         }
  1349.         else  {         /* Need to find and store the old value if any */
  1350.             for (k = 0, found_old = FALSE; !found_old && k < oldargc; k++) {
  1351.                 if (unique_option[i][0] == 'J') /* Range of -J? options */
  1352.                     found_old = !strncmp (&oldargv[k][1], unique_option[i], 2);
  1353.                 else
  1354.                     found_old = (oldargv[k][1] == unique_option[i][0]);
  1355.             }
  1356.  
  1357.             if (found_old)  /* Keep old value */
  1358.                 fprintf (fp_new, "%s\n", oldargv[k-1]);
  1359.         }
  1360.     }
  1361.     fclose (fp_new);
  1362.  
  1363.     for (i = 0; i < N_UNIQUE; i++) if (oldargv[i]) free (oldargv[i]);
  1364.     if (gmt_lut) free ((char *)gmt_lut);
  1365.     free_plot_array ();
  1366.  
  1367.     exit (0);
  1368. }
  1369.  
  1370. int map_getframe (args)
  1371. char *args; {
  1372.     /* map_getframe scans an argument string and extract parameters that
  1373.      * set the interval for  tickmars and anotations on the boundary.
  1374.      * The string must be continous, i.e. no whitespace must be present
  1375.      * The string may have 1, 2,  or 3 parts, separated by a slash '/'. All
  1376.      * info after the first slash are assigned to the y-axis.  Info after
  1377.      * the second slash are assigned to the z-axis.  If there is no
  1378.      * slash, x-values are copied to y-values.
  1379.      * A substring looks like [t][value][m|c]. The [t] and [m|c] are optional
  1380.      * ([ and ] are NOT part of the string and are just used to clarify)
  1381.      * [t] can be any of [a](anotation int), [f](frame int), or [g](gridline int).
  1382.      * Default is a AND f. The [m], if present indicates value is in minutes.
  1383.      * The [c], if present indicates value is in seConds (s already used for south...).
  1384.      * Text between : and : are labels for the respective axes. If the first
  1385.      * character of the text is a period, then the rest of the text is used
  1386.      * as the plot title.
  1387.      * For LINEAR axes: If the first characters in args are one or more of w,e,s,n
  1388.      * only those axes will be drawn. Upper case letters means the chosen axes
  1389.      * also will be annotated. Default is all 4 axes drawn/annotated.
  1390.      * For logscale plots:  l will cause log10(x) to be plotted
  1391.      *            p will cause 10 ^ log10(x) to be plotted
  1392.      *    anot/tick/grid interval can here be either:
  1393.      *        1.0    -> Only powers of 10 are anotated
  1394.      *        2.0    -> powers of 10 times (1, 2, 5) are anotated
  1395.      *        3.0    -> powers of 10 times (1,2,3,..9) are anotated
  1396.      */
  1397.      
  1398.     int i, i1, i2, xyz_side = 0, n_colons = 0, side[5];
  1399.     BOOLEAN xyz_set[3], error = FALSE, set_sides = FALSE;
  1400.     double value;
  1401.     char flag;
  1402.     
  1403.     for (i = 0; i < 3; i++) {
  1404.         frame_info.anot_int[i] = 0.0;
  1405.         frame_info.frame_int[i] = 0.0;
  1406.         frame_info.grid_int[i] = 0.0;
  1407.         frame_info.label[i][0] = 0;
  1408.         frame_info.anot_type[i] = 0;
  1409.         xyz_set[i] = FALSE;
  1410.     }
  1411.     frame_info.plot = TRUE;
  1412.     frame_info.draw_box = FALSE;
  1413.     frame_info.header[0] = 0;
  1414.     for (i = 0; i < 5; i++) side[i] = 0;
  1415.     
  1416.     i1 = 0;
  1417.     while (args[i1]) {
  1418.         if (args[i1] == '/') {
  1419.             xyz_side++;
  1420.             i1++;
  1421.         }
  1422.         flag = '*';    /* If a,f, or g is not appended, we set all to the same value */
  1423.         if (isalpha(args[i1])) {
  1424.             flag = args[i1];
  1425.             i1++;
  1426.         }
  1427.         if (flag == 'w' || flag == 'W') {
  1428.             side[3] = (flag == 'W') ? 2 : 1;
  1429.             set_sides = TRUE;
  1430.             continue;
  1431.         }
  1432.         if (flag == 'e' || flag == 'E') {
  1433.             side[1] = (flag == 'E') ? 2 : 1;
  1434.             set_sides = TRUE;
  1435.             continue;
  1436.         }
  1437.         if (flag == 's' || flag == 'S') {
  1438.             side[0] = (flag == 'S') ? 2 : 1;
  1439.             set_sides = TRUE;
  1440.             continue;
  1441.         }
  1442.         if (flag == 'n' || flag == 'N') {
  1443.             side[2] = (flag == 'N') ? 2 : 1;
  1444.             set_sides = TRUE;
  1445.             continue;
  1446.         }
  1447.         if (flag == 'z' || flag == 'Z') {
  1448.             side[4] = (flag == 'Z') ? 2 : 1;
  1449.             if (args[i1] == '+') {
  1450.                 frame_info.draw_box = TRUE;
  1451.                 i1++;
  1452.             }
  1453.             set_sides = TRUE;
  1454.             continue;
  1455.         }
  1456.         if (isupper((int)flag)) flag = tolower ((int)flag);
  1457.         if (flag == 'l') {    /* log10(val) anotations */
  1458.             frame_info.anot_type[xyz_side] = 1;
  1459.             continue;
  1460.         }
  1461.         if (flag == 'p') {    /* Powers of 10 anotations */
  1462.             frame_info.anot_type[xyz_side] = 2;
  1463.             continue;
  1464.         }
  1465.         if (args[i1] == ':') {    /* Label string */
  1466.             n_colons++;
  1467.             flag = ' ';
  1468.             i2 = ++i1;
  1469.             while (args[i2] && args[i2] != ':') i2++;
  1470.             if (args[i2] == ':') n_colons++;
  1471.             if (args[i1] == '.') {
  1472.                 i1++;
  1473.                 strncpy (frame_info.header, &args[i1], i2-i1);
  1474.                 frame_info.header[i2-i1] = 0;
  1475.             }
  1476.             else {
  1477.                 strncpy (frame_info.label[xyz_side], &args[i1], i2-i1);
  1478.                 frame_info.label[xyz_side][i2-i1] = 0;
  1479.             }
  1480.             i1 = i2 + 1;
  1481.         }
  1482.         i2 = i1;
  1483.         while (args[i2] && strchr ("WESNacefglmnpswz/:", (int)args[i2]) == NULL) i2++;
  1484.         if (flag != ' ') {    /* Decode the numerical value */
  1485.             value = atof (&args[i1]);
  1486.             if (args[i2] == 'm') {
  1487.                 value /= 60.0;
  1488.                 i2++;
  1489.             }
  1490.             else if (args[i2] == 'c') {
  1491.                 value /= 3600.0;
  1492.                 i2++;
  1493.             }
  1494.             xyz_set[xyz_side] = TRUE;
  1495.         }
  1496.         if (flag == '*')
  1497.             frame_info.anot_int[xyz_side] = frame_info.frame_int[xyz_side] = value;
  1498.         else if (flag == 'a')
  1499.             frame_info.anot_int[xyz_side] = value;
  1500.         else if (flag == 'f')
  1501.             frame_info.frame_int[xyz_side] = value;
  1502.         else if (flag == 'g')
  1503.             frame_info.grid_int[xyz_side] = value;
  1504.         i1 = i2;
  1505.     }
  1506.     if (!xyz_set[1]) frame_info.anot_type[1] = frame_info.anot_type[0];
  1507.     for (i = 0; i < 3; i++) {    /* Set both a and f if only one of them is set */
  1508.         if (frame_info.anot_int[i] != 0.0 && frame_info.frame_int[i] == 0.0)
  1509.             frame_info.frame_int[i] = frame_info.anot_int[i];
  1510.         else if (frame_info.frame_int[i] != 0.0 && frame_info.anot_int[i] == 0.0)
  1511.             frame_info.anot_int[i] = frame_info.frame_int[i];
  1512.     }
  1513.     if (!xyz_set[1]) {    /* No separate y-axis info given, copy x values */
  1514.         frame_info.anot_int[1] = frame_info.anot_int[0];
  1515.         frame_info.frame_int[1] = frame_info.frame_int[0];
  1516.         frame_info.grid_int[1] = frame_info.grid_int[0];
  1517.     }
  1518.     if (set_sides) for (i = 0; i < 5; i++) frame_info.side[i] = side[i];    /* Override default */
  1519.  
  1520.     if (n_colons%2) error++;
  1521.     
  1522.     return (error);
  1523. }
  1524.  
  1525. int map_getproject (args)
  1526. char *args; {
  1527.     /* map_getproject scans the arguments given and extracts the parameters needed
  1528.      * for the specified map projection. These parameters are passed through the
  1529.      * project_info structure.  The function returns TRUE if an error is encountered.
  1530.      */
  1531.      
  1532.     int j, k, n, slash, l_pos[2], p_pos[2], id, project = -1, n_slashes = 0;
  1533.     BOOLEAN error = FALSE, skip = FALSE;
  1534.     double o_x, o_y, b_x, b_y, c, az;
  1535.     char type, txt_a[32], txt_b[32], txt_c[32], txt_d[32];
  1536.     
  1537.     l_pos[0] = l_pos[1] = p_pos[0] = p_pos[1] = 0;
  1538.     type = args[0];
  1539.  
  1540.     if (strchr ("AaBbCcEeGgHhIiKkLlMmNnOoPpQqRrSsTtUuWwXxYyZz", type) == NULL) return (TRUE);    /* NO valid projection specified */
  1541.     args++;
  1542.  
  1543.     for (j = 0; args[j]; j++) if (args[j] == '/') n_slashes++;
  1544.      
  1545.     if (!(type == 'z' || type == 'Z')) {
  1546.         /* Check to see if scale is specified in 1:xxxx */
  1547.         for (j = strlen (args), k = -1; j > 0 && k < 0 && args[j] != '/'; j--) if (args[j] == ':') k = j + 1; 
  1548.         project_info.units_pr_degree = (k == -1) ? TRUE : FALSE;
  1549.         project_info.unit = gmt_units[gmtdefs.measure_unit];
  1550.     }
  1551.      
  1552.      switch (type) {
  1553.          case 'X':
  1554.              project_info.compute_scale[0] = project_info.compute_scale[1] = TRUE;
  1555.              if (args[0] == 'v') {
  1556.                  project_info.pars[0] = gmtdefs.y_axis_length;
  1557.                  project_info.pars[1] = gmtdefs.x_axis_length;
  1558.                  skip = TRUE;
  1559.              }
  1560.              else if (args[0] == 'h') {
  1561.                  project_info.pars[0] = gmtdefs.x_axis_length;
  1562.                  project_info.pars[1] = gmtdefs.y_axis_length;
  1563.                  skip = TRUE;
  1564.              }
  1565.              
  1566.          case 'x':        /* Linear x/y scaling */
  1567.              project_info.pars[4] = (strchr (args, 'd')) ? 1.0 : 0.0;    /* TRUE if input is degrees and d is appended */
  1568.             error = (n_slashes > 1);
  1569.              
  1570.              /* Find occurrences of /, l, or p */
  1571.              for (j = 0, slash = 0; args[j] && slash == 0; j++) if (args[j] == '/') slash = j;
  1572.              for (j = id = 0; args[j]; j++) {
  1573.                  if (args[j] == '/') id = 1;
  1574.                  if (args[j] == 'L' || args[j] == 'l') l_pos[id] = j;
  1575.                  if (args[j] == 'P' || args[j] == 'p') p_pos[id] = j;
  1576.              }
  1577.              
  1578.              /* Get x-arguments */
  1579.              
  1580.              if (!skip) project_info.pars[0] = atof (args);    /* x-scale */
  1581.              
  1582.              if (l_pos[0] > 0)
  1583.                  project_info.xyz_projection[0] = LOG10;
  1584.              else if (p_pos[0] > 0) {
  1585.                  project_info.xyz_projection[0] = POW;
  1586.                  project_info.pars[2] = atof (&args[p_pos[0]+1]);    /* pow to raise x */
  1587.              }
  1588.              
  1589.              if (slash) {    /* Separate y-scaling desired */
  1590.                  if (!skip) project_info.pars[1] = atof (&args[slash+1]);    /* y-scale */
  1591.                  
  1592.                  if (l_pos[1] > 0)
  1593.                      project_info.xyz_projection[1] = LOG10;
  1594.                  else if (p_pos[1] > 0) {
  1595.                      project_info.xyz_projection[1] = POW;
  1596.                      project_info.pars[3] = atof (&args[p_pos[1]+1]);    /* pow to raise y */
  1597.                  }
  1598.              }
  1599.              else {    /* Just copy x parameters */
  1600.                  project_info.xyz_projection[1] = project_info.xyz_projection[0];
  1601.                  if (!skip) project_info.pars[1] = project_info.pars[0];
  1602.                  project_info.pars[3] = project_info.pars[2];
  1603.              }
  1604.              project = LINEAR;
  1605.              if (project_info.pars[0] == 0.0 || project_info.pars[1] == 0.0) error = TRUE;
  1606.              break;
  1607.          case 'Z':
  1608.             project_info.compute_scale[2] = TRUE;
  1609.          case 'z':
  1610.              
  1611.             error = (n_slashes > 0);
  1612.  
  1613.              /* Find occurrences of l or p */
  1614.              for (j = 0; args[j]; j++) if (args[j] == 'L' || args[j] == 'l') l_pos[0] = j;
  1615.              for (j = 0; args[j]; j++) if (args[j] == 'P' || args[j] == 'p') p_pos[0] = j;
  1616.              
  1617.              /* Get arguments */
  1618.              
  1619.              project_info.z_pars[0] = atof (args);    /* z-scale */
  1620.              
  1621.              if (l_pos[0] > 0)
  1622.                  project_info.xyz_projection[2] = LOG10;
  1623.              else if (p_pos[0] > 0) {
  1624.                  project_info.xyz_projection[2] = POW;
  1625.                  project_info.z_pars[1] = atof (&args[p_pos[0]+1]);    /* pow to raise z */
  1626.              }
  1627.              if (project_info.z_pars[0] == 0.0) error = TRUE;
  1628.              break;
  1629.          case 'P':        /* Polar (theta,r) */
  1630.              project_info.gave_map_width = TRUE;
  1631.          case 'p':
  1632.              n = sscanf (args, "%lf", &project_info.pars[0]);
  1633.             error = (n_slashes > 0 || n != 1 || project_info.pars[0] <= 0.0);
  1634.              project = POLAR;
  1635.              break;
  1636.              
  1637.          /* Map projections */
  1638.  
  1639.          case 'A':    /* Lambert Azimuthal Equal-Area */
  1640.              project_info.gave_map_width = TRUE;
  1641.          case 'a':
  1642.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1643.                  n = sscanf (args, "%[^/]/%[^/]/1:%lf", txt_a, txt_b, &project_info.pars[2]);
  1644.                  if (project_info.pars[2] != 0.0) project_info.pars[2] = 1.0 / (project_info.pars[2] * project_info.unit);
  1645.                 error = (!(n_slashes == 2 && n == 3));
  1646.              }
  1647.              else if (project_info.gave_map_width) {
  1648.                  n = sscanf (args, "%[^/]/%[^/]/%lf", txt_a, txt_b, &project_info.pars[2]);
  1649.                 error = (!(n_slashes == 2 && n == 3));
  1650.              }
  1651.              else {
  1652.                  n = sscanf (args, "%[^/]/%[^/]/%lf/%s", txt_a, txt_b, &project_info.pars[2], txt_c);
  1653.                 project_info.pars[3] = ddmmss_to_degree (txt_c);
  1654.                 error = (!(n_slashes == 3 && n == 4));
  1655.              }
  1656.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1657.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  1658.             error += (project_info.pars[2] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1659.              project = LAMB_AZ_EQ;
  1660.              break;
  1661.          case 'B':        /* Albers Equal-area Conic */
  1662.              project_info.gave_map_width = TRUE;
  1663.          case 'b':
  1664.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1665.                  n = sscanf (args, "%[^/]/%[^/]/%[^/]/%[^/]/1:%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1666.                  if (project_info.pars[4] != 0.0) project_info.pars[4] = 1.0 / (project_info.pars[4] * project_info.unit);
  1667.              }
  1668.              else
  1669.                  n = sscanf (args, "%[^/]/%[^/]/%[^/]/%[^/]/%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1670.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1671.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  1672.             project_info.pars[2] = ddmmss_to_degree (txt_c);
  1673.             project_info.pars[3] = ddmmss_to_degree (txt_d);
  1674.             error = !(n_slashes == 4 && n == 5);
  1675.             error += (project_info.pars[4] <= 0.0 || project_info.pars[2] == project_info.pars[3]);
  1676.             error += (k >= 0 && project_info.gave_map_width);
  1677.              project = ALBERS;
  1678.              break;
  1679.  
  1680.          case 'C':    /* Cassini */
  1681.              project_info.gave_map_width = TRUE;
  1682.          case 'c':
  1683.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1684.                  n = sscanf (args, "%[^/]/%[^/]/1:%lf", txt_a, txt_b, &project_info.pars[2]);
  1685.                  if (project_info.pars[2] != 0.0) project_info.pars[2] = 1.0 / (project_info.pars[2] * project_info.unit);
  1686.              }
  1687.              else
  1688.                  n = sscanf (args, "%[^/]/%[^/]/%lf", txt_a, txt_b, &project_info.pars[2]);
  1689.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1690.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  1691.             error = !(n_slashes == 2 && n == 3);
  1692.             error += (project_info.pars[2] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1693.              project = CASSINI;
  1694.              break;
  1695.  
  1696.          case 'E':        /* Azimuthal equal-distant */
  1697.              project_info.gave_map_width = TRUE;
  1698.          case 'e':
  1699.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1700.                  n = sscanf (args, "%[^/]/%[^/]/1:%lf", txt_a, txt_b, &project_info.pars[2]);
  1701.                  if (project_info.pars[2] != 0.0) project_info.pars[2] = 1.0 / (project_info.pars[2] * project_info.unit);
  1702.                 error = (!(n_slashes == 2 && n == 3));
  1703.              }
  1704.              else if (project_info.gave_map_width) {
  1705.                  n = sscanf (args, "%[^/]/%[^/]/%lf", txt_a, txt_b, &project_info.pars[2]);
  1706.                 error = (!(n_slashes == 2 && n == 3));
  1707.              }
  1708.              else {
  1709.                  n = sscanf (args, "%[^/]/%[^/]/%lf/%s", txt_a, txt_b, &project_info.pars[2], txt_c);
  1710.                 project_info.pars[3] = ddmmss_to_degree (txt_c);
  1711.                 error = (!(n_slashes == 3 && n == 4));
  1712.              }
  1713.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1714.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  1715.             error += (project_info.pars[2] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1716.              project = AZ_EQDIST;
  1717.              break;
  1718.  
  1719.          case 'G':        /* Orthographic */
  1720.              project_info.gave_map_width = TRUE;
  1721.          case 'g':        /* Orthographic */
  1722.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1723.                  n = sscanf (args, "%[^/]/%[^/]/1:%lf", txt_a, txt_b, &project_info.pars[2]);
  1724.                  if (project_info.pars[2] != 0.0) project_info.pars[2] = 1.0 / (project_info.pars[2] * project_info.unit);
  1725.                 error = (!(n_slashes == 2 && n == 3));
  1726.              }
  1727.              else if (project_info.gave_map_width) {
  1728.                  n = sscanf (args, "%[^/]/%[^/]/%lf", txt_a, txt_b, &project_info.pars[2]);
  1729.                 error = (!(n_slashes == 2 && n == 3));
  1730.             }
  1731.              else {
  1732.                  n = sscanf (args, "%[^/]/%[^/]/%lf/%s", txt_a, txt_b, &project_info.pars[2], txt_c);
  1733.                 project_info.pars[3] = ddmmss_to_degree (txt_c);
  1734.                 error = (!(n_slashes == 3 && n == 4));
  1735.             }
  1736.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1737.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  1738.             error += (project_info.pars[2] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1739.              project = ORTHO;
  1740.              break;
  1741.  
  1742.          case 'H':    /* Hammer-Aitoff Equal-Area */
  1743.              project_info.gave_map_width = TRUE;
  1744.          case 'h':
  1745.              if (k >= 0) {
  1746.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1747.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = gmtdefs.ellipse[N_ELLIPSOIDS-1].eq_radius / (project_info.pars[1] * project_info.unit);
  1748.              }
  1749.              else
  1750.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1751.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1752.             error = !(n_slashes == 1 && n == 2);
  1753.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1754.              project = HAMMER;
  1755.              break;
  1756.  
  1757.          case 'I':    /* Sinusoidal Equal-Area */
  1758.              project_info.gave_map_width = TRUE;
  1759.          case 'i':
  1760.              if (k >= 0) {
  1761.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1762.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = 2.0 * M_PI * gmtdefs.ellipse[N_ELLIPSOIDS-1].eq_radius / (project_info.pars[1] * project_info.unit);
  1763.              }
  1764.              else
  1765.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1766.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1767.             error = !(n_slashes == 1 && n == 2);
  1768.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1769.              project = SINUSOIDAL;
  1770.              break;
  1771.  
  1772.          case 'K':    /* Eckert VI projection */
  1773.              project_info.gave_map_width = TRUE;
  1774.          case 'k':
  1775.              if (k >= 0) {
  1776.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1777.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = gmtdefs.ellipse[N_ELLIPSOIDS-1].eq_radius / (project_info.pars[1] * project_info.unit);
  1778.              }
  1779.              else
  1780.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1781.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1782.             error = !(n_slashes == 1 && n == 2);
  1783.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1784.              project = ECKERT;
  1785.              break;
  1786.  
  1787.          case 'L':        /* Lambert Conformal Conic */
  1788.              project_info.gave_map_width = TRUE;
  1789.          case 'l':
  1790.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1791.                  n = sscanf (args, "%[^/]/%[^/]/%[^/]/%[^/]/1:%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1792.                  if (project_info.pars[4] != 0.0) project_info.pars[4] = 1.0 / (project_info.pars[4] * project_info.unit);
  1793.              }
  1794.              else
  1795.                  n = sscanf (args, "%[^/]/%[^/]/%[^/]/%[^/]/%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1796.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1797.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  1798.             project_info.pars[2] = ddmmss_to_degree (txt_c);
  1799.             project_info.pars[3] = ddmmss_to_degree (txt_d);
  1800.             error = !(n_slashes == 4 && n == 5);
  1801.             error += (project_info.pars[4] <= 0.0 || project_info.pars[2] == project_info.pars[3]);
  1802.             error += (k >= 0 && project_info.gave_map_width);
  1803.              project = LAMBERT;
  1804.              break;
  1805.          case 'M':        /* Mercator */
  1806.              project_info.gave_map_width = TRUE;
  1807.          case 'm':
  1808.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1809.                  n = sscanf (args, "1:%lf", &project_info.pars[0]);
  1810.                  if (project_info.pars[0] != 0.0) project_info.pars[0] = 1.0 / (project_info.pars[0] * project_info.unit);
  1811.              }
  1812.              else
  1813.                  n = sscanf (args, "%lf", &project_info.pars[0]);
  1814.             error = (n_slashes > 0 || n != 1 || project_info.pars[0] <= 0.0);
  1815.              project = MERCATOR;
  1816.              break;
  1817.  
  1818.          case 'N':    /* Robinson Projection */
  1819.              project_info.gave_map_width = TRUE;
  1820.          case 'n':
  1821.              if (k >= 0) {
  1822.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1823.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = gmtdefs.ellipse[N_ELLIPSOIDS-1].eq_radius / (project_info.pars[1] * project_info.unit);
  1824.              }
  1825.              else
  1826.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1827.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1828.             error = !(n_slashes == 1 && n == 2);
  1829.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1830.              project = ROBINSON;
  1831.              break;
  1832.  
  1833.          case 'O':        /* Oblique Mercator */
  1834.              project_info.gave_map_width = TRUE;
  1835.          case 'o':
  1836.              if (args[0] == 'a') {    /* Origin and azimuth specified */
  1837.                  if (k >= 0) {
  1838.                     n = sscanf (&args[1], "%[^/]/%[^/]/%lf/1:%lf", txt_a, txt_b, &az, &project_info.pars[4]);
  1839.                      if (project_info.pars[4] != 0.0) project_info.pars[4] = 1.0 / (project_info.pars[4] * project_info.unit);
  1840.                  }
  1841.                  else
  1842.                     n = sscanf (&args[1], "%[^/]/%[^/]/%lf/%lf", txt_a, txt_b, &az, &project_info.pars[4]);
  1843.  
  1844.                 o_x = ddmmss_to_degree (txt_a);
  1845.                 o_y = ddmmss_to_degree (txt_b);
  1846.                  c = 10.0;    /* compute point 10 degrees from origin along azimuth */
  1847.                  b_x = o_x + R2D * atan (sind (c) * sind (az) / (cosd (o_y) * cosd (c) - sind (o_y) * sind (c) * cosd (az)));
  1848.                  b_y = R2D * d_asin (sind (o_y) * cosd (c) + cosd (o_y) * sind (c) * cosd (az));
  1849.                  project_info.pars[6] = 0.0;
  1850.                 error = !(n_slashes == 3 && n == 4);
  1851.              }
  1852.              else if (args[0] == 'b') {    /* Origin and second point specified */
  1853.                  if (k >= 0) {
  1854.                      n = sscanf (&args[1], "%[^/]/%[^/]/%[^/]/%[^/]/1:%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1855.                      if (project_info.pars[4] != 0.0) project_info.pars[4] = 1.0 / (project_info.pars[4] * project_info.unit);
  1856.                  }
  1857.                  else
  1858.                      n = sscanf (&args[1], "%[^/]/%[^/]/%[^/]/%[^/]/%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1859.                 o_x = ddmmss_to_degree (txt_a);
  1860.                 o_y = ddmmss_to_degree (txt_b);
  1861.                 b_x = ddmmss_to_degree (txt_c);
  1862.                 b_y = ddmmss_to_degree (txt_d);
  1863.                  project_info.pars[6] = 0.0;
  1864.                 error = !(n_slashes == 4 && n == 5);
  1865.              }
  1866.              else if (args[0] == 'c') {    /* Origin and Pole specified */
  1867.                  if (k >= 0) {
  1868.                      n = sscanf (&args[1], "%[^/]/%[^/]/%[^/]/%[^/]/1:%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1869.                      if (project_info.pars[4] != 0.0) project_info.pars[4] = 1.0 / (project_info.pars[4] * project_info.unit);
  1870.                  }
  1871.                  else
  1872.                      n = sscanf (&args[1], "%[^/]/%[^/]/%[^/]/%[^/]/%lf", txt_a, txt_b, txt_c, txt_d, &project_info.pars[4]);
  1873.                 o_x = ddmmss_to_degree (txt_a);
  1874.                 o_y = ddmmss_to_degree (txt_b);
  1875.                 b_x = ddmmss_to_degree (txt_c);
  1876.                 b_y = ddmmss_to_degree (txt_d);
  1877.                  if (b_y < 0.0) {    /* Flip from S hemisphere to N */
  1878.                      b_y = -b_y;
  1879.                      b_x += 180.0;
  1880.                      if (b_x >= 360.0) b_x -= 360.0;
  1881.                  }
  1882.                  project_info.pars[6] = 1.0;
  1883.                 error = !(n_slashes == 4 && n == 5);
  1884.              }
  1885.              else
  1886.                  project = -1;
  1887.             error += (project_info.pars[4] <= 0.0);
  1888.             error += (k >= 0 && project_info.gave_map_width);
  1889.              project_info.pars[0] = o_x;    project_info.pars[1] = o_y;
  1890.              project_info.pars[2] = b_x;    project_info.pars[3] = b_y;
  1891.              
  1892.              /* see if wesn is in oblique degrees or just diagonal corners */
  1893.              
  1894.              project = OBLIQUE_MERC;
  1895.              break;
  1896.  
  1897.          case 'Q':    /* Equidistant Cylindrical (Plate Carree) */
  1898.              project_info.gave_map_width = TRUE;
  1899.          case 'q':
  1900.              if (k >= 0) {
  1901.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1902.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = gmtdefs.ellipse[N_ELLIPSOIDS-1].eq_radius / (project_info.pars[1] * project_info.unit);
  1903.              }
  1904.              else
  1905.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1906.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1907.             error = !(n_slashes == 1 && n == 2);
  1908.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1909.              project = CYL_EQDIST;
  1910.              break;
  1911.  
  1912.          case 'R':    /* Winkel Tripel Modified azimuthal */
  1913.              project_info.gave_map_width = TRUE;
  1914.          case 'r':
  1915.              if (k >= 0) {
  1916.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1917.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = gmtdefs.ellipse[N_ELLIPSOIDS-1].eq_radius / (project_info.pars[1] * project_info.unit);
  1918.              }
  1919.              else
  1920.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1921.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1922.             error = !(n_slashes == 1 && n == 2);
  1923.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1924.              project = WINKEL;
  1925.              break;
  1926.  
  1927.          case 'S':        /* Stereographic */
  1928.              project_info.gave_map_width = TRUE;
  1929.          case 's':
  1930.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1931.                  n = sscanf (args, "%[^/]/%[^/]/1:%lf", txt_a, txt_b, &project_info.pars[2]);
  1932.                  if (project_info.pars[2] != 0.0) project_info.pars[2] = 1.0 / (project_info.pars[2] * project_info.unit);
  1933.                 error = (!(n_slashes == 2 && n == 3));
  1934.              }
  1935.              else if (project_info.gave_map_width) {
  1936.                  n = sscanf (args, "%[^/]/%[^/]/%lf", txt_a, txt_b, &project_info.pars[2]);
  1937.                 error = (!(n_slashes == 2 && n == 3));
  1938.              }
  1939.              else {
  1940.                  n = sscanf (args, "%[^/]/%[^/]/%lf/%s", txt_a, txt_b, &project_info.pars[2], txt_c);
  1941.                 project_info.pars[3] = ddmmss_to_degree (txt_c);
  1942.                 error = (!(n_slashes == 3 && n == 4));
  1943.             }
  1944.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1945.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  1946.             error += (project_info.pars[2] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1947.              project = STEREO;
  1948.              break;
  1949.  
  1950.          case 'T':    /* Transverse Mercator */
  1951.              project_info.gave_map_width = TRUE;
  1952.          case 't':
  1953.              if (k >= 0) {
  1954.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1955.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = 1.0 / (project_info.pars[1] * project_info.unit);
  1956.              }
  1957.              else
  1958.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1959.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1960.             error = !(n_slashes == 1 && n == 2);
  1961.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1962.              project = TM;
  1963.              break;
  1964.  
  1965.          case 'U':    /* Universal Transverse Mercator */
  1966.              project_info.gave_map_width = TRUE;
  1967.          case 'u':
  1968.              if (k >= 0) {
  1969.                  n = sscanf (args, "%lf/1:%lf", &project_info.pars[0], &project_info.pars[1]);
  1970.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = 1.0 / (project_info.pars[1] * project_info.unit);
  1971.              }
  1972.              else
  1973.                  n = sscanf (args, "%lf/%lf", &project_info.pars[0], &project_info.pars[1]);
  1974.              project_info.north_pole = (project_info.pars[0] > 0.0);
  1975.              project_info.pars[0] = fabs (project_info.pars[0]);
  1976.             error = !(n_slashes == 1 && n == 2);
  1977.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1978.              project = UTM;
  1979.              break;
  1980.          case 'W':    /* Mollweide Equal-Area */
  1981.              project_info.gave_map_width = TRUE;
  1982.          case 'w':
  1983.              if (k >= 0) {
  1984.                  n = sscanf (args, "%[^/]/1:%lf", txt_a, &project_info.pars[1]);
  1985.                  if (project_info.pars[1] != 0.0) project_info.pars[1] = gmtdefs.ellipse[N_ELLIPSOIDS-1].eq_radius / (project_info.pars[1] * project_info.unit);
  1986.              }
  1987.              else
  1988.                  n = sscanf (args, "%[^/]/%lf", txt_a, &project_info.pars[1]);
  1989.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  1990.             error = !(n_slashes == 1 && n == 2);
  1991.             error += (project_info.pars[1] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  1992.              project = MOLLWEIDE;
  1993.              break;
  1994.              
  1995.          case 'Y':        /* Cylindrical Equal Area */
  1996.              project_info.gave_map_width = TRUE;
  1997.          case 'y':
  1998.              if (k >= 0) {    /* Scale entered as 1:mmmmm */
  1999.                  n = sscanf (args, "%[^/]/%[^/]/1:%lf", txt_a, txt_b, &project_info.pars[2]);
  2000.                  if (project_info.pars[2] != 0.0) project_info.pars[2] = 1.0 / (project_info.pars[2] * project_info.unit);
  2001.                 error = (!(n_slashes == 2 && n == 3));
  2002.              }
  2003.              else {
  2004.                  n = sscanf (args, "%[^/]/%[^/]/%lf", txt_a, txt_b, &project_info.pars[2]);
  2005.                 error = (!(n_slashes == 2 && n == 3));
  2006.             }
  2007.             project_info.pars[0] = ddmmss_to_degree (txt_a);
  2008.             project_info.pars[1] = ddmmss_to_degree (txt_b);
  2009.             error += (fabs(project_info.pars[1]) >= 90.0);
  2010.             error += (project_info.pars[2] <= 0.0 || (k >= 0 && project_info.gave_map_width));
  2011.              project = CYL_EQ;
  2012.              break;
  2013.  
  2014.          default:
  2015.              error = TRUE;
  2016.              project = -1;
  2017.              break;
  2018.      }
  2019.      
  2020.      if (!project_info.units_pr_degree && project_info.gave_map_width) {
  2021.          fprintf (stderr, "%s: GMT SYNTAX ERROR -J%c option: Cannot specify map width with 1:xxxx format\n", gmt_program, type);
  2022.          error++;
  2023.      }
  2024.      
  2025.      if (!(type == 'z' || type == 'Z')) project_info.projection = project;
  2026.      return (error);
  2027. }
  2028.  
  2029. int prepare_three_D () {    /* Initialize 3-D parameters */
  2030.     project_info.z_pars[0] = project_info.z_pars[1] = 0.0;
  2031.     project_info.xyz_pos[2] = TRUE;
  2032.     project_info.zmin = project_info.zmax = 0.0;
  2033.     z_forward = (PFI) NULL;
  2034.     z_inverse = (PFI) NULL;
  2035.     z_project.view_azimuth = 180.0;
  2036.     z_project.view_elevation = 90.0;
  2037.     project_info.z_bottom = project_info.z_top = 0.0;
  2038. }
  2039.  
  2040.