stk.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Routines to implement a stack-like storage library
*
* A stack consists of a link list of variable size frames
* The beginning of each frame is initialized with a frame structure
* that contains a pointer to the previous frame and a pointer to the
* end of the current frame.
*
* This is a rewrite of the stk library that uses sfio
*
* David Korn
* AT&T Research
* dgk@research.att.com
*
*/
#include <sfio_t.h>
#include <ast.h>
#include <align.h>
#include <stk.h>
/*
* A stack is a header and a linked list of frames
* The first frame has structure
* Sfio_t
* Sfdisc_t
* struct stk
* Frames have structure
* struct frame
* data
*/
#define STK_ALIGN ALIGN_BOUND
#define STK_FSIZE (1024*sizeof(char*))
typedef char* (*_stk_overflow_)(int);
struct frame
{
char *prev; /* address of previous frame */
char *end; /* address of end this frame */
char **aliases; /* address aliases */
int nalias; /* number of aliases */
};
struct stk
{
short stkref; /* reference count; */
short stkflags; /* stack attributes */
char *stkbase; /* beginning of current stack frame */
char *stkend; /* end of current stack frame */
};
#ifdef STKSTATS
static struct
{
int create;
int delete;
int install;
int alloc;
int copy;
int puts;
int seek;
int set;
int grow;
int addsize;
int delsize;
int movsize;
} _stkstats;
#else
# define increment(x)
# define count(x,n)
#endif /* STKSTATS */
static const char Omsg[] = "malloc failed while growing stack\n";
/*
* default overflow exception
*/
static char *overflow(int n)
{
NoP(n);
exit(2);
/* NOTREACHED */
return(0);
}
/*
* initialize stkstd, sfio operations may have already occcured
*/
{
init = 1;
}
{
switch(type)
{
case SF_CLOSING:
{
{
else
{
while(1)
{
{
}
else
{
break;
}
}
}
}
}
return(0);
case SF_FINAL:
return(1);
case SF_DPOP:
return(-1);
case SF_WRITE:
case SF_SEEK:
{
if(init)
{
return(-1);
if(old)
}
else
}
return(1);
case SF_NEW:
return(-1);
}
return(0);
}
/*
* create a stack
*/
{
register char *cp;
return(0);
#ifndef USE_REALLOC
else
#endif /* USE_REALLOC */
{
return(0);
}
return((Sfio_t*)0);
return(stream);
}
/*
* return a pointer to the current stack
* if <stream> is not null, it becomes the new current stack
* <oflow> becomes the new overflow function
*/
{
if(!init)
{
stkinit(1);
if(oflow)
return((Sfio_t*)0);
}
if(stream)
{
#ifdef USE_REALLOC
/*** someday ***/
#endif /* USE_REALLOC */
}
else
if(oflow)
return(old);
}
/*
* increase the reference count on the given <stack>
*/
{
}
/*
* terminate a stack and free up the space
* >0 returned if reference decremented but still > 0
* 0 returned on last close
* <0 returned on error
*/
{
{
return(1);
}
}
/*
* returns 1 if <loc> is on this stack
*/
{
return(1);
return(0);
}
/*
* reset the bottom of the current stack back to <loc>
* if <loc> is not in this stack, then the stack is reset to the beginning
* otherwise, the top of the stack is set to stkbot+<offset>
*
*/
{
register char *cp;
register int frames = 0;
int n;
if(!init)
while(1)
{
while(n-->0)
{
{
break;
}
}
/* see whether <loc> is in current stack frame */
{
if(frames)
goto found;
}
{
}
else
break;
frames++;
}
/* set stack back to the beginning */
if(frames)
else
}
/*
* allocate <n> bytes on the current stack
*/
{
register unsigned char *old;
if(!init)
stkinit(n);
return(0);
return((char*)old);
}
/*
* begin a new stack word of at least <n> bytes
*/
{
if(!init)
stkinit(n);
return(0);
}
/*
* advance the stack to the current top
* if extra is non-zero, first add a extra bytes and zero the first
*/
{
if(!init)
if(extra)
{
{
return(0);
}
*top = 0;
}
return((char*)old);
}
/*
* copy string <str> onto the stack as a new stack word
*/
{
register size_t n;
if(off)
{
{
{
return(0);
}
}
}
while(*cp++);
if(!init)
stkinit(n);
cp = 0;
else
{
if(off)
{
}
}
return((char*)cp);
}
/*
* add a new stack frame of size >= <n> to the current stack.
* if <n> > 0, copy the bytes from stkbot to stktop to the new stack
* if <n> is zero, then copy the remainder of the stack frame from stkbot
* to the end is copied into the new stack frame
*/
{
char *end=0;
n += (m + sizeof(struct frame)+1);
#ifndef USE_REALLOC
else
#endif /* !USE_REALLOC */
/* see whether current frame can be extended */
{
}
return(0);
{
nn--;
add = 0;
}
else if(dp)
{
}
{
if(add)
}
if(m && !dp)
{
}
}