# HG changeset patch # User Kristian H?gsberg # Date 1212624297 14400 # Node ID 9aed412ed2b879d9660cd85fff0ff8b70cb70908 # Parent bf5d87af3e1e0020d07f5e9c730f13e79f81da05 Process all option structs that match a given arg. This lets us handle options such as -i that have different meanings depending on what other options are present on the command line. diff -r bf5d87af3e1e -r 9aed412ed2b8 rpm-razor.c --- a/rpm-razor.c Wed Jun 04 15:04:45 2008 -0400 +++ b/rpm-razor.c Wed Jun 04 20:04:57 2008 -0400 @@ -38,6 +38,14 @@ void *data; }; +/* A note about all these options: rpm allows options to mean + * different things depending on what other options are present on the + * command line. For example, if -q or --query is present, -i no + * longer means install, but info. The way we handle this is by + * setting all the options that may match (ie if -i is given we set + * install and info), and then look at the relevent one depending on + * what else in on the command line. */ + static int option_all, option_whatrequires, option_whatprovides; static int option_package; @@ -170,7 +178,8 @@ { } }; -static int option_conflicts, option_obsoletes, option_requires, option_provides; +static int option_conflicts, option_obsoletes, option_requires; +static int option_provides, option_info, option_changelog; static const struct option alias_options[] = { { OPTION_BOOL, "scripts", 0, NULL, "list install/erase scriptlets from package(s)", NULL, }, @@ -180,8 +189,8 @@ { OPTION_BOOL, "obsoletes", 0, NULL, "list other packages removed by installing this package", &option_obsoletes, }, { OPTION_BOOL, "provides", 0, NULL, "list capabilities that this package provides", &option_provides, }, { OPTION_BOOL, "requires", 0, NULL, "list capabilities required by package(s)", &option_requires, }, - { OPTION_BOOL, "info", 0, NULL, "list descriptive information from package(s)", NULL, }, - { OPTION_BOOL, "changelog", 0, NULL, "list change logs for this package", NULL, }, + { OPTION_BOOL, "info", 'i', NULL, "list descriptive information from package(s)", &option_info, }, + { OPTION_BOOL, "changelog", 0, NULL, "list change logs for this package", &option_changelog, }, { OPTION_BOOL, "xml", 0, NULL, "list metadata in xml", NULL, }, { OPTION_BOOL, "triggers", 0, NULL, "list trigger scriptlets from package(s)", NULL, }, { OPTION_BOOL, "last", 0, NULL, "list package(s) by install time, most recent first", NULL, }, @@ -328,6 +337,18 @@ razor_property_iterator_destroy(pi); } +static void +print_package_info(struct razor_set *set, struct razor_package *package) +{ + printf("FIXME: Package info not tracked.\n"); +} + +static void +print_package_changelog(struct razor_set *set, struct razor_package *package) +{ + printf("FIXME: Package changelog not tracked.\n"); +} + static struct razor_set * create_set_from_command_line(int argc, const char *argv[]) { @@ -407,8 +428,14 @@ if (option_provides) print_package_properties(set, package, RAZOR_PROPERTY_PROVIDES); - if (!option_conflicts && !option_obsoletes && - !option_requires && !option_provides) + if (option_info) + print_package_info(set, package); + if (option_changelog) + print_package_changelog(set, package); + + if (option_conflicts + option_obsoletes + + option_requires + option_provides + + option_info + option_changelog == 0) printf("%s-%s.%s\n", name, version, arch); } @@ -463,28 +490,31 @@ printf("command update - not implemented\n"); } -static const struct option * -find_option(const struct option *options, const char *s) +static int +for_each_option(const struct option *options, const char *s, + void (*fn)(const struct option *o, + const char *arg, void *data), void *data) { - const struct option *o; - int i; + int i, count = 0; for (i = 0; options[i].type != OPTION_LAST; i++) { switch (options[i].type) { case OPTION_GROUP: - o = find_option(options[i].data, s); - if (o != NULL) - return o; + count += for_each_option(options[i].data, s, fn, data); break; case OPTION_BOOL: case OPTION_STRING: if (s[0] == '-' && - s[1] == options[i].short_name && s[2] == '\0') - return &options[i]; + s[1] == options[i].short_name && s[2] == '\0') { + fn(&options[i], s, data); + count++; + } if (s[0] == '-' && s[1] == '-' && - strcmp(options[i].name, s + 2) == 0) - return &options[i]; + strcmp(options[i].name, s + 2) == 0) { + fn(&options[i], s, data); + count++; + } break; case OPTION_LAST: @@ -492,13 +522,36 @@ } } - return NULL; + return count; +} + +static void +handle_option(const struct option *o, const char *arg, void *data) +{ + if (o->data == NULL) { + printf("option \"%s\" not supported\n", arg); + return; + } + + switch (o->type) { + case OPTION_BOOL: + *(int *) o->data = 1; + break; + + case OPTION_STRING: + *(const char **) o->data = arg + strlen(o->name) + 3; + break; + + case OPTION_LAST: + case OPTION_GROUP: + /* Shouldn't happen. */ + break; + } } static int parse_options(const struct option *options, int argc, const char **argv) { - const struct option *o; int i, j; /* FIXME: Bundling... rpm -Uvh must work :) */ @@ -508,29 +561,11 @@ argv[j++] = argv[i]; continue; } - o = find_option(options, argv[i]); - if (o == NULL) { + + if (for_each_option(options, argv[i], + handle_option, NULL) == 0) { printf("unknown option: \"%s\"\n", argv[i]); - continue; - } - if (o->data == NULL) { - printf("option \"%s\" not supported\n", argv[i]); - continue; - } - switch (o->type) { - case OPTION_BOOL: - *(int *) o->data = 1; - break; - - case OPTION_STRING: - *(const char **) o->data = - argv[i] + strlen(o->name) + 3; - break; - - case OPTION_LAST: - case OPTION_GROUP: - /* Shouldn't happen. */ - break; + exit(1); } } @@ -639,23 +674,16 @@ exit(0); } - if (option_query + option_verify + - option_erase + option_install + option_upgrade > 1) { - printf("specify only one of query, verify, erase, install " - "or upgrade\n"); - exit(1); - } - - if (option_query) { + if (option_verify) { + command_verify(argc, argv); + } else if (option_query) { command_query(argc, argv); - } else if (option_verify) { - command_verify(argc, argv); - } else if (option_erase) { - command_erase(argc, argv); } else if (option_install) { command_install(argc, argv); } else if (option_upgrade) { command_update(argc, argv); + } else if (option_erase) { + command_erase(argc, argv); } else { print_options_usage(rpm_options); printf("\n");