1 /* 2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <getopt.h> 8 #include <stdio.h> 9 #include <string.h> 10 11 #include <Entry.h> 12 #include <package/PackageInfo.h> 13 14 #include "package.h" 15 16 17 using namespace BPackageKit; 18 19 20 int 21 command_info(int argc, const char* const* argv) 22 { 23 const char* format = "name: %name% version: %version%\n"; 24 25 while (true) { 26 static struct option sLongOptions[] = { 27 { "format", required_argument, 0, 'f' }, 28 { "help", no_argument, 0, 'h' }, 29 { 0, 0, 0, 0 } 30 }; 31 32 opterr = 0; // don't print errors 33 int c = getopt_long(argc, (char**)argv, "f:h", sLongOptions, NULL); 34 if (c == -1) 35 break; 36 37 switch (c) { 38 case 'f': 39 format = optarg; 40 break; 41 42 default: 43 print_usage_and_exit(true); 44 break; 45 } 46 } 47 48 // One argument should remain -- the package file name. 49 if (optind + 1 != argc) 50 print_usage_and_exit(true); 51 52 const char* fileName = argv[optind++]; 53 54 // Read the package info from the package file. If it doesn't look like a 55 // package file, assume it is a package info file. 56 BPackageInfo info; 57 if (BString(fileName).EndsWith(".hpkg")) { 58 status_t error = info.ReadFromPackageFile(fileName); 59 if (error != B_OK) { 60 fprintf(stderr, "Error: Failed to read package file \"%s\": %s\n", 61 fileName, strerror(error)); 62 return 1; 63 } 64 } else { 65 status_t error = info.ReadFromConfigFile(BEntry(fileName)); 66 if (error != B_OK) { 67 fprintf(stderr, "Error: Failed to read package info file \"%s\": " 68 "%s\n", fileName, strerror(error)); 69 return 1; 70 } 71 } 72 73 // parse format string and produce output 74 BString output; 75 while (*format != '\0') { 76 char c = *format++; 77 switch (c) { 78 case '%': 79 { 80 const char* start = format; 81 while (*format != '\0' && *format != '%') 82 format++; 83 if (*format != '%') { 84 fprintf(stderr, "Error: Unexpected at end of the format " 85 "string. Expected \"%%\".\n"); 86 return 1; 87 } 88 89 if (format == start) { 90 output << '%'; 91 } else { 92 BString variable(start, format - start); 93 if (variable == "fileName") { 94 output << info.CanonicalFileName(); 95 } else if (variable == "name") { 96 output << info.Name(); 97 } else if (variable == "version") { 98 output << info.Version().ToString(); 99 } else { 100 fprintf(stderr, "Error: Unsupported placeholder \"%s\" " 101 "in format string.\n", variable.String()); 102 return 1; 103 } 104 } 105 106 format++; 107 break; 108 } 109 110 case '\\': 111 c = *format++; 112 if (c == '\0') { 113 fprintf(stderr, "Error: \"\\\" at the end of the format " 114 "string.\n"); 115 return 1; 116 } 117 switch (c) { 118 case 'n': 119 c = '\n'; 120 break; 121 case 't': 122 c = '\t'; 123 break; 124 } 125 // fall through 126 127 default: 128 output << c; 129 break; 130 } 131 } 132 133 fputs(output.String(), stdout); 134 135 return 0; 136 } 137