1 /*--------------------------------------------------------------------
2  *
3  *	Copyright (c) 1991-2021 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
4  *	See LICENSE.TXT file for copying and redistribution conditions.
5  *
6  *	This program is free software; you can redistribute it and/or modify
7  *	it under the terms of the GNU Lesser General Public License as published by
8  *	the Free Software Foundation; version 3 or any later version.
9  *
10  *	This program is distributed in the hope that it will be useful,
11  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *	GNU Lesser General Public License for more details.
14  *
15  *	Contact info: www.generic-mapping-tools.org
16  *--------------------------------------------------------------------*/
17 /*
18  * gmt_types.h contains definitions of special types used by GMT.
19  *
20  * Author:	Paul Wessel
21  * Date:	01-OCT-2009
22  * Version:	6 API
23  */
24 
25 /*!
26  * \file gmt_types.h
27  * \brief Definitions of special types used by GMT.
28  */
29 
30 #ifndef GMT_TYPES_H
31 #define GMT_TYPES_H
32 #include <stdbool.h>
33 #include <stdint.h>
34 
35 /*--------------------------------------------------------------------
36  * GMT TYPE DEFINITIONS
37  *--------------------------------------------------------------------*/
38 
39 /*! Definition of CONTOUR_ARGS used by grdcontour and pscontour */
40 struct CONTOUR_ARGS {
41 	bool cpt;		/* true of we were given a CPT file */
42 	bool check;		/* true if in modern mode and no CPT was given */
43 	unsigned int mode;	/* Module specific action, usually to indicate no annotations desired */
44 	char *file;		/* File with cpt or contours, or list of contours */
45 	double interval;	/* Constant interval */
46 	double single_cont;	/* Single specified contour */
47 };
48 
49 /*! Definition of CONTOUR_CLOSED used by grdcontour and pscontour */
50 struct CONTOUR_CLOSED {
51 	bool label;
52 	bool all;
53 	bool low, high;	/* true to tick low and high locals */
54 	double dim[2];	/* spacing, length */
55 	char *txt[2];	/* Low and high label [-+] */
56 };
57 
58 /*! Definition of GMT_MATH_MACRO used by grdmath and gmtmath */
59 struct GMT_MATH_MACRO {
60 	unsigned int n_arg;	/* How many commands this macro represents */
61 	char *name;	/* The macro name */
62 	char **arg;	/* List of those commands */
63 };
64 
65 /*! Definition of GMT_KEYWORD_DICTIONARY used to expand keyword-value pairs to GMT options */
66 struct GMT_KEYWORD_DICTIONARY {	/* Used for keyword-value lookup */
67 	char separator;			/* Single character separating 2 or more identical specifications [0 for no repeat] */
68 	char short_option;		/* Single character GMT option code */
69 	char long_option[GMT_LEN32-1];		/* Name of corresponding long option */
70 	char short_directives[GMT_LEN32];	/* Single character directives, comma-separated */
71 	char long_directives[GMT_LEN256];	/* Long name directives, comma-separated */
72 	char short_modifiers[GMT_LEN32];	/* Single character modifiers, comma-separated */
73 	char long_modifiers[GMT_LEN256];	/* Long name modifiers, comma-separated */
74 };
75 
76 /*! Definition of structure use for finding optimal n_columns/n_rows for surface */
77 struct GMT_SURFACE_SUGGESTION {	/* Used to find top ten list of faster grid dimensions  */
78 	unsigned int n_columns;
79 	unsigned int n_rows;
80 	double factor;	/* Speed up by a factor of factor  */
81 };
82 
83 /*! Definition of structure used for holding information of integer items to be selected */
84 struct GMT_INT_SELECTION {	/* Used to hold array with items (0-n) that have been selected */
85 	uint64_t *item;		/* Array with item numbers given (0 is first), sorted into ascending order */
86 	uint64_t n;		/* Number of items */
87 	uint64_t current;	/* Current item in item array */
88 	bool invert;		/* Instead select the items NOT listed in item[] */
89 };
90 
91 /*! Definition of structure used for holding information of text items to be selected */
92 struct GMT_TEXT_SELECTION {	/* Used to hold array with items (0-n) that have been selected */
93 	char **pattern;		/* Array with text items given, sorted into lexical order */
94 	int ogr_item;		/* Used if ogr_match is true */
95 	uint64_t n;		/* Number of items */
96 	bool invert;		/* Instead select the items NOT listed in item[] */
97 	bool *regexp;		/* Item is a regex expression */
98 	bool *caseless;		/* Treat as caseless */
99 	bool ogr_match;		/* Compare pattern to an OGR item */
100 };
101 
102 /*! For weighted mean/mode */
103 struct GMT_OBSERVATION {
104 	gmt_grdfloat value;
105 	gmt_grdfloat weight;
106 };
107 
108 /*! For finding tightest west/east range of multiple items */
109 struct GMT_RANGE {
110 	double west;
111 	double east;
112 	double center;	/* Forced to be 0-360 */
113 };
114 
115 /*! For accessing singular values in sorted order */
116 struct GMT_SINGULAR_VALUE {
117 	double value;
118 	unsigned int order;
119 };
120 
121 /*! For information on 1-D array */
122 
123 struct GMT_ARRAY {	/* Used by modules that needs to set up 1-D output/bin arrays */
124 	bool temporal;	/* true if array will be in absolute time */
125 	bool vartime;	/* true if <unit> implies a variable calendar unit */
126 	bool count;	/* true if we got number of items rather than increment */
127 	bool add;	/* true if we are asked to add a computed spatial distance column to output */
128 	bool reverse;	/* true if we want to reverse the array to give high to low on output */
129 	bool reciprocal;	/* true if we gave the reciprocal increment */
130 	bool round;	/* true if we want to adjust increment to ensure min/max range is a multiple of inc */
131 	bool exact_inc;	/* true if we want the increment to be exact and to adjust min/max instead */
132 	bool var_inc;	/* true if the resulting array has variable spacing */
133 	bool logarithmic;	/* true if inc = 1,2,3 and we want logarithmic scale */
134 	bool logarithmic2;	/* true if inc = integer and we want log2 scale */
135 	bool unique;	/* true if any list shall be reduced to a monotonic, sorted array */
136 	bool delay[2];	/* true if min and/or max shall be set from data set extremes after read [false] */
137 	unsigned int spatial;	/* 1 if <unit> implies a Cartesian and 2 if a geospatial distance */
138 	unsigned int set;	/* 1 if inc set, 3 if min/max/in set, 0 otherwise */
139 	unsigned int col;	/* The column that this array goes with */
140 	int distmode;	/* Type of geospatial calculation mode for distances */
141 	uint64_t n;	/* Number of elements in the array when complete */
142 	double min, max, inc;	/* Equidistant items */
143 	double *array;	/* This will eventually hold the array */
144 	char *file;	/* In case a file is given with the values */
145 	char *list;	/* In case a comma-separated list of values */
146 	char unit;	/* To remind us what units the inc is in, if given */
147 };
148 
149 /*! For keeping table,segment IDs in a 1-D array */
150 struct GMT_TBLSEG {
151 	uint64_t tbl, seg;
152 };
153 
154 /*! For keeping track of GMT figures under modern mode */
155 struct GMT_FIGURE {
156 	int ID;	/* Figure number [0] */
157 	char prefix[GMT_LEN256];	/* File prefix (no extension) */
158 	char formats[GMT_LEN64];	/* List of comma-separated extensions(formats) */
159 	char options[GMT_LEN256];	/* Optional arguments to psconvert (e.g., -A, -E, ...) */
160 };
161 
162 struct GMT_INSET {
163 	bool active;	/* true the first time we set up scaling for a map inset */
164 	bool first;	/* true the first time we plot into the map inset */
165 	double w, h;	/* Width and height of current inset */
166 	double dx, dy;	/* offsets */
167 };
168 
169 /*! For keeping track of GMT subplots under modern mode */
170 struct GMT_SUBPLOT {
171 	unsigned int active;	/* 1 if subplot is in effect */
172 	unsigned int first;		/* 1 the first time we reach panel, 0 later */
173 	unsigned int no_scaling;	/* 1 when we are plotting a scale, bar, etc and not map and don't want to auto-scale plot */
174 	unsigned int parallel;	/* 1 for axis-parallel annotations [0 for standard] */
175 	unsigned int inside;	/* 1 if all annots/ticks are inside panels [0 for outside] */
176 	int row, col;			/* Current panel position e.g., 0,0 */
177 	int nrows, ncolumns;	/* Panel arrangement for subplot window */
178 	int dir[2];				/* Cartesian axis direction: +1 or -1 [1/1] */
179 	double x, y;			/* LB corner of current panel */
180 	double dx, dy;			/* Offset from LB when projection rescaling is required to center */
181 	double w, h;			/* Width and height of current panel */
182 	double dim[2];			/* Dimension of entire subplot */
183 	double origin[2];		/* Location of lower left figure origin set via -X -Y */
184 	double off[2];			/* Offset from justification point of panel tag */
185 	double soff[2];			/* Shade offset from justification point of panel tag */
186 	double clearance[4];	/* Space around text for surrounding textbox */
187 	double gap[4];			/* Shrink plottable region to make space for enhancements */
188 	char refpoint[3];		/* Reference point for panel tag */
189 	char justify[3];		/* Justification relative to refpoint */
190 	char tag[GMT_LEN128];		/* Panel tag, e.g., a) */
191 	char fill[GMT_LEN64];		/* Panel fill color */
192 	char shade[GMT_LEN64];		/* Panel tag shade color */
193 	char pen[GMT_LEN64];		/* Panel tag pen outline */
194 	char Baxes[GMT_LEN128];		/* The -B setting for selected axes, including +color, tec */
195 	char Btitle[GMT_LEN128];	/* The -B setting for any title */
196 	char Bxlabel[GMT_LEN128];	/* The -Bx setting for x labels */
197 	char Bylabel[GMT_LEN128];	/* The -By setting for x labels */
198 	char Bxannot[GMT_LEN32];	/* The -Bx setting for annotations */
199 	char Byannot[GMT_LEN32];	/* The -By setting for annotations */
200 };
201 
202 /*! For trend-fitting models */
203 struct GMT_MODEL_TERM {	/* A single model term */
204 	unsigned int kind;	/* GMT_POLYNOMIAL | GMT_COSINE | GMT_SINE | GMT_FOURIER */
205 	unsigned int order[2];	/* Polygon or Fourier order */
206 	unsigned int type;	/* 0-7 for which kind of sin/cos combination */
207 };
208 
209 struct GMT_MODEL {	/* A model consists of n_terms */
210 	bool robust;		/* True for L1 fitting [L2] */
211 	bool chebyshev;		/* True if given polynomial of order n */
212 	bool intercept;		/* True if given model has intercept */
213 	bool got_origin[2];	/* True if we got origin(s) */
214 	bool got_period[2];	/* True if we got periods(s) */
215 	unsigned int dim;	/* 1 or 2 */
216 	unsigned int type;	/* 1 = poly, 2 = Fourier, 3 = both */
217 	unsigned int n_terms;	/* Terms in model */
218 	unsigned int n_poly;	/* The first n_poly terms contain the Polynomial/Chebyshev portion (if any) */
219 	double origin[2];	/* x (or t) and y origins */
220 	double period[2];	/* x (or t) and y periods */
221 	struct GMT_MODEL_TERM term[GMT_N_MAX_MODEL];
222 };
223 
224 struct GMT_ORDER {	/* Used to sort some item (e.g., structure) based on a value */
225 	double value;		/* The value to sort on */
226 	uint64_t order;		/* Original position of item in the array */
227 };
228 
229 /*! For segments */
230 struct GMT_SEGMENTIZE {	/* Information about segmentation */
231 	unsigned int method;	/* Type of segmentation [0] */
232 	unsigned int level;	/* Organized by segments (0), per table (1) or per dataset (2) [0] */
233 	double origin[2];	/* Reference point for segmentation */
234 };
235 
236 struct GMT_DIST {	/* Holds info for a particular distance calculation */
237 	bool init;	/* true if we have initialized settings for this type via gmt_init_distaz */
238 	bool arc;	/* true if distances are in deg/min/sec or arc; otherwise they are e|f|k|M|n or Cartesian */
239 	double (*func) (struct GMT_CTRL *, double, double, double, double);	/* pointer to function returning distance between two points points */
240 	double scale;	/* Scale to convert function output to desired unit */
241 };
242 
243 struct GMT_MAP {		/* Holds all map-related parameters */
244 	struct GMT_PLOT_FRAME frame;		/* Everything about the frame parameters */
245 	int this_x_status;			/* Tells us what quadrant old and new points are in (-4/4) */
246 	int this_y_status;
247 	int prev_x_status;
248 	int prev_y_status;
249 	int corner;			/* Tells us which corner 1-4 or -1 if not a corner */
250 	bool coastline;			/* true if we are currently plotting the coastline data in pscoast */
251 	bool on_border_is_outside;		/* true if a point exactly on the map border should be considered outside the map */
252 	bool is_world;			/* true if map has 360 degrees of longitude range */
253 	bool is_world_tm;			/* true if GMT_TM map is global? */
254 	bool lon_wrap;			/* true when longitude wrapping over 360 degrees is allowed */
255 	bool lat_wrap;			/* true when "latitude" wrapping over 180 degrees is allowed (may be periodic time in y-axis instead) */
256 	bool z_periodic;			/* true if grid values are 0-360 degrees (phases etc) */
257 	bool loxodrome;				/* true if we are computing loxodrome distances */
258 	unsigned int meridian_straight;		/* 1 if meridians plot as straight lines, 2 for special case */
259 	unsigned int parallel_straight;		/* 1 if parallels plot as straight lines, 2 for special case */
260 	unsigned int n_lon_nodes;		/* Somewhat arbitrary # of nodes for lines in longitude (may be reset in gmt_map.c) */
261 	unsigned int n_lat_nodes;		/* Somewhat arbitrary # of nodes for lines in latitude (may be reset in gmt_map.c) */
262 	unsigned int path_mode;		/* 0 if we should call gmt_fix_up_path to resample across gaps > path_step, 1 to leave alone */
263 	double last_width;			/* Full width in inches of previous plot */
264 	double last_height;			/* Full height in inches of previous plot */
265 	double width;				/* Full width in inches of this world map */
266 	double height;				/* Full height in inches of this world map */
267 	double half_width;			/* Half width in inches of this world map */
268 	double half_height;			/* Half height of this world map */
269 	double dlon;				/* Steps taken in longitude along gridlines (gets reset in gmt_init.c) */
270 	double dlat;				/* Steps taken in latitude along gridlines (gets reset in gmt_init.c) */
271 	double path_step;			/* Sampling interval if resampling of paths should be done */
272 	double lon_wrap_range;		/* 360 for longitudes, but others values for periodic time */
273 	double lat_wrap_range;		/* Usually means for for periodic time */
274 	bool (*outside) (struct GMT_CTRL *, double, double);	/* Pointer to function checking if a lon/lat point is outside map */
275 	bool (*overlap) (struct GMT_CTRL *, double, double, double, double);	/* Pointer to function checking for overlap between 2 regions */
276 	bool (*will_it_wrap) (struct GMT_CTRL *, double *, double *, uint64_t, uint64_t *);	/* true if consecutive points indicate wrap */
277 	int (*jump) (struct GMT_CTRL *, double, double, double, double);	/* true if we jump in x or y */
278 	unsigned int (*crossing) (struct GMT_CTRL *, double, double, double, double, double *, double *, double *, double *, unsigned int *);	/* Pointer to functions returning crossover point at boundary */
279 	uint64_t (*clip) (struct GMT_CTRL *, double *, double *, uint64_t, double **, double **, uint64_t *);	/* Pointer to functions that clip a polygon to fit inside map */
280 	double (*left_edge) (struct GMT_CTRL *, double);	/* Pointers to functions that return left edge of map */
281 	double (*right_edge) (struct GMT_CTRL *, double);	/* Pointers to functions that return right edge of map */
282 	struct GMT_DIST dist[3];		/* struct with pointers to functions/scales returning distance between two points points */
283 	bool (*near_lines_func) (struct GMT_CTRL *, double, double, struct GMT_DATATABLE *, unsigned int, double *, double *, double *);	/* Pointer to function returning distance to nearest line among a set of lines */
284 	bool (*near_a_line_func) (struct GMT_CTRL *, double, double, uint64_t, struct GMT_DATASEGMENT *, unsigned int, double *, double *, double *);	/* Pointer to function returning distance to line */
285 	bool (*near_point_func) (struct GMT_CTRL *, double, double, struct GMT_DATATABLE *, double);	/* Pointer to function returning distance to nearest point */
286 	unsigned int (*wrap_around_check) (struct GMT_CTRL *, double *, double, double, double, double, double *, double *, unsigned int *);	/* Does x or y wrap checks */
287 	double (*azimuth_func) (struct GMT_CTRL *, double, double, double, double, bool);	/* Pointer to function returning azimuth between two points points */
288 	void (*get_crossings) (struct GMT_CTRL *, double *, double *, double, double, double, double);	/* Returns map crossings in x or y */
289 	double (*geodesic_meter) (struct GMT_CTRL *, double, double, double, double);	/* pointer to geodesic function returning distance between two points points in meter */
290 	double (*geodesic_az_backaz) (struct GMT_CTRL *, double, double, double, double, bool);	/* pointer to geodesic function returning azimuth or backazimuth between two points points */
291 	void (*second_point) (struct GMT_CTRL *, double, double, double, double, double *, double *, double *);	/* pointer to function returning second point (and bakaz) given first point, az, and dist */
292 };
293 
294 struct GMT_GCAL {	/* (proleptic) Gregorian calendar  */
295 	int year;		/* signed; negative and 0 allowed  */
296 	unsigned int month;	/* Always between 1 and 12  */
297 	unsigned int day_m;	/* Day of month; always in 1 - 31  */
298 	unsigned int day_y;	/* Day of year; 1 through 366  */
299 	unsigned int day_w;	/* Day of week; 0 (Sun) through 6 (Sat)  */
300 	int iso_y;		/* ISO year; not necessarily == year */
301 	unsigned int iso_w;	/* ISO week of iso_y; must be in 1 -- 53  */
302 	unsigned int iso_d;	/* ISO day of iso_w; uses 1 (Mon) through 7 (Sun)  */
303 	unsigned int hour;	/* 00 through 23  */
304 	unsigned int min;	/* 00 through 59  */
305 	double sec;		/* 00 through 59.xxxx; leap not yet handled  */
306 };
307 
308 struct GMT_Y2K_FIX {	/* The issue that refuses to go away... */
309 	unsigned int y2_cutoff;	/* The 2-digit offset year.  If y2 >= y2_cuttoff, add y100 else add y200 */
310 	int y100;	/* The multiple of 100 to add to the 2-digit year if we are above the time_Y2K_offset_year */
311 	int y200;	/* The multiple of 100 to add to the 2-digit year if we are below the time_Y2K_offset_year */
312 };
313 
314 struct GMT_MOMENT_INTERVAL {
315 	struct GMT_GCAL	cc[2];
316 	double dt[2];
317 	double sd[2];		/* Seconds since the start of the day.  */
318 	int64_t rd[2];
319 	unsigned int step;
320 	char unit;
321 };
322 
323 struct GMT_TRUNCATE_TIME {		/* Used when TIME_IS_INTERVAL is not OFF */
324 	struct GMT_MOMENT_INTERVAL T;
325 	unsigned int direction;		/* 0 [+] to center on next interval, 1 [-] for previous interval */
326 };
327 
328 struct GMT_TIME_CONV {		/* Holds all time-related parameters */
329 	struct GMT_TRUNCATE_TIME truncate;
330 	struct GMT_Y2K_FIX Y2K_fix;		/* Used to convert 2-digit years to 4-digit years */
331 	time_t tic;				/* Last system time marker */
332 	int64_t today_rata_die;			/* The rata die of current day at start of program */
333 };
334 
335 struct GMT_LANGUAGE {		/* Language-specific text strings for calendars, map annotations, etc. */
336 	char month_name[4][12][GMT_LEN16];	/* Full, short, 1-char, and short (upper case) month names */
337 	char day_name[3][7][GMT_LEN16];	/* Full, short, and 1-char weekday names */
338 	char week_name[3][GMT_LEN16];	/* Full, short, and 1-char versions of the word Week */
339 	char cardinal_name[3][4][GMT_LEN16];	/* Full, and abbreviated (map annot., direction) versions of compass directions */
340 };
341 
342 struct GMT_INIT { /* Holds misc run-time parameters */
343 	unsigned int n_custom_symbols;
344 	const char *module_name;      /* Name of current module or NULL if not set */
345 	const char *module_lib;       /* Name of current shared library or NULL if not set */
346 	/* The rest of the struct contains pointers that may point to memory not included by this struct */
347 	char *runtime_bindir;         /* Directory that contains the main exe at run-time */
348 	char *runtime_libdir;         /* Directory that contains the main shared lib at run-time */
349 	char *runtime_library;        /* Name of the main shared library at run-time */
350 	char *runtime_plugindir;      /* Directory that contains the main supplemental plugins at run-time */
351 	char *history[GMT_N_UNIQUE];  /* The internal gmt.history information */
352 	struct GMT_CUSTOM_SYMBOL **custom_symbol; /* For custom symbol plotting in psxy[z]. */
353 };
354 
355 struct GMT_PLOT {		/* Holds all plotting-related parameters */
356 	uint64_t n;			/* Number of such points */
357 	size_t n_alloc;			/* Size of allocated plot arrays */
358 	bool r_theta_annot;		/* true for special r-theta map annotation (see gmtlib_get_annot_label) */
359 	bool substitute_pi;		/* true when -R or -B was given with pi and we want to use pi in annotations if possible */
360 	unsigned int mode_3D;		/* Determines if we draw fore and/or back 3-D box lines [Default is both] */
361 	unsigned int *pen;		/* Pen (PSL_MOVE = up, PSL_DRAW = down) for these points */
362 	unsigned int color_seq_id[2];	/* Next sequential color entries (table,segment) in the auto-CPT list of colors from COLOR_SET */
363 	struct GMT_PLOT_CALCLOCK calclock;
364 	/* The rest of the struct contains pointers that may point to memory not included by this struct */
365 	double *x;			/* Holds the x/y (inches) of a line to be plotted */
366 	double *y;
367 	double gridline_spacing[2];		/* Holds last gridline spacing used for this plot, via gmt.history */
368 	char format[3][2][GMT_LEN256];	/* Keeps the 6 formats for dd:mm:ss plot output */
369 	struct GMT_SUBPLOT panel;	/* Current subplot panel settings */
370 	struct GMT_INSET inset;		/* Current inset settings */
371 };
372 
373 struct GMT_CURRENT {
374 	/* These are internal parameters that need to be passed around between
375 	 * many GMT functions.  These values may change by user interaction. */
376 	struct GMT_DEFAULTS setting;	/* Holds all GMT defaults parameters */
377 	struct GMT_IO io;		/* Holds all i/o-related parameters */
378 	struct GMT_PROJ proj;		/* Holds all projection-related parameters */
379 	struct GMT_MAP map;		/* Holds all projection-related parameters */
380 	struct GMT_PLOT plot;		/* Holds all plotting-related parameters */
381 	struct GMT_TIME_CONV time;	/* Holds all time-related parameters */
382 	struct GMT_LANGUAGE language;	/* Holds all language-related parameters */
383 	struct GMT_PSL ps;		/* Hold parameters related to PSL setup */
384 	struct GMT_OPTION *options;	/* Pointer to current program's options */
385 	struct GMT_FFT_HIDDEN fft;	/* Structure with info that must survive between FFT calls */
386 #ifdef HAVE_GDAL
387 	struct GMT_GDALREAD_IN_CTRL  gdal_read_in;  /* Hold parameters related to options transmitted to gdalread */
388 	struct GMT_GDALREAD_OUT_CTRL gdal_read_out; /* Hold parameters related to options transmitted from gdalread */
389 	struct GMT_GDALWRITE_CTRL    gdal_write;    /* Hold parameters related to options transmitted to gdalwrite */
390 #endif
391 };
392 
393 struct GMT_INTERNAL {
394 	/* These are internal parameters that need to be passed around between
395 	 * many GMT functions.  These may change during execution but are not
396 	 * modified directly by user interaction. */
397 	unsigned int func_level;	/* Keeps track of what level in a nested GMT_func calling GMT_func etc we are.  GMT_CONTROLLER (0) is initiating process (e.g. gmt.c) */
398 	bool mem_set;			/* true when we have initialized the tmp memory already */
399 	bool sample_along_arc;		/* true when sample1d need exact sampling along the arc */
400 	size_t mem_cols;		/* Current number of allocated columns for temp memory */
401 	size_t mem_rows;		/* Current number of allocated rows for temp memory */
402 	size_t mem_txt_alloc;
403 	size_t mem_txt_dup;
404 	double **mem_coord;		/* Columns of temp memory */
405 	char **mem_txt;			/* For temp text */
406 	struct MEMORY_TRACKER *mem_keeper;	/* Only filled when #ifdef MEMDEBUG  */
407 #ifdef DEBUG
408 	bool gridline_debug;
409 	char gridline_kind;
410 	double gridline_val;
411 #endif
412 };
413 
414 struct GMT_SHORTHAND {	/* Holds information for each grid extension shorthand read from the user's .gmtio file */
415 	char *suffix; /* suffix of file */
416 	char *format; /* format: ff/scale/offset/invalid */
417 };
418 
419 struct GMT_SESSION {
420 	/* These are parameters that is set once at the start of a GMT session and
421 	 * are essentially read-only constants for the duration of the session */
422 	FILE *std[3];			/* Pointers for standard input, output, and error */
423 	void * (*input_ascii) (struct GMT_CTRL *, FILE *, uint64_t *, int *);	/* Pointer to function reading ASCII tables only */
424 	int (*output_ascii) (struct GMT_CTRL *, FILE *, uint64_t, double *, char *);	/* Pointer to function writing ASCII tables only */
425 	unsigned int n_fonts;		/* Total number of fonts returned by gmtinit_init_fonts */
426 	unsigned int n_user_media;	/* Total number of user media returned by gmtinit_load_user_media */
427 	size_t min_meminc;		/* with -DMEMDEBUG, sets min/max memory increments */
428 	size_t max_meminc;
429 	float f_NaN;			/* Holds the IEEE NaN for floats */
430 	double d_NaN;			/* Holds the IEEE NaN for doubles */
431 	double no_rgb[4];		/* To hold {-1, -1, -1, 0} when needed */
432 	double u2u[4][4];		/* u2u is the 4x4 conversion matrix for cm, inch, m, pt */
433 	char unit_name[4][GMT_LEN8];	/* Full name of the 4 units cm, inch, m, pt */
434 	struct GMT_HASH rgb_hashnode[GMT_N_COLOR_NAMES];/* Used to translate colornames to r/g/b */
435 	bool rgb_hashnode_init;		/* true once the rgb_hashnode array has been loaded; false otherwise */
436 	unsigned int n_shorthands;			/* Length of array with shorthand information */
437 	char *grdformat[GMT_N_GRD_FORMATS];	/* Type and description of grid format */
438 	int (*readinfo[GMT_N_GRD_FORMATS]) (struct GMT_CTRL *, struct GMT_GRID_HEADER *);	/* Pointers to grid read header functions */
439 	int (*updateinfo[GMT_N_GRD_FORMATS]) (struct GMT_CTRL *, struct GMT_GRID_HEADER *);	/* Pointers to grid update header functions */
440 	int (*writeinfo[GMT_N_GRD_FORMATS]) (struct GMT_CTRL *, struct GMT_GRID_HEADER *);	/* Pointers to grid write header functions */
441 	int (*readgrd[GMT_N_GRD_FORMATS]) (struct GMT_CTRL *, struct GMT_GRID_HEADER *, gmt_grdfloat *, double *, unsigned int *, unsigned int);	/* Pointers to grid read functions */
442 	int (*writegrd[GMT_N_GRD_FORMATS]) (struct GMT_CTRL *, struct GMT_GRID_HEADER *, gmt_grdfloat *, double *, unsigned int *, unsigned int);	/* Pointers to grid read functions */
443 	int (*fft1d[k_n_fft_algorithms]) (struct GMT_CTRL *, gmt_grdfloat *, unsigned int, int, unsigned int);	/* Pointers to available 1-D FFT functions (or NULL if not configured) */
444 	int (*fft2d[k_n_fft_algorithms]) (struct GMT_CTRL *, gmt_grdfloat *, unsigned int, unsigned int, int, unsigned int);	/* Pointers to available 2-D FFT functions (or NULL if not configured) */
445 	/* This part contains pointers that may point to additional memory outside this struct */
446 	char *DCWDIR;			/* Path to the DCW directory */
447 	char *GSHHGDIR;			/* Path to the GSHHG directory */
448 	char *SHAREDIR;			/* Path to the GMT share directory */
449 	char *HOMEDIR;			/* Path to the user's home directory */
450 	char *USERDIR;			/* Path to the user's GMT data directory */
451 	char *CACHEDIR;			/* Path to the user's GMT cache directory for downloaded files */
452 	char *DATADIR;			/* Path to one or more directories with data sets */
453 	char *TMPDIR;			/* Path to the directory directory for isolation mode */
454 	char *CUSTOM_LIBS;		/* Names of one or more comma-separated GMT-compatible shared libraries */
455 	char *DATASERVER;		/* URL where to get remote @files */
456 	char **user_media_name;		/* Length of array with custom media dimensions */
457 	struct GMT_FONTSPEC *font;		/* Array with font names and height specification */
458 	struct GMT_MEDIA *user_media;		/* Array with custom media dimensions */
459 	struct GMT_SHORTHAND *shorthand;	/* Array with info about shorthand file extension magic */
460 };
461 
462 struct GMT_CTRL {
463 	/* Master structure for a GMT invocation.  All internal settings for GMT is accessed here */
464 	struct GMT_SESSION session;	/* Structure with all values that do not change throughout a session */
465 	struct GMT_INIT init;		/* Structure with all values that do not change in a GMT_func call */
466 	struct GMT_COMMON common;	/* Structure with all the common GMT command settings (-R -J ..) */
467 	struct GMT_CURRENT current;	/* Structure with all the GMT items that can change during execution, such as defaults settings (pens, colors, fonts.. ) */
468 	struct GMT_INTERNAL hidden;	/* Internal global variables that are not to be changed directly by users */
469 	struct PSL_CTRL *PSL;		/* Pointer to the PSL structure [or NULL] */
470 	struct GMTAPI_CTRL *parent;	/* Owner of this structure [or NULL]; gives access to the API from functions being passed *GMT only */
471 };
472 
473 /* p_to_io_func is used as a pointer to functions such as GMT_read_d in assignments
474  * and is used to declare gmtlib_get_io_ptr in gmt_io.c and gmt_prototypes.h */
475 typedef int (*p_to_io_func) (struct GMT_CTRL *, FILE *, uint64_t, double *);
476 
477 /* Exit or return:  For some environments (e.g., Matlab) we do not
478    wish to call the system "Exit" as it brings down Matlab as well.  In those cases
479    we instead call return and let Matlab client deal with any follow-up.  This
480    decision is set in GMT_Create_Session via its flags.  While exit always returns
481    an integer code, the return functions may have to return other types, hence we
482    let GMT_exit possibly call exit, else it does nothing.  Thus, calls to GMT_exit
483    must be followed by return <type> so that we return where we said we would. */
484 
485 /* If GMT is not set or do_not_exit is false then we call system exit, else we move along */
GMT_exit(struct GMT_CTRL * GMT,int code)486 static inline void GMT_exit (struct GMT_CTRL *GMT, int code) {
487 	if (GMT == NULL || GMT->parent == NULL || GMT->parent->do_not_exit == false)
488 		exit (code);
489 }
490 
491 #endif  /* GMT_TYPES_H */
492