/*
* dyna.h -- 動的に大きくなるバッファ
* Copyright (C) 1991-1993 by candy
* Thu Oct 31 10:13:53 JST 1996
* DYNA_IZ() 不要に
* Sat May 3 00:27:48 JST 1997
* BOGUS_REALLOC
*/
/*
* $Id: dyna.h,v 3.6 1996/11/28 09:01:21 candy Exp $
*/
#ifndef __DYNA_H /* [ */
#define __DYNA_H
#ifdef BOGUS_REALLOC
#undef realloc
#define realloc(p,s) ((p)?((realloc)(p,s)):malloc(s))
#endif
/*
* NAME
* STRUCT_DYNA - 構造体の宣言(の一部!!)
*
* SYNOPSIS
* struct DYNA STRUCT_DYNA(TYPE);
*
* DESCRIPTION
* TYPE 型を要素とする動的に大きくなる配列を扱う構造体
* struct DYNA
* を宣言します。
*
* EXAPMLE
* struct CHAR_BUF STRUCT_DYNA(char); 文字バッファ
* struct LIST_BUF STRUCT_DYNA(char *); 文字列のリスト
* のように宣言します。
* TYPE の書式には制限があって、定義
* TYPE * identifier;
* において、identifier が TYPE へのポインタとなるようなものしか書けません。
* 例えば
* STRUCT_DYNA(char **) はいいけれど
* STRUCT_DYNA(int (*)()) はだめです。
*/
#define STRUCT_DYNA(TYPE) \
{ \
unsigned int more, size, used; \
TYPE *buf; \
TYPE *spare; \
}
/*
* NAME
* DYNA_IZ - 構造体の初期化
*
* SYNOPSIS
* void DYNA_IZ(struct DYNA *dyna, unsigned int nmore);
*
* DESCRIPTION
* 構造体を初期化します。
* dyna には STRUCT_DYNA で宣言した構造体のアドレスを与えます。
* nmore には一度に増加する要素の数を指定します。
*
* EXAMPLE
* struct LIST_BUF STRUCT_DYNA(char *) list_buf;
* の時、
* DYNA_IZ(&list_buf, 64);
* のように初期化します。
*/
#define DYNA_IZ(dyna, nmore) ((void)( \
(dyna)->more = (nmore), \
(dyna)->used = (dyna)->size = 0, \
(dyna)->buf = (void *)0 \
))
/*
* NAME
* DYNA_BRK - 配列の拡大
*
* SYNOPSIS
* TYPE *DYNA_BRK(struct DYNA *dyna, unsigned int nmore);
*
* DESCRIPTION
* 構造体の配列を nmore 個だけ拡大します。
* DYNA_NEXT() が自動的に実行するので普通は関係ありません。
* 成功なら NULL 以外を返し、失敗なら NULL を返します。
*
* EXAMPLE
* struct LIST_BUF STRUCT_DYNA(char *) list_buf;
* DYNA_IZ(&list_buf, 64);
* の時、
* if (DYNA_BRK(&list_buf, 16) == NULL)
* goto no_memory;
* などとします。
*/
#define DYNA_BRK(dyna, nmore) ( \
(dyna)->spare = (dyna)->buf, \
(dyna)->size += (nmore), \
(dyna)->buf = realloc((dyna)->buf, (dyna)->size * sizeof((dyna)->buf[0])), \
(((dyna)->buf != (void *)0) ? (dyna)->buf \
: ((dyna)->buf = (dyna)->spare, \
(dyna)->size -= (nmore), \
(void *)0)) \
)
/*
* NAME
* DYNA_NEXT - バッファの拡大
*
* SYNOPSIS
* TYPE *DYNA_NEXT(struct DYNA *dyna);
*
* DESCRIPTION
* 配列の新しい要素のアドレスを返します。
* 使用領域が 1 増えます。
* 足りない場合は DYNA_BRK() を呼び出します。
* 失敗なら NULL を返します。
*
* EXAMPLE
* struct LIST_BUF STRUCT_DYNA(char *)list_buf;
* char **next;
* DYNA_IZ(&list_buf, 64);
* の時、
* if ((next = DYNA_NEXT(&list_buf)) == NULL)
* goto no_memory;
* *next = malloc(256);
* などとします。
*/
#define DYNA_NEXT(dyna) ( \
((dyna)->used >= (dyna)->size && DYNA_BRK(dyna, \
((dyna)->more ? (dyna)->more : 256)) == (void *)0) \
? (void *)0 \
: (dyna)->buf + (dyna)->used++ \
)
/*
* NAME
* DYNA_ALLOC - バッファの拡大
*
* SYNOPSIS
* TYPE *DYNA_ALLOC(struct DYNA *dyna, unsigned int n);
*
* DESCRIPTION
* 配列の中の新しい n 個の連続した要素のアドレスを返します。
* 使用領域が n 増えます。
* 足りない場合は DYNA_BRK() を呼び出します。
* 失敗なら NULL を返します。
*
* EXAMPLE
* struct CHAR_BUF STRUCT_DYNA(char) char_buf;
* char *next;
* DYNA_IZ(&char_buf, 256);
* の時、
* if ((next = DYNA_ALLOC(&char_buf, strlen(s) + 1)) == NULL)
* goto no_memory;
* strcpy(next, s);
* などとします。
*/
#define DYNA_ALLOC(dyna, nmore) ( \
((dyna)->used + (nmore) > (dyna)->size && DYNA_BRK(dyna, (dyna)->more + (nmore)) == (void *)0) \
? ((void *)0)\
: ((dyna)->used += (nmore), (dyna)->buf + (dyna)->used - (nmore))\
)
/*
* NAME
* DYNA_RESET - バッファを空にする
*
* SYNOPSIS
* void DYNA_RESET(struct DYNA *dyna)
*
* DESCRIPTION
* バッファを空にします(使用領域を 0 にします)。
* dyna には STRUCT_DYNA で宣言した構造体のアドレスを与えます。
*/
#define DYNA_RESET(dyna) ((void)((dyna)->used = 0))
/*
* NAME
* DYNA_UNGROW - バッファの縮小
*
* SYNOPSIS
* void DYNA_UNGROW(struct DYNA *dyna, unsigned int n);
*
* DESCRIPTION
* バッファの大きさ(使用領域)が 0 でなければ、n 要素分縮小します。
*
*/
#define DYNA_UNGROW(dyna, n) ((void)((dyna)->used > (n) ? ((dyna)->used -= (n)) : ((dyna)->used = 0)))
/*
* NAME
* DYNA_BUF - バッファのアドレス
*
* SYNOPSIS
* TYPE *DYNA_BUF(struct DYNA *dyna);
*
* DESCRIPTION
* バッファの最初の要素のアドレスを返します。
* DYNA_BRK() や DYNA_NEXT() によって値が変化しますので、
* それらを呼び出した後は以前の値は無効になります。
*/
#define DYNA_BUF(dyna) ((dyna)->buf)
/*
* NAME
* DYNA_USED - バッファの大きさ
*
* SYNOPSIS
* unsigned int DYNA_USED(struct DYNA *dyna);
*
* DESCRIPTION
* バッファの大きさを返します。
* DYNA_IZ() 直後は 0 で、
* DYNA_NEXT() する毎に + 1 します。
*/
#define DYNA_USED(dyna) ((dyna)->used)
#endif /* ] !__DYNA_H */
syntax highlighted by Code2HTML, v. 0.9.1