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