Annotation of /tags/mkinitrd-6_3_0/busybox/coreutils/fold.c
Parent Directory
|
Revision Log
Revision 532 -
(hide annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/coreutils/fold.c
File MIME type: text/plain
File size: 3765 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/coreutils/fold.c
File MIME type: text/plain
File size: 3765 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | niro | 532 | /* vi: set sw=4 ts=4: */ |
2 | /* fold -- wrap each input line to fit in specified width. | ||
3 | |||
4 | Written by David MacKenzie, djm@gnu.ai.mit.edu. | ||
5 | Copyright (C) 91, 1995-2002 Free Software Foundation, Inc. | ||
6 | |||
7 | Modified for busybox based on coreutils v 5.0 | ||
8 | Copyright (C) 2003 Glenn McGrath <bug1@iinet.net.au> | ||
9 | |||
10 | Licensed under the GPL v2 or later, see the file LICENSE in this tarball. | ||
11 | */ | ||
12 | |||
13 | #include "busybox.h" | ||
14 | |||
15 | static unsigned long flags; | ||
16 | #define FLAG_COUNT_BYTES 1 | ||
17 | #define FLAG_BREAK_SPACES 2 | ||
18 | #define FLAG_WIDTH 4 | ||
19 | |||
20 | /* Assuming the current column is COLUMN, return the column that | ||
21 | printing C will move the cursor to. | ||
22 | The first column is 0. */ | ||
23 | |||
24 | static int adjust_column(int column, char c) | ||
25 | { | ||
26 | if (!(flags & FLAG_COUNT_BYTES)) { | ||
27 | if (c == '\b') { | ||
28 | if (column > 0) | ||
29 | column--; | ||
30 | } else if (c == '\r') | ||
31 | column = 0; | ||
32 | else if (c == '\t') | ||
33 | column = column + 8 - column % 8; | ||
34 | else /* if (isprint (c)) */ | ||
35 | column++; | ||
36 | } else | ||
37 | column++; | ||
38 | return column; | ||
39 | } | ||
40 | |||
41 | int fold_main(int argc, char **argv) | ||
42 | { | ||
43 | char *w_opt; | ||
44 | int width = 80; | ||
45 | int i; | ||
46 | int errs = 0; | ||
47 | |||
48 | if (ENABLE_INCLUDE_SUSv2) { | ||
49 | /* Turn any numeric options into -w options. */ | ||
50 | for (i = 1; i < argc; i++) { | ||
51 | char const *a = argv[i]; | ||
52 | |||
53 | if (*a++ == '-') { | ||
54 | if (*a == '-' && !a[1]) | ||
55 | break; | ||
56 | if (isdigit(*a)) { | ||
57 | argv[i] = xasprintf("-w%s", a); | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | |||
63 | flags = getopt32(argc, argv, "bsw:", &w_opt); | ||
64 | if (flags & FLAG_WIDTH) | ||
65 | width = xatoul_range(w_opt, 1, 10000); | ||
66 | |||
67 | argv += optind; | ||
68 | if (!*argv) { | ||
69 | *--argv = "-"; | ||
70 | } | ||
71 | |||
72 | do { | ||
73 | FILE *istream = fopen_or_warn_stdin(*argv); | ||
74 | int c; | ||
75 | int column = 0; /* Screen column where next char will go. */ | ||
76 | int offset_out = 0; /* Index in `line_out' for next char. */ | ||
77 | static char *line_out = NULL; | ||
78 | static int allocated_out = 0; | ||
79 | |||
80 | if (istream == NULL) { | ||
81 | errs |= EXIT_FAILURE; | ||
82 | continue; | ||
83 | } | ||
84 | |||
85 | while ((c = getc(istream)) != EOF) { | ||
86 | if (offset_out + 1 >= allocated_out) { | ||
87 | allocated_out += 1024; | ||
88 | line_out = xrealloc(line_out, allocated_out); | ||
89 | } | ||
90 | |||
91 | if (c == '\n') { | ||
92 | line_out[offset_out++] = c; | ||
93 | fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); | ||
94 | column = offset_out = 0; | ||
95 | continue; | ||
96 | } | ||
97 | |||
98 | rescan: | ||
99 | column = adjust_column(column, c); | ||
100 | |||
101 | if (column > width) { | ||
102 | /* This character would make the line too long. | ||
103 | Print the line plus a newline, and make this character | ||
104 | start the next line. */ | ||
105 | if (flags & FLAG_BREAK_SPACES) { | ||
106 | /* Look for the last blank. */ | ||
107 | int logical_end; | ||
108 | |||
109 | for (logical_end = offset_out - 1; logical_end >= 0; logical_end--) { | ||
110 | if (isblank(line_out[logical_end])) { | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | if (logical_end >= 0) { | ||
115 | /* Found a blank. Don't output the part after it. */ | ||
116 | logical_end++; | ||
117 | fwrite(line_out, sizeof(char), (size_t) logical_end, stdout); | ||
118 | putchar('\n'); | ||
119 | /* Move the remainder to the beginning of the next line. | ||
120 | The areas being copied here might overlap. */ | ||
121 | memmove(line_out, line_out + logical_end, offset_out - logical_end); | ||
122 | offset_out -= logical_end; | ||
123 | for (column = i = 0; i < offset_out; i++) { | ||
124 | column = adjust_column(column, line_out[i]); | ||
125 | } | ||
126 | goto rescan; | ||
127 | } | ||
128 | } else { | ||
129 | if (offset_out == 0) { | ||
130 | line_out[offset_out++] = c; | ||
131 | continue; | ||
132 | } | ||
133 | } | ||
134 | line_out[offset_out++] = '\n'; | ||
135 | fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); | ||
136 | column = offset_out = 0; | ||
137 | goto rescan; | ||
138 | } | ||
139 | |||
140 | line_out[offset_out++] = c; | ||
141 | } | ||
142 | |||
143 | if (offset_out) { | ||
144 | fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); | ||
145 | } | ||
146 | |||
147 | if (ferror(istream) || fclose_if_not_stdin(istream)) { | ||
148 | bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ | ||
149 | errs |= EXIT_FAILURE; | ||
150 | } | ||
151 | } while (*++argv); | ||
152 | |||
153 | fflush_stdout_and_exit(errs); | ||
154 | } |