Skip to content

Instantly share code, notes, and snippets.

@spedru
Created January 25, 2015 08:15
Show Gist options
  • Save spedru/cf319dde516ecb838de3 to your computer and use it in GitHub Desktop.
Save spedru/cf319dde516ecb838de3 to your computer and use it in GitHub Desktop.
absolutely haram
/*
* binary.c
* by yuuko
*
* This file is intended to never exceed 200 LOC.
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* Version 2, December 2004
*
* Copyright (C) 2004 Sam Hocevar <[email protected]>
*
* Everyone is permitted to copy and distribute verbatim or modified
* copies of this license document, and changing it is allowed as long
* as the name is changed.
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
*
* 0. You just DO WHAT THE FUCK YOU WANT TO.
*/
#include <stdio.h> // Basic I/O
#include <stdlib.h> // strtoul, malloc, free
#include <stdarg.h> // vfprintf for variadic die
#include <getopt.h> // I'll give you 3 guesses
#include <errno.h> // check if input is over length
#include <string.h> // strlen
#include <math.h> // log2
#define BINLEN(T) (sizeof(T) * 8 + 1) // Not inline for typelessness
typedef enum {
OK = EXIT_SUCCESS,
NOARGS = 1,
EMPTYARG = 2,
BADINTARG = 3
} die_code;
static const char *die_strings[] = {
[OK] = "",
[NOARGS] = "You must provide at least one character, string, or "
"octal, decimal, or hexadecimal integer.\n",
[EMPTYARG] = "Argument %d (after %s) is an empty string.\n",
[BADINTARG] = "Argument to option -%c (%s) is not an integer.\n"
};
int die(die_code dc, ...)
{
if(dc) {
fputs("", stderr);
va_list args;
va_start(args, dc);
vfprintf(stderr, die_strings[dc], args);
va_end(args);
}
exit(dc);
}
char *ultonba(size_t ul, size_t n, char *ba)
{
ba[n] = '\0';
while(n) {
ba[--n] = '0' + ul % 2;
ul /= 2;
}
return ba;
}
int main(int argc, char *argv[])
{
size_t pad = 0;
for (int opt; (opt = getopt(argc, argv, "0:h")) != -1;) {
switch(opt) {
case '0':
pad = strtoul(optarg, NULL, 0) + 1;
if(pad || *optarg == '0')
break;
else
die(BADINTARG, opt, optarg);
case 'h':
//help code
case ':':
case '?':
default:
break;
}
}
if(optind == argc) die(NOARGS);
unsigned long in;
size_t len, pos = 0;
char *buf = calloc(len = BINLEN(in), sizeof(*buf));
for (int i = optind; i < argc; i++) {
if ((in = strtoul(argv[i], NULL, 0)) || *argv[i] == '0')
puts(ultonba(in, pad > (pos = (size_t)log2(in) + 1) ? pad : pos, buf));
else if (strlen(argv[i])) {
for (size_t max = strlen(argv[i]); pos < max && argv[i][pos]; pos++) {
printf("%s%c", ultonba(argv[i][pos], 8, buf), argv[i][pos + 1] ? ' ' : '\n');
}
pos = 0;
} else {
free(buf);
die(EMPTYARG, i, argv[i - 1]);
}
}
free(buf);
die(OK);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment