/* $Id: must2.h,v 1.4 2021/11/16 21:57:49 oj14ozun Exp $ * further experiments with c error handling * * examples: * mzr stat("/etc/passwd", &buf); -- must be zero, or return * mpf mem = malloc(1024); -- must be positive or exit(failure) * mnb listen = accept(sock, NULL, NULL); -- must be negative or break */ #include #define __must(handle, check) \ for (void *___q = 1, *___v = NULL; \ (*__v || ((check(__v)) && handle)) || ___q; \ ___q = 0) \ __v = & /* handles */ #define __Rn(n) { return n; } /* return n */ #define __RN __Rn(-1) /* return negative */ #define __R0 __Rn(0) /* return zero */ #define __E1 { exit(EXIT_FAILURE); }; /* exit with 1 */ #define __E0 { exit(EXIT_SUCCESS); } /* exit with 0 */ #define __W1 /* warn and exit with 1 */ \ { perror(__FILE__ ", " #__LINE__); exit(EXIT_FAILURE); } #define __W0 /* warn and exit with 0 */ \ { perror(__FILE__ ", " #__LINE__); exit(EXIT_SUCCESS); } #define __JC { continue; } /* just continue */ #define __JB { break; } /* just break */ #define __Gl(l) { goto l; } /* goto label */ /* checks */ #define __ER(no) ((x), no == errno) /* non-negative */ /* actual macros */ #define mzr __must(__RN, 0 ==) /* must be zero or return negative */ #define mzf __must(__E0, 0 ==) /* must be zero or fail (exit 1) */ #define mze __must(__E1, 0 ==) /* must be zero or quit (exit 0) */ #define mzw __must(__W1, 0 ==) /* must be zero or warn and fail (exit 1) */ #define mzc __must(__JC, 0 ==) /* must be zero or continue */ #define mzb __must(__JB, 0 ==) /* must be zero or break */ #define mzn(n) __must(__Rn(n), 0 ==) /* must be zero or return n */ #define mzg(l) __must(__Gl(l), 0 ==) /* must be zero or goto l */ #define mpr __must(__RN, 0 <) /* must be positive or return negative */ #define mpf __must(__E0, 0 <) /* must be positive or fail (exit 1) */ #define mpe __must(__E1, 0 <) /* must be positive or quit (exit 0) */ #define mpw __must(__W1, 0 <) /* must be positive or warn and fail (exit 1) */ #define mpc __must(__JC, 0 <) /* must be positive or continue */ #define mpb __must(__JB, 0 <) /* must be positive or break */ #define mpn(n) __must(__Rn(n), 0 <) /* must be positive or return n */ #define mpg(l) __must(__Gl(l), 0 <) /* must be positive or goto l */ #define mnr __must(__RN, 0 >) /* must be negative or return negative */ #define mnf __must(__E0, 0 >) /* must be negative or fail (exit 1) */ #define mne __must(__E1, 0 >) /* must be negative or quit (exit 0) */ #define mnw __must(__W1, 0 >) /* must be negative or warn and fail (exit 1) */ #define mnc __must(__JC, 0 >) /* must be negative or continue */ #define mnb __must(__JB, 0 >) /* must be negative or break */ #define mnn(n) __must(__Rn(n), 0 >) /* must be negative or return n */ #define mng(l) __must(__Gl(l), 0 >) /* must be negative or goto l */ #define mer __must(__RN, __ER(0)) /* errno must be zero or return negative */ #define mef __must(__E0, __ER(0)) /* errno must be zero or fail (exit 1) */ #define mee __must(__E1, __ER(0)) /* errno must be zero or quit (exit 0) */ #define mew __must(__W1, __ER(0)) /* errno must be zero or warn and fail (exit 1) */ #define mec __must(__JC, __ER(0)) /* errno must be zero or continue */ #define meb __must(__JB, __ER(0)) /* errno must be zero or break */ #define men(n) __must(__Rn(n), __ER(0)) /* errno must be zero or return n */ #define meg(l) __must(__Gl(l), __ER(0)) /* errno must be zero or goto l */ /* Local Variables: */ /* comment-column: 50 */ /* indent-tabs-mode: nil */ /* End: */