exit mem_realloc, enters p_realloc/xrealloc.
[apps/madmutt.git] / lib / str.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
5  *
6  * This file is part of mutt-ng, see http://www.muttng.org/.
7  * It's licensed under the GNU General Public License,
8  * please see the file GPL in the top level source directory.
9  */
10
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14
15 #include <lib-lib/mem.h>
16
17 #include "str.h"
18
19 char *str_dup (const char *s)
20 {
21   if (!s || !*s)
22       return NULL;
23   return p_dupstr(s, str_len(s));
24 }
25
26 char *str_cat (char *d, size_t l, const char *s)
27 {
28   char *p = d;
29
30   if (!l)
31     return d;
32
33   l--;                          /* Space for the trailing '\0'. */
34
35   for (; *d && l; l--)
36     d++;
37   for (; *s && l; l--)
38     *d++ = *s++;
39
40   *d = '\0';
41
42   return p;
43 }
44
45 char *str_ncat (char *d, size_t l, const char *s, size_t sl)
46 {
47   char *p = d;
48
49   if (!l)
50     return d;
51
52   l--;                          /* Space for the trailing '\0'. */
53
54   for (; *d && l; l--)
55     d++;
56   for (; *s && l && sl; l--, sl--)
57     *d++ = *s++;
58
59   *d = '\0';
60
61   return p;
62 }
63
64 int str_cmp (const char *a, const char *b)
65 {
66   return strcmp (NONULL (a), NONULL (b));
67 }
68
69 int str_casecmp (const char *a, const char *b)
70 {
71   return strcasecmp (NONULL (a), NONULL (b));
72 }
73
74 int str_ncmp (const char *a, const char *b, size_t l)
75 {
76   return strncmp (NONULL (a), NONULL (b), l);
77 }
78
79 int str_ncasecmp (const char *a, const char *b, size_t l)
80 {
81   return strncasecmp (NONULL (a), NONULL (b), l);
82 }
83
84 size_t str_len (const char *a)
85 {
86   return a ? strlen (a) : 0;
87 }
88
89 int str_coll (const char *a, const char *b)
90 {
91   return strcoll (NONULL (a), NONULL (b));
92 }
93
94 void str_replace (char **p, const char *s)
95 {
96   p_delete(p);
97   *p = str_dup (s);
98 }
99
100 void str_adjust (char **p)
101 {
102   if (!p || !*p)
103     return;
104   p_realloc(p, str_len (*p) + 1);
105 }
106
107 /* convert all characters in the string to lowercase */
108 char *str_tolower (char *s)
109 {
110   char *p = s;
111
112   while (*p) {
113     *p = tolower ((unsigned char) *p);
114     p++;
115   }
116
117   return (s);
118 }
119
120 /* NULL-pointer aware string comparison functions */
121
122 char *str_substrcpy (char *dest, const char *beg, const char *end,
123                       size_t destlen)
124 {
125   size_t len;
126
127   len = end - beg;
128   if (len > destlen - 1)
129     len = destlen - 1;
130   memcpy (dest, beg, len);
131   dest[len] = 0;
132   return dest;
133 }
134
135 char *str_substrdup(const char *begin, const char *end)
136 {
137     return p_dupstr(begin, (end ? end - begin : strlen(begin)));
138 }
139
140 const char *str_isstr (const char *haystack, const char *needle)
141 {
142   const char *p, *q;
143
144   if (!haystack)
145     return NULL;
146   if (!needle)
147     return (haystack);
148
149   while (*(p = haystack)) {
150     for (q = needle;
151          *p && *q &&
152          tolower ((unsigned char) *p) == tolower ((unsigned char) *q);
153          p++, q++);
154     if (!*q)
155       return (haystack);
156     haystack++;
157   }
158   return NULL;
159 }
160
161 int str_eq (const char* s1, const char* s2) {
162   int l = str_len (s1);
163
164   if (l != str_len (s2))
165     return (0);
166   return (str_ncmp (s1, s2, l) == 0);
167 }
168
169 char* str_skip_initws (char* s) {
170   SKIPWS (s);
171   return (s);
172 }
173
174 void str_skip_trailws (char *s) {
175   char *p;
176
177   for (p = s + str_len (s) - 1; p >= s && ISSPACE (*p); p--)
178     *p = 0;
179 }