2 * Copyright 2002, Ryan Fleet.
3 * Copyright 2006-2007, Axel Dörfler, axeld@pinc-software.de.
5 * Distributed under the terms of the MIT license.
9 #include <AppFileInfo.h>
18 #ifdef HAIKU_HOST_PLATFORM_SUNOS
19 const char *kProgramName
= "setversion";
21 extern const char *__progname
;
23 const char *kProgramName
= __progname
;
28 switch_needed
, major_version
, middle_version
, minor_version
,
29 variety_version
, internal_version
, long_string
, short_string
33 e_base
= B_ERRORS_END
,
34 e_unknown
, e_app_sys_switch
, e_specify_version
, e_major_version
,
35 e_middle_version
, e_minor_version
, e_variety_version
, e_internal_version
,
36 e_expecting
, e_long_string
, e_short_string
,
37 e_parameter
, e_app_twice
, e_sys_twice
40 enum processing_mode
{ no_switch
, app_switch
, sys_switch
};
46 fprintf(stdout
, "Usage: %s filename\n", kProgramName
);
47 fprintf(stdout
, " [ -system <major> <middle> <minor>\n");
48 fprintf(stdout
, " [ [ d | a | b | g | gm | f ] [ <internal> ] ]\n");
49 fprintf(stdout
, " [ -short <shortVersionString> ]\n");
50 fprintf(stdout
, " [ -long <longVersionString> ] ] # system info\n");
51 fprintf(stdout
, " [ -app <major> <middle> <minor>\n");
52 fprintf(stdout
, " [ [ d | a | b | g | gm | f ] [ <internal> ] ]\n");
53 fprintf(stdout
, " [ -short <shortVersionString> ]\n");
54 fprintf(stdout
, " [ -long <longVersionString> ] ] # application info\n");
59 convertVariety(const char *str
)
61 if (!strcmp(str
, "d") || !strcmp(str
, "development"))
63 if (!strcmp(str
, "a") || !strcmp(str
, "alpha"))
65 if (!strcmp(str
, "b") || !strcmp(str
, "beta"))
67 if (!strcmp(str
, "g") || !strcmp(str
, "gamma"))
69 if (strcmp(str
, "gm") || !strcmp(str
, "goldenmaster"))
71 if (!strcmp(str
, "f") || !strcmp(str
, "final"))
79 errorToString(BString
& output
, status_t error
, const char *appName
= NULL
)
82 case e_app_sys_switch
:
83 output
= "-system or -app expected\n";
85 case e_specify_version
:
86 output
= "you did not specify any version\n";
89 output
= "major version number error\n";
91 case e_middle_version
:
92 output
= "middle version number error\n";
95 output
= "minor version number error\n";
97 case e_variety_version
:
98 output
= "variety letter error\n";
100 case e_internal_version
:
101 output
= "internal version number error\n";
104 output
= "expecting -short, -long, -app or -system\n";
107 output
= "expecting long version string\n";
110 output
= "expecting short version string\n";
113 output
= "parameter error\n";
116 output
= "you cannot specify the app version twice\n";
119 output
= "you cannot specify the system version twice\n";
122 output
= "unknown internal error\n";
126 output
= strerror(error
);
128 if (appName
!= NULL
) {
138 errorOut(status_t error
, const char *appName
= NULL
, bool showUsage
= true)
141 errorToString(output
, error
, appName
);
143 fprintf(stderr
, "%s: %s", kProgramName
, output
.String());
153 parse(bool &systemModified
, bool &appModified
, arg_needed
&argNeeded
,
154 processing_mode
&mode
, version_info
&systemVersion
, version_info
&appVersion
,
155 int argc
, char *argv
[])
157 systemModified
= false;
160 argNeeded
= switch_needed
;
162 for (int i
= 2; i
< argc
; ++i
) {
163 version_info
&version
= mode
== app_switch
? appVersion
: systemVersion
;
167 if (strcmp(argv
[i
], "-app") == 0) {
168 if (mode
== app_switch
)
169 errorOut(e_app_twice
);
171 errorOut(e_parameter
);
174 argNeeded
= major_version
;
176 } else if (strcmp(argv
[i
], "-system") == 0) {
177 if (mode
== sys_switch
)
178 errorOut(e_sys_twice
);
180 errorOut(e_parameter
);
183 argNeeded
= major_version
;
184 systemModified
= true;
185 } else if (strcmp(argv
[i
], "-long") == 0) {
186 if (mode
== no_switch
)
187 errorOut(e_app_sys_switch
);
189 argNeeded
= long_string
;
190 } else if (strcmp(argv
[i
], "-short") == 0) {
191 if (mode
== no_switch
)
192 errorOut(e_app_sys_switch
);
194 argNeeded
= short_string
;
195 } else if (mode
== no_switch
)
196 errorOut(e_app_sys_switch
);
197 else if (strncmp(argv
[i
], "-", 1) == 0)
198 errorOut(e_parameter
);
200 errorOut(e_expecting
);
204 if (isalpha(argv
[i
][0]))
205 errorOut(e_major_version
);
207 version
.major
= atoi(argv
[i
]);
208 argNeeded
= middle_version
;
212 if (isalpha(argv
[i
][0]))
213 errorOut(e_middle_version
);
215 version
.middle
= atoi(argv
[i
]);
216 argNeeded
= minor_version
;
220 if (isalpha(argv
[i
][0]))
221 errorOut(e_minor_version
);
223 version
.minor
= atoi(argv
[i
]);
226 argNeeded
= switch_needed
;
230 argNeeded
= variety_version
;
233 case variety_version
:
235 if (!strncmp(argv
[i
], "-", 1)) {
237 argNeeded
= switch_needed
;
241 int variety
= convertVariety(argv
[i
]);
243 errorOut(e_variety_version
);
245 version
.variety
= variety
;
246 argNeeded
= internal_version
;
250 case internal_version
:
251 if (isalpha(argv
[i
][0]))
252 errorOut(e_expecting
);
254 version
.internal
= atoi(argv
[i
]);
255 argNeeded
= switch_needed
;
259 strcpy(version
.long_info
, argv
[i
]);
260 argNeeded
= switch_needed
;
264 strcpy(version
.short_info
, argv
[i
]);
265 argNeeded
= switch_needed
;
270 if (mode
== no_switch
)
271 errorOut(e_app_sys_switch
);
275 errorOut(e_major_version
);
278 errorOut(e_middle_version
);
281 errorOut(e_minor_version
);
283 case variety_version
:
284 errorOut(e_variety_version
);
286 case internal_version
:
287 errorOut(e_internal_version
);
290 errorOut(e_long_string
);
293 errorOut(e_short_string
);
303 main(int argc
, char *argv
[])
307 return errorOut(e_app_sys_switch
);
309 return errorOut(e_specify_version
);
312 // reset version infos
314 version_info systemVersion
, appVersion
;
315 memset(&systemVersion
, 0, sizeof(version_info
));
316 memset(&appVersion
, 0, sizeof(version_info
));
320 processing_mode mode
;
321 arg_needed argNeeded
;
322 bool systemModified
, appModified
;
324 parse(systemModified
, appModified
, argNeeded
, mode
, systemVersion
,
325 appVersion
, argc
, argv
);
327 // write back changes
330 status_t status
= file
.SetTo(argv
[1], B_READ_WRITE
);
332 errorOut(status
, argv
[1], false);
335 status
= info
.SetTo(&file
);
337 errorOut(status
, argv
[1], false);
339 if (systemModified
^ appModified
) {
340 // clear out other app info if not present - this works around a
341 // bug in BeOS, see bug #681.
342 version_kind kind
= systemModified
? B_APP_VERSION_KIND
: B_SYSTEM_VERSION_KIND
;
345 if (info
.GetVersionInfo(&clean
, kind
) != B_OK
) {
346 memset(&clean
, 0, sizeof(version_info
));
347 info
.SetVersionInfo(&clean
, kind
);
352 status
= info
.SetVersionInfo(&appVersion
, B_APP_VERSION_KIND
);
354 errorOut(status
, NULL
, false);
357 if (systemModified
) {
358 status
= info
.SetVersionInfo(&systemVersion
, B_SYSTEM_VERSION_KIND
);
360 errorOut(status
, NULL
, false);