PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
optionlist.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 *
6 * PostGIS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * PostGIS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **********************************************************************
20 *
21 * Copyright 2021 Paul Ramsey <pramsey@cleverelephant.ca>
22 *
23 **********************************************************************/
24
25#include "liblwgeom_internal.h"
26#include "optionlist.h"
27
28#include <ctype.h> // tolower
29#include <string.h> // strtok
30
31static void
33{
34 if (!key) return;
35 while (*key) {
36 *key = tolower(*key);
37 key++;
38 }
39 return;
40}
41
42// static void
43// option_list_string_to_upper(char* key)
44// {
45// if (!key) return;
46// while (*key) {
47// *key = toupper(*key);
48// key++;
49// }
50// return;
51// }
52
53const char*
54option_list_search(char** olist, const char* key)
55{
56 size_t i = 0;
57 if (!olist) return NULL;
58 if (!key) return NULL;
59 while (olist[i]) {
60 // Even entries are keys
61 if (!(i % 2)) {
62 // Does this key match ours?
63 if (strcmp(olist[i], key) == 0) {
64 return olist[i+1];
65 }
66 }
67 i++;
68 }
69 return NULL;
70}
71
72size_t
73option_list_length(char** olist)
74{
75 size_t i = 0;
76 char **iter = olist;
77 if (!olist) return 0;
78 while(*iter) {
79 i++;
80 iter++;
81 }
82 return i;
83}
84
85void
86option_list_parse(char* input, char** olist)
87{
88 const char *toksep = " ";
89 const char kvsep = '=';
90 char *key, *val;
91 if (!input) return;
92 size_t i = 0, sz;
93
94 /* strtok nulls out the space between each token */
95 for (key = strtok(input, toksep); key; key = strtok(NULL, toksep)) {
96 if (i >= OPTION_LIST_SIZE) return;
97 olist[i] = key;
98 i += 2;
99 }
100
101 sz = i;
102 /* keys are every second entry in the olist */
103 for (i = 0; i < sz; i += 2) {
104 if (i >= OPTION_LIST_SIZE) return;
105 key = olist[i];
106 /* find the key/value separator */
107 val = strchr(key, kvsep);
108 if (!val) {
109 lwerror("Option string entry '%s' lacks separator '%c'", key, kvsep);
110 }
111 /* null out the separator */
112 *val = '\0';
113 /* point value entry to just after separator */
114 olist[i+1] = ++val;
115 /* all keys forced to lower case */
117 }
118}
119
120void
121option_list_gdal_parse(char* input, char** olist)
122{
123 const char *toksep = " ";
124 const char kvsep = '=';
125 const char q2 = '"';
126 const char q1 = '\'';
127 const char notspace = 0x1F;
128
129 char *key, *val;
130 int in_str = 0;
131 size_t i = 0, sz, input_sz;
132 char *ptr = input;
133
134 if (!input)
135 lwerror("Option string is null");
136 input_sz = strlen(input);
137
138 /* Temporarily hide quoted spaces */
139 while(*ptr) {
140 if (*ptr == q2 || *ptr == q1)
141 in_str = !in_str;
142 else if (in_str && *ptr == ' ')
143 *ptr = notspace;
144
145 ptr++;
146 }
147
148 /* Tokenize on spaces */
149 for (key = strtok(input, toksep); key; key = strtok(NULL, toksep)) {
150 if (i >= OPTION_LIST_SIZE) return;
151 olist[i++] = key;
152 }
153
154 /* Check that these are GDAL KEY=VALUE options */
155 sz = i;
156 for (i = 0; i < sz; ++i) {
157 if (i >= OPTION_LIST_SIZE) return;
158 key = olist[i];
159 /* find the key/value separator */
160 val = strchr(key, kvsep);
161 if (!val) {
162 lwerror("Option string entry '%s' lacks separator '%c'", key, kvsep);
163 return;
164 }
165 }
166
167 /* Unhide quoted space */
168 for (i = 0; i <= input_sz; ++i) {
169 if (input[i] == notspace)
170 input[i] = ' ';
171 }
172}
173
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
const char * option_list_search(char **olist, const char *key)
Returns null if the key cannot be found.
Definition optionlist.c:54
static void option_list_string_to_lower(char *key)
Definition optionlist.c:32
void option_list_gdal_parse(char *input, char **olist)
Definition optionlist.c:121
size_t option_list_length(char **olist)
Returns the total number of keys and values in the list.
Definition optionlist.c:73
void option_list_parse(char *input, char **olist)
option_list is a null-terminated list of strings, where every odd string is a key and every even stri...
Definition optionlist.c:86
#define OPTION_LIST_SIZE
Definition optionlist.h:31