Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/cut.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/coreutils/cut.c
r1765 r2725 5 5 * Copyright (C) 1999,2000,2001 by Lineo, inc. 6 6 * Written by Mark Whitley <markw@codepoet.org> 7 * debloated by Bernhard Fischer7 * debloated by Bernhard Reutner-Fischer 8 8 * 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.9 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 10 10 */ 11 11 … … 17 17 /* option vars */ 18 18 static const char optstring[] ALIGN1 = "b:c:f:d:sn"; 19 #define CUT_OPT_BYTE_FLGS (1<<0) 20 #define CUT_OPT_CHAR_FLGS (1<<1) 21 #define CUT_OPT_FIELDS_FLGS (1<<2) 22 #define CUT_OPT_DELIM_FLGS (1<<3) 23 #define CUT_OPT_SUPPRESS_FLGS (1<<4) 24 25 static char delim = '\t'; /* delimiter, default is tab */ 19 #define CUT_OPT_BYTE_FLGS (1 << 0) 20 #define CUT_OPT_CHAR_FLGS (1 << 1) 21 #define CUT_OPT_FIELDS_FLGS (1 << 2) 22 #define CUT_OPT_DELIM_FLGS (1 << 3) 23 #define CUT_OPT_SUPPRESS_FLGS (1 << 4) 26 24 27 25 struct cut_list { … … 36 34 }; 37 35 38 /* growable array holding a series of lists */39 static struct cut_list *cut_lists;40 static unsigned int nlists; /* number of elements in above list */41 42 43 36 static int cmpfunc(const void *a, const void *b) 44 37 { 45 38 return (((struct cut_list *) a)->startpos - 46 39 ((struct cut_list *) b)->startpos); 47 48 40 } 49 41 50 static void cut_file(FILE * file)42 static void cut_file(FILE *file, char delim, const struct cut_list *cut_lists, unsigned nlists) 51 43 { 52 char *line = NULL;53 unsigned intlinenum = 0; /* keep these zero-based to be consistent */44 char *line; 45 unsigned linenum = 0; /* keep these zero-based to be consistent */ 54 46 55 47 /* go through every line in the file */ 56 while ((line = xmalloc_ getline(file)) != NULL) {48 while ((line = xmalloc_fgetline(file)) != NULL) { 57 49 58 50 /* set up a list so we can keep track of what's been printed */ 59 char * printed = xzalloc(strlen(line) * sizeof(char)); 60 char * orig_line = line; 61 unsigned int cl_pos = 0; 51 int linelen = strlen(line); 52 char *printed = xzalloc(linelen + 1); 53 char *orig_line = line; 54 unsigned cl_pos = 0; 62 55 int spos; 63 56 … … 67 60 for (; cl_pos < nlists; cl_pos++) { 68 61 spos = cut_lists[cl_pos].startpos; 69 while (spos < strlen(line)) {62 while (spos < linelen) { 70 63 if (!printed[spos]) { 71 64 printed[spos] = 'X'; … … 74 67 spos++; 75 68 if (spos > cut_lists[cl_pos].endpos 76 || cut_lists[cl_pos].endpos == NON_RANGE) 69 /* NON_RANGE is -1, so if below is true, 70 * the above was true too (spos is >= 0) */ 71 /* || cut_lists[cl_pos].endpos == NON_RANGE */ 72 ) { 77 73 break; 74 } 78 75 } 79 76 } … … 83 80 /* get out if we have no more lists to process or if the lines 84 81 * are lower than what we're interested in */ 85 if ( linenum < spos || cl_pos >= nlists)82 if (((int)linenum < spos) || (cl_pos >= nlists)) 86 83 goto next_line; 87 84 88 85 /* if the line we're looking for is lower than the one we were 89 86 * passed, it means we displayed it already, so move on */ 90 while (spos < linenum) {87 while (spos < (int)linenum) { 91 88 spos++; 92 89 /* go to the next list if we're at the end of this one */ 93 90 if (spos > cut_lists[cl_pos].endpos 94 || cut_lists[cl_pos].endpos == NON_RANGE) { 91 || cut_lists[cl_pos].endpos == NON_RANGE 92 ) { 95 93 cl_pos++; 96 94 /* get out if there's no more lists to process */ … … 100 98 /* get out if the current line is lower than the one 101 99 * we just became interested in */ 102 if ( linenum < spos)100 if ((int)linenum < spos) 103 101 goto next_line; 104 102 } … … 113 111 int nfields_printed = 0; 114 112 char *field = NULL; 115 const char delimiter[2] = { delim, 0 }; 113 char delimiter[2]; 114 115 delimiter[0] = delim; 116 delimiter[1] = 0; 116 117 117 118 /* does this line contain any delimiters? */ … … 151 152 * list */ 152 153 } while (spos <= cut_lists[cl_pos].endpos && line 153 154 && cut_lists[cl_pos].endpos != NON_RANGE); 154 155 } 155 156 } … … 164 165 } 165 166 166 static const char _op_on_field[] ALIGN1 = " only when operating on fields"; 167 168 int cut_main(int argc, char **argv); 169 int cut_main(int argc, char **argv) 167 int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 168 int cut_main(int argc UNUSED_PARAM, char **argv) 170 169 { 170 /* growable array holding a series of lists */ 171 struct cut_list *cut_lists = NULL; 172 unsigned nlists = 0; /* number of elements in above list */ 173 char delim = '\t'; /* delimiter, default is tab */ 171 174 char *sopt, *ltok; 175 unsigned opt; 172 176 173 177 opt_complementary = "b--bcf:c--bcf:f--bcf"; 174 getopt32(argv, optstring, &sopt, &sopt, &sopt, <ok);178 opt = getopt32(argv, optstring, &sopt, &sopt, &sopt, <ok); 175 179 // argc -= optind; 176 180 argv += optind; 177 if (!(opt ion_mask32& (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))181 if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) 178 182 bb_error_msg_and_die("expected a list of bytes, characters, or fields"); 179 183 180 if (opt ion_mask32& CUT_OPT_DELIM_FLGS) {181 if ( strlen(ltok) > 1) {184 if (opt & CUT_OPT_DELIM_FLGS) { 185 if (ltok[0] && ltok[1]) { /* more than 1 char? */ 182 186 bb_error_msg_and_die("the delimiter must be a single character"); 183 187 } … … 186 190 187 191 /* non-field (char or byte) cutting has some special handling */ 188 if (!(option_mask32 & CUT_OPT_FIELDS_FLGS)) { 189 if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) { 192 if (!(opt & CUT_OPT_FIELDS_FLGS)) { 193 static const char _op_on_field[] ALIGN1 = " only when operating on fields"; 194 195 if (opt & CUT_OPT_SUPPRESS_FLGS) { 190 196 bb_error_msg_and_die 191 197 ("suppressing non-delimited lines makes sense%s", … … 207 213 int s = 0, e = 0; 208 214 209 /* take apart the lists, one by one (they are separated with commas */215 /* take apart the lists, one by one (they are separated with commas) */ 210 216 while ((ltok = strsep(&sopt, ",")) != NULL) { 211 217 212 218 /* it's actually legal to pass an empty list */ 213 if ( strlen(ltok) == 0)219 if (!ltok[0]) 214 220 continue; 215 221 216 222 /* get the start pos */ 217 223 ntok = strsep(<ok, "-"); 218 if (ntok == NULL) { 219 bb_error_msg 220 ("internal error: ntok is null for start pos!?\n"); 221 } else if (strlen(ntok) == 0) { 224 if (!ntok[0]) { 222 225 s = BOL; 223 226 } else { 224 s = xatoi_ u(ntok);227 s = xatoi_positive(ntok); 225 228 /* account for the fact that arrays are zero based, while 226 229 * the user expects the first char on the line to be char #1 */ … … 230 233 231 234 /* get the end pos */ 232 ntok = strsep(<ok, "-"); 233 if (ntok == NULL) { 235 if (ltok == NULL) { 234 236 e = NON_RANGE; 235 } else if ( strlen(ntok) == 0) {237 } else if (!ltok[0]) { 236 238 e = EOL; 237 239 } else { 238 e = xatoi_ u(ntok);239 /* if the user specified and end position of 0, that means "til the240 * end of the line*/240 e = xatoi_positive(ltok); 241 /* if the user specified and end position of 0, 242 * that means "til the end of the line" */ 241 243 if (e == 0) 242 244 e = EOL; … … 246 248 } 247 249 248 /* if there's something left to tokenize, the user passed249 * an invalid list */250 if (ltok)251 bb_error_msg_and_die("invalid byte or field list");252 253 250 /* add the new list */ 254 cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); 255 cut_lists[nlists-1].startpos = s; 256 cut_lists[nlists-1].endpos = e; 251 cut_lists = xrealloc_vector(cut_lists, 4, nlists); 252 /* NB: startpos is always >= 0, 253 * while endpos may be = NON_RANGE (-1) */ 254 cut_lists[nlists].startpos = s; 255 cut_lists[nlists].endpos = e; 256 nlists++; 257 257 } 258 258 … … 264 264 * easier on us when it comes time to print the chars / fields / lines 265 265 */ 266 qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); 267 } 268 269 /* argv[0..argc-1] should be names of file to process. If no 270 * files were specified or '-' was specified, take input from stdin. 271 * Otherwise, we process all the files specified. */ 272 if (argv[0] == NULL || LONE_DASH(argv[0])) { 273 cut_file(stdin); 274 } else { 275 FILE *file; 266 qsort(cut_lists, nlists, sizeof(cut_lists[0]), cmpfunc); 267 } 268 269 { 270 int retval = EXIT_SUCCESS; 271 272 if (!*argv) 273 *--argv = (char *)"-"; 276 274 277 275 do { 278 file = fopen_or_warn(argv[0], "r"); 279 if (file) { 280 cut_file(file); 281 fclose(file); 282 } 276 FILE *file = fopen_or_warn_stdin(*argv); 277 if (!file) { 278 retval = EXIT_FAILURE; 279 continue; 280 } 281 cut_file(file, delim, cut_lists, nlists); 282 fclose_if_not_stdin(file); 283 283 } while (*++argv); 284 } 285 if (ENABLE_FEATURE_CLEAN_UP) 286 free(cut_lists); 287 return EXIT_SUCCESS; 284 285 if (ENABLE_FEATURE_CLEAN_UP) 286 free(cut_lists); 287 fflush_stdout_and_exit(retval); 288 } 288 289 }
Note:
See TracChangeset
for help on using the changeset viewer.