Postfix3.3.1
vstring_vstream.c
[詳解]
1 /*++
2 /* NAME
3 /* vstring_vstream 3
4 /* SUMMARY
5 /* auto-resizing string library, standard I/O interface
6 /* SYNOPSIS
7 /* #include <vstring_vstream.h>
8 /*
9 /* int vstring_get(vp, fp)
10 /* VSTRING *vp;
11 /* VSTREAM *fp;
12 /*
13 /* int vstring_get_nonl(vp, fp)
14 /* VSTRING *vp;
15 /* VSTREAM *fp;
16 /*
17 /* int vstring_get_null(vp, fp)
18 /* VSTRING *vp;
19 /* VSTREAM *fp;
20 /*
21 /* int vstring_get_bound(vp, fp, bound)
22 /* VSTRING *vp;
23 /* VSTREAM *fp;
24 /* ssize_t bound;
25 /*
26 /* int vstring_get_nonl_bound(vp, fp, bound)
27 /* VSTRING *vp;
28 /* VSTREAM *fp;
29 /* ssize_t bound;
30 /*
31 /* int vstring_get_null_bound(vp, fp, bound)
32 /* VSTRING *vp;
33 /* VSTREAM *fp;
34 /* ssize_t bound;
35 /* DESCRIPTION
36 /* The routines in this module each read one newline or null-terminated
37 /* string from an input stream. In all cases the result is either the
38 /* last character read, typically the record terminator, or VSTREAM_EOF.
39 /*
40 /* vstring_get() reads one line from the named stream, including the
41 /* terminating newline character if present.
42 /*
43 /* vstring_get_nonl() reads a line from the named stream and strips
44 /* the trailing newline character.
45 /*
46 /* vstring_get_null() reads a null-terminated string from the named
47 /* stream.
48 /*
49 /* the vstring_get<whatever>_bound() routines read no more
50 /* than \fIbound\fR characters. Otherwise they behave like the
51 /* unbounded versions documented above.
52 /* DIAGNOSTICS
53 /* Fatal errors: memory allocation failure.
54 /* Panic: improper string bound.
55 /* LICENSE
56 /* .ad
57 /* .fi
58 /* The Secure Mailer license must be distributed with this software.
59 /* AUTHOR(S)
60 /* Wietse Venema
61 /* IBM T.J. Watson Research
62 /* P.O. Box 704
63 /* Yorktown Heights, NY 10598, USA
64 /*--*/
65 
66 /* System library. */
67 
68 #include "sys_defs.h"
69 #include <stdio.h>
70 #include <string.h>
71 
72 /* Application-specific. */
73 
74 #include "msg.h"
75 #include "vstring.h"
76 #include "vstream.h"
77 #include "vstring_vstream.h"
78 
79  /*
80  * Macro to return the last character added to a VSTRING, for consistency.
81  */
82 #define VSTRING_GET_RESULT(vp) \
83  (VSTRING_LEN(vp) > 0 ? vstring_end(vp)[-1] : VSTREAM_EOF)
84 
85 /* vstring_get - read line from file, keep newline */
86 
88 {
89  int c;
90 
91  VSTRING_RESET(vp);
92  while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF) {
93  VSTRING_ADDCH(vp, c);
94  if (c == '\n')
95  break;
96  }
98  return (VSTRING_GET_RESULT(vp));
99 }
100 
101 /* vstring_get_nonl - read line from file, strip newline */
102 
104 {
105  int c;
106 
107  VSTRING_RESET(vp);
108  while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n')
109  VSTRING_ADDCH(vp, c);
110  VSTRING_TERMINATE(vp);
111  return (c == '\n' ? c : VSTRING_GET_RESULT(vp));
112 }
113 
114 /* vstring_get_null - read null-terminated string from file */
115 
117 {
118  int c;
119 
120  VSTRING_RESET(vp);
121  while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0)
122  VSTRING_ADDCH(vp, c);
123  VSTRING_TERMINATE(vp);
124  return (c == 0 ? c : VSTRING_GET_RESULT(vp));
125 }
126 
127 /* vstring_get_bound - read line from file, keep newline, up to bound */
128 
129 int vstring_get_bound(VSTRING *vp, VSTREAM *fp, ssize_t bound)
130 {
131  int c;
132 
133  if (bound <= 0)
134  msg_panic("vstring_get_bound: invalid bound %ld", (long) bound);
135 
136  VSTRING_RESET(vp);
137  while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF) {
138  VSTRING_ADDCH(vp, c);
139  if (c == '\n')
140  break;
141  }
142  VSTRING_TERMINATE(vp);
143  return (VSTRING_GET_RESULT(vp));
144 }
145 
146 /* vstring_get_nonl_bound - read line from file, strip newline, up to bound */
147 
148 int vstring_get_nonl_bound(VSTRING *vp, VSTREAM *fp, ssize_t bound)
149 {
150  int c;
151 
152  if (bound <= 0)
153  msg_panic("vstring_get_nonl_bound: invalid bound %ld", (long) bound);
154 
155  VSTRING_RESET(vp);
156  while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n')
157  VSTRING_ADDCH(vp, c);
158  VSTRING_TERMINATE(vp);
159  return (c == '\n' ? c : VSTRING_GET_RESULT(vp));
160 }
161 
162 /* vstring_get_null_bound - read null-terminated string from file */
163 
164 int vstring_get_null_bound(VSTRING *vp, VSTREAM *fp, ssize_t bound)
165 {
166  int c;
167 
168  if (bound <= 0)
169  msg_panic("vstring_get_null_bound: invalid bound %ld", (long) bound);
170 
171  VSTRING_RESET(vp);
172  while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0)
173  VSTRING_ADDCH(vp, c);
174  VSTRING_TERMINATE(vp);
175  return (c == 0 ? c : VSTRING_GET_RESULT(vp));
176 }
177 
178 #ifdef TEST
179 
180  /*
181  * Proof-of-concept test program: copy the source to this module to stdout.
182  */
183 #include <fcntl.h>
184 
185 #define TEXT_VSTREAM "vstring_vstream.c"
186 
187 int main(void)
188 {
189  VSTRING *vp = vstring_alloc(1);
190  VSTREAM *fp;
191 
192  if ((fp = vstream_fopen(TEXT_VSTREAM, O_RDONLY, 0)) == 0)
193  msg_fatal("open %s: %m", TEXT_VSTREAM);
194  while (vstring_fgets(vp, fp))
196  vstream_fclose(fp);
198  vstring_free(vp);
199  return (0);
200 }
201 
202 #endif
#define vstring_fgets(s, p)
#define VSTREAM_EOF
Definition: vstream.h:110
int vstring_get_null(VSTRING *vp, VSTREAM *fp)
int vstring_get_nonl(VSTRING *vp, VSTREAM *fp)
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define vstring_str(vp)
Definition: vstring.h:71
#define VSTREAM_OUT
Definition: vstream.h:67
int main(int argc, char **argv)
Definition: anvil.c:1010
#define VSTREAM_GETC(vp)
Definition: vstream.h:108
int vstring_get(VSTRING *vp, VSTREAM *fp)
int vstring_get_null_bound(VSTRING *vp, VSTREAM *fp, ssize_t bound)
int vstring_get_nonl_bound(VSTRING *vp, VSTREAM *fp, ssize_t bound)
VSTREAM * vstream_fopen(const char *path, int flags, mode_t mode)
Definition: vstream.c:1241
#define VSTRING_TERMINATE(vp)
Definition: vstring.h:74
#define VSTRING_GET_RESULT(vp)
#define VSTRING_ADDCH(vp, ch)
Definition: vstring.h:81
VSTREAM * vstream_fprintf(VSTREAM *stream, const char *fmt,...)
Definition: vstream.c:1348
int vstream_fclose(VSTREAM *stream)
Definition: vstream.c:1268
#define VSTRING_RESET(vp)
Definition: vstring.h:77
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
int vstring_get_bound(VSTRING *vp, VSTREAM *fp, ssize_t bound)