GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r72105
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
strings.c
Go to the documentation of this file.
1 /*!
2  \file lib/gis/strings.c
3 
4  \brief GIS Library - string/chring movement functions
5 
6  \todo merge interesting functions from ../datetime/scan.c here
7 
8  (C) 1999-2008, 2011 by the GRASS Development Team
9 
10  This program is free software under the GNU General Public License
11  (>=v2). Read the file COPYING that comes with GRASS for details.
12 
13  \author Dave Gerdes (USACERL)
14  \author Michael Shapiro (USACERL)
15  \author Amit Parghi (USACERL)
16  \author Bernhard Reiter (Intevation GmbH, Germany) and many others
17 */
18 
19 #include <string.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <sys/types.h>
23 #include <grass/gis.h>
24 
25 #ifndef NULL
26 #define NULL 0
27 #endif
28 
29 static int _strncasecmp(const char *, const char *, int);
30 
31 /*!
32  \brief String compare ignoring case (upper or lower)
33 
34  Returning a value that has the same sign as the difference between
35  the first differing pair of characters.
36 
37  Note: strcasecmp() is affected by the locale (LC_CTYPE), while
38  G_strcasecmp() isn't.
39 
40  \param x first string to compare
41  \param y second string to compare
42 
43  \return 0 the two strings are equal
44  \return -1, 1
45 */
46 int G_strcasecmp(const char *x, const char *y)
47 {
48  return _strncasecmp(x, y, -1);
49 }
50 
51 /*!
52  \brief String compare ignoring case (upper or lower) - limited
53  number of characters
54 
55  Returning a value that has the same sign as the difference between
56  the first differing pair of characters.
57 
58  Note: strcasecmp() is affected by the locale (LC_CTYPE), while
59  G_strcasecmp() isn't.
60 
61  \param x first string to compare
62  \param y second string to compare
63  \param n number or characters to compare
64 
65  \return 0 the two strings are equal
66  \return -1, 1
67 */
68 int G_strncasecmp(const char *x, const char *y, int n)
69 {
70  return _strncasecmp(x, y, n);
71 }
72 
73 /*!
74  \brief Copy string to allocated memory.
75 
76  This routine allocates enough memory to hold the string <b>s</b>,
77  copies <em>s</em> to the allocated memory, and returns a pointer
78  to the allocated memory.
79 
80  If <em>s</em> is NULL then empty string is returned.
81 
82  \param s string
83 
84  \return pointer to newly allocated string
85 */
86 char *G_store(const char *s)
87 {
88  char *buf;
89 
90  if (s == NULL) {
91  buf = G_malloc(sizeof(char));
92  buf[0] = '\0';
93  }
94  else {
95  buf = G_malloc(strlen(s) + 1);
96  strcpy(buf, s);
97  }
98 
99  return buf;
100 }
101 
102 /*!
103  \brief Copy string to allocated memory and convert copied string
104  to upper case
105 
106  This routine allocates enough memory to hold the string <b>s</b>,
107  copies <em>s</em> to the allocated memory, and returns a pointer
108  to the allocated memory.
109 
110  If <em>s</em> is NULL then empty string is returned.
111 
112  \param s string
113 
114  \return pointer to newly allocated upper case string
115 */
116 char *G_store_upper(const char *s)
117 {
118  char *u_s;
119 
120  u_s = G_store(s);
121  G_str_to_upper(u_s);
122 
123  return u_s;
124 }
125 
126 /*!
127  \brief Copy string to allocated memory and convert copied string
128  to lower case
129 
130  This routine allocates enough memory to hold the string <b>s</b>,
131  copies <em>s</em> to the allocated memory, and returns a pointer
132  to the allocated memory.
133 
134  If <em>s</em> is NULL then empty string is returned.
135 
136  \param s string
137 
138  \return pointer to newly allocated lower case string
139 */
140 char *G_store_lower(const char *s)
141 {
142  char *l_s;
143 
144  l_s = G_store(s);
145  G_str_to_lower(l_s);
146 
147  return l_s;
148 }
149 
150 /*!
151  \brief Replace all occurrences of character in string bug with new
152 
153  \param[in,out] bug base string
154  \param character character to replace
155  \param new new character
156 
157  \return bug string
158 */
159 char *G_strchg(char *bug, char character, char new)
160 {
161  char *help = bug;
162 
163  while (*help) {
164  if (*help == character)
165  *help = new;
166  help++;
167  }
168  return bug;
169 }
170 
171 /*!
172  \brief Replace all occurrences of old_str in buffer with new_str
173 
174  Code example:
175  \code
176  char *name;
177  name = G_str_replace ( inbuf, ".exe", "" );
178  ...
179  G_free (name);
180  \endcode
181 
182  \param buffer input string buffer
183  \param old_str string to be replaced
184  \param new_str new string
185 
186  \return the newly allocated string, input buffer is unchanged
187 */
188 char *G_str_replace(const char *buffer, const char *old_str, const char *new_str)
189 {
190  char *R;
191  const char *N, *B;
192  char *replace;
193  int count, len;
194 
195  /* Make sure old_str and new_str are not NULL */
196  if (old_str == NULL || new_str == NULL)
197  return G_store(buffer);
198  /* Make sure buffer is not NULL */
199  if (buffer == NULL)
200  return NULL;
201 
202  /* Make sure old_str occurs */
203  B = strstr(buffer, old_str);
204  if (B == NULL)
205  /* return NULL; */
206  return G_store(buffer);
207 
208  if (strlen(new_str) > strlen(old_str)) {
209  /* Count occurrences of old_str */
210  count = 0;
211  len = strlen(old_str);
212  B = buffer;
213  while (B != NULL && *B != '\0') {
214  B = strstr(B, old_str);
215  if (B != NULL) {
216  B += len;
217  count++;
218  }
219  }
220 
221  len = count * (strlen(new_str) - strlen(old_str))
222  + strlen(buffer);
223 
224  }
225  else
226  len = strlen(buffer);
227 
228  /* Allocate new replacement */
229  replace = G_malloc(len + 1);
230  if (replace == NULL)
231  return NULL;
232 
233  /* Replace old_str with new_str */
234  B = buffer;
235  R = replace;
236  len = strlen(old_str);
237  while (*B != '\0') {
238  if (*B == old_str[0] && strncmp(B, old_str, len) == 0) {
239  N = new_str;
240  while (*N != '\0')
241  *R++ = *N++;
242  B += len;
243  }
244  else {
245  *R++ = *B++;
246  }
247  }
248  *R = '\0';
249 
250  return replace;
251 }
252 
253 /*!
254  \brief Removes all leading and trailing white space from string.
255 
256  \param[in,out] buf buffer to be worked on
257 */
258 void G_strip(char *buf)
259 {
260  char *a, *b;
261 
262  /* remove leading white space */
263  for (a = b = buf; *a == ' ' || *a == '\t'; a++) ;
264  if (a != b)
265  while ((*b++ = *a++)) ;
266  /* remove trailing white space */
267  for (a = buf; *a; a++) ;
268  if (a != buf) {
269  for (a--; *a == ' ' || *a == '\t'; a--) ;
270  a++;
271  *a = 0;
272  }
273 }
274 
275 /*!
276  \brief Chop leading and trailing white spaces.
277 
278  \verbatim space, \f, \n, \r, \t, \v \endverbatim
279 
280  Modified copy of G_squeeze() by RB in March 2000.
281 
282  \param line buffer to be worked on
283 
284  \return pointer to string
285 */
286 char *G_chop(char *line)
287 {
288  char *f = line, *t = line;
289 
290  while (isspace(*f)) /* go to first non white-space char */
291  f++;
292 
293  if (!*f) { /* no more chars in string */
294  *t = '\0';
295  return (line);
296  }
297 
298  for (t = f; *t; t++) /* go from first non white-space char to end */
299  ;
300  while (isspace(*--t)) ;
301  *++t = '\0'; /* remove trailing white-spaces */
302 
303  if (f != line) {
304  t = line;
305  while (*f) /* leading white spaces, shift */
306  *t++ = *f++;
307  *t = '\0';
308  }
309 
310  return (line);
311 }
312 
313 /*!
314  \brief Convert string to upper case
315 
316  \param[in,out] str pointer to string
317 */
318 void G_str_to_upper(char *str)
319 {
320  int i = 0;
321 
322  if (!str)
323  return;
324 
325  while (str[i]) {
326  str[i] = toupper(str[i]);
327  i++;
328  }
329 }
330 
331 /*!
332  \brief Convert string to lower case
333 
334  \param[in,out] str pointer to string
335 */
336 void G_str_to_lower(char *str)
337 {
338  int i = 0;
339 
340  if (!str)
341  return;
342 
343  while (str[i]) {
344  str[i] = tolower(str[i]);
345  i++;
346  }
347 }
348 
349 /*!
350  \brief Make string SQL compliant
351 
352  \param[in,out] str pointer to string
353 
354  \return number of changed characters
355 */
356 int G_str_to_sql(char *str)
357 {
358  int count;
359  char *c;
360 
361  count = 0;
362 
363  if (!str || !*str)
364  return 0;
365 
366  c = str;
367  while (*c) {
368  *c = toascii(*c);
369 
370  if (!(*c >= 'A' && *c <= 'Z') && !(*c >= 'a' && *c <= 'z') &&
371  !(*c >= '0' && *c <= '9')) {
372  *c = '_';
373  count++;
374  }
375  c++;
376  }
377 
378  c = str;
379  if (!(*c >= 'A' && *c <= 'Z') && !(*c >= 'a' && *c <= 'z')) {
380  *c = 'x';
381  count++;
382  }
383 
384  return count;
385 }
386 
387 /*!
388  \brief Remove superfluous white space.
389 
390  Leading and trailing white space is removed from the string
391  <b>line</b> and internal white space which is more than one character
392  is reduced to a single space character. White space here means
393  spaces, tabs, linefeeds, newlines, and formfeeds.
394 
395  \param[in,out] line
396 
397  \return Pointer to <b>line</b>
398 */
399 void G_squeeze(char *line)
400 {
401  char *f = line, *t = line;
402  int l;
403 
404  /* skip over space at the beginning of the line. */
405  while (isspace(*f))
406  f++;
407 
408  while (*f)
409  if (!isspace(*f))
410  *t++ = *f++;
411  else if (*++f)
412  if (!isspace(*f))
413  *t++ = ' ';
414  *t = '\0';
415  l = strlen(line) - 1;
416  if (*(line + l) == '\n')
417  *(line + l) = '\0';
418 }
419 
420 /*!
421  \brief Finds the first occurrence of the sub-string in the
422  null-terminated string ignoring case (upper or lower)
423 
424  \param str string where to find sub-string
425  \param substr sub-string
426 
427  \return a pointer to the first occurrence of sub-string
428  \return NULL if no occurrences are found
429 */
430 char *G_strcasestr(const char *str, const char *substr)
431 {
432  const char *p;
433  const char *q;
434  int length;
435 
436  p = substr;
437  q = str;
438  length = strlen(substr);
439 
440  do {
441  /* match 1st substr char */
442  while (*q != '\0' && toupper(*q) != toupper(*p)) {
443  q++;
444  }
445  } while (*q != '\0' && G_strncasecmp(p, q, length) != 0 && q++);
446 
447  if (*q == '\0') {
448  /* ran off end of str */
449  return NULL;
450  }
451 
452  return (char *) q;
453 }
454 
455 int _strncasecmp(const char *x, const char *y, int n)
456 {
457  int xx, yy, i;
458 
459  if (!x)
460  return y ? -1 : 0;
461  if (!y)
462  return x ? 1 : 0;
463 
464  i = 1;
465  while (*x && *y) {
466  xx = *x++;
467  yy = *y++;
468  if (xx >= 'A' && xx <= 'Z')
469  xx = xx + 'a' - 'A';
470  if (yy >= 'A' && yy <= 'Z')
471  yy = yy + 'a' - 'A';
472  if (xx < yy)
473  return -1;
474  if (xx > yy)
475  return 1;
476 
477  if (n > -1 && i >= n)
478  return 0;
479 
480  i++;
481  }
482 
483  if (*x)
484  return 1;
485  if (*y)
486  return -1;
487  return 0;
488 }
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:46
char * G_strcasestr(const char *str, const char *substr)
Finds the first occurrence of the sub-string in the null-terminated string ignoring case (upper or lo...
Definition: strings.c:430
void G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:258
int G_strncasecmp(const char *x, const char *y, int n)
String compare ignoring case (upper or lower) - limited number of characters.
Definition: strings.c:68
char * G_strchg(char *bug, char character, char new)
Replace all occurrences of character in string bug with new.
Definition: strings.c:159
int count
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:86
#define N
Definition: e_intersect.c:923
char * G_store_lower(const char *s)
Copy string to allocated memory and convert copied string to lower case.
Definition: strings.c:140
#define NULL
Definition: ccmath.h:32
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition: strings.c:286
#define x
void G_str_to_lower(char *str)
Convert string to lower case.
Definition: strings.c:336
double l
Definition: r_raster.c:39
double t
Definition: r_raster.c:39
double b
Definition: r_raster.c:39
void G_squeeze(char *line)
Remove superfluous white space.
Definition: strings.c:399
char * G_store_upper(const char *s)
Copy string to allocated memory and convert copied string to upper case.
Definition: strings.c:116
char * G_str_replace(const char *buffer, const char *old_str, const char *new_str)
Replace all occurrences of old_str in buffer with new_str.
Definition: strings.c:188
void G_str_to_upper(char *str)
Convert string to upper case.
Definition: strings.c:318
int G_str_to_sql(char *str)
Make string SQL compliant.
Definition: strings.c:356