-
Notifications
You must be signed in to change notification settings - Fork 375
/
Copy pathfigure.c
190 lines (159 loc) · 7.89 KB
/
figure.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*--------------------------------------------------------------------
*
* Copyright (c) 1991-2025 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
* See LICENSE.TXT file for copying and redistribution conditions.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 3 or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* Contact info: www.generic-mapping-tools.org
*--------------------------------------------------------------------*/
/*
* Author: Paul Wessel
* Date: 23-Jun-2017
* Version: 6 API
*
* Brief synopsis: gmt figure sets name, formats and options for current figure.
* gmt figure <prefix> [<formats>] [<psconvertoptions>]
*/
#include "gmt_dev.h"
#define THIS_MODULE_CLASSIC_NAME "figure"
#define THIS_MODULE_MODERN_NAME "figure"
#define THIS_MODULE_LIB "core"
#define THIS_MODULE_PURPOSE "Set attributes for the current modern mode session figure"
#define THIS_MODULE_KEYS ""
#define THIS_MODULE_NEEDS ""
#define THIS_MODULE_OPTIONS "V"
#include "gmt_gsformats.h"
static int usage (struct GMTAPI_CTRL *API, int level) {
const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE);
if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR);
GMT_Usage (API, 0, "usage: %s <prefix> [<formats>] [<psconvertoptions>] [%s]\n", name, GMT_V_OPT);
if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS);
GMT_Message (API, GMT_TIME_NONE, " REQUIRED ARGUMENTS:\n");
GMT_Usage (API, 1, "\n<prefix>");
GMT_Usage (API, -2, "is the prefix to use for the registered figure\'s name.");
GMT_Message (API, GMT_TIME_NONE, "\n OPTIONAL ARGUMENTS:\n");
GMT_Usage (API, 1, "\n<formats>");
GMT_Usage (API, -2, "Contains one or more comma-separated formats [%s].", gmt_session_format[API->GMT->current.setting.graphics_format]);
GMT_Usage (API, -2, "\nChoose from these valid extensions:");
GMT_Usage (API, 3, "bmp: MicroSoft BitMap.");
GMT_Usage (API, 3, "eps: Encapsulated PostScript.");
GMT_Usage (API, 3, "jpg: Joint Photographic Experts Group format.");
GMT_Usage (API, 3, "pdf: Portable Document Format [Default].");
GMT_Usage (API, 3, "png: Portable Network Graphics.");
GMT_Usage (API, 3, "PNG: Portable Network Graphics (with transparency layer).");
GMT_Usage (API, 3, "ppm: Portable Pixel Map.");
GMT_Usage (API, 3, "ps: PostScript.");
GMT_Usage (API, 3, "tif: Tagged Image Format File.");
GMT_Usage (API, -2, "Two raster modifiers may be appended:");
GMT_Usage (API, 3, "+m For bmp, png, jpg, and tif, make a monochrome (grayscale) image [color].");
GMT_Usage (API, 3, "+q Append quality in 0-100 for jpg only [%d].", GMT_JPEG_DEF_QUALITY);
GMT_Usage (API, 1, "\n<psconvertoptions>");
GMT_Usage (API, -2, "Contains one or more comma-separated options that"
" will be passed to psconvert when preparing this figure [%s].", GMT_SESSION_CONVERT);
GMT_Usage (API, -2, "\nThe valid subset of psconvert options are");
GMT_Usage (API, -3, "A[<args>],C<args>,D<dir>,E<dpi>,H<factor>,I<args>,Mb|f<file>,N<args>,Q<args>,S");
GMT_Usage (API, -2, "See the psconvert documentation for details.");
GMT_Option (API, "V,;");
return (GMT_MODULE_USAGE);
}
#define GMT_IS_FMT 0
#define GMT_IS_OPT 1
static int parse (struct GMT_CTRL *GMT, struct GMT_OPTION *options) {
/* This parses the options provided to figure and sets parameters in CTRL.
* Any GMT common options will override values set previously by other commands.
* It also replaces any file names specified as input or output with the data ID
* returned when registering these sources/destinations with the API.
*/
unsigned int n_errors = 0, pos = 0;
int arg_category = GMT_NOTSET;
char p[GMT_LEN256] = {""};
struct GMT_OPTION *opt = NULL;
struct GMTAPI_CTRL *API = GMT->parent;
if ((opt = options) == NULL) { /* Gave no arguments */
if (GMT->parent->external) return GMT_NOERROR;
GMT_Report (API, GMT_MSG_ERROR, "Required figure name not specified!\n");
return GMT_PARSE_ERROR;
}
gmt_filename_set (opt->arg);
/* Gave a figure prefix so can go on to check optional items */
opt = opt->next; /* Skip the figure prefix since we don't need to check it here */
while (opt) {
if (opt->option == 'I') { opt = opt->next; continue; } /* Skip the special undocumented movie option here */
gmt_filename_set (opt->arg);
arg_category = GMT_NOTSET; /* We know noothing */
pos = 0;
while (gmt_strtok (opt->arg, ",", &pos, p)) { /* Check args to determine what kind it is */
if (arg_category == GMT_NOTSET)
arg_category = (strlen (p) == 1 || strchr (p, '+') || (isupper (p[0]) && strcmp (p, "PNG"))) ? GMT_IS_OPT : GMT_IS_FMT;
if (arg_category == GMT_IS_FMT) { /* Got format specifications, check if OK */
int k = gmt_get_graphics_id (GMT, p);
if (k == GMT_NOTSET) {
GMT_Report (API, GMT_MSG_ERROR, "Unrecognized graphics format %s\n", p);
n_errors++;
}
}
else { /* Check if valid psconvert options */
if (!strchr (GMT_PSCONVERT_LIST, p[0])) {
GMT_Report (API, GMT_MSG_ERROR, "Unrecognized psconvert option -%s\n", p);
n_errors++;
}
}
}
opt = opt->next;
if (opt && opt->option == 'V') opt = opt->next; /* Skip the verbose option */
}
/* If we get here without errors then we know the input arguments are all valid */
return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR);
}
#define bailout(code) {gmt_M_free_options (mode); return (code);}
#define Return(code) {gmt_end_module (GMT, GMT_cpy); bailout (code);}
EXTERN_MSC int GMT_figure (void *V_API, int mode, void *args) {
int error = 0;
char *arg = NULL, *param_file = NULL;
struct GMT_CTRL *GMT = NULL, *GMT_cpy = NULL;
struct GMT_OPTION *options = NULL, *opt = NULL;
struct GMTAPI_CTRL *API = gmt_get_api_ptr (V_API); /* Cast from void to GMTAPI_CTRL pointer */
/*----------------------- Standard module initialization and parsing ----------------------*/
if (API == NULL) return (GMT_NOT_A_SESSION);
if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */
options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */
if (options && !API->external) {
if (options->option == GMT_OPT_USAGE) bailout (usage (API, GMT_USAGE)); /* Return the usage message */
if (options->option == GMT_OPT_SYNOPSIS) bailout (usage (API, GMT_SYNOPSIS)); /* Return the synopsis */
}
if (API->GMT->current.setting.run_mode == GMT_CLASSIC) {
GMT_Report (API, GMT_MSG_ERROR, "Not available in classic mode\n");
return (GMT_NOT_MODERN_MODE);
}
/* Parse the command-line arguments */
if ((GMT = gmt_init_module (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_KEYS, THIS_MODULE_NEEDS, NULL, &options, &GMT_cpy)) == NULL) bailout (API->error); /* Save current state */
if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error);
if ((error = parse (GMT, options)) != 0) Return (error);
/*---------------------------- This is the figure main code ----------------------------*/
if (options) {
if ((opt = GMT_Find_Option (API, 'I', options))) { /* Magic option issued by movie to pass parameter file */
if (opt->arg[0]) param_file = strdup (opt->arg); /* Isolate the parameter file */
GMT_Delete_Option (API, opt, &options);
}
arg = GMT_Create_Cmd (API, options);
}
if (gmt_add_figure (API, arg, param_file))
error = GMT_RUNTIME_ERROR;
if (options) GMT_Destroy_Cmd (API, &arg);
opt = options;
while (opt) {
gmt_filename_get (opt->arg);
opt = opt->next;
}
gmt_reset_history (GMT); /* Prevent gmt figure from copying previous history to this new fig */
if (param_file) gmt_M_str_free (param_file);
Return (error);
}