1 /*	Public domain	*/
2 
3 #ifndef	_AGAR_CORE_ERROR_H_
4 #define	_AGAR_CORE_ERROR_H_
5 
6 #include <agar/config/_mk_have_stdlib_h.h>
7 #ifdef _MK_HAVE_STDLIB_H
8 #include <stdlib.h>
9 #endif
10 
11 #include <agar/core/begin.h>
12 
13 /* Standard error code */
14 typedef enum ag_error_code {
15 	AG_EUNDEFINED,		/* Undefined error */
16 	AG_EPERM,		/* Operation not permitted */
17 	AG_ENOENT,		/* No such file or directory */
18 	AG_EINTR,		/* Interrupted system call */
19 	AG_EIO,			/* Input/output error */
20 	AG_E2BIG,		/* Argument list too long */
21 	AG_EACCESS,		/* Permission denied */
22 	AG_EBUSY,		/* Device or resource busy */
23 	AG_EEXIST,		/* File exists */
24 	AG_ENOTDIR,		/* Not a directory */
25 	AG_EISDIR,		/* Is a directory */
26 	AG_EMFILE,		/* Too many open files */
27 	AG_EFBIG,		/* File too large */
28 	AG_ENOSPC,		/* No space left on device */
29 	AG_EROFS,		/* Read-only file system */
30 	AG_EAGAIN		/* Resource temporarily unavailable */
31 } AG_ErrorCode;
32 
33 #if defined(_AGAR_INTERNAL) || defined(_USE_AGAR_STD)
34 # define Malloc(len) AG_Malloc(len)
35 # define TryMalloc(len) AG_TryMalloc(len)
36 # define Free(p) AG_Free(p)
37 # define Realloc(p,len) AG_Realloc((p),(len))
38 # define TryRealloc(p,len) AG_TryRealloc((p),(len))
39 # define Verbose AG_Verbose
40 # ifdef AG_DEBUG
41 #  define Debug AG_Debug
42 # else
43 #  ifdef __GNUC__
44 #   define Debug(obj, arg...) ((void)0)
45 #  else
46 #   define Debug AG_Debug
47 #  endif
48 # endif /* AG_DEBUG */
49 #endif /* _AGAR_INTERNAL or _USE_AGAR_STD */
50 
51 __BEGIN_DECLS
52 extern int agDebugLvl;
53 
54 int		 AG_InitErrorSubsystem(void);
55 void		 AG_DestroyErrorSubsystem(void);
56 AG_ErrorCode	 AG_GetErrorCode(void);
57 const char	*AG_GetError(void);
58 void		 AG_SetErrorCode(AG_ErrorCode);
59 void		 AG_SetError(const char *, ...)
60 		     FORMAT_ATTRIBUTE(printf, 1, 2)
61 		     NONNULL_ATTRIBUTE(1);
62 void		 AG_FatalError(const char *, ...)
63 		     NORETURN_ATTRIBUTE;
64 void		 AG_SetFatalCallback(void (*callback)(const char *));
65 void		 AG_SetVerboseCallback(int (*callback)(const char *));
66 void		 AG_SetDebugCallback(int (*callback)(const char *));
67 void		 AG_Debug(void *, const char *, ...)
68 		     FORMAT_ATTRIBUTE(printf, 2, 3)
69 		     NONNULL_ATTRIBUTE(2);
70 void		 AG_Verbose(const char *, ...)
71 		     FORMAT_ATTRIBUTE(printf, 1, 2)
72 		     NONNULL_ATTRIBUTE(1);
73 void		*AG_PtrMismatch(void);
74 void		*AG_ObjectMismatch(const char *, const char *);
75 int		 AG_IntMismatch(void);
76 float		 AG_FloatMismatch(void);
77 const char	*AG_Strerror(int);
78 
79 /* Malloc wrapper (failure is fatal) */
80 static __inline__ void *
AG_Malloc(size_t len)81 AG_Malloc(size_t len)
82 {
83 	void *p;
84 	if ((p = malloc(len)) == NULL) { AG_FatalError("malloc"); }
85 	return (p);
86 }
87 
88 /* Malloc wrapper (return on failure) */
89 static __inline__ void *
AG_TryMalloc(size_t len)90 AG_TryMalloc(size_t len)
91 {
92 	void *p;
93 	if ((p = malloc(len)) == NULL) {
94 		AG_SetError("Out of memory");
95 		return (NULL);
96 	}
97 	return (p);
98 }
99 
100 /* Realloc wrapper (failure is fatal) */
101 static __inline__ void *
AG_Realloc(void * pOld,size_t len)102 AG_Realloc(void *pOld, size_t len)
103 {
104 	void *pNew;
105 	/* XXX redundant on some systems */
106 	if (pOld == NULL) {
107 		if ((pNew = malloc(len)) == NULL)
108 			AG_FatalError("malloc");
109 	} else {
110 		if ((pNew = realloc(pOld, len)) == NULL)
111 			AG_FatalError("realloc");
112 	}
113 	return (pNew);
114 }
115 
116 /* Realloc wrapper (return on failure) */
117 static __inline__ void *
AG_TryRealloc(void * pOld,size_t len)118 AG_TryRealloc(void *pOld, size_t len)
119 {
120 	void *pNew;
121 	/* XXX redundant on some systems */
122 	if (pOld == NULL) {
123 		if ((pNew = malloc(len)) == NULL)
124 			goto outofmem;
125 	} else {
126 		if ((pNew = realloc(pOld, len)) == NULL)
127 			goto outofmem;
128 	}
129 	return (pNew);
130 outofmem:
131 	AG_SetError("Out of memory");
132 	return (NULL);
133 }
134 
135 /* Free wrapper for symmetry */
136 #define AG_Free(p) free(p)
137 __END_DECLS
138 
139 #include <agar/core/close.h>
140 #endif /* _AGAR_CORE_ERROR_H_ */
141