1
2 static char rcsid[] = "@(#)$Id: prlong.c,v 1.4 1996/03/14 17:30:11 wfp5p Exp $";
3
4 /*******************************************************************************
5 * The Elm Mail System - $Revision: 1.4 $
6 *
7 * Copyright (c) 1988-1995 USENET Community Trust
8 * Copyright (c) 1986,1987 Dave Taylor
9 *******************************************************************************
10 * Bug reports, patches, comments, suggestions should be sent to:
11 *
12 * Bill Pemberton, Elm Coordinator
13 * flash@virginia.edu
14 *
15 *******************************************************************************
16 * $Log: prlong.c,v $
17 * Revision 1.4 1996/03/14 17:30:11 wfp5p
18 * Alpha 9
19 *
20 * Revision 1.3 1995/09/29 17:42:47 wfp5p
21 * Alpha 8 (Chip's big changes)
22 *
23 * Revision 1.2 1995/04/20 21:02:09 wfp5p
24 * Added the showreply feature and emacs key bindings.
25 *
26 * Revision 1.1.1.1 1995/04/19 20:38:41 wfp5p
27 * Initial import of elm 2.4 PL0 as base for elm 2.5.
28 *
29 ******************************************************************************/
30
31
32 /*
33 * Format large amounts of output, folding across multiple lines.
34 *
35 * Input is read in a line at a time, and the input records are joined
36 * together into output records up to a maximum line width. A field
37 * seperator is placed between every input record, and a configurable
38 * leader is printed at the front of each line. The default field
39 * seperator is a single space. The default output leader is an empty
40 * string for the first output line, and a single tab for all subsequent
41 * lines.
42 *
43 * Usage:
44 *
45 * prlong [-w wid] [-1 first_leader] [-l leader] [-f sep] < data
46 *
47 * Options:
48 *
49 * -w wid Maximum output line width.
50 * -1 leader Leader for the first line of output.
51 * -l leader Leader for all subsequent lines of output.
52 * -f sep Field seperator.
53 *
54 * Example:
55 *
56 * $ elmalias -en friends | /usr/lib/elm/prlong -w40
57 * tom@sleepy.acme.com (Tom Smith)
58 * dick@dopey.acme.com (Dick Jones)
59 * harry@grumpy.acme.com
60 * $ elmalias -en friends | /usr/lib/elm/prlong -w40 -1 "To: " -f ", "
61 * To: tom@sleepy.acme.com (Tom Smith),
62 * dick@dopey.acme.com (Dick Jones),
63 * harry@grumpy.acme.com
64 */
65
66
67 #include "elm_defs.h"
68
69 #define MAXWID 78 /* default maximum line width */
70 #define ONE_LDR "" /* default leader for first line */
71 #define DFLT_LDR "\t" /* default leader for other lines */
72 #define FLDSEP " " /* default field seperator */
73
74 char inbuf[1024]; /* space to hold an input record */
75 char outbuf[4096]; /* space to accumulate output record */
76
77 int calc_col(); /* calculate output column position */
78
79
usage_error(prog)80 void usage_error(prog)
81 char *prog;
82 {
83 fprintf(stderr,
84 "usage: %s [-w wid] [-1 first_leader] [-l leader] [-f sep]\n", prog);
85 exit(1);
86 }
87
88
main(argc,argv)89 main(argc, argv)
90 int argc;
91 char *argv[];
92 {
93 char *one_ldr; /* output leader to use on first line */
94 char *dflt_ldr; /* output leader for subsequent lines */
95 char *fld_sep; /* selected field seperator */
96 char *curr_sep; /* text to output before next field */
97 int maxwid; /* maximum output line width */
98 int outb_col; /* current column pos in output rec */
99 int outb_len; /* current length of output record */
100 int i;
101 extern int optind;
102 extern char *optarg;
103
104 /*
105 * Initialize defaults.
106 */
107 maxwid = MAXWID;
108 one_ldr = ONE_LDR;
109 dflt_ldr = DFLT_LDR;
110 fld_sep = FLDSEP;
111
112 /*
113 * Crack command line.
114 */
115 while ((i = getopt(argc, argv, "w:1:l:f:")) != EOF) {
116 switch (i) {
117 case 'w': maxwid = atoi(optarg); break;
118 case '1': one_ldr = optarg; break;
119 case 'l': dflt_ldr = optarg; break;
120 case 'f': fld_sep = optarg; break;
121 default: usage_error(argv[0]);
122 }
123 }
124 if (optind != argc)
125 usage_error(argv[0]);
126
127 /*
128 * Initialize output buffer.
129 */
130 (void) strfcpy(outbuf, one_ldr, sizeof(outbuf));
131 outb_col = calc_col(0, one_ldr);
132 outb_len = strlen(one_ldr);
133 curr_sep = "";
134
135 /*
136 * Process the input a line at a time.
137 */
138 while (fgets(inbuf, sizeof(inbuf), stdin) != NULL) {
139
140 /*
141 * Trim trailing space. Skip blank lines.
142 */
143 for (i = strlen(inbuf) - 1 ; i >= 0 && isspace(inbuf[i]) ; --i)
144 ;
145 inbuf[i+1] = '\0';
146 if (inbuf[0] == '\0')
147 continue;
148
149 /*
150 * If this text exceeds the line length then print the stored
151 * info and reset the line.
152 */
153 if (calc_col(calc_col(outb_col, curr_sep), inbuf) >= maxwid) {
154 printf("%s%s\n", outbuf, curr_sep);
155 curr_sep = dflt_ldr;
156 outb_col = 0;
157 outb_len = 0;
158 outbuf[0] = '\0';
159 }
160
161 /*
162 * Append the current field seperator to the stored info.
163 */
164 (void) strfcpy(outbuf+outb_len, curr_sep, sizeof(outbuf)-outb_len);
165 outb_col = calc_col(outb_col, outbuf+outb_len);
166 outb_len += strlen(outbuf+outb_len);
167
168 /*
169 * Append the text to the stored info.
170 */
171 (void) strfcpy(outbuf+outb_len, inbuf, sizeof(outbuf)-outb_len);
172 outb_col = calc_col(outb_col, outbuf+outb_len);
173 outb_len += strlen(outbuf+outb_len);
174
175 /*
176 * Enable the field seperator.
177 */
178 curr_sep = fld_sep;
179
180 }
181
182 if (*outbuf != '\0')
183 puts(outbuf);
184 exit(0);
185 }
186
187
calc_col(col,s)188 int calc_col(col, s)
189 register int col;
190 register char *s;
191 {
192 while (*s != '\0') {
193 switch (*s) {
194 case '\b': --col; break;
195 case '\r': col = 0; break;
196 case '\t': col = ((col + 8) & ~7); break;
197 default: ++col; break;
198 }
199 ++s;
200 }
201 return col;
202 }
203
204