Line data Source code
1 : #ifndef RAII_H
2 : #define RAII_H
3 :
4 : #include <stdlib.h>
5 : #include <stdio.h>
6 : #include <dirent.h>
7 : #include "html_parser.h"
8 :
9 : /**
10 : * Cleanup functions for GNU RAII attributes.
11 : * These are called when a variable with the __attribute__((cleanup(func))) goes out of scope.
12 : */
13 :
14 113358 : static inline void free_ptr(void *ptr) {
15 113358 : void **p = (void **)ptr;
16 113358 : if (*p) {
17 111649 : free(*p);
18 111649 : *p = NULL;
19 : }
20 113358 : }
21 :
22 32145 : static inline void fclose_ptr(void *ptr) {
23 32145 : FILE **p = (FILE **)ptr;
24 32145 : if (*p) {
25 25017 : fclose(*p);
26 25016 : *p = NULL;
27 : }
28 32144 : }
29 :
30 10 : static inline void pclose_ptr(FILE **p) {
31 10 : if (p && *p) {
32 8 : pclose(*p);
33 8 : *p = NULL;
34 : }
35 10 : }
36 :
37 60694 : static inline void closedir_ptr(DIR **p) {
38 60694 : if (p && *p) {
39 6133 : closedir(*p);
40 6133 : *p = NULL;
41 : }
42 60694 : }
43 :
44 : #define RAII_STRING __attribute__((cleanup(free_ptr)))
45 : #define RAII_FILE __attribute__((cleanup(fclose_ptr)))
46 : #define RAII_PFILE __attribute__((cleanup(pclose_ptr)))
47 : #define RAII_DIR __attribute__((cleanup(closedir_ptr)))
48 :
49 : /* To avoid circular dependencies with Config, we use a generic cleanup for it
50 : * but it must be defined in each file that uses it or we use a macro. */
51 : #define RAII_WITH_CLEANUP(func) __attribute__((cleanup(func)))
52 :
53 21 : static inline void html_node_free_ptr(HtmlNode **p) {
54 21 : if (p && *p) { html_node_free(*p); *p = NULL; }
55 21 : }
56 : #define RAII_HTML_NODE __attribute__((cleanup(html_node_free_ptr)))
57 :
58 : #endif /* RAII_H */
|