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

Let GMT_Put_Vector accept GMT_DATETIME as type #3396

Merged
merged 10 commits into from
May 29, 2020
4 changes: 3 additions & 1 deletion doc/rst/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,9 @@ For vectors the same principles apply:
where ``V`` is the :ref:`GMT_VECTOR <struct-vector>` created by GMT_Create_Data_, ``col`` is the vector
column in question, ``type`` is one of the
recognized data :ref:`types <tbl-types>` used for this vector, and ``vector`` is
a pointer to this custom vector.
a pointer to this custom vector. In addition, ``type`` may be also **GMT_DATETIME**, in which case
we expect an array of strings with ISO datetime strings and we do the conversion to internal
GMT time and allocate a vector to hold the result in the given ``col``.
To extract a custom vector from an output :ref:`GMT_VECTOR <struct-vector>` you can use

.. _GMT_Get_Vector:
Expand Down
26 changes: 24 additions & 2 deletions src/gmt_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ GMT_LOCAL inline struct GMT_VECTOR * gmtapi_get_vector_data (struct GMT_VECTOR
GMT_LOCAL inline struct GMT_MATRIX * gmtapi_get_matrix_data (struct GMT_MATRIX *ptr) {return (ptr);}
GMT_LOCAL inline struct GMT_POSTSCRIPT * gmtapi_get_postscript_data (struct GMT_POSTSCRIPT *ptr) {return (ptr);}
GMT_LOCAL inline struct GMT_PALETTE * gmtapi_get_palette_data (struct GMT_PALETTE *ptr) {return (ptr);}
GMT_LOCAL inline char ** gmtapi_get_char_char_ptr (char **ptr) {return (ptr);}

/*! If API is not set or do_not_exit is false then we call system exit, else we move along.
* This is required for some external interfaces where calling exit would bring down the
Expand Down Expand Up @@ -12728,11 +12729,17 @@ int GMT_Change_Layout_ (unsigned int *family, char *code, unsigned int *mode, vo

/* Deal with assignments of custom vectors and matrices to GMT containers */

int GMT_Put_Vector (void *API, struct GMT_VECTOR *V, unsigned int col, unsigned int type, void *vector) {
int GMT_Put_Vector (void *V_API, struct GMT_VECTOR *V, unsigned int col, unsigned int type, void *vector) {
/* Hooks a users custom vector onto V's column array and sets the type.
* It is the user's responsibility to pass correct type for the given vector.
* We also check that the number of rows have been set earlier. */
struct GMTAPI_CTRL *API = NULL;
struct GMT_VECTOR_HIDDEN *VH = NULL;
char **dt = NULL;
double *t_vector = NULL;
uint64_t row, n_bad = 0;

API = gmtapi_get_api_ptr (V_API);
if (API == NULL) return_error (API, GMT_NOT_A_SESSION);
if (V == NULL) return_error (API, GMT_PTR_IS_NULL);
if (V->n_rows == 0) return_error (API, GMT_DIM_TOO_SMALL);
Expand All @@ -12748,12 +12755,27 @@ int GMT_Put_Vector (void *API, struct GMT_VECTOR *V, unsigned int col, unsigned
case GMT_SHORT: V->type[col] = GMT_SHORT; V->data[col].si2 = vector; break;
case GMT_UCHAR: V->type[col] = GMT_UCHAR; V->data[col].uc1 = vector; break;
case GMT_CHAR: V->type[col] = GMT_CHAR; V->data[col].sc1 = vector; break;
case GMT_DATETIME: /* Must convert from string-time to double */
if ((dt = gmtapi_get_char_char_ptr (vector)) == NULL) {
GMT_Report (API, GMT_MSG_ERROR, "Datetime string array is NULL\n");
return GMT_MEMORY_ERROR;
}
if ((t_vector = malloc (V->n_rows * sizeof(double))) == NULL) {
GMT_Report (API, GMT_MSG_ERROR, "Unable to allocate array of %" PRIu64 " doubles for converted datetime strings\n", V->n_rows);
return GMT_MEMORY_ERROR;
}
for (row = 0; row < V->n_rows; row++) {
if (gmt_scanf (API->GMT, dt[row], GMT_IS_ABSTIME, &(t_vector[row])) == GMT_IS_NAN) n_bad++;
}
V->type[col] = GMT_DOUBLE; V->data[col].f8 = t_vector;
if (n_bad) GMT_Report (API, GMT_MSG_ERROR, "Unable to parse %" PRIu64 " datetime strings (ISO datetime format required)\n", n_bad);
break;
default:
return_error (API, GMT_NOT_A_VALID_TYPE);
break;
}
VH = gmt_get_V_hidden (V);
VH->alloc_mode[col] = GMT_ALLOC_EXTERNALLY; /* Since it clearly is a user array */
VH->alloc_mode[col] = (type == GMT_DATETIME) ? GMT_ALLOC_INTERNALLY : GMT_ALLOC_EXTERNALLY;
return GMT_NOERROR;
}

Expand Down