/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ #ifndef lint static char RCSid[] = "$Header: /home/mjr/hacks/umud/RCS/sbuf.c,v 1.1 92/02/09 22:59:34 mjr Exp $"; #endif /* configure all options BEFORE including system stuff. */ #include "config.h" #include <stdio.h> #include "mud.h" #include "sbuf.h" /* increment to stretch a stretchy buffer by */ #define SBUF_INCR 256 char _sbufgrow(c,b) char c; Sbuf *b; { char *xp; if(b == (Sbuf *)0) return('\0'); if(b->buf == (char *)0) { b->bsiz = SBUF_INCR; if((b->buf = (char *)malloc(b->bsiz)) == (char *)0) return('\0'); b->bc = b->bsiz; b->bp = b->buf; } else { int xoff = (int)(b->bp - b->buf); b->bsiz += SBUF_INCR; /* disaster */ if((xp = (char *)realloc((mall_t)b->buf,(unsigned)b->bsiz)) == (char *)0) { b->bp = (char *)0; b->bc = 0; b->bsiz = 0; return('\0'); } b->buf = xp; b->bp = xp + xoff; b->bc = SBUF_INCR; } b->bc--; return(*(b->bp)++ = c); } /* reset a stretchy buffer to a clean slate. */ void sbuf_reset(b) Sbuf *b; { if(b == (Sbuf *)0 || b->buf == (char *)0) return; /* figure out the average size used so far - DO FIRST! */ if(b->bp != b->buf && b->rct < 100000) { b->avg = ((b->avg * b->rct) + sbuf_len(b)) / (b->rct + 1); b->rct++; } b->bp = b->buf; b->bc = b->bsiz - 1; *(b->bp) = '\0'; /* if the buffer is statistically rather large, free it */ if(b->bsiz > SBUF_INCR && b->bsiz > (b->avg + SBUF_INCR)) { (void)free((mall_t)b->buf); b->bp = b->buf = (char *)0; b->bsiz = 0; b->bc = 0; } } Sbuf * sbuf_new() { Sbuf *b; if((b = (Sbuf *)malloc(sizeof(Sbuf))) == (Sbuf *)0) return((Sbuf *)0); b->bp = (char *)0; b->buf = (char *)0; b->bc = b->bsiz = b->rct = b->avg = 0; return(b); } void sbuf_free(b) Sbuf *b; { if(b == (Sbuf *)0) return; if(b->buf != (char *)0) (void)free((mall_t)b->buf); /* in case some bonehead tries to use one after deallocation :) */ b->bp = b->buf = (char *)0; b->bc = 0; b->bsiz = 0; free((mall_t)b); } void sbuf_freestatic(b) Sbuf *b; { if(b->buf != (char *)0) (void)free((mall_t)b->buf); b->bp = b->buf = (char *)0; b->bc = 0; b->bsiz = 0; } void sbuf_initstatic(b) Sbuf *b; { b->bp = b->buf = (char *)0; b->bc = 0; b->bsiz = 0; b->avg = b->rct = 0; } char * sbuf_strcpy(s,sb) char *s; Sbuf *sb; { sbuf_reset(sb); while(*s != '\0') { sbuf_put(*s,sb); s++; } sbuf_put('\0',sb); return(sbuf_buf(sb)); } char * sbuf_strcat(s,sb) char *s; Sbuf *sb; { /* lose trailing null (if one) */ if(sb->bp > sb->buf && *(sb->bp - 1) == '\0') sbuf_unput(sb); while(*s != '\0') { sbuf_put(*s,sb); s++; } sbuf_put('\0',sb); return(sbuf_buf(sb)); } /* read a line from a Buf into an Sbuf. */ char * sbuf_fgets(s,f) FILE *f; Sbuf *s; { int c; if(f == (FILE *)0 || s == (Sbuf *)0 || ferror(f)) return((char *)0); sbuf_reset(s); while(1) { c = getc(f); if(c == EOF || ferror(f)) { if(s->bp == s->buf) return((char *)0); sbuf_put('\0',s); return(sbuf_buf(s)); } if(c == '\n') { sbuf_put('\0',s); return(sbuf_buf(s)); } sbuf_put(c,s); } }