static void data_readlines(void) { int i; char current_line[256]; FILE *fp; fp = (inp_stdin) ? stdin : bb_xfopen(filename, "r"); flines = NULL; for (i = 0; (feof(fp)==0) && (i <= MAXLINES); i++) { strcpy(current_line, ""); fgets(current_line, 256, fp); if (fp != stdin) bb_xferror(fp, filename); flines = xrealloc(flines, (i+1) * sizeof(char *)); flines[i] = bb_xstrdup(current_line); } num_flines = i - 2; /* Reset variables for a new file */ line_pos = 0; past_eof = 0; fclose(fp); if (inp == NULL) inp = (inp_stdin) ? bb_xfopen(CURRENT_TTY, "r") : stdin; if (flags & FLAG_N) add_linenumbers(); }
int sort_main(int argc, char **argv) { FILE *fp; char *line, **lines = NULL; int i, nlines = 0, inc; int (*compare)(const void *, const void *) = compare_ascii; int flags; bb_default_error_retval = 2; flags = bb_getopt_ulflags(argc, argv, "nru"); if (flags & 1) { compare = compare_numeric; } argv += optind; if (!*argv) { *--argv = "-"; } do { fp = xgetoptfile_sort_uniq(argv, "r"); while ((line = bb_get_chomped_line_from_file(fp)) != NULL) { lines = xrealloc(lines, sizeof(char *) * (nlines + 1)); lines[nlines++] = line; } bb_xferror(fp, *argv); bb_fclose_nonstdin(fp); } while (*++argv); /* sort it */ qsort(lines, nlines, sizeof(char *), compare); /* print it */ i = 0; --nlines; if ((inc = 1 - (flags & 2)) < 0) { /* reverse */ i = nlines; } flags &= 4; while (nlines >= 0) { if (!flags || !nlines || strcmp(lines[i+inc], lines[i])) { puts(lines[i]); } i += inc; --nlines; } bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int cmp_main(int argc, char **argv) { FILE *fp1, *fp2, *outfile = stdout; const char *filename1, *filename2; const char *fmt; int c1, c2, char_pos, line_pos; int opt_flags; int exit_val = 0; bb_default_error_retval = 2; /* 1 is returned if files are different. */ opt_flags = bb_getopt_ulflags(argc, argv, opt_chars); if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) { bb_show_usage(); } fp1 = cmp_xfopen_input(filename1 = *(argv += optind)); filename2 = "-"; if (*++argv) { filename2 = *argv; } fp2 = cmp_xfopen_input(filename2); if (fp1 == fp2) { /* Paranioa check... stdin == stdin? */ /* Note that we don't bother reading stdin. Neither does gnu wc. * But perhaps we should, so that other apps down the chain don't * get the input. Consider 'echo hello | (cmp - - && cat -)'. */ return 0; } fmt = fmt_differ; if (opt_flags == OPT_l) { fmt = fmt_l_opt; } char_pos = 0; line_pos = 1; do { c1 = getc(fp1); c2 = getc(fp2); ++char_pos; if (c1 != c2) { /* Remember -- a read error may have occurred. */ exit_val = 1; /* But assume the files are different for now. */ if (c2 == EOF) { /* We know that fp1 isn't at EOF or in an error state. But to * save space below, things are setup to expect an EOF in fp1 * if an EOF occurred. So, swap things around. */ fp1 = fp2; filename1 = filename2; c1 = c2; } if (c1 == EOF) { bb_xferror(fp1, filename1); fmt = fmt_eof; /* Well, no error, so it must really be EOF. */ outfile = stderr; /* There may have been output to stdout (option -l), so * make sure we fflush before writing to stderr. */ bb_xfflush_stdout(); } if (opt_flags != OPT_s) { if (opt_flags == OPT_l) { line_pos = c1; /* line_pos is unused in the -l case. */ } bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2); if (opt_flags) { /* This must be -l since not -s. */ /* If we encountered and EOF, the while check will catch it. */ continue; } } break; } if (c1 == '\n') { ++line_pos; } } while (c1 != EOF); bb_xferror(fp1, filename1); bb_xferror(fp2, filename2); bb_fflush_stdout_and_exit(exit_val); }
int uniq_main(int argc, char **argv) { FILE *in, *out; /* Note: Ignore the warning about dups and e0 being used uninitialized. * They will be initialized on the fist pass of the loop (since s0 is NULL). */ unsigned long dups, skip_fields, skip_chars, i; const char *s0, *e0, *s1, *e1, *input_filename; int opt; int uniq_flags = 6; /* -u */ skip_fields = skip_chars = 0; while ((opt = getopt(argc, argv, uniq_opts)) > 0) { if (opt == 'f') { skip_fields = bb_xgetularg10(optarg); } else if (opt == 's') { skip_chars = bb_xgetularg10(optarg); } else if ((s0 = strchr(uniq_opts, opt)) != NULL) { uniq_flags &= s0[4]; uniq_flags |= s0[7]; } else { bb_show_usage(); } } input_filename = *(argv += optind); in = xgetoptfile_sort_uniq(argv, "r"); if (*argv) { ++argv; } out = xgetoptfile_sort_uniq(argv, "w"); if (*argv && argv[1]) { bb_show_usage(); } s0 = NULL; /* gnu uniq ignores newlines */ while ((s1 = bb_get_chomped_line_from_file(in)) != NULL) { e1 = s1; for (i=skip_fields ; i ; i--) { e1 = bb_skip_whitespace(e1); while (*e1 && !isspace(*e1)) { ++e1; } } for (i = skip_chars ; *e1 && i ; i--) { ++e1; } if (s0) { if (strcmp(e0, e1) == 0) { ++dups; /* Note: Testing for overflow seems excessive. */ continue; } DO_LAST: if ((dups && (uniq_flags & 2)) || (!dups && (uniq_flags & 4))) { bb_fprintf(out, "\0%7d\t" + (uniq_flags & 1), dups + 1); bb_fprintf(out, "%s\n", s0); } free((void *)s0); } s0 = s1; e0 = e1; dups = 0; } if (s0) { e1 = NULL; goto DO_LAST; } bb_xferror(in, input_filename); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int uniq_main(int argc, char **argv) { FILE *in, *out; unsigned long dups, skip_fields, skip_chars, i, uniq_flags; const char *s0, *e0, *s1, *e1, *input_filename; int opt; uniq_flags = skip_fields = skip_chars = 0; while ((opt = getopt(argc, argv, uniq_opts)) > 0) { if ((opt == 'f') || (opt == 's')) { int t = bb_xgetularg10(optarg); if (opt == 'f') { skip_fields = t; } else { skip_chars = t; } } else if ((s0 = strchr(uniq_opts, opt)) != NULL) { uniq_flags |= s0[4]; } else { bb_show_usage(); } } input_filename = *(argv += optind); in = xgetoptfile_uniq_s(argv, 0); if (*argv) { ++argv; } out = xgetoptfile_uniq_s(argv, 2); if (*argv && argv[1]) { bb_show_usage(); } s1 = e1 = NULL; /* prime the pump */ do { s0 = s1; e0 = e1; dups = 0; /* gnu uniq ignores newlines */ while ((s1 = bb_get_chomped_line_from_file(in)) != NULL) { e1 = s1; for (i=skip_fields ; i ; i--) { e1 = bb_skip_whitespace(e1); while (*e1 && !isspace(*e1)) { ++e1; } } for (i = skip_chars ; *e1 && i ; i--) { ++e1; } if (!s0 || strcmp(e0, e1)) { break; } ++dups; /* Note: Testing for overflow seems excessive. */ } if (s0) { if (!(uniq_flags & (2 << !!dups))) { bb_fprintf(out, "\0%d " + (uniq_flags & 1), dups + 1); bb_fprintf(out, "%s\n", s0); } free((void *)s0); } } while (s1); bb_xferror(in, input_filename); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }