about summary refs log tree commit diff
path: root/stdio/linewrap.h
blob: 2ecb387e73ad32bc15fd5c7a11d65e1ca12a82d8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* Word-wrapping and line-truncating streams.
   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#ifndef __LINEWRAP_H__
#define __LINEWRAP_H__

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <features.h>

#include <string.h>		/* Need size_t.  */

__BEGIN_DECLS

/* We keep this data for each line-wrapping stream.  */
struct line_wrap_data
  {
    size_t lmargin, rmargin;	/* Left and right margins.  */
    ssize_t wmargin;		/* Margin to wrap to, or -1 to truncate.  */

    /* Point in stdio buffer to which we've processed for wrapping, but
       not output.  */
    size_t point_offs;
    /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin.  */
    ssize_t point_col;

    /* Original cookie and hooks from the stream.  */
    void *cookie;
    void (*output) (FILE *, int);
    __io_close_fn *close;
    __io_fileno_fn *fileno;
    __io_seek_fn *seek;
  };

/* Modify STREAM so that it prefixes lines written on it with LMARGIN spaces
   and limits them to RMARGIN columns total.  If WMARGIN >= 0, words that
   extend past RMARGIN are wrapped by replacing the whitespace before them
   with a newline and WMARGIN spaces.  Otherwise, chars beyond RMARGIN are
   simply dropped until a newline.  Returns STREAM after modifying it, or
   NULL if there was an error.  */
FILE *line_wrap_stream (FILE *stream,
			size_t lmargin, size_t rmargin, ssize_t wmargin);

/* Remove the hooks placed in STREAM by `line_wrap_stream'.  */
void line_unwrap_stream (FILE *stream);

/* Returns true if STREAM is line wrapped.  */
extern inline int line_wrapped (FILE *stream);

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern size_t line_wrap_lmargin (FILE *stream);

/* If STREAM is not line-wrapped return -1, else set its left margin to
   LMARGIN and return the old value.  */
extern size_t line_wrap_set_lmargin (FILE *stream, size_t lmargin);

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern size_t line_wrap_rmargin (FILE *stream);

/* If STREAM is not line-wrapped return -1, else set its right margin to
   RMARGIN and return the old value.  */
extern size_t line_wrap_set_rmargin (FILE *stream, size_t rmargin);

/* If STREAM is not line-wrapped return -1, else return its wrap margin.  */
extern size_t line_wrap_wmargin (FILE *stream);

/* If STREAM is not line-wrapped return -1, else set its left margin to
   WMARGIN and return the old value.  */
extern size_t line_wrap_set_wmargin (FILE *stream, size_t wmargin);

/* If STREAM is not line-wrapped return -1, else return the column number of
   the current output point.  */
extern size_t line_wrap_point (FILE *stream);

#ifdef	__OPTIMIZE__

extern void __line_wrap_output (FILE *, int); /* private */

/* If STREAM is not line-wrapped, return 0.  Otherwise all pending text
   buffered text in STREAM so that the POINT_OFFS field refers to the last
   position in the stdio buffer, and return the line wrap state object for
   STREAM.  Since all text has been processed, this means that (1) the
   POINT_COL field refers to the column at which any new text would be added,
   and (2) any changes to the margin parameters will only affect new text.  */
extern struct line_wrap_data *__line_wrap_update (FILE *stream); /* private */

/* Returns true if STREAM is line wrapped.  */
extern inline int
line_wrapped (FILE *stream)
{
  return (stream->__room_funcs.__output == &__line_wrap_output);
}

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern inline size_t
line_wrap_lmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->lmargin;
}

/* If STREAM is not line-wrapped return -1, else set its left margin to
   LMARGIN and return the old value.  */
extern inline size_t
line_wrap_set_lmargin (FILE *stream, size_t lmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->lmargin;
      d->lmargin = lmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern inline size_t
line_wrap_rmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->rmargin;
}

/* If STREAM is not line-wrapped return -1, else set its right margin to
   RMARGIN and return the old value.  */
extern inline size_t
line_wrap_set_rmargin (FILE *stream, size_t rmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->rmargin;
      d->rmargin = rmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return its wrap margin.  */
extern inline size_t
line_wrap_wmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->wmargin;
}

/* If STREAM is not line-wrapped return -1, else set its left margin to
   WMARGIN and return the old value.  */
extern inline size_t
line_wrap_set_wmargin (FILE *stream, size_t wmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->wmargin;
      d->wmargin = wmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return the column number of
   the current output point.  */
extern inline size_t
line_wrap_point (FILE *stream)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  return d ? (d->point_col >= 0 ? d->point_col : 0) : -1;
}

#endif /* Optimizing.  */

__END_DECLS

#endif /* __LINEWRAP_H__ */