49#ifndef HAVE_STRCASESTR
56static char *
strcasestr(
const char *haystack,
const char *needle)
58 size_t haystackn = strlen(haystack);
59 size_t needlen = strlen(needle);
61 const char *p = haystack;
62 while (haystackn >= needlen)
64 if (strncasecmp(p, needle, needlen) == 0)
82static char *
strsep(
char **stringp,
const char *delim)
87 char *start = *stringp;
88 for (
char *p = *stringp; *p !=
'\0'; p++)
90 for (
const char *s = delim; *s !=
'\0'; s++)
117 { 0xff & EX_USAGE,
"Bad usage." },
120 { 0xff & EX_DATAERR,
"Data format error." },
123 { 0xff & EX_NOINPUT,
"Can't open input." },
126 { 0xff & EX_NOUSER,
"User unknown." },
129 { 0xff & EX_NOHOST,
"Host unknown." },
132 { 0xff & EX_UNAVAILABLE,
"Service unavailable." },
135 { 0xff & EX_SOFTWARE,
"Internal error." },
138 { 0xff & EX_OSERR,
"Operating system error." },
141 { 0xff & EX_OSFILE,
"System file missing." },
144 { 0xff & EX_CANTCREAT,
"Can't create output." },
147 { 0xff & EX_IOERR,
"I/O error." },
150 { 0xff & EX_TEMPFAIL,
"Deferred." },
153 { 0xff & EX_PROTOCOL,
"Remote protocol error." },
156 { 0xff & EX_NOPERM,
"Insufficient permission." },
159 { 0xff & EX_NOPERM,
"Local configuration error." },
161 {
S_ERR,
"Exec error." },
188 if (!stringp || !*stringp || !delim)
190 return strsep(stringp, delim);
201static size_t startswith(
const char *str,
const char *prefix,
bool match_case)
203 if (!str || (str[0] ==
'\0') || !prefix || (prefix[0] ==
'\0'))
208 const char *saved_prefix = prefix;
209 for (; *str && *prefix; str++, prefix++)
214 if (!match_case && tolower(*str) == tolower(*prefix))
220 return (*prefix ==
'\0') ? (prefix - saved_prefix) : 0;
255 if (!str || (*str ==
'\0'))
258 char *p = strdup(str);
284 const char *tmp = *p;
322 *p = tolower((
unsigned char) *p);
345 *p = toupper((
unsigned char) *p);
362 if (!src || !dest || (len == 0) || (dsize == 0))
365 if (len > (dsize - 1))
367 memcpy(dest, src, len);
386 memcpy(p, begin, len);
469const char *
mutt_istrn_rfind(
const char *haystack,
size_t haystack_length,
const char *needle)
471 if (!haystack || (haystack_length == 0) || !needle)
474 int needle_length = strlen(needle);
475 const char *haystack_end = haystack + haystack_length - needle_length;
477 for (
const char *p = haystack_end; p >= haystack; --p)
479 for (
size_t i = 0; i < needle_length; i++)
481 if ((tolower((
unsigned char) p[i]) != tolower((
unsigned char) needle[i])))
498 return a ? strlen(a) : 0;
528 const char *p = NULL, *q = NULL;
530 while (*(p = haystack))
533 *p && *q && (tolower((
unsigned char) *p) == tolower((
unsigned char) *q));
570 for (
char *p = s +
mutt_str_len(s) - 1; (p >= s) && isspace(*p); p--)
583 if (!dest || (dsize == 0))
592 while ((--dsize > 0) && (*src !=
'\0'))
639 for (; p < (s + n); p++)
641 if (!strchr(
" \t\r\n", *p))
648 if ((len != 0) && strchr(
"\r\n", *(p - 1)))
688 for (; (*str !=
'\0') && (len > 0); str++, len--)
689 if ((*str & 0x80) != 0)
711 while (*src && strchr(
" \t\n", *src))
713 while (*src && !strchr(
" \t\n", *src))
731 const char *val = getenv(name);
732 if (val && (val[0] !=
'\0'))
752 while ((str = (
char *)
strcasestr(str, target)))
755 memmove(str, str + target_len, 1 + strlen(str + target_len));
780 n = vasprintf(strp, fmt, ap);
815 const int n = vsnprintf(*strp, rlen, fmt, ap);
829 else if (n != rlen - 1)
851 if (!buf || (buflen == 0) || !str)
855 for (; *buf !=
'\0'; buf++)
889#define IS_INBOX(s) (mutt_istrn_equal(s, "inbox", 5) && !isalnum((s)[5]))
890#define CMP_INBOX(a, b) (IS_INBOX(b) - IS_INBOX(a))
893 if ((a[0] ==
'+') && (b[0] ==
'+'))
898 const char *a_end = strrchr(a,
'/');
899 const char *b_end = strrchr(b,
'/');
902 if ((!a_end) ^ (!b_end))
910 size_t a_len = a_end - a;
911 size_t b_len = b_end - b;
912 size_t min =
MIN(a_len, b_len);
913 int same = (a[min] ==
'/') && (b[min] ==
'/') && (a[min + 1] !=
'\0') &&
919 return CMP_INBOX(a + 1 + min, b + 1 + min);
int mutt_str_inbox_cmp(const char *a, const char *b)
Do two folders share the same path and one is an inbox -.
void mutt_exit(int code)
Leave NeoMutt NOW.
Memory management wrappers.
#define MUTT_MEM_REALLOC(pptr, n, type)
#define MUTT_MEM_MALLOC(n, type)
#define mutt_array_size(x)
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
int mutt_istrn_cmp(const char *a, const char *b, size_t num)
Compare two strings ignoring case (to a maximum), safely.
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
static size_t startswith(const char *str, const char *prefix, bool match_case)
Check whether a string starts with a prefix.
char * mutt_str_dup(const char *str)
Copy a string, safely.
int mutt_str_asprintf(char **strp, const char *fmt,...)
char * mutt_str_upper(char *str)
Convert all characters in the string to uppercase.
char * mutt_str_lower(char *str)
Convert all characters in the string to lowercase.
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
const char * mutt_istrn_rfind(const char *haystack, size_t haystack_length, const char *needle)
Find last instance of a substring, ignoring case.
size_t mutt_str_lws_len(const char *s, size_t n)
Measure the linear-white-space at the beginning of a string.
bool mutt_str_is_ascii(const char *str, size_t len)
Is a string ASCII (7-bit)?
int mutt_istr_cmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
static char * strsep(char **stringp, const char *delim)
Extract a token from a string.
const char * mutt_str_find_word(const char *src)
Find the end of a word (non-space)
char * mutt_strn_copy(char *dest, const char *src, size_t len, size_t dsize)
Copy a sub-string into a buffer.
int mutt_istr_remall(char *str, const char *target)
Remove all occurrences of substring, ignoring case.
const char * mutt_str_getenv(const char *name)
Get an environment variable.
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
void mutt_str_hyphenate(char *buf, size_t buflen, const char *str)
Hyphenate a snake-case string.
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
void mutt_str_adjust(char **ptr)
Shrink-to-fit a string.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
static char * strcasestr(const char *haystack, const char *needle)
Find the first occurrence of needle in haystack, ignoring case.
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
const char * mutt_str_sysexit(int err_num)
Return a string matching an error code.
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
char * mutt_str_sep(char **stringp, const char *delim)
Find first occurrence of any of delim characters in *stringp.
String manipulation functions.
static bool mutt_str_is_email_wsp(char c)
Is this a whitespace character (for an email header)
Lookup table of error messages.
const char * err_str
Human-readable string for error.
int err_num
Error number, see errno(3)