Re: [PATCH 6/6] grep: obey --textconv for the case rev:path

2013-04-20 Thread Jeff King
On Sat, Apr 20, 2013 at 04:42:49PM +0200, Michael J Gruber wrote:

> > And this mass of almost-the-same functions is gross, too, especially
> > given that the object_context contains a mode itself.
> 
> Well, it's just providing different ways to call into the one and only
> function, in order to satisfy different callers' needs. It's not unheard
> of (or rather: unseen) in our code, is it?

No, we have instances of it already. And they're ugly, too. :) I think
when we hit more than 2 or 3 wrappers it is time to start thinking
whether they can be consolidated.  I think it is mostly the overlap in
context and mode that makes me find this one particularly ugly. But it's
probably not solvable without some pretty heavy refactoring.

> I vaguely seem to recall we had some more general framework cooking but
> I may be wrong (I was offline due to sickness for a while). It was about
> attaching some additional info to something. Yes, I said "vaguely" ...

Yeah, I really wanted to keep the context inside the object_array, but
it means either wasting a lot of space (due to over-large buffers) or
having the array elements be variable-sized (with a flex-array for the
pathname). And object_array entries already have a memory-leak problem
from the "name" field, which I think we just punt on elsewhere. So I
think this is probably the lesser of the possible evils.

-Peff
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 6/6] grep: obey --textconv for the case rev:path

2013-04-20 Thread Michael J Gruber
Jeff King venit, vidit, dixit 20.04.2013 06:24:
> On Fri, Apr 19, 2013 at 06:44:49PM +0200, Michael J Gruber wrote:
> 
>> @@ -820,12 +820,13 @@ int cmd_grep(int argc, const char **argv, const char 
>> *prefix)
>>  for (i = 0; i < argc; i++) {
>>  const char *arg = argv[i];
>>  unsigned char sha1[20];
>> +struct object_context oc;
>>  /* Is it a rev? */
>> -if (!get_sha1(arg, sha1)) {
>> +if (!get_sha1_with_context(arg, 0, sha1, &oc)) {
>>  struct object *object = parse_object_or_die(sha1, arg);
>>  if (!seen_dashdash)
>>  verify_non_filename(prefix, arg);
>> -add_object_array(object, arg, &list);
>> +add_object_array_with_context(object, arg, &list, 
>> xmemdupz(&oc, sizeof(struct object_context)));
> 
> Hrm. I'm not excited about the extra allocation here. Who frees it?
> 
>> +void add_object_array(struct object *obj, const char *name, struct 
>> object_array *array)
>> +{
>> +add_object_array_with_mode(obj, name, array, S_IFINVALID);
>> +}
>> +
>> +void add_object_array_with_mode(struct object *obj, const char *name, 
>> struct object_array *array, unsigned mode)
>> +{
>> +add_object_array_with_mode_context(obj, name, array, mode, NULL);
>> +}
>> +
>> +void add_object_array_with_context(struct object *obj, const char *name, 
>> struct object_array *array, struct object_context *context)
>> +{
>> +if (context)
>> +add_object_array_with_mode_context(obj, name, array, 
>> context->mode, context);
>> +else
>> +add_object_array_with_mode_context(obj, name, array, 
>> S_IFINVALID, context);
>> +}
> 
> And this mass of almost-the-same functions is gross, too, especially
> given that the object_context contains a mode itself.

Well, it's just providing different ways to call into the one and only
function, in order to satisfy different callers' needs. It's not unheard
of (or rather: unseen) in our code, is it?

> Unfortunately, I'm not sure if I have a more pleasant suggestion. I seem
> to recall wrestling with this issue during the last round, too.

Yes, I think that's what we ended up with. At least it's just one
context struct per argument to grep, so it's not that bad after all.

I vaguely seem to recall we had some more general framework cooking but
I may be wrong (I was offline due to sickness for a while). It was about
attaching some additional info to something. Yes, I said "vaguely" ...

Michael
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 6/6] grep: obey --textconv for the case rev:path

2013-04-19 Thread Jeff King
On Fri, Apr 19, 2013 at 06:44:49PM +0200, Michael J Gruber wrote:

> @@ -820,12 +820,13 @@ int cmd_grep(int argc, const char **argv, const char 
> *prefix)
>   for (i = 0; i < argc; i++) {
>   const char *arg = argv[i];
>   unsigned char sha1[20];
> + struct object_context oc;
>   /* Is it a rev? */
> - if (!get_sha1(arg, sha1)) {
> + if (!get_sha1_with_context(arg, 0, sha1, &oc)) {
>   struct object *object = parse_object_or_die(sha1, arg);
>   if (!seen_dashdash)
>   verify_non_filename(prefix, arg);
> - add_object_array(object, arg, &list);
> + add_object_array_with_context(object, arg, &list, 
> xmemdupz(&oc, sizeof(struct object_context)));

Hrm. I'm not excited about the extra allocation here. Who frees it?

> +void add_object_array(struct object *obj, const char *name, struct 
> object_array *array)
> +{
> + add_object_array_with_mode(obj, name, array, S_IFINVALID);
> +}
> +
> +void add_object_array_with_mode(struct object *obj, const char *name, struct 
> object_array *array, unsigned mode)
> +{
> + add_object_array_with_mode_context(obj, name, array, mode, NULL);
> +}
> +
> +void add_object_array_with_context(struct object *obj, const char *name, 
> struct object_array *array, struct object_context *context)
> +{
> + if (context)
> + add_object_array_with_mode_context(obj, name, array, 
> context->mode, context);
> + else
> + add_object_array_with_mode_context(obj, name, array, 
> S_IFINVALID, context);
> +}

And this mass of almost-the-same functions is gross, too, especially
given that the object_context contains a mode itself.

Unfortunately, I'm not sure if I have a more pleasant suggestion. I seem
to recall wrestling with this issue during the last round, too.

-Peff
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/6] grep: obey --textconv for the case rev:path

2013-04-19 Thread Michael J Gruber
Make "grep" obey the "--textconv" option also for the object case, i.e.
when used with an argument "rev:path".

Signed-off-by: Michael J Gruber 
---
 builtin/grep.c | 11 ++-
 object.c   | 26 --
 object.h   |  2 ++
 t/t7008-grep-binary.sh |  6 --
 4 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 00ee57d..bb7f970 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -458,10 +458,10 @@ static int grep_tree(struct grep_opt *opt, const struct 
pathspec *pathspec,
 }
 
 static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
-  struct object *obj, const char *name)
+  struct object *obj, const char *name, struct 
object_context *oc)
 {
if (obj->type == OBJ_BLOB)
-   return grep_sha1(opt, obj->sha1, name, 0, NULL);
+   return grep_sha1(opt, obj->sha1, name, 0, oc ? oc->path : NULL);
if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
struct tree_desc tree;
void *data;
@@ -503,7 +503,7 @@ static int grep_objects(struct grep_opt *opt, const struct 
pathspec *pathspec,
for (i = 0; i < nr; i++) {
struct object *real_obj;
real_obj = deref_tag(list->objects[i].item, NULL, 0);
-   if (grep_object(opt, pathspec, real_obj, 
list->objects[i].name)) {
+   if (grep_object(opt, pathspec, real_obj, list->objects[i].name, 
list->objects[i].context)) {
hit = 1;
if (opt->status_only)
break;
@@ -820,12 +820,13 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
for (i = 0; i < argc; i++) {
const char *arg = argv[i];
unsigned char sha1[20];
+   struct object_context oc;
/* Is it a rev? */
-   if (!get_sha1(arg, sha1)) {
+   if (!get_sha1_with_context(arg, 0, sha1, &oc)) {
struct object *object = parse_object_or_die(sha1, arg);
if (!seen_dashdash)
verify_non_filename(prefix, arg);
-   add_object_array(object, arg, &list);
+   add_object_array_with_context(object, arg, &list, 
xmemdupz(&oc, sizeof(struct object_context)));
continue;
}
if (!strcmp(arg, "--")) {
diff --git a/object.c b/object.c
index 20703f5..c8ffc9e 100644
--- a/object.c
+++ b/object.c
@@ -255,12 +255,7 @@ int object_list_contains(struct object_list *list, struct 
object *obj)
return 0;
 }
 
-void add_object_array(struct object *obj, const char *name, struct 
object_array *array)
-{
-   add_object_array_with_mode(obj, name, array, S_IFINVALID);
-}
-
-void add_object_array_with_mode(struct object *obj, const char *name, struct 
object_array *array, unsigned mode)
+static void add_object_array_with_mode_context(struct object *obj, const char 
*name, struct object_array *array, unsigned mode, struct object_context 
*context)
 {
unsigned nr = array->nr;
unsigned alloc = array->alloc;
@@ -275,9 +270,28 @@ void add_object_array_with_mode(struct object *obj, const 
char *name, struct obj
objects[nr].item = obj;
objects[nr].name = name;
objects[nr].mode = mode;
+   objects[nr].context = context;
array->nr = ++nr;
 }
 
+void add_object_array(struct object *obj, const char *name, struct 
object_array *array)
+{
+   add_object_array_with_mode(obj, name, array, S_IFINVALID);
+}
+
+void add_object_array_with_mode(struct object *obj, const char *name, struct 
object_array *array, unsigned mode)
+{
+   add_object_array_with_mode_context(obj, name, array, mode, NULL);
+}
+
+void add_object_array_with_context(struct object *obj, const char *name, 
struct object_array *array, struct object_context *context)
+{
+   if (context)
+   add_object_array_with_mode_context(obj, name, array, 
context->mode, context);
+   else
+   add_object_array_with_mode_context(obj, name, array, 
S_IFINVALID, context);
+}
+
 void object_array_remove_duplicates(struct object_array *array)
 {
unsigned int ref, src, dst;
diff --git a/object.h b/object.h
index 97d384b..695847d 100644
--- a/object.h
+++ b/object.h
@@ -13,6 +13,7 @@ struct object_array {
struct object *item;
const char *name;
unsigned mode;
+   struct object_context *context;
} *objects;
 };
 
@@ -85,6 +86,7 @@ int object_list_contains(struct object_list *list, struct 
object *obj);
 /* Object array handling .. */
 void add_object_array(struct object *obj, const char *name, struct 
object_array *array);
 void add_object_array_with_mode(struct object *obj, const char *name, struct 
object_array *array