b69e0934b04f3fcb4898f3868afa14e7e7dd0e72
[reactos.git] / reactos / tools / buildno.c
1 /* $Id: buildno.c,v 1.4 2004/01/12 00:22:34 gvg Exp $
2 *
3 * buildno - Generate the build number for ReactOS
4 *
5 * Copyright (c) 1999,2000 Emanuele Aliberti
6 *
7 * The build number is the day on which the build took
8 * place, as YYYYMMDD
9 *
10 * The build number is stored in the file
11 * <reactos/buildno.h> as a set of macros:
12 *
13 * KERNEL_VERSION_BUILD base 10 number
14 * KERNEL_VERSION_BUILD_STR C string
15 * KERNEL_VERSION_BUILD_RC RC string
16 *
17 * REVISIONS
18 * ---------
19 * 2000-01-22 (ea)
20 * Fixed bugs: tm_year is (current_year - 1900),
21 * tm_month is 0-11 not 1-12 and code ignored TZ.
22 * 2000-12-10 (ea)
23 * Added -p option to make it simply print the
24 * version number, but skip buildno.h generation.
25 */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <time.h>
29 #include <string.h>
30 #include "../include/reactos/version.h"
31
32 #define FALSE 0
33 #define TRUE 1
34
35 /* File to (over)write */
36 #define BUILDNO_INCLUDE_FILE "../include/reactos/buildno.h"
37
38 static char * argv0 = "";
39
40 #ifdef DBG
41 void
42 tm_dump (const char *tag, struct tm * t)
43 {
44 printf ("%s->tm_sec = %d\n", tag, t->tm_sec);
45 printf ("%s->tm_min = %d\n", tag, t->tm_min);
46 printf ("%s->tm_hour = %d\n", tag, t->tm_hour);
47 printf ("%s->tm_mday = %d\n", tag, t->tm_mday);
48 printf ("%s->tm_mon = %d\n", tag, t->tm_mon);
49 printf ("%s->tm_year = %d\n", tag, t->tm_year);
50 printf ("%s->tm_wday = %d\n", tag, t->tm_wday);
51 printf ("%s->tm_yday = %d\n", tag, t->tm_yday);
52 printf ("%s->tm_isdst = %d\n\n", tag, t->tm_isdst);
53 }
54 #endif
55
56
57 int
58 elapsed_days (
59 time_t t_today,
60 time_t t_release_day
61 )
62 {
63 double seconds = difftime (t_today, t_release_day);
64 double days = seconds / (double) 86400.0;
65 char buf [32];
66 char * dot = buf;
67
68 sprintf (buf, "%f", days );
69
70 while ( *dot && *dot != '.') ++dot;
71 *dot = '\0';
72
73 return atol (buf);
74 }
75
76 void
77 write_h (int build)
78 {
79 FILE *h = NULL;
80 char* s;
81 char* s1;
82 int length;
83
84 s1 = s = malloc(256 * 1024);
85
86 s = s + sprintf (s, "/* Do not edit - Machine generated */\n");
87
88 s = s + sprintf (s, "#ifndef _INC_REACTOS_BUILDNO\n" );
89 s = s + sprintf (s, "#define _INC_REACTOS_BUILDNO\n" );
90
91 s = s + sprintf (s, "#define KERNEL_VERSION_BUILD\t%d\n", build);
92 s = s + sprintf (s, "#define KERNEL_VERSION_BUILD_STR\t\"%d\"\n", build);
93 s = s + sprintf (s, "#define KERNEL_RELEASE_RC\t\"%d.%d",
94 KERNEL_VERSION_MAJOR, KERNEL_VERSION_MINOR);
95 if (0 != KERNEL_VERSION_PATCH_LEVEL)
96 {
97 s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL);
98 }
99 s = s + sprintf (s, "-%S\\0\"\n", KERNEL_VERSION_BUILD_TYPE);
100 s = s + sprintf (s, "#define KERNEL_RELEASE_STR\t\"%d.%d",
101 KERNEL_VERSION_MAJOR,
102 KERNEL_VERSION_MINOR);
103 if (0 != KERNEL_VERSION_PATCH_LEVEL)
104 {
105 s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL);
106 }
107 s = s + sprintf (s, "-%S\"\n", KERNEL_VERSION_BUILD_TYPE);
108 s = s + sprintf (s, "#define KERNEL_VERSION_RC\t\"%d.%d",
109 KERNEL_VERSION_MAJOR,
110 KERNEL_VERSION_MINOR);
111 if (0 != KERNEL_VERSION_PATCH_LEVEL)
112 {
113 s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL);
114 }
115 s = s + sprintf (s, "-%S\\0\"\n", KERNEL_VERSION_BUILD_TYPE);
116 s = s + sprintf (s, "#define KERNEL_VERSION_STR\t\"%d.%d",
117 KERNEL_VERSION_MAJOR,
118 KERNEL_VERSION_MINOR);
119 if (0 != KERNEL_VERSION_PATCH_LEVEL)
120 {
121 s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL);
122 }
123 s = s + sprintf (s, "-%S\"\n", KERNEL_VERSION_BUILD_TYPE);
124 s = s + sprintf (s, "#endif\n/* EOF */\n");
125
126 h = fopen (BUILDNO_INCLUDE_FILE, "rb");
127 if (h != NULL)
128 {
129 fseek(h, 0, SEEK_END);
130 length = ftell(h);
131 if (length == strlen(s1))
132 {
133 char* orig;
134
135 orig = malloc(length);
136 fseek(h, 0, SEEK_SET);
137 fread(orig, 1, length, h);
138 if (memcmp(s1, orig, length) == 0)
139 {
140 fclose(h);
141 return;
142 }
143 }
144 fclose(h);
145 }
146
147 h = fopen (BUILDNO_INCLUDE_FILE, "wb");
148 if (!h)
149 {
150 fprintf (stderr,
151 "%s: can not create file \"%s\"!\n",
152 argv0,
153 BUILDNO_INCLUDE_FILE);
154 return;
155 }
156 fwrite(s1, 1, strlen(s1), h);
157 fclose (h);
158 }
159
160 void
161 usage (void)
162 {
163 fprintf (
164 stderr,
165 "Usage: %s [-{p|q}]\n\n -p print version number and exit\n -q run in quiet mode\n",
166 argv0
167 );
168 exit (EXIT_SUCCESS);
169 }
170
171
172 int
173 main (int argc, char * argv [])
174 {
175 int print_only = FALSE;
176 int quiet = FALSE;
177
178 int build = 0;
179
180 time_t t1 = 0;
181 struct tm * t1_tm = NULL;
182
183 argv0 = argv[0];
184
185 switch (argc)
186 {
187 case 1:
188 break;
189 case 2:
190 if (argv[1][0] == '-')
191 {
192 if (argv[1][1] == 'q')
193 {
194 quiet = TRUE;
195 }
196 else if (argv[1][1] == 'p')
197 {
198 print_only = TRUE;
199 }
200 else
201 {
202 usage ();
203 }
204 }
205 else
206 {
207 usage ();
208 }
209 break;
210 default:
211 usage ();
212 }
213 /*
214 * Set TZ information.
215 */
216 tzset ();
217 /*
218 * We are building TODAY!
219 */
220 if (FALSE == quiet)
221 {
222 printf ( "\nReactOS Build Number Generator\n\n");
223 }
224
225 time (& t1); /* current build time */
226 t1_tm = gmtime (& t1);
227
228 #ifdef DBG
229 tm_dump ("t1", t1_tm);
230 #endif
231 t1_tm->tm_year += 1900;
232 #ifdef DBG
233 tm_dump ("t1", t1_tm);
234 #endif
235 if (FALSE == quiet)
236 {
237 printf (
238 "Current date: %4d-%02d-%02d\n\n",
239 t1_tm->tm_year,
240 (t1_tm->tm_mon + 1),
241 t1_tm->tm_mday
242 );
243 }
244 /*
245 * Compute build number.
246 */
247 build = t1_tm->tm_year * 10000 + (t1_tm->tm_mon + 1) * 100 + t1_tm->tm_mday;
248
249 if (FALSE == quiet)
250 {
251 printf (
252 "ROS Version : %d.%d",
253 KERNEL_VERSION_MAJOR,
254 KERNEL_VERSION_MINOR
255 );
256 if (0 != KERNEL_VERSION_PATCH_LEVEL)
257 {
258 printf(".%d", KERNEL_VERSION_PATCH_LEVEL);
259 }
260 printf("-%S (Build %d)\n\n", KERNEL_VERSION_BUILD_TYPE, build);
261 }
262 /*
263 * (Over)write the include file, unless
264 * the user switched on -p.
265 */
266 if (FALSE == print_only)
267 {
268 write_h (build);
269 }
270 else
271 {
272 printf ("%s: no code generated", argv [0]);
273 }
274
275 return EXIT_SUCCESS;
276 }
277
278
279 /* EOF */