On Tue, Oct 24, 2017 at 11:53 AM, Jeff Hostetler <g...@jeffhostetler.com> wrote:
> + * <arg> ::= blob:none
> + *           blob:limit:<n>[kmg]
> + *           sparse:oid:<oid-expression>
> + *           sparse:path:<pathname>

I notice in the code below that there are some usages of "=" instead
of ":" - could you clarify which one it is? (Ideally this would point
to one point of documentation which serves as both user and technical
documentation.)

> + */
> +int parse_list_objects_filter(struct list_objects_filter_options 
> *filter_options,
> +                             const char *arg)
> +{
> +       struct object_context oc;
> +       struct object_id sparse_oid;
> +       const char *v0;
> +       const char *v1;
> +
> +       if (filter_options->choice)
> +               die(_("multiple object filter types cannot be combined"));
> +
> +       /*
> +        * TODO consider rejecting 'arg' if it contains any
> +        * TODO injection characters (since we might send this
> +        * TODO to a sub-command or to the server and we don't
> +        * TODO want to deal with legacy quoting/escaping for
> +        * TODO a new feature).
> +        */
> +
> +       filter_options->raw_value = strdup(arg);
> +
> +       if (skip_prefix(arg, "blob:", &v0) || skip_prefix(arg, "blobs:", 
> &v0)) {

I know that some people prefer leniency, but I think it's better to
standardize on one form ("blob" instead of both "blob" and "blobs").

> +               if (!strcmp(v0, "none")) {
> +                       filter_options->choice = LOFC_BLOB_NONE;
> +                       return 0;
> +               }
> +
> +               if (skip_prefix(v0, "limit=", &v1) &&
> +                   git_parse_ulong(v1, &filter_options->blob_limit_value)) {
> +                       filter_options->choice = LOFC_BLOB_LIMIT;
> +                       return 0;
> +               }
> +       }
> +       else if (skip_prefix(arg, "sparse:", &v0)) {
> +               if (skip_prefix(v0, "oid=", &v1)) {
> +                       filter_options->choice = LOFC_SPARSE_OID;
> +                       if (!get_oid_with_context(v1, GET_OID_BLOB,
> +                                                 &sparse_oid, &oc)) {
> +                               /*
> +                                * We successfully converted the <oid-expr>
> +                                * into an actual OID.  Rewrite the raw_value
> +                                * in canonoical form with just the OID.
> +                                * (If we send this request to the server, we
> +                                * want an absolute expression rather than a
> +                                * local-ref-relative expression.)
> +                                */
> +                               free((char *)filter_options->raw_value);
> +                               filter_options->raw_value =
> +                                       xstrfmt("sparse:oid=%s",
> +                                               oid_to_hex(&sparse_oid));
> +                               filter_options->sparse_oid_value =
> +                                       oiddup(&sparse_oid);
> +                       } else {
> +                               /*
> +                                * We could not turn the <oid-expr> into an
> +                                * OID.  Leave the raw_value as is in case
> +                                * the server can parse it.  (It may refer to
> +                                * a branch, commit, or blob we don't have.)
> +                                */
> +                       }
> +                       return 0;
> +               }
> +
> +               if (skip_prefix(v0, "path=", &v1)) {
> +                       filter_options->choice = LOFC_SPARSE_PATH;
> +                       filter_options->sparse_path_value = strdup(v1);
> +                       return 0;
> +               }
> +       }
> +
> +       die(_("invalid filter expression '%s'"), arg);
> +       return 0;
> +}
> +
> +int opt_parse_list_objects_filter(const struct option *opt,
> +                                 const char *arg, int unset)
> +{
> +       struct list_objects_filter_options *filter_options = opt->value;
> +
> +       assert(arg);
> +       assert(!unset);
> +
> +       return parse_list_objects_filter(filter_options, arg);
> +}
> diff --git a/list-objects-filter-options.h b/list-objects-filter-options.h
> new file mode 100644
> index 0000000..23bd68e
> --- /dev/null
> +++ b/list-objects-filter-options.h
> @@ -0,0 +1,50 @@
> +#ifndef LIST_OBJECTS_FILTER_OPTIONS_H
> +#define LIST_OBJECTS_FILTER_OPTIONS_H
> +
> +#include "parse-options.h"
> +
> +/*
> + * Common declarations and utilities for filtering objects (such as omitting
> + * large blobs) in list_objects:traverse_commit_list() and git-rev-list.
> + */
> +
> +enum list_objects_filter_choice {
> +       LOFC_DISABLED = 0,
> +       LOFC_BLOB_NONE,
> +       LOFC_BLOB_LIMIT,
> +       LOFC_SPARSE_OID,
> +       LOFC_SPARSE_PATH,
> +};
> +
> +struct list_objects_filter_options {
> +       /*
> +        * The raw argument value given on the command line or
> +        * protocol request.  (The part after the "--keyword=".)
> +        */
> +       char *raw_value;
> +
> +       /*
> +        * Parsed values. Only 1 will be set depending on the flags below.
> +        */
> +       struct object_id *sparse_oid_value;
> +       char *sparse_path_value;
> +       unsigned long blob_limit_value;
> +
> +       enum list_objects_filter_choice choice;
> +};
> +
> +/* Normalized command line arguments */
> +#define CL_ARG__FILTER "filter"
> +
> +int parse_list_objects_filter(struct list_objects_filter_options 
> *filter_options,
> +                             const char *arg);
> +
> +int opt_parse_list_objects_filter(const struct option *opt,
> +                                 const char *arg, int unset);
> +
> +#define OPT_PARSE_LIST_OBJECTS_FILTER(fo) \
> +       { OPTION_CALLBACK, 0, CL_ARG__FILTER, fo, N_("args"), \
> +         N_("object filtering"), PARSE_OPT_NONEG, \
> +         opt_parse_list_objects_filter }

Thanks - this does make it easier to have a standard argument name and
description everywhere.

> +
> +#endif /* LIST_OBJECTS_FILTER_OPTIONS_H */
> --
> 2.9.3
>

Reply via email to