NeoMutt  2019-12-07
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...
 
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.

Definition at line 453 of file string.c.

454 {
455  if (!p)
456  return;
457  FREE(p);
458  *p = mutt_str_strdup(s);
459 }
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 471 of file string.c.

472 {
473  if (!str || !item)
474  return;
475 
476  size_t sz = mutt_str_strlen(item);
477  size_t ssz = mutt_str_strlen(*str);
478 
479  mutt_mem_realloc(str, ssz + (((ssz > 0) && (sep != '\0')) ? 1 : 0) + sz + 1);
480  char *p = *str + ssz;
481  if ((ssz > 0) && (sep != '\0'))
482  *p++ = sep;
483  memcpy(p, item, sz + 1);
484 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
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 495 of file string.c.

496 {
497  if (!p || !*p)
498  return;
499  mutt_mem_realloc(p, strlen(*p) + 1);
500 }
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 509 of file string.c.

510 {
511  if (!s)
512  return NULL;
513 
514  char *p = s;
515 
516  while (*p)
517  {
518  *p = tolower((unsigned char) *p);
519  p++;
520  }
521 
522  return s;
523 }
+ 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 538 of file string.c.

539 {
540  if (!s)
541  return NULL;
542 
543  for (; *s && (*s != c); s++)
544  ;
545  return s;
546 }
+ 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 556 of file string.c.

557 {
558  if (!begin || !end || !buf || (buflen == 0))
559  return buf;
560 
561  size_t len = end - begin;
562  if (len > (buflen - 1))
563  len = buflen - 1;
564  memcpy(buf, begin, len);
565  buf[len] = '\0';
566  return buf;
567 }
+ 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 579 of file string.c.

580 {
581  size_t len;
582  char *p = NULL;
583 
584  if (!begin)
585  {
586  mutt_debug(LL_DEBUG1, "%s: ERROR: 'begin' is NULL\n", __func__);
587  return NULL;
588  }
589 
590  if (end)
591  {
592  if (begin > end)
593  return NULL;
594  len = end - begin;
595  }
596  else
597  {
598  len = strlen(begin);
599  }
600 
601  p = mutt_mem_malloc(len + 1);
602  memcpy(p, begin, len);
603  p[len] = '\0';
604  return p;
605 }
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 615 of file string.c.

616 {
617  return strcmp(NONULL(a), NONULL(b));
618 }
#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 628 of file string.c.

629 {
630  return strcasecmp(NONULL(a), NONULL(b));
631 }
#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 642 of file string.c.

643 {
644  return strncmp(NONULL(a), NONULL(b), l);
645 }
#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 656 of file string.c.

657 {
658  return strncasecmp(NONULL(a), NONULL(b), l);
659 }
#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 666 of file string.c.

667 {
668  return a ? strlen(a) : 0;
669 }

◆ 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 679 of file string.c.

680 {
681  return strcoll(NONULL(a), NONULL(b));
682 }
#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 691 of file string.c.

692 {
693  if (!haystack)
694  return NULL;
695  if (!needle)
696  return haystack;
697 
698  const char *p = NULL, *q = NULL;
699 
700  while (*(p = haystack))
701  {
702  for (q = needle;
703  *p && *q && (tolower((unsigned char) *p) == tolower((unsigned char) *q));
704  p++, q++)
705  {
706  }
707  if (!*q)
708  return haystack;
709  haystack++;
710  }
711  return NULL;
712 }
+ 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 720 of file string.c.

721 {
722  if (!p)
723  return NULL;
724  SKIPWS(p);
725  return (char *) p;
726 }
#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 734 of file string.c.

735 {
736  if (!s)
737  return;
738 
739  for (char *p = s + mutt_str_strlen(s) - 1; (p >= s) && IS_SPACE(*p); p--)
740  *p = '\0';
741 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
#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 750 of file string.c.

751 {
752  if (!dest || (dsize == 0))
753  return 0;
754  if (!src)
755  {
756  dest[0] = '\0';
757  return 0;
758  }
759 
760  char *dest0 = dest;
761  while ((--dsize > 0) && (*src != '\0'))
762  *dest++ = *src++;
763 
764  *dest = '\0';
765  return dest - dest0;
766 }

◆ 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 776 of file string.c.

777 {
778  if (!s)
779  return NULL;
780  return (char *) (s + strspn(s, EMAIL_WSP));
781 }
#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 788 of file string.c.

789 {
790  return c && (strchr(EMAIL_WSP, c));
791 }
#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 801 of file string.c.

802 {
803  return mutt_str_strfcpy(dest, src, MIN(n + 1, dsize));
804 }
#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:750
+ 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 815 of file string.c.

816 {
817  if (!s)
818  return 0;
819 
820  const char *p = s;
821  size_t len = n;
822 
823  if (n == 0)
824  return 0;
825 
826  for (; p < (s + n); p++)
827  {
828  if (!strchr(" \t\r\n", *p))
829  {
830  len = p - s;
831  break;
832  }
833  }
834 
835  if ((len != 0) && strchr("\r\n", *(p - 1))) /* LWS doesn't end with CRLF */
836  len = 0;
837  return len;
838 }
+ 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 849 of file string.c.

850 {
851  if (!s)
852  return 0;
853 
854  const char *p = s + n - 1;
855  size_t len = n;
856 
857  if (n == 0)
858  return 0;
859 
860  if (strchr("\r\n", *p)) /* LWS doesn't end with CRLF */
861  return 0;
862 
863  for (; p >= s; p--)
864  {
865  if (!strchr(" \t\r\n", *p))
866  {
867  len = s + n - 1 - p;
868  break;
869  }
870  }
871 
872  return len;
873 }
+ 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 881 of file string.c.

882 {
883  if (!s)
884  return;
885 
886  char *w = s;
887 
888  for (; *s; s++)
889  {
890  if (*s == '\\')
891  {
892  if (!*++s)
893  break; /* error? */
894  *w++ = *s;
895  }
896  else if (*s != '\"')
897  {
898  if (w != s)
899  *w = *s;
900  w++;
901  }
902  }
903  *w = '\0';
904 }
+ 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 916 of file string.c.

917 {
918  if (!s)
919  return NULL;
920 
921  while (*s && !IS_SPACE(*s))
922  s++;
923  SKIPWS(s);
924  return s;
925 }
#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 938 of file string.c.

939 {
940  if (!haystack || (haystack_length == 0) || !needle)
941  return NULL;
942 
943  int needle_length = strlen(needle);
944  const char *haystack_end = haystack + haystack_length - needle_length;
945 
946  for (const char *p = haystack_end; p >= haystack; --p)
947  {
948  for (size_t i = 0; i < needle_length; i++)
949  {
950  if (p[i] != needle[i])
951  goto next;
952  }
953  return p;
954 
955  next:;
956  }
957  return NULL;
958 }
+ 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 973 of file string.c.

974 {
975  if (!b)
976  {
977  if (a)
978  return 1;
979  return 0;
980  }
981 
982  char tmp[128] = { 0 };
983 
984  int i;
985  for (i = 0; i < (sizeof(tmp) - 2); i++, b++)
986  {
987  if (!*b || IS_SPACE(*b))
988  {
989  tmp[i] = '\0';
990  break;
991  }
992  tmp[i] = *b;
993  }
994  tmp[i + 1] = '\0';
995 
996  return mutt_str_strcasecmp(a, tmp);
997 }
#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:628
+ 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 1005 of file string.c.

1006 {
1007  if (!str)
1008  return true;
1009 
1010  for (; (*str != '\0') && (len > 0); str++, len--)
1011  if ((*str & 0x80) != 0)
1012  return false;
1013 
1014  return true;
1015 }
+ 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 1028 of file string.c.

1029 {
1030  if (!src)
1031  return NULL;
1032 
1033  while (*src && strchr(" \t\n", *src))
1034  src++;
1035  while (*src && !strchr(" \t\n", *src))
1036  src++;
1037  return src;
1038 }
+ 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 1048 of file string.c.

1049 {
1050  if (!name)
1051  return NULL;
1052 
1053  const char *val = getenv(name);
1054  if (val && (val[0] != '\0'))
1055  return val;
1056 
1057  return NULL;
1058 }
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 1070 of file string.c.

1071 {
1072  if (!buf || !rstr || (xlen >= buflen))
1073  return false;
1074 
1075  size_t slen = mutt_str_strlen(buf + xlen);
1076  size_t rlen = mutt_str_strlen(rstr);
1077 
1078  if ((slen + rlen) >= buflen)
1079  return false;
1080 
1081  memmove(buf + rlen, buf + xlen, slen + 1);
1082  memmove(buf, rstr, rlen);
1083 
1084  return true;
1085 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
+ 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 1094 of file string.c.

1095 {
1096  int rc = 1;
1097 
1098  // Look through an ensure all instances of the substring are gone.
1099  while ((str = (char *) mutt_str_strcasestr(str, target)))
1100  {
1101  size_t target_len = mutt_str_strlen(target);
1102  memmove(str, str + target_len, 1 + strlen(str + target_len));
1103  rc = 0; // If we got here, then a substring existed and has been removed.
1104  }
1105 
1106  return rc;
1107 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
const char * mutt_str_strcasestr(const char *haystack, const char *needle)
Find a substring within a string without worrying about case.
Definition: string.c:1119
+ 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 1119 of file string.c.

1120 {
1121  if (!needle)
1122  return NULL;
1123 
1124  size_t haystack_len = mutt_str_strlen(haystack);
1125  size_t needle_len = mutt_str_strlen(needle);
1126 
1127  // Empty string exists at the front of a string. Check strstr if you don't believe me.
1128  if (needle_len == 0)
1129  return haystack;
1130 
1131  // Check size conditions. No point wasting CPU cycles.
1132  if ((haystack_len == 0) || (haystack_len < needle_len))
1133  return NULL;
1134 
1135  // Only check space that needle could fit in.
1136  // Conditional has + 1 to handle when the haystack and needle are the same length.
1137  for (size_t i = 0; i < (haystack_len - needle_len) + 1; i++)
1138  {
1139  for (size_t j = 0; j < needle_len; j++)
1140  {
1141  if (tolower((unsigned char) haystack[i + j]) != tolower((unsigned char) needle[j]))
1142  break;
1143 
1144  // If this statement is true, the needle has been found.
1145  if (j == (needle_len - 1))
1146  return haystack + i;
1147  }
1148  }
1149 
1150  return NULL;
1151 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
+ 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 1194 of file string.c.

1195 {
1196  if (!strp || !fmt)
1197  return -1;
1198 
1199  int rlen = 256;
1200 
1201  *strp = mutt_mem_malloc(rlen);
1202  while (true)
1203  {
1204  va_list ap;
1205  va_start(ap, fmt);
1206  const int n = vsnprintf(*strp, rlen, fmt, ap);
1207  va_end(ap);
1208  if (n < 0)
1209  {
1210  FREE(strp);
1211  return n;
1212  }
1213 
1214  if (n < rlen)
1215  {
1216  /* reduce space to just that which was used. note that 'n' does not
1217  * include the terminal nul char. */
1218  if (n == 0) /* convention is to use NULL for zero-length strings. */
1219  FREE(strp);
1220  else if (n != rlen - 1)
1221  mutt_mem_realloc(strp, n + 1);
1222  return n;
1223  }
1224  /* increase size and try again */
1225  rlen = n + 1;
1226  mutt_mem_realloc(strp, rlen);
1227  }
1228  /* not reached */
1229 }
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
#define FREE(x)
Definition: memory.h:40
+ 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.