NetBSD/gnu/dist/postfix/util/vstring_vstream.c

181 lines
4.2 KiB
C

/*++
/* NAME
/* vstring_vstream 3
/* SUMMARY
/* auto-resizing string library, standard I/O interface
/* SYNOPSIS
/* #include <vstring_vstream.h>
/*
/* int vstring_get(vp, fp)
/* VSTRING *vp;
/* VSTREAM *fp;
/*
/* int vstring_get_nonl(vp, fp)
/* VSTRING *vp;
/* VSTREAM *fp;
/*
/* int vstring_get_null(vp, fp)
/* VSTRING *vp;
/* VSTREAM *fp;
/*
/* int vstring_get_bound(vp, fp, bound)
/* VSTRING *vp;
/* VSTREAM *fp;
/* int bound;
/*
/* int vstring_get_nonl_bound(vp, fp, bound)
/* VSTRING *vp;
/* VSTREAM *fp;
/* int bound;
/* DESCRIPTION
/* The routines in this module each read one newline or null-terminated
/* string from an input stream. In all cases the result is either the
/* last character read, typically the record terminator, or VSTREAM_EOF.
/*
/* vstring_get() reads one line from the named stream, including the
/* terminating newline character if present.
/*
/* vstring_get_nonl() reads a line from the named stream and strips
/* the trailing newline character.
/*
/* vstring_get_null() reads a null-terminated string from the named
/* stream.
/*
/* vstring_get_bound() and vstring_get_nonl_bound() read no more
/* than \fIbound\fR characters. Otherwise they behave like the
/* unbounded versions documented above.
/* DIAGNOSTICS
/* Fatal errors: memory allocation failure.
/* Panic: improper string bound.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include "sys_defs.h"
#include <stdio.h>
#include <string.h>
/* Application-specific. */
#include "msg.h"
#include "vstring.h"
#include "vstream.h"
#include "vstring_vstream.h"
/*
* Macro to return the last character added to a VSTRING, for consistency.
*/
#define VSTRING_GET_RESULT(vp) \
(VSTRING_LEN(vp) > 0 ? vstring_end(vp)[-1] : VSTREAM_EOF)
/* vstring_get - read line from file, keep newline */
int vstring_get(VSTRING *vp, VSTREAM *fp)
{
int c;
VSTRING_RESET(vp);
while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF) {
VSTRING_ADDCH(vp, c);
if (c == '\n')
break;
}
VSTRING_TERMINATE(vp);
return (VSTRING_GET_RESULT(vp));
}
/* vstring_get_nonl - read line from file, strip newline */
int vstring_get_nonl(VSTRING *vp, VSTREAM *fp)
{
int c;
VSTRING_RESET(vp);
while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n')
VSTRING_ADDCH(vp, c);
VSTRING_TERMINATE(vp);
return (c == '\n' ? c : VSTRING_GET_RESULT(vp));
}
/* vstring_get_null - read null-terminated string from file */
int vstring_get_null(VSTRING *vp, VSTREAM *fp)
{
int c;
VSTRING_RESET(vp);
while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0)
VSTRING_ADDCH(vp, c);
VSTRING_TERMINATE(vp);
return (c == 0 ? c : VSTRING_GET_RESULT(vp));
}
/* vstring_get_bound - read line from file, keep newline, up to bound */
int vstring_get_bound(VSTRING *vp, VSTREAM *fp, int bound)
{
int c;
if (bound <= 0)
msg_panic("vstring_get_bound: invalid bound %d", bound);
VSTRING_RESET(vp);
while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF) {
VSTRING_ADDCH(vp, c);
if (c == '\n')
break;
}
VSTRING_TERMINATE(vp);
return (VSTRING_GET_RESULT(vp));
}
/* vstring_get_nonl_bound - read line from file, strip newline, up to bound */
int vstring_get_nonl_bound(VSTRING *vp, VSTREAM *fp, int bound)
{
int c;
if (bound <= 0)
msg_panic("vstring_get_nonl_bound: invalid bound %d", bound);
VSTRING_RESET(vp);
while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n')
VSTRING_ADDCH(vp, c);
VSTRING_TERMINATE(vp);
return (c == '\n' ? c : VSTRING_GET_RESULT(vp));
}
#ifdef TEST
/*
* Proof-of-concept test program: copy the source to this module to stdout.
*/
#include <fcntl.h>
#define TEXT_VSTREAM "vstring_vstream.c"
main(void)
{
VSTRING *vp = vstring_alloc(1);
VSTREAM *fp;
if ((fp = vstream_fopen(TEXT_VSTREAM, O_RDONLY, 0)) == 0)
msg_fatal("open %s: %m", TEXT_VSTREAM);
while (vstring_fgets(vp, fp))
vstream_fprintf(VSTREAM_OUT, "%s", vstring_str(vp));
vstream_fclose(fp);
vstream_fflush(VSTREAM_OUT);
vstring_free(vp);
}
#endif