k9core

Coreutils for *nix operating systems [fork]
git clone git://bvnf.space/k9core.git
Log | Files | Refs | LICENSE

wc.c (2266B)


      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int show_lines, show_words, show_bytes;
struct wc_values data;

struct wc_values
{
	int lines;
	int bytes;
	int words;
	int total_lines;
	int total_bytes;
	int total_words;
};

int
wc(const char *filename, struct wc_values *data)
{
	FILE *file = fopen(filename, "r");
	if(file == NULL) {
		fprintf(stderr, "wc: %s: %s\n", filename, strerror(errno));
		return 1;
	}
	size_t c;
	char buf;
	int newlines, spaces, bytes = 0;
	newlines = spaces = bytes = 0;
	while((c = fread(&buf, 1, 1, file)) > 0) {
		if(!isascii(buf))
			buf = toascii(buf);
		bytes++;
		if(buf == '\n')
			newlines++;
		if(isspace(buf))
			spaces++;
	}
	data->bytes = bytes;
	data->lines = newlines;
	data->words = spaces;

	data->total_bytes += data->bytes;
	data->total_lines += data->lines;
	data->total_words += data->words;

	fclose(file);
	return 0;
}

void
print_values(const char *filename, struct wc_values data)
{
	if(show_bytes && show_lines && show_words)
		printf("%i %i %i", data.lines, data.words, data.bytes);
	else {
		if(!show_lines)
			printf("%i ", data.lines);
		if(!show_words)
			printf("%i ", data.words);
		if(!show_bytes)
			printf("%i ", data.bytes);
	}
	printf(" %s\n", filename);
}

int
main(int argc, char *argv[])
{
	int c;
	struct wc_values data;
	data.total_bytes = data.total_lines = data.total_words = 0;
	int return_value = 0; /* Please let me know a better name */
	show_lines = show_words = show_bytes = 1;
	/* Process arguments */
	while((c = getopt(argc, argv, "lwcm")) > 0) {
		switch(c) {
			case 'l':
				show_lines = 0;
				break;
			case 'w':
				show_words = 0;
				break;
			case 'c':
			case 'm':
				show_bytes = 0;
				break;
		}
	}
	if(optind == argc) {
		return_value = wc("/dev/stdin", &data); /* lol */
		print_values("stdin", data);
	} else
		for(int i = optind; i < argc; i++) {
			if(argv[i][0] == '-' && argv[i][1] == '\0')
				return_value = wc("/dev/stdin", &data);
			else
				return_value = wc(argv[i], &data);
			if(return_value == 0)
				print_values(argv[i], data);
		}
	if(argc > optind + 1)
		printf("%i %i %i total\n",
			  data.total_lines,
			  data.total_words,
			  data.total_bytes);

	return return_value;
}