bin.c (1801B)
1#include <stdlib.h> 2#include <stdio.h> 3#include <string.h> 4#include <stdarg.h> 5 6#define ISFLAG(str, fshort, flong) (!strcmp(str, fshort) || !strcmp(str, flong)) 7 8const char *usage = "USAGE: bin [-r] [-s SKIP] [-n COUNT] [FILE]\n"; 9 10void 11die(const char *fmtstr, ...) 12{ 13 va_list ap; 14 15 va_start(ap, fmtstr); 16 vfprintf(stderr, fmtstr, ap); 17 va_end(ap); 18 19 exit(EXIT_FAILURE); 20} 21 22int 23main(int argc, const char **argv) 24{ 25 unsigned char byte, bit; 26 size_t skip, cnt, pos; 27 const char *filepath; 28 int i, revbyte, cntset; 29 char *end; 30 FILE *f; 31 32 filepath = NULL; 33 cnt = skip = 0; 34 revbyte = 0; 35 cntset = 0; 36 37 for (i = 1; i < argc; i++) { 38 if (ISFLAG(argv[i], "-s", "--skip")) { 39 if (i++ >= argc - 1) goto missing_arg; 40 skip = strtoul(argv[i], &end, 0); 41 if (end && *end) goto bad_arg; 42 } else if (ISFLAG(argv[i], "-n", "--count")) { 43 if (i++ >= argc - 1) goto missing_arg; 44 cnt = strtoul(argv[i], &end, 0); 45 cntset = 1; 46 if (end && *end) goto bad_arg; 47 } else if (ISFLAG(argv[i], "-r", "--revb")) { 48 revbyte = 1; 49 } else if (ISFLAG(argv[i], "-h", "--help")) { 50 die(usage); 51 } else if (*argv[i] == '-') { 52 die("Unknown flag: %s\n", argv[i]); 53 } else if (filepath) { 54 die("Too many files specified\n"); 55 } else { 56 filepath = argv[i]; 57 } 58 } 59 60 if (!filepath) 61 f = stdin; 62 else if (!(f = fopen(filepath, "r"))) 63 die("Failed to open file\n"); 64 65 pos = 0; 66 while (!cntset || pos < skip + cnt) { 67 if (pos % 8 == 0) byte = fgetc(f); 68 if (feof(f)) break; 69 if (pos >= skip) { 70 if (revbyte) 71 bit = (byte >> (pos % 8)) & 1; 72 else 73 bit = (byte >> (7 - pos % 8)) & 1; 74 putchar(bit ? '1' : '0'); 75 } 76 pos += 1; 77 } 78 79 fclose(f); 80 81 return EXIT_SUCCESS; 82 83missing_arg: 84 die("Flag %s expects an argument\n", argv[i]); 85 86bad_arg: 87 die("Argument has unexpected value: %s\n", argv[i]); 88}