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