7 /* auto-resizing string library, standard I/O interface
9 /* #include <vstring_vstream.h>
11 /* int vstring_get(vp, fp)
15 /* int vstring_get_nonl(vp, fp)
19 /* int vstring_get_null(vp, fp)
23 /* int vstring_get_bound(vp, fp, bound)
28 /* int vstring_get_nonl_bound(vp, fp, bound)
33 /* int vstring_get_null_bound(vp, fp, bound)
38 /* The routines in this module each read one newline or null-terminated
39 /* string from an input stream. In all cases the result is either the
40 /* last character read, typically the record terminator, or VSTREAM_EOF.
42 /* vstring_get() reads one line from the named stream, including the
43 /* terminating newline character if present.
45 /* vstring_get_nonl() reads a line from the named stream and strips
46 /* the trailing newline character.
48 /* vstring_get_null() reads a null-terminated string from the named
51 /* the vstring_get<whatever>_bound() routines read no more
52 /* than \fIbound\fR characters. Otherwise they behave like the
53 /* unbounded versions documented above.
55 /* Fatal errors: memory allocation failure.
56 /* Panic: improper string bound.
60 /* The Secure Mailer license must be distributed with this software.
63 /* IBM T.J. Watson Research
65 /* Yorktown Heights, NY 10598, USA
74 /* Application-specific. */
79 #include "vstring_vstream.h"
82 * Macro to return the last character added to a VSTRING, for consistency.
84 #define VSTRING_GET_RESULT(vp) \
85 (VSTRING_LEN(vp) > 0 ? vstring_end(vp)[-1] : VSTREAM_EOF)
87 /* vstring_get - read line from file, keep newline */
89 int vstring_get(VSTRING
*vp
, VSTREAM
*fp
)
94 while ((c
= VSTREAM_GETC(fp
)) != VSTREAM_EOF
) {
99 VSTRING_TERMINATE(vp
);
100 return (VSTRING_GET_RESULT(vp
));
103 /* vstring_get_nonl - read line from file, strip newline */
105 int vstring_get_nonl(VSTRING
*vp
, VSTREAM
*fp
)
110 while ((c
= VSTREAM_GETC(fp
)) != VSTREAM_EOF
&& c
!= '\n')
111 VSTRING_ADDCH(vp
, c
);
112 VSTRING_TERMINATE(vp
);
113 return (c
== '\n' ? c
: VSTRING_GET_RESULT(vp
));
116 /* vstring_get_null - read null-terminated string from file */
118 int vstring_get_null(VSTRING
*vp
, VSTREAM
*fp
)
123 while ((c
= VSTREAM_GETC(fp
)) != VSTREAM_EOF
&& c
!= 0)
124 VSTRING_ADDCH(vp
, c
);
125 VSTRING_TERMINATE(vp
);
126 return (c
== 0 ? c
: VSTRING_GET_RESULT(vp
));
129 /* vstring_get_bound - read line from file, keep newline, up to bound */
131 int vstring_get_bound(VSTRING
*vp
, VSTREAM
*fp
, ssize_t bound
)
136 msg_panic("vstring_get_bound: invalid bound %ld", (long) bound
);
139 while (bound
-- > 0 && (c
= VSTREAM_GETC(fp
)) != VSTREAM_EOF
) {
140 VSTRING_ADDCH(vp
, c
);
144 VSTRING_TERMINATE(vp
);
145 return (VSTRING_GET_RESULT(vp
));
148 /* vstring_get_nonl_bound - read line from file, strip newline, up to bound */
150 int vstring_get_nonl_bound(VSTRING
*vp
, VSTREAM
*fp
, ssize_t bound
)
155 msg_panic("vstring_get_nonl_bound: invalid bound %ld", (long) bound
);
158 while (bound
-- > 0 && (c
= VSTREAM_GETC(fp
)) != VSTREAM_EOF
&& c
!= '\n')
159 VSTRING_ADDCH(vp
, c
);
160 VSTRING_TERMINATE(vp
);
161 return (c
== '\n' ? c
: VSTRING_GET_RESULT(vp
));
164 /* vstring_get_null_bound - read null-terminated string from file */
166 int vstring_get_null_bound(VSTRING
*vp
, VSTREAM
*fp
, ssize_t bound
)
171 msg_panic("vstring_get_nonl_bound: invalid bound %ld", (long) bound
);
174 while (bound
-- > 0 && (c
= VSTREAM_GETC(fp
)) != VSTREAM_EOF
&& c
!= 0)
175 VSTRING_ADDCH(vp
, c
);
176 VSTRING_TERMINATE(vp
);
177 return (c
== 0 ? c
: VSTRING_GET_RESULT(vp
));
183 * Proof-of-concept test program: copy the source to this module to stdout.
187 #define TEXT_VSTREAM "vstring_vstream.c"
191 VSTRING
*vp
= vstring_alloc(1);
194 if ((fp
= vstream_fopen(TEXT_VSTREAM
, O_RDONLY
, 0)) == 0)
195 msg_fatal("open %s: %m", TEXT_VSTREAM
);
196 while (vstring_fgets(vp
, fp
))
197 vstream_fprintf(VSTREAM_OUT
, "%s", vstring_str(vp
));
199 vstream_fflush(VSTREAM_OUT
);