Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax column content check for pstext #8045

Merged
merged 4 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/gmt_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -8408,6 +8408,7 @@ void * GMT_Create_Session (const char *session, unsigned int pad, unsigned int m
API->runmode = mode & GMT_SESSION_RUNMODE; /* If nonzero we set up modern GMT run-mode, else classic */
API->no_history = mode & GMT_SESSION_NOHISTORY; /* If nonzero we disable the gmt.history mechanism (shorthands) entirely */
if (API->internal) API->leave_grid_scaled = 1; /* Do NOT undo grid scaling after write since modules do not reuse grids we save some CPU */
API->n_numerical_columns = GMT_NOTSET;
if (session) { /* Pick up a tag for this session */
char *tmptag = strdup (session);
API->session_tag = strdup (basename (tmptag)); /* Only used in reporting and error messages */
Expand Down
17 changes: 14 additions & 3 deletions src/gmt_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3390,18 +3390,24 @@ bool gmtlib_maybe_abstime (struct GMT_CTRL *GMT, char *txt) {
gmt_M_unused (GMT);

if (L > 24U) return false; /* Most likely too long to be an absolute time, e.g. 31-SEP-2000T13:45:31.3333 is 24 char long */
if (L < 4U) return false; /* Most likely too short to be an absolute time, e.g. 2001T is 5 char long */
for (k = 0; k < L; k++) { /* Count slashes and dashes */
if (txt[k] == '-') { n_dash++; if (start == -1) start = k; }
else if (txt[k] == '/') { n_slash++; if (start == -1) start = k; }
else if (txt[k] == ':') { n_colon++; if (start == -1) start = k; }
}
if ((c = strchr (txt, 'T'))) { /* Maybe the T between date and clock */
size_t first = (size_t) (c - txt); /* Position of that T must be either 0, 4, or between 9 and 12 */
if (first == 0 || first == 4 || (first > 8 && first < 13)) return true; /* Absolute date detected (most likely) */
if (first == 0 || first == 4 || (first > 8 && first < 13)) {
if (txt[first+1] == '\0' || isdigit (txt[first+1])) /* Absolute date detected (most likely), e.g. 2001T, T14:45 */
return true;
else
return false;
}
}
else if (n_colon && n_slash == 0 && n_dash == 0) /* No 'T', got xxx..:yy...[:ss...] probably */
else if (n_colon && n_slash == 0 && n_dash <= 1) /* No 'T', got [-]xxx..:yy...[:ss...] probably */
return false;
else if (txt[0] == '-' || txt[0] == '+') /* No 'T' and start with a sign is likely non-time related */
else if (txt[0] == '-' || txt[0] == '+') /* No 'T' and starts with a sign is likely non-time related */
return false; /* datestring most likely do not start with a sign. */
/* Maybe user forgot the 'T' flag? */
if (start > 0 && ((n_dash + n_slash) == 2) && (n_dash == 2 || n_slash == 2)) /* Absolute date detected (most likely) */
Expand Down Expand Up @@ -3529,6 +3535,7 @@ GMT_LOCAL unsigned int gmtio_examine_current_record (struct GMT_CTRL *GMT, char
* the FORMAT_DATE_IN, FORMAT_CLOCK_IN settings.
*/
unsigned int ret_val = GMT_READ_DATA, pos = 0, col = 0, k, *type = NULL;
unsigned int n_numeric_cols = (GMT->parent->n_numerical_columns == GMT_NOTSET) ? UINT_MAX : GMT->parent->n_numerical_columns;
int got;
enum gmt_col_enum phys_col_type;
bool found_text = false;
Expand All @@ -3543,6 +3550,10 @@ GMT_LOCAL unsigned int gmtio_examine_current_record (struct GMT_CTRL *GMT, char
found_text = true; /* We stop right here, return flag as nan and hence n_columns will be col. */
got = GMT_IS_NAN;
}
else if (n_numeric_cols && col >= n_numeric_cols) { /* No point trying to determine what text, font, justification it is */
got = GMT_IS_NAN;
col++;
}
else { /* Auto-guess from examining the token */
phys_col_type = gmtio_physical_coltype (GMT, col);
if (phys_col_type == GMT_IS_ABSTIME || gmtlib_maybe_abstime (GMT, token)) { /* Is or might be ISO Absolute time; if not we got junk (and got -> GMT_IS_NAN) */
Expand Down
1 change: 1 addition & 0 deletions src/gmt_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ struct GMTAPI_CTRL {
unsigned int verbose; /* Used until GMT is set up */
unsigned int n_tmp_headers; /* Number of temporarily held table headers */
unsigned int terminal_width; /* Width of the terminal */
unsigned int n_numerical_columns; /* 0 except for pstext where there will be 2-4 numerical leading columns before text */
bool registered[2]; /* true if at least one source/destination has been registered (in and out) */
bool io_enabled[2]; /* true if access has been allowed (in and out) */
bool module_input; /* true when we are about to read inputs to the module (command line) */
Expand Down
2 changes: 1 addition & 1 deletion src/gmt_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -18272,7 +18272,7 @@ bool gmt_no_pstext_input (struct GMTAPI_CTRL *API, char *arg) {
/* Determine if -F is such that there is nothing to read */
if (strstr (arg, "+c") == NULL) return false; /* Without +c there will be input */
if (strstr (arg, "+t") == NULL) return false; /* Without +t there will be input */
if ((c = strstr (arg, "+A")) && (c[2] == '+' || c[2] == '\0')) return false; /* With +a and no arg there must be input */
if ((c = strstr (arg, "+A")) && (c[2] == '+' || c[2] == '\0')) return false; /* With +A and no arg there must be input */
if ((c = strstr (arg, "+a")) && (c[2] == '+' || c[2] == '\0')) return false; /* With +a and no arg there must be input */
if ((c = strstr (arg, "+j")) && (c[2] == '+' || c[2] == '\0')) return false; /* With +j and no arg there must be input */
if ((c = strstr (arg, "+f")) && (c[2] == '+' || c[2] == '\0')) return false; /* With +f and no arg there must be input */
Expand Down
13 changes: 11 additions & 2 deletions src/pstext.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ struct PSTEXT_CTRL {
bool get_xy_from_justify; /* True if +c was given and we just get it from input */
bool word; /* True if we are to select a single word from the trailing text as the label */
bool no_input; /* True if we give a single static text and place it via +c */
bool no_xy_coord; /* If -F+c given then we dont read/parse two coordinates */
struct GMT_FONT font;
double angle;
int justify, R_justify, nread, first, w_col;
int justify, R_justify, nread, nread_numerics, first, w_col;
unsigned int get_text; /* 0 = from data record, 1 = segment label (+l), 2 = segment header (+h), 3 = specified text (+t), 4 = format z using text (+z) */
char read[4]; /* Contains a|A, c, f, and/or j in order required to be read from input */
char *text;
Expand Down Expand Up @@ -489,6 +490,7 @@ static int parse (struct GMT_CTRL *GMT, struct PSTEXT_CTRL *Ctrl, struct GMT_OPT
if (p[1] == '+' || p[1] == '\0') { /* Must read angle from input */
Ctrl->F.read[Ctrl->F.nread] = p[0];
Ctrl->F.nread++;
Ctrl->F.nread_numerics++;
}
else /* Gave a fixed angle here */
Ctrl->F.angle = atof (&p[1]);
Expand Down Expand Up @@ -525,6 +527,7 @@ static int parse (struct GMT_CTRL *GMT, struct PSTEXT_CTRL *Ctrl, struct GMT_OPT
if (!explicit_justify) /* If not set explicitly, default to same justification as corner */
Ctrl->F.justify = Ctrl->F.R_justify;
}
Ctrl->F.no_xy_coord = true; /* Not reading lon,lat or x,y in this case */
break;
case 'l': /* Segment label request */
if (Ctrl->F.get_text) {
Expand Down Expand Up @@ -862,7 +865,12 @@ EXTERN_MSC int GMT_pstext (void *V_API, int mode, void *args) {
GMT_Report (API, GMT_MSG_INFORMATION, "Processing input text table data\n");
pstext_load_parameters_pstext (GMT, &T, Ctrl); /* Pass info from Ctrl to T */
tcol_f = 2 + Ctrl->Z.active; tcol_s = tcol_f + 1;

/* Since pstext input is complicated we need to help gmtio_examine_current_record by determining how many leading numerical columns to expect */
API->n_numerical_columns = (Ctrl->F.no_xy_coord) ? 0 : 2; /* Normally first 2 columns are x/y coordinates but not if -F+c */
if (Ctrl->F.get_text == GET_CMD_FORMAT) API->n_numerical_columns++; /* Expect a 3rd column value for formatting */
if (Ctrl->Z.active) API->n_numerical_columns++; /* Expect a 3-D z coordinate */
if (Ctrl->F.nread_numerics) API->n_numerical_columns++; /* Will read angle from input file */
fprintf (stderr, "ncol = %d\n", API->n_numerical_columns);
n_expected_cols = 2 + Ctrl->Z.active + Ctrl->F.nread + GMT->common.t.n_transparencies; /* Normal number of columns to read, plus any text. This includes x,y */
if (Ctrl->M.active) n_expected_cols += 3;
no_in_txt = (Ctrl->F.get_text > 1); /* No text in the input record */
Expand Down Expand Up @@ -1503,6 +1511,7 @@ EXTERN_MSC int GMT_pstext (void *V_API, int mode, void *args) {

GMT->current.map.is_world = old_is_world;
GMT->current.io.scan_separators = GMT_TOKEN_SEPARATORS; /* Reset */
API->n_numerical_columns = GMT_NOTSET;

gmt_map_basemap (GMT);
gmt_plane_perspective (GMT, -1, 0.0);
Expand Down