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