[net.sources] charb

rusty (06/10/82)

	====> charb.3 <====

	.TH CHARB 3
	.SH NAME
	cballoc, cbrealloc, fgetcb, makcb, cbbuf, cbmax, cbcat, cbncat, cbcpy, cbncpy \- operations for variable length strings
	.SH SYNOPSIS
	.nf
	.PP
	.B #include <local/charb.h>
	.PP
	.B charb *cballoc(n)
	.B unsigned int n;
	.PP
	.B charb *cbrealloc(cb, n)
	.B charb *cb;
	.B unsigned int n;
	.PP
	.B fgetcb(cb, stream)
	.B charb *cb;
	.SM
	.B FILE *stream;
	.PP
	.B charb *makcb(str)
	.B char *str;
	.PP
	.B cbbuf(cb)
	.B charb *cb;
	.PP
	.B cbmax(cb)
	.B charb *cb;
	.PP
	.B charb *cbcat(cb1, cb2)
	.B charb *cb1, *cb2;
	.PP
	.B charb *cbncat(cb1, cb2, n)
	.B charb *cb1, *cb2;
	.PP
	.B char *cbcpy(cb1, cb2)
	.B charb *cb1, *cb2;
	.PP
	.B char *cbncpy(cb1, cb2, n)
	.B charb *cb1, *cb2;
	.fi
	.SH DESCRIPTION
	These functions operate on variable length strings whose
	type is
	.IR charb .
	The definition of
	.I charb
	is in the include file.
	In the cases of copying or concatenation the target
	.IR charb 's
	string buffer size is increased, if necessary, so
	that the result will fit.
	In all cases (except for
	.IR cbncpy ,
	see below) the
	.IR charb 's
	string buffer is null terminated.
	.PP
	.I cballoc
	returns a pointer to a
	.I charb
	whose string buffer is of size
	.IR n .
	.I cbrealloc
	returns a pointer to a
	.I charb
	whose string buffer's size is changed to
	.IR n,
	the previous contents of the string buffer
	are unchanged.
	.PP
	.I fgetcb
	reads a line of characters, up to and and including
	the newline from the
	.I stream
	into
	.IR cb .
	.PP
	.I makcb
	returns a pointer to a
	.I charb
	whose string buffer contains the string pointed
	to by
	.IR str .
	.PP
	.I cbbuf
	yields the string buffer of
	.IR cb .
	.I cbmax
	yields the size of the string buffer of
	.IR cb ,
	this is not necessarily the same as the
	length of the string therein.
	.I cbbuf
	would be used, for example, when one wants
	to
	.B printf(3)
	the
	.IR charb .
	.I cbmax
	isn't normally needed but is provided for
	diagnostice purposes.
	Both are macros.
	.PP
	.I cbcat
	appends a copy of
	.I cb2
	to the end of
	.IR cb1 .
	.I cbncat
	copies at most
	.I n
	characters.
	Both return
	.IR cb1 .
	.PP
	.I cbcpy
	copies
	.I cb2
	to
	.I cb1,
	stopping after the null character has been moved.
	.I cbncpy
	copies exactly
	.I n
	characters,
	truncating or null-padding
	.I cb2;
	the target may not be null-terminated if the size
	of
	.I cb2
	is
	.I n
	or more.
	Both return
	.IR cb1 .
	.SH "SEE ALSO"
	fgets(3), malloc(3), string(3)
	.SH DIAGNOSTICS
	All routines that return a pointer to a
	.I charb
	return NULL upon error (usually running out of memory).
	.I fgetcb
	returns EOF upon end of file or error, otherwise 0.
	.SH BUGS
	The maximum size of a
	.I charb
	string buffer is limited to 65535.

	====> makefile <====

	SRC =		cballoc.c cbcat.c cbcpy.c fgetcb.c makcb.c
	OBJ =		cballoc.o cbcat.o cbcpy.o fgetcb.o makcb.o
	CFLAGS =	-O

	libcb.a:	${OBJ}
			ar uv libcb.a ${OBJ}
			ranlib libcb.a

	${OBJ}:		charb.h

	install:	libcb.a charb.h
			cp libcb.a /usr/local/lib
			cp charb.h /usr/include/local

	clean:
			rm -f *.o errs core libcb.a

	====> charb.h <====

	# ifdef debug
	# define CBINC	1
	# else debug
	# define CBINC	16
	# endif debug

	/*
	 * macros to get at
	 * parts of a charb
	 */
	# define cbbuf(cb)		(cb->c_buf)
	# define cbmax(cb)		(cb->c_max)

	typedef struct {
		unsigned short c_max;
		char *c_buf;
	} charb;

	extern charb *cbrealloc();
	extern charb *cballoc();
	extern charb *cbncat();
	extern charb *cbcat();
	extern charb *cbncpy();
	extern charb *cbcpy();
	extern charb *makcb();

	====> cballoc.c <====

	# include <stdio.h>
	# include "charb.h"

	extern char *realloc();
	extern char *malloc();

	charb *
	cballoc(n)
	unsigned int n;
	{
		register charb *cb;

		if ((cb = (charb *) malloc(sizeof(charb))) == NULL)
			return(NULL);

		if ((cb->c_buf = malloc(n)) == NULL) {
			free((char *) cb);
			return(NULL);
		}

		cb->c_max = n;

		return(cb);
	}

	charb *
	cbrealloc(cb, n)
	charb *cb;
	unsigned int n;
	{
		if ((cb->c_buf = realloc(cb->c_buf, n)) == NULL)
			return(NULL);

		cb->c_max = n;

		return(cb);
	}

	cbfree(cb)
	charb *cb;
	{
		free(cb->c_buf);
		free((char *) cb);
	}

	====> cbcat.c <====

	# include <stdio.h>
	# include "charb.h"

	charb *
	cbcat(cb1, cb2)
	charb *cb1, *cb2;
	{
		register int len1, len2;

		len1 = strlen(cb1->c_buf);
		len2 = strlen(cb2->c_buf);

		if (len1+len2+1 >= cb1->c_max) {
			if ((cb1 = cbrealloc(cb1, len1+len2+1)) == NULL)
				return(NULL);
		}

		strcat(cb1->c_buf, cb2->c_buf);

		return(cb1);
	}

	charb *
	cbncat(cb1, cb2, n)
	charb *cb1, *cb2;
	{
		if (n+1 >= cb1->c_max) {
			if ((cb1 = cbrealloc(cb1, n+1)) == NULL)
				return(NULL);
		}

		strncat(cb1->c_buf, cb2->c_buf, n);

		return(cb1);
	}

	====> cbcpy.c <====

	# include <stdio.h>
	# include "charb.h"

	charb *
	cbcpy(cb1, cb2)
	charb *cb1, *cb2;
	{
		register int len;

		len = strlen(cb2->c_buf);

		if (len+1 >= cb1->c_max) {
			if ((cb1 = cbrealloc(cb1, len+1)) == NULL)
				return(NULL);
		}

		strcpy(cb1->c_buf, cb2->c_buf);

		return(cb1);
	}

	charb *
	cbncpy(cb1, cb2, n)
	charb *cb1, *cb2;
	{
		if (n+1 >= cb1->c_max) {
			if ((cb1 = cbrealloc(cb1, n+1)) == NULL)
				return(NULL);
		}

		strncpy(cb1->c_buf, cb2->c_buf, n);

		return(cb1);
	}

	====> fgetcb.c <====

	# include <stdio.h>
	# include "charb.h"

	/*
	 * read a newline terminated
	 * string from FILE fd into
	 * charb cb.
	 *
	 * returns EOF upon end of file
	 * or error.
	 *
	 * no indication given for lines
	 * not newline terminated.
	 */

	fgetcb(cb, fd)
	register charb *cb;
	FILE *fd;
	{
		register int ch;
		register int i;

		i = 0;
		while ((ch = getc(fd)) != EOF) {
			if (i >= cb->c_max) {
				if ((cb = cbrealloc(cb, i+CBINC)) == NULL)
					return(EOF);
			}

			cb->c_buf[i++] = ch;

			if (ch == '\n')
				break;
		}

		if (i == 0)
			return(EOF);

		if (i >= cb->c_max) {
			if ((cb = cbrealloc(cb, i+CBINC)) == NULL)
				return(EOF);
		}

		cb->c_buf[i] = NULL;

		return(NULL);
	}

	====> makcb.c <====

	# include <stdio.h>
	# include "charb.h"

	charb *
	makcb(str)
	char *str;
	{
		register charb *cb;

		if ((cb = cballoc(strlen(str)+1)) == NULL)
			return(NULL);

		strcpy(cb->c_buf, str);

		return(cb);
	}