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