#include #include #include #include #include #include #include #include "io/read_file.h" #include "util/debug.h" #include "util/error.h" #include "util/loop_files.h" #include "util/versie.h" static int gn, gc; static void usage(FILE *f) { fprintf(f, "Gebruik: staart [-nchV] [BESTAND]...\n" "\n" "Toon de laatste 10 regels van elk BESTAND naar standaard uitvoer\n" "\n" " -n AANTAL Aantal regels om weer te geven\n" " -c AANTAL Aantal karakters om weer te geven\n" " -h Toon deze hulptekst\n" " -V Toon versienummer\n"); } // Returns pointer to argument array containing the file names static char** parse_options(int argc, char **argv, int *n, int *c) { int opt; while ((opt = getopt(argc, argv, "n:c:hV")) != -1) { switch (opt) { case 'c': *c = atoi(optarg); *n = -1; break; case 'n': *c = -1; *n = atoi(optarg); break; case 'h': usage(stdout); exit(0); case 'V': drukkedoos_print_versie(stdout); exit(0); case '?': usage(stderr); exit(1); } } return argv + optind; } static int process(struct filebuf *fb, char*, bool) { // handle byte limits if (gc != -1) { assert(gc >= 0); fwrite(fb->buf+fb->sz-gc, 1, gc, stdout); goto done; } assert(gn >= 0); size_t n = gn; if (fb->buf[fb->sz - 1] == '\n') { // if the file has a trailing newline, we should ignore it. So we should // except one newline more n += 1; } ssize_t i; for (i = fb->sz - 1; i >= 0; i--) { if (fb->buf[i] == '\n') n--; if (n == 0) break; } if (i < 0) { // we haven't encountered the maximum of newlines, write everything fwrite(fb->buf, 1, fb->sz, stdout); goto done; } fwrite(fb->buf + i + 1, 1, fb->sz - i, stdout); done: free_filebuf(fb); return 0; } int entry_staart(int argc, char **argv) { gn = 10; gc = -1; char **args = parse_options(argc, argv, &gn, &gc); return loop_files(args, process); }