Re: [PATCH] color.h: document and modernize header

2018-02-14 Thread Stefan Beller
On Tue, Feb 13, 2018 at 11:23 PM, Eric Sunshine  wrote:
> On Mon, Feb 12, 2018 at 10:55 PM, Eric Sunshine  
> wrote:
>> On Mon, Feb 12, 2018 at 8:41 PM, Stefan Beller  wrote:
>>> + * Output the formatted string in the specified color (and then reset to 
>>> normal
>>> + * color so subsequent output is uncolored). Omits the color encapsulation 
>>> if
>>> + * `color` is NULL. The `color_fprintf_ln` prints a new line after 
>>> resetting
>>> + * the color.  BUG: The `color_print_strbuf` prints the given pre-formatted
>>> + * strbuf instead, up to its first NUL character.
>>
>> "`color_print_strbuf` prints the given pre-formatted strbuf (BUG: but
>> only up to the first NUL character)."
>>
>> Probably not worth a re-roll is Junio can amend it locally.
>
> By the way, thanks for the patience in the face of the nit-picking
> this patch has undergone.

In retrospect it is clear why we have so much nitpicking here
as it adds documentation to a part of git that is rather non-essential. ;-)

Thanks for bearing with my inability to write perfect code on the first try.


Re: [PATCH] color.h: document and modernize header

2018-02-13 Thread Eric Sunshine
On Mon, Feb 12, 2018 at 10:55 PM, Eric Sunshine  wrote:
> On Mon, Feb 12, 2018 at 8:41 PM, Stefan Beller  wrote:
>> + * Output the formatted string in the specified color (and then reset to 
>> normal
>> + * color so subsequent output is uncolored). Omits the color encapsulation 
>> if
>> + * `color` is NULL. The `color_fprintf_ln` prints a new line after resetting
>> + * the color.  BUG: The `color_print_strbuf` prints the given pre-formatted
>> + * strbuf instead, up to its first NUL character.
>
> "`color_print_strbuf` prints the given pre-formatted strbuf (BUG: but
> only up to the first NUL character)."
>
> Probably not worth a re-roll is Junio can amend it locally.

By the way, thanks for the patience in the face of the nit-picking
this patch has undergone.


Re: [PATCH] color.h: document and modernize header

2018-02-12 Thread Eric Sunshine
On Mon, Feb 12, 2018 at 8:41 PM, Stefan Beller  wrote:
> Add documentation explaining the functions in color.h.
> While at it, migrate the function `color_set` into grep.c,
> where the only callers are.
>
> Signed-off-by: Stefan Beller 
> ---
> diff --git a/color.h b/color.h
> @@ -76,22 +76,46 @@ int git_color_config(const char *var, const char *value, 
> void *cb);
> +/*
> + * Output the formatted string in the specified color (and then reset to 
> normal
> + * color so subsequent output is uncolored). Omits the color encapsulation if
> + * `color` is NULL. The `color_fprintf_ln` prints a new line after resetting
> + * the color.  BUG: The `color_print_strbuf` prints the given pre-formatted
> + * strbuf instead, up to its first NUL character.
> + */

"`color_print_strbuf` prints the given pre-formatted strbuf (BUG: but
only up to the first NUL character)."

Probably not worth a re-roll is Junio can amend it locally.


Re: [PATCH] color.h: document and modernize header

2018-02-12 Thread Eric Sunshine
On Mon, Feb 12, 2018 at 3:19 PM, Stefan Beller  wrote:
> Add documentation explaining the functions in color.h.
> While at it, mark them extern and migrate the function `color_set`
> into grep.c, where the only callers are.

This re-roll no longer marks functions as 'extern', so the commit
message saying that it does seems rather odd.

> Signed-off-by: Stefan Beller 
> ---
> diff --git a/color.h b/color.h
> @@ -76,22 +76,47 @@ int git_color_config(const char *var, const char *value, 
> void *cb);
> +/*
> + * Return a boolean whether to use color,
> + * resolving ambigious settings such as GIT_COLOR_AUTO, which is returned
> + * by git_config_colorbool().
> + */
>  int want_color(int var);

I'm probably being dense, but (if I hadn't had Peff's explanation[1]
to fall back on), based upon the comment block alone, I'd still have
no idea what I'm supposed to pass in as 'var'. Partly this is due to
the comment block not mentioning 'var' explicitly; it talks about
GIT_COLOR_AUTO and git_config_colorbool() abstractly, and, as a
reader, I can't tell if those are supposed to be passed in as 'var' or
if the function somehow grabs them out of the environment. Partly it's
due to the name "var" not conveying any useful meaning. Perhaps take
Peff's hint and state explicitly that the passed-in value is one of
GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO,
then further explain that that value comes from
git_config_colorbool(), possibly modified by local option processing,
such as --color.

[1]: https://public-inbox.org/git/20180208222851.ga8...@sigill.intra.peff.net/

> +/*
> + * Output the formatted string in the specified color (and then reset to 
> normal
> + * color so subsequent output is uncolored). Omits the color encapsulation if
> + * `color` is NULL. The `color_fprintf_ln` prints a new line after resetting
> + * the color. The `color_print_strbuf` prints the given pre-formatted strbuf
> + * instead, up to its first NUL character.
> + */

Perhaps prefix the last sentence with "BUG:" since we don't want
people relying on this NUL bug/misfeature.


Re: [PATCH] color.h: document and modernize header

2018-02-08 Thread Jeff King
On Thu, Feb 08, 2018 at 05:26:33PM -0500, Eric Sunshine wrote:

> > I think the point is that "var" is a quad-state variable (yes, no, auto,
> > or "unknown") and we are converting to a boolean. This would probably be
> > a lot more clear if GIT_COLOR_* were all enum values and not #defines,
> > and this function took the matching enum type.
> >
> > So I think that's what you were trying to name with "constants as
> > returned by...", but it definitely took me some thinking to parse it.
> 
> Rather than talking about plural "constants" (which makes it more
> confusing), it would likely be helpful for it to say (explicitly) that
> the caller passes in the result of git_config_colorbool() as 'var'.
> 
> Or something like that.

That's not quite it, though. "var" is really the current program's idea
of whether color has been requested. So it's git_config_colorbool(), as
modified by things like "--color".

I think the best explanation is that it resolves an "enum color_bool"
into a single 0/1 boolean. Except that "enum color_bool" doesn't exist,
so we have no name for it.

-Peff


Re: [PATCH] color.h: document and modernize header

2018-02-08 Thread Eric Sunshine
On Thu, Feb 8, 2018 at 3:43 PM, Jeff King  wrote:
> On Thu, Feb 08, 2018 at 12:15:46PM -0800, Stefan Beller wrote:
>> +/*
>> + * Resolve the constants as returned by git_config_colorbool()
>> + * (specifically "auto") to a boolean answer.
>> + */
>> +extern int want_color(int var);
>
> This explanation left me even more confused about what should go in
> "var", and I think I'm the one who wrote the function. ;)

Agreed, this still fails to (directly) answer the question I asked in
[1] about what 'var' is.

> I think the point is that "var" is a quad-state variable (yes, no, auto,
> or "unknown") and we are converting to a boolean. This would probably be
> a lot more clear if GIT_COLOR_* were all enum values and not #defines,
> and this function took the matching enum type.
>
> So I think that's what you were trying to name with "constants as
> returned by...", but it definitely took me some thinking to parse it.

Rather than talking about plural "constants" (which makes it more
confusing), it would likely be helpful for it to say (explicitly) that
the caller passes in the result of git_config_colorbool() as 'var'.

Or something like that.

>> +/*
>> + * Output the formatted string in the specified color (and then reset to 
>> normal
>> + * color so subsequent output is uncolored). Omits the color encapsulation 
>> if
>> + * `color` is NULL. The `color_fprintf_ln` prints a new line after resetting
>> + * the color. The `color_print_strbuf` prints the given pre-formatted strbuf
>> + * instead, up to its first NUL character.
>> + */
>
> It probably doesn't matter much in practice, but the color_print_strbuf
> behavior sounds like a bug. Shouldn't it print the whole strbuf, even if
> it has an embedded NUL?

I (parenthetically) suggested[1] the same about fixing the
bug/misbehavior, though doing so is outside the scope of this
particular patch.

[1]: 
https://public-inbox.org/git/capig+cqvgsqk3tj43v6f3rftd8smdxqwvug_u4__ewxoqg9...@mail.gmail.com/


Re: [PATCH] color.h: document and modernize header

2018-02-08 Thread Stefan Beller
On Thu, Feb 8, 2018 at 12:43 PM, Jeff King  wrote:
> On Thu, Feb 08, 2018 at 12:15:46PM -0800, Stefan Beller wrote:
>
>>  int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
>>  {
>>   va_list args;
>> diff --git a/color.h b/color.h
>> index fd2b688dfb..8c7e6c41c2 100644
>> --- a/color.h
>> +++ b/color.h
>> @@ -72,26 +72,50 @@ extern int color_stdout_is_tty;
>>   * Use the first one if you need only color config; the second is a 
>> convenience
>>   * if you are just going to change to git_default_config, too.
>>   */
>> -int git_color_config(const char *var, const char *value, void *cb);
>> -int git_color_default_config(const char *var, const char *value, void *cb);
>> +extern int git_color_config(const char *var, const char *value, void *cb);
>> +extern int git_color_default_config(const char *var, const char *value, 
>> void *cb);
>
> Hmph, I thought we weren't adding "extern" everywhere. See:
>
>   https://public-inbox.org/git/xmqq8tea5hxi@gitster.mtv.corp.google.com/
>
> Other than that, these changes mostly look like improvements. A few

...

> Those are all suggestions. Given that there's no documentation currently
> on most of these, I think even if you don't take any of my suggestions,
> this would still be a net improvement (modulo the "extern" thing).

A funny and sad rant about why clear communication matters:

[Once upon a time, maybe 2 years ago] I had the impression that the old
code is nicely written and was consistently marked extern in header files.
(which btw is consistent with variable declarations, they need the extern).
All the new code doesn't make use of extern, so I had this on my low prio
todo list, that eventually all code converges to have 'extern'
functions in headers.

C.f. the following commits, found via
  git log -p --author=Beller -S extern

  5ec8274b84 (xdiff-interface: export comparing and hashing strings,
  2017-10-25) adding new externs

  1ecbf31d02 (hashmap: migrate documentation from Documentation/technical
  into header, 2017-06-30), a cleanup, which doesn't touch externs

  a6d7eb2c7a (pull: optionally rebase submodules (remote submodule
  changes only), 2017-06-23) new code using externs

  bd26756112 (submodule.h: add extern keyword to functions, 2016-12-20)
  (The commit message is as accurate as it gets)

You may sense a pattern here: I currently have the very firm understanding
we use the extern keyword in our codebase.

And I can also attest that this was not always the case, as back in the
day I remember writing patches without the extern keyword only to be told:
(A) be similar to the function in the next lines
(B) the standard is to use extern
and I was convinced it was a bad decision to prefix declarations with
the extern keyword, but followed along as I don't want to have style
in the way of writing features.

  $ cat Documentation/CodingGuidelines |grep extern
  $ # oh no it's empty!

Care to add a section to our coding guidelines?

Thanks,
Stefan


Re: [PATCH] color.h: document and modernize header

2018-02-08 Thread Jeff King
On Thu, Feb 08, 2018 at 12:15:46PM -0800, Stefan Beller wrote:

>  int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
>  {
>   va_list args;
> diff --git a/color.h b/color.h
> index fd2b688dfb..8c7e6c41c2 100644
> --- a/color.h
> +++ b/color.h
> @@ -72,26 +72,50 @@ extern int color_stdout_is_tty;
>   * Use the first one if you need only color config; the second is a 
> convenience
>   * if you are just going to change to git_default_config, too.
>   */
> -int git_color_config(const char *var, const char *value, void *cb);
> -int git_color_default_config(const char *var, const char *value, void *cb);
> +extern int git_color_config(const char *var, const char *value, void *cb);
> +extern int git_color_default_config(const char *var, const char *value, void 
> *cb);

Hmph, I thought we weren't adding "extern" everywhere. See:

  https://public-inbox.org/git/xmqq8tea5hxi@gitster.mtv.corp.google.com/

Other than that, these changes mostly look like improvements. A few
comments:

> +/*
> + * Resolve the constants as returned by git_config_colorbool()
> + * (specifically "auto") to a boolean answer.
> + */
> +extern int want_color(int var);

This explanation left me even more confused about what should go in
"var", and I think I'm the one who wrote the function. ;)

I think the point is that "var" is a quad-state variable (yes, no, auto,
or "unknown") and we are converting to a boolean. This would probably be
a lot more clear if GIT_COLOR_* were all enum values and not #defines,
and this function took the matching enum type.

So I think that's what you were trying to name with "constants as
returned by...", but it definitely took me some thinking to parse it.

> +/*
> + * Translate a Git color from 'value' into a string that the terminal can
> + * interpret and store it into 'dst'. The Git color values are of the form
> + * "foreground [background] [attr]" where fore- and background can be a color
> + * name ("red"), a RGB code (#0xFF) or a 256-color-mode from the 
> terminal.
> + */
> +extern int color_parse(const char *value, char *dst);
> +extern int color_parse_mem(const char *value, int len, char *dst);

The inputs here are called "value" mostly because we feed them from the
var/value pair of config. But maybe "colorspec", or even just "src"
would be more clear than "value".

> +/*
> + * Output the formatted string in the specified color (and then reset to 
> normal
> + * color so subsequent output is uncolored). Omits the color encapsulation if
> + * `color` is NULL. The `color_fprintf_ln` prints a new line after resetting
> + * the color. The `color_print_strbuf` prints the given pre-formatted strbuf
> + * instead, up to its first NUL character.
> + */

It probably doesn't matter much in practice, but the color_print_strbuf
behavior sounds like a bug. Shouldn't it print the whole strbuf, even if
it has an embedded NUL?

> +/*
> + * Check if the given color is GIT_COLOR_NIL that means "no color selected".
> + * The caller needs to replace the color with the actual desired color.
> + */
> +extern int color_is_nil(const char *color);

Is this a parsed color string, or a human-readable source? I think
consistent naming of the two variables would help (using a type doesn't
work since they're both "const char *").

> diff --git a/grep.c b/grep.c
> index 3d7cd0e96f..834b8eb439 100644
> --- a/grep.c
> +++ b/grep.c
> @@ -18,6 +18,11 @@ static void std_output(struct grep_opt *opt, const void 
> *buf, size_t size)
>   fwrite(buf, size, 1, stdout);
>  }
>  
> +static void color_set(char *dst, const char *color_bytes)
> +{
> + xsnprintf(dst, COLOR_MAXLEN, "%s", color_bytes);
> +}
> +

This part seems OK. I think we made color_set() globally available with
the notion that other callers might make use of it. But it's pretty
horrid as public interfaces go, requiring that the caller has created a
buffer of the appropriate size. We'd do better to have a "struct color"
with the correctly-sized buffer. But at this point I don't think it's worth
overhauling the color code.


Those are all suggestions. Given that there's no documentation currently
on most of these, I think even if you don't take any of my suggestions,
this would still be a net improvement (modulo the "extern" thing).

-Peff