/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ /* configure all options BEFORE including system stuff. */ #include "config.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 ((int) b->bsiz > SBUF_INCR && (int) 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 (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); } }