oops, ascii_strncasecmp tried to compare one byte too far
[apps/madmutt.git] / lib-lib / str.c
index e4616e6..f421530 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "lib-lib.h"
 
-#ifndef _DOXYGEN_SKIP_ME
+#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,
@@ -80,7 +80,7 @@ char const __m_b36chars_upper[36] = {
 /** \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.
+ * adding a final \c \\0 in \c dst.
  *
  * \param[in]  dst      destination buffer.
  * \param[in]  n        size of the buffer. Negative sizes are allowed.
@@ -102,6 +102,18 @@ ssize_t m_strcpy(char *dst, ssize_t n, const char *src)
     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);
@@ -117,16 +129,12 @@ ssize_t m_strncpy(char *dst, ssize_t n, const char *src, ssize_t l)
 
 char *m_strrtrim(char *s)
 {
-    if (s) {
-        char *p = s + m_strlen(s);
+    ssize_t len = m_strlen(s);
 
-        while (p > s && ISSPACE(p[-1])) {
-            *--p = '\0';
-        }
-        return p;
-    }
+    while (len > 1 && ISSPACE(s[len - 1]))
+        s[--len] = '\0';
 
-    return NULL;
+    return s + len;
 }
 
 const char *m_stristrn(const char *haystack, const char *needle, ssize_t nlen)
@@ -162,39 +170,51 @@ const char *m_stristrn(const char *haystack, const char *needle, ssize_t nlen)
     }
 }
 
+/** \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)
 {
-    int i;
-
     if (a == b)
         return 0;
-    if (a == NULL && b)
+    if (!a)
         return -1;
-    if (b == NULL && a)
+    if (!b)
         return 1;
 
-    for (; *a || *b; a++, b++) {
-        if ((i = ascii_tolower(*a) - ascii_tolower(*b)))
+    while (*a || *b) {
+        int i;
+        if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))
             return i;
     }
 
     return 0;
 }
 
-int ascii_strncasecmp (const char *a, const char *b, ssize_t n)
+/** \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)
 {
-    int i, j;
-
     if (a == b)
         return 0;
-    if (a == NULL && b)
+    if (!a)
         return -1;
-    if (b == NULL && a)
+    if (!b)
         return 1;
 
-    for (j = 0; (*a || *b) && j < n; a++, b++, j++) {
-        if ((i = ascii_tolower(*a) - ascii_tolower(*b)))
+    while ((*a || *b) && n > 0) {
+        int i;
+        if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))
             return i;
+        n--;
     }
 
     return 0;