+/** \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));
+}
+
+/** \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);
+}
+
+/** \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);
+}
+
+int ascii_strcasecmp(const char *a, const char *b);
+int ascii_strncasecmp(const char *a, const char *b, ssize_t n);
+
+/****************************************************************************/
+/* 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;
+}
+
+/** \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));
+}
+
+/** \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));
+}
+
+/** \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;
+ dst[1] = '\0';
+ }
+ return 1;
+}