summaryrefslogtreecommitdiffstats
path: root/lib.h
blob: 61aa51a21a07100fe348298c3ab599227d8d6bf0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
 * Copyright (C) 1996-2000,2007,2010,2012 Michael R. Elkins <me@mutt.org>
 * Copyright (C) 1999-2005,2007 Thomas Roessler <roessler@does-not-exist.org>
 *
 *     This program is free software; you can redistribute it
 *     and/or modify it under the terms of the GNU General Public
 *     License as published by the Free Software Foundation; either
 *     version 2 of the License, or (at your option) any later
 *     version.
 *
 *     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, write to the Free
 *     Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *     Boston, MA  02110-1301, USA.
 */

/* mutt functions which are generally useful. */

#ifndef _LIB_H
# define _LIB_H

# include <stdio.h>
# include <string.h>
# include <unistd.h> /* needed for SEEK_SET */
# include <sys/types.h>
# include <sys/stat.h>
# include <time.h>
# include <limits.h>
# include <stdarg.h>
# include <signal.h>

# ifndef _POSIX_PATH_MAX
#  include <limits.h>
# endif

# ifdef ENABLE_NLS
#  include "gettext.h"
# define _(a) (gettext (a))
#  ifdef gettext_noop
#   define N_(a) gettext_noop (a)
#  else
#   define N_(a) (a)
#  endif
# else
#  define _(a) (a)
#  define N_(a) a
# endif

# define TRUE 1
# define FALSE 0

# define HUGE_STRING        8192
# define LONG_STRING        1024
# define STRING             256
# define SHORT_STRING       128

/*
 * Create a format string to be used with scanf.
 * To use it, write, for instance, MUTT_FORMAT(HUGE_STRING).
 *
 * See K&R 2nd ed, p. 231 for an explanation.
 */
# define _MUTT_FORMAT_2(a,b)	"%" a  b
# define _MUTT_FORMAT_1(a, b)	_MUTT_FORMAT_2(#a, b)
# define MUTT_FORMAT(a)		_MUTT_FORMAT_1(a, "s")
# define MUTT_FORMAT2(a,b)	_MUTT_FORMAT_1(a, b)


# define FREE(x) safe_free(x)
# define NONULL(x) x?x:""

#ifdef HAVE_MEMCCPY
# define strfcpy(A,B,C) memccpy(A,B,0,(C)-1), *((A)+(C)-1)=0
#else
/* Note it would be technically more correct to strncpy with length
 * (C)-1, as above.  But this tickles more compiler warnings.
 */
# define strfcpy(A,B,C) strncpy(A,B,C), *((A)+(C)-1)=0
#endif

# undef MAX
# undef MIN
# define MAX(a,b) ((a) < (b) ? (b) : (a))
# define MIN(a,b) ((a) < (b) ? (a) : (b))

#define mutt_numeric_cmp(a,b) ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0))

/* Use this with care.  If the compiler can't see the array
 * definition, it obviously won't produce a correct result. */
#define mutt_array_size(x)  (sizeof (x) / sizeof ((x)[0]))

/* For mutt_format_string() justifications */
/* Making left 0 and center -1 is of course completely nonsensical, but
 * it retains compatibility for any patches that call mutt_format_string.
 * Once patches are updated to use FMT_*, these can be made sane. */
#define FMT_LEFT	0
#define FMT_RIGHT	1
#define FMT_CENTER	-1

#define FOREVER while (1)

/*
 * ASCII Whitespace
 * 0x09-0x0d (\t \n \v \f \r)
 * 0x20      (space)
 */
#define IS_ASCII_WS(c) ((9 <= (c) && (c) <= 13) || (c) == 32)

#define SKIP_ASCII_WS(c) while (IS_ASCII_WS (*(c))) c++;

/*
 * WSP as defined by RFC5322.
 * This is used primarily for parsing header fields.
 */
#define EMAIL_WSP " \t\r\n"

static inline int is_email_wsp (char c)
{
  return c && (strchr(EMAIL_WSP, c) != NULL);
}

static inline char *skip_email_wsp (const char *s)
{
  if (s)
    return (char *)(s + strspn(s, EMAIL_WSP));
  return (char *)s;
}

/*
 * Locale-defined whitespace.
 * This should only be used when dealing with user input, because
 * some platforms return unexpected results with 8-bit values.
 */
#define IS_LOCALE_WS(c) isspace((unsigned char)c)

/* this macro must check for *c == 0 since isspace(0) has unreliable behavior
   on some systems */
#define SKIP_LOCALE_WS(c) while (*(c) && IS_LOCALE_WS (*(c))) c++;

/*
 * These functions aren't defined in lib.c, but
 * they are used there.
 *
 * A non-mutt "implementation" (ahem) can be found in extlib.c.
 */


# ifndef _EXTLIB_C
extern void (*mutt_error) (const char *, ...);
# endif

# ifdef _LIB_C
#  define MUTT_LIB_WHERE
#  define MUTT_LIB_INITVAL(x) = x
# else
#  define MUTT_LIB_WHERE extern
#  define MUTT_LIB_INITVAL(x)
# endif

void mutt_exit (int);


# ifdef DEBUG

MUTT_LIB_WHERE FILE *debugfile;
MUTT_LIB_WHERE int debuglevel;

void mutt_debug (FILE *, const char *, ...);
void mutt_debug_f (const char *, const int, const char *, const char *, ...);

#  define dprint(N,X) do { if (debuglevel>=N && debugfile) mutt_debug X; } while (0)

/* __func__ is a C99 provision, but we now require C99 so it's safe */
#  define dprintf(N, ...) do { if (debuglevel >= (N)) mutt_debug_f (__FILE__, __LINE__, __func__, __VA_ARGS__); } while (0)

# else

#  define dprint(N,X) do { } while (0)
#  define dprintf(N, ...) do { } while (0)

# endif


/* Exit values used in send_msg() */
#define S_ERR 127
#define S_BKG 126

/* Flags for mutt_read_line() */
#define MUTT_CONT		(1<<0)		/* \-continuation */
#define MUTT_EOL		(1<<1)		/* don't strip \n/\r\n */

/* Flags for mutt_sanitize_filename() and mutt_buffer_sanitize_filename() */
#define MUTT_SANITIZE_ALLOW_SLASH   (1<<0)
#define MUTT_SANITIZE_ALLOW_8BIT    (1<<1)

/* The actual library functions. */

char *mutt_concat_path (char *, const char *, const char *, size_t);
char *mutt_read_line (char *, size_t *, FILE *, int *, int);
char *mutt_skip_ascii_ws (char *);
char *mutt_strlower (char *);
char *mutt_substrcpy (char *, const char *, const char *, size_t);
char *mutt_substrdup (const char *, const char *);
char *safe_strcat (char *, size_t, const char *);
char *safe_strncat (char *, size_t, const char *, size_t);
char *safe_strdup (const char *);

/* mutt_atoX() flags:
 *
 * Without the flag, the function will return -1, but the dst parameter
 * will still be set to 0. */
#define MUTT_ATOI_ALLOW_EMPTY     (1<<0)  /* allow NULL or "" */
#define MUTT_ATOI_ALLOW_TRAILING  (1<<1)  /* allow values after the number */

/* strtol() wrappers with range checking; they return
 * 	 0 success
 * 	-1 format error
 * 	-2 out of range
 * the dst pointer may be NULL to test only without conversion
 */
int mutt_atos (const char *, short *, int);
int mutt_atoi (const char *, int *, int);
int mutt_atol (const char *, long *, int);
int mutt_atoll (const char *, long long *, int);
int mutt_atoui (const char *, unsigned int *, int);
int mutt_atoul (const char *, unsigned long *, int);
int mutt_atoull (const char *, unsigned long long *, int);

const char *mutt_stristr (const char *, const char *);
const char *mutt_basename (const char *);

int compare_stat (struct stat *, struct stat *);
int mutt_copy_stream (FILE *, FILE *);
int mutt_copy_bytes (FILE *, FILE *, size_t);
int mutt_strcasecmp (const char *, const char *);
int mutt_strcmp (const char *, const char *);
int mutt_strncasecmp (const char *, const char *, size_t);
int mutt_strncmp (const char *, const char *, size_t);
int mutt_strcoll (const char *, const char *);
int safe_asprintf (char **, const char *, ...);
int safe_rename (const char *, const char *);
int safe_fclose (FILE **);
int safe_fsync_close (FILE **);

size_t mutt_strlen (const char *);

void *safe_calloc (size_t, size_t);
void *safe_malloc (size_t);
void mutt_nocurses_error (const char *, ...);
void mutt_remove_trailing_ascii_ws (char *);
void mutt_sanitize_filename (char *, int flags);
void mutt_str_replace (char **p, const char *s);
int mutt_mkdir (char *path, mode_t mode);
void mutt_str_adjust (char **p);
void mutt_unlink (const char *);
void safe_free (void *);
void safe_realloc (void *, size_t);

const char *mutt_strsysexit(int e);
#endif