-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmacro.h
123 lines (105 loc) · 3.71 KB
/
macro.h
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
/*****************************************************************************\
** **
** LCR **
** **
**---------------------------------------------------------------------------**
** Copyright: Andreas Eversberg **
** **
** Macros to do safe string operations to avoid buffer overflows **
** Macros for memory allocation, feeing and error handling **
** **
\*****************************************************************************/
/* safe strcpy/strncpy */
#define SCPY(dst, src) scpy(dst, src, sizeof(dst))
static inline void scpy(char *dst, const char *src, unsigned int siz)
{
strncpy(dst, src, siz);
dst[siz-1] = '\0';
}
/* safe strcat/strncat */
#define SCAT(dst, src) scat(dst, src, sizeof(dst))
static inline void scat(char *dst, const char *src, unsigned int siz)
{
strncat(dst, src, siz-strlen(dst)-1);
dst[siz-1] = '\0';
}
/* safe concat of a byte */
#define SCCAT(dst, src) sccat(dst, src, sizeof(dst))
static inline void sccat(char *dst, char chr, unsigned int siz)
{
if (strlen(dst) < siz-1)
{
dst[strlen(dst)+1] = '\0';
dst[strlen(dst)] = chr;
}
}
/* safe sprintf/snprintf */
#define SPRINT(dst, fmt, arg...) sprint(dst, sizeof(dst), fmt, ## arg)
static inline void sprint(char *dst, unsigned int siz, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsnprintf(dst, siz, fmt, args);
dst[siz-1] = '\0';
va_end(args);
}
/* unsafe */
#define UCPY strcpy
#define UNCPY strncpy
#define UCAT strcat
#define UNCAT strncat
#define UPRINT sprintf
#define UNPRINT snprintf
#define VUNPRINT vsnprintf
#define FATAL(fmt, arg...) _fatal(__FILE__, __FUNCTION__, __LINE__, fmt, ##arg)
/* fatal error with error message and exit */
static inline void _fatal(const char *file, const char *function, int line, const char *fmt, ...)
{
va_list args;
char buffer[256];
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
buffer[sizeof(buffer)-1] = '\0';
fprintf(stderr, "FATAL ERROR in function %s/%s, line %d: %s", file, function, line, buffer);
fprintf(stderr, "This error is not recoverable, must exit here.\n");
#ifdef DEBUG_FUNC
debug(file, function, line, "FATAL", buffer);
debug(file, function, line, "FATAL", (char *)"This error is not recoverable, must exit here.\n");
#endif
exit(EXIT_FAILURE);
}
/* memory allocation with setting to zero */
#define MALLOC(size) _malloc(size, __FILE__, __FUNCTION__, __LINE__)
static inline void *_malloc(unsigned int size, const char *file, const char *function, int line)
{
void *addr;
addr = malloc(size);
if (!addr)
_fatal(file, function, line, "No memory for %d bytes.\n", size);
memset(addr, 0, size);
return addr;
}
/* memory freeing with clearing memory to prevent using freed memory */
#define FREE(addr, size) _free(addr, size)
static inline void _free(void *addr, int size)
{
if (size)
memset(addr, 0, size);
free(addr);
}
/* fill buffer and be sure that it's result is 0-terminated, also remove newline */
#define GETLINE(buffer, fp) _getline(buffer, sizeof(buffer), fp)
static inline char *_getline(char *buffer, int size, FILE *fp)
{
if (!fgets(buffer, size-1, fp))
return NULL;
buffer[size-1] = '\0';
if (!buffer[0])
return buffer;
if (buffer[strlen(buffer)-1] == '\n')
buffer[strlen(buffer)-1] = '\0';
if (buffer[strlen(buffer)-1] == '\r')
buffer[strlen(buffer)-1] = '\0';
return buffer;
}