+ if (i >= argc)
+ show_usage();
+
+ have_output = 1;
+ }
+ else if (!strcmp(argv[i], "--false"))
+ {
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_FALSE, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--help"))
+ {
+ show_usage();
+ }
+ else if (!strcmp(argv[i], "--ls"))
+ {
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_LIST, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ }
+ else if (!strcmp(argv[i], "--local"))
+ {
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_IS_LOCAL, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--name"))
+ {
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_NAME_REGEX, invert, NULL, argv[i],
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--not"))
+ {
+ invert = 1;
+ }
+ else if (!strcmp(argv[i], "--or"))
+ {
+ if (logic != IPPFIND_OP_OR && current)
+ {
+ /*
+ * OK, we have two possibilities; either this is the top-level
+ * rule or we have a bunch of AND rules at this level.
+ */
+
+ if (!parent)
+ {
+ /*
+ * This is the top-level rule; we have to group *all* of the AND
+ * rules down a level, as AND has precedence over OR.
+ */
+
+ if ((temp = new_expr(IPPFIND_OP_AND, 0, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ while (current->prev)
+ {
+ current->parent = temp;
+ current = current->prev;
+ }
+
+ current->parent = temp;
+ temp->child = current;
+
+ expressions = current = temp;
+ }
+ else
+ {
+ /*
+ * This isn't the top rule, so go up one level...
+ */
+
+ current = parent;
+ parent = current->parent;
+ }
+ }
+
+ logic = IPPFIND_OP_OR;
+ temp = NULL;
+ }
+ else if (!strcmp(argv[i], "--path"))
+ {
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_PATH_REGEX, invert, NULL, argv[i],
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--print"))
+ {
+ if ((temp = new_expr(IPPFIND_OP_PRINT_URI, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ }
+ else if (!strcmp(argv[i], "--print-name"))
+ {
+ if ((temp = new_expr(IPPFIND_OP_PRINT_NAME, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ }
+ else if (!strcmp(argv[i], "--quiet"))
+ {
+ if ((temp = new_expr(IPPFIND_OP_QUIET, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ }
+ else if (!strcmp(argv[i], "--remote"))
+ {
+ if ((temp = new_expr(IPPFIND_OP_IS_REMOTE, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--true"))
+ {
+ if ((temp = new_expr(IPPFIND_OP_TRUE, invert, NULL, argv[i],
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--txt"))
+ {
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_TXT_EXISTS, invert, argv[i], NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strncmp(argv[i], "--txt-", 5))
+ {
+ const char *key = argv[i] + 5;/* TXT key */
+
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_TXT_REGEX, invert, key, argv[i],
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--uri"))
+ {
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_URI_REGEX, invert, NULL, argv[i],
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ }
+ else if (!strcmp(argv[i], "--version"))
+ {
+ show_version();
+ }
+ else
+ {
+ _cupsLangPrintf(stderr, _("%s: Unknown option \"%s\"."),
+ "ippfind", argv[i]);
+ show_usage();
+ }
+
+ if (temp)
+ {
+ /*
+ * Add new expression...
+ */
+
+ if (current)
+ {
+ temp->parent = parent;
+ current->next = temp;
+ }
+ else if (parent)
+ parent->child = temp;
+ else
+ expressions = temp;
+
+ temp->prev = current;
+ current = temp;
+ invert = 0;
+ temp = NULL;
+ }
+ }
+ else
+ {
+ /*
+ * Parse -o options
+ */
+
+ for (opt = argv[i] + 1; *opt; opt ++)
+ {
+ switch (*opt)
+ {
+ case '4' :
+ address_family = AF_INET;
+ break;
+
+ case '6' :
+ address_family = AF_INET6;
+ break;
+
+ case 'T' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ bonjour_timeout = atof(argv[i]);
+ break;
+
+ case 'V' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if (!strcmp(argv[i], "1.1"))
+ ipp_version = 11;
+ else if (!strcmp(argv[i], "2.0"))
+ ipp_version = 20;
+ else if (!strcmp(argv[i], "2.1"))
+ ipp_version = 21;
+ else if (!strcmp(argv[i], "2.2"))
+ ipp_version = 22;
+ else
+ show_usage();
+ break;
+
+ case 'd' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_DOMAIN_REGEX, invert, NULL,
+ argv[i], NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ break;
+
+ case 'e' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_EXEC, invert, NULL, NULL,
+ argv + i)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ while (i < argc)
+ if (!strcmp(argv[i], ";"))
+ break;
+ else
+ i ++;
+
+ if (i >= argc)
+ show_usage();
+
+ have_output = 1;
+ break;
+
+ case 'l' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_LIST, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ break;
+
+ case 'n' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_NAME_REGEX, invert, NULL,
+ argv[i], NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ break;
+
+ case 'p' :
+ if ((temp = new_expr(IPPFIND_OP_PRINT_URI, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ break;
+
+ case 'q' :
+ if ((temp = new_expr(IPPFIND_OP_QUIET, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ break;
+
+ case 'r' :
+ if ((temp = new_expr(IPPFIND_OP_IS_REMOTE, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ break;
+
+ case 's' :
+ if ((temp = new_expr(IPPFIND_OP_PRINT_NAME, invert, NULL, NULL,
+ NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+
+ have_output = 1;
+ break;
+
+ case 't' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_TXT_EXISTS, invert, argv[i],
+ NULL, NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ break;
+
+ case 'u' :
+ i ++;
+ if (i >= argc)
+ show_usage();
+
+ if ((temp = new_expr(IPPFIND_OP_URI_REGEX, invert, NULL,
+ argv[i], NULL)) == NULL)
+ return (IPPFIND_EXIT_MEMORY);
+ break;
+
+ default :
+ _cupsLangPrintf(stderr, _("%s: Unknown option \"-%c\"."),
+ "ippfind", *opt);
+ show_usage();
+ break;
+ }
+
+ if (temp)
+ {
+ /*
+ * Add new expression...
+ */
+
+ if (current)
+ {
+ temp->parent = parent;
+ current->next = temp;
+ }
+ else if (parent)
+ parent->child = temp;
+ else
+ expressions = temp;
+
+ temp->prev = current;
+ current = temp;
+ invert = 0;
+ temp = NULL;
+ }
+ }
+ }
+ }
+ else if (!strcmp(argv[i], "("))