Postfix3.3.1
line_wrap.c
[詳解]
1 /*++
2 /* NAME
3 /* line_wrap 3
4 /* SUMMARY
5 /* wrap long lines upon output
6 /* SYNOPSIS
7 /* #include <line_wrap.h>
8 /*
9 /* void line_wrap(string, len, indent, output_fn, context)
10 /* const char *buf;
11 /* int len;
12 /* int indent;
13 /* void (*output_fn)(const char *str, int len, int indent, void *context);
14 /* void *context;
15 /* DESCRIPTION
16 /* The \fBline_wrap\fR routine outputs the specified string via
17 /* the specified output function, and attempts to keep output lines
18 /* shorter than the specified length. The routine does not attempt to
19 /* break long words that do not fit on a single line. Upon output,
20 /* trailing whitespace is stripped.
21 /*
22 /* Arguments
23 /* .IP string
24 /* The input, which cannot contain any newline characters.
25 /* .IP len
26 /* The desired maximal output line length.
27 /* .IP indent
28 /* The desired amount of indentation of the second etc. output lines
29 /* with respect to the first output line. A negative indent causes
30 /* only the first line to be indented; a positive indent causes all
31 /* but the first line to be indented. A zero count causes no indentation.
32 /* .IP output_fn
33 /* The output function that is called with as arguments a string
34 /* pointer, a string length, a non-negative indentation count, and
35 /* application context. A typical implementation looks like this:
36 /* .sp
37 /* .nf
38 /* .na
39 void print(const char *str, int len, int indent, void *context)
40 {
41  VSTREAM *fp = (VSTREAM *) context;
42 
43  vstream_fprintf(fp, "%*s%.*s", indent, "", len, str);
44 }
45 /* .fi
46 /* .ad
47 /* .IP context
48 /* Application context that is passed on to the output function.
49 /* For example, a VSTREAM pointer, or a structure that contains
50 /* a VSTREAM pointer.
51 /* BUGS
52 /* No tab expansion and no backspace processing.
53 /* LICENSE
54 /* .ad
55 /* .fi
56 /* The Secure Mailer license must be distributed with this software.
57 /* AUTHOR(S)
58 /* Wietse Venema
59 /* IBM T.J. Watson Research
60 /* P.O. Box 704
61 /* Yorktown Heights, NY 10598, USA
62 /*--*/
63 
64 /* System library. */
65 
66 #include <sys_defs.h>
67 #include <string.h>
68 #include <ctype.h>
69 
70 /* Utility library. */
71 
72 #include <line_wrap.h>
73 
74 /* line_wrap - wrap long lines upon output */
75 
76 void line_wrap(const char *str, int len, int indent, LINE_WRAP_FN output_fn,
77  void *context)
78 {
79  const char *start_line;
80  const char *word;
81  const char *next_word;
82  const char *next_space;
83  int line_len;
84  int curr_len;
85  int curr_indent;
86 
87  if (indent < 0) {
88  curr_indent = -indent;
89  curr_len = len + indent;
90  } else {
91  curr_indent = 0;
92  curr_len = len;
93  }
94 
95  /*
96  * At strategic positions, output what we have seen, after stripping off
97  * trailing blanks.
98  */
99  for (start_line = word = str; word != 0; word = next_word) {
100  next_space = word + strcspn(word, " \t");
101  if (word > start_line) {
102  if (next_space - start_line > curr_len) {
103  line_len = word - start_line;
104  while (line_len > 0 && ISSPACE(start_line[line_len - 1]))
105  line_len--;
106  output_fn(start_line, line_len, curr_indent, context);
107  while (*word && ISSPACE(*word))
108  word++;
109  if (start_line == str) {
110  curr_indent += indent;
111  curr_len -= indent;
112  }
113  start_line = word;
114  }
115  }
116  next_word = *next_space ? next_space + 1 : 0;
117  }
118  line_len = strlen(start_line);
119  while (line_len > 0 && ISSPACE(start_line[line_len - 1]))
120  line_len--;
121  output_fn(start_line, line_len, curr_indent, context);
122 }
void line_wrap(const char *str, int len, int indent, LINE_WRAP_FN output_fn, void *context)
Definition: line_wrap.c:76
void(* LINE_WRAP_FN)(const char *, int, int, void *)
Definition: line_wrap.h:17
#define ISSPACE(c)
Definition: sys_defs.h:1753