- move some string functions out to lib/str.[ch], add str_eq()
[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 "str.h"
16
17 #include "mem.h"
18
19 char *safe_strdup (const char *s)
20 {
21   char *p;
22   size_t l;
23
24   if (!s || !*s)
25     return 0;
26   l = safe_strlen (s) + 1;
27   p = (char *) safe_malloc (l);
28   memcpy (p, s, l);
29   return (p);
30 }
31
32 char *safe_strcat (char *d, size_t l, const char *s)
33 {
34   char *p = d;
35
36   if (!l)
37     return d;
38
39   l--;                          /* Space for the trailing '\0'. */
40
41   for (; *d && l; l--)
42     d++;
43   for (; *s && l; l--)
44     *d++ = *s++;
45
46   *d = '\0';
47
48   return p;
49 }
50
51 char *safe_strncat (char *d, size_t l, const char *s, size_t sl)
52 {
53   char *p = d;
54
55   if (!l)
56     return d;
57
58   l--;                          /* Space for the trailing '\0'. */
59
60   for (; *d && l; l--)
61     d++;
62   for (; *s && l && sl; l--, sl--)
63     *d++ = *s++;
64
65   *d = '\0';
66
67   return p;
68 }
69
70 int safe_strcmp (const char *a, const char *b)
71 {
72   return strcmp (NONULL (a), NONULL (b));
73 }
74
75 int safe_strcasecmp (const char *a, const char *b)
76 {
77   return strcasecmp (NONULL (a), NONULL (b));
78 }
79
80 int safe_strncmp (const char *a, const char *b, size_t l)
81 {
82   return strncmp (NONULL (a), NONULL (b), l);
83 }
84
85 int safe_strncasecmp (const char *a, const char *b, size_t l)
86 {
87   return strncasecmp (NONULL (a), NONULL (b), l);
88 }
89
90 size_t safe_strlen (const char *a)
91 {
92   return a ? strlen (a) : 0;
93 }
94
95 int safe_strcoll (const char *a, const char *b)
96 {
97   return strcoll (NONULL (a), NONULL (b));
98 }
99
100 void str_replace (char **p, const char *s)
101 {
102   FREE (p);
103   *p = safe_strdup (s);
104 }
105
106 void str_adjust (char **p)
107 {
108   if (!p || !*p)
109     return;
110   safe_realloc (p, safe_strlen (*p) + 1);
111 }
112
113 /* convert all characters in the string to lowercase */
114 char *str_tolower (char *s)
115 {
116   char *p = s;
117
118   while (*p) {
119     *p = tolower ((unsigned char) *p);
120     p++;
121   }
122
123   return (s);
124 }
125
126 /* NULL-pointer aware string comparison functions */
127
128 char *str_substrcpy (char *dest, const char *beg, const char *end,
129                       size_t destlen)
130 {
131   size_t len;
132
133   len = end - beg;
134   if (len > destlen - 1)
135     len = destlen - 1;
136   memcpy (dest, beg, len);
137   dest[len] = 0;
138   return dest;
139 }
140
141 char *str_substrdup (const char *begin, const char *end)
142 {
143   size_t len;
144   char *p;
145
146   if (end)
147     len = end - begin;
148   else
149     len = safe_strlen (begin);
150
151   p = safe_malloc (len + 1);
152   memcpy (p, begin, len);
153   p[len] = 0;
154   return p;
155 }
156
157 const char *str_isstr (const char *haystack, const char *needle)
158 {
159   const char *p, *q;
160
161   if (!haystack)
162     return NULL;
163   if (!needle)
164     return (haystack);
165
166   while (*(p = haystack)) {
167     for (q = needle;
168          *p && *q &&
169          tolower ((unsigned char) *p) == tolower ((unsigned char) *q);
170          p++, q++);
171     if (!*q)
172       return (haystack);
173     haystack++;
174   }
175   return NULL;
176 }
177
178 int str_eq (const char* s1, const char* s2) {
179   int l = safe_strlen (s1);
180
181   if (l != safe_strlen (s2))
182     return (0);
183   return (safe_strncmp (s1, s2, l) == 0);
184 }
185
186 char* str_skip_initws (char* s) {
187   SKIPWS (s);
188   return (s);
189 }
190
191 void str_skip_trailws (char *s) {
192   char *p;
193
194   for (p = s + safe_strlen (s) - 1; p >= s && ISSPACE (*p); p--)
195     *p = 0;
196 }