]>
git.saurik.com Git - apple/xnu.git/blob - libsa/vers_rsrc.c
1 #include <libsa/vers_rsrc.h>
7 c
== '1' || c
== '2' || c
== '3' ||
8 c
== '4' || c
== '5' || c
== '6' ||
9 c
== '7' || c
== '8' || c
== '9');
20 int isreleasestate(char c
) {
21 return (c
== 'd' || c
== 'a' || c
== 'b' || c
== 'f');
25 UInt8
BCD_digit_for_char(char c
) {
27 case '0': return 0; break;
28 case '1': return 1; break;
29 case '2': return 2; break;
30 case '3': return 3; break;
31 case '4': return 4; break;
32 case '5': return 5; break;
33 case '6': return 6; break;
34 case '7': return 7; break;
35 case '8': return 8; break;
36 case '9': return 9; break;
37 default: return BCD_illegal
; break;
43 char BCD_char_for_digit(UInt8 digit
) {
45 case 0: return '0'; break;
46 case 1: return '1'; break;
47 case 2: return '2'; break;
48 case 3: return '3'; break;
49 case 4: return '4'; break;
50 case 5: return '5'; break;
51 case 6: return '6'; break;
52 case 7: return '7'; break;
53 case 8: return '8'; break;
54 case 9: return '9'; break;
55 default: return '?'; break;
61 VERS_revision
VERS_revision_for_string(char ** string_p
) {
64 if (!string_p
|| !*string_p
) {
70 if (isspace(string
[0]) || string
[0] == '\0') {
75 if (isdigit(string
[1])) {
76 *string_p
= &string
[1];
77 return VERS_development
;
81 if (isdigit(string
[1])) {
82 *string_p
= &string
[1];
87 if (isdigit(string
[1])) {
88 *string_p
= &string
[1];
93 if (isdigit(string
[1])) {
94 *string_p
= &string
[1];
95 return VERS_candidate
;
96 } else if (string
[1] == 'c' && isdigit(string
[2])) {
97 *string_p
= &string
[2];
98 return VERS_candidate
;
113 int VERS_parse_string(const char * vers_string
, UInt32
* version_num
) {
116 char * current_char_p
;
119 if (!vers_string
|| *vers_string
== '\0') {
125 current_char_p
= &vers_string
[0];
129 * Check for an initial digit of the major release number.
131 vers
.bytes
[0] = BCD_digit_for_char(*current_char_p
);
132 if (vers
.bytes
[0] == BCD_illegal
) {
140 * Check for a second digit of the major release number.
142 if (*current_char_p
== '\0') {
143 vers
.bytes
[2] = VERS_release
;
144 vers
.bytes
[3] = 0xff;
146 } else if (isdigit(*current_char_p
)) {
147 scratch
= BCD_digit_for_char(*current_char_p
);
148 if (scratch
== BCD_illegal
) {
151 vers
.bytes
[0] = BCD_combine(vers
.bytes
[0], scratch
);
154 if (*current_char_p
== '\0') {
155 vers
.bytes
[2] = VERS_release
;
156 vers
.bytes
[3] = 0xff;
158 } else if (isreleasestate(*current_char_p
)) {
160 } else if (*current_char_p
== '.') {
165 } else if (isreleasestate(*current_char_p
)) {
167 } else if (*current_char_p
== '.') {
175 * Check for the minor release number.
177 if (*current_char_p
== '\0') {
178 vers
.bytes
[2] = VERS_release
;
179 vers
.bytes
[3] = 0xff;
181 } else if (isdigit(*current_char_p
)) {
182 vers
.bytes
[1] = BCD_digit_for_char(*current_char_p
);
183 if (vers
.bytes
[1] == BCD_illegal
) {
187 // Make sure its the first nibble of byte 1!
188 vers
.bytes
[1] = BCD_combine(vers
.bytes
[1], 0);
192 if (*current_char_p
== '\0') {
193 vers
.bytes
[2] = VERS_release
;
194 vers
.bytes
[3] = 0xff;
196 } else if (isreleasestate(*current_char_p
)) {
198 } else if (*current_char_p
== '.') {
209 * Check for the bugfix number.
211 if (*current_char_p
== '\0') {
212 vers
.bytes
[2] = VERS_release
;
213 vers
.bytes
[3] = 0xff;
215 } else if (isdigit(*current_char_p
)) {
216 scratch
= BCD_digit_for_char(*current_char_p
);
217 if (scratch
== BCD_illegal
) {
221 /* vers.bytes[1] has its left nibble set already */
222 vers
.bytes
[1] = vers
.bytes
[1] | scratch
;
226 if (*current_char_p
== '\0') {
227 vers
.bytes
[2] = VERS_release
;
228 vers
.bytes
[3] = 0xff;
230 } else if (isreleasestate(*current_char_p
)) {
243 * Check for the release state.
245 if (*current_char_p
== '\0') {
246 vers
.bytes
[2] = VERS_release
;
247 vers
.bytes
[3] = 0xff;
250 vers
.bytes
[2] = VERS_revision_for_string(¤t_char_p
);
251 if (vers
.bytes
[2] == VERS_invalid
) {
258 * Get the nonrelease revision number (0..255).
260 if (vers
.bytes
[2] != VERS_release
) {
261 UInt32 revision_num
= 0;
264 if (*current_char_p
== '\0' || !isdigit(*current_char_p
)) {
267 for (i
= 0; i
< 3 && *current_char_p
!= '\0'; i
++, current_char_p
++) {
269 scratch_digit
= BCD_digit_for_char(*current_char_p
);
270 if (scratch_digit
== BCD_illegal
) {
274 revision_num
+= scratch_digit
;
276 if (isdigit(*current_char_p
) || revision_num
> 255) {
279 vers
.bytes
[3] = (UInt8
)revision_num
;
282 if (vers
.bytes
[2] == VERS_release
) {
283 vers
.bytes
[3] = 0xff;
285 if (vers
.bytes
[2] == VERS_candidate
) {
286 if (vers
.bytes
[3] == 0) {
289 vers
.bytes
[2] = VERS_release
;
296 *version_num
= vers
.vnum
;
301 #define VERS_STRING_MAX_LEN (12)
303 int VERS_string(char * buffer
, UInt32 length
, UInt32 vers
) {
304 VERS_version version
;
315 /* No buffer, length less than longest possible vers string,
318 if (!buffer
|| length
< VERS_STRING_MAX_LEN
) {
323 bzero(buffer
, length
* sizeof(char));
327 * Major version number.
329 major1
= BCD_char_for_digit(BCD_get_left(version
.bytes
[0]));
332 } /* this is not an 'else' situation */
334 buffer
[cpos
] = major1
;
338 major2
= BCD_char_for_digit(BCD_get_right(version
.bytes
[0]));
343 buffer
[cpos
] = major2
;
348 * Minor & bug-fix version numbers.
350 minor
= BCD_char_for_digit(BCD_get_left(version
.bytes
[1]));
354 bugfix
= BCD_char_for_digit(BCD_get_right(version
.bytes
[1]));
360 /* Always display the minor version number.
364 buffer
[cpos
] = minor
;
368 /* Only display the bugfix version number if it's nonzero.
373 buffer
[cpos
] = bugfix
;
378 /* If the release state is final, we're done!
380 if (version
.bytes
[2] == VERS_release
&& version
.bytes
[3] == 255) {
387 * Do the release state and update level.
389 switch (version
.bytes
[2]) {
390 case VERS_development
:
403 if (version
.bytes
[3] < 255) {
405 buffer
[cpos
+1] = 'c';
419 if (version
.bytes
[2] != VERS_release
) {
420 sprintf(&buffer
[cpos
], "%d", version
.bytes
[3]);
422 if (version
.bytes
[3] < 255) {
423 sprintf(&buffer
[cpos
], "%d", version
.bytes
[3] + 1);