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