No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / line_wrap.c
blobafc396397f68c0c99bb0f4660d745a7d143291ea
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* line_wrap 3
6 /* SUMMARY
7 /* wrap long lines upon output
8 /* SYNOPSIS
9 /* #include <line_wrap.h>
11 /* void line_wrap(string, len, indent, output_fn, context)
12 /* const char *buf;
13 /* int len;
14 /* int indent;
15 /* void (*output_fn)(const char *str, int len, int indent, char *context);
16 /* char *context;
17 /* DESCRIPTION
18 /* The \fBline_wrap\fR routine outputs the specified string via
19 /* the specified output function, and attempts to keep output lines
20 /* shorter than the specified length. The routine does not attempt to
21 /* break long words that do not fit on a single line. Upon output,
22 /* trailing whitespace is stripped.
24 /* Arguments
25 /* .IP string
26 /* The input, which cannot contain any newline characters.
27 /* .IP len
28 /* The desired maximal output line length.
29 /* .IP indent
30 /* The desired amount of indentation of the second etc. output lines
31 /* with respect to the first output line. A negative indent causes
32 /* only the first line to be indented; a positive indent causes all
33 /* but the first line to be indented. A zero count causes no indentation.
34 /* .IP output_fn
35 /* The output function that is called with as arguments a string
36 /* pointer, a string length, a non-negative indentation count, and
37 /* application context. A typical implementation looks like this:
38 /* .sp
39 /* .nf
40 /* .na
41 void print(const char *str, int len, int indent, char *context)
43 VSTREAM *fp = (VSTREAM *) context;
45 vstream_fprintf(fp, "%*s%.*s", indent, "", len, str);
47 /* .fi
48 /* .ad
49 /* .IP context
50 /* Application context that is passed on to the output function.
51 /* For example, a VSTREAM pointer, or a structure that contains
52 /* a VSTREAM pointer.
53 /* BUGS
54 /* No tab expansion and no backspace processing.
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 /*--*/
66 /* System library. */
68 #include <sys_defs.h>
69 #include <string.h>
70 #include <ctype.h>
72 /* Utility library. */
74 #include <line_wrap.h>
76 /* line_wrap - wrap long lines upon output */
78 void line_wrap(const char *str, int len, int indent, LINE_WRAP_FN output_fn,
79 char *context)
81 const char *start_line;
82 const char *word;
83 const char *next_word;
84 const char *next_space;
85 int line_len;
86 int curr_len;
87 int curr_indent;
89 if (indent < 0) {
90 curr_indent = -indent;
91 curr_len = len + indent;
92 } else {
93 curr_indent = 0;
94 curr_len = len;
98 * At strategic positions, output what we have seen, after stripping off
99 * trailing blanks.
101 for (start_line = word = str; word != 0; word = next_word) {
102 next_space = word + strcspn(word, " \t");
103 if (word > start_line) {
104 if (next_space - start_line > curr_len) {
105 line_len = word - start_line;
106 while (line_len > 0 && ISSPACE(start_line[line_len - 1]))
107 line_len--;
108 output_fn(start_line, line_len, curr_indent, context);
109 while (*word && ISSPACE(*word))
110 word++;
111 if (start_line == str) {
112 curr_indent += indent;
113 curr_len -= indent;
115 start_line = word;
118 next_word = *next_space ? next_space + 1 : 0;
120 line_len = strlen(start_line);
121 while (line_len > 0 && ISSPACE(start_line[line_len - 1]))
122 line_len--;
123 output_fn(start_line, line_len, curr_indent, context);