From 8050d258f3105e50920392653dffc84e7c612092 Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Wed, 13 Mar 2019 22:01:35 -0400 Subject: migrate to gitlab --- wc.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 wc.c diff --git a/wc.c b/wc.c new file mode 100644 index 0000000..ae1ae03 --- /dev/null +++ b/wc.c @@ -0,0 +1,139 @@ +/* + * UNG's Not GNU + * + * Copyright (c) 2011, Jakob Kaivo + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include +#include + +const char *wc_desc = "word, line, and byte or character count"; +const char *wc_inv = "wc [-c|-m] [-lw] [file...]"; + +#define BYTES 1 << 0 +#define CHARS 1 << 1 +#define LINES 1 << 2 +#define WORDS 1 << 3 + +static unsigned long total_n = 0; +static unsigned long total_w = 0; +static unsigned long total_c = 0; + +int flagprint (unsigned long n, unsigned long w, unsigned long c, char *f, + int flags) +{ + if (flags == 0) flags = LINES | WORDS | CHARS; + + if (flags & LINES) + printf ("%lu%s", n, flags ^ LINES ? " " : ""); + if (flags & WORDS) + printf ("%lu%s", w, flags ^ (LINES | WORDS) ? " " : ""); + if (flags & CHARS || flags & BYTES) + printf ("%lu", c); + // FIXME: What an ass-pain + if (f != NULL) + printf ("%s%s", flags & CHARS || flags & BYTES ? " " : "", f); + printf ("\n"); +} + +int wc (FILE *f, int flags, char *name) +{ + unsigned long newlines = 0; + unsigned long words = 0; + unsigned long charbytes = 0; + int wasword = 0; + int n, i; + char buf[BUFSIZ]; + + while (!feof(f)) { + n = fread (buf, sizeof(char), BUFSIZ, f); + + if (flags & CHARS) { + charbytes += n; // FIXME: wrong, convert to wc_type or mb_char + } else { + charbytes += n; + } + + for (i = 0; i < n; i++) { + if (buf[i] == '\n') { + newlines++; + if (wasword == 0) { + wasword = 1; + words++; + } + } else if (wasword == 0 && isspace(buf[i])) { + wasword = 1; + words++; + } else { + wasword = 0; + } + } + } + + total_n += newlines; + total_w += words; + total_c += charbytes; + + flagprint (newlines, words, charbytes, name, flags); +} + +int +main(int argc, char **argv) +{ + int flags = 0; + int total = 0; + + int c; + while ((c = getopt (argc, argv, ":cmlw")) != -1) { + switch (c) { + case 'c': + if (flags & CHARS) { return 1; } + flags |= BYTES; + break; + case 'm': + if (flags & BYTES) { return 1; } + flags |= CHARS; + break; + case 'l': + flags |= LINES; + break; + case 'w': + flags |= WORDS; + break; + default: + return 1; + } + } + + if (argc - optind > 1) + total = 1; + + if (optind >= argc) { + wc (stdin, flags, NULL); + } else while (optind < argc) { + FILE *in = fopen (argv[optind], "r"); + wc (in, flags, argv[optind]); + fclose (in); + optind++; + } + + if (total) { + flagprint (total_n, total_w, total_c, "total", flags); + } + + return 0; +} -- cgit v1.2.1