-/* Get the next include/exclude arg from the string. The token will not
- * be '\0' terminated, so use the returned length to limit the string.
- * Also, be sure to add this length to the returned pointer before passing
- * it back to ask for the next token. This routine parses the "!" (list-
- * clearing) token and (depending on the mflags) the various prefixes.
- * The *mflags_ptr value will be set on exit to the new MATCHFLG_* bits
- * for the current token. */
-static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags,
- unsigned int *len_ptr, uint32 *mflags_ptr)
+static char *grab_paren_value(const uchar **s_ptr)
+{
+ const uchar *start, *end;
+ int val_sz;
+ char *val;
+
+ if ((*s_ptr)[1] != '(')
+ return NULL;
+ start = (*s_ptr) + 2;
+
+ for (end = start; *end != ')'; end++)
+ if (!*end || *end == ' ' || *end == '_')
+ return NULL;
+
+ val_sz = end - start + 1;
+ val = new_array(char, val_sz);
+ strlcpy(val, (const char *)start, val_sz);
+ *s_ptr = end; /* remember ++s in parse_rule_tok */
+ return val;
+}
+
+static struct filter_chmod_struct *make_chmod_struct(char *modestr)
+{
+ struct filter_chmod_struct *chmod;
+ struct chmod_mode_struct *modes = NULL;
+
+ if (!parse_chmod(modestr, &modes))
+ return NULL;
+
+ if (!(chmod = new(struct filter_chmod_struct)))
+ out_of_memory("make_chmod_struct");
+ chmod->ref_cnt = 1;
+ chmod->modestr = modestr;
+ chmod->modes = modes;
+ return chmod;
+}
+
+#define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \
+ | MATCHFLG_DIRECTORY | MATCHFLG_NEGATE \
+ | MATCHFLG_PERISHABLE | MATCHFLGS_ATTRS)
+
+/* Gets the next include/exclude rule from *rulestr_ptr and advances
+ * *rulestr_ptr to point beyond it. Stores the pattern's start (within
+ * *rulestr_ptr) and length in *pat_ptr and *pat_len_ptr, and returns a newly
+ * allocated filter_struct containing the rest of the information. Returns
+ * NULL if there are no more rules in the input.
+ *
+ * The template provides defaults for the new rule to inherit, and the
+ * template mflags and the xflags additionally affect parsing. */
+static struct filter_struct *parse_rule_tok(const char **rulestr_ptr,
+ struct filter_struct *template, int xflags,
+ const char **pat_ptr, unsigned int *pat_len_ptr)