#include #include #include void printhelp(char *callname) { printf("bintime - show the current time of day in binary format\n"); printf("Usage: %s [-dsvh]\n\n", callname); printf(" -d, --decimal Show decimal numbers along with the binary ones\n"); printf(" -s, --seconds Show seconds along with hours and minutes\n"); printf(" -v, --version Print the version of bintime and exit\n"); printf(" -h, --help Print this help and exit\n"); } void dec2binstr(int in, char *out, int outlen) { /* See http://en.wikipedia.org/wiki/Binary_numeral_system#Decimal for the * * principle of the conversion algorithm used here. */ char *outend = out + outlen; /* Initialize a pointer to do the */ *outend = '\0'; /* string from behind and insert */ /* the ASCII 0 at the end */ while (in) { /* Fill wih binary digits from LSB to MSB */ outend--; switch (in % 2) { case 0: *outend = '0'; break; case 1: *outend = '1'; break; } in = in / 2; } while (outend > out) { /* Fill with '0's until beginning of out */ outend--; *outend = '0'; } } int main(int argc, char *argv[]) { /* --- Declarations for getopt_long.h functionality ------------------- */ int opt_seconds = 0; int opt_decimal = 0; struct option longoptions[] = { {"decimal", no_argument, 0, 'd'}, {"seconds", no_argument, 0, 's'}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'} }; int longoptions_i = 0; signed char c; /* --- Declarations for time.h functionality ---------------------------*/ time_t curtime; struct tm *timedata; /* --- My own humble declarations --------------------------------------*/ int twelve_hour; char bin_hour[5]; /* only four digits for the hour */ char bin_min[7]; char bin_sec[7]; /* For a better idea of how getopt_long is used, you'd better check out * * http://www.gnu.org/software/libc/manual/html_node/Getopt.html along * * with my code here. They do it differently and more intelligible IMHO.*/ while(1) { if ((c = getopt_long(argc, argv, "dsvh", longoptions, &longoptions_i)) == -1) { break; } switch (c) { case 0: break; case 'd': opt_decimal = 1; break; case 's': opt_seconds = 1; break; case 'v': printf("bintime 0.0.1\n"); return 0; break; case 'h': printhelp(argv[0]); return 0; break; case '?': default: printhelp(argv[0]); return 1; break; } } curtime = time(0); /* Getting system time and making it 12h*/ timedata = localtime(&curtime); twelve_hour = timedata->tm_hour; if (twelve_hour > 12) { twelve_hour -= 12; } dec2binstr(twelve_hour, bin_hour, 4); dec2binstr(timedata->tm_min, bin_min, 6); if (opt_seconds) { dec2binstr(timedata->tm_sec, bin_sec, 6); } /* I thought a lot about how to do this and I've decided to rather go * * with a bunch of printf(); lines than to do some kind of smartass * * printf("%s %s\n", bin_min, dec_min) black voodoo thing, because * * that would involve initializing an empty dec_min string and then * * filling it if needed. And since this is C and not Perl, that would * * be Shooting Myself In The Foot(tm) big time. */ if (opt_decimal) { if (timedata->tm_hour < 10) { printf(" %s (0%ih)\n", bin_hour, timedata->tm_hour); } else { printf(" %s (%ih)\n", bin_hour, timedata->tm_hour); } if (timedata->tm_min < 10) { printf("%s (0%im)\n", bin_min, timedata->tm_min); } else { printf("%s (%im)\n", bin_min, timedata->tm_min); } if (opt_seconds) { if (timedata->tm_sec < 10) { printf("%s (0%is)\n", bin_sec, timedata->tm_sec); } else { printf("%s (%is)\n", bin_sec, timedata->tm_sec); } } } else { /* Life's much easier without decimal! */ printf(" %s\n%s\n", bin_hour, bin_min); if (opt_seconds) { printf("%s\n", bin_sec); } } return 0; }