xref: /freebsd/contrib/nvi/common/util.h (revision 39ee7a7a6bdd1557b1c3532abf60d139798ac88b)
1 /*-
2  * Copyright (c) 1994
3  *	The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1994, 1995, 1996
5  *	Keith Bostic.  All rights reserved.
6  *
7  * See the LICENSE file for redistribution information.
8  *
9  *	$Id: util.h,v 10.7 2013/02/24 21:00:10 zy Exp $
10  */
11 
12 /* Macros to init/set/clear/test flags. */
13 #define	FL_INIT(l, f)	(l) = (f)		/* Specific flags location. */
14 #define	FL_SET(l, f)	((l) |= (f))
15 #define	FL_CLR(l, f)	((l) &= ~(f))
16 #define	FL_ISSET(l, f)	((l) & (f))
17 
18 #define	LF_INIT(f)	FL_INIT(flags, f)	/* Local variable flags. */
19 #define	LF_SET(f)	FL_SET(flags, f)
20 #define	LF_CLR(f)	FL_CLR(flags, f)
21 #define	LF_ISSET(f)	FL_ISSET(flags, f)
22 
23 #define	F_INIT(p, f)	FL_INIT((p)->flags, f)	/* Structure element flags. */
24 #define	F_SET(p, f)	FL_SET((p)->flags, f)
25 #define	F_CLR(p, f)	FL_CLR((p)->flags, f)
26 #define	F_ISSET(p, f)	FL_ISSET((p)->flags, f)
27 
28 /* Offset to next column of stop size, e.g. tab offsets. */
29 #define	COL_OFF(c, stop)	((stop) - ((c) % (stop)))
30 
31 /* Busy message types. */
32 typedef enum { B_NONE, B_OFF, B_READ, B_RECOVER, B_SEARCH, B_WRITE } bmsg_t;
33 
34 /*
35  * Number handling defines and protoypes.
36  *
37  * NNFITS:	test for addition of two negative numbers under a limit
38  * NPFITS:	test for addition of two positive numbers under a limit
39  * NADD_SLONG:	test for addition of two signed longs
40  * NADD_USLONG:	test for addition of two unsigned longs
41  */
42 enum nresult { NUM_ERR, NUM_OK, NUM_OVER, NUM_UNDER };
43 #define	NNFITS(min, cur, add)						\
44 	(((long)(min)) - (cur) <= (add))
45 #define	NPFITS(max, cur, add)						\
46 	(((unsigned long)(max)) - (cur) >= (add))
47 #define	NADD_SLONG(sp, v1, v2)						\
48 	((v1) < 0 ?							\
49 	    ((v2) < 0 &&						\
50 	    NNFITS(LONG_MIN, (v1), (v2))) ? NUM_UNDER : NUM_OK :	\
51 	 (v1) > 0 ?							\
52 	    (v2) > 0 &&							\
53 	    NPFITS(LONG_MAX, (v1), (v2)) ? NUM_OK : NUM_OVER :		\
54 	 NUM_OK)
55 #define	NADD_USLONG(sp, v1, v2)						\
56 	(NPFITS(ULONG_MAX, (v1), (v2)) ? NUM_OK : NUM_OVER)
57 
58 /* Macros for min/max. */
59 #undef	MIN
60 #undef	MAX
61 #define	MIN(_a,_b)	((_a)<(_b)?(_a):(_b))
62 #define	MAX(_a,_b)	((_a)<(_b)?(_b):(_a))
63 
64 /* Operations on timespecs */
65 #undef timespecclear
66 #undef timespecisset
67 #undef timespeccmp
68 #undef timespecadd
69 #undef timespecsub
70 #define	timespecclear(tvp)	((tvp)->tv_sec = (tvp)->tv_nsec = 0)
71 #define	timespecisset(tvp)	((tvp)->tv_sec || (tvp)->tv_nsec)
72 #define	timespeccmp(tvp, uvp, cmp)					\
73 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
74 	    ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :			\
75 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
76 #define timespecadd(vvp, uvp)						\
77 	do {								\
78 		(vvp)->tv_sec += (uvp)->tv_sec;				\
79 		(vvp)->tv_nsec += (uvp)->tv_nsec;			\
80 		if ((vvp)->tv_nsec >= 1000000000) {			\
81 			(vvp)->tv_sec++;				\
82 			(vvp)->tv_nsec -= 1000000000;			\
83 		}							\
84 	} while (0)
85 #define timespecsub(vvp, uvp)						\
86 	do {								\
87 		(vvp)->tv_sec -= (uvp)->tv_sec;				\
88 		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
89 		if ((vvp)->tv_nsec < 0) {				\
90 			(vvp)->tv_sec--;				\
91 			(vvp)->tv_nsec += 1000000000;			\
92 		}							\
93 	} while (0)
94