* Copyright © 2006 Pierre Habouzit
*/
-#include "macros.h"
-#include "str.h"
+/** \addtogroup mutt_strings */
+/*@{*/
+/** \file str.c
+ * \brief Madmutt string API module implementation.
+ * \author Pierre Habouzit <madcoder@debian.org>
+ */
+
+#include "lib-lib.h"
+
+#ifndef __doxygen_skip__
#define XX 255
unsigned char const __m_strdigits[128] = {
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
};
+#endif
-
+/** \brief safe strcpy.
+ *
+ * Copies at most <tt>n-1</tt> characters from \c src into \c dst, always
+ * adding a final \c \\0 in \c dst.
+ *
+ * \param[in] dst destination buffer.
+ * \param[in] n size of the buffer. Negative sizes are allowed.
+ * \param[in] src source string.
+ *
+ * \return \c src \e length. If this value is \>= \c n then the copy was
+ * truncated.
+ */
ssize_t m_strcpy(char *dst, ssize_t n, const char *src)
{
ssize_t len = m_strlen(src);
- if (dst && n > 0) {
+ if (n > 0) {
ssize_t dlen = MIN(n - 1, len);
memcpy(dst, src, dlen);
dst[dlen] = '\0';
return len;
}
+/** \brief safe limited strcpy.
+ *
+ * Copies at most min(<tt>n-1</tt>, \c l) characters from \c src into \c dst,
+ * always adding a final \c \\0 in \c dst.
+ *
+ * \param[in] dst destination buffer.
+ * \param[in] n size of the buffer. Negative sizes are allowed.
+ * \param[in] src source string.
+ * \param[in] l maximum number of chars to copy.
+ *
+ * \return minimum of \c src \e length and \c l.
+ */
ssize_t m_strncpy(char *dst, ssize_t n, const char *src, ssize_t l)
{
ssize_t len = MIN(m_strlen(src), l);
- if (dst && n > 0) {
+ if (n > 0) {
ssize_t dlen = MIN(n - 1, len);
memcpy(dst, src, dlen);
dst[dlen] = '\0';
return len;
}
+
+char *m_strrtrim(char *s)
+{
+ ssize_t len = m_strlen(s);
+
+ while (len > 1 && ISSPACE(s[len - 1]))
+ s[--len] = '\0';
+
+ return s + len;
+}
+
+const char *m_stristrn(const char *haystack, const char *needle, ssize_t nlen)
+{
+ int nc;
+
+ if (!nlen)
+ return haystack;
+
+ nc = tolower(*needle);
+ for (;;) {
+ int c = tolower(*haystack);
+
+ if (c != nc) {
+ if (c == '\0')
+ return NULL;
+ } else {
+ ssize_t i;
+
+ /* compare the rest of needle */
+ for (i = 1;; i++) {
+ if (i == nlen)
+ return haystack;
+ if (c == '\0')
+ return NULL;
+ c = tolower(haystack[i]);
+ if (c != tolower(needle[i]))
+ break;
+ }
+ }
+
+ haystack++;
+ }
+}
+
+/** \brief \c NULL resistant strcasecmp.
+ * \param[in] a the first string.
+ * \param[in] b the second string.
+ * \return <tt>strcasecmp(a, b)</tt>, and treats \c NULL strings like \c ""
+ * ones, as if we were in the C locale.
+ */
+int ascii_strcasecmp(const char *a, const char *b)
+{
+ if (a == b)
+ return 0;
+ if (!a)
+ return -1;
+ if (!b)
+ return 1;
+
+ while (*a || *b) {
+ int i;
+ if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))
+ return i;
+ }
+
+ return 0;
+}
+
+/** \brief \c NULL resistant strncasecmp.
+ * \param[in] a the first string.
+ * \param[in] b the second string.
+ * \param[in] n the number of maximum chars to compare.
+ * \return <tt>strncasecmp(a, b)</tt>, and treats \c NULL strings like \c ""
+ * ones, as if we were in the C locale.
+ */
+int ascii_strncasecmp(const char *a, const char *b, ssize_t n)
+{
+ if (a == b)
+ return 0;
+ if (!a)
+ return -1;
+ if (!b)
+ return 1;
+
+ while ((*a || *b) && n > 0) {
+ int i;
+ if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))
+ return i;
+ n--;
+ }
+
+ return 0;
+}
+
+/*@}*/