/* option vars */
static const char optstring[] = "b:c:f:d:sn";
-
#define CUT_OPT_BYTE_FLGS (1<<0)
#define CUT_OPT_CHAR_FLGS (1<<1)
#define CUT_OPT_FIELDS_FLGS (1<<2)
#define CUT_OPT_DELIM_FLGS (1<<3)
#define CUT_OPT_SUPPRESS_FLGS (1<<4)
-static unsigned opt;
static char delim = '\t'; /* delimiter, default is tab */
unsigned int linenum = 0; /* keep these zero-based to be consistent */
/* go through every line in the file */
- while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
+ while ((line = xmalloc_getline(file)) != NULL) {
/* set up a list so we can keep track of what's been printed */
char * printed = xzalloc(strlen(line) * sizeof(char));
int spos;
/* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
- if ((opt & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS))) {
+ if (option_mask32 & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS)) {
/* print the chars specified in each cut list */
for (; cl_pos < nlists; cl_pos++) {
spos = cut_lists[cl_pos].startpos;
/* does this line contain any delimiters? */
if (strchr(line, delim) == NULL) {
- if (!(opt & CUT_OPT_SUPPRESS_FLGS))
+ if (!(option_mask32 & CUT_OPT_SUPPRESS_FLGS))
puts(line);
goto next_line;
}
for (; cl_pos < nlists && line; cl_pos++) {
spos = cut_lists[cl_pos].startpos;
do {
-
/* find the field we're looking for */
while (line && ndelim < spos) {
field = strsep(&line, delimiter);
/* if we printed anything at all, we need to finish it with a
* newline cuz we were handed a chomped line */
putchar('\n');
- next_line:
+ next_line:
linenum++;
free(printed);
free(orig_line);
}
}
-static int getval(char *ntok)
-{
- char *junk;
- int i = strtoul(ntok, &junk, 10);
-
- if (*junk != '\0' || i < 0)
- bb_error_msg_and_die("invalid byte or field list");
- return i;
-}
-
-static const char * const _op_on_field = " only when operating on fields";
+static const char _op_on_field[] = " only when operating on fields";
+int cut_main(int argc, char **argv);
int cut_main(int argc, char **argv)
{
char *sopt, *ltok;
opt_complementary = "b--bcf:c--bcf:f--bcf";
- opt = getopt32(argc, argv, optstring, &sopt, &sopt, &sopt, <ok);
- if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
- bb_error_msg_and_die
- ("expected a list of bytes, characters, or fields");
- if (opt & BB_GETOPT_ERROR)
+ getopt32(argc, argv, optstring, &sopt, &sopt, &sopt, <ok);
+// argc -= optind;
+ argv += optind;
+ if (!(option_mask32 & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
+ bb_error_msg_and_die("expected a list of bytes, characters, or fields");
+ if (option_mask32 & BB_GETOPT_ERROR)
bb_error_msg_and_die("only one type of list may be specified");
- if ((opt & (CUT_OPT_DELIM_FLGS))) {
+ if (option_mask32 & CUT_OPT_DELIM_FLGS) {
if (strlen(ltok) > 1) {
bb_error_msg_and_die("the delimiter must be a single character");
}
}
/* non-field (char or byte) cutting has some special handling */
- if (!(opt & CUT_OPT_FIELDS_FLGS)) {
- if (opt & CUT_OPT_SUPPRESS_FLGS) {
+ if (!(option_mask32 & CUT_OPT_FIELDS_FLGS)) {
+ if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) {
bb_error_msg_and_die
("suppressing non-delimited lines makes sense%s",
_op_on_field);
} else if (strlen(ntok) == 0) {
s = BOL;
} else {
- s = getval(ntok);
+ s = xatoi_u(ntok);
/* account for the fact that arrays are zero based, while
* the user expects the first char on the line to be char #1 */
if (s != 0)
} else if (strlen(ntok) == 0) {
e = EOL;
} else {
- e = getval(ntok);
+ e = xatoi_u(ntok);
/* if the user specified and end position of 0, that means "til the
* end of the line */
if (e == 0)
bb_error_msg_and_die("invalid byte or field list");
/* add the new list */
- cut_lists =
- xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists));
- cut_lists[nlists - 1].startpos = s;
- cut_lists[nlists - 1].endpos = e;
+ cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists));
+ cut_lists[nlists-1].startpos = s;
+ cut_lists[nlists-1].endpos = e;
}
/* make sure we got some cut positions out of all that */
qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc);
}
- /* argv[(optind)..(argc-1)] should be names of file to process. If no
+ /* argv[0..argc-1] should be names of file to process. If no
* files were specified or '-' was specified, take input from stdin.
* Otherwise, we process all the files specified. */
- if (argv[optind] == NULL
- || (argv[optind][0] == '-' && argv[optind][1] == '\0')) {
+ if (argv[0] == NULL || LONE_DASH(argv[0])) {
cut_file(stdin);
} else {
FILE *file;
- for (; optind < argc; optind++) {
- file = bb_wfopen(argv[optind], "r");
+ do {
+ file = fopen_or_warn(argv[0], "r");
if (file) {
cut_file(file);
fclose(file);
}
- }
+ } while (*++argv);
}
if (ENABLE_FEATURE_CLEAN_UP)
free(cut_lists);