OpenDNSSEC-enforcer  1.4.3
string_util.c
Go to the documentation of this file.
1 /*
2  * $Id: string_util.c 3718 2010-08-10 21:17:18Z jakob $
3  *
4  * Copyright (c) 2008-2009 Nominet UK. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 /*++
30  * Filename: string_util.c
31  *
32  * Description:
33  * String utility functions used by the whois programs.
34 -*/
35 
36 #include "config.h"
37 
38 #include <assert.h>
39 #include <ctype.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 
44 #include "compat.h"
45 
46 #include "ksm/string_util.h"
47 #include "ksm/message.h"
48 #include "ksm/ksmdef.h"
49 
50 /*+
51  * StrUncomment - Uncomment Line
52  *
53  * Description:
54  * Locates the first comment character in the line, and truncates the line
55  * at that point. The comment character is hard-coded as the hash (#)
56  * character.
57  *
58  * Arguments:
59  * char* line (modified)
60  * Line to check. If a comment introducer exists, it is replaced with
61  * a null character. If the line is NULL, the routine is a no-op.
62  *
63  * Returns:
64  * void
65 -*/
66 
67 void StrUncomment(char* line)
68 {
69  char *comment; /* Pointer to first comment character */
70 
71  if (line && (comment = strstr(line, COMMENT_CHAR))) {
72 
73  /* comment points to character, or null if not found */
74 
75  *comment = '\0';
76  }
77 }
78 
79 
80 
81 /*+
82  * StrWhitespace - Replace Whitespace
83  *
84  * Description:
85  * Replaces every whitespace characters with a space. This conversion is
86  * usually done to simplify future processing.
87  *
88  * Arguments:
89  * char* line (modified)
90  * Line to modify.
91  *
92  * Returns:
93  * void
94 -*/
95 
96 void StrWhitespace(char* line)
97 {
98  if (line) {
99  while (*line) {
100  if (isspace((int) *line)) {
101  *line = ' ';
102  }
103  ++line;
104  }
105  }
106 }
107 
108 
109 /*+
110  * StrStrdup - Duplicate String
111  *
112  * Description:
113  * Wrapper for "strdup" that always returns, or exits the program (after
114  * outputting a message to stderr) if the string duplication fails.
115  *
116  * Arguments:
117  * const char* string (input)
118  * String to be duplicated.
119  *
120  * Returns:
121  * char*
122  * Pointer to duplicated string (guaranteed to be non-null). The
123  * string should be freed with StrFree() - a macro wrapper for "free".
124 -*/
125 
126 char* StrStrdup(const char* string)
127 {
128  char* duplicate = NULL; /* Pointer to the duplicated string */
129 
130  if (string) {
131  duplicate = strdup(string);
132  if (duplicate == NULL) {
133  MsgLog(KSM_STMTALLOC, "StrStrdup: Call to malloc() returned null - out of swap space?");
134  fprintf(stderr, "StrStrdup: Call to malloc() returned null - out of swap space?");
135  exit(1);
136  }
137  }
138  else {
139  duplicate = MemCalloc(1, 1); /* Allocate a single zeroed byte */
140  }
141 
142  return duplicate;
143 }
144 
145 
146 /*+
147  * StrStrncpy - Copy String
148  * StrStrncat - Concatenate String
149  *
150  * Description:
151  * Wrapper for "strncpy"/"strncat" that guarantees that:
152  *
153  * (a) As much of the source string as possible is copied to the
154  * destination.
155  * (b) The destination string is terminated by a null byte (something not
156  * guaranteed by the standard functions).
157  *
158  * Also, the function is void, unlike the standard library counterparts
159  * that return a pointer to the destination string.
160  *
161  * Arguments:
162  * char* dst (output)
163  * Destination string. The final byte of this string will always be
164  * set to NULL. If this argument is NULL, the routine is a no-op.
165  *
166  * const char* src (input)
167  * Source string. If NULL, the routine is a no-op (StrStrncat) or
168  * the destination is set to the empty string (StrStrncpy).
169  *
170  * size_t dstlen (input)
171  * Total amount of space allocated for the destination, including the
172  * terminating null byte. If this is zero, the routine is a no-op.
173  * Note that in the case of StrStrncat, this is the total amount of
174  * space IGNORING the current contents of "dst" - it is just the total
175  * space available to hold the entire resultant string.
176 -*/
177 
178 void StrStrncpy(char* dst, const char* src, size_t dstlen)
179 {
180  if (dst && (dstlen > 0)) {
181  if (src) {
182  (void) strlcpy(dst, src, dstlen);
183  /* dst[dstlen - 1] = '\0'; */
184  }
185  else {
186  dst[0] = '\0';
187  }
188  }
189 
190  return;
191 }
192 
193 void StrStrncat(char* dst, const char* src, size_t dstlen)
194 {
195  size_t length; /* Amount of space used in dst */
196  size_t remain; /* Remaining space in dst */
197 
198  if (dst) {
199  length = strlen(dst);
200  remain = dstlen - length;
201  if (remain > 1) {
202 
203  /* More space than just the trailing NULL */
204 
205  StrStrncpy(&dst[length], src, remain);
206  }
207  }
208 
209  return;
210 }
211 
212 
213 
214 /*+
215  * StrTrimR - Trim Right
216  *
217  * Description:
218  * Modifies a string by trimming white-space characters from the right of
219  * the string. It does this by modifying the string, inserting a null
220  * character after the last non white-space character.
221  *
222  * Arguments:
223  * char *text (modified)
224  * Text to modify. If this is NULL, the routine is a no-op.
225  *
226  * Returns:
227  * void
228 -*/
229 
230 void StrTrimR(char *text)
231 {
232  if (text) {
233 
234  /* Work backwards through the string */
235 
236  int textlen = strlen(text);
237  while (-- textlen >= 0) {
238  if (! isspace((int) text[textlen])) {
239  text[textlen + 1] = '\0';
240  return;
241  }
242  }
243 
244  /* Get here if the entire string is white space */
245 
246  text[0] = '\0';
247  }
248  return;
249 }
250 
251 
252 
253 /*+
254  * StrTrimL - Trim Left
255  *
256  * Description:
257  * Searches a string and returns a pointer to the first non white-space
258  * character in it.
259  *
260  * Arguments:
261  * char* text (input)
262  * Text to search.
263  *
264  * Returns:
265  * char*
266  * Pointer to first non white-space character in the string. If the
267  * string is NULL, NULL is returned. If the string is all white space,
268  * a pointer to the trailing null character is returned.
269 -*/
270 
271 char* StrTrimL(char* text)
272 {
273  if (text) {
274  while (*text && isspace((int) *text)) {
275  ++text;
276  }
277  }
278 
279  return text;
280 }
281 
282 
283 /*+
284  * StrTrim - Trim String
285  *
286  * Description:
287  * A combination of StrTrimL and StrTrimR, this routine modifies the passed
288  * string by inserting the null character after the last non-space in the
289  * string, then returning a pointer into the string to the first non
290  * white-space character.
291  *
292  * Arguments:
293  * char *text (modified)
294  * Text to be trimmed. The text may be modified.
295  *
296  * Returns:
297  * char*
298  * Pointer into text of the first non white-space character. If the
299  * input string is NULL, NULL is returned.
300 -*/
301 
302 char* StrTrim(char* text)
303 {
304  StrTrimR(text);
305  return StrTrimL(text);
306 }
307 
308 
309 /*+
310  * StrToLower - Convert to Lower Case
311  *
312  * Description:
313  * Converts the passed string to lowercase characters. As a side-effect it
314  * also returns the length of the string.
315  *
316  * Arguments:
317  * char *text (modified)
318  * String to be modified. If NULL, this routine is a no-op.
319  *
320  * Returns:
321  * size_y
322  * Length of the string.
323 -*/
324 
325 size_t StrToLower(char* string)
326 {
327  char* ptr = string;
328  if (ptr) {
329  while (*ptr) {
330  *ptr = tolower((int) *ptr);
331  ++ptr;
332  }
333  }
334 
335  return (size_t) (ptr - string);
336 }
337 
338 
339 /*+
340  * StrToUpper - Convert to Upper Case
341  *
342  * Description:
343  * Converts the passed string to uppercase characters. As a side-effect it
344  * also returns the length of the string.
345  *
346  * Arguments:
347  * char *text (modified)
348  * String to be modified. If NULL, this routine is a no-op.
349  *
350  * Returns:
351  * size_t
352  * Length of the string.
353 -*/
354 
355 size_t StrToUpper(char* string)
356 {
357  char* ptr = string;
358  if (ptr) {
359  while (*ptr) {
360  *ptr = toupper((int) *ptr);
361  ++ptr;
362  }
363  }
364 
365  return (size_t) (ptr - string);
366 }
367 
368 
369 
370 /*+
371  * StrReplaceChar - Replace Character - Null-Terminated String
372  * StrReplaceCharN - Replace Character - Length Given
373  *
374  * Description:
375  * Replaces all occurrences of a given character in a string by the given
376  * character.
377  *
378  * StrReplaceCharN is generally used where the string may contain embedded
379  * null characters in order to remove them.
380  *
381  * Arguments:
382  * char* string (modified)
383  * String in which the replacement is to take place.
384  *
385  * size_t len (input, StrReplaceCharN only)
386  * Lenght of input string.
387  *
388  * char search (input)
389  * Character to search for.
390  *
391  * char replace (input)
392  * Replacement chaaracter.
393  *
394  * Returns:
395  * size_t
396  * Number of replacements.
397 -*/
398 
399 size_t StrReplaceCharN(char* string, size_t len, char search, char replace)
400 {
401  size_t count = 0; /* Replacement count */
402  size_t i; /* Loop counter */
403 
404  if (string) {
405  for (i = 0; i < len; ++i) {
406  if (string[i] == search) {
407  string[i] = replace;
408  ++count;
409  }
410  }
411  }
412  return count;
413 }
414 
415 size_t StrReplaceChar(char* string, char search, char replace)
416 {
417  size_t count = 0; /* Replacement count */
418 
419  if (string) {
420  count = StrReplaceCharN(string, strlen(string), search, replace);
421  }
422  return count;
423 }
424 
425 
426 
427 /*+
428  * StrTrimmedLength
429  *
430  * Description:
431  * Searches the string and returns the length of the string less leading
432  * and trailing spaces. Essentially, this will be the result of a call to
433  * strlen() after the string has been passed through StrTrim().
434  *
435  * Arguments:
436  * const char* string (input)
437  * String to search.
438  *
439  * Returns:
440  * size_t
441  * Size of the string.
442 -*/
443 
444 size_t StrTrimmedLength(const char* string)
445 {
446  size_t length = 0; /* Length of trimmed string */
447  size_t in_length; /* Length of input string */
448  size_t first_char; /* Position of first non-space character */
449  size_t last_char; /* Position of last non-space character */
450 
451  if (string) {
452  in_length = strlen(string);
453 
454  /*
455  * Get offset of first non-space character. If the string does not
456  * contain any such characters, first_char will equal "length".
457  */
458 
459  first_char = 0;
460  while (first_char < in_length) {
461  if (! isspace((int) string[first_char])) {
462  break;
463  }
464  ++first_char;
465  }
466 
467  if (first_char < in_length) {
468 
469  /*
470  * Must be a printable character, so find the offset of the last
471  * such character.
472  */
473 
474  last_char = in_length - 1;
475  while (isspace((int) string[last_char])) {
476  --last_char;
477  }
478 
479  /* ... and work out the length */
480 
481  length = last_char - first_char + 1;
482  assert(length > 0);
483  }
484 
485  /* No "else" - length is set to zero on enty */
486  }
487 
488  return length;
489 }
void * MemCalloc(size_t nmemb, size_t size)
Definition: memory.c:70
char * StrTrim(char *text)
Definition: string_util.c:302
int MsgLog(int status,...)
Definition: message.c:337
void StrWhitespace(char *line)
Definition: string_util.c:96
size_t StrToLower(char *string)
Definition: string_util.c:325
void StrStrncat(char *dst, const char *src, size_t dstlen)
Definition: string_util.c:193
void StrUncomment(char *line)
Definition: string_util.c:67
#define KSM_STMTALLOC
Definition: ksmdef.h:79
size_t StrTrimmedLength(const char *string)
Definition: string_util.c:444
char * StrStrdup(const char *string)
Definition: string_util.c:126
void StrStrncpy(char *dst, const char *src, size_t dstlen)
Definition: string_util.c:178
void StrTrimR(char *text)
Definition: string_util.c:230
#define COMMENT_CHAR
Definition: string_util.h:46
size_t StrToUpper(char *string)
Definition: string_util.c:355
size_t StrReplaceCharN(char *string, size_t len, char search, char replace)
Definition: string_util.c:399
size_t StrReplaceChar(char *string, char search, char replace)
Definition: string_util.c:415
char * StrTrimL(char *text)
Definition: string_util.c:271