magic/utils/stack.h

84 lines
2.5 KiB
C

/*
* stack.h --
*
* General purpose stack manipulation routines.
*
* *********************************************************************
* * Copyright (C) 1985, 1990 Regents of the University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*
* Needs to include magic.h
*
* sccsid @(#)stack.h 4.1 MAGIC (Berkeley) 7/4/85
*/
#ifndef _MAGIC__UTILS__STACK_H
#define _MAGIC__UTILS__STACK_H
#include "utils/magic.h"
struct stackBody
{
struct stackBody *sb_next; /* Next block on stack chain */
ClientData sb_data[1]; /* Size determined when malloc'd */
};
/*
* The following macro determines the size of the region to malloc
* for a stack body able to hold sincr elements.
*/
#define sHDRSIZE (sizeof (struct stackBody *))
#define stackSize(sincr) (sHDRSIZE + (sizeof (ClientData)) * (sincr))
typedef struct stack
{
int st_incr; /* Amount by which to grow stack */
ClientData *st_ptr; /* Stack pointer */
struct stackBody *st_body; /* First stack block on chain */
} Stack;
/* --------------------- Procedure headers ---------------------------- */
Stack *StackNew();
ClientData StackPop();
ClientData StackLook();
void StackPush();
void StackFree();
void StackEnum();
void StackCopy();
#define stackBodyEmpty(st) ((st)->st_ptr <= (st)->st_body->sb_data)
/*
* bool StackEmpty(st) Stack *st; returns TRUE if stack is empty
*/
#define StackEmpty(st) (stackBodyEmpty(st) && (st)->st_body->sb_next == NULL)
/*
* Macro interfaces to StackLook(), StackPop(), and StackPush().
*/
#define STACKLOOK(st) \
(stackBodyEmpty(st) ? StackLook(st) : *((st)->st_ptr - 1))
#define STACKPOP(st) \
(stackBodyEmpty(st) ? StackPop(st) : *--((st)->st_ptr))
#define STACKPUSH(a, st) \
if (1) { \
if ((st)->st_ptr >= &(st)->st_body->sb_data[(st)->st_incr]) \
StackPush(a, st); \
else \
*((st)->st_ptr++) = (ClientData)(pointertype) (a); \
} else
#endif /* _MAGIC__UTILS__STACK_H */