updaterevision/updaterevision.c

changeset 632
63e6243b880c
child 659
06c4477675e4
equal deleted inserted replaced
631:93272c0f9a80 632:63e6243b880c
1 /* updaterevision.c
2 *
3 * Public domain. This program uses git commands command to get
4 * various bits of repository status for a particular directory
5 * and writes it into a header file so that it can be used for a
6 * project's versioning.
7 */
8
9 #define _CRT_SECURE_NO_DEPRECATE
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
15 #include <errno.h>
16
17 #ifdef _WIN32
18 #define popen _popen
19 #define pclose _pclose
20 #endif
21
22 // Used to strip newline characters from lines read by fgets.
23 void stripnl(char *str)
24 {
25 if (*str != '\0')
26 {
27 size_t len = strlen(str);
28 if (str[len - 1] == '\n')
29 {
30 str[len - 1] = '\0';
31 }
32 }
33 }
34
35 int main(int argc, char **argv)
36 {
37 char vertag[64], lastlog[64], lasthash[64], *hash = NULL;
38 FILE *stream = NULL;
39 int gotrev = 0, needupdate = 1;
40
41 vertag[0] = '\0';
42 lastlog[0] = '\0';
43
44 if (argc != 2)
45 {
46 fprintf(stderr, "Usage: %s <path to gitinfo.h>\n", argv[0]);
47 return 1;
48 }
49
50 // Use git describe --tags to get a version string. If we are sitting directly
51 // on a tag, it returns that tag. Otherwise it returns <most recent tag>-<number of
52 // commits since the tag>-<short hash>.
53 // Use git log to get the time of the latest commit in ISO 8601 format and its full hash.
54 stream = popen("git describe --tags && git log -1 --format=%ai*%H", "r");
55
56 if (NULL != stream)
57 {
58 if (fgets(vertag, sizeof vertag, stream) == vertag &&
59 fgets(lastlog, sizeof lastlog, stream) == lastlog)
60 {
61 stripnl(vertag);
62 stripnl(lastlog);
63 gotrev = 1;
64 }
65
66 pclose(stream);
67 }
68
69 if (gotrev)
70 {
71 hash = strchr(lastlog, '*');
72 if (hash != NULL)
73 {
74 *hash = '\0';
75 hash++;
76 }
77 }
78 if (hash == NULL)
79 {
80 fprintf(stderr, "Failed to get commit info: %s\n", strerror(errno));
81 strcpy(vertag, "<unknown version>");
82 lastlog[0] = '\0';
83 lastlog[1] = '0';
84 lastlog[2] = '\0';
85 hash = lastlog + 1;
86 }
87
88 stream = fopen (argv[1], "r");
89 if (stream != NULL)
90 {
91 if (!gotrev)
92 { // If we didn't get a revision but the file does exist, leave it alone.
93 fclose (stream);
94 return 0;
95 }
96 // Read the revision that's in this file already. If it's the same as
97 // what we've got, then we don't need to modify it and can avoid rebuilding
98 // dependant files.
99 if (fgets(lasthash, sizeof lasthash, stream) == lasthash)
100 {
101 stripnl(lasthash);
102 if (strcmp(hash, lasthash + 3) == 0)
103 {
104 needupdate = 0;
105 }
106 }
107 fclose (stream);
108 }
109
110 if (needupdate)
111 {
112 stream = fopen (argv[1], "w");
113 if (stream == NULL)
114 {
115 return 1;
116 }
117 fprintf(stream,
118 "// %s\n"
119 "//\n"
120 "// This file was automatically generated by the\n"
121 "// updaterevision tool. Do not edit by hand.\n"
122 "\n"
123 "#define GIT_DESCRIPTION \"%s\"\n"
124 "#define GIT_HASH \"%s\"\n"
125 "#define GIT_TIME \"%s\"\n",
126 hash, vertag, hash, lastlog);
127 fclose(stream);
128 fprintf(stderr, "%s updated to commit %s.\n", argv[1], vertag);
129 }
130 else
131 {
132 fprintf (stderr, "%s is up to date at commit %s.\n", argv[1], vertag);
133 }
134
135 return 0;
136 }

mercurial