aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/cut.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 0fbeff8ea..33aeff6ea 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -86,7 +86,7 @@ static int cmpfunc(const void *a, const void *b)
86} 86}
87 87
88static void cut_file(FILE *file, const char *delim, const char *odelim, 88static void cut_file(FILE *file, const char *delim, const char *odelim,
89 const struct cut_list *cut_lists, unsigned nlists) 89 const struct cut_list *cut_list, unsigned nlists)
90{ 90{
91#define opt_REGEX (option_mask32 & OPT_REGEX) 91#define opt_REGEX (option_mask32 & OPT_REGEX)
92 char *line; 92 char *line;
@@ -110,19 +110,19 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
110 /* print the chars specified in each cut list */ 110 /* print the chars specified in each cut list */
111 for (; cl_pos < nlists; cl_pos++) { 111 for (; cl_pos < nlists; cl_pos++) {
112 int spos; 112 int spos;
113 for (spos = cut_lists[cl_pos].startpos; spos < linelen;) { 113 for (spos = cut_list[cl_pos].startpos; spos < linelen;) {
114 if (!printed[spos]) { 114 if (!printed[spos]) {
115 printed[spos] = 'X'; 115 printed[spos] = 'X';
116 putchar(line[spos]); 116 putchar(line[spos]);
117 } 117 }
118 if (++spos > cut_lists[cl_pos].endpos) { 118 if (++spos > cut_list[cl_pos].endpos) {
119 break; 119 break;
120 } 120 }
121 } 121 }
122 } 122 }
123 free(printed); 123 free(printed);
124 } else if (*delim == '\n') { /* cut by lines */ 124 } else if (*delim == '\n') { /* cut by lines */
125 int spos = cut_lists[cl_pos].startpos; 125 int spos = cut_list[cl_pos].startpos;
126 126
127 /* get out if we have no more lists to process or if the lines 127 /* get out if we have no more lists to process or if the lines
128 * are lower than what we're interested in */ 128 * are lower than what we're interested in */
@@ -134,12 +134,12 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
134 while (spos < (int)linenum) { 134 while (spos < (int)linenum) {
135 spos++; 135 spos++;
136 /* go to the next list if we're at the end of this one */ 136 /* go to the next list if we're at the end of this one */
137 if (spos > cut_lists[cl_pos].endpos) { 137 if (spos > cut_list[cl_pos].endpos) {
138 cl_pos++; 138 cl_pos++;
139 /* get out if there's no more lists to process */ 139 /* get out if there's no more lists to process */
140 if (cl_pos >= nlists) 140 if (cl_pos >= nlists)
141 goto next_line; 141 goto next_line;
142 spos = cut_lists[cl_pos].startpos; 142 spos = cut_list[cl_pos].startpos;
143 /* get out if the current line is lower than the one 143 /* get out if the current line is lower than the one
144 * we just became interested in */ 144 * we just became interested in */
145 if ((int)linenum < spos) 145 if ((int)linenum < spos)
@@ -153,8 +153,8 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
153 goto next_line; 153 goto next_line;
154 } else { /* cut by fields */ 154 } else { /* cut by fields */
155 unsigned next = 0, start = 0, end = 0; 155 unsigned next = 0, start = 0, end = 0;
156 int dcount = 0; /* Nth delimiter we saw (0 - didn't see any yet) */
156 int first_print = 1; 157 int first_print = 1;
157 int dcount = 0;
158 158
159 /* Blank line? Check -s (later check for -s does not catch empty lines) */ 159 /* Blank line? Check -s (later check for -s does not catch empty lines) */
160 if (linelen == 0) { 160 if (linelen == 0) {
@@ -165,12 +165,12 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
165 /* Loop through bytes, finding next delimiter */ 165 /* Loop through bytes, finding next delimiter */
166 for (;;) { 166 for (;;) {
167 /* End of current range? */ 167 /* End of current range? */
168 if (end == linelen || dcount > cut_lists[cl_pos].endpos) { 168 if (end == linelen || dcount > cut_list[cl_pos].endpos) {
169 if (++cl_pos >= nlists) 169 if (++cl_pos >= nlists)
170 break; 170 break;
171 if (option_mask32 & OPT_NOSORT) 171 if (option_mask32 & OPT_NOSORT)
172 start = dcount = next = 0; 172 start = dcount = next = 0;
173 end = 0; 173 end = 0; /* (why?) */
174 } 174 }
175 /* End of current line? */ 175 /* End of current line? */
176 if (next == linelen) { 176 if (next == linelen) {
@@ -178,8 +178,9 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
178 if (cl_pos == 0 && dcount == 0 && !opt_REGEX) { 178 if (cl_pos == 0 && dcount == 0 && !opt_REGEX) {
179 if (option_mask32 & OPT_SUPPRESS) 179 if (option_mask32 & OPT_SUPPRESS)
180 goto next_line; 180 goto next_line;
181 } else if (dcount < cut_lists[cl_pos].startpos) 181 /* else: will print entire line */
182 start = linelen; 182 } else if (dcount < cut_list[cl_pos].startpos)
183 start = linelen; /* do not print */
183 end = linelen; 184 end = linelen;
184 } else { 185 } else {
185 /* Find next delimiter */ 186 /* Find next delimiter */
@@ -200,7 +201,7 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
200 } 201 }
201 202
202 /* Got delimiter. Loop if not yet within range. */ 203 /* Got delimiter. Loop if not yet within range. */
203 if (dcount++ < cut_lists[cl_pos].startpos) { 204 if (dcount++ < cut_list[cl_pos].startpos) {
204 start = next; 205 start = next;
205 continue; 206 continue;
206 } 207 }
@@ -230,7 +231,7 @@ int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
230int cut_main(int argc UNUSED_PARAM, char **argv) 231int cut_main(int argc UNUSED_PARAM, char **argv)
231{ 232{
232 /* growable array holding a series of lists */ 233 /* growable array holding a series of lists */
233 struct cut_list *cut_lists = NULL; 234 struct cut_list *cut_list = NULL;
234 unsigned nlists = 0; /* number of elements in above list */ 235 unsigned nlists = 0; /* number of elements in above list */
235 char *sopt, *ltok; 236 char *sopt, *ltok;
236 const char *delim = NULL; 237 const char *delim = NULL;
@@ -309,10 +310,10 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
309 bb_error_msg_and_die("invalid range %s-%s", ntok, ltok ?: ntok); 310 bb_error_msg_and_die("invalid range %s-%s", ntok, ltok ?: ntok);
310 311
311 /* add the new list */ 312 /* add the new list */
312 cut_lists = xrealloc_vector(cut_lists, 4, nlists); 313 cut_list = xrealloc_vector(cut_list, 4, nlists);
313 /* NB: startpos is always >= 0 */ 314 /* NB: startpos is always >= 0 */
314 cut_lists[nlists].startpos = s; 315 cut_list[nlists].startpos = s;
315 cut_lists[nlists].endpos = e; 316 cut_list[nlists].endpos = e;
316 nlists++; 317 nlists++;
317 } 318 }
318 319
@@ -324,7 +325,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
324 * easier on us when it comes time to print the chars / fields / lines 325 * easier on us when it comes time to print the chars / fields / lines
325 */ 326 */
326 if (!(opt & OPT_NOSORT)) 327 if (!(opt & OPT_NOSORT))
327 qsort(cut_lists, nlists, sizeof(cut_lists[0]), cmpfunc); 328 qsort(cut_list, nlists, sizeof(cut_list[0]), cmpfunc);
328 } 329 }
329 330
330 { 331 {
@@ -339,12 +340,12 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
339 retval = EXIT_FAILURE; 340 retval = EXIT_FAILURE;
340 continue; 341 continue;
341 } 342 }
342 cut_file(file, delim, odelim, cut_lists, nlists); 343 cut_file(file, delim, odelim, cut_list, nlists);
343 fclose_if_not_stdin(file); 344 fclose_if_not_stdin(file);
344 } while (*++argv); 345 } while (*++argv);
345 346
346 if (ENABLE_FEATURE_CLEAN_UP) 347 if (ENABLE_FEATURE_CLEAN_UP)
347 free(cut_lists); 348 free(cut_list);
348 fflush_stdout_and_exit(retval); 349 fflush_stdout_and_exit(retval);
349 } 350 }
350} 351}