PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
stringutils.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

char * strtokx (const char *s, const char *whitespace, const char *delim, const char *quote, char escape, bool e_strings, bool del_quotes, int encoding)
 
void strip_quotes (char *source, char quote, char escape, int encoding)
 
char * quote_if_needed (const char *source, const char *entails_quote, char quote, char escape, bool force_quote, int encoding)
 

Function Documentation

◆ quote_if_needed()

char* quote_if_needed ( const char *  source,
const char *  entails_quote,
char  quote,
char  escape,
bool  force_quote,
int  encoding 
)

Definition at line 292 of file stringutils.c.

295 {
296  const char *src;
297  char *ret;
298  char *dst;
299  bool need_quotes = force_quote;
300 
301  Assert(source != NULL);
302  Assert(quote != '\0');
303 
304  src = source;
305  dst = ret = pg_malloc(2 * strlen(src) + 3); /* excess */
306 
307  *dst++ = quote;
308 
309  while (*src)
310  {
311  char c = *src;
312  int i;
313 
314  if (c == quote)
315  {
316  need_quotes = true;
317  *dst++ = quote;
318  }
319  else if (c == escape)
320  {
321  need_quotes = true;
322  *dst++ = escape;
323  }
324  else if (strchr(entails_quote, c))
325  need_quotes = true;
326 
327  i = PQmblenBounded(src, encoding);
328  while (i--)
329  *dst++ = *src++;
330  }
331 
332  *dst++ = quote;
333  *dst = '\0';
334 
335  if (!need_quotes)
336  {
337  free(ret);
338  ret = NULL;
339  }
340 
341  return ret;
342 }
#define Assert(condition)
Definition: c.h:863
int PQmblenBounded(const char *s, int encoding)
Definition: fe-misc.c:1234
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:72
int32 encoding
Definition: pg_database.h:41
static rewind_source * source
Definition: pg_rewind.c:89
char * c

References Assert, encoding, free, i, pg_malloc(), PQmblenBounded(), and source.

◆ strip_quotes()

void strip_quotes ( char *  source,
char  quote,
char  escape,
int  encoding 
)

Definition at line 240 of file stringutils.c.

241 {
242  char *src;
243  char *dst;
244 
245  Assert(source != NULL);
246  Assert(quote != '\0');
247 
248  src = dst = source;
249 
250  if (*src && *src == quote)
251  src++; /* skip leading quote */
252 
253  while (*src)
254  {
255  char c = *src;
256  int i;
257 
258  if (c == quote && src[1] == '\0')
259  break; /* skip trailing quote */
260  else if (c == quote && src[1] == quote)
261  src++; /* process doubled quote */
262  else if (c == escape && src[1] != '\0')
263  src++; /* process escaped character */
264 
265  i = PQmblenBounded(src, encoding);
266  while (i--)
267  *dst++ = *src++;
268  }
269 
270  *dst = '\0';
271 }

References Assert, encoding, i, PQmblenBounded(), and source.

Referenced by parse_slash_copy(), and strtokx().

◆ strtokx()

char* strtokx ( const char *  s,
const char *  whitespace,
const char *  delim,
const char *  quote,
char  escape,
bool  e_strings,
bool  del_quotes,
int  encoding 
)

Definition at line 52 of file stringutils.c.

60 {
61  static char *storage = NULL; /* store the local copy of the users
62  * string here */
63  static char *string = NULL; /* pointer into storage where to continue on
64  * next call */
65 
66  /* variously abused variables: */
67  unsigned int offset;
68  char *start;
69  char *p;
70 
71  if (s)
72  {
73  free(storage);
74 
75  /*
76  * We may need extra space to insert delimiter nulls for adjacent
77  * tokens. 2X the space is a gross overestimate, but it's unlikely
78  * that this code will be used on huge strings anyway.
79  */
80  storage = pg_malloc(2 * strlen(s) + 1);
81  strcpy(storage, s);
82  string = storage;
83  }
84 
85  if (!storage)
86  return NULL;
87 
88  /* skip leading whitespace */
89  offset = strspn(string, whitespace);
90  start = &string[offset];
91 
92  /* end of string reached? */
93  if (*start == '\0')
94  {
95  /* technically we don't need to free here, but we're nice */
96  free(storage);
97  storage = NULL;
98  string = NULL;
99  return NULL;
100  }
101 
102  /* test if delimiter character */
103  if (delim && strchr(delim, *start))
104  {
105  /*
106  * If not at end of string, we need to insert a null to terminate the
107  * returned token. We can just overwrite the next character if it
108  * happens to be in the whitespace set ... otherwise move over the
109  * rest of the string to make room. (This is why we allocated extra
110  * space above).
111  */
112  p = start + 1;
113  if (*p != '\0')
114  {
115  if (!strchr(whitespace, *p))
116  memmove(p + 1, p, strlen(p) + 1);
117  *p = '\0';
118  string = p + 1;
119  }
120  else
121  {
122  /* at end of string, so no extra work */
123  string = p;
124  }
125 
126  return start;
127  }
128 
129  /* check for E string */
130  p = start;
131  if (e_strings &&
132  (*p == 'E' || *p == 'e') &&
133  p[1] == '\'')
134  {
135  quote = "'";
136  escape = '\\'; /* if std strings before, not any more */
137  p++;
138  }
139 
140  /* test if quoting character */
141  if (quote && strchr(quote, *p))
142  {
143  /* okay, we have a quoted token, now scan for the closer */
144  char thisquote = *p++;
145 
146  for (; *p; p += PQmblenBounded(p, encoding))
147  {
148  if (*p == escape && p[1] != '\0')
149  p++; /* process escaped anything */
150  else if (*p == thisquote && p[1] == thisquote)
151  p++; /* process doubled quote */
152  else if (*p == thisquote)
153  {
154  p++; /* skip trailing quote */
155  break;
156  }
157  }
158 
159  /*
160  * If not at end of string, we need to insert a null to terminate the
161  * returned token. See notes above.
162  */
163  if (*p != '\0')
164  {
165  if (!strchr(whitespace, *p))
166  memmove(p + 1, p, strlen(p) + 1);
167  *p = '\0';
168  string = p + 1;
169  }
170  else
171  {
172  /* at end of string, so no extra work */
173  string = p;
174  }
175 
176  /* Clean up the token if caller wants that */
177  if (del_quotes)
178  strip_quotes(start, thisquote, escape, encoding);
179 
180  return start;
181  }
182 
183  /*
184  * Otherwise no quoting character. Scan till next whitespace, delimiter
185  * or quote. NB: at this point, *start is known not to be '\0',
186  * whitespace, delim, or quote, so we will consume at least one character.
187  */
188  offset = strcspn(start, whitespace);
189 
190  if (delim)
191  {
192  unsigned int offset2 = strcspn(start, delim);
193 
194  if (offset > offset2)
195  offset = offset2;
196  }
197 
198  if (quote)
199  {
200  unsigned int offset2 = strcspn(start, quote);
201 
202  if (offset > offset2)
203  offset = offset2;
204  }
205 
206  p = start + offset;
207 
208  /*
209  * If not at end of string, we need to insert a null to terminate the
210  * returned token. See notes above.
211  */
212  if (*p != '\0')
213  {
214  if (!strchr(whitespace, *p))
215  memmove(p + 1, p, strlen(p) + 1);
216  *p = '\0';
217  string = p + 1;
218  }
219  else
220  {
221  /* at end of string, so no extra work */
222  string = p;
223  }
224 
225  return start;
226 }
return str start
#define storage
Definition: indent_codes.h:68
void strip_quotes(char *source, char quote, char escape, int encoding)
Definition: stringutils.c:240

References encoding, free, pg_malloc(), PQmblenBounded(), start, storage, and strip_quotes().

Referenced by parse_slash_copy().