598569d00462512eeb9f13022073a3a708b974e0
[exim.git] / src / src / mytypes.h
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
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 */
9
10
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). */
14
15 #ifndef MYTYPES_H
16 #define MYTYPES_H
17
18 # include <string.h>
19
20 #ifndef FALSE
21 # define FALSE         0
22 #endif
23
24 #ifndef TRUE
25 # define TRUE          1
26 #endif
27
28 #ifndef TRUE_UNSET
29 # define TRUE_UNSET    2
30 #endif
31
32
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. */
37
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))
45 # ifndef __clang__
46 #  define ALLOC_SIZE(A)         __attribute__((alloc_size(A)))
47 # else
48 #  define ALLOC_SIZE(A)         /**/
49 # endif
50 #else
51 # define ARG_UNUSED             /**/
52 # define FUNC_MAYBE_UNUSED      /**/
53 # define WARN_UNUSED_RESULT     /**/
54 # define ALLOC                  /**/
55 # define ALLOC_SIZE(A)          /**/
56 # define NORETURN               /**/
57 #endif
58
59 #ifndef PRINTF_FUNCTION
60 # define PRINTF_FUNCTION(A,B)   /**/
61 #endif
62
63 #ifdef WANT_DEEPER_PRINTF_CHECKS
64 # define ALMOST_PRINTF(A, B) PRINTF_FUNCTION(A, B)
65 #else
66 # define ALMOST_PRINTF(A, B)    /**/
67 #endif
68
69
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. */
73
74 typedef unsigned char uschar;
75 typedef unsigned BOOL;
76 /* We also have SIGNAL_BOOL, which requires signal.h be included, so is defined
77 elsewhere */
78
79
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. */
85
86 #define CS   (char *)
87 #define CCS  (const char *)
88 #define CSS  (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 **)
94
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. */
99
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)
108
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))
139
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)
145 #else
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__)
150 #endif
151
152 #endif
153 /* End of mytypes.h */