# include "lex.h"
# include "ppstr.h"
/*
* A string utility for the preprocessor.
*/
# define SCHUNKSZ 8
typedef struct _schunk_ {
struct _schunk_ *next; /* next in list */
str s[SCHUNKSZ]; /* chunk of pp strings */
} schunk;
static schunk *slist; /* list of pps string chunks */
static int schunksz; /* size of current chunk */
static str *flist; /* list of free pp strings */
/*
* NAME: str->init()
* DESCRIPTION: initialize string handling
*/
void pps_init()
{
slist = (schunk *) NULL;
schunksz = SCHUNKSZ;
flist = (str *) NULL;
}
/*
* NAME: str->clear()
* DESCRIPTION: finish string handling
*/
void pps_clear()
{
register schunk *l, *f;
for (l = slist; l != (schunk *) NULL; ) {
f = l;
l = l->next;
FREE(f);
}
slist = (schunk *) NULL;
}
/*
* NAME: str->new()
* DESCRIPTION: make a new string with length 0.
*/
str *pps_new(buf, sz)
char *buf;
int sz;
{
register str *sb;
if (flist != (str *) NULL) {
/* from free list */
sb = flist;
flist = (str *) sb->buffer;
} else {
/* allocate new string */
if (schunksz == SCHUNKSZ) {
register schunk *l;
l = ALLOC(schunk, 1);
l->next = slist;
slist = l;
schunksz = 0;
}
sb = &slist->s[schunksz++];
}
sb->buffer = buf;
sb->buffer[0] = '\0';
sb->size = sz;
sb->len = 0;
return sb;
}
/*
* NAME: str->del()
* DESCRIPTION: delete a string
*/
void pps_del(sb)
str *sb;
{
sb->buffer = (char *) flist;
flist = sb;
}
/*
* NAME: str->scat()
* DESCRIPTION: append a string. The length becomes -1 if the result is too long
*/
int pps_scat(sb, s)
register str *sb;
char *s;
{
register int l;
if (sb->len < 0 || sb->len + (l = strlen(s)) >= sb->size) {
return sb->len = -1;
}
strcpy(sb->buffer + sb->len, s);
return sb->len += l;
}
/*
* NAME: str->ccat()
* DESCRIPTION: append a char. The length becomes -1 if the result is too long
*/
int pps_ccat(sb, c)
register str *sb;
int c;
{
if (sb->len < 0 || c == '\0' || sb->len + 1 >= sb->size) {
return sb->len = -1;
}
sb->buffer[sb->len++] = c;
sb->buffer[sb->len] = '\0';
return sb->len;
}