bin

Bit stream reader / writer
git clone https://git.sinitax.com/sinitax/bin
Log | Files | Refs | LICENSE | sfeed.txt

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}