79bb46932e719096fd8216d5e4c9b1db94fc8acb
[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 = mutt_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 void mutt_str_replace (char **p, const char *s)
71 {
72   FREE (p);
73   *p = safe_strdup (s);
74 }
75
76 void mutt_str_adjust (char **p)
77 {
78   if (!p || !*p)
79     return;
80   safe_realloc (p, mutt_strlen (*p) + 1);
81 }
82
83 /* convert all characters in the string to lowercase */
84 char *mutt_strlower (char *s)
85 {
86   char *p = s;
87
88   while (*p) {
89     *p = tolower ((unsigned char) *p);
90     p++;
91   }
92
93   return (s);
94 }
95
96 /* NULL-pointer aware string comparison functions */
97
98 char *mutt_substrcpy (char *dest, const char *beg, const char *end,
99                       size_t destlen)
100 {
101   size_t len;
102
103   len = end - beg;
104   if (len > destlen - 1)
105     len = destlen - 1;
106   memcpy (dest, beg, len);
107   dest[len] = 0;
108   return dest;
109 }
110
111 char *mutt_substrdup (const char *begin, const char *end)
112 {
113   size_t len;
114   char *p;
115
116   if (end)
117     len = end - begin;
118   else
119     len = mutt_strlen (begin);
120
121   p = safe_malloc (len + 1);
122   memcpy (p, begin, len);
123   p[len] = 0;
124   return p;
125 }
126
127 int mutt_strcmp (const char *a, const char *b)
128 {
129   return strcmp (NONULL (a), NONULL (b));
130 }
131
132 int mutt_strcasecmp (const char *a, const char *b)
133 {
134   return strcasecmp (NONULL (a), NONULL (b));
135 }
136
137 int mutt_strncmp (const char *a, const char *b, size_t l)
138 {
139   return strncmp (NONULL (a), NONULL (b), l);
140 }
141
142 int mutt_strncasecmp (const char *a, const char *b, size_t l)
143 {
144   return strncasecmp (NONULL (a), NONULL (b), l);
145 }
146
147 size_t mutt_strlen (const char *a)
148 {
149   return a ? strlen (a) : 0;
150 }
151
152 int mutt_strcoll (const char *a, const char *b)
153 {
154   return strcoll (NONULL (a), NONULL (b));
155 }
156
157 const char *mutt_stristr (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 char *mutt_skip_whitespace (char *p)
179 {
180   SKIPWS (p);
181   return p;
182 }
183
184 void mutt_remove_trailing_ws (char *s)
185 {
186   char *p;
187
188   for (p = s + mutt_strlen (s) - 1; p >= s && ISSPACE (*p); p--)
189     *p = 0;
190 }
191