2 * buildno - Generate the build number for ReactOS
4 * Copyright (c) 1999,2000 Emanuele Aliberti
5 * Copyright (c) 2006 Christoph von Wittich
6 * Copyright (c) 2008 Hervé Poussineau
8 * The build number is the day on which the build took
11 * The build number is stored in the output file as a set of macros
15 * 2008-01-12 (hpoussin)
16 * Add -t option to change the build tag
17 * 2006-09-09 (cwittich)
18 * Read binary entries files from SVN 1.4.x
20 * Fixed bugs: tm_year is (current_year - 1900),
21 * tm_month is 0-11 not 1-12 and code ignored TZ.
23 * Added -p option to make it simply print the
24 * version number, but skip buildno.h generation.
36 static const char * argv0
= "";
37 static char * filename
= NULL
;
38 static char * build_tag
= NULL
;
40 int count_wide_string( const wchar_t *str
)
43 for( i
= 0; str
[i
]; i
++ )
49 GetRev(char *Revision
, size_t length
)
55 fp
= fopen(".svn/entries", "r");
58 if (fgets(Revision
, length
, fp
) != NULL
)
60 /* If the first character of the file is not a digit,
61 then it is probably in XML format. */
62 if (isdigit(Revision
[0]))
64 while (fgets(Revision
, length
, fp
) != NULL
)
66 revno
= strtol(Revision
, &p
, 10);
85 head
= XMLLoadFile(".svn/entries");
87 catch(XMLFileNotFoundException
)
89 head
= XMLLoadFile("_svn/entries");
91 XMLElement
*entries
= head
->subElements
[0];
92 for (size_t i
= 0; i
< entries
->subElements
.size(); i
++)
94 XMLElement
*entry
= entries
->subElements
[i
];
95 if ("entry" == entry
->name
)
99 bool GotRevision
= false;
100 for (size_t j
= 0; j
< entry
->attributes
.size(); j
++)
102 XMLAttribute
*Attribute
= entry
->attributes
[j
];
103 if ("name" == Attribute
->name
&& "" == Attribute
->value
)
107 if ("kind" == Attribute
->name
&& "dir" == Attribute
->value
)
111 if ("revision" == Attribute
->name
)
113 if (length
<= Attribute
->value
.length() + 1)
115 strcpy(Revision
, "revtoobig");
119 strcpy(Revision
, Attribute
->value
.c_str());
120 revno
= strtol(Revision
, NULL
, 10);
124 if (GotName
&& GotKind
&& GotRevision
)
140 strcpy(Revision
, "UNKNOWN");
145 write_h (int build
, char *buildstr
, long revno
)
151 int dllversion
= KERNEL_VERSION_MAJOR
+ 42;
153 s1
= s
= (char *) malloc(256 * 1024);
155 s
= s
+ sprintf (s
, "/* Do not edit - Machine generated */\n");
157 s
= s
+ sprintf (s
, "#ifndef _INC_REACTOS_BUILDNO\n" );
158 s
= s
+ sprintf (s
, "#define _INC_REACTOS_BUILDNO\n" );
160 s
= s
+ sprintf (s
, "#define KERNEL_VERSION_BUILD\t%d\n", build
);
161 s
= s
+ sprintf (s
, "#define KERNEL_VERSION_BUILD_HEX\t0x%lx\n", revno
);
162 s
= s
+ sprintf (s
, "#define KERNEL_VERSION_BUILD_STR\t\"%s\"\n", buildstr
);
163 s
= s
+ sprintf (s
, "#define KERNEL_VERSION_BUILD_RC\t\"%s\\0\"\n", buildstr
);
164 s
= s
+ sprintf (s
, "#define KERNEL_RELEASE_RC\t\"%d.%d",
165 KERNEL_VERSION_MAJOR
, KERNEL_VERSION_MINOR
);
166 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
168 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
170 s
= s
+ sprintf (s
, "%s\\0\"\n", build_tag
);
171 s
= s
+ sprintf (s
, "#define KERNEL_RELEASE_STR\t\"%d.%d",
172 KERNEL_VERSION_MAJOR
,
173 KERNEL_VERSION_MINOR
);
174 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
176 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
178 s
= s
+ sprintf (s
, "%s\"\n", build_tag
);
179 s
= s
+ sprintf (s
, "#define KERNEL_VERSION_RC\t\"%d.%d",
180 KERNEL_VERSION_MAJOR
,
181 KERNEL_VERSION_MINOR
);
182 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
184 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
186 s
= s
+ sprintf (s
, "%s\\0\"\n", build_tag
);
187 s
= s
+ sprintf (s
, "#define KERNEL_VERSION_STR\t\"%d.%d",
188 KERNEL_VERSION_MAJOR
,
189 KERNEL_VERSION_MINOR
);
190 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
192 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
194 s
= s
+ sprintf (s
, "%s\"\n", build_tag
);
195 s
= s
+ sprintf (s
, "#define REACTOS_DLL_VERSION_MAJOR\t%d\n", dllversion
);
196 s
= s
+ sprintf (s
, "#define REACTOS_DLL_RELEASE_RC\t\"%d.%d",
197 dllversion
, KERNEL_VERSION_MINOR
);
198 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
200 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
202 s
= s
+ sprintf (s
, "%s\\0\"\n", build_tag
);
203 s
= s
+ sprintf (s
, "#define REACTOS_DLL_RELEASE_STR\t\"%d.%d",
205 KERNEL_VERSION_MINOR
);
206 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
208 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
210 s
= s
+ sprintf (s
, "%s\"\n", build_tag
);
211 s
= s
+ sprintf (s
, "#define REACTOS_DLL_VERSION_RC\t\"%d.%d",
213 KERNEL_VERSION_MINOR
);
214 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
216 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
218 s
= s
+ sprintf (s
, "%s\\0\"\n", build_tag
);
219 s
= s
+ sprintf (s
, "#define REACTOS_DLL_VERSION_STR\t\"%d.%d",
221 KERNEL_VERSION_MINOR
);
222 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
224 s
= s
+ sprintf (s
, ".%d", KERNEL_VERSION_PATCH_LEVEL
);
226 s
= s
+ sprintf (s
, "%s\"\n", build_tag
);
227 s
= s
+ sprintf (s
, "#endif\n/* EOF */\n");
229 h
= fopen (filename
, "rb");
232 fseek(h
, 0, SEEK_END
);
234 if (length
== strlen(s1
))
238 orig
= (char *) malloc(length
);
245 fseek(h
, 0, SEEK_SET
);
246 fread(orig
, 1, length
, h
);
247 if (memcmp(s1
, orig
, length
) == 0)
259 h
= fopen (filename
, "wb");
263 "%s: can not create file \"%s\"!\n",
269 fwrite(s1
, 1, strlen(s1
), h
);
278 "Usage: %s [-{p|q}] [-t tag] path-to-header\n\n"
279 " -p print version number and exit\n"
280 " -q run in quiet mode\n"
281 " -t specify a build tag\n",
288 main (int argc
, char * argv
[])
291 int print_only
= FALSE
;
296 char buildstr
[64], revision
[10];
299 struct tm
* t1_tm
= NULL
;
303 /* Check arguments */
304 for (i
= 1; i
< argc
; i
++)
319 build_tag
= argv
[++i
];
342 /* Set TZ information. */
344 /* We are building TODAY! */
347 printf ( "\nReactOS Build Number Generator\n\n");
350 time (& t1
); /* current build time */
351 t1_tm
= gmtime (& t1
);
353 t1_tm
->tm_year
+= 1900;
357 "Current date: %4d-%02d-%02d\n\n",
363 /* Compute build number. */
364 build
= t1_tm
->tm_year
* 10000 + (t1_tm
->tm_mon
+ 1) * 100 + t1_tm
->tm_mday
;
368 /* Create default build tag */
369 length
= count_wide_string(KERNEL_VERSION_BUILD_TYPE
);
370 build_tag
= (char *)malloc(length
+2);
374 for (i
= 0; KERNEL_VERSION_BUILD_TYPE
[i
]; i
++)
376 build_tag
[i
+ 1] = KERNEL_VERSION_BUILD_TYPE
[i
];
386 length
= strlen(build_tag
);
387 char *new_build_tag
= (char *)malloc(length
+ 2);
388 strcpy(new_build_tag
, "-");
389 strcat(new_build_tag
, build_tag
);
390 build_tag
= new_build_tag
;
393 revno
= GetRev(revision
, sizeof(revision
));
394 sprintf(buildstr
, "%d-r%s", build
, revision
);
399 "ROS Version : %d.%d",
400 KERNEL_VERSION_MAJOR
,
401 KERNEL_VERSION_MINOR
);
402 if (0 != KERNEL_VERSION_PATCH_LEVEL
)
404 printf(".%d", KERNEL_VERSION_PATCH_LEVEL
);
406 printf("%s (Build %s)\n\n", build_tag
, buildstr
);
408 /* (Over)write the include file, unless the user switched on -p. */
411 write_h (build
, buildstr
, revno
);
415 printf ("%s: no code generated", argv
[0]);