1 /******************************************************************************/
2 /* pfixtools: a collection of postfix related tools */
4 /* ________________________________________________________________________ */
6 /* Redistribution and use in source and binary forms, with or without */
7 /* modification, are permitted provided that the following conditions */
10 /* 1. Redistributions of source code must retain the above copyright */
11 /* notice, this list of conditions and the following disclaimer. */
12 /* 2. Redistributions in binary form must reproduce the above copyright */
13 /* notice, this list of conditions and the following disclaimer in the */
14 /* documentation and/or other materials provided with the distribution. */
15 /* 3. The names of its contributors may not be used to endorse or promote */
16 /* products derived from this software without specific prior written */
19 /* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS */
20 /* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY */
23 /* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */
24 /* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS */
25 /* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) */
26 /* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, */
27 /* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
28 /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
29 /* POSSIBILITY OF SUCH DAMAGE. */
31 /* Copyright (c) 2006-2008 the Authors */
32 /* see AUTHORS and source files for details */
33 /******************************************************************************/
36 * Copyright © 2006 Pierre Habouzit
39 /** \addtogroup mutt_strings */
43 * \brief Madmutt string API module implementation.
44 * \author Pierre Habouzit <madcoder@debian.org>
49 #ifndef __doxygen_skip__
51 unsigned char const __m_strdigits[128] = {
52 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
53 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
54 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
55 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, XX, XX, XX, XX, XX, XX,
56 XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
57 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX,
58 XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
59 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX,
64 signed char const __m_b64digits[128] = {
65 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
66 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
67 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, 62, XX, XX, XX, 63,
68 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, XX, XX, XX, XX, XX, XX,
69 XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
70 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, XX, XX, XX, XX, XX,
71 XX, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
72 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, XX, XX, XX, XX, XX
76 char const __m_b64chars[64] = {
77 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
78 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
79 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
80 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
84 char const __m_b36chars_lower[36] = {
85 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
86 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
87 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
88 'u', 'v', 'w', 'x', 'y', 'z'
91 char const __m_b36chars_upper[36] = {
92 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
93 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
94 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
95 'U', 'V', 'W', 'X', 'Y', 'Z'
99 /** \brief safe strcpy.
101 * Copies at most <tt>n-1</tt> characters from \c src into \c dst, always
102 * adding a final \c \\0 in \c dst.
104 * \param[in] dst destination buffer.
105 * \param[in] n size of the buffer. Negative sizes are allowed.
106 * \param[in] src source string.
108 * \return \c src \e length. If this value is \>= \c n then the copy was
111 ssize_t m_strcpy(char *dst, ssize_t n, const char *src)
113 ssize_t len = m_strlen(src);
116 ssize_t dlen = MIN(n - 1, len);
117 memcpy(dst, src, dlen);
124 /** \brief safe limited strcpy.
126 * Copies at most min(<tt>n-1</tt>, \c l) characters from \c src into \c dst,
127 * always adding a final \c \\0 in \c dst.
129 * \param[in] dst destination buffer.
130 * \param[in] n size of the buffer. Negative sizes are allowed.
131 * \param[in] src source string.
132 * \param[in] l maximum number of chars to copy.
134 * \return minimum of \c src \e length and \c l.
136 ssize_t m_strncpy(char *dst, ssize_t n, const char *src, ssize_t l)
138 ssize_t len = m_strnlen(src, l);
141 ssize_t dlen = MIN(n - 1, len);
142 memcpy(dst, src, dlen);
149 char *m_strrtrim(char *s)
151 ssize_t len = m_strlen(s);
153 while (len > 1 && isspace((unsigned char)s[len - 1]))
159 const char *m_stristrn(const char *haystack, const char *needle, ssize_t nlen)
166 nc = tolower(*needle);
168 int c = tolower(*haystack);
176 /* compare the rest of needle */
182 c = tolower(haystack[i]);
183 if (c != tolower(needle[i]))
192 /** \brief \c NULL resistant strcasecmp.
193 * \param[in] a the first string.
194 * \param[in] b the second string.
195 * \return <tt>strcasecmp(a, b)</tt>, and treats \c NULL strings like \c ""
196 * ones, as if we were in the C locale.
198 int ascii_strcasecmp(const char *a, const char *b)
209 if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))
216 /** \brief \c NULL resistant strncasecmp.
217 * \param[in] a the first string.
218 * \param[in] b the second string.
219 * \param[in] n the number of maximum chars to compare.
220 * \return <tt>strncasecmp(a, b)</tt>, and treats \c NULL strings like \c ""
221 * ones, as if we were in the C locale.
223 int ascii_strncasecmp(const char *a, const char *b, ssize_t n)
232 while ((*a || *b) && n > 0) {
234 if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))