From 16c83730262f1e4f0fc69d80744bb36dcfbbe3af Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 9 Oct 2013 03:43:08 +0200 Subject: [PATCH] package: Add "info" command It allows to print individual information from the package meta data. --- src/bin/package/Jamfile | 2 +- src/bin/package/command_info.cpp | 136 +++++++++++++++++++++++++++++++ src/bin/package/package.cpp | 16 ++++ src/bin/package/package.h | 3 +- src/tools/package/Jamfile | 1 + 5 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 src/bin/package/command_info.cpp diff --git a/src/bin/package/Jamfile b/src/bin/package/Jamfile index 7f34919c05..80f0c95f85 100644 --- a/src/bin/package/Jamfile +++ b/src/bin/package/Jamfile @@ -7,11 +7,11 @@ BinCommand package : command_create.cpp command_dump.cpp command_extract.cpp + command_info.cpp command_list.cpp package.cpp PackageWriterListener.cpp PackageWritingUtils.cpp - : package be $(TARGET_LIBSUPC++) diff --git a/src/bin/package/command_info.cpp b/src/bin/package/command_info.cpp new file mode 100644 index 0000000000..301e358ef2 --- /dev/null +++ b/src/bin/package/command_info.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include + +#include +#include + +#include "package.h" + + +using namespace BPackageKit; + + +int +command_info(int argc, const char* const* argv) +{ + const char* format = "name: %name% version: %version%\n"; + + while (true) { + static struct option sLongOptions[] = { + { "format", required_argument, 0, 'f' }, + { "help", no_argument, 0, 'h' }, + { 0, 0, 0, 0 } + }; + + opterr = 0; // don't print errors + int c = getopt_long(argc, (char**)argv, "f:h", sLongOptions, NULL); + if (c == -1) + break; + + switch (c) { + case 'f': + format = optarg; + break; + + default: + print_usage_and_exit(true); + break; + } + } + + // One argument should remain -- the package file name. + if (optind + 1 != argc) + print_usage_and_exit(true); + + const char* fileName = argv[optind++]; + + // Read the package info from the package file. If it doesn't look like a + // package file, assume it is a package info file. + BPackageInfo info; + if (BString(fileName).EndsWith(".hpkg")) { + status_t error = info.ReadFromPackageFile(fileName); + if (error != B_OK) { + fprintf(stderr, "Error: Failed to read package file \"%s\": %s\n", + fileName, strerror(error)); + return 1; + } + } else { + status_t error = info.ReadFromConfigFile(BEntry(fileName)); + if (error != B_OK) { + fprintf(stderr, "Error: Failed to read package info file \"%s\": " + "%s\n", fileName, strerror(error)); + return 1; + } + } + + // parse format string and produce output + BString output; + while (*format != '\0') { + char c = *format++; + switch (c) { + case '%': + { + const char* start = format; + while (*format != '\0' && *format != '%') + format++; + if (*format != '%') { + fprintf(stderr, "Error: Unexpected at end of the format " + "string. Expected \"%%\".\n"); + return 1; + } + + if (format == start) { + output << '%'; + } else { + BString variable(start, format - start); + if (variable == "fileName") { + output << info.CanonicalFileName(); + } else if (variable == "name") { + output << info.Name(); + } else if (variable == "version") { + output << info.Version().ToString(); + } else { + fprintf(stderr, "Error: Unsupported placeholder \"%s\" " + "in format string.\n", variable.String()); + return 1; + } + } + + format++; + break; + } + + case '\\': + c = *format++; + if (c == '\0') { + fprintf(stderr, "Error: \"\\\" at the end of the format " + "string.\n"); + return 1; + } + switch (c) { + case 'n': + c = '\n'; + break; + case 't': + c = '\t'; + break; + } + // fall through + + default: + output << c; + break; + } + } + + fputs(output.String(), stdout); + + return 0; +} diff --git a/src/bin/package/package.cpp b/src/bin/package/package.cpp index 180169c6b3..4954d99060 100644 --- a/src/bin/package/package.cpp +++ b/src/bin/package/package.cpp @@ -76,6 +76,19 @@ static const char* kUsage = " of the archive.\n" " -i - Extract the .PackageInfo file to instead.\n" "\n" + " info [ ] \n" + " Prints individual meta information of package file .\n" + "\n" + " -f , --format \n" + " - Print the given format string, performing the following\n" + " replacements:\n" + " %fileName% - the package's canonical file name\n" + " %name% - the package name\n" + " %version% - the package version\n" + " %% - %\n" + " \n - new line\n" + " \t - tab\n" + "\n" " list [ ] \n" " Lists the contents of package file .\n" "\n" @@ -118,6 +131,9 @@ main(int argc, const char* const* argv) if (strcmp(command, "list") == 0) return command_list(argc - 1, argv + 1); + if (strcmp(command, "info") == 0) + return command_info(argc - 1, argv + 1); + if (strcmp(command, "help") == 0) print_usage_and_exit(false); else diff --git a/src/bin/package/package.h b/src/bin/package/package.h index 05ebf17fde..966386b728 100644 --- a/src/bin/package/package.h +++ b/src/bin/package/package.h @@ -1,5 +1,5 @@ /* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef PACKAGE_H @@ -12,6 +12,7 @@ int command_add(int argc, const char* const* argv); int command_create(int argc, const char* const* argv); int command_dump(int argc, const char* const* argv); int command_extract(int argc, const char* const* argv); +int command_info(int argc, const char* const* argv); int command_list(int argc, const char* const* argv); diff --git a/src/tools/package/Jamfile b/src/tools/package/Jamfile index 771e6a2bbf..b9dfd3628a 100644 --- a/src/tools/package/Jamfile +++ b/src/tools/package/Jamfile @@ -11,6 +11,7 @@ BuildPlatformMain package : command_create.cpp command_dump.cpp command_extract.cpp + command_info.cpp command_list.cpp package.cpp PackageWriterListener.cpp