NeoMutt  2020-04-24
Teaching an old dog new tricks
DOXYGEN
string.c File Reference

String manipulation functions. More...

#include "config.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "exit.h"
#include "logging.h"
#include "memory.h"
#include "message.h"
#include "string2.h"
+ Include dependency graph for string.c:

Go to the source code of this file.

Data Structures

struct  SysExits
 Lookup table of error messages. More...
 

Typedefs

typedef bool(* char_cmp) (char, char)
 Pointer to a function taking two characters and returning bool. More...
 

Functions

const char * mutt_str_sysexit (int err_num)
 Return a string matching an error code. More...
 
static bool char_cmp_identity (char a, char b)
 Compare two characters. More...
 
static bool char_cmp_lower (char a, char b)
 Compare two characters ignoring case. More...
 
static char_cmp get_char_cmp (enum CaseSensitivity cs)
 Retrieve the correct function to compare characters according to a case sensitivity setting. More...
 
size_t mutt_str_startswith (const char *str, const char *prefix, enum CaseSensitivity cs)
 Check whether a string starts with a prefix. More...
 
int mutt_str_atol (const char *str, long *dst)
 Convert ASCII string to a long. More...
 
int mutt_str_atos (const char *str, short *dst)
 Convert ASCII string to a short. More...
 
int mutt_str_atoi (const char *str, int *dst)
 Convert ASCII string to an integer. More...
 
int mutt_str_atoui (const char *str, unsigned int *dst)
 Convert ASCII string to an unsigned integer. More...
 
int mutt_str_atoul (const char *str, unsigned long *dst)
 Convert ASCII string to an unsigned long. More...
 
int mutt_str_atoull (const char *str, unsigned long long *dst)
 Convert ASCII string to an unsigned long long. More...
 
char * mutt_str_strdup (const char *str)
 Copy a string, safely. More...
 
char * mutt_str_strcat (char *buf, size_t buflen, const char *s)
 Concatenate two strings. More...
 
char * mutt_str_strncat (char *d, size_t l, const char *s, size_t sl)
 Concatenate two strings. More...
 
void mutt_str_replace (char **p, const char *s)
 Replace one string with another. More...
 
void mutt_str_append_item (char **str, const char *item, char sep)
 Add string to another separated by sep. More...
 
void mutt_str_adjust (char **p)
 Shrink-to-fit a string. More...
 
char * mutt_str_strlower (char *s)
 Convert all characters in the string to lowercase. More...
 
char * mutt_str_strnlower (char *str, size_t num)
 Convert some characters in the string to lowercase. More...
 
const char * mutt_str_strchrnul (const char *s, char c)
 Find first occurrence of character in string. More...
 
char * mutt_str_substr_copy (const char *begin, const char *end, char *buf, size_t buflen)
 Copy a sub-string into a buffer. More...
 
char * mutt_str_substr_dup (const char *begin, const char *end)
 Duplicate a sub-string. More...
 
int mutt_str_strcmp (const char *a, const char *b)
 Compare two strings, safely. More...
 
int mutt_str_strcasecmp (const char *a, const char *b)
 Compare two strings ignoring case, safely. More...
 
int mutt_str_strncmp (const char *a, const char *b, size_t l)
 Compare two strings (to a maximum), safely. More...
 
int mutt_str_strncasecmp (const char *a, const char *b, size_t l)
 Compare two strings ignoring case (to a maximum), safely. More...
 
size_t mutt_str_strlen (const char *a)
 Calculate the length of a string, safely. More...
 
int mutt_str_strcoll (const char *a, const char *b)
 Collate two strings (compare using locale), safely. More...
 
const char * mutt_str_stristr (const char *haystack, const char *needle)
 Find first occurrence of string (ignoring case) More...
 
char * mutt_str_skip_whitespace (const char *p)
 Find the first non-whitespace character in a string. More...
 
void mutt_str_remove_trailing_ws (char *s)
 Trim trailing whitespace from a string. More...
 
size_t mutt_str_strfcpy (char *dest, const char *src, size_t dsize)
 Copy a string into a buffer (guaranteeing NUL-termination) More...
 
char * mutt_str_skip_email_wsp (const char *s)
 Skip over whitespace as defined by RFC5322. More...
 
bool mutt_str_is_email_wsp (char c)
 Is this a whitespace character (for an email header) More...
 
size_t mutt_str_strnfcpy (char *dest, const char *src, size_t n, size_t dsize)
 Copy a limited string into a buffer (guaranteeing NUL-termination) More...
 
size_t mutt_str_lws_len (const char *s, size_t n)
 Measure the linear-white-space at the beginning of a string. More...
 
size_t mutt_str_lws_rlen (const char *s, size_t n)
 Measure the linear-white-space at the end of a string. More...
 
void mutt_str_dequote_comment (char *s)
 Un-escape characters in an email address comment. More...
 
const char * mutt_str_next_word (const char *s)
 Find the next word in a string. More...
 
const char * mutt_str_rstrnstr (const char *haystack, size_t haystack_length, const char *needle)
 Find last instance of a substring. More...
 
int mutt_str_word_casecmp (const char *a, const char *b)
 Find word a in word list b. More...
 
bool mutt_str_is_ascii (const char *str, size_t len)
 Is a string ASCII (7-bit)? More...
 
const char * mutt_str_find_word (const char *src)
 Find the end of a word (non-space) More...
 
const char * mutt_str_getenv (const char *name)
 Get an environment variable. More...
 
bool mutt_str_inline_replace (char *buf, size_t buflen, size_t xlen, const char *rstr)
 Replace the beginning of a string. More...
 
int mutt_str_remall_strcasestr (char *str, const char *target)
 Remove all occurrences of substring, ignoring case. More...
 
const char * mutt_str_strcasestr (const char *haystack, const char *needle)
 Find a substring within a string without worrying about case. More...
 
int mutt_str_asprintf (char **strp, const char *fmt,...)
 

Variables

static const struct SysExits sysexits []
 

Detailed Description

String manipulation functions.

Authors
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file string.c.

Typedef Documentation

◆ char_cmp

typedef bool(* char_cmp) (char, char)

Pointer to a function taking two characters and returning bool.

Definition at line 52 of file string.c.

Function Documentation

◆ mutt_str_sysexit()

const char* mutt_str_sysexit ( int  err_num)

Return a string matching an error code.

Parameters
err_numError code, e.g. EX_NOPERM
Return values
ptrstring representing the error code

Definition at line 117 of file string.c.

118 {
119  for (size_t i = 0; i < mutt_array_size(sysexits); i++)
120  {
121  if (err_num == sysexits[i].err_num)
122  return sysexits[i].err_str;
123  }
124 
125  return NULL;
126 }
static const struct SysExits sysexits[]
Definition: string.c:63
#define mutt_array_size(x)
Definition: memory.h:33
const char * err_str
Definition: string.c:60
+ Here is the caller graph for this function:

◆ char_cmp_identity()

static bool char_cmp_identity ( char  a,
char  b 
)
inlinestatic

Compare two characters.

Parameters
aFirst character to compare
bSecond character to compare
Return values
trueIf (a == b)

Definition at line 134 of file string.c.

135 {
136  return a == b;
137 }
+ Here is the caller graph for this function:

◆ char_cmp_lower()

static bool char_cmp_lower ( char  a,
char  b 
)
inlinestatic

Compare two characters ignoring case.

Parameters
aFirst character to compare
bSecond character to compare
Return values
trueIf (a == b), ignoring case

Definition at line 145 of file string.c.

146 {
147  return tolower((unsigned char) a) == tolower((unsigned char) b);
148 }
+ Here is the caller graph for this function:

◆ get_char_cmp()

static char_cmp get_char_cmp ( enum CaseSensitivity  cs)
static

Retrieve the correct function to compare characters according to a case sensitivity setting.

Parameters
csCase sensitivity setting
Return values
ptrchar_cmp function pointer

Definition at line 155 of file string.c.

156 {
157  return (cs == CASE_IGNORE) ? char_cmp_lower : char_cmp_identity;
158 }
static bool char_cmp_lower(char a, char b)
Compare two characters ignoring case.
Definition: string.c:145
Ignore case when comparing strings.
Definition: string2.h:68
static bool char_cmp_identity(char a, char b)
Compare two characters.
Definition: string.c:134
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_startswith()

size_t mutt_str_startswith ( const char *  str,
const char *  prefix,
enum CaseSensitivity  cs 
)

Check whether a string starts with a prefix.

Parameters
strString to check
prefixPrefix to match
csCase sensitivity setting
Return values
numLength of prefix if str starts with prefix
0if str does not start with prefix

Definition at line 168 of file string.c.

169 {
170  if (!str || (str[0] == '\0') || !prefix || (prefix[0] == '\0'))
171  {
172  return 0;
173  }
174 
175  const char *saved_prefix = prefix;
176  for (char_cmp fn = get_char_cmp(cs); *str && *prefix; str++, prefix++)
177  {
178  if (!fn(*str, *prefix))
179  {
180  return 0;
181  }
182  }
183 
184  return (!*prefix) ? prefix - saved_prefix : 0;
185 }
bool(* char_cmp)(char, char)
Pointer to a function taking two characters and returning bool.
Definition: string.c:52
static char_cmp get_char_cmp(enum CaseSensitivity cs)
Retrieve the correct function to compare characters according to a case sensitivity setting...
Definition: string.c:155
+ Here is the call graph for this function:

◆ mutt_str_atol()

int mutt_str_atol ( const char *  str,
long *  dst 
)

Convert ASCII string to a long.

Parameters
[in]strString to read
[out]dstStore the result
Return values
0Success
-1Error
-2Overflow

This is a strtol() wrapper with range checking. errno may be set on error, e.g. ERANGE

Definition at line 198 of file string.c.

199 {
200  if (dst)
201  *dst = 0;
202 
203  if (!str || !*str) /* no input: 0 */
204  return 0;
205 
206  char *e = NULL;
207  errno = 0;
208 
209  long res = strtol(str, &e, 10);
210  if (dst)
211  *dst = res;
212  if (((res == LONG_MIN) || (res == LONG_MAX)) && (errno == ERANGE))
213  return -2;
214  if (e && (*e != '\0'))
215  return -1;
216  return 0;
217 }
+ Here is the caller graph for this function:

◆ mutt_str_atos()

int mutt_str_atos ( const char *  str,
short *  dst 
)

Convert ASCII string to a short.

Parameters
[in]strString to read
[out]dstStore the result
Return values
0Success
-1Error
-2Error, overflow

This is a strtol() wrapper with range checking. If dst is NULL, the string will be tested only (without conversion).

errno may be set on error, e.g. ERANGE

Definition at line 232 of file string.c.

233 {
234  if (dst)
235  *dst = 0;
236 
237  long res = 0;
238  int rc = mutt_str_atol(str, &res);
239  if (rc < 0)
240  return rc;
241  if ((res < SHRT_MIN) || (res > SHRT_MAX))
242  return -2;
243 
244  if (dst)
245  *dst = (short) res;
246 
247  return 0;
248 }
int mutt_str_atol(const char *str, long *dst)
Convert ASCII string to a long.
Definition: string.c:198
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_atoi()

int mutt_str_atoi ( const char *  str,
int *  dst 
)

Convert ASCII string to an integer.

Parameters
[in]strString to read
[out]dstStore the result
Return values
0Success
-1Error
-2Error, overflow

This is a strtol() wrapper with range checking. If dst is NULL, the string will be tested only (without conversion). errno may be set on error, e.g. ERANGE

Definition at line 262 of file string.c.

263 {
264  if (dst)
265  *dst = 0;
266 
267  long res = 0;
268  int rc = mutt_str_atol(str, &res);
269  if (rc < 0)
270  return rc;
271  if ((res < INT_MIN) || (res > INT_MAX))
272  return -2;
273 
274  if (dst)
275  *dst = (int) res;
276 
277  return 0;
278 }
int mutt_str_atol(const char *str, long *dst)
Convert ASCII string to a long.
Definition: string.c:198
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_atoui()

int mutt_str_atoui ( const char *  str,
unsigned int *  dst 
)

Convert ASCII string to an unsigned integer.

Parameters
[in]strString to read
[out]dstStore the result
Return values
1Successful conversion, with trailing characters
0Successful conversion
-1Invalid input
-2Input out of range
Note
This function's return value differs from the other functions. They return -1 if there is input beyond the number.

Definition at line 292 of file string.c.

293 {
294  if (dst)
295  *dst = 0;
296 
297  unsigned long res = 0;
298  int rc = mutt_str_atoul(str, &res);
299  if (rc < 0)
300  return rc;
301  if (res > UINT_MAX)
302  return -2;
303 
304  if (dst)
305  *dst = (unsigned int) res;
306 
307  return rc;
308 }
int mutt_str_atoul(const char *str, unsigned long *dst)
Convert ASCII string to an unsigned long.
Definition: string.c:321
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_atoul()

int mutt_str_atoul ( const char *  str,
unsigned long *  dst 
)

Convert ASCII string to an unsigned long.

Parameters
[in]strString to read
[out]dstStore the result
Return values
1Successful conversion, with trailing characters
0Successful conversion
-1Invalid input
Note
This function's return value differs from the other functions. They return -1 if there is input beyond the number.

Definition at line 321 of file string.c.

322 {
323  if (dst)
324  *dst = 0;
325 
326  if (!str || !*str) /* no input: 0 */
327  return 0;
328 
329  char *e = NULL;
330  errno = 0;
331 
332  unsigned long res = strtoul(str, &e, 10);
333  if (dst)
334  *dst = res;
335  if ((res == ULONG_MAX) && (errno == ERANGE))
336  return -1;
337  if (e && (*e != '\0'))
338  return 1;
339  return 0;
340 }
+ Here is the caller graph for this function:

◆ mutt_str_atoull()

int mutt_str_atoull ( const char *  str,
unsigned long long *  dst 
)

Convert ASCII string to an unsigned long long.

Parameters
[in]strString to read
[out]dstStore the result
Return values
1Successful conversion, with trailing characters
0Successful conversion
-1Invalid input
Note
This function's return value differs from the other functions. They return -1 if there is input beyond the number.

Definition at line 353 of file string.c.

354 {
355  if (dst)
356  *dst = 0;
357 
358  if (!str || !*str) /* no input: 0 */
359  return 0;
360 
361  char *e = NULL;
362  errno = 0;
363 
364  unsigned long long res = strtoull(str, &e, 10);
365  if (dst)
366  *dst = res;
367  if ((res == ULLONG_MAX) && (errno == ERANGE))
368  return -1;
369  if (e && (*e != '\0'))
370  return 1;
371  return 0;
372 }
+ Here is the caller graph for this function:

◆ mutt_str_strdup()

char* mutt_str_strdup ( const char *  str)

Copy a string, safely.

Parameters
strString to copy
Return values
ptrCopy of the string
NULLif str was NULL or empty

Definition at line 380 of file string.c.

381 {
382  if (!str || !*str)
383  return NULL;
384 
385  return strdup(str);
386 }

◆ mutt_str_strcat()

char* mutt_str_strcat ( char *  buf,
size_t  buflen,
const char *  s 
)

Concatenate two strings.

Parameters
bufBuffer containing source string
buflenLength of buffer
sString to add
Return values
ptrStart of the buffer

Definition at line 395 of file string.c.

396 {
397  if (!buf || (buflen == 0) || !s)
398  return buf;
399 
400  char *p = buf;
401 
402  buflen--; /* Space for the trailing '\0'. */
403 
404  for (; (*buf != '\0') && buflen; buflen--)
405  buf++;
406  for (; *s && buflen; buflen--)
407  *buf++ = *s++;
408 
409  *buf = '\0';
410 
411  return p;
412 }
+ Here is the caller graph for this function:

◆ mutt_str_strncat()

char* mutt_str_strncat ( char *  d,
size_t  l,
const char *  s,
size_t  sl 
)

Concatenate two strings.

Parameters
dBuffer containing source string
lLength of buffer
sString to add
slMaximum amount of string to add
Return values
ptrStart of joined string

Add a string to a maximum of sl bytes.

Definition at line 424 of file string.c.

425 {
426  if (!d || (l == 0) || !s)
427  return d;
428 
429  char *p = d;
430 
431  l--; /* Space for the trailing '\0'. */
432 
433  for (; *d && l; l--)
434  d++;
435  for (; *s && l && sl; l--, sl--)
436  *d++ = *s++;
437 
438  *d = '\0';
439 
440  return p;
441 }
+ Here is the caller graph for this function:

◆ mutt_str_replace()

void mutt_str_replace ( char **  p,
const char *  s 
)

Replace one string with another.

Parameters
[out]pString to replace
[in]sNew string

This function free()s the original string, strdup()s the new string and overwrites the pointer to the first string.

This function alters the pointer of the caller.

Note
Free *p afterwards to handle the case that *p and s reference the same memory

Definition at line 455 of file string.c.

456 {
457  if (!p)
458  return;
459  const char *tmp = *p;
460  *p = mutt_str_strdup(s);
461  FREE(&tmp);
462 }
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:

◆ mutt_str_append_item()

void mutt_str_append_item ( char **  str,
const char *  item,
char  sep 
)

Add string to another separated by sep.

Parameters
[out]strString appended
[in]itemString to append
[in]sepseparator between string item

Append a string to another, separating them by sep if needed.

This function alters the pointer of the caller.

Definition at line 474 of file string.c.

475 {
476  if (!str || !item)
477  return;
478 
479  size_t sz = mutt_str_strlen(item);
480  size_t ssz = mutt_str_strlen(*str);
481 
482  mutt_mem_realloc(str, ssz + (((ssz > 0) && (sep != '\0')) ? 1 : 0) + sz + 1);
483  char *p = *str + ssz;
484  if ((ssz > 0) && (sep != '\0'))
485  *p++ = sep;
486  memcpy(p, item, sz + 1);
487 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_adjust()

void mutt_str_adjust ( char **  p)

Shrink-to-fit a string.

Parameters
[out]pString to alter

Take a string which is allocated on the heap, find its length and reallocate the memory to be exactly the right size.

This function alters the pointer of the caller.

Definition at line 498 of file string.c.

499 {
500  if (!p || !*p)
501  return;
502  mutt_mem_realloc(p, strlen(*p) + 1);
503 }
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_strlower()

char* mutt_str_strlower ( char *  s)

Convert all characters in the string to lowercase.

Parameters
sString to lowercase
Return values
ptrLowercase string

The string is transformed in place.

Definition at line 512 of file string.c.

513 {
514  if (!s)
515  return NULL;
516 
517  char *p = s;
518 
519  while (*p)
520  {
521  *p = tolower((unsigned char) *p);
522  p++;
523  }
524 
525  return s;
526 }
+ Here is the caller graph for this function:

◆ mutt_str_strnlower()

char* mutt_str_strnlower ( char *  str,
size_t  num 
)

Convert some characters in the string to lowercase.

Parameters
strString to lowercase
numMaximum number of characters to lowercase
Return values
ptrLowercase string

The string is transformed in place.

Definition at line 536 of file string.c.

537 {
538  if (!str)
539  return NULL;
540 
541  for (size_t i = 0; i < num; i++)
542  {
543  if (str[i] == '\0')
544  break;
545  str[i] = tolower((unsigned char) str[i]);
546  }
547 
548  return str;
549 }
+ Here is the caller graph for this function:

◆ mutt_str_strchrnul()

const char* mutt_str_strchrnul ( const char *  s,
char  c 
)

Find first occurrence of character in string.

Parameters
sHaystack
cNeedle
Return values
ptrSuccess, first occurrence of the character
ptrFailure, pointer to the terminating NUL character

This function is like GNU's strchrnul, which is similar to the standard strchr function: it looks for the c character in the NULL-terminated string s and returns a pointer to its location. If c is not in s, instead of returning NULL like its standard counterpart, this function returns a pointer to the terminating NUL character.

Definition at line 564 of file string.c.

565 {
566  if (!s)
567  return NULL;
568 
569  for (; *s && (*s != c); s++)
570  ;
571  return s;
572 }
+ Here is the caller graph for this function:

◆ mutt_str_substr_copy()

char* mutt_str_substr_copy ( const char *  begin,
const char *  end,
char *  buf,
size_t  buflen 
)

Copy a sub-string into a buffer.

Parameters
beginStart of the string to copy
endEnd of the string to copy
bufBuffer for the result
buflenLength of buffer
Return values
ptrDestination buffer

Definition at line 582 of file string.c.

583 {
584  if (!begin || !end || !buf || (buflen == 0))
585  return buf;
586 
587  size_t len = end - begin;
588  if (len > (buflen - 1))
589  len = buflen - 1;
590  memcpy(buf, begin, len);
591  buf[len] = '\0';
592  return buf;
593 }
+ Here is the caller graph for this function:

◆ mutt_str_substr_dup()

char* mutt_str_substr_dup ( const char *  begin,
const char *  end 
)

Duplicate a sub-string.

Parameters
beginStart of the string to copy
endEnd of the string to copy
Return values
ptrNew string

If end is NULL, then the rest of the string from begin will be copied.

The caller must free the returned string.

Definition at line 605 of file string.c.

606 {
607  size_t len;
608  char *p = NULL;
609 
610  if (!begin)
611  {
612  mutt_debug(LL_DEBUG1, "%s: ERROR: 'begin' is NULL\n", __func__);
613  return NULL;
614  }
615 
616  if (end)
617  {
618  if (begin > end)
619  return NULL;
620  len = end - begin;
621  }
622  else
623  {
624  len = strlen(begin);
625  }
626 
627  p = mutt_mem_malloc(len + 1);
628  memcpy(p, begin, len);
629  p[len] = '\0';
630  return p;
631 }
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
Log at debug level 1.
Definition: logging.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_strcmp()

int mutt_str_strcmp ( const char *  a,
const char *  b 
)

Compare two strings, safely.

Parameters
aFirst string to compare
bSecond string to compare
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 641 of file string.c.

642 {
643  return strcmp(NONULL(a), NONULL(b));
644 }
#define NONULL(x)
Definition: string2.h:37

◆ mutt_str_strcasecmp()

int mutt_str_strcasecmp ( const char *  a,
const char *  b 
)

Compare two strings ignoring case, safely.

Parameters
aFirst string to compare
bSecond string to compare
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 654 of file string.c.

655 {
656  return strcasecmp(NONULL(a), NONULL(b));
657 }
#define NONULL(x)
Definition: string2.h:37

◆ mutt_str_strncmp()

int mutt_str_strncmp ( const char *  a,
const char *  b,
size_t  l 
)

Compare two strings (to a maximum), safely.

Parameters
aFirst string to compare
bSecond string to compare
lMaximum number of bytes to compare
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 668 of file string.c.

669 {
670  return strncmp(NONULL(a), NONULL(b), l);
671 }
#define NONULL(x)
Definition: string2.h:37
+ Here is the caller graph for this function:

◆ mutt_str_strncasecmp()

int mutt_str_strncasecmp ( const char *  a,
const char *  b,
size_t  l 
)

Compare two strings ignoring case (to a maximum), safely.

Parameters
aFirst string to compare
bSecond string to compare
lMaximum number of bytes to compare
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 682 of file string.c.

683 {
684  return strncasecmp(NONULL(a), NONULL(b), l);
685 }
#define NONULL(x)
Definition: string2.h:37
+ Here is the caller graph for this function:

◆ mutt_str_strlen()

size_t mutt_str_strlen ( const char *  a)

Calculate the length of a string, safely.

Parameters
aString to measure
Return values
numLength in bytes

Definition at line 692 of file string.c.

693 {
694  return a ? strlen(a) : 0;
695 }

◆ mutt_str_strcoll()

int mutt_str_strcoll ( const char *  a,
const char *  b 
)

Collate two strings (compare using locale), safely.

Parameters
aFirst string to compare
bSecond string to compare
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 705 of file string.c.

706 {
707  return strcoll(NONULL(a), NONULL(b));
708 }
#define NONULL(x)
Definition: string2.h:37
+ Here is the caller graph for this function:

◆ mutt_str_stristr()

const char* mutt_str_stristr ( const char *  haystack,
const char *  needle 
)

Find first occurrence of string (ignoring case)

Parameters
haystackString to search through
needleString to find
Return values
ptrFirst match of the search string
NULLNo match, or an error

Definition at line 717 of file string.c.

718 {
719  if (!haystack)
720  return NULL;
721  if (!needle)
722  return haystack;
723 
724  const char *p = NULL, *q = NULL;
725 
726  while (*(p = haystack))
727  {
728  for (q = needle;
729  *p && *q && (tolower((unsigned char) *p) == tolower((unsigned char) *q));
730  p++, q++)
731  {
732  }
733  if (!*q)
734  return haystack;
735  haystack++;
736  }
737  return NULL;
738 }
+ Here is the caller graph for this function:

◆ mutt_str_skip_whitespace()

char* mutt_str_skip_whitespace ( const char *  p)

Find the first non-whitespace character in a string.

Parameters
pString to search
Return values
ptrFirst non-whitespace character
ptrTerminating NUL character, if the string was entirely whitespace

Definition at line 746 of file string.c.

747 {
748  if (!p)
749  return NULL;
750  SKIPWS(p);
751  return (char *) p;
752 }
#define SKIPWS(ch)
Definition: string2.h:47
+ Here is the caller graph for this function:

◆ mutt_str_remove_trailing_ws()

void mutt_str_remove_trailing_ws ( char *  s)

Trim trailing whitespace from a string.

Parameters
sString to trim

The string is modified in place.

Definition at line 760 of file string.c.

761 {
762  if (!s)
763  return;
764 
765  for (char *p = s + mutt_str_strlen(s) - 1; (p >= s) && IS_SPACE(*p); p--)
766  *p = '\0';
767 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
#define IS_SPACE(ch)
Definition: string2.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_strfcpy()

size_t mutt_str_strfcpy ( char *  dest,
const char *  src,
size_t  dsize 
)

Copy a string into a buffer (guaranteeing NUL-termination)

Parameters
destBuffer for the result
srcString to copy
dsizeDestination buffer size
Return values
numDestination string length

Definition at line 776 of file string.c.

777 {
778  if (!dest || (dsize == 0))
779  return 0;
780  if (!src)
781  {
782  dest[0] = '\0';
783  return 0;
784  }
785 
786  char *dest0 = dest;
787  while ((--dsize > 0) && (*src != '\0'))
788  *dest++ = *src++;
789 
790  *dest = '\0';
791  return dest - dest0;
792 }

◆ mutt_str_skip_email_wsp()

char* mutt_str_skip_email_wsp ( const char *  s)

Skip over whitespace as defined by RFC5322.

Parameters
sString to search
Return values
ptrFirst non-whitespace character
ptrTerminating NUL character, if the string was entirely whitespace

This is used primarily for parsing header fields.

Definition at line 802 of file string.c.

803 {
804  if (!s)
805  return NULL;
806  return (char *) (s + strspn(s, EMAIL_WSP));
807 }
#define EMAIL_WSP
Definition: string2.h:39
+ Here is the caller graph for this function:

◆ mutt_str_is_email_wsp()

bool mutt_str_is_email_wsp ( char  c)

Is this a whitespace character (for an email header)

Parameters
cCharacter to test
Return values
trueIt is whitespcae

Definition at line 814 of file string.c.

815 {
816  return c && (strchr(EMAIL_WSP, c));
817 }
#define EMAIL_WSP
Definition: string2.h:39
+ Here is the caller graph for this function:

◆ mutt_str_strnfcpy()

size_t mutt_str_strnfcpy ( char *  dest,
const char *  src,
size_t  n,
size_t  dsize 
)

Copy a limited string into a buffer (guaranteeing NUL-termination)

Parameters
destBuffer for the result
srcString to copy
nMaximum number of characters to copy
dsizeDestination buffer size
Return values
numDestination string length

Definition at line 827 of file string.c.

828 {
829  return mutt_str_strfcpy(dest, src, MIN(n + 1, dsize));
830 }
#define MIN(a, b)
Definition: memory.h:31
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
int n
Definition: acutest.h:492
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_lws_len()

size_t mutt_str_lws_len ( const char *  s,
size_t  n 
)

Measure the linear-white-space at the beginning of a string.

Parameters
sString to check
nMaximum number of characters to check
Return values
numCount of whitespace characters

Count the number of whitespace characters at the beginning of a string. They can be <space>, <tab>, <cr> or <lf>.

Definition at line 841 of file string.c.

842 {
843  if (!s)
844  return 0;
845 
846  const char *p = s;
847  size_t len = n;
848 
849  if (n == 0)
850  return 0;
851 
852  for (; p < (s + n); p++)
853  {
854  if (!strchr(" \t\r\n", *p))
855  {
856  len = p - s;
857  break;
858  }
859  }
860 
861  if ((len != 0) && strchr("\r\n", *(p - 1))) /* LWS doesn't end with CRLF */
862  len = 0;
863  return len;
864 }
int n
Definition: acutest.h:492
+ Here is the caller graph for this function:

◆ mutt_str_lws_rlen()

size_t mutt_str_lws_rlen ( const char *  s,
size_t  n 
)

Measure the linear-white-space at the end of a string.

Parameters
sString to check
nMaximum number of characters to check
Return values
numCount of whitespace characters

Count the number of whitespace characters at the end of a string. They can be <space>, <tab>, <cr> or <lf>.

Definition at line 875 of file string.c.

876 {
877  if (!s)
878  return 0;
879 
880  const char *p = s + n - 1;
881  size_t len = n;
882 
883  if (n == 0)
884  return 0;
885 
886  if (strchr("\r\n", *p)) /* LWS doesn't end with CRLF */
887  return 0;
888 
889  for (; p >= s; p--)
890  {
891  if (!strchr(" \t\r\n", *p))
892  {
893  len = s + n - 1 - p;
894  break;
895  }
896  }
897 
898  return len;
899 }
int n
Definition: acutest.h:492
+ Here is the caller graph for this function:

◆ mutt_str_dequote_comment()

void mutt_str_dequote_comment ( char *  s)

Un-escape characters in an email address comment.

Parameters
sString to be un-escaped
Note
The string is changed in-place

Definition at line 907 of file string.c.

908 {
909  if (!s)
910  return;
911 
912  char *w = s;
913 
914  for (; *s; s++)
915  {
916  if (*s == '\\')
917  {
918  if (!*++s)
919  break; /* error? */
920  *w++ = *s;
921  }
922  else if (*s != '\"')
923  {
924  if (w != s)
925  *w = *s;
926  w++;
927  }
928  }
929  *w = '\0';
930 }
+ Here is the caller graph for this function:

◆ mutt_str_next_word()

const char* mutt_str_next_word ( const char *  s)

Find the next word in a string.

Parameters
sString to examine
Return values
ptrNext word

If the s is pointing to a word (non-space) is is skipped over. Then, any whitespace is skipped over.

Note
What is/isn't a word is determined by isspace()

Definition at line 942 of file string.c.

943 {
944  if (!s)
945  return NULL;
946 
947  while (*s && !IS_SPACE(*s))
948  s++;
949  SKIPWS(s);
950  return s;
951 }
#define SKIPWS(ch)
Definition: string2.h:47
#define IS_SPACE(ch)
Definition: string2.h:38
+ Here is the caller graph for this function:

◆ mutt_str_rstrnstr()

const char* mutt_str_rstrnstr ( const char *  haystack,
size_t  haystack_length,
const char *  needle 
)

Find last instance of a substring.

Parameters
haystackString to search through
haystack_lengthLength of the string
needleString to find
Return values
NULLString not found
ptrLocation of string

Return the last instance of needle in the haystack, or NULL. Like strstr(), only backwards, and for a limited haystack length.

Definition at line 964 of file string.c.

965 {
966  if (!haystack || (haystack_length == 0) || !needle)
967  return NULL;
968 
969  int needle_length = strlen(needle);
970  const char *haystack_end = haystack + haystack_length - needle_length;
971 
972  for (const char *p = haystack_end; p >= haystack; --p)
973  {
974  for (size_t i = 0; i < needle_length; i++)
975  {
976  if (p[i] != needle[i])
977  goto next;
978  }
979  return p;
980 
981  next:;
982  }
983  return NULL;
984 }
+ Here is the caller graph for this function:

◆ mutt_str_word_casecmp()

int mutt_str_word_casecmp ( const char *  a,
const char *  b 
)

Find word a in word list b.

Parameters
aWord to find
bString to check
Return values
0Word was found
!=0Word was not found

Given a word "apple", check if it exists at the start of a string of words, e.g. "apple banana". It must be an exact match, so "apple" won't match "apples banana".

The case of the words is ignored.

Definition at line 999 of file string.c.

1000 {
1001  if (!b)
1002  {
1003  if (a)
1004  return 1;
1005  return 0;
1006  }
1007 
1008  char tmp[128] = { 0 };
1009 
1010  int i;
1011  for (i = 0; i < (sizeof(tmp) - 2); i++, b++)
1012  {
1013  if (!*b || IS_SPACE(*b))
1014  {
1015  tmp[i] = '\0';
1016  break;
1017  }
1018  tmp[i] = *b;
1019  }
1020  tmp[i + 1] = '\0';
1021 
1022  return mutt_str_strcasecmp(a, tmp);
1023 }
#define IS_SPACE(ch)
Definition: string2.h:38
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:654
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_is_ascii()

bool mutt_str_is_ascii ( const char *  str,
size_t  len 
)

Is a string ASCII (7-bit)?

Parameters
strString to examine
lenLength of string to examine
Return values
trueThere are no 8-bit chars

Definition at line 1031 of file string.c.

1032 {
1033  if (!str)
1034  return true;
1035 
1036  for (; (*str != '\0') && (len > 0); str++, len--)
1037  if ((*str & 0x80) != 0)
1038  return false;
1039 
1040  return true;
1041 }
+ Here is the caller graph for this function:

◆ mutt_str_find_word()

const char* mutt_str_find_word ( const char *  src)

Find the end of a word (non-space)

Parameters
srcString to search
Return values
ptrEnd of the word

Skip to the end of the current word. Skip past any whitespace characters.

Note
If there aren't any more words, this will return a pointer to the final NUL character.

Definition at line 1054 of file string.c.

1055 {
1056  if (!src)
1057  return NULL;
1058 
1059  while (*src && strchr(" \t\n", *src))
1060  src++;
1061  while (*src && !strchr(" \t\n", *src))
1062  src++;
1063  return src;
1064 }
+ Here is the caller graph for this function:

◆ mutt_str_getenv()

const char* mutt_str_getenv ( const char *  name)

Get an environment variable.

Parameters
nameEnvironment variable to get
Return values
ptrValue of variable
NULLVariable isn't set, or is empty
Warning
The caller must not free the returned pointer.

Definition at line 1074 of file string.c.

1075 {
1076  if (!name)
1077  return NULL;
1078 
1079  const char *val = getenv(name);
1080  if (val && (val[0] != '\0'))
1081  return val;
1082 
1083  return NULL;
1084 }
const char * name
Definition: pgpmicalg.c:46
+ Here is the caller graph for this function:

◆ mutt_str_inline_replace()

bool mutt_str_inline_replace ( char *  buf,
size_t  buflen,
size_t  xlen,
const char *  rstr 
)

Replace the beginning of a string.

Parameters
bufBuffer to modify
buflenLength of buffer
xlenLength of string to overwrite
rstrReplacement string
Return values
trueSuccess

String (XX<OOOOOO>......, 16, 2, RRRR) becomes RRRR<OOOOOO>....

Definition at line 1096 of file string.c.

1097 {
1098  if (!buf || !rstr || (xlen >= buflen))
1099  return false;
1100 
1101  size_t slen = mutt_str_strlen(buf + xlen);
1102  size_t rlen = mutt_str_strlen(rstr);
1103 
1104  if ((slen + rlen) >= buflen)
1105  return false;
1106 
1107  memmove(buf + rlen, buf + xlen, slen + 1);
1108  memmove(buf, rstr, rlen);
1109 
1110  return true;
1111 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_remall_strcasestr()

int mutt_str_remall_strcasestr ( char *  str,
const char *  target 
)

Remove all occurrences of substring, ignoring case.

Parameters
strString containing the substring
targetTarget substring for removal
Return values
0String contained substring and substring was removed successfully
1String did not contain substring

Definition at line 1120 of file string.c.

1121 {
1122  int rc = 1;
1123 
1124  // Look through an ensure all instances of the substring are gone.
1125  while ((str = (char *) mutt_str_strcasestr(str, target)))
1126  {
1127  size_t target_len = mutt_str_strlen(target);
1128  memmove(str, str + target_len, 1 + strlen(str + target_len));
1129  rc = 0; // If we got here, then a substring existed and has been removed.
1130  }
1131 
1132  return rc;
1133 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
const char * mutt_str_strcasestr(const char *haystack, const char *needle)
Find a substring within a string without worrying about case.
Definition: string.c:1145
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_strcasestr()

const char* mutt_str_strcasestr ( const char *  haystack,
const char *  needle 
)

Find a substring within a string without worrying about case.

Parameters
haystackString that may or may not contain the substring
needleSubstring we're looking for
Return values
ptrBeginning of substring
NULLSubstring is not in substring

This performs a byte-to-byte check so it will return unspecified results for multibyte locales.

Definition at line 1145 of file string.c.

1146 {
1147  if (!needle)
1148  return NULL;
1149 
1150  size_t haystack_len = mutt_str_strlen(haystack);
1151  size_t needle_len = mutt_str_strlen(needle);
1152 
1153  // Empty string exists at the front of a string. Check strstr if you don't believe me.
1154  if (needle_len == 0)
1155  return haystack;
1156 
1157  // Check size conditions. No point wasting CPU cycles.
1158  if ((haystack_len == 0) || (haystack_len < needle_len))
1159  return NULL;
1160 
1161  // Only check space that needle could fit in.
1162  // Conditional has + 1 to handle when the haystack and needle are the same length.
1163  for (size_t i = 0; i < (haystack_len - needle_len) + 1; i++)
1164  {
1165  for (size_t j = 0; j < needle_len; j++)
1166  {
1167  if (tolower((unsigned char) haystack[i + j]) != tolower((unsigned char) needle[j]))
1168  break;
1169 
1170  // If this statement is true, the needle has been found.
1171  if (j == (needle_len - 1))
1172  return haystack + i;
1173  }
1174  }
1175 
1176  return NULL;
1177 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_asprintf()

int mutt_str_asprintf ( char **  strp,
const char *  fmt,
  ... 
)

Definition at line 1220 of file string.c.

1221 {
1222  if (!strp || !fmt)
1223  return -1;
1224 
1225  int rlen = 256;
1226 
1227  *strp = mutt_mem_malloc(rlen);
1228  while (true)
1229  {
1230  va_list ap;
1231  va_start(ap, fmt);
1232  const int n = vsnprintf(*strp, rlen, fmt, ap);
1233  va_end(ap);
1234  if (n < 0)
1235  {
1236  FREE(strp);
1237  return n;
1238  }
1239 
1240  if (n < rlen)
1241  {
1242  /* reduce space to just that which was used. note that 'n' does not
1243  * include the terminal nul char. */
1244  if (n == 0) /* convention is to use NULL for zero-length strings. */
1245  FREE(strp);
1246  else if (n != rlen - 1)
1247  mutt_mem_realloc(strp, n + 1);
1248  return n;
1249  }
1250  /* increase size and try again */
1251  rlen = n + 1;
1252  mutt_mem_realloc(strp, rlen);
1253  }
1254  /* not reached */
1255 }
static int const char * fmt
Definition: acutest.h:488
vsnprintf(buffer, sizeof(buffer), fmt, args)
va_start(args, fmt)
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
int n
Definition: acutest.h:492
#define FREE(x)
Definition: memory.h:40
va_end(args)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ sysexits

const struct SysExits sysexits[]
static

Definition at line 63 of file string.c.