crc32/main.c

143 lines
3.1 KiB
C
Raw Normal View History

2012-08-04 05:23:29 -07:00
/* Copyright (C) 2012 Connor Olding
*
* This program is licensed under the terms of the MIT License, and
* is distributed without any warranty. You should have received a
* copy of the license along with this program; see the file LICENSE.
*/
2012-04-13 02:43:39 -07:00
#include <stdio.h>
#include <stdlib.h>
#include "crc32.h"
#include "args.h"
#ifdef _MSC_VER
#define FREOPEN_BLANK ("")
#else
#define FREOPEN_BLANK (NULL)
#endif
static ulong remainder = 0xFFFFFFFF;
2012-04-13 02:43:39 -07:00
static FILE* input_stream = NULL;
2012-04-13 12:54:53 -07:00
static char* input_filename = "-";
2012-04-13 02:43:39 -07:00
static char print_binary = 0;
static char xor_output = 1;
static char reflect_output = 0;
char args_info[] = "crc32 - 32-bit cyclic redundancy check calculator\n";
char args_usage[] = "Usage: %s [-i f] [-s n] [-p n] [-e] [-x] [-r] [-b]\n";
2012-04-21 10:08:48 -07:00
void args_print_help_suffix()
{
puts("\n\
numbers (n) can be entered as hexadecimal or octal with prefixes");
}
2012-04-13 02:43:39 -07:00
2012-04-13 12:54:53 -07:00
const int args_switch_count = 9;
char* args_switches[] = {
2012-04-13 02:43:39 -07:00
"-h","--help"," display this text",
2012-04-13 12:54:53 -07:00
" ","--license"," show copyright & license information",
2012-04-13 02:43:39 -07:00
"-i","--input","f open file f for reading (default: stdin)",
"-s","--start-at","n start cycle with n (default: 0xFFFFFFFF)",
2012-04-13 12:54:53 -07:00
"-p","--polynomial","n use n as the crc divisor (default: 0x04C11DB7)",
2012-04-13 02:43:39 -07:00
"-e","--big-endian"," use big endian calculations (default: little)",
"-b","--binary"," output as binary (default: hex with newline)",
"-x","--xor"," xor the output by 0xFFFFFFFF",
"-r","--reflect"," reverse the bits of the output",
};
2012-04-13 12:54:53 -07:00
void print_license()
{
puts("crc32 Copyright (C) 2012 Connor Olding\n\
This program comes with ABSOLUTELY NO WARRANTY, and is free software.\n\
See the file \"LICENSE\" or <http://gnu.org/licenses/gpl.txt> for details.");
exit(0);
}
2012-04-13 02:43:39 -07:00
void start_at()
{
remainder = strtoul(args_poll(), NULL, 0);
}
void set_input()
{
2012-04-13 12:54:53 -07:00
input_filename = args_poll();
2012-04-13 02:43:39 -07:00
}
void set_polynomial()
{
const int p = strtoul(args_poll(), NULL, 0);
crc_set_polynomial(p);
}
void set_binary()
{
print_binary = 1;
}
void set_xor()
{
xor_output = 0;
}
void set_reflect()
{
reflect_output = 1;
}
void (*args_functions[])() =
2012-04-13 12:54:53 -07:00
{args_print_help, print_license, set_input, start_at, set_polynomial,
2012-04-15 03:41:43 -07:00
crc_set_big_endian, set_binary, set_xor, set_reflect};
2012-04-13 02:43:39 -07:00
static void open_stream()
{
const char mode[] = "rb";
2012-04-13 12:54:53 -07:00
if (!strcmp(input_filename, "-")) {
2012-04-13 02:43:39 -07:00
freopen(FREOPEN_BLANK, mode, stdin);
input_stream = stdin;
} else {
2012-04-13 12:54:53 -07:00
input_stream = fopen(input_filename, mode);
2012-04-13 02:43:39 -07:00
}
if (input_stream == NULL) {
fprintf(stderr, "Could not open file for reading: %s\n",
2012-04-13 12:54:53 -07:00
input_filename);
2012-04-13 02:43:39 -07:00
exit(1);
}
}
static void close_stream()
{
fclose(input_stream);
}
static void cycle_input()
{
int c;
open_stream();
2012-04-15 00:18:44 -07:00
while ((c = getc(input_stream)) != EOF)
2012-04-13 02:43:39 -07:00
crc_cycle(&remainder, c);
close_stream();
if (xor_output)
remainder ^= 0xFFFFFFFF;
if (reflect_output)
remainder = crc_reflect(remainder);
}
static void print_crc()
{
if (print_binary)
fwrite(&remainder, sizeof(remainder), 1, stdout);
else
printf("%08X\n", (int) remainder);
}
int main(int argc, char** argv)
{
crc_set_little_endian();
args_handle(argc, argv);
cycle_input();
print_crc();
return 0;
}