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