1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 2020 - 2023 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
11 /* This header file contains type definitions and macros that I use as
12 "standard" in the code of Exim and its utilities. Make it idempotent because
13 local_scan.h includes it and exim.h includes them both (to get this earlier). */
33 /* We gave up on trying to get compilers to check on printf-like functions
34 because they are both whiney about value sizes where they cannot do decent
35 static analysis, and incapable of handling extensions to printf formats.
36 The annotation on functions is still in place but does nothing. */
38 #if defined(__GNUC__) || defined(__clang__)
39 /* # define PRINTF_FUNCTION(A,B) __attribute__((format(printf,A,B))) */
40 # define ARG_UNUSED __attribute__((__unused__))
41 # define FUNC_MAYBE_UNUSED __attribute__((__unused__))
42 # define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
43 # define ALLOC __attribute__((malloc))
44 # define NORETURN __attribute__((noreturn))
46 # define ALLOC_SIZE(A) __attribute__((alloc_size(A)))
48 # define ALLOC_SIZE(A) /**/
51 # define ARG_UNUSED /**/
52 # define FUNC_MAYBE_UNUSED /**/
53 # define WARN_UNUSED_RESULT /**/
55 # define ALLOC_SIZE(A) /**/
56 # define NORETURN /**/
59 #ifndef PRINTF_FUNCTION
60 # define PRINTF_FUNCTION(A,B) /**/
63 #ifdef WANT_DEEPER_PRINTF_CHECKS
64 # define ALMOST_PRINTF(A, B) PRINTF_FUNCTION(A, B)
66 # define ALMOST_PRINTF(A, B) /**/
70 /* Some operating systems (naughtily, imo) include a definition for "uchar" in
71 the standard header files, so we use "uschar". Solaris has u_char in
72 sys/types.h. This is just a typing convenience, of course. */
74 typedef unsigned char uschar;
75 typedef unsigned BOOL;
76 /* We also have SIGNAL_BOOL, which requires signal.h be included, so is defined
80 /* These macros save typing for the casting that is needed to cope with the
81 mess that is "char" in ISO/ANSI C. Having now been bitten enough times by
82 systems where "char" is actually signed, I've converted Exim to use entirely
83 unsigned chars, except in a few special places such as arguments that are
84 almost always literal strings. */
87 #define CCS (const char *)
89 #define US (unsigned char *)
90 #define CUS (const unsigned char *)
91 #define USS (unsigned char **)
92 #define CUSS (const unsigned char **)
93 #define CCSS (const char **)
95 /* The C library string functions expect "char *" arguments. Use macros to
96 avoid having to write a cast each time. We do this for string and file
97 functions that are called quite often; for other calls to external libraries
98 (which are on the whole special-purpose) we just use individual casts. */
100 #define Uatoi(s) atoi(CCS(s))
101 #define Uatol(s) atol(CCS(s))
102 #define Uchdir(s) chdir(CCS(s))
103 #define Uchmod(s,n) chmod(CCS(s),n)
104 #define Ufgets(b,n,f) fgets(CS(b),n,f)
105 #define Ufopen(s,t) exim_fopen(CCS(s),CCS(t))
106 #define Ulink(s,t) link(CCS(s),CCS(t))
107 #define Ulstat(s,t) lstat(CCS(s),t)
109 #ifdef O_BINARY /* This is for Cygwin, */
110 # define Uopen(s,n,m) exim_open(CCS(s),(n)|O_BINARY,m) /* where all files must */
111 # define Uopen2(s,n) exim_open2(CCS(s),(n)|O_BINARY)
112 #else /* be opened as binary */
113 # define Uopen(s,n,m) exim_open(CCS(s),n,m) /* to avoid problems */
114 # define Uopen2(s,n) exim_open2(CCS(s),n)
115 #endif /* with CRLF endings. */
116 #define Uread(f,b,l) read(f,CS(b),l)
117 #define Urename(s,t) rename(CCS(s),CCS(t))
118 #define Ustat(s,t) stat(CCS(s),t)
119 #define Ustrchr(s,n) US strchr(CCS(s),n)
120 #define Ustrchrnul(s,n) US strchrnul(CCS(s),n)
121 #define CUstrerror(n) CUS strerror(n)
122 #define Ustrcmp(s,t) strcmp(CCS(s),CCS(t))
123 #define Ustrcpy_nt(s,t) strcpy(CS s, CCS t) /* no taint check */
124 #define Ustrcspn(s,t) strcspn(CCS(s),CCS(t))
125 #define Ustrftime(s,m,f,t) strftime(CS(s),m,f,t)
126 #define Ustrlen(s) (int)strlen(CCS(s))
127 #define Ustrncmp(s,t,n) strncmp(CCS(s),CCS(t),n)
128 #define Ustrncpy_nt(s,t,n) strncpy(CS s, CCS t, n) /* no taint check */
129 #define Ustrpbrk(s,t) strpbrk(CCS(s),CCS(t))
130 #define Ustrrchr(s,n) US strrchr(CCS(s),n)
131 #define CUstrrchr(s,n) CUS strrchr(CCS(s),n)
132 #define Ustrspn(s,t) strspn(CCS(s),CCS(t))
133 #define Ustrstr(s,t) US strstr(CCS(s),CCS(t))
134 #define CUstrstr(s,t) CUS strstr(CCS(s),CCS(t))
135 #define Ustrtod(s,t) strtod(CCS(s),CSS(t))
136 #define Ustrtol(s,t,b) strtol(CCS(s),CSS(t),b)
137 #define Ustrtoul(s,t,b) strtoul(CCS(s),CSS(t),b)
138 #define Uunlink(s) unlink(CCS(s))
140 #if defined(EM_VERSION_C) || defined(LOCAL_SCAN) || defined(DLFUNC_IMPL)
141 # define Ustrcat(s,t) strcat(CS(s), CCS(t))
142 # define Ustrcpy(s,t) strcpy(CS(s), CCS(t))
143 # define Ustrncat(s,t,n) strncat(CS(s), CCS(t), n)
144 # define Ustrncpy(s,t,n) strncpy(CS(s), CCS(t), n)
146 # define Ustrcat(s,t) __Ustrcat(s, CUS(t), __FUNCTION__, __LINE__)
147 # define Ustrcpy(s,t) __Ustrcpy(s, CUS(t), __FUNCTION__, __LINE__)
148 # define Ustrncat(s,t,n) __Ustrncat(s, CUS(t), n, __FUNCTION__, __LINE__)
149 # define Ustrncpy(s,t,n) __Ustrncpy(s, CUS(t), n, __FUNCTION__, __LINE__)
153 /* End of mytypes.h */