support for multiple inputs

This commit is contained in:
Connor Olding 2012-08-04 09:12:37 -07:00
parent 2eb515f4cf
commit 99e948e5f9

103
main.c
View File

@ -18,10 +18,15 @@
#define FREOPEN_BLANK (NULL) #define FREOPEN_BLANK (NULL)
#endif #endif
static ulong remainder = 0xFFFFFFFF; typedef struct string_node_s string_node;
struct string_node_s {
char *s;
string_node *next;
};
static FILE *input_stream = NULL; static string_node *input_node = NULL;
static char *input_filename = "-";
static ulong starting = 0xFFFFFFFF;
static char print_binary = 0; static char print_binary = 0;
static char xor_output = 1; static char xor_output = 1;
static char reflect_output = 0; static char reflect_output = 0;
@ -29,8 +34,8 @@ static char reflect_output = 0;
static const char help1[] = "\ static const char help1[] = "\
crc32 - a 32-bit cyclic rendundancy check calculator\n\ crc32 - a 32-bit cyclic rendundancy check calculator\n\
\n\ \n\
<files...> open files as inputs\n\
-h display this text\n\ -h display this text\n\
-i <file> open file for reading (default: stdin)\n\
-s <n> start cycle with n (default: 0xFFFFFFFF)\n\ -s <n> start cycle with n (default: 0xFFFFFFFF)\n\
-p <n> use n as the crc divisor (default: 0x04C11DB7)\n\ -p <n> use n as the crc divisor (default: 0x04C11DB7)\n\
-e use big endian calculations\n\ -e use big endian calculations\n\
@ -43,7 +48,16 @@ static const char help2[] = "\
numbers <n> may be entered as hexadecimal or octal with prefixes\n\ numbers <n> may be entered as hexadecimal or octal with prefixes\n\
"; ";
static void handle_flag(char flag, char *(*nextarg)()) { static char *check_next(char flag, char *next) {
if (!next) {
fprintf(stderr, "-%c requires another argument\n", flag);
exit(1);
}
return next;
}
static void handle_flag(char flag, char *(*nextarg)())
{
char *next; char *next;
switch (flag) { switch (flag) {
case 'h': case 'h':
@ -64,18 +78,13 @@ static void handle_flag(char flag, char *(*nextarg)()) {
return; return;
} }
if (!(next = nextarg())) {
fprintf(stderr, "-%c requires another argument\n", flag);
exit(1);
}
switch (flag) { switch (flag) {
case 's': case 's':
remainder = strtoul(next, NULL, 0); next = check_next(flag, nextarg());
break; starting = strtoul(next, NULL, 0);
case 'i':
input_filename = next;
break; break;
case 'p': case 'p':
next = check_next(flag, nextarg());
crc_set_polynomial(strtoul(next, NULL, 0)); crc_set_polynomial(strtoul(next, NULL, 0));
break; break;
default: default:
@ -84,48 +93,50 @@ static void handle_flag(char flag, char *(*nextarg)()) {
} }
} }
static void complain(char *arg) static void add_input(char *arg)
{ {
fprintf(stderr, "Unhandled argument: %s\n", arg); static string_node *last = NULL;
exit(1); string_node *n = calloc(1, sizeof(string_node));
} if (!n) {
fprintf(stderr, "calloc failed\n");
static void open_stream()
{
const char mode[] = "rb";
if (!strcmp(input_filename, "-")) {
freopen(FREOPEN_BLANK, mode, stdin);
input_stream = stdin;
} else {
input_stream = fopen(input_filename, mode);
}
if (input_stream == NULL) {
fprintf(stderr, "Could not open file for reading: %s\n",
input_filename);
exit(1); exit(1);
} }
n->s = arg;
if (!input_node)
input_node = n;
else
last->next = n;
last = n;
} }
static void close_stream() static FILE *open_stream(char *filename)
{ {
fclose(input_stream); FILE *stream = NULL;
stream = fopen(filename, "rb");
if (stream == NULL) {
perror(filename);
exit(1);
}
return stream;
} }
static void cycle_input() static ulong cycle_file(FILE *stream)
{ {
int c; int c;
open_stream(); ulong remainder = starting;
while ((c = getc(input_stream)) != EOF)
while ((c = getc(stream)) != EOF)
crc_cycle(&remainder, c); crc_cycle(&remainder, c);
close_stream();
if (xor_output) if (xor_output)
remainder ^= 0xFFFFFFFF; remainder ^= 0xFFFFFFFF;
if (reflect_output) if (reflect_output)
remainder = crc_reflect(remainder); remainder = crc_reflect(remainder);
return remainder;
} }
static void print_crc() static void print_crc(ulong remainder)
{ {
if (print_binary) if (print_binary)
fwrite(&remainder, sizeof(remainder), 1, stdout); fwrite(&remainder, sizeof(remainder), 1, stdout);
@ -135,9 +146,19 @@ static void print_crc()
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
string_node *n;
crc_set_little_endian(); crc_set_little_endian();
args_parse(argc, argv, handle_flag, complain); args_parse(argc, argv, handle_flag, add_input);
cycle_input();
print_crc(); if (!input_node) {
freopen(FREOPEN_BLANK, "rb", stdin);
print_crc(cycle_file(stdin));
}
for (n = input_node; n; n = n->next) {
FILE *stream = open_stream(n->s);
print_crc(cycle_file(stream));
fclose(stream);
free(n);
}
return 0; return 0;
} }