Skip to content

Instantly share code, notes, and snippets.

@dnaeon
Created September 10, 2011 12:47
Show Gist options
  • Save dnaeon/1208272 to your computer and use it in GitHub Desktop.
Save dnaeon/1208272 to your computer and use it in GitHub Desktop.
pkg query - diff
diff --git a/pkg/query.c b/pkg/query.c
index 69bb6c7..ad6786e 100644
--- a/pkg/query.c
+++ b/pkg/query.c
@@ -12,6 +12,38 @@
#include "query.h"
+static struct query_flags {
+ const char flag;
+ const char *options;
+ const unsigned multiline;
+ const int dbflags;
+} q_flags[] = {
+ { 'd', "nov", 1, PKG_LOAD_DEPS },
+ { 'r', "nov", 1, PKG_LOAD_RDEPS },
+ { 'C', "", 1, PKG_LOAD_CATEGORIES },
+ { 'F', "ps", 1, PKG_LOAD_FILES },
+ { 'S', "", 1, PKG_LOAD_SCRIPTS },
+ { 'O', "kv", 1, PKG_LOAD_OPTIONS },
+ { 'D', "", 1, PKG_LOAD_DIRS },
+ { 'L', "", 1, PKG_LOAD_LICENSES },
+ { 'U', "", 1, PKG_LOAD_USERS },
+ { 'G', "", 1, PKG_LOAD_GROUPS },
+ { 'K', "", 1, PKG_LOAD_CONFLICTS },
+ { '?', "drCFODLUGK", 1, PKG_LOAD_BASIC }, /* dbflags handled in analyse_query_string() */
+ { 's', "hb", 0, PKG_LOAD_BASIC },
+ { 'n', "", 0, PKG_LOAD_BASIC },
+ { 'v', "", 0, PKG_LOAD_BASIC },
+ { 'o', "", 0, PKG_LOAD_BASIC },
+ { 'p', "", 0, PKG_LOAD_BASIC },
+ { 'm', "", 0, PKG_LOAD_BASIC },
+ { 'c', "", 0, PKG_LOAD_BASIC },
+ { 'w', "", 0, PKG_LOAD_BASIC },
+ { 'l', "", 0, PKG_LOAD_BASIC },
+ { 'a', "", 0, PKG_LOAD_BASIC },
+};
+
+const unsigned int flags_len = (sizeof(q_flags)/sizeof(q_flags[0]));
+
static void
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
{
@@ -269,190 +301,82 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
static int
analyse_query_string(char *qstr, int *flags, char *multiline)
{
+ unsigned int i, j, k;
+ unsigned int valid_flag = 0;
+ unsigned int valid_opts = 0;
+
while (qstr[0] != '\0') {
if (qstr[0] == '%') {
qstr++;
- switch (qstr[0]) {
- case 'd':
- qstr++;
- if (qstr[0] != 'n' && qstr[0] != 'o' && qstr[0] != 'v') {
- fprintf(stderr, "Invalid query: %%d should be followed by: n, o or v\n");
- return (EPKG_FATAL);
- }
- if (*multiline != 0 && *multiline != 'd') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%d' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'd';
- *flags |= PKG_LOAD_DEPS;
- break;
- case 'r':
- qstr++;
- if (qstr[0] != 'n' && qstr[0] != 'o' && qstr[0] != 'v') {
- fprintf(stderr, "Invalid query: %%r should be followed by: n, o or v\n");
- return (EPKG_FATAL);
- }
- if (*multiline != 0 && *multiline != 'r') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%r' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'r';
- *flags |= PKG_LOAD_RDEPS;
- break;
- case 'C':
- if (*multiline != 0 && *multiline != 'C') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%c' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'C';
- *flags |= PKG_LOAD_CATEGORIES;
- break;
- case 'F':
- qstr++;
- if (qstr[0] != 'p' && qstr[0] != 's') {
- fprintf(stderr, "Invalid query: %%F should be followed by: p or s\n");
- return (EPKG_FATAL);
- }
- if (*multiline != 0 && *multiline != 'F') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%F' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'F';
- *flags |= PKG_LOAD_FILES;
- break;
- case 'S':
- if (*multiline != 0 && *multiline != 'S') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%S' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'S';
- *flags |= PKG_LOAD_SCRIPTS;
- break;
- case 'O':
- qstr++;
- if (qstr[0] != 'k' && qstr[0] != 'v') {
- fprintf(stderr, "Invalid query: %%O should be followed by: k or v\n");
- return (EPKG_FATAL);
- }
- if (*multiline != 0 && *multiline != 'O') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%O' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'O';
- *flags |= PKG_LOAD_OPTIONS;
- break;
- case 'D':
- if (*multiline != 0 && *multiline != 'D') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%D' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'D';
- *flags |= PKG_LOAD_DIRS;
- break;
- case 'L':
- if (*multiline != 0 && *multiline != 'L') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%L' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'L';
- *flags |= PKG_LOAD_LICENSES;
- break;
- case 'U':
- if (*multiline != 0 && *multiline != 'U') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%U' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'U';
- *flags |= PKG_LOAD_USERS;
- break;
- case 'G':
- if (*multiline != 0 && *multiline != 'G') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%G' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'G';
- *flags |= PKG_LOAD_GROUPS;
- break;
- case 'K':
- if (*multiline != 0 && *multiline != 'K') {
- fprintf(stderr, "Invalid query format string, you can't query '%%%c' and '%%K' at the same time\n", *multiline);
- return (EPKG_FATAL);
- }
- *multiline = 'K';
- *flags |= PKG_LOAD_CONFLICTS;
- break;
- case 's':
- qstr++;
- if (qstr[0] != 'h' && qstr[0] != 'b') {
- fprintf(stderr, "Invalid query: %%s should be followed by: h or b\n");
- return (EPKG_FATAL);
- }
- break;
- case '?':
- qstr++;
- if (qstr[0] != 'd' && qstr[0] != 'r' && qstr[0] != 'C' &&
- qstr[0] != 'F' && qstr[0] != 'O' &&
- qstr[0] != 'D' && qstr[0] != 'L' &&
- qstr[0] != 'U' && qstr[0] != 'G' &&
- qstr[0] != 'K' ) {
- fprintf(stderr, "Invalid query: %%? should be followed by: d, r, C, F, O, D, L, U, G or K\n");
- return (EPKG_FATAL);
+ valid_flag = 0;
+
+ for (i = 0; i < flags_len; i++) {
+ /* found the flag */
+ if (qstr[0] == q_flags[i].flag) {
+ valid_flag = 1;
+
+ /* if the flag is followed by additional options */
+ if (q_flags[i].options[0] != '\0') {
+ qstr++;
+ valid_opts = 0;
+
+ for (j = 0; j < strlen(q_flags[i].options); j++) {
+ if (qstr[0] == q_flags[i].options[j]) {
+ valid_opts = 1;
+ break;
+ }
+ }
+
+ if (valid_opts == 0) {
+ fprintf(stderr, "Invalid query: '%%%c' should be followed by:", q_flags[i].flag);
+
+ for (j = 0; j < strlen(q_flags[i].options); j++)
+ fprintf(stderr, " %c%c", q_flags[i].options[j],
+ q_flags[i].options[j + 1] == '\0' ?
+ '\n' : ',');
+
+ return (EPKG_FATAL);
+ }
}
- switch (qstr[0]) {
- case 'd':
- *flags |= PKG_LOAD_DEPS;
- break;
- case 'r':
- *flags |= PKG_LOAD_RDEPS;
- break;
- case 'C':
- *flags |= PKG_LOAD_CATEGORIES;
- break;
- case 'F':
- *flags |= PKG_LOAD_FILES;
- break;
- case 'O':
- *flags |= PKG_LOAD_OPTIONS;
- break;
- case 'D':
- *flags |= PKG_LOAD_DIRS;
- break;
- case 'L':
- *flags |= PKG_LOAD_LICENSES;
- break;
- case 'U':
- *flags |= PKG_LOAD_USERS;
- break;
- case 'G':
- *flags |= PKG_LOAD_GROUPS;
- break;
- case 'K':
- *flags |= PKG_LOAD_CONFLICTS;
- break;
+
+ /* if this is a multiline flag */
+ if (q_flags[i].multiline == 1)
+ if (*multiline != 0 && *multiline != q_flags[i].flag) {
+ fprintf(stderr, "Invalid query: you cannot query '%%%c' and '%%%c' at the same time\n",
+ *multiline, q_flags[i].flag);
+ return (EPKG_FATAL);
+ } else {
+ *multiline = q_flags[i].flag;
+ }
+
+ /* handle the '?' flag cases */
+ if (q_flags[i].flag == '?') {
+ for (k = 0; k < flags_len; k++)
+ if (q_flags[k].flag == q_flags[i].options[j]) {
+ *flags |= q_flags[k].dbflags;
+ break;
+ }
+ } else {
+ *flags |= q_flags[i].dbflags;
}
- break;
- case 'n':
- case 'v':
- case 'o':
- case 'p':
- case 'm':
- case 'c':
- case 'w':
- case 'l':
- case 'a':
- /* this is ok */
- break;
- default:
- fprintf(stderr, "Unkown query format key: '%%%c'\n", qstr[0]);
- return (EPKG_FATAL);
+ break; /* don't iterate over the rest of the flags */
+ }
+ }
+
+ if (valid_flag == 0) {
+ fprintf(stderr, "Unkown query format key: '%%%c'\n", qstr[0]);
+ return (EPKG_FATAL);
}
}
+
qstr++;
}
return (EPKG_OK);
}
+
void
usage_query(void)
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment