xref: /haiku/src/bin/setversion.cpp (revision 17049c451a91f427aec94b944b75876b611103e7)
1 // Author: Ryan Fleet
2 // Created: 12th October 2002
3 // Modified: 14th October 2002
4 
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include <AppFileInfo.h>
11 
12 
13 enum eArgNeeded
14 {
15 	switch_needed, major_version, middle_version, minor_version,
16 	variety_version, internal_version, long_string, short_string
17 };
18 
19 enum eError
20 {
21 	e_unknown, e_app_sys_switch, e_specify_version, e_major_version,
22 	e_middle_version, e_minor_version, e_variety_version, e_internal_version,
23 	e_expecting, e_long_string, e_short_string, e_no_file,
24 	e_parameter, e_app_twice, e_sys_twice
25 };
26 
27 enum eMode { no_switch, app_switch, sys_switch };
28 
29 
30 void usage(const char *app)
31 {
32 	fprintf(stdout, "Usage: %s filename\n", app);
33 	fprintf(stdout, "   [ -system <major> <middle> <minor>\n");
34 	fprintf(stdout, "       [ [ d | a | b | g | gm | f ] [ <internal> ] ]\n");
35 	fprintf(stdout, "       [ -short <shortVersionString> ]\n");
36 	fprintf(stdout, "       [ -long <longVersionString> ] ] # system info\n");
37 	fprintf(stdout, "   [ -app <major> <middle> <minor>\n");
38 	fprintf(stdout, "       [ [ d | a | b | g | gm | f ] [ <internal> ] ]\n");
39 	fprintf(stdout, "       [ -short <shortVersionString> ]\n");
40 	fprintf(stdout, "       [ -long <longVersionString> ] ] # application info\n");
41 }
42 
43 
44 int convertVariety(const char *str)
45 {
46 	if(strcmp(str, "d") == 0)
47 		return 0;
48 	else if(strcmp(str, "a") == 0)
49 		return 1;
50 	else if(strcmp(str, "b") == 0)
51 		return 2;
52 	else if(strcmp(str, "g") == 0)
53 		return 3;
54 	else if(strcmp(str, "gm") == 0)
55 		return 4;
56 	else if(strcmp(str, "f") == 0)
57 		return 5;
58 	else
59 		return -1;
60 }
61 
62 
63 int errorOut(eError error, const char *thisApp, const char *appName = NULL)
64 {
65 	switch(error)
66 	{
67 	case e_app_sys_switch:
68 		fprintf(stderr, "%s: -system or -app expected\n", thisApp);
69 		break;
70 	case e_specify_version:
71 		fprintf(stderr, "%s: you did not specify any version\n", thisApp);
72 		break;
73 	case e_major_version:
74 		fprintf(stderr, "%s: major version number error\n", thisApp);
75 		break;
76 	case e_middle_version:
77 		fprintf(stderr, "%s: middle version number error\n", thisApp);
78 		break;
79 	case e_minor_version:
80 		fprintf(stderr, "%s: minor version number error\n", thisApp);
81 		break;
82 	case e_variety_version:
83 		fprintf(stderr, "%s: variety letter error\n", thisApp);
84 		break;
85 	case e_internal_version:
86 		fprintf(stderr, "%s: internal version number error\n", thisApp);
87 		break;
88 	case e_expecting:
89 		fprintf(stderr, "%s: expecting -short, -long, -app or -system\n", thisApp);
90 		break;
91 	case e_long_string:
92 		fprintf(stderr, "%s: expecting long version string\n", thisApp);
93 		break;
94 	case e_short_string:
95 		fprintf(stderr, "%s: expecting short version string\n", thisApp);
96 		break;
97 	case e_no_file:
98 		fprintf(stderr, "%s: error No such file or directory opening file %s!\n", thisApp, appName);
99 		break;
100 	case e_parameter:
101 		fprintf(stderr, "%s: parameter error\n", thisApp);
102 		break;
103 	case e_app_twice:
104 		fprintf(stderr, "%s: you cannot specify the app version twice\n", thisApp);
105 		break;
106 	case e_sys_twice:
107 		fprintf(stderr, "%s: you cannot specify the system version twice\n", thisApp);
108 		break;
109 	case e_unknown:
110 		fprintf(stderr, "%s: unknown internal error\n", thisApp);
111 		break;
112 	};
113 
114 	usage(thisApp);
115 	exit(1);
116 }
117 
118 
119 void parse(bool &bSysModified, bool &bAppModified, eArgNeeded &argNeeded, eMode &mode, version_info &sysInfo, version_info &appInfo, int argc, char *argv[])
120 {
121 	bSysModified = false;
122 	bAppModified = false;
123 	mode = no_switch;
124 	argNeeded = switch_needed;
125 
126 	for(int i = 2; i < argc; ++i)
127 	{
128 		switch(argNeeded)
129 		{
130 		case switch_needed:
131 			{
132 				if(strcmp(argv[i], "-app") == 0)
133 				{
134 					if(mode == app_switch)
135 						errorOut(e_app_twice, argv[0]);
136 					if(true == bAppModified)
137 						errorOut(e_parameter, argv[0]);
138 					mode = app_switch;
139 					argNeeded = major_version;
140 					bAppModified = true;
141 				}
142 				else if(strcmp(argv[i], "-system") == 0)
143 				{
144 					if(mode == sys_switch)
145 						errorOut(e_sys_twice, argv[0]);
146 					if(true == bSysModified)
147 						errorOut(e_parameter, argv[0]);
148 					mode = sys_switch;
149 					argNeeded = major_version;
150 					bSysModified = true;
151 				}
152 				else if(strcmp(argv[i], "-long") == 0)
153 				{
154 					if(mode == no_switch)
155 						errorOut(e_app_sys_switch, argv[0]);
156 
157 					argNeeded = long_string;
158 				}
159 				else if(strcmp(argv[i], "-short") == 0)
160 				{
161 					if(mode == no_switch)
162 						errorOut(e_app_sys_switch, argv[0]);
163 					argNeeded = short_string;
164 				}
165 				else if(mode == no_switch)
166 					errorOut(e_app_sys_switch, argv[0]);
167 				else if(strncmp(argv[i], "-", 1) == 0)
168 					errorOut(e_parameter, argv[0]);
169 				else
170 					errorOut(e_expecting, argv[0]);
171 			} break;
172 
173 		case major_version:
174 			{
175 				if(mode == app_switch)
176 				{
177 					if(isalpha(argv[i][0]))
178 						errorOut(e_major_version, argv[0]);
179 
180 					appInfo.major = atoi(argv[i]);
181 				}
182 				else if(mode == sys_switch)
183 				{
184 					if(isalpha(argv[i][0]))
185 						errorOut(e_major_version, argv[0]);
186 
187 					sysInfo.major = atoi(argv[i]);
188 				}
189 				else
190 					errorOut(e_unknown, argv[0]); // (should never reach here)
191 
192 				argNeeded = middle_version;
193 			} break;
194 
195 		case middle_version:
196 			{
197 				if(mode == app_switch)
198 				{
199 					if(isalpha(argv[i][0]))
200 						errorOut(e_middle_version, argv[0]);
201 
202 					appInfo.middle = atoi(argv[i]);
203 				}
204 				else if(mode == sys_switch)
205 				{
206 					if(isalpha(argv[i][0]))
207 						errorOut(e_middle_version, argv[0]);
208 
209 					sysInfo.middle = atoi(argv[i]);
210 				}
211 				else
212 					errorOut(e_unknown, argv[0]); // (should never reach here)
213 				argNeeded = minor_version;
214 			} break;
215 
216 		case minor_version:
217 			{
218 				if(mode == app_switch)
219 				{
220 					if(isalpha(argv[i][0]))
221 						errorOut(e_minor_version, argv[0]);
222 
223 					appInfo.minor = atoi(argv[i]);
224 				}
225 				else if(mode == sys_switch)
226 				{
227 					if(isalpha(argv[i][0]))
228 						errorOut(e_minor_version, argv[0]);
229 
230 					sysInfo.minor = atoi(argv[i]);
231 				}
232 				else
233 					errorOut(e_unknown, argv[0]); // (should never reach here)
234 
235 				if(i >= argc-1)
236 				{
237 					argNeeded = switch_needed;
238 					break;
239 				}
240 
241 				argNeeded = variety_version;
242 			} break;
243 		case variety_version:
244 			{
245 				if(strncmp(argv[i], "-", 1) == 0)
246 				{
247 					--i;
248 					argNeeded = switch_needed;
249 					break;
250 				}
251 
252 				if(mode == app_switch)
253 				{
254 					int v = convertVariety(argv[i]);
255 					if(v < 0)
256 						errorOut(e_variety_version, argv[0]);
257 					appInfo.variety = v;
258 				}
259 				else if(mode == sys_switch)
260 				{
261 					int v = convertVariety(argv[i]);
262 					if(v < 0)
263 						errorOut(e_variety_version, argv[0]);
264 					sysInfo.variety = v;
265 				}
266 				else
267 					errorOut(e_unknown, argv[0]); // (should never reach here)
268 				argNeeded = internal_version;
269 			} break;
270 		case internal_version:
271 			{
272 				if(mode == app_switch)
273 				{
274 					if(isalpha(argv[i][0]))
275 						errorOut(e_expecting, argv[0]);
276 
277 					appInfo.internal = atoi(argv[i]);
278 				}
279 				else if(mode == sys_switch)
280 				{
281 					if(isalpha(argv[i][0]))
282 						errorOut(e_expecting, argv[0]);
283 
284 					sysInfo.internal = atoi(argv[i]);
285 				}
286 				else
287 					errorOut(e_unknown, argv[0]); // (should never reach here)
288 				argNeeded = switch_needed;
289 			} break;
290 		case long_string:
291 			{
292 				if(mode == app_switch)
293 					strcpy(appInfo.long_info, argv[i]);
294 				else if(mode == sys_switch)
295 					strcpy(sysInfo.long_info, argv[i]);
296 				else
297 					errorOut(e_unknown, argv[0]); // (should never reach here)
298 				argNeeded = switch_needed;
299 			} break;
300 		case short_string:
301 			{
302 				if(mode == app_switch)
303 					strcpy(appInfo.short_info, argv[i]);
304 				else if(mode == sys_switch)
305 					strcpy(sysInfo.short_info, argv[i]);
306 				else
307 					errorOut(e_unknown, argv[0]); // (should never reach here)
308 				argNeeded = switch_needed;
309 			} break;
310 		};
311 	}
312 
313 	if(mode == no_switch)
314 		errorOut(e_app_sys_switch, argv[0]);
315 
316 	switch(argNeeded)
317 	{
318 	case major_version:
319 		errorOut(e_major_version, argv[0]);
320 		break;
321 	case middle_version:
322 		errorOut(e_middle_version, argv[0]);
323 		break;
324 	case minor_version:
325 		errorOut(e_minor_version, argv[0]);
326 		break;
327 	case variety_version:
328 		errorOut(e_variety_version, argv[0]);
329 		break;
330 	case internal_version:
331 		errorOut(e_internal_version, argv[0]);
332 		break;
333 	case long_string:
334 		errorOut(e_long_string, argv[0]);
335 		break;
336 	case short_string:
337 		errorOut(e_short_string, argv[0]);
338 		break;
339 	case switch_needed:
340 		// all is well. continue
341 		break;
342 	};
343 }
344 
345 
346 int main(int argc, char *argv[])
347 {
348 	if(argc < 3)
349 	{
350 		if(argc < 2)
351 			return errorOut(e_app_sys_switch, argv[0]);
352 		else
353 			return errorOut(e_specify_version, argv[0]);
354 	}
355 
356 	eMode mode;
357 	eArgNeeded argNeeded;
358 	version_info sysInfo, appInfo;
359 	bool bSysModified, bAppModified;
360 
361 	parse(bSysModified, bAppModified, argNeeded, mode, sysInfo, appInfo, argc, argv);
362 
363 	BFile file(argv[1], B_WRITE_ONLY);
364 	if(file.InitCheck() != B_OK)
365 		errorOut(e_no_file, argv[0], argv[1]);
366 
367 	BAppFileInfo info(&file);
368 	if(info.InitCheck() != B_OK)
369 		errorOut(e_unknown, argv[0]);
370 
371 	status_t status;
372 	if(bAppModified)
373 	{
374 		status = info.SetVersionInfo(&appInfo, B_APP_VERSION_KIND);
375 		if(status < 0)
376 			errorOut(e_unknown, argv[0]);
377 	}
378 
379 	if(bSysModified)
380 	{
381 		status = info.SetVersionInfo(&sysInfo, B_SYSTEM_VERSION_KIND);
382 		if(status < 0)
383 			errorOut(e_unknown, argv[0]);
384 	}
385 
386 	return 0;
387 }
388 
389