| 1623 | } |
| 1624 | |
| 1625 | GMT_LOCAL char ** gmtapi_process_keys (void *V_API, const char *string, char type, struct GMT_OPTION *head, int *n_to_add, unsigned int *n_items) { |
| 1626 | /* Turn the comma-separated list of 3-char codes in string into an array of such codes. |
| 1627 | * In the process, replace any ?-types with the selected type if type is not 0. |
| 1628 | * We return the array of strings and its number (n_items). */ |
| 1629 | size_t len, k, kk, n; |
| 1630 | int o_id = GMT_NOTSET, family = GMT_NOTSET, geometry = GMT_NOTSET; |
| 1631 | bool change_type = false; |
| 1632 | char **s = NULL, *next = NULL, *tmp = NULL, magic = 0, revised[GMT_LEN64] = {""}; |
| 1633 | struct GMT_OPTION *opt = NULL; |
| 1634 | struct GMTAPI_CTRL *API = gmtapi_get_api_ptr (V_API); |
| 1635 | |
| 1636 | *n_items = 0; /* No keys yet */ |
| 1637 | |
| 1638 | for (k = 0; k < GMT_N_FAMILIES; k++) n_to_add[k] = GMT_NOTSET; /* Initially no input counts */ |
| 1639 | if (!string) return NULL; /* Got NULL, so just give up */ |
| 1640 | tmp = gmtapi_prepare_keys (API, string); /* Get the correct KEYS if there are separate ones for Classic and Modern mode */ |
| 1641 | len = strlen (tmp); /* Get the length of this item */ |
| 1642 | if (len == 0) { /* Got no characters, so give up */ |
| 1643 | gmt_M_str_free (tmp); |
| 1644 | return NULL; |
| 1645 | } |
| 1646 | /* Replace unknown types (marked as ?) in tmp with selected type give by input variable "type" */ |
| 1647 | if (type) { /* Got a nonzero type which we use to update any unspecified types */ |
| 1648 | for (k = 0; k < strlen (tmp); k++) |
| 1649 | if (tmp[k] == '?') tmp[k] = type; |
| 1650 | } |
| 1651 | /* Count the number of items (start n at 1 since there are one less comma than items) */ |
| 1652 | for (k = 0, n = 1; k < len; k++) |
| 1653 | if (tmp[k] == ',') n++; |
| 1654 | /* Allocate and populate the character array, then return it and n_items */ |
| 1655 | s = (char **) calloc (n, sizeof (char *)); |
| 1656 | k = 0; |
| 1657 | while ((next = strsep (&tmp, ",")) != NULL) { /* Get each comma-separated key */ |
| 1658 | if (strlen (next) < 3) { |
| 1659 | GMT_Report (API, GMT_MSG_WARNING, |
| 1660 | "gmtapi_process_keys: Key %s contains less than 3 characters\n", next); |
| 1661 | continue; |
| 1662 | } |
| 1663 | if (strchr (next, '!')) { /* Type did not get determined in GMT_Encode_Options so key is skipped */ |
| 1664 | GMT_Report (API, GMT_MSG_DEBUG, |
| 1665 | "gmtapi_process_keys: key %s contains type = ! so we skip it\n", next); |
| 1666 | n--; |
| 1667 | continue; |
| 1668 | } |
| 1669 | s[k] = strdup (next); |
| 1670 | if (next[K_DIR] == API_PRIMARY_OUTPUT) { /* Identified primary output key */ |
| 1671 | if (o_id >= 0) /* Already had a primary output key */ |
| 1672 | GMT_Report (API, GMT_MSG_WARNING, |
| 1673 | "gmtapi_process_keys: Keys %s contain more than one primary output key\n", tmp); |
| 1674 | else |
| 1675 | o_id = (int)k; |
| 1676 | } |
| 1677 | k++; |
| 1678 | } |
| 1679 | |
| 1680 | /* While processing the array we also determine the key # for the primary output (if there is one) */ |
| 1681 | for (k = 0; k < n; k++) { /* Check for presence of any of the magic X,Y,Z keys */ |
| 1682 | if (s[k][K_OPT] == '-') { /* Key letter X missing: Means that option -Y, if given, changes the type of input|output */ |
no test coverage detected