Last active
August 29, 2015 14:05
-
-
Save erichschroeter/fc03959197e94a0c104c to your computer and use it in GitHub Desktop.
Generate program for version header.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <getopt.h> | |
#include <time.h> | |
#define VERSION_H \ | |
"#ifndef %s_VERSION_H\n" \ | |
"#define %s_VERSION_H\n" \ | |
"\n" \ | |
"#define %s_VERSION_MAJOR %d\n" \ | |
"#define %s_VERSION_MINOR %d\n" \ | |
"#define %s_VERSION_PATCH %d\n" \ | |
"#define %s_VERSION_BUILD %d\n" \ | |
"#define %s_VERSION_META \"%s\"\n" \ | |
"#define %s_VERSION \"%d.%d.%d.%d%s\"\n" \ | |
"#define %s_COMPILE_DATE \"%s\"\n" \ | |
"#define %s_COMPILE_TIME \"%s\"\n" \ | |
"\n" \ | |
"#endif /* %s_VERSION_H */\n" | |
#define USAGE \ | |
"Usage: %s [-hMmpbaPDTiB]\n" \ | |
"\n" \ | |
"Options:\n" \ | |
" -h, --help Print this menu and exit.\n" \ | |
" -M, --major Major number.\n" \ | |
" -m, --minor Minor number.\n" \ | |
" -p, --patch Patch number.\n" \ | |
" -b, --build Build number.\n" \ | |
" -a, --meta Meta information.\n" \ | |
" -P, --prefix The macro prefix [default: \"%s\"]\n" \ | |
" -D, --date Date format [default: \"%s\"]\n" \ | |
" -T, --time Time format [default: \"%s\"]\n" \ | |
" -i, --auto-build Auto increment build number.\n" \ | |
" -F, --build-file The file containing the build number.\n" \ | |
"\n" | |
int main(int argc, char **argv) | |
{ | |
struct option long_options[] = { | |
{"help", required_argument, NULL, 'h'}, | |
{"major", required_argument, NULL, 'M'}, | |
{"minor", required_argument, NULL, 'm'}, | |
{"patch", required_argument, NULL, 'p'}, | |
{"build", required_argument, NULL, 'b'}, | |
{"meta", required_argument, NULL, 'a'}, | |
{"prefix", required_argument, NULL, 'P'}, | |
{"date", required_argument, NULL, 'D'}, | |
{"time", required_argument, NULL, 'T'}, | |
{"auto-build", no_argument, NULL, 'i'}, | |
{"build-file", required_argument, NULL, 'F'}, | |
}; | |
int major, minor, patch, build, c, auto_inc_build; | |
char *meta, *prefix, *datefmt, *timefmt, *buildfile; | |
time_t timer; | |
struct tm *tm_info; | |
char datestr[32]; | |
char timestr[32]; | |
memset(datestr, 0, sizeof(datestr)); | |
memset(timestr, 0, sizeof(timestr)); | |
major = minor = patch = build = auto_inc_build = 0; | |
meta = ""; | |
prefix = "EXAMPLE"; | |
datefmt = "%Y-%m-%d"; | |
timefmt = "%H:%M:%S"; | |
buildfile = NULL; | |
while ((c = getopt_long(argc, argv, "hM:m:p:b:a:P:D:T:iF:", | |
long_options, 0)) != -1) { | |
switch (c) { | |
case 'h': | |
printf(USAGE, argv[0], prefix, datefmt, timefmt); | |
return 0; | |
case 'M': | |
major = atoi(optarg); | |
break; | |
case 'm': | |
minor = atoi(optarg); | |
break; | |
case 'p': | |
patch = atoi(optarg); | |
break; | |
case 'b': | |
build = atoi(optarg); | |
break; | |
case 'a': | |
meta = optarg; | |
break; | |
case 'P': | |
prefix = optarg; | |
break; | |
case 'D': | |
datefmt = optarg; | |
break; | |
case 'T': | |
timefmt = optarg; | |
break; | |
case 'i': | |
auto_inc_build = 1; | |
break; | |
case 'F': | |
buildfile = optarg; | |
break; | |
case '?': | |
exit(1); | |
} | |
} | |
if (auto_inc_build) { | |
if (buildfile) { | |
/* 65535 builds should be plenty (plus null-terminator) */ | |
char line[17]; | |
FILE *fp = fopen(buildfile, "r"); | |
if (fp == NULL) { | |
/* Don't overwrite build number if we can't | |
* open file; keep the existing value. */ | |
build = build != 0 ? build : 0; | |
} else { | |
fread(line, sizeof(line), 1, fp); | |
build = atoi(line); | |
fclose(fp); | |
} | |
build++; | |
/* Reopen to write new value; Truncate file. */ | |
fp = fopen(buildfile, "w+"); | |
if (fp == NULL) { | |
fprintf(stderr, "%s: %s\n", buildfile, strerror(errno)); | |
exit(1); | |
} | |
/* Overwrite existing build value. */ | |
snprintf(line, sizeof(line), "%d", build); | |
fprintf(fp, "%d", build); | |
fclose(fp); | |
} | |
} | |
time(&timer); | |
tm_info = localtime(&timer); | |
strftime(datestr, sizeof(datestr), datefmt, tm_info); | |
strftime(timestr, sizeof(timestr), timefmt, tm_info); | |
printf(VERSION_H, | |
prefix, | |
prefix, | |
prefix, major, | |
prefix, minor, | |
prefix, patch, | |
prefix, build, | |
prefix, meta, | |
prefix, major, minor, patch, build, meta, | |
prefix, datestr, | |
prefix, timestr, | |
prefix); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment