string documentation.
authorPierre Habouzit <madcoder@debian.org>
Fri, 1 Dec 2006 22:40:30 +0000 (23:40 +0100)
committerPierre Habouzit <madcoder@debian.org>
Fri, 1 Dec 2006 22:40:30 +0000 (23:40 +0100)
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
apidoc/doxygen.cfg.in
lib-lib/str.c
lib-lib/str.h
muttlib.c

index 9c328db..708849e 100644 (file)
@@ -574,13 +574,13 @@ STRIP_CODE_COMMENTS    = YES
 # then for each documented function all documented 
 # functions referencing it will be listed.
 
 # then for each documented function all documented 
 # functions referencing it will be listed.
 
-REFERENCED_BY_RELATION = YES
+REFERENCED_BY_RELATION = NO
 
 # If the REFERENCES_RELATION tag is set to YES (the default) 
 # then for each documented function all documented entities 
 # called/used by that function will be listed.
 
 
 # If the REFERENCES_RELATION tag is set to YES (the default) 
 # then for each documented function all documented entities 
 # called/used by that function will be listed.
 
-REFERENCES_RELATION    = YES
+REFERENCES_RELATION    = NO
 
 # If the USE_HTAGS tag is set to YES then the references to source code 
 # will point to the HTML generated by the htags(1) tool instead of doxygen 
 
 # If the USE_HTAGS tag is set to YES then the references to source code 
 # will point to the HTML generated by the htags(1) tool instead of doxygen 
@@ -709,7 +709,7 @@ TOC_EXPAND             = NO
 # top of each HTML page. The value NO (the default) enables the index and 
 # the value YES disables it.
 
 # top of each HTML page. The value NO (the default) enables the index and 
 # the value YES disables it.
 
-DISABLE_INDEX          = YES
+DISABLE_INDEX          = NO
 
 # This tag can be used to set the number of enum values (range [1..20]) 
 # that doxygen will group on one line in the generated HTML documentation.
 
 # This tag can be used to set the number of enum values (range [1..20]) 
 # that doxygen will group on one line in the generated HTML documentation.
@@ -1006,14 +1006,15 @@ INCLUDE_FILE_PATTERNS  =
 # undefined via #undef or recursively expanded use the := operator 
 # instead of the = operator.
 
 # undefined via #undef or recursively expanded use the := operator 
 # instead of the = operator.
 
-PREDEFINED             = _DOXYGEN_SKIP_ME
+PREDEFINED             = __doxygen_skip__                 \
+                         __attribute__(x)=
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
 # this tag can be used to specify a list of macro names that should be expanded. 
 # The macro definition that is found in the sources will be used. 
 # Use the PREDEFINED tag if you want to use a different macro definition.
 
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
 # this tag can be used to specify a list of macro names that should be expanded. 
 # The macro definition that is found in the sources will be used. 
 # Use the PREDEFINED tag if you want to use a different macro definition.
 
-EXPAND_AS_DEFINED      = 
+EXPAND_AS_DEFINED      = __attribute__(x)
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
 # doxygen's preprocessor will remove all function-like macros that are alone 
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
 # doxygen's preprocessor will remove all function-like macros that are alone 
index ab603da..39e6a90 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "lib-lib.h"
 
 
 #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,
 #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
 /** \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.
  *
  * \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;
 }
 
     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);
 ssize_t m_strncpy(char *dst, ssize_t n, const char *src, ssize_t l)
 {
     ssize_t len = MIN(m_strlen(src), l);
@@ -158,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 ascii_strcasecmp(const char *a, const char *b)
 {
-    int i;
-
     if (a == b)
         return 0;
     if (a == b)
         return 0;
-    if (a == NULL && b)
-        return -1;
-    if (b == NULL && a)
-        return 1;
-
-    for (; *a || *b; a++, b++) {
-        if ((i = ascii_tolower(*a) - ascii_tolower(*b)))
+    if (!a)
+        a = "";
+    if (!b)
+        b = "";
+
+    while (*a || *b) {
+        int i;
+        if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))
             return i;
     }
 
     return 0;
 }
 
             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 == b)
         return 0;
-    if (a == NULL && b)
-        return -1;
-    if (b == NULL && a)
-        return 1;
-
-    for (j = 0; (*a || *b) && j < n; a++, b++, j++) {
-        if ((i = ascii_tolower(*a) - ascii_tolower(*b)))
+    if (!a)
+        a = "";
+    if (!b)
+        b = "";
+
+    while ((*a || *b) && n >= 0) {
+        int i;
+        if ((i = ascii_tolower(*a++) - ascii_tolower(*b++)))
             return i;
             return i;
+        n--;
     }
 
     return 0;
     }
 
     return 0;
index 8c793fb..3133585 100644 (file)
  * strings.
  *
  * The strong point that have to be followed are:
  * strings.
  *
  * The strong point that have to be followed are:
- *  - strings are always \c '\\0' terminated, meaning that we don't have
+ *  - strings are always \c \\0 terminated, meaning that we don't have
  *    stupid semantics à la strncpy.
  *  - function try to always work on buffers with its size (including the
  *    stupid semantics à la strncpy.
  *  - function try to always work on buffers with its size (including the
- *    ending \c '\\0') to prevent buffer overflows.
+ *    ending \c \\0) to prevent buffer overflows.
  *  - string and buffers sizes are \c ssize_t, negative values are allowed and
  *    supported.
  *  - functions use a à la sprintf semantics (for those that produce strings)
  *    meaning that they all return the len that could have fit in the buffer
  *    if it would have been big enough. We never try to reallocate the
  *    buffers, it's up to the caller if it's needed.
  *  - string and buffers sizes are \c ssize_t, negative values are allowed and
  *    supported.
  *  - functions use a à la sprintf semantics (for those that produce strings)
  *    meaning that they all return the len that could have fit in the buffer
  *    if it would have been big enough. We never try to reallocate the
  *    buffers, it's up to the caller if it's needed.
+ *
+ * Many of the function do no difference between \c NULL and \c "" and will
+ * behave the same when you pass either the former or the latter (m_strlen(),
+ * m_strcpy(), ... to cite a few).
  */
 /*@{*/
 
  */
 /*@{*/
 
 #define LONG_STRING     1024   /**< \brief Long buffers */
 #define STRING          256    /**< \brief Usual buffers */
 
 #define LONG_STRING     1024   /**< \brief Long buffers */
 #define STRING          256    /**< \brief Usual buffers */
 
-#define NONULL(x)       (x ? x : "")  /**< \brief replace \c NULL strings
-                                                  with emtpy strings */
-#define ISSPACE(c)      isspace((unsigned char)c) /**< \brief safe isspace */
+/** \brief replace \c NULL strings with emtpy strings */
+#define NONULL(x)       (x ? x : "")
+/** \brief safe isspace */
+#define ISSPACE(c)      isspace((unsigned char)c)
 
 /** \brief Convert ascii digits into ints.
  *
 
 /** \brief Convert ascii digits into ints.
  *
@@ -66,7 +71,7 @@
  *
  * Translating a digit \c c into its numerical value in base \c x is just doing:
  * \code
  *
  * Translating a digit \c c into its numerical value in base \c x is just doing:
  * \code
- *   return (c & ~127) && __m_strdigits[c] < x ? __m_strdigits[c] : -1;
+ *   return !(c & ~127) && __m_strdigits[c] < x ? __m_strdigits[c] : -1;
  * \endcode
  */
 extern unsigned char const __m_strdigits[128];
  * \endcode
  */
 extern unsigned char const __m_strdigits[128];
@@ -89,19 +94,41 @@ extern char const __m_b36chars_upper[36];
 /* conversions                                                              */
 /****************************************************************************/
 
 /* conversions                                                              */
 /****************************************************************************/
 
+/** \brief Converts an hexadecimal digit into an int.
+ * \param[in]  c    the hexadecimal char
+ * \return
+ *   - 0&ndash;15 if c is a valid hexadecimal digit,
+ *   - -1 on error.
+ */
 static inline int hexval(int c) {
     return !(c & ~127) && __m_strdigits[c] < 16 ? __m_strdigits[c] : -1;
 }
 
 static inline int hexval(int c) {
     return !(c & ~127) && __m_strdigits[c] < 16 ? __m_strdigits[c] : -1;
 }
 
+/** \brief Converts a base64 digit into an int.
+ * \param[in]  c    the base64 char
+ * \return
+ *   - 0&ndash;15 if c is a valid base64 digit,
+ *   - -1 on error.
+ */
 static inline int base64val(int c) {
     return (c & ~127) ? -1 : __m_b64digits[c];
 }
 
 static inline int base64val(int c) {
     return (c & ~127) ? -1 : __m_b64digits[c];
 }
 
-static inline void m_strtolower(char *p) {
+/** \brief Converts a string to lowercase.
+ * \param[in] p     the string, shall not be \c NULL.
+ * \return a pointer to the terminating \c \\0.
+ */
+__attribute__((nonnull(1)))
+static inline char *m_strtolower(char *p) {
     for (; *p; p++)
         *p = tolower((unsigned char)*p);
     for (; *p; p++)
         *p = tolower((unsigned char)*p);
+    return p;
 }
 
 }
 
+/** \brief Converts a lower case ascii char to upper case.
+ * \param[in]  c    the character.
+ * \return the upper case character.
+ */
 static inline int ascii_toupper(int c) {
     if ('a' <= c && c <= 'z')
         return c & ~32;
 static inline int ascii_toupper(int c) {
     if ('a' <= c && c <= 'z')
         return c & ~32;
@@ -109,6 +136,10 @@ static inline int ascii_toupper(int c) {
     return c;
 }
 
     return c;
 }
 
+/** \brief Converts a upper case ascii char to lower case.
+ * \param[in]  c    the character.
+ * \return the lower case character.
+ */
 static inline int ascii_tolower(int c) {
     if ('A' <= c && c <= 'Z')
         return c | 32;
 static inline int ascii_tolower(int c) {
     if ('A' <= c && c <= 'Z')
         return c | 32;
@@ -120,35 +151,89 @@ static inline int ascii_tolower(int c) {
 /* length related                                                           */
 /****************************************************************************/
 
 /* length related                                                           */
 /****************************************************************************/
 
+/** \brief Short hand to test if a string is empty or not.
+ * \param[in]  s    the string.
+ * \return \c true iff s is an empty string.
+ */
 static inline int m_strisempty(const char *s) {
     return !s || !*s;
 }
 
 static inline int m_strisempty(const char *s) {
     return !s || !*s;
 }
 
+/** \brief \c NULL resistant strlen.
+ *
+ * Unlinke it's libc sibling, m_strlen returns a ssize_t, and supports its
+ * argument beeing NULL.
+ *
+ * \param[in]  s    the string.
+ * \return the string length (or 0 if \c s is \c NULL).
+ */
 static inline ssize_t m_strlen(const char *s) {
     return s ? strlen(s) : 0;
 }
 
 static inline ssize_t m_strlen(const char *s) {
     return s ? strlen(s) : 0;
 }
 
+/** \brief \c NULL resistant strnlen.
+ *
+ * Unlinke it's GNU libc sibling, m_strnlen returns a ssize_t, and supports
+ * its argument beeing NULL.
+ *
+ * The m_strnlen() function returns the number of characters in the string
+ * pointed to by \c s, not including the terminating \c \\0 character, but at
+ * most \c n. In doing this, m_strnlen() looks only at the first \c n
+ * characters at \c s and never beyond \c s+n.
+ *
+ * \param[in]  s    the string.
+ * \param[in]  n    the maximum length to return.
+ * \return \c m_strlen(s) if less than \c n, else \c n.
+ */
 static inline ssize_t m_strnlen(const char *s, ssize_t n) {
 static inline ssize_t m_strnlen(const char *s, ssize_t n) {
-    const char *p = memchr(s, '\0', n);
-    return p ? p - s : n;
+    if (s) {
+        const char *p = memchr(s, '\0', n);
+        return p ? p - s : n;
+    }
+    return 0;
 }
 
 /****************************************************************************/
 /* comparisons                                                              */
 /****************************************************************************/
 
 }
 
 /****************************************************************************/
 /* comparisons                                                              */
 /****************************************************************************/
 
+/** \brief \c NULL resistant strcmp.
+ * \param[in]  a     the first string.
+ * \param[in]  b     the second string.
+ * \return <tt>strcmp(a, b)</tt>, and treats \c NULL strings like \c "" ones.
+ */
 static inline int m_strcmp(const char *a, const char *b) {
     return strcmp(NONULL(a), NONULL(b));
 }
 
 static inline int m_strcmp(const char *a, const char *b) {
     return strcmp(NONULL(a), NONULL(b));
 }
 
+/** \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.
+ */
 static inline int m_strcasecmp(const char *a, const char *b) {
     return strcasecmp(NONULL(a), NONULL(b));
 }
 
 static inline int m_strcasecmp(const char *a, const char *b) {
     return strcasecmp(NONULL(a), NONULL(b));
 }
 
+/** \brief \c NULL resistant strncmp.
+ * \param[in]  a     the first string.
+ * \param[in]  b     the second string.
+ * \param[in]  n     the number of maximum chars to compare.
+ * \return <tt>strncmp(a, b, n)</tt>, and treats \c NULL strings like \c ""
+ * ones.
+ */
 static inline int m_strncmp(const char *a, const char *b, ssize_t n) {
     return strncmp(NONULL(a), NONULL(b), n);
 }
 
 static inline int m_strncmp(const char *a, const char *b, ssize_t n) {
     return strncmp(NONULL(a), NONULL(b), 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>strcasecmp(a, b, n)</tt>, and treats \c NULL strings like \c ""
+ * ones.
+ */
 static inline int m_strncasecmp(const char *a, const char *b, ssize_t n) {
     return strncasecmp(NONULL(a), NONULL(b), n);
 }
 static inline int m_strncasecmp(const char *a, const char *b, ssize_t n) {
     return strncasecmp(NONULL(a), NONULL(b), n);
 }
@@ -160,20 +245,54 @@ int ascii_strncasecmp(const char *a, const char *b, ssize_t n);
 /* making copies                                                            */
 /****************************************************************************/
 
 /* making copies                                                            */
 /****************************************************************************/
 
+/** \brief \c NULL resistant strdup.
+ *
+ * the m_strdup() function returns a pointer to a new string, which is a
+ * duplicate of \c s. Memory should be freed using p_delete().
+ *
+ * \warning when s is \c "", it returns NULL !
+ *
+ * \param[in]  s    the string to duplicate.
+ * \return a pointer to the duplicated string.
+ */
 static inline char *m_strdup(const char *s) {
     ssize_t len = m_strlen(s);
     return len ? p_dup(s, len + 1) : NULL;
 }
 
 static inline char *m_strdup(const char *s) {
     ssize_t len = m_strlen(s);
     return len ? p_dup(s, len + 1) : NULL;
 }
 
+/** \brief Duplicate substrings.
+ * \deprecated API IS NOT GOOD, I WILL DEPRECATE IT IN A NEAR FUTURE.
+ */
 static inline char *m_substrdup(const char *s, const char *end) {
     return p_dupstr(s, end ? end - s : m_strlen(s));
 }
 
 static inline char *m_substrdup(const char *s, const char *end) {
     return p_dupstr(s, end ? end - s : m_strlen(s));
 }
 
+/** \brief Replace an allocated string with another.
+ *
+ * Replace the string pointed by \c *p with a copy of the string \c s.
+ * \c *p must point to a buffer allocated with p_new() or one of its alias.
+ *
+ * \param[in,out]  p    a pointer on a string (<tt>char **</tt>)
+ * \param[in]      s    the string to copy into p.
+ * \return a pointer on the duplicated string (aka \c *p).
+ */
+__attribute__((nonnull(1)))
 static inline char *m_strreplace(char **p, const char *s) {
     p_delete(p);
     return (*p = m_strdup(s));
 }
 
 static inline char *m_strreplace(char **p, const char *s) {
     p_delete(p);
     return (*p = m_strdup(s));
 }
 
+/** \brief Puts a char in a string buffer.
+ *
+ * Puts a char at position 0 of a string buffer of size \c n.
+ * Then \c \\0 terminate the buffer.
+ *
+ * \param[in]  dst   pointer to the buffer.
+ * \param[in]  n     size of that buffer (negative values allowed).
+ * \param[in]  c     the character to append.
+ * \return always return 1.
+ */
+__attribute__((nonnull(1)))
 static inline ssize_t m_strputc(char *dst, ssize_t n, int c) {
     if (n > 1) {
         dst[0] = c;
 static inline ssize_t m_strputc(char *dst, ssize_t n, int c) {
     if (n > 1) {
         dst[0] = c;
@@ -188,11 +307,33 @@ ssize_t m_strcpy(char *dst, ssize_t n, const char *src)
 ssize_t m_strncpy(char *dst, ssize_t n, const char *src, ssize_t l)
     __attribute__((nonnull(1)));
 
 ssize_t m_strncpy(char *dst, ssize_t n, const char *src, ssize_t l)
     __attribute__((nonnull(1)));
 
+/** \brief safe strcat.
+ *
+ * The m_strcat() function appends the string \c src at the end of the buffer
+ * \c dst if space is available.
+ *
+ * \param[in]  dst   destination buffer.
+ * \param[in]  n     size of the buffer, Negative sizes are allowed.
+ * \param[in]  src   the string to append.
+ * \return <tt>m_strlen(dst) + m_strlen(src)</tt>
+ */
 static inline ssize_t m_strcat(char *dst, ssize_t n, const char *src) {
     ssize_t dlen = m_strnlen(dst, n - 1);
     return dlen + m_strcpy(dst + dlen, n - dlen, src);
 }
 
 static inline ssize_t m_strcat(char *dst, ssize_t n, const char *src) {
     ssize_t dlen = m_strnlen(dst, n - 1);
     return dlen + m_strcpy(dst + dlen, n - dlen, src);
 }
 
+/** \brief safe strncat.
+ *
+ * The m_strncat() function appends at most \c n chars from the string \c src
+ * at the end of the buffer \c dst if space is available.
+ *
+ * \param[in]  dst   destination buffer.
+ * \param[in]  n     size of the buffer, Negative sizes are allowed.
+ * \param[in]  src   the string to append.
+ * \param[in]  l     maximum number of chars of src to consider.
+ * \return the smallest value between <tt>m_strlen(dst) + m_strlen(src)</tt>
+ *         and <tt>m_strlen(dst) + l</tt>
+ */
 static inline ssize_t
 m_strncat(char *dst, ssize_t n, const char *src, ssize_t l) {
     ssize_t dlen = m_strnlen(dst, n - 1);
 static inline ssize_t
 m_strncat(char *dst, ssize_t n, const char *src, ssize_t l) {
     ssize_t dlen = m_strnlen(dst, n - 1);
index 1f8ab30..590b53a 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -750,7 +750,7 @@ int mutt_extract_token(BUFFER *dest, BUFFER *tok, int flags)
                 if (!*tok->dptr)
                     return -1;          /* premature end of token */
                 mutt_buffer_addch(dest,
                 if (!*tok->dptr)
                     return -1;          /* premature end of token */
                 mutt_buffer_addch(dest,
-                                  (ascii_toupper(*tok->dptr) - 'A' + 1) & 0x7f);
+                                  (toupper((unsigned char)*tok->dptr) - 'A' + 1) & 0x7f);
                 tok->dptr++;
                 break;
               case 'r':
                 tok->dptr++;
                 break;
               case 'r':
@@ -792,7 +792,7 @@ int mutt_extract_token(BUFFER *dest, BUFFER *tok, int flags)
                 mutt_buffer_addch(dest, '\033');
             } else
             if (isalpha((unsigned char)ch)) {
                 mutt_buffer_addch(dest, '\033');
             } else
             if (isalpha((unsigned char)ch)) {
-                mutt_buffer_addch(dest, ascii_toupper(ch) - 'A' + 1);
+                mutt_buffer_addch(dest, toupper((unsigned char)ch) - 'A' + 1);
             } else {
                 mutt_buffer_addch(dest, '^');
                 mutt_buffer_addch(dest, ch);
             } else {
                 mutt_buffer_addch(dest, '^');
                 mutt_buffer_addch(dest, ch);