1 /**
2  * @file
3  * String manipulation functions
4  *
5  * @authors
6  * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
7  * Copyright (C) 2019 Pietro Cerutti <gahr@gahr.ch>
8  *
9  * @copyright
10  * This program is free software: you can redistribute it and/or modify it under
11  * the terms of the GNU General Public License as published by the Free Software
12  * Foundation, either version 2 of the License, or (at your option) any later
13  * version.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License along with
21  * this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 /* @note This file is called string2.h so that other files can safely
25  * #include <string.h>
26  */
27 
28 #ifndef MUTT_LIB_STRING_H
29 #define MUTT_LIB_STRING_H
30 
31 #include <ctype.h>
32 #include <stdbool.h>
33 #include <stdio.h>
34 
35 #define STR_COMMAND 8192  ///< Enough space for a long command line
36 
37 #define NONULL(x) ((x) ? (x) : "")
38 #define IS_SPACE(ch) isspace((unsigned char) ch)
39 
40 /* Exit values */
41 #define S_ERR 127
42 #define S_BKG 126
43 
44 /* this macro must check for (*ch == 0) since isspace(0) has unreliable behavior
45  * on some systems */
46 #define SKIPWS(ch)                                                             \
47   while (*(ch) && isspace((unsigned char) *(ch)))                              \
48     ch++;
49 
50 #define terminate_string(str, strlen, buflen)                                  \
51   (str)[MIN((strlen), (buflen))] = '\0'
52 
53 #define terminate_buffer(str, strlen)                                          \
54   terminate_string(str, strlen, sizeof(str) - 1)
55 
56 void        mutt_str_adjust(char **ptr);
57 void        mutt_str_append_item(char **str, const char *item, char sep);
58 int         mutt_str_asprintf(char **strp, const char *fmt, ...);
59 int         mutt_str_atoi(const char *str, int *dst);
60 int         mutt_str_atol(const char *str, long *dst);
61 int         mutt_str_atos(const char *str, short *dst);
62 int         mutt_str_atoui(const char *str, unsigned int *dst);
63 int         mutt_str_atoul(const char *str, unsigned long *dst);
64 int         mutt_str_atoull(const char *str, unsigned long long *dst);
65 int         mutt_str_coll(const char *a, const char *b);
66 void        mutt_str_dequote_comment(char *str);
67 const char *mutt_str_find_word(const char *src);
68 const char *mutt_str_getenv(const char *name);
69 bool        mutt_str_inline_replace(char *buf, size_t buflen, size_t xlen, const char *rstr);
70 bool        mutt_str_is_ascii(const char *str, size_t len);
71 bool        mutt_str_is_email_wsp(char c);
72 size_t      mutt_str_len(const char *a);
73 char *      mutt_str_lower(char *str);
74 size_t      mutt_str_lws_len(const char *s, size_t n);
75 size_t      mutt_str_lws_rlen(const char *s, size_t n);
76 const char *mutt_str_next_word(const char *s);
77 void        mutt_str_remove_trailing_ws(char *s);
78 char *      mutt_str_replace(char **p, const char *s);
79 char *      mutt_str_skip_email_wsp(const char *s);
80 char *      mutt_str_skip_whitespace(const char *p);
81 const char *mutt_str_sysexit(int e);
82 
83 /* case-sensitive flavours */
84 char *      mutt_str_cat(char *buf, size_t buflen, const char *s);
85 int         mutt_str_cmp(const char *a, const char *b);
86 size_t      mutt_str_copy(char *dest, const char *src, size_t dsize);
87 char *      mutt_str_dup(const char *str);
88 bool        mutt_str_equal(const char *a, const char *b);
89 size_t      mutt_str_startswith(const char *str, const char *prefix);
90 
91 /* case-sensitive, length-bound flavours */
92 char *      mutt_strn_cat(char *dest, size_t l, const char *s, size_t sl);
93 char *      mutt_strn_copy(char *dest, const char *src, size_t len, size_t dsize);
94 char *      mutt_strn_dup(const char *begin, size_t l);
95 bool        mutt_strn_equal(const char *a, const char *b, size_t num);
96 const char *mutt_strn_rfind(const char *haystack, size_t haystack_length, const char *needle);
97 
98 /* case-insensitive flavours */
99 int         mutt_istr_cmp(const char *a, const char *b);
100 bool        mutt_istr_equal(const char *a, const char *b);
101 const char *mutt_istr_find(const char *haystack, const char *needle);
102 int         mutt_istr_remall(char *str, const char *target);
103 size_t      mutt_istr_startswith(const char *str, const char *prefix);
104 
105 /* case-insensitive, length-bound flavours */
106 int         mutt_istrn_cmp(const char *a, const char *b, size_t num);
107 bool        mutt_istrn_equal(const char *a, const char *b, size_t num);
108 const char *mutt_istrn_rfind(const char *haystack, size_t haystack_length, const char *needle);
109 
110 #endif /* MUTT_LIB_STRING_H */
111