Skip to content

Instantly share code, notes, and snippets.

@isometry
Created January 28, 2018 21:23
Show Gist options
  • Save isometry/eb9bf91c346e9cba5f058376f9cb5a04 to your computer and use it in GitHub Desktop.
Save isometry/eb9bf91c346e9cba5f058376f9cb5a04 to your computer and use it in GitHub Desktop.
Flex implementation of the standard wc(1) utility
%{
#include <sys/types.h>
#include <unistd.h>
char **files;
int cfile, nfile;
int dochar = 0, doword = 0, doline = 0;
unsigned long charct = 0, wordct = 0, linect = 0;
unsigned long tcharct = 0, twordct = 0, tlinect = 0;
int yywrap(void);
static void usage(void);
%}
LINE \n
WORD [^\n\t ]+
%%
{LINE} { ++charct; ++linect; }
{WORD} { charct += yyleng; ++wordct; }
. { charct += yyleng; }
%%
int main(int argc, char *argv[]) {
int ch;
while ((ch = getopt(argc, argv, "clw")) != -1)
switch((char)ch) {
case 'c':
dochar = 1; break;
case 'w':
doword = 1; break;
case 'l':
doline = 1; break;
case '?':
default:
usage();
}
files = argv += optind;
nfile = argc -= optind;
if (dochar + doword + doline == 0)
dochar = doword = doline = 1;
if (nfile == 0) {
yyin = stdin;
} else if (nfile == 1) {
if (!(yyin = fopen(files[0], "r")))
exit(1);
cfile = 1;
} else {
yywrap();
}
yylex();
if (nfile > 1) {
if (doline) (void)printf(" %7ld", tlinect);
if (doword) (void)printf(" %7ld", twordct);
if (dochar) (void)printf(" %7ld", tcharct);
(void)printf(" total\n");
} else {
if (doline) (void)printf(" %7ld", linect);
if (doword) (void)printf(" %7ld", wordct);
if (dochar) (void)printf(" %7ld", charct);
if (yyin != stdin)
(void)printf(" %s\n", files[0]);
else
(void)printf("\n");
}
return 0;
}
int yywrap(void) {
FILE *file = NULL;
if ((cfile != 0) && (nfile > 1) && (cfile < nfile)) {
if (doline) (void)printf(" %7ld", linect);
if (doword) (void)printf(" %7ld", wordct);
if (dochar) (void)printf(" %7ld", charct);
(void)printf(" %s\n", files[cfile-1]);
tcharct += charct;
twordct += wordct;
tlinect += linect;
charct = wordct = linect = 0;
fclose(yyin);
}
while (files[cfile] != NULL) {
if ((file = fopen(files[cfile++], "r"))) {
yyin = file;
break;
} else
fprintf(stderr,"Error: %s\n", files[cfile-1]);
}
return (file ? 0 : 1);
}
static void usage(void) {
(void)fprintf(stderr, "usage: iwc [-clw] [file]\n");
exit(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment