Update to LGPL v2.1.
[jlayton/glibc.git] / stdio / linewrap.h
1 /* Word-wrapping and line-truncating streams.
2    Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #ifndef __LINEWRAP_H__
21 #define __LINEWRAP_H__
22
23 #include <stdio.h>
24 #include <ctype.h>
25 #include <string.h>
26
27 #include <features.h>
28
29 #include <string.h>             /* Need size_t.  */
30
31 __BEGIN_DECLS
32
33 /* We keep this data for each line-wrapping stream.  */
34 struct line_wrap_data
35   {
36     size_t lmargin, rmargin;    /* Left and right margins.  */
37     ssize_t wmargin;            /* Margin to wrap to, or -1 to truncate.  */
38
39     /* Point in stdio buffer to which we've processed for wrapping, but
40        not output.  */
41     size_t point_offs;
42     /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin.  */
43     ssize_t point_col;
44
45     /* Original cookie and hooks from the stream.  */
46     void *cookie;
47     void (*output) (FILE *, int);
48     __io_close_fn *close;
49     __io_fileno_fn *fileno;
50     __io_seek_fn *seek;
51   };
52 \f
53 /* Modify STREAM so that it prefixes lines written on it with LMARGIN spaces
54    and limits them to RMARGIN columns total.  If WMARGIN >= 0, words that
55    extend past RMARGIN are wrapped by replacing the whitespace before them
56    with a newline and WMARGIN spaces.  Otherwise, chars beyond RMARGIN are
57    simply dropped until a newline.  Returns STREAM after modifying it, or
58    NULL if there was an error.  */
59 FILE *line_wrap_stream (FILE *stream,
60                         size_t lmargin, size_t rmargin, ssize_t wmargin);
61
62 /* Remove the hooks placed in STREAM by `line_wrap_stream'.  */
63 void line_unwrap_stream (FILE *stream);
64
65 /* Returns true if STREAM is line wrapped.  */
66 extern inline int line_wrapped (FILE *stream);
67
68 /* If STREAM is not line-wrapped return -1, else return its left margin.  */
69 extern size_t line_wrap_lmargin (FILE *stream);
70
71 /* If STREAM is not line-wrapped return -1, else set its left margin to
72    LMARGIN and return the old value.  */
73 extern size_t line_wrap_set_lmargin (FILE *stream, size_t lmargin);
74
75 /* If STREAM is not line-wrapped return -1, else return its left margin.  */
76 extern size_t line_wrap_rmargin (FILE *stream);
77
78 /* If STREAM is not line-wrapped return -1, else set its right margin to
79    RMARGIN and return the old value.  */
80 extern size_t line_wrap_set_rmargin (FILE *stream, size_t rmargin);
81
82 /* If STREAM is not line-wrapped return -1, else return its wrap margin.  */
83 extern size_t line_wrap_wmargin (FILE *stream);
84
85 /* If STREAM is not line-wrapped return -1, else set its left margin to
86    WMARGIN and return the old value.  */
87 extern size_t line_wrap_set_wmargin (FILE *stream, size_t wmargin);
88
89 /* If STREAM is not line-wrapped return -1, else return the column number of
90    the current output point.  */
91 extern size_t line_wrap_point (FILE *stream);
92
93 #ifdef  __OPTIMIZE__
94
95 extern void __line_wrap_output (FILE *, int); /* private */
96
97 /* If STREAM is not line-wrapped, return 0.  Otherwise all pending text
98    buffered text in STREAM so that the POINT_OFFS field refers to the last
99    position in the stdio buffer, and return the line wrap state object for
100    STREAM.  Since all text has been processed, this means that (1) the
101    POINT_COL field refers to the column at which any new text would be added,
102    and (2) any changes to the margin parameters will only affect new text.  */
103 extern struct line_wrap_data *__line_wrap_update (FILE *stream); /* private */
104
105 /* Returns true if STREAM is line wrapped.  */
106 extern inline int
107 line_wrapped (FILE *stream)
108 {
109   return (stream->__room_funcs.__output == &__line_wrap_output);
110 }
111
112 /* If STREAM is not line-wrapped return -1, else return its left margin.  */
113 extern inline size_t
114 line_wrap_lmargin (FILE *stream)
115 {
116   if (! line_wrapped (stream))
117     return -1;
118   return ((struct line_wrap_data *)stream->__cookie)->lmargin;
119 }
120
121 /* If STREAM is not line-wrapped return -1, else set its left margin to
122    LMARGIN and return the old value.  */
123 extern inline size_t
124 line_wrap_set_lmargin (FILE *stream, size_t lmargin)
125 {
126   struct line_wrap_data *d = __line_wrap_update (stream);
127   if (d)
128     {
129       size_t old = d->lmargin;
130       d->lmargin = lmargin;
131       return old;
132     }
133   else
134     return -1;
135 }
136
137 /* If STREAM is not line-wrapped return -1, else return its left margin.  */
138 extern inline size_t
139 line_wrap_rmargin (FILE *stream)
140 {
141   if (! line_wrapped (stream))
142     return -1;
143   return ((struct line_wrap_data *)stream->__cookie)->rmargin;
144 }
145
146 /* If STREAM is not line-wrapped return -1, else set its right margin to
147    RMARGIN and return the old value.  */
148 extern inline size_t
149 line_wrap_set_rmargin (FILE *stream, size_t rmargin)
150 {
151   struct line_wrap_data *d = __line_wrap_update (stream);
152   if (d)
153     {
154       size_t old = d->rmargin;
155       d->rmargin = rmargin;
156       return old;
157     }
158   else
159     return -1;
160 }
161
162 /* If STREAM is not line-wrapped return -1, else return its wrap margin.  */
163 extern inline size_t
164 line_wrap_wmargin (FILE *stream)
165 {
166   if (! line_wrapped (stream))
167     return -1;
168   return ((struct line_wrap_data *)stream->__cookie)->wmargin;
169 }
170
171 /* If STREAM is not line-wrapped return -1, else set its left margin to
172    WMARGIN and return the old value.  */
173 extern inline size_t
174 line_wrap_set_wmargin (FILE *stream, size_t wmargin)
175 {
176   struct line_wrap_data *d = __line_wrap_update (stream);
177   if (d)
178     {
179       size_t old = d->wmargin;
180       d->wmargin = wmargin;
181       return old;
182     }
183   else
184     return -1;
185 }
186
187 /* If STREAM is not line-wrapped return -1, else return the column number of
188    the current output point.  */
189 extern inline size_t
190 line_wrap_point (FILE *stream)
191 {
192   struct line_wrap_data *d = __line_wrap_update (stream);
193   return d ? (d->point_col >= 0 ? d->point_col : 0) : -1;
194 }
195
196 #endif /* Optimizing.  */
197
198 __END_DECLS
199
200 #endif /* __LINEWRAP_H__ */