/* conversions */
/****************************************************************************/
+/** \brief Converts an octal digit into an int.
+ * \param[in] c the octal char
+ * \return
+ * - 0–7 if c is a valid octal digit,
+ * - -1 on error.
+ */
+static inline int octval(int c) {
+ return !(c & ~127) && __m_strdigits[c] < 7 ? __m_strdigits[c] : -1;
+}
+
/** \brief Converts an hexadecimal digit into an int.
* \param[in] c the hexadecimal char
* \return
return 0;
}
+ssize_t m_strwidth(const char *s);
+
/****************************************************************************/
/* comparisons */
/****************************************************************************/
+/** \brief Tells whether s begins with p.
+ *
+ * \param[in] s the input string
+ * \param[in] p the prefix
+ * \param[out] pp position in s
+ *
+ * \return 1 if a match is found, 0 otherwise.
+ */
+static inline int m_strstart(const char *s, const char *p, const char **pp)
+{
+ if (!s)
+ return 0;
+
+ while (*p) {
+ if (*s++ != *p++)
+ return 0;
+ }
+ if (pp)
+ *pp = s;
+ return 1;
+}
+
/** \brief \c NULL resistant strcmp.
* \param[in] a the first string.
* \param[in] b the second string.
return 1;
}
+/** \brief Sets a portion of a string to a defined character, à la memset.
+ *
+ * \param[in] dst pointer to the buffer.
+ * \param[in] n size of that buffer, (negative values allowed).
+ * \param[in] c the char to use in the padding.
+ * \param[in] len length of the padding.
+ * \return MAX(0, len).
+ */
+__attribute__((nonnull(1)))
+static inline ssize_t m_strpad(char *dst, ssize_t n, int c, ssize_t len)
+{
+ ssize_t dlen = MIN(n - 1, len);
+ if (dlen > 0) {
+ memset(dst, c, dlen);
+ dst[dlen] = '\0';
+ }
+ return MAX(0, len);
+}
+
ssize_t m_strcpy(char *dst, ssize_t n, const char *src)
__attribute__((nonnull(1)));
return dlen + m_strncpy(dst + dlen, n - dlen, src, l);
}
+/* flags for m_strformat() */
+typedef enum {
+ M_FORMAT_FORCESUBJ = (1 << 0), /* print the subject even if unchanged */
+ M_FORMAT_TREE = (1 << 1), /* draw the thread tree */
+ M_FORMAT_MAKEPRINT = (1 << 2), /* make sure that all chars are printable */
+ M_FORMAT_OPTIONAL = (1 << 3),
+ M_FORMAT_STAT_FILE = (1 << 4), /* used by mutt_attach_fmt */
+ M_FORMAT_INDEX = (1 << 6), /* this is a main index entry */
+} format_flag;
+
+typedef const char *
+format_t(char *, ssize_t, char, const char *,
+ const char *, const char *, const char *, anytype, format_flag);
+
+ssize_t m_strformat(char *, ssize_t, int, const char *,
+ format_t *, anytype, format_flag);
+
/****************************************************************************/
/* parsing related */
/****************************************************************************/
+__attribute__((nonnull(1)))
static inline const char *m_strchrnul(const char *s, int c) {
while (*s && *s != c)
s++;
return s;
}
+__attribute__((nonnull(1)))
static inline const char *m_strnextsp(const char *s) {
while (*s && !isspace((unsigned char)*s))
s++;
return s;
}
+__attribute__((nonnull(1)))
static inline const char *skipspaces(const char *s) {
- while (*s && isspace((unsigned char)*s))
+ while (isspace((unsigned char)*s))
s++;
return s;
}
+__attribute__((nonnull(1)))
static inline char *vskipspaces(const char *s) {
return (char *)skipspaces(s);
}