119304Speter/*-
219304Speter * Copyright (c) 1993, 1994
319304Speter *	The Regents of the University of California.  All rights reserved.
419304Speter * Copyright (c) 1993, 1994, 1995, 1996
519304Speter *	Keith Bostic.  All rights reserved.
619304Speter *
719304Speter * See the LICENSE file for redistribution information.
819304Speter *
919304Speter *	@(#)mem.h	10.7 (Berkeley) 3/30/96
1019304Speter */
1119304Speter
1219304Speter/* Increase the size of a malloc'd buffer.  Two versions, one that
1319304Speter * returns, one that jumps to an error label.
1419304Speter */
1519304Speter#define	BINC_GOTO(sp, lp, llen, nlen) {					\
1619304Speter	void *L__bincp;							\
1719304Speter	if ((nlen) > llen) {						\
1819304Speter		if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL)	\
1919304Speter			goto alloc_err;					\
2019304Speter		/*							\
2119304Speter		 * !!!							\
2219304Speter		 * Possible pointer conversion.				\
2319304Speter		 */							\
2419304Speter		lp = L__bincp;						\
2519304Speter	}								\
2619304Speter}
2719304Speter#define	BINC_RET(sp, lp, llen, nlen) {					\
2819304Speter	void *L__bincp;							\
2919304Speter	if ((nlen) > llen) {						\
3019304Speter		if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL)	\
3119304Speter			return (1);					\
3219304Speter		/*							\
3319304Speter		 * !!!							\
3419304Speter		 * Possible pointer conversion.				\
3519304Speter		 */							\
3619304Speter		lp = L__bincp;						\
3719304Speter	}								\
3819304Speter}
3919304Speter
4019304Speter/*
4119304Speter * Get some temporary space, preferably from the global temporary buffer,
4219304Speter * from a malloc'd buffer otherwise.  Two versions, one that returns, one
4319304Speter * that jumps to an error label.
4419304Speter */
4519304Speter#define	GET_SPACE_GOTO(sp, bp, blen, nlen) {				\
4619304Speter	GS *L__gp = (sp) == NULL ? NULL : (sp)->gp;			\
4719304Speter	if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) {		\
4819304Speter		bp = NULL;						\
4919304Speter		blen = 0;						\
5019304Speter		BINC_GOTO(sp, bp, blen, nlen); 				\
5119304Speter	} else {							\
5219304Speter		BINC_GOTO(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen);	\
5319304Speter		bp = L__gp->tmp_bp;					\
5419304Speter		blen = L__gp->tmp_blen;					\
5519304Speter		F_SET(L__gp, G_TMP_INUSE);				\
5619304Speter	}								\
5719304Speter}
5819304Speter#define	GET_SPACE_RET(sp, bp, blen, nlen) {				\
5919304Speter	GS *L__gp = (sp) == NULL ? NULL : (sp)->gp;			\
6019304Speter	if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) {		\
6119304Speter		bp = NULL;						\
6219304Speter		blen = 0;						\
6319304Speter		BINC_RET(sp, bp, blen, nlen);				\
6419304Speter	} else {							\
6519304Speter		BINC_RET(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen);	\
6619304Speter		bp = L__gp->tmp_bp;					\
6719304Speter		blen = L__gp->tmp_blen;					\
6819304Speter		F_SET(L__gp, G_TMP_INUSE);				\
6919304Speter	}								\
7019304Speter}
7119304Speter
7219304Speter/*
7319304Speter * Add space to a GET_SPACE returned buffer.  Two versions, one that
7419304Speter * returns, one that jumps to an error label.
7519304Speter */
7619304Speter#define	ADD_SPACE_GOTO(sp, bp, blen, nlen) {				\
7719304Speter	GS *L__gp = (sp) == NULL ? NULL : (sp)->gp;			\
7819304Speter	if (L__gp == NULL || bp == L__gp->tmp_bp) {			\
7919304Speter		F_CLR(L__gp, G_TMP_INUSE);				\
8019304Speter		BINC_GOTO(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen);	\
8119304Speter		bp = L__gp->tmp_bp;					\
8219304Speter		blen = L__gp->tmp_blen;					\
8319304Speter		F_SET(L__gp, G_TMP_INUSE);				\
8419304Speter	} else								\
8519304Speter		BINC_GOTO(sp, bp, blen, nlen);				\
8619304Speter}
8719304Speter#define	ADD_SPACE_RET(sp, bp, blen, nlen) {				\
8819304Speter	GS *L__gp = (sp) == NULL ? NULL : (sp)->gp;			\
8919304Speter	if (L__gp == NULL || bp == L__gp->tmp_bp) {			\
9019304Speter		F_CLR(L__gp, G_TMP_INUSE);				\
9119304Speter		BINC_RET(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen);	\
9219304Speter		bp = L__gp->tmp_bp;					\
9319304Speter		blen = L__gp->tmp_blen;					\
9419304Speter		F_SET(L__gp, G_TMP_INUSE);				\
9519304Speter	} else								\
9619304Speter		BINC_RET(sp, bp, blen, nlen);				\
9719304Speter}
9819304Speter
9919304Speter/* Free a GET_SPACE returned buffer. */
10019304Speter#define	FREE_SPACE(sp, bp, blen) {					\
10119304Speter	GS *L__gp = (sp) == NULL ? NULL : (sp)->gp;			\
10219304Speter	if (L__gp != NULL && bp == L__gp->tmp_bp)			\
10319304Speter		F_CLR(L__gp, G_TMP_INUSE);				\
10419304Speter	else								\
10519304Speter		free(bp);						\
10619304Speter}
10719304Speter
10819304Speter/*
10919304Speter * Malloc a buffer, casting the return pointer.  Various versions.
11019304Speter *
11119304Speter * !!!
11219304Speter * The cast should be unnecessary, malloc(3) and friends return void *'s,
11319304Speter * which is all we need.  However, some systems that nvi needs to run on
11419304Speter * don't do it right yet, resulting in the compiler printing out roughly
11519304Speter * a million warnings.  After awhile, it seemed easier to put the casts
11619304Speter * in instead of explaining it all the time.
11719304Speter */
11819304Speter#define	CALLOC(sp, p, cast, nmemb, size) {				\
11919304Speter	if ((p = (cast)calloc(nmemb, size)) == NULL)			\
12019304Speter		msgq(sp, M_SYSERR, NULL);				\
12119304Speter}
12219304Speter#define	CALLOC_GOTO(sp, p, cast, nmemb, size) {				\
12319304Speter	if ((p = (cast)calloc(nmemb, size)) == NULL)			\
12419304Speter		goto alloc_err;						\
12519304Speter}
12619304Speter#define	CALLOC_NOMSG(sp, p, cast, nmemb, size) {			\
12719304Speter	p = (cast)calloc(nmemb, size);					\
12819304Speter}
12919304Speter#define	CALLOC_RET(sp, p, cast, nmemb, size) {				\
13019304Speter	if ((p = (cast)calloc(nmemb, size)) == NULL) {			\
13119304Speter		msgq(sp, M_SYSERR, NULL);				\
13219304Speter		return (1);						\
13319304Speter	}								\
13419304Speter}
13519304Speter
13619304Speter#define	MALLOC(sp, p, cast, size) {					\
13719304Speter	if ((p = (cast)malloc(size)) == NULL)				\
13819304Speter		msgq(sp, M_SYSERR, NULL);				\
13919304Speter}
14019304Speter#define	MALLOC_GOTO(sp, p, cast, size) {				\
14119304Speter	if ((p = (cast)malloc(size)) == NULL)				\
14219304Speter		goto alloc_err;						\
14319304Speter}
14419304Speter#define	MALLOC_NOMSG(sp, p, cast, size) {				\
14519304Speter	p = (cast)malloc(size);						\
14619304Speter}
14719304Speter#define	MALLOC_RET(sp, p, cast, size) {					\
14819304Speter	if ((p = (cast)malloc(size)) == NULL) {				\
14919304Speter		msgq(sp, M_SYSERR, NULL);				\
15019304Speter		return (1);						\
15119304Speter	}								\
15219304Speter}
15319304Speter/*
15419304Speter * XXX
15519304Speter * Don't depend on realloc(NULL, size) working.
15619304Speter */
15719304Speter#define	REALLOC(sp, p, cast, size) {					\
15819304Speter	if ((p = (cast)(p == NULL ?					\
15919304Speter	    malloc(size) : realloc(p, size))) == NULL)			\
16019304Speter		msgq(sp, M_SYSERR, NULL);				\
16119304Speter}
16219304Speter
16319304Speter/*
16419304Speter * Versions of memmove(3) and memset(3) that use the size of the
16519304Speter * initial pointer to figure out how much memory to manipulate.
16619304Speter */
16719304Speter#define	MEMMOVE(p, t, len)	memmove(p, t, (len) * sizeof(*(p)))
16819304Speter#define	MEMSET(p, value, len)	memset(p, value, (len) * sizeof(*(p)))
169