* [PATCH] document string_list_clear
@ 2014-12-06 1:51 Stefan Beller
2014-12-06 2:04 ` Jonathan Nieder
0 siblings, 1 reply; 49+ messages in thread
From: Stefan Beller @ 2014-12-06 1:51 UTC (permalink / raw)
To: gitster, git; +Cc: Stefan Beller
Signed-off-by: Stefan Beller <sbeller@google.com>
---
Just stumbled accross this one and wasn't sure if it also frees up
the memory involved.
string-list.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/string-list.h b/string-list.h
index 494eb5d..99ecc44 100644
--- a/string-list.h
+++ b/string-list.h
@@ -21,6 +21,11 @@ struct string_list {
void string_list_init(struct string_list *list, int strdup_strings);
void print_string_list(const struct string_list *p, const char *text);
+
+/*
+ * Clears the string list, so it has zero items. All former items are freed.
+ * If free_util is true, all util pointers are also freed.
+ */
void string_list_clear(struct string_list *list, int free_util);
/* Use this function to call a custom clear function on each util pointer */
--
2.2.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-06 1:51 [PATCH] document string_list_clear Stefan Beller
@ 2014-12-06 2:04 ` Jonathan Nieder
2014-12-06 5:27 ` Jeff King
` (2 more replies)
0 siblings, 3 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-06 2:04 UTC (permalink / raw)
To: Stefan Beller; +Cc: gitster, git
Stefan Beller wrote:
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>
> Just stumbled accross this one and wasn't sure if it also frees up
> the memory involved.
>
> string-list.h | 5 +++++
> 1 file changed, 5 insertions(+)
Sounds reasonable. Documentation/technical/api-string-list.txt
documents these functions more fully. The right balance between
documenting things in two places vs. adding "see also" pointers vs.
just putting the highlights in one of the two places isn't obvious to
me.
[...]
> --- a/string-list.h
> +++ b/string-list.h
> @@ -21,6 +21,11 @@ struct string_list {
> void string_list_init(struct string_list *list, int strdup_strings);
>
> void print_string_list(const struct string_list *p, const char *text);
> +
> +/*
> + * Clears the string list, so it has zero items. All former items are freed.
> + * If free_util is true, all util pointers are also freed.
> + */
> void string_list_clear(struct string_list *list, int free_util);
The api doc says
Free a string_list. The `string` pointer of the items will be freed in
case the `strdup_strings` member of the string_list is set. The second
parameter controls if the `util` pointer of the items should be freed
or not.
One option here would be to say
Free a string_list. See Documentation/technical/api-string-list.txt
for details.
That reminds me: why do we call this string_list_clear instead of
string_list_free?
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-06 2:04 ` Jonathan Nieder
@ 2014-12-06 5:27 ` Jeff King
2014-12-06 5:30 ` Jeff King
2014-12-09 19:37 ` Junio C Hamano
2 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2014-12-06 5:27 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Stefan Beller, gitster, git
On Fri, Dec 05, 2014 at 06:04:58PM -0800, Jonathan Nieder wrote:
> That reminds me: why do we call this string_list_clear instead of
> string_list_free?
Because it does not free the struct itself, and because you can then use
the result again. I think we try to draw a distinction between:
/* Free resources, but do not reinitialize! */
void string_list_free_data(struct string_list *s)
{
int i;
for (i = 0; i < s->nr; i++)
free(s->items[i].string);
free(s->items[i];
}
/* Free resources, and go back to initialized but empty state */
void string_list_clear(struct string_list *s)
{
string_list_free_data(s);
s->nr = s->alloc = 0;
s->items = NULL;
}
/* Free all resources from dynamically allocated structure */
void string_list_free(struct string_list *s)
{
string_list_clear(s);
free(s);
}
Ideally we use consistent names to distinguish between them. We are not
always consistent, though (probably strbuf_release should be called
strbuf_clear for consistency). But I think we are fairly consistent that
"_free()" means "...and free the pointer, too".
In general, we try to avoid the first as a public interface (because it
is error-prone when somebody tries to reuse the list, and the extra work
of zero-ing the pointer is not enough to care about).
We also tend to avoid the third, because it is quite often not the
business of the object whether it was dynamically constructed or not
(exceptions tend to be node-oriented structures like linked lists and
trees; c.f. cache_tree and commit_list).
Maybe that should go into CodingGuidelines? It's not really style,
exactly, but it is convention.
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-06 2:04 ` Jonathan Nieder
2014-12-06 5:27 ` Jeff King
@ 2014-12-06 5:30 ` Jeff King
2014-12-09 19:41 ` Junio C Hamano
2014-12-09 19:37 ` Junio C Hamano
2 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2014-12-06 5:30 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Stefan Beller, gitster, git
On Fri, Dec 05, 2014 at 06:04:58PM -0800, Jonathan Nieder wrote:
> Stefan Beller wrote:
>
> > Signed-off-by: Stefan Beller <sbeller@google.com>
> > ---
> >
> > Just stumbled accross this one and wasn't sure if it also frees up
> > the memory involved.
> >
> > string-list.h | 5 +++++
> > 1 file changed, 5 insertions(+)
>
> Sounds reasonable. Documentation/technical/api-string-list.txt
> documents these functions more fully. The right balance between
> documenting things in two places vs. adding "see also" pointers vs.
> just putting the highlights in one of the two places isn't obvious to
> me.
Also, I forgot to mention: if we consistently put the API docs into the
header files and extracted it automatically into standalone documents,
we would not need to have two places.
This is something I've been meaning to look at for a long time, but it
never quite makes the priority list. And my past experiences with tools
like doxygen has been that they are complicated and have a lot of
dependencies. It's been a long time since I've tried, though.
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-06 2:04 ` Jonathan Nieder
2014-12-06 5:27 ` Jeff King
2014-12-06 5:30 ` Jeff King
@ 2014-12-09 19:37 ` Junio C Hamano
2014-12-09 19:48 ` Stefan Beller
2014-12-09 20:00 ` Jonathan Nieder
2 siblings, 2 replies; 49+ messages in thread
From: Junio C Hamano @ 2014-12-09 19:37 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Stefan Beller, git
Jonathan Nieder <jrnieder@gmail.com> writes:
>> +/*
>> + * Clears the string list, so it has zero items. All former items are freed.
>> + * If free_util is true, all util pointers are also freed.
>> + */
>> void string_list_clear(struct string_list *list, int free_util);
>
> The api doc says
>
> Free a string_list. The `string` pointer of the items will be freed in
> case the `strdup_strings` member of the string_list is set. The second
> parameter controls if the `util` pointer of the items should be freed
> or not.
>
> One option here would be to say
>
> Free a string_list. See Documentation/technical/api-string-list.txt
> for details.
If we later introduce string_list_free() that is in line with the
distinction between "free" and "clear" discussed on this thread, the
comment for this function needs to be fixed to "Clear the string
list. See $doc". and that is not much different from "See $doc"
without the first sentence which is the function name.
Perhaps the API doc that currently says "Free" is the only thing
that needs fixing? And perhaps add "See $doc" at the beginning of
the header and remove duplicated comments we already have in the
file?
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-06 5:30 ` Jeff King
@ 2014-12-09 19:41 ` Junio C Hamano
2014-12-09 20:15 ` Jeff King
0 siblings, 1 reply; 49+ messages in thread
From: Junio C Hamano @ 2014-12-09 19:41 UTC (permalink / raw)
To: Jeff King; +Cc: Jonathan Nieder, Stefan Beller, git
Jeff King <peff@peff.net> writes:
> Also, I forgot to mention: if we consistently put the API docs into the
> header files and extracted it automatically into standalone documents,
> we would not need to have two places.
>
> This is something I've been meaning to look at for a long time, but it
> never quite makes the priority list. And my past experiences with tools
> like doxygen has been that they are complicated and have a lot of
> dependencies. It's been a long time since I've tried, though.
Yeah, that is a thought.
Some existing documentation pages like allocation-growing may not be
a good match for this strategy, though; cache.h has a lot more than
just alloc-grow, and there needs to be a way to generate more than
one API docs from a single header (and vice versa, taking text from
more than one source for a single API, I suspect).
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 19:37 ` Junio C Hamano
@ 2014-12-09 19:48 ` Stefan Beller
2014-12-09 20:17 ` Jonathan Nieder
2014-12-09 20:00 ` Jonathan Nieder
1 sibling, 1 reply; 49+ messages in thread
From: Stefan Beller @ 2014-12-09 19:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jonathan Nieder, git@vger.kernel.org
On Tue, Dec 9, 2014 at 11:37 AM, Junio C Hamano <gitster@pobox.com> wrote:
>
> Perhaps the API doc that currently says "Free" is the only thing
> that needs fixing? And perhaps add "See $doc" at the beginning of
> the header and remove duplicated comments we already have in the
> file?
The reason I wrote this patch originally was because I seem to forget we have
more than one place to document our APIs. If there are comments in the header
I seem to have thought it were the only place where we have documentation.
But as we have some comments in the header for about half the functions there,
I missed looking into the Documentation at all.
I'd support Jeffs efforts to only write doc into the headers and then
export it or just
have documentation in the Documentation/technical dir. If there is
only one way to obtain
the information I wouldn't send in patches duplicating information.
Personally I first visit the header files to see if there is
documentation/comments on the
desired function. Looking at Documentation/technical/ is only reserved
for high lievel discussion on
API choices, so everything not prefixed with "api-" there.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 19:37 ` Junio C Hamano
2014-12-09 19:48 ` Stefan Beller
@ 2014-12-09 20:00 ` Jonathan Nieder
1 sibling, 0 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-09 20:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Stefan Beller, git
Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>>> +/*
>>> + * Clears the string list, so it has zero items. All former items are freed.
>>> + * If free_util is true, all util pointers are also freed.
>>> + */
>>> void string_list_clear(struct string_list *list, int free_util);
>>
>> The api doc says
>>
>> Free a string_list. The `string` pointer of the items will be freed in
>> case the `strdup_strings` member of the string_list is set. The second
>> parameter controls if the `util` pointer of the items should be freed
>> or not.
>>
>> One option here would be to say
>>
>> Free a string_list. See Documentation/technical/api-string-list.txt
>> for details.
>
> If we later introduce string_list_free() that is in line with the
> distinction between "free" and "clear" discussed on this thread, the
> comment for this function needs to be fixed to "Clear the string
> list. See $doc". and that is not much different from "See $doc"
> without the first sentence which is the function name.
I still find the term "clear" to be confusing here. It makes me think
the function will be analagous to strbuf_reset, when it's actually
analagous to strbuf_release.
In other words, the important thing is that this frees all members of
the string_list. There might be a clearer way to say that. The
string_list itself may not be dynamically allocated --- I'm not sure
what it would mean to free it.
How about string_list_release?
I think I could get used to "clear" if we used it consistently though.
I suspect anything we do will be confusing, unless we make them
consistent.
> Perhaps the API doc that currently says "Free" is the only thing
> that needs fixing?
I find the API doc to be pretty clear, actually. If someone was
confused in practice then I'd be happy to try to debug the wording.
> And perhaps add "See $doc" at the beginning of
> the header and remove duplicated comments we already have in the
> file?
Yes, that sounds like a good way to go about it.
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 19:41 ` Junio C Hamano
@ 2014-12-09 20:15 ` Jeff King
2014-12-09 20:21 ` Jonathan Nieder
0 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2014-12-09 20:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jonathan Nieder, Stefan Beller, git
On Tue, Dec 09, 2014 at 11:41:44AM -0800, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
>
> > Also, I forgot to mention: if we consistently put the API docs into the
> > header files and extracted it automatically into standalone documents,
> > we would not need to have two places.
> >
> > This is something I've been meaning to look at for a long time, but it
> > never quite makes the priority list. And my past experiences with tools
> > like doxygen has been that they are complicated and have a lot of
> > dependencies. It's been a long time since I've tried, though.
>
> Yeah, that is a thought.
>
> Some existing documentation pages like allocation-growing may not be
> a good match for this strategy, though; cache.h has a lot more than
> just alloc-grow, and there needs to be a way to generate more than
> one API docs from a single header (and vice versa, taking text from
> more than one source for a single API, I suspect).
I think that would be a matter of tool support for saying "now I am
outputting api-foo" in the inline documentation[1]. It does make writing
Makefiles a lot harder, though, if there isn't a one-to-one
correspondence between targets and their sources. Perhaps it is a sign
that we should split our include files more along functional boundaries.
If we cannot make sane documentation out of the file, then it is
probably confusing for humans to read it.
Opening cache.h shows it starting with git_{in,de}flate_*, and then
DEFAULT_GIT_PORT!? It has long been a dumping ground for random global
functions and definitions. If we are going to document subsystems,
splitting them into their own files seems sensible. Skimming through the
file, some of the splits seem pretty easy and obvious.
-Peff
[1] I do not have a tool in mind, so this is something to think about
while evaluating them. It seems like just parsing:
/**
* All of this will get dumped in a file (sans asterisks),
* which can then be fed to asciidoc. The "**" marker
* starts the docstring, which ends at the normal comment
* boundary.
*/
would be an easy place to start, and by implementing it ourselves
with sed we would be free to implement any other rules we wanted.
That is probably too naive, though. It would be nice if the tool
actually understood C function declarations, so that we would not
have to repeat them manually in the comments.
I guess all tools like doxygen probably started off as "just pull
out and format the comments", and then grew and grew in complexity. :)
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 19:48 ` Stefan Beller
@ 2014-12-09 20:17 ` Jonathan Nieder
2014-12-09 20:27 ` Jeff King
2014-12-09 22:49 ` Jonathan Nieder
0 siblings, 2 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-09 20:17 UTC (permalink / raw)
To: Stefan Beller
Cc: Junio C Hamano, git@vger.kernel.org, Jeff King, Michael Haggerty
Stefan Beller wrote:
> On Tue, Dec 9, 2014 at 11:37 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Perhaps the API doc that currently says "Free" is the only thing
>> that needs fixing? And perhaps add "See $doc" at the beginning of
>> the header and remove duplicated comments we already have in the
>> file?
>
> The reason I wrote this patch originally was because I seem to forget we have
> more than one place to document our APIs. If there are comments in the header
> I seem to have thought it were the only place where we have documentation.
How about this patch?
-- >8 --
Subject: put strbuf API documentation in one place
v1.8.1-rc0~61^2 (strbuf_split*(): document functions, 2012-11-04)
added some nice API documentation for a few functions to strbuf.h, to
complement the documentation at Documentation/technical/api-strbuf.
That was helpful because it meant one less hop for someone reading the
header to find API documentation.
In practice, unfortunately, it is too hard to remember that there
is documentation in two places. The longer documentation comments
in the header made Documentation/technical/api-strbuf less
discoverable. So move the information to
Documentation/technical/api-strbuf and drop the long comments.
Hopefully in the long term we will find a good way to
generate well organized Documentation/technical/api-* documents
from comments in headers and this problem will be eliminated
completely.
Short reminders in the header file are still okay.
Reported-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/technical/api-strbuf.txt | 20 +++++++++++++++--
strbuf.h | 40 ++--------------------------------
2 files changed, 20 insertions(+), 40 deletions(-)
diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt
index cca6543..a43facc 100644
--- a/Documentation/technical/api-strbuf.txt
+++ b/Documentation/technical/api-strbuf.txt
@@ -252,6 +252,11 @@ which can be used by the programmer of the callback as she sees fit.
destination. This is useful for literal data to be fed to either
strbuf_expand or to the *printf family of functions.
+`strbuf_addstr_xml_quoted`::
+
+ Append a string to a strbuf with the characters '<', '>', '&', and
+ '"' converted into XML entities.
+
`strbuf_humanise_bytes`::
Append the given byte size as a human-readable string (i.e. 12.23 KiB,
@@ -266,6 +271,13 @@ which can be used by the programmer of the callback as she sees fit.
Add a formatted string prepended by a comment character and a
blank to the buffer.
+`xstrfmt`::
+`xstrvfmt`::
+
+ Create a newly allocated string using printf format. You can do
+ this easily with a strbuf, but this provides a shortcut to save a
+ few lines.
+
`strbuf_fread`::
Read a given size of data from a FILE* pointer to the buffer.
@@ -336,11 +348,15 @@ same behaviour as well.
terminator characters. Some of these functions take a `max`
parameter, which, if positive, limits the output to that
number of substrings.
++
+For lighter-weight alternatives, see `string_list_split` and
+`string_list_split_in_place` from the
+link:api-string-list.html[string list API].
`strbuf_list_free`::
- Free a list of strbufs (for example, the return values of the
- `strbuf_split()` functions).
+ Free a NULL-terminated list of strbufs (for example, the return
+ values of the `strbuf_split()` functions).
`launch_editor`::
diff --git a/strbuf.h b/strbuf.h
index 652b6c4..f3c9bb6 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -58,56 +58,27 @@ static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
return 0;
}
-/*
- * Split str (of length slen) at the specified terminator character.
- * Return a null-terminated array of pointers to strbuf objects
- * holding the substrings. The substrings include the terminator,
- * except for the last substring, which might be unterminated if the
- * original string did not end with a terminator. If max is positive,
- * then split the string into at most max substrings (with the last
- * substring containing everything following the (max-1)th terminator
- * character).
- *
- * For lighter-weight alternatives, see string_list_split() and
- * string_list_split_in_place().
- */
-extern struct strbuf **strbuf_split_buf(const char *, size_t,
+extern struct strbuf **strbuf_split_buf(const char *str, size_t slen,
int terminator, int max);
-/*
- * Split a NUL-terminated string at the specified terminator
- * character. See strbuf_split_buf() for more information.
- */
static inline struct strbuf **strbuf_split_str(const char *str,
int terminator, int max)
{
return strbuf_split_buf(str, strlen(str), terminator, max);
}
-/*
- * Split a strbuf at the specified terminator character. See
- * strbuf_split_buf() for more information.
- */
static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,
int terminator, int max)
{
return strbuf_split_buf(sb->buf, sb->len, terminator, max);
}
-/*
- * Split a strbuf at the specified terminator character. See
- * strbuf_split_buf() for more information.
- */
static inline struct strbuf **strbuf_split(const struct strbuf *sb,
int terminator)
{
return strbuf_split_max(sb, terminator, 0);
}
-/*
- * Free a NULL-terminated list of strbufs (for example, the return
- * values of the strbuf_split*() functions).
- */
extern void strbuf_list_free(struct strbuf **);
/*----- add data in your buffer -----*/
@@ -158,10 +129,7 @@ extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
-/*
- * Append s to sb, with the characters '<', '>', '&' and '"' converted
- * into XML entities.
- */
+/* append s with <, >, &, and " converted to XML entities */
extern void strbuf_addstr_xml_quoted(struct strbuf *sb, const char *s);
static inline void strbuf_complete_line(struct strbuf *sb)
@@ -200,10 +168,6 @@ extern int fprintf_ln(FILE *fp, const char *fmt, ...);
char *xstrdup_tolower(const char *);
-/*
- * Create a newly allocated string using printf format. You can do this easily
- * with a strbuf, but this provides a shortcut to save a few lines.
- */
__attribute__((format (printf, 1, 0)))
char *xstrvfmt(const char *fmt, va_list ap);
__attribute__((format (printf, 1, 2)))
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 20:15 ` Jeff King
@ 2014-12-09 20:21 ` Jonathan Nieder
0 siblings, 0 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-09 20:21 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, Stefan Beller, git
Jeff King wrote:
> On Tue, Dec 09, 2014 at 11:41:44AM -0800, Junio C Hamano wrote:
>> Yeah, that is a thought.
>>
>> Some existing documentation pages like allocation-growing may not be
>> a good match for this strategy, though; cache.h has a lot more than
>> just alloc-grow, and there needs to be a way to generate more than
>> one API docs from a single header (and vice versa, taking text from
>> more than one source for a single API, I suspect).
>
> I think that would be a matter of tool support for saying "now I am
> outputting api-foo" in the inline documentation[1]. It does make writing
> Makefiles a lot harder, though, if there isn't a one-to-one
> correspondence between targets and their sources. Perhaps it is a sign
> that we should split our include files more along functional boundaries.
Yeah, I think a separate alloc-grow.h would be fine.
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 20:17 ` Jonathan Nieder
@ 2014-12-09 20:27 ` Jeff King
2014-12-09 20:32 ` Stefan Beller
2014-12-09 22:23 ` Jonathan Nieder
2014-12-09 22:49 ` Jonathan Nieder
1 sibling, 2 replies; 49+ messages in thread
From: Jeff King @ 2014-12-09 20:27 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Tue, Dec 09, 2014 at 12:17:13PM -0800, Jonathan Nieder wrote:
> Stefan Beller wrote:
> > On Tue, Dec 9, 2014 at 11:37 AM, Junio C Hamano <gitster@pobox.com> wrote:
>
> >> Perhaps the API doc that currently says "Free" is the only thing
> >> that needs fixing? And perhaps add "See $doc" at the beginning of
> >> the header and remove duplicated comments we already have in the
> >> file?
> >
> > The reason I wrote this patch originally was because I seem to forget we have
> > more than one place to document our APIs. If there are comments in the header
> > I seem to have thought it were the only place where we have documentation.
>
> How about this patch?
>
> -- >8 --
> Subject: put strbuf API documentation in one place
>
> v1.8.1-rc0~61^2 (strbuf_split*(): document functions, 2012-11-04)
> added some nice API documentation for a few functions to strbuf.h, to
> complement the documentation at Documentation/technical/api-strbuf.
> That was helpful because it meant one less hop for someone reading the
> header to find API documentation.
>
> In practice, unfortunately, it is too hard to remember that there
> is documentation in two places. The longer documentation comments
> in the header made Documentation/technical/api-strbuf less
> discoverable. So move the information to
> Documentation/technical/api-strbuf and drop the long comments.
>
> Hopefully in the long term we will find a good way to
> generate well organized Documentation/technical/api-* documents
> from comments in headers and this problem will be eliminated
> completely.
>
> Short reminders in the header file are still okay.
I somewhat feel this goes in the opposite direction of where we want to
be (all data in one place, but that place is the header). Your patch
might make api-strbuf more discoverable, but it also vastly increases
the chances of function getting out of sync with their documentation, or
new functions being added without getting documented (very often the
presence of other documentation in the comments is enough to guilt me
into writing it for new ones).
Elsewhere I mentioned a tool to extract comments and format them. But do
people actually care about the formatting step? Does anybody asciidoc
the technical/api-* files? We did not even support building them until
sometime in 2012. Personally, I only ever view them as text.
In which case can we simply start migrating api-strbuf.txt into
in-header comments, without worrying about a parsing tool?
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 20:27 ` Jeff King
@ 2014-12-09 20:32 ` Stefan Beller
2014-12-09 20:46 ` Jeff King
2014-12-09 22:23 ` Jonathan Nieder
1 sibling, 1 reply; 49+ messages in thread
From: Stefan Beller @ 2014-12-09 20:32 UTC (permalink / raw)
To: Jeff King
Cc: Jonathan Nieder, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Tue, Dec 9, 2014 at 12:27 PM, Jeff King <peff@peff.net> wrote:
>
> In which case can we simply start migrating api-strbuf.txt into
> in-header comments, without worrying about a parsing tool?
>
> -Peff
That would be my preference as well. Putting the API documentation
into the header files. Optionally if you're fancy you may enjoy the generated
API documentation. But I personally would rather look into the header for
the most up to date information.
As said above the Documentation/technical would only serve a purpose to
explain very high level concepts. So racy-git.txt or
pack-heuristics.txt will fit
in there very good.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 20:32 ` Stefan Beller
@ 2014-12-09 20:46 ` Jeff King
0 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2014-12-09 20:46 UTC (permalink / raw)
To: Stefan Beller
Cc: Jonathan Nieder, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Tue, Dec 09, 2014 at 12:32:15PM -0800, Stefan Beller wrote:
> As said above the Documentation/technical would only serve a purpose to
> explain very high level concepts. So racy-git.txt or
> pack-heuristics.txt will fit
> in there very good.
Yeah, I think we would leave anything that isn't api-*, with the goal
that all of api-* would eventually migrate into headers (it does not all
have to happen on day one, of course). There are a few spots which do
refer to api-credential, which is where you can find information on the
credential protocol. But that could be split out into a separate
technical document (which is probably an improvement, anyway; people who
are writing a helper do not know or care about our internal C API; they
only care about the protocol).
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 20:27 ` Jeff King
2014-12-09 20:32 ` Stefan Beller
@ 2014-12-09 22:23 ` Jonathan Nieder
2014-12-09 23:18 ` Junio C Hamano
2014-12-10 8:43 ` Jeff King
1 sibling, 2 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-09 22:23 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
> Elsewhere I mentioned a tool to extract comments and format them. But do
> people actually care about the formatting step?
If formatting means "convert to a straightforward text document that I
can read through", then I do.
> Does anybody asciidoc
> the technical/api-* files? We did not even support building them until
> sometime in 2012. Personally, I only ever view them as text.
I also view them as text. I tend to find it easier to read the
technical/api-* files than headers. That might be for the same reason
that some other people prefer header files --- a
Documentation/technical/ file tends to be written in one chunk
together and ends up saying exactly what I need to know about the
calling sequence in a coherent way, while header files tend to evolve
over time to match the implementation without maintaining that
organization and usability.
I suspect a simple tool to extract the comments and produce something
like the technical/api-* files would help, since then when someone
writes a patch, they could try the tool and see if the result is still
easy to read.
Anyway, the patch I wrote was an attempt at a minimal fix (and an
attempt at getting out of a conversation that seemed to be moving
toward bikeshedding). If someone wants to move the documentation from
api-strbuf.txt to strbuf.h, I won't object, since I hope that a simple
tool like described above isn't too far away.
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 20:17 ` Jonathan Nieder
2014-12-09 20:27 ` Jeff King
@ 2014-12-09 22:49 ` Jonathan Nieder
2014-12-09 23:07 ` Stefan Beller
1 sibling, 1 reply; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-09 22:49 UTC (permalink / raw)
To: Stefan Beller
Cc: Junio C Hamano, git@vger.kernel.org, Jeff King, Michael Haggerty
Jonathan Nieder wrote:
> Stefan Beller wrote:
>> On Tue, Dec 9, 2014 at 11:37 AM, Junio C Hamano <gitster@pobox.com> wrote:
>>> Perhaps the API doc that currently says "Free" is the only thing
>>> that needs fixing? And perhaps add "See $doc" at the beginning of
>>> the header and remove duplicated comments we already have in the
>>> file?
>>
>> The reason I wrote this patch originally was because I seem to forget we have
>> more than one place to document our APIs. If there are comments in the header
>> I seem to have thought it were the only place where we have documentation.
>
> How about this patch?
And another:
-- >8--
Subject: put string-list API documentation in one place
Until recently (v1.8.0-rc0~46^2~5, 2012-09-12), the string-list API
was documented in detail in Documentation/technical/api-string-list.txt
and the header file contained section markers and some short reminders
but little other documentation.
Since then, the header has acquired some more comments that are mostly
identical to the documentation from technical/. In principle that
should help convenience, since it means one less hop for someone
reading the header to find API documentation. In practice,
unfortunately, it is hard to remember that there is documentation in
two places, and the comprehensive documentation of some functions in
the header makes it too easy to forget that the other functions are
documented at all (and where).
Add a comment pointing to Documentation/technical/ and remove the
comments that duplicate what is written there. Longer term, we may
want to move all of the technical docs to header files and generate
printer-ready API documentation another way, but that is a larger
change for another day.
Short reminders in the header file are still okay.
Reported-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/technical/api-string-list.txt | 12 ++++++-
string-list.h | 56 ++---------------------------
2 files changed, 14 insertions(+), 54 deletions(-)
diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt
index d51a657..a85e713 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -185,7 +185,17 @@ overwriting the delimiter characters with NULs and creating new
string_list_items that point into the original string (the original
string must therefore not be modified or freed while the `string_list`
is in use).
-
++
+Examples:
++
+----
+string_list_split(l, "foo:bar:baz", ':', -1) -> ["foo", "bar", "baz"]
+string_list_split(l, "foo:bar:baz", ':', 0) -> ["foo:bar:baz"]
+string_list_split(l, "foo:bar:baz", ':', 1) -> ["foo", "bar:baz"]
+string_list_split(l, "foo:bar:", ':', -1) -> ["foo", "bar", ""]
+string_list_split(l, "", ':', -1) -> [""]
+string_list_split(l, ":", ':', -1) -> ["", ""]
+----
Data structures
---------------
diff --git a/string-list.h b/string-list.h
index 494eb5d..e6a7841 100644
--- a/string-list.h
+++ b/string-list.h
@@ -1,6 +1,8 @@
#ifndef STRING_LIST_H
#define STRING_LIST_H
+/* See Documentation/technical/api-string-list.txt */
+
struct string_list_item {
char *string;
void *util;
@@ -35,20 +37,9 @@ int for_each_string_list(struct string_list *list,
#define for_each_string_list_item(item,list) \
for (item = (list)->items; item < (list)->items + (list)->nr; ++item)
-/*
- * Apply want to each item in list, retaining only the ones for which
- * the function returns true. If free_util is true, call free() on
- * the util members of any items that have to be deleted. Preserve
- * the order of the items that are retained.
- */
void filter_string_list(struct string_list *list, int free_util,
string_list_each_func_t want, void *cb_data);
-/*
- * Remove any empty strings from the list. If free_util is true, call
- * free() on the util members of any items that have to be deleted.
- * Preserve the order of the items that are retained.
- */
void string_list_remove_empty_items(struct string_list *list, int free_util);
/* Use these functions only on sorted lists: */
@@ -59,30 +50,12 @@ struct string_list_item *string_list_insert(struct string_list *list, const char
struct string_list_item *string_list_insert_at_index(struct string_list *list,
int insert_at, const char *string);
struct string_list_item *string_list_lookup(struct string_list *list, const char *string);
-
-/*
- * Remove all but the first of consecutive entries with the same
- * string value. If free_util is true, call free() on the util
- * members of any items that have to be deleted.
- */
void string_list_remove_duplicates(struct string_list *sorted_list, int free_util);
/* Use these functions only on unsorted lists: */
-/*
- * Add string to the end of list. If list->strdup_string is set, then
- * string is copied; otherwise the new string_list_entry refers to the
- * input string.
- */
struct string_list_item *string_list_append(struct string_list *list, const char *string);
-
-/*
- * Like string_list_append(), except string is never copied. When
- * list->strdup_strings is set, this function can be used to hand
- * ownership of a malloc()ed string to list without making an extra
- * copy.
- */
struct string_list_item *string_list_append_nodup(struct string_list *list, char *string);
void sort_string_list(struct string_list *list);
@@ -92,32 +65,9 @@ struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
void unsorted_string_list_delete_item(struct string_list *list, int i, int free_util);
-/*
- * Split string into substrings on character delim and append the
- * substrings to list. The input string is not modified.
- * list->strdup_strings must be set, as new memory needs to be
- * allocated to hold the substrings. If maxsplit is non-negative,
- * then split at most maxsplit times. Return the number of substrings
- * appended to list.
- *
- * Examples:
- * string_list_split(l, "foo:bar:baz", ':', -1) -> ["foo", "bar", "baz"]
- * string_list_split(l, "foo:bar:baz", ':', 0) -> ["foo:bar:baz"]
- * string_list_split(l, "foo:bar:baz", ':', 1) -> ["foo", "bar:baz"]
- * string_list_split(l, "foo:bar:", ':', -1) -> ["foo", "bar", ""]
- * string_list_split(l, "", ':', -1) -> [""]
- * string_list_split(l, ":", ':', -1) -> ["", ""]
- */
int string_list_split(struct string_list *list, const char *string,
int delim, int maxsplit);
-
-/*
- * Like string_list_split(), except that string is split in-place: the
- * delimiter characters in string are overwritten with NULs, and the
- * new string_list_items point into string (which therefore must not
- * be modified or freed while the string_list is in use).
- * list->strdup_strings must *not* be set.
- */
int string_list_split_in_place(struct string_list *list, char *string,
int delim, int maxsplit);
+
#endif /* STRING_LIST_H */
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 22:49 ` Jonathan Nieder
@ 2014-12-09 23:07 ` Stefan Beller
2014-12-09 23:15 ` Jonathan Nieder
0 siblings, 1 reply; 49+ messages in thread
From: Stefan Beller @ 2014-12-09 23:07 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Junio C Hamano, git@vger.kernel.org, Jeff King, Michael Haggerty
On Tue, Dec 09, 2014 at 02:49:50PM -0800, Jonathan Nieder wrote:
> Jonathan Nieder wrote:
> > Stefan Beller wrote:
> >> On Tue, Dec 9, 2014 at 11:37 AM, Junio C Hamano <gitster@pobox.com> wrote:
>
> >>> Perhaps the API doc that currently says "Free" is the only thing
> >>> that needs fixing? And perhaps add "See $doc" at the beginning of
> >>> the header and remove duplicated comments we already have in the
> >>> file?
> >>
> >> The reason I wrote this patch originally was because I seem to forget we have
> >> more than one place to document our APIs. If there are comments in the header
> >> I seem to have thought it were the only place where we have documentation.
> >
> > How about this patch?
>
> And another:
this goes on top or replaces the previous one? (This applies cleanly on origin/master)
> -- >8--
> Subject: put string-list API documentation in one place
>
> Until recently (v1.8.0-rc0~46^2~5, 2012-09-12), the string-list API
> was documented in detail in Documentation/technical/api-string-list.txt
> and the header file contained section markers and some short reminders
> but little other documentation.
>
> Since then, the header has acquired some more comments that are mostly
> identical to the documentation from technical/. In principle that
> should help convenience, since it means one less hop for someone
> reading the header to find API documentation. In practice,
> unfortunately, it is hard to remember that there is documentation in
> two places, and the comprehensive documentation of some functions in
> the header makes it too easy to forget that the other functions are
> documented at all (and where).
>
> Add a comment pointing to Documentation/technical/ and remove the
> comments that duplicate what is written there. Longer term, we may
> want to move all of the technical docs to header files and generate
> printer-ready API documentation another way, but that is a larger
> change for another day.
>
> Short reminders in the header file are still okay.
>
> Reported-by: Stefan Beller <sbeller@google.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> ---
Thanks a lot for this patch. It's improving the situation a lot.
No information is lost albeit many deleted lines, have a
Reviewed-by: Stefan Beller <sbeller@google.com>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 23:07 ` Stefan Beller
@ 2014-12-09 23:15 ` Jonathan Nieder
0 siblings, 0 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-09 23:15 UTC (permalink / raw)
To: Stefan Beller
Cc: Junio C Hamano, git@vger.kernel.org, Jeff King, Michael Haggerty
Stefan Beller wrote:
> On Tue, Dec 09, 2014 at 02:49:50PM -0800, Jonathan Nieder wrote:
>> And another:
>
> this goes on top or replaces the previous one? (This applies cleanly on origin/master)
They're independent. :)
[...]
>> Reported-by: Stefan Beller <sbeller@google.com>
>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
>> ---
>
> Thanks a lot for this patch. It's improving the situation a lot.
> No information is lost albeit many deleted lines, have a
>
> Reviewed-by: Stefan Beller <sbeller@google.com>
Thanks for looking it over.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 22:23 ` Jonathan Nieder
@ 2014-12-09 23:18 ` Junio C Hamano
2014-12-10 8:52 ` Jeff King
2014-12-10 8:43 ` Jeff King
1 sibling, 1 reply; 49+ messages in thread
From: Junio C Hamano @ 2014-12-09 23:18 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Jeff King, Stefan Beller, git@vger.kernel.org, Michael Haggerty
Jonathan Nieder <jrnieder@gmail.com> writes:
> Jeff King wrote:
>
>> Elsewhere I mentioned a tool to extract comments and format them. But do
>> people actually care about the formatting step?
>
> If formatting means "convert to a straightforward text document that I
> can read through", then I do.
If the result becomes unparsable by AsciiDoc(or), those who
AsciiDoc'ified the api-*.txt may feel unhappy. I however strongly
suspect that the primary consumer of these api-*.txt documents are
consuming the text version, not AsciiDoc-to-html output.
>> Does anybody asciidoc
>> the technical/api-* files? We did not even support building them until
>> sometime in 2012. Personally, I only ever view them as text.
>
> I also view them as text. I tend to find it easier to read the
> technical/api-* files than headers. That might be for the same reason
> that some other people prefer header files --- a
> Documentation/technical/ file tends to be written in one chunk
> together and ends up saying exactly what I need to know about the
> calling sequence in a coherent way, while header files tend to evolve
> over time to match the implementation without maintaining that
> organization and usability.
The documentation that was written with an explicit purpose to serve
as documentation would explain how each pieces fit in the whole
system much better than a list of pieces extracted from per-function
comments, unless the header comment that serves as the source of
generated document is written carefully. But as people pointed out,
having the same set of information in two places in sync forces us
to be extra careful in a different way. There is no free lunch.
We would want (1) documentation in one place, (2) easy access to it
when deciding which API function to call with what information, and
(3) make it hard to forget updating the documentation when making
changes to the API. If that single source of truth is the header
file, perhaps we would become more careful commenting our headers
(i.e. "do not just comment each functions and structures, but
enhance introductory part that describes how things fit together"),
so I think it would be OK in the end. We may need to reorganize and
reorder the headers so that associated comments to functions and
data types match desirable presentation order, but that effort will
kill two birds with one stone. The resulting header would also be
easier to read by humans.
I am a bit hesitant to see us spending extra cycles either to
reinvent doxygen (if we do our own) or working around quirks in
third-party tools (if we decide to use existing ones).
Thanks.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 22:23 ` Jonathan Nieder
2014-12-09 23:18 ` Junio C Hamano
@ 2014-12-10 8:43 ` Jeff King
2014-12-10 9:18 ` Jonathan Nieder
2014-12-10 20:09 ` Michael Haggerty
1 sibling, 2 replies; 49+ messages in thread
From: Jeff King @ 2014-12-10 8:43 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Tue, Dec 09, 2014 at 02:23:37PM -0800, Jonathan Nieder wrote:
> Jeff King wrote:
>
> > Elsewhere I mentioned a tool to extract comments and format them. But do
> > people actually care about the formatting step?
>
> If formatting means "convert to a straightforward text document that I
> can read through", then I do.
I meant "run asciidoc in api-*". I am confused by your response. Here it
implies to me that you asciidoc them into a text format to make it
easier to read. But below you say "I also view [the api-* files] as
text", which implies you just look at them in your editor.
> > Does anybody asciidoc
> > the technical/api-* files? We did not even support building them until
> > sometime in 2012. Personally, I only ever view them as text.
>
> I also view them as text. I tend to find it easier to read the
> technical/api-* files than headers. That might be for the same reason
> that some other people prefer header files --- a
> Documentation/technical/ file tends to be written in one chunk
> together and ends up saying exactly what I need to know about the
> calling sequence in a coherent way, while header files tend to evolve
> over time to match the implementation without maintaining that
> organization and usability.
We could probably do a better job of keeping our header files neat and
well-ordered. And perhaps would so if they had a coherent narrative in
the first place.
My feeling is that it is at least as much work to keep an api-*.txt file
neat as it would be to keep the header file neat (generally more,
because of the duplication of effort). The one exception might be that
ordering in the header file may require some forward declarations. I'd
guess that to be pretty rare, though (and certainly I did not run into
it when converting the strbuf documentation below).
> I suspect a simple tool to extract the comments and produce something
> like the technical/api-* files would help, since then when someone
> writes a patch, they could try the tool and see if the result is still
> easy to read.
That seems like wishful thinking to me. Some subset of developers will
be happy reading the documentation in the header file, and will not
commonly run the tool. Therefore they will also not bother to examine
the output of the tool when making a change (either because they forget,
or because it is simply a hassle that they do not care about).
> Anyway, the patch I wrote was an attempt at a minimal fix (and an
> attempt at getting out of a conversation that seemed to be moving
> toward bikeshedding). If someone wants to move the documentation from
> api-strbuf.txt to strbuf.h, I won't object, since I hope that a simple
> tool like described above isn't too far away.
I do not mind a partial or minimal fix. This conversion is tedious, and
it does not have to be done all at once. But IMHO, your patch is
actively making things worse. The api-* files have slowly grown out of
date over the years, and I believe that is because they are too far
removed from the code people are actually touching. I've been making an
active effort recently to document function interfaces in comments, and
I feel like the presence of other comments has encouraged me to do so.
Here's strbuf.h, with the data from api-strbuf.txt moved into it. I
followed the ordering of api-strbuf.txt, since that has a more coherent
grouping of functions (but it does make the latter parts of the diff
messier, as we have to move function declarations around). I left the
bottom part of strbuf.h, where there are several undocumented functions,
largely untouched. As further work, it would make sense to document
those functions and also fit them into the right spot amidst the
already-grouped functions.
This has almost every bit of text from api-strbuf.txt. I omitted a few
descriptions where the documentation already in strbuf.h was actually
_better_. I did remove the function names, sine they are redundant with
the declarations below. E.g., rather than:
/**
* `foo`::
* Do something.
*/
void foo(int x);
just:
/**
* Do something.
*/
void foo(int x);
The declaration is nearby and has strictly more information, and the
less boilerplate the better for convincing people to actually write
something. An extraction tool can pretty-print the function name if it
wants.
I did drop some asciidoc-specific formatting from the main text (e.g.,
"+" lines for connecting blocks), which means that extracting the result
and running it through asciidoc won't work. I think it makes the actual
text much more readable, though. But we could do it the other way if
people really want to asciidoc it.
---
diff --git a/strbuf.h b/strbuf.h
index 652b6c4..6143680 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -1,22 +1,105 @@
#ifndef STRBUF_H
#define STRBUF_H
-/* See Documentation/technical/api-strbuf.txt */
-
-extern char strbuf_slopbuf[];
+/**
+ * strbuf's are meant to be used with all the usual C string and memory
+ * APIs. Given that the length of the buffer is known, it's often better to
+ * use the mem* functions than a str* one (memchr vs. strchr e.g.).
+ * Though, one has to be careful about the fact that str* functions often
+ * stop on NULs and that strbufs may have embedded NULs.
+ *
+ * A strbuf is NUL terminated for convenience, but no function in the
+ * strbuf API actually relies on the string being free of NULs.
+ *
+ * strbufs have some invariants that are very important to keep in mind:
+ *
+ * . The `buf` member is never NULL, so it can be used in any usual C
+ * string operations safely. strbuf's _have_ to be initialized either by
+ * `strbuf_init()` or by `= STRBUF_INIT` before the invariants, though.
+ *
+ * Do *not* assume anything on what `buf` really is (e.g. if it is
+ * allocated memory or not), use `strbuf_detach()` to unwrap a memory
+ * buffer from its strbuf shell in a safe way. That is the sole supported
+ * way. This will give you a malloced buffer that you can later `free()`.
+ *
+ * However, it is totally safe to modify anything in the string pointed by
+ * the `buf` member, between the indices `0` and `len-1` (inclusive).
+ *
+ * . The `buf` member is a byte array that has at least `len + 1` bytes
+ * allocated. The extra byte is used to store a `'\0'`, allowing the
+ * `buf` member to be a valid C-string. Every strbuf function ensure this
+ * invariant is preserved.
+ *
+ * NOTE: It is OK to "play" with the buffer directly if you work it this
+ * way:
+ *
+ * ----
+ * strbuf_grow(sb, SOME_SIZE); <1>
+ * strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
+ * ----
+ * <1> Here, the memory array starting at `sb->buf`, and of length
+ * `strbuf_avail(sb)` is all yours, and you can be sure that
+ * `strbuf_avail(sb)` is at least `SOME_SIZE`.
+ *
+ * NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`.
+ *
+ * Doing so is safe, though if it has to be done in many places, adding the
+ * missing API to the strbuf module is the way to go.
+ *
+ * WARNING: Do _not_ assume that the area that is yours is of size `alloc
+ * - 1` even if it's true in the current implementation. Alloc is somehow a
+ * "private" member that should not be messed with. Use `strbuf_avail()`
+ * instead.
+*/
+
+/**
+ * This is the string buffer structure. The `len` member can be used to
+ * determine the current length of the string, and `buf` member provides
+ * access to the string itself.
+ */
struct strbuf {
size_t alloc;
size_t len;
char *buf;
};
+extern char strbuf_slopbuf[];
#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
-/*----- strbuf life cycle -----*/
+/** strbuf lifecycle */
+
+/**
+ * Initialize the structure. The second parameter can be zero or a bigger
+ * number to allocate memory, in case you want to prevent further reallocs.
+ */
extern void strbuf_init(struct strbuf *, size_t);
+
+/**
+ * Release a string buffer and the memory it used. You should not use the
+ * string buffer after using this function, unless you initialize it again.
+ */
extern void strbuf_release(struct strbuf *);
+
+/**
+ * Detach the string from the strbuf and returns it; you now own the
+ * storage the string occupies and it is your responsibility from then on
+ * to release it with `free(3)` when you are done with it.
+ */
extern char *strbuf_detach(struct strbuf *, size_t *);
+
+/**
+ * Attach a string to a buffer. You should specify the string to attach,
+ * the current length of the string and the amount of allocated memory.
+ * The amount must be larger than the string length, because the string you
+ * pass is supposed to be a NUL-terminated string. This string _must_ be
+ * malloc()ed, and after attaching, the pointer cannot be relied upon
+ * anymore, and neither be free()d directly.
+ */
extern void strbuf_attach(struct strbuf *, void *, size_t, size_t);
+
+/**
+ * Swap the contents of two string buffers.
+ */
static inline void strbuf_swap(struct strbuf *a, struct strbuf *b)
{
struct strbuf tmp = *a;
@@ -24,14 +107,33 @@ static inline void strbuf_swap(struct strbuf *a, struct strbuf *b)
*b = tmp;
}
-/*----- strbuf size related -----*/
+
+/** Related to the size of the buffer */
+
+/**
+ * Determine the amount of allocated but unused memory.
+ */
static inline size_t strbuf_avail(const struct strbuf *sb)
{
return sb->alloc ? sb->alloc - sb->len - 1 : 0;
}
+/**
+ * Ensure that at least this amount of unused memory is available after
+ * `len`. This is used when you know a typical size for what you will add
+ * and want to avoid repetitive automatic resizing of the underlying buffer.
+ * This is never a needed operation, but can be critical for performance in
+ * some cases.
+ */
extern void strbuf_grow(struct strbuf *, size_t);
+/**
+ * Set the length of the buffer to a given value. This function does *not*
+ * allocate new memory, so you should not perform a `strbuf_setlen()` to a
+ * length that is larger than `len + strbuf_avail()`. `strbuf_setlen()` is
+ * just meant as a 'please fix invariants from this strbuf I just messed
+ * with'.
+ */
static inline void strbuf_setlen(struct strbuf *sb, size_t len)
{
if (len > (sb->alloc ? sb->alloc - 1 : 0))
@@ -39,16 +141,279 @@ static inline void strbuf_setlen(struct strbuf *sb, size_t len)
sb->len = len;
sb->buf[len] = '\0';
}
+
+/**
+ * Empty the buffer by setting the size of it to zero.
+ */
#define strbuf_reset(sb) strbuf_setlen(sb, 0)
-/*----- content related -----*/
+
+/** Related to the contents of the buffer */
+
+/**
+ * Strip whitespace from the beginning and end of a string.
+ * Equivalent to performing `strbuf_rtrim()` followed by `strbuf_ltrim()`.
+ */
extern void strbuf_trim(struct strbuf *);
+
+/**
+ * Strip whitespace from the end of a string.
+ */
extern void strbuf_rtrim(struct strbuf *);
+
+/**
+ * Strip whitespace from the beginning of a string.
+ */
extern void strbuf_ltrim(struct strbuf *);
+
+/**
+ * Replace the contents of the strbuf with a reencoded form. Returns -1
+ * on error, 0 on success.
+ */
extern int strbuf_reencode(struct strbuf *sb, const char *from, const char *to);
+
+/**
+ * Lowercase each character in the buffer using `tolower`.
+ */
extern void strbuf_tolower(struct strbuf *sb);
+
+/**
+ * Compare two buffers. Returns an integer less than, equal to, or greater
+ * than zero if the first buffer is found, respectively, to be less than,
+ * to match, or be greater than the second buffer.
+ */
extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
+
+/** Adding data to the buffer
+ *
+ * NOTE: All of the functions in this section will grow the buffer as
+ * necessary. If they fail for some reason other than memory shortage and the
+ * buffer hadn't been allocated before (i.e. the `struct strbuf` was set to
+ * `STRBUF_INIT`), then they will free() it.
+ */
+
+/**
+ * Add a single character to the buffer.
+ */
+static inline void strbuf_addch(struct strbuf *sb, int c)
+{
+ strbuf_grow(sb, 1);
+ sb->buf[sb->len++] = c;
+ sb->buf[sb->len] = '\0';
+}
+
+/**
+ * Add a character the specified number of times to the buffer.
+ */
+extern void strbuf_addchars(struct strbuf *sb, int c, size_t n);
+
+/**
+ * Insert data to the given position of the buffer. The remaining contents
+ * will be shifted, not overwritten.
+ */
+extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t);
+
+/**
+ * Remove given amount of data from a given position of the buffer.
+ */
+extern void strbuf_remove(struct strbuf *, size_t pos, size_t len);
+
+/**
+ * Remove the bytes between `pos..pos+len` and replace it with the given
+ * data.
+ */
+extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
+ const void *, size_t);
+
+/**
+ * Add a NUL-terminated string to the buffer. Each line will be prepended
+ * by a comment character and a blank.
+ */
+extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
+
+
+/**
+ * Add data of given length to the buffer.
+ */
+extern void strbuf_add(struct strbuf *, const void *, size_t);
+
+/**
+ * Add a NUL-terminated string to the buffer.
+ *
+ * NOTE: This function will *always* be implemented as an inline or a macro
+ * using strlen, meaning that this is efficient to write things like:
+ *
+ * strbuf_addstr(sb, "immediate string");
+ */
+static inline void strbuf_addstr(struct strbuf *sb, const char *s)
+{
+ strbuf_add(sb, s, strlen(s));
+}
+
+/**
+ * Copy the contents of another buffer at the end of the current one.
+ */
+static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
+{
+ strbuf_grow(sb, sb2->len);
+ strbuf_add(sb, sb2->buf, sb2->len);
+}
+
+/**
+ * Copy part of the buffer from a given position till a given length to the
+ * end of the buffer.
+ */
+extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
+
+/**
+ * This function can be used to expand a format string containing
+ * placeholders. To that end, it parses the string and calls the specified
+ * function for every percent sign found.
+ *
+ * The callback function is given a pointer to the character after the `%`
+ * and a pointer to the struct strbuf. It is expected to add the expanded
+ * version of the placeholder to the strbuf, e.g. to add a newline
+ * character if the letter `n` appears after a `%`. The function returns
+ * the length of the placeholder recognized and `strbuf_expand()` skips
+ * over it.
+ *
+ * The format `%%` is automatically expanded to a single `%` as a quoting
+ * mechanism; callers do not need to handle the `%` placeholder themselves,
+ * and the callback function will not be invoked for this placeholder.
+ *
+ * All other characters (non-percent and not skipped ones) are copied
+ * verbatim to the strbuf. If the callback returned zero, meaning that the
+ * placeholder is unknown, then the percent sign is copied, too.
+ *
+ * In order to facilitate caching and to make it possible to give
+ * parameters to the callback, `strbuf_expand()` passes a context pointer,
+ * which can be used by the programmer of the callback as she sees fit.
+ */
+typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
+extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context);
+
+/**
+ * Used as callback for `strbuf_expand()`, expects an array of
+ * struct strbuf_expand_dict_entry as context, i.e. pairs of
+ * placeholder and replacement string. The array needs to be
+ * terminated by an entry with placeholder set to NULL.
+ */
+struct strbuf_expand_dict_entry {
+ const char *placeholder;
+ const char *value;
+};
+extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context);
+
+/**
+ * Append the contents of one strbuf to another, quoting any
+ * percent signs ("%") into double-percents ("%%") in the
+ * destination. This is useful for literal data to be fed to either
+ * strbuf_expand or to the *printf family of functions.
+ */
+extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
+
+/**
+ * Append the given byte size as a human-readable string (i.e. 12.23 KiB,
+ * 3.50 MiB).
+ */
+extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
+
+/**
+ * Add a formatted string to the buffer.
+ */
+__attribute__((format (printf,2,3)))
+extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
+
+/**
+ * Add a formatted string prepended by a comment character and a
+ * blank to the buffer.
+ */
+__attribute__((format (printf, 2, 3)))
+extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...);
+
+__attribute__((format (printf,2,0)))
+extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
+
+/**
+ * Read a given size of data from a FILE* pointer to the buffer.
+ *
+ * NOTE: The buffer is rewound if the read fails. If -1 is returned,
+ * `errno` must be consulted, like you would do for `read(3)`.
+ * `strbuf_read()`, `strbuf_read_file()` and `strbuf_getline()` has the
+ * same behaviour as well.
+ */
+extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
+
+/**
+ * Read the contents of a given file descriptor. The third argument can be
+ * used to give a hint about the file size, to avoid reallocs. If read fails,
+ * any partial read is undone */
+extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
+
+/**
+ * Read the contents of a file, specified by its path. The third argument
+ * can be used to give a hint about the file size, to avoid reallocs.
+ */
+extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
+
+/**
+ * Read the target of a symbolic link, specified by its path. The third
+ * argument can be used to give a hint about the size, to avoid reallocs.
+ */
+extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
+
+/**
+ * Set the buffer to the path of the current working directory.
+ */
+extern int strbuf_getcwd(struct strbuf *sb);
+
+/**
+ * Read a line from a FILE *, overwriting the existing contents
+ * of the strbuf. The second argument specifies the line
+ * terminator character, typically `'\n'`.
+ * Reading stops after the terminator or at EOF. The terminator
+ * is removed from the buffer before returning. Returns 0 unless
+ * there was nothing left before EOF, in which case it returns `EOF`.
+ */
+extern int strbuf_getline(struct strbuf *, FILE *, int);
+
+/**
+ * Like `strbuf_getline`, but keeps the trailing terminator (if
+ * any) in the buffer.
+ */
+extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
+
+/**
+ * Like `strbuf_getwholeline`, but operates on a file descriptor.
+ * It reads one character at a time, so it is very slow. Do not
+ * use it unless you need the correct position in the file
+ * descriptor.
+ */
+extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
+
+/**
+ * Add a path to a buffer, converting a relative path to an
+ * absolute one in the process. Symbolic links are not
+ * resolved.
+ */
+extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
+
+/**
+ * Strip whitespace from a buffer. The second parameter controls if
+ * comments are considered contents to be removed or not.
+ */
+extern void stripspace(struct strbuf *buf, int skip_comments);
+
+/**
+ * Launch the user preferred editor to edit a file and fill the buffer
+ * with the file's contents upon the user completing their editing. The
+ * third argument can be used to set the environment which the editor is
+ * run in. If the buffer is NULL the editor is launched as usual but the
+ * file's contents are not read into the buffer upon completion.
+ */
+extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
+
static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
{
if (strip_suffix_mem(sb->buf, &sb->len, suffix)) {
@@ -110,52 +475,6 @@ static inline struct strbuf **strbuf_split(const struct strbuf *sb,
*/
extern void strbuf_list_free(struct strbuf **);
-/*----- add data in your buffer -----*/
-static inline void strbuf_addch(struct strbuf *sb, int c)
-{
- strbuf_grow(sb, 1);
- sb->buf[sb->len++] = c;
- sb->buf[sb->len] = '\0';
-}
-
-extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t);
-extern void strbuf_remove(struct strbuf *, size_t pos, size_t len);
-
-/* splice pos..pos+len with given data */
-extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
- const void *, size_t);
-
-extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
-
-extern void strbuf_add(struct strbuf *, const void *, size_t);
-static inline void strbuf_addstr(struct strbuf *sb, const char *s)
-{
- strbuf_add(sb, s, strlen(s));
-}
-static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
-{
- strbuf_grow(sb, sb2->len);
- strbuf_add(sb, sb2->buf, sb2->len);
-}
-extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
-extern void strbuf_addchars(struct strbuf *sb, int c, size_t n);
-
-typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
-extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context);
-struct strbuf_expand_dict_entry {
- const char *placeholder;
- const char *value;
-};
-extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context);
-extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
-
-__attribute__((format (printf,2,3)))
-extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
-__attribute__((format (printf, 2, 3)))
-extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...);
-__attribute__((format (printf,2,0)))
-extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
-
extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
/*
@@ -170,28 +489,11 @@ static inline void strbuf_complete_line(struct strbuf *sb)
strbuf_addch(sb, '\n');
}
-extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
-/* XXX: if read fails, any partial read is undone */
-extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
-extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
-extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
-extern int strbuf_getcwd(struct strbuf *sb);
-
-extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
-extern int strbuf_getline(struct strbuf *, FILE *, int);
-extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
-
-extern void stripspace(struct strbuf *buf, int skip_comments);
-extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
-
extern int strbuf_branchname(struct strbuf *sb, const char *name);
extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
int reserved);
-extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
-
-extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
__attribute__((format (printf,1,2)))
extern int printf_ln(const char *fmt, ...);
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-09 23:18 ` Junio C Hamano
@ 2014-12-10 8:52 ` Jeff King
0 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2014-12-10 8:52 UTC (permalink / raw)
To: Junio C Hamano
Cc: Jonathan Nieder, Stefan Beller, git@vger.kernel.org,
Michael Haggerty
On Tue, Dec 09, 2014 at 03:18:28PM -0800, Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
> > Jeff King wrote:
> >
> >> Elsewhere I mentioned a tool to extract comments and format them. But do
> >> people actually care about the formatting step?
> >
> > If formatting means "convert to a straightforward text document that I
> > can read through", then I do.
>
> If the result becomes unparsable by AsciiDoc(or), those who
> AsciiDoc'ified the api-*.txt may feel unhappy. I however strongly
> suspect that the primary consumer of these api-*.txt documents are
> consuming the text version, not AsciiDoc-to-html output.
Yeah, that was my point. They were not even asciidoc'd for a long time,
then one contributor, who does not otherwise work on the code,
volunteered to asciidoc them. AFAIK there are no regular developers who
wanted this feature (but I do not know for sure, which is why I asked).
I do not _mind_ if they can be asciidoc'd, but if nobody does so, they
are bound to develop formatting errors. And matching asciidoc syntax
does come at a readability cost to the text.
> The documentation that was written with an explicit purpose to serve
> as documentation would explain how each pieces fit in the whole
> system much better than a list of pieces extracted from per-function
> comments, unless the header comment that serves as the source of
> generated document is written carefully.
If we split the header files sanely (i.e., to match what would be one
api-* file), then I had imagined each header file having a long
free-form comment at the top giving the overview, followed by commented
structures and functions, with possibly other free-form comments in the
middle as necessary. That's what I did for the strbuf.h conversion I
just sent.
> I am a bit hesitant to see us spending extra cycles either to
> reinvent doxygen (if we do our own) or working around quirks in
> third-party tools (if we decide to use existing ones).
Me too. That's what I hoped that we could come up with a form whose
in-header source is readable enough that people would use it. Then there
is really no tool necessary.
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 8:43 ` Jeff King
@ 2014-12-10 9:18 ` Jonathan Nieder
2014-12-12 9:16 ` Jeff King
2014-12-10 20:09 ` Michael Haggerty
1 sibling, 1 reply; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-10 9:18 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
>> Jeff King wrote:
> We could probably do a better job of keeping our header files neat and
> well-ordered. And perhaps would so if they had a coherent narrative in
> the first place.
The example I was looking at before was refs.h. It is still a mess.
Hopefully strbuf.h will work better.
[...]
> On Tue, Dec 09, 2014 at 02:23:37PM -0800, Jonathan Nieder wrote:
>> I suspect a simple tool to extract the comments and produce something
>> like the technical/api-* files would help, since then when someone
>> writes a patch, they could try the tool and see if the result is still
>> easy to read.
>
> That seems like wishful thinking to me. Some subset of developers will
> be happy reading the documentation in the header file, and will not
> commonly run the tool. Therefore they will also not bother to examine
> the output of the tool when making a change (either because they forget,
> or because it is simply a hassle that they do not care about).
That is okay as long as enough people extract documentation to ensure
the result is sane.
It is similar to what happens with Documentation/*.txt. A subset of
developers just work with the source and make local changes without
looking at the big picture (and sometimes buggy markup or documentation
organized in a confusing way results). But that doesn't change much.
When people forget to look at the manpage and write text that is
awkward in context or markup errors, one of a few things happens:
* a reviewer notices. The patch is fixed, and the patch author
develops better habits for next time.
* someone using the documentation notices later, and it gets fixed
then, which is still fine.
Both outcomes are much, much better than documentation that never gets
organized.
[...]
> The api-* files have slowly grown out of
> date over the years, and I believe that is because they are too far
> removed from the code people are actually touching.
I don't think they ever were very comprehensive or up to date.
As far as I understand, the api-* files are intended to be usually out
of date. Their main purpose is to explain the gist of how to use the
API. They were usually written way after the API was introduced (so
they are behind already). They are clearly written and as long as
they mostly match the code, that is enough for them to be useful and
educational.
Then every few years or so, someone updates the file with the latest
API changes, still with an eye to overall organization and readability
of the document.
In other words, they prioritize clarity over currency.
Of course if it's possible to have clear documentation that also
matches the current code, that would be even better. I have hope that
moving the documentation to the header files will get us there if we
do it right.
> I did drop some asciidoc-specific formatting from the main text (e.g.,
> "+" lines for connecting blocks), which means that extracting the result
> and running it through asciidoc won't work.
This unfortunately lost some structure (e.g., which paragraphs were
part of the same bulleted list). It would be more common to use a
hanging indent:
- The `buf` member is never NULL, so ...
string operations ...
by `strbuf_init()` ...
Do not assume anything about what `buf` really is ...
...
- ...
[...]
> I think it makes the actual
> text much more readable, though. But we could do it the other way if
> people really want to asciidoc it.
I also don't mind losing the asciidoc markup, especially given that it
would be a pain to reconstruct and render.
My reaction at first glance is that this is trying to do something
good but the current implementation is less readable than
Documentation/technical/api-strbuf.txt. Am I looking at a work in
progress, or is this meant to be ready for application? Which aspects
would you be interested in comments on?
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 8:43 ` Jeff King
2014-12-10 9:18 ` Jonathan Nieder
@ 2014-12-10 20:09 ` Michael Haggerty
2014-12-10 21:51 ` Jonathan Nieder
1 sibling, 1 reply; 49+ messages in thread
From: Michael Haggerty @ 2014-12-10 20:09 UTC (permalink / raw)
To: Jeff King, Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org
My vote is for putting the API docs in the header files:
* Functions are documented right next to their declarations (which the
compiler guarantees are up-to-date), removing ambiguity and avoiding
some redundancy.
* It is obvious at a glance which functions are documented and which
still need docs.
* It is easier to remember to update the documentation when it is near
the code, and easier for reviewers to remember to pester authors to do so.
I also like it when function declarations in header files include the
names of their parameters, as (1) it's an efficient way to give the
reader a good hint about how the function should be used, and (2) it
makes it easier to refer to the parameters from the docstring.
I agree that there is an important need for introductory/conceptual
documentation about and API, but I think this fits fine as a large
docstring at the top of the header file.
I personally don't have much use for formatted documentation but if that
were a need I would think that a standard tool like doxygen could be used.
I have been trying hard to add good header-file docstrings for code that
I have worked on, and even for code that I had to read because I needed
to figure out how to use it. I would find it a pity for that work to be
squashed into Documentation/technical/api-*.txt, where in my opinion it
is less discoverable and more likely to fall into disrepair.
Michael
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 20:09 ` Michael Haggerty
@ 2014-12-10 21:51 ` Jonathan Nieder
2014-12-10 22:28 ` Junio C Hamano
0 siblings, 1 reply; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-10 21:51 UTC (permalink / raw)
To: Michael Haggerty
Cc: Jeff King, Stefan Beller, Junio C Hamano, git@vger.kernel.org
Michael Haggerty wrote:
> I would find it a pity for that work to be
> squashed into Documentation/technical/api-*.txt, where in my opinion it
> is less discoverable and more likely to fall into disrepair.
I think we're in violent agreement and keep repeating ourselves.
All I said is that api-strbuf.txt is currently the most readable
documentation of the strbuf API I can find. The patch to move the
text to strbuf.h looked rough and incomplete. Therefore I don't think
it's ready to be applied as is. If you'd like more details about why
I say that, feel free to ask.
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 21:51 ` Jonathan Nieder
@ 2014-12-10 22:28 ` Junio C Hamano
2014-12-10 22:37 ` Jonathan Nieder
0 siblings, 1 reply; 49+ messages in thread
From: Junio C Hamano @ 2014-12-10 22:28 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Michael Haggerty, Jeff King, Stefan Beller, git@vger.kernel.org
Jonathan Nieder <jrnieder@gmail.com> writes:
> Michael Haggerty wrote:
>
>> I would find it a pity for that work to be
>> squashed into Documentation/technical/api-*.txt, where in my opinion it
>> is less discoverable and more likely to fall into disrepair.
>
> I think we're in violent agreement and keep repeating ourselves.
Hmph, I am confused.
I somehow had an impression that the "move to doc and remove from
header" patch was to illustrate how unpleasant the result will be as
a whole (i.e. results in a nice documentation as a starting point,
but we can see that it will be hard to motivate and help people to
keep it up to date during further development). Which would suggest
that you are in favor of moving the other way around, to keep the
header rich with documentation only at the higher level. Am I
reading you correctly?
> All I said is that api-strbuf.txt is currently the most readable
> documentation of the strbuf API I can find. The patch to move the
> text to strbuf.h looked rough and incomplete. Therefore I don't think
> it's ready to be applied as is. If you'd like more details about why
> I say that, feel free to ask.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 22:28 ` Junio C Hamano
@ 2014-12-10 22:37 ` Jonathan Nieder
2014-12-10 23:04 ` Junio C Hamano
0 siblings, 1 reply; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-10 22:37 UTC (permalink / raw)
To: Junio C Hamano
Cc: Michael Haggerty, Jeff King, Stefan Beller, git@vger.kernel.org
Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>> Michael Haggerty wrote:
>>> I would find it a pity for that work to be
>>> squashed into Documentation/technical/api-*.txt, where in my opinion it
>>> is less discoverable and more likely to fall into disrepair.
>>
>> I think we're in violent agreement and keep repeating ourselves.
>
> Hmph, I am confused.
>
> I somehow had an impression that the "move to doc and remove from
> header" patch was to illustrate how unpleasant the result will be as
> a whole (i.e. results in a nice documentation as a starting point,
> but we can see that it will be hard to motivate and help people to
> keep it up to date during further development). Which would suggest
> that you are in favor of moving the other way around, to keep the
> header rich with documentation only at the higher level. Am I
> reading you correctly?
Sorry, I think I was unclear.
Some possibilities, in order of my preference (earlier items are better):
1. Move documentation to header and provide a program to generate a nice
standalone document.
2. Move documentation to header, being careful enough that the header
sort of works as a standalone document.
3. Move documentation to Documentation/technical/ and keep the header
bare-bones.
4. Status quo (comprehensive documentation for some functions in both
places, for others in only one place, no reliable way for someone
to find the information they need in one place).
Since (3) is better than (4), I wrote simple patches to do that for
strbuf.h and string-list.h. I meant them in earnest --- I hope they
get applied.
I think peff was working on (2), which is an admirable goal. The
patch seemed to be incomplete.
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 22:37 ` Jonathan Nieder
@ 2014-12-10 23:04 ` Junio C Hamano
2014-12-10 23:08 ` Jonathan Nieder
0 siblings, 1 reply; 49+ messages in thread
From: Junio C Hamano @ 2014-12-10 23:04 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Michael Haggerty, Jeff King, Stefan Beller, git@vger.kernel.org
Jonathan Nieder <jrnieder@gmail.com> writes:
> Some possibilities, in order of my preference (earlier items are better):
>
> 1. Move documentation to header and provide a program to generate a nice
> standalone document.
>
> 2. Move documentation to header, being careful enough that the header
> sort of works as a standalone document.
>
> 3. Move documentation to Documentation/technical/ and keep the header
> bare-bones.
>
> 4. Status quo (comprehensive documentation for some functions in both
> places, for others in only one place, no reliable way for someone
> to find the information they need in one place).
>
> Since (3) is better than (4), I wrote simple patches to do that for
> strbuf.h and string-list.h. I meant them in earnest --- I hope they
> get applied.
>
> I think peff was working on (2), which is an admirable goal. The
> patch seemed to be incomplete.
Yeah, I agree with the above preferred ordering, and also think once
we get to (2) it would be "usable" by the intended audience. Those
who prefer (1) over (2) are the ones who somehow want to read hard
copies ;-) and are likely to be different audiences and are better
served by people with different skill-set and inclination.
I am not sure if (2) and (3) are that incompatible, though. If you
had an acceptable version of (3), wouldn't it be just the matter of
indenting the whole thing with "s/^/ */", sprinkle "/**" and "*/" at
strategic paragraph breaks, and move them back to the corresponding
header?
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 23:04 ` Junio C Hamano
@ 2014-12-10 23:08 ` Jonathan Nieder
0 siblings, 0 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-10 23:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: Michael Haggerty, Jeff King, Stefan Beller, git@vger.kernel.org
Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>> 2. Move documentation to header, being careful enough that the header
>> sort of works as a standalone document.
>>
>> 3. Move documentation to Documentation/technical/ and keep the header
>> bare-bones.
[...]
> I am not sure if (2) and (3) are that incompatible, though. If you
> had an acceptable version of (3), wouldn't it be just the matter of
> indenting the whole thing with "s/^/ */", sprinkle "/**" and "*/" at
> strategic paragraph breaks, and move them back to the corresponding
> header?
Presumably. There's also the question of whether to use asciidoc
markup, which got mixed in somehow (but I don't see why it has to be ---
a header with asciidoc would be fine with me, as would a file in
Documentation/technical/ without asciidoc).
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-10 9:18 ` Jonathan Nieder
@ 2014-12-12 9:16 ` Jeff King
2014-12-12 18:31 ` Jonathan Nieder
0 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2014-12-12 9:16 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Wed, Dec 10, 2014 at 01:18:15AM -0800, Jonathan Nieder wrote:
> > That seems like wishful thinking to me. Some subset of developers will
> > be happy reading the documentation in the header file, and will not
> > commonly run the tool. Therefore they will also not bother to examine
> > the output of the tool when making a change (either because they forget,
> > or because it is simply a hassle that they do not care about).
>
> That is okay as long as enough people extract documentation to ensure
> the result is sane.
I have a guess that the "subset" I mentioned above is "most", but I
admit that is my intuition, not backed up by data.
> > The api-* files have slowly grown out of
> > date over the years, and I believe that is because they are too far
> > removed from the code people are actually touching.
>
> I don't think they ever were very comprehensive or up to date.
Surely at least some of them were up to date when they were first
written? Take api-strbuf, for example. It started in dd613e6b, which
claims almost complete coverage. And then it slowly grew stale as
functions were added and not documented.
> As far as I understand, the api-* files are intended to be usually out
> of date. Their main purpose is to explain the gist of how to use the
> API. They were usually written way after the API was introduced (so
> they are behind already). They are clearly written and as long as
> they mostly match the code, that is enough for them to be useful and
> educational.
I'm not sure any such thought as "intended to be out of date" went into
it. I think it was more "geez, these really need some documentation at
all". Out-of-date documentation can be dangerous and misleading, and is
one of the reasons I think it is a good idea to keep the documentation
closer to the code. It's not a silver bullet, but it helps make it more
obvious when both need to be updated.
> Then every few years or so, someone updates the file with the latest
> API changes, still with an eye to overall organization and readability
> of the document.
Again, look at api-strbuf.txt. The changes after the initial checkin are
almost entirely adding functions to the giant list. They are (hopefully)
added to the most appropriate spot, but that is also (again, hopefully)
done in the header file, too. I don't see any real effort towards
organization or readability.
Maybe I'm not understanding what you mean by organization or
readability. It seems to me like the api docs look like:
some intro text and overall description
some header (optional)
- some-func
description of some-func
- some-func2
description of some-func2
and I am proposing basically:
/*
* some intro text and overall description
*/
/* some header (optional) */
/* description of some-func */
int some_func(...);
/* description of some-func2 */
int some_func2(...);
The readability and organization of those do not seem substantially
different to me.
> > I did drop some asciidoc-specific formatting from the main text (e.g.,
> > "+" lines for connecting blocks), which means that extracting the result
> > and running it through asciidoc won't work.
>
> This unfortunately lost some structure (e.g., which paragraphs were
> part of the same bulleted list). It would be more common to use a
> hanging indent:
>
> - The `buf` member is never NULL, so ...
> string operations ...
> by `strbuf_init()` ...
>
> Do not assume anything about what `buf` really is ...
> ...
>
> - ...
Yeah, I think a hanging indent would be fine. I didn't actually spend
much effort on formatting. My point was to say "is this really so bad to
read inline?"
We could stick with asciidoc, too, but I really would like to keep the
barrier to writing documentation as low as possible, in order to
encourage it happening. I find that asciidoc syntax often ends up making
both writing and reading the source more tedious than it needs to be.
> > I think it makes the actual
> > text much more readable, though. But we could do it the other way if
> > people really want to asciidoc it.
>
> I also don't mind losing the asciidoc markup, especially given that it
> would be a pain to reconstruct and render.
I'm not sure it would be that hard if you can extract to text (which you
seem to want). But in the patch I posted (and the outline I showed
above), I chose to turn:
foo::
description of foo
into just:
/* description of foo */
void foo(void);
to avoid writers having to repeat themselves. But it does mean that the
extracted comments do not stand alone. You can either hack your own
parser (which is what doxygen does), or build something on top of a real
parser (there is cldoc, which uses libclang to extract comments next to
declarations).
That's why I suggested the possibility of punting on extraction
entirely, and just treating the header file as both the source and
finished document.
> My reaction at first glance is that this is trying to do something
> good but the current implementation is less readable than
> Documentation/technical/api-strbuf.txt. Am I looking at a work in
> progress, or is this meant to be ready for application? Which aspects
> would you be interested in comments on?
It was more "this is the direction I think we should go, and I will try
to implement a complete conversion to convince myself and others that I
am not forgetting any corner case". I probably should have given the
"outline" I gave above along with it.
I think the end result that I posted is still strictly better than what
we have currently, with the exception that I should have reformatted the
hanging indents. What is it that you don't like about it?
I'm not super interested in going back and forth over minor markup
issues if there are overall issues with the concept that might block it
from happening (just because they are tedious and time-consuming, and I
do not want to spend a lot of time formatting something that will get
thrown away). So please list your complaints in order of increasing
specificity. :)
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 9:16 ` Jeff King
@ 2014-12-12 18:31 ` Jonathan Nieder
2014-12-12 19:17 ` Junio C Hamano
` (2 more replies)
0 siblings, 3 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-12 18:31 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
> I'm not sure any such thought as "intended to be out of date" went into
> it.
Junio started the documentation in v1.5.4-rc1~49 (2007-11-24). I'm
not sure if there was a discussion preceding that commit. My
understanding was always that putting the documentation out-of-line
was an intentional decision and that it was understood that the
documentation would have cycles of falling out of date and needing to
be updated, but I may be misunderstanding the history.
Separate from the question of history, I honestly prefer this way of
doing API documentation relative to 90% of the API documentation in
headers I've seen in other projects. I suspect you don't. That's
okay --- it's possible for rational people to disagree about things.
It's moot given that we don't seem to disagree about what should be
done about it. Why keep arguing?
> I think the end result that I posted is still strictly better than what
> we have currently, with the exception that I should have reformatted the
> hanging indents. What is it that you don't like about it?
Other issues of inconsistent markup. For example, some comments are
strangely indented, and some look like
/* First line
* second line
* third line */
> I'm not super interested in going back and forth over minor markup
> issues if there are overall issues with the concept that might block it
> from happening (just because they are tedious and time-consuming, and I
> do not want to spend a lot of time formatting something that will get
> thrown away). So please list your complaints in order of increasing
> specificity. :)
The overall concept is good.
I chose not to list markup issues for the same reason (it's more
tedious to go back and forth than for someone to spend some time to
get it mostly-right first on their own). I am kind of confused about
the current status, since I've said again and again that I'd be happy
to see the documentation in the header but you still seem to be trying
to convince me of that. What am I missing?
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 18:31 ` Jonathan Nieder
@ 2014-12-12 19:17 ` Junio C Hamano
2014-12-12 19:19 ` Stefan Beller
2014-12-12 19:24 ` Jeff King
2 siblings, 0 replies; 49+ messages in thread
From: Junio C Hamano @ 2014-12-12 19:17 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Jeff King, Stefan Beller, git@vger.kernel.org, Michael Haggerty
Jonathan Nieder <jrnieder@gmail.com> writes:
> Jeff King wrote:
>
>> I'm not sure any such thought as "intended to be out of date" went into
>> it.
>
> Junio started the documentation in v1.5.4-rc1~49 (2007-11-24). I'm
> not sure if there was a discussion preceding that commit. My
> understanding was always that putting the documentation out-of-line
> was an intentional decision and that it was understood that the
> documentation would have cycles of falling out of date and needing to
> be updated, but I may be misunderstanding the history.
There of course was not "intended to be out of date". It was just
that the prevailing style of comments in the header back then was
sporadic per-function explanation that would have served only as a
reminder for those who have read the corresponding *.c file, without
any overall structure of the API described.
We could have gone to "in header description" route back then and
the commit you referred to could have added
/*
* NEEDSWORK: describe the overall structure of the API
* here, so that people can use it without reading the
* implementation of the API itself.
*/
to each header file instead. I chose not to primarily because those
who wanted to have documentation pages that are pointed from api-index
were audience different from those who updated *.[ch] files, and also
I had slight preference to have a set of *.txt files that do not force
me to squelch /* * * */ while reading them.
> Separate from the question of history, I honestly prefer this way of
> doing API documentation relative to 90% of the API documentation in
> headers I've seen in other projects. I suspect you don't. That's
> okay --- it's possible for rational people to disagree about things.
Yes.
> The overall concept is good.
OK, then let's agree to go in the "comprehensive doc in the *.h and
then those who want *.txt can help the machinery to extract"
direction.
Thanks.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 18:31 ` Jonathan Nieder
2014-12-12 19:17 ` Junio C Hamano
@ 2014-12-12 19:19 ` Stefan Beller
2014-12-12 19:29 ` Jeff King
2014-12-12 19:24 ` Jeff King
2 siblings, 1 reply; 49+ messages in thread
From: Stefan Beller @ 2014-12-12 19:19 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Jeff King, Junio C Hamano, git@vger.kernel.org, Michael Haggerty
On Fri, Dec 12, 2014 at 10:31 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Jeff King wrote:
>
>> I'm not sure any such thought as "intended to be out of date" went into
>> it.
>
> Junio started the documentation in v1.5.4-rc1~49 (2007-11-24). I'm
> not sure if there was a discussion preceding that commit. My
> understanding was always that putting the documentation out-of-line
> was an intentional decision and that it was understood that the
> documentation would have cycles of falling out of date and needing to
> be updated, but I may be misunderstanding the history.
>
> Separate from the question of history, I honestly prefer this way of
> doing API documentation relative to 90% of the API documentation in
> headers I've seen in other projects. I suspect you don't. That's
> okay --- it's possible for rational people to disagree about things.
>
> It's moot given that we don't seem to disagree about what should be
> done about it. Why keep arguing?
>
So you proposed an order of desirability w.r.t. the way we want to go
documenting things.
> Some possibilities, in order of my preference (earlier items are better):
>
> 1. Move documentation to header and provide a program to generate a nice
> standalone document.
Junio agrees with that order. Michael said
> My vote is for putting the API docs in the header files:
which seems to be an agreement with your most desired way to do it.
Jeff said earlier when reviewing your patch:
> I somewhat feel this goes in the opposite direction of where we want to
> be *(all data in one place, but that place is the header)*.
which sounds to me as if he prefers also the header as the one place of truth.
I do agree on your proposed order of desirability as well. So nobody
showed up yet,
who dislikes the headers as the one place of truth.
So the open question is:
* The historic reasoning to introduce technical/api-$header at all. As
Junio mainly
put persons to ask into the stubs in 530e741c726 (2007-11-24, Start
preparing the API documents.),
it was probably improving the status quo back then. Maybe it was
easier to have all names in place
than using git blame/git pickaxe at the time?
Answering this question makes sure we don't oversee some reasons.
* Assuming we put everything into headers now, we'd need to discuss
-> Do we want to extract it to technical/api-$somedoc later at all?
(There seems to be some disagreement?)
-> How do we extract (plain sed for lines starting with "*", or
doxygen, or a self cooked script)
-> How do we ensure the generated documentation doesn't get stale over time?
As I personally just look up things in the header anyway, I'd rather
get started on polishing the comments in the
headers as on arguing how to extract it. Though that's a required step
to know which format we want in the headers.
Thanks,
Stefan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 18:31 ` Jonathan Nieder
2014-12-12 19:17 ` Junio C Hamano
2014-12-12 19:19 ` Stefan Beller
@ 2014-12-12 19:24 ` Jeff King
2014-12-12 19:35 ` Jonathan Nieder
2 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2014-12-12 19:24 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Fri, Dec 12, 2014 at 10:31:14AM -0800, Jonathan Nieder wrote:
> Separate from the question of history, I honestly prefer this way of
> doing API documentation relative to 90% of the API documentation in
> headers I've seen in other projects. I suspect you don't. That's
> okay --- it's possible for rational people to disagree about things.
>
> It's moot given that we don't seem to disagree about what should be
> done about it. Why keep arguing?
Fair enough.
> > I think the end result that I posted is still strictly better than what
> > we have currently, with the exception that I should have reformatted the
> > hanging indents. What is it that you don't like about it?
>
> Other issues of inconsistent markup. For example, some comments are
> strangely indented, and some look like
>
> /* First line
> * second line
> * third line */
Yeah, I had to strip the indent from:
strbuf_init::
description of strbuf_init...
when "strbuf_init::" went away, but it looks like I missed two of them.
And I see one "/* First line" where the "header" from "Adding data to
the buffer" got merged with a note. I agree those should be fixed.
I used our normal single-line comment style for most of those:
/* Related to the size of the buffer */
in some places. But I'd be happy, too, with:
/*
* Related to the size of the buffer
*/
(and probably using a full sentence, or caps or underlining or something
to indicate that the comment begins a new section of the header file).
> I chose not to list markup issues for the same reason (it's more
> tedious to go back and forth than for someone to spend some time to
> get it mostly-right first on their own). I am kind of confused about
> the current status, since I've said again and again that I'd be happy
> to see the documentation in the header but you still seem to be trying
> to convince me of that. What am I missing?
I think partially it was crossing mails. While I was writing the
response that you responded to just now, I ended up postponing it for
other work, and in the meantime you sent several more messages
indicating you were OK with moving documentation into the headers. I
almost scrapped my response, but frankly I was left a bit confused by
your position, since it seemed the opposite of the 2 patches you had
sent moving things out of headers.
Do not feel obligated to make me unconfused. If you are on board with
putting documentation in the headers, then I think we can move forward
with that plan.
So what next?
I agree there are some formatting problems in the strbuf.h patch I sent
earlier. I'm happy to fix them and resend, but I'm not 100% sure that
fixing all the problems I see will not leave problems for you. I can fix
them and you can review if you want. Or alternatively, if you have more
drastic formatting or wording changes in mind, maybe it would make sense
for you to take a pass?
I _don't_ want to commit to moving all of api-* into headers myself.
It's something I would rather have happen over time as people touch
areas[1], because it's tedious and time-consuming. That does create an
inconsistency, in the sense that some APIs will be documented in
Documentation/technical, and others in their header files. But as long
as each _individual_ API is documented in one or the other, I don't see
that as a big problem (of course the status quo is a mix for some APIs,
so we will live with that until they are touched, but that is no worse
than today's state).
-Peff
[1] I had a vague plan to put new documentation into headers, and slowly
migrate that way until we had a critical mass. But that was moving
somewhat slowly, and obviously escaped the notice of many people. :)
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 19:19 ` Stefan Beller
@ 2014-12-12 19:29 ` Jeff King
0 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2014-12-12 19:29 UTC (permalink / raw)
To: Stefan Beller
Cc: Jonathan Nieder, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Fri, Dec 12, 2014 at 11:19:23AM -0800, Stefan Beller wrote:
> * Assuming we put everything into headers now, we'd need to discuss
> -> Do we want to extract it to technical/api-$somedoc later at all?
> (There seems to be some disagreement?)
> -> How do we extract (plain sed for lines starting with "*", or
> doxygen, or a self cooked script)
> -> How do we ensure the generated documentation doesn't get stale over time?
I think it would be _nice_ to extract it, and that should be a
consideration when doing the manual work of moving it into headers
(you'll notice I used the "/**" convention to start comments which
should be extractable, but I am happy to use any similar convention[1]).
But unless somebody is excited about working on the extractor
immediately, I think we should punt on it for now. Moving the
documentation is already a big job, and I do not want to add an extra
dependency to the task.
The exact extractor choice might influence formatting decisions (e.g.,
should extracted text stand alone, or must it be viewed in context of the
function it prefaces), but we might be able to do a mechanical
conversion later if those facts change.
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 19:24 ` Jeff King
@ 2014-12-12 19:35 ` Jonathan Nieder
2014-12-12 21:27 ` Jeff King
0 siblings, 1 reply; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-12 19:35 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
> I agree there are some formatting problems in the strbuf.h patch I sent
> earlier. I'm happy to fix them and resend, but I'm not 100% sure that
> fixing all the problems I see will not leave problems for you. I can fix
> them and you can review if you want. Or alternatively, if you have more
> drastic formatting or wording changes in mind, maybe it would make sense
> for you to take a pass?
For the sake of reviewability, I think the less that happens in a
single working patch, the better. :)
If I were doing it, I would first de-asciidoc within technical/ and
then move into the header in a separate patch. Or first move with
asciidoc intact and then de-asciidoc in a separate patch. Combining
the two into a single patch is also fine. Please don't change wording
at the same time.
> I _don't_ want to commit to moving all of api-* into headers myself.
Yeah, I think that's fine. Moving one at a time when people want to
do it doesn't hurt consistency at all relative to the status quo.
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 19:35 ` Jonathan Nieder
@ 2014-12-12 21:27 ` Jeff King
2014-12-12 21:28 ` [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h Jeff King
` (4 more replies)
0 siblings, 5 replies; 49+ messages in thread
From: Jeff King @ 2014-12-12 21:27 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Fri, Dec 12, 2014 at 11:35:52AM -0800, Jonathan Nieder wrote:
> If I were doing it, I would first de-asciidoc within technical/ and
> then move into the header in a separate patch. Or first move with
> asciidoc intact and then de-asciidoc in a separate patch. Combining
> the two into a single patch is also fine. Please don't change wording
> at the same time.
Here's what I came up with. The first patch probably does more than
you'd like (and more than I would have done if I were starting from
scratch today). But I didn't want to get into undoing the stripping of
each function-name list item that I showed earlier, as it would be a lot
of tedious manual work. If we decide we want to keep those, I'm happy to
do the work to restore them, but it didn't seem like a good tradeoff
just to create an intermediate state to make the patch prettier.
I did split out some of the other formatting decisions, though, so they
can be evaluated individually.
[1/4]: strbuf: migrate api-strbuf.txt documentation to strbuf.h
[2/4]: strbuf.h: drop asciidoc list formatting from API docs
[3/4]: strbuf.h: format asciidoc code blocks as 4-space indent
[4/4]: strbuf.h: reorganize api function grouping headers
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h
2014-12-12 21:27 ` Jeff King
@ 2014-12-12 21:28 ` Jeff King
2014-12-12 21:40 ` Jeff King
` (2 more replies)
2014-12-12 21:28 ` [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs Jeff King
` (3 subsequent siblings)
4 siblings, 3 replies; 49+ messages in thread
From: Jeff King @ 2014-12-12 21:28 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Some of strbuf is documented as comments above functions,
and some is separate in Documentation/technical/api-strbuf.txt.
This makes it annoying to find the appropriate documentation.
We'd rather have it all in one place, which means all in the
text document, or all in the header.
Let's choose the header as that place. Even though the
formatting is not quite as pretty, this keeps the
documentation close to the related code. The hope is that
this makes it easier to find what you want (human-readable
comments are right next to the C declarations), and easier
for writers to keep the documentation up to date.
This is more or less a straight import of the text from
api-strbuf.txt into C comments, complete with asciidoc
formatting. The exceptions are:
1. All comments created in this way are started with "/**"
to indicate they are part of the API documentation. This
may help later with extracting the text to pretty-print
it.
2. Function descriptions do not repeat the function name,
as it is available in the context directly below. So:
`strbuf_add`::
Add data of given length to the buffer.
from api-strbuf.txt becomes:
/**
* Add data of given length to the buffer.
*/
void strbuf_add(struct strbuf *sb, const void *, size_t);
As a result, any block-continuation required in asciidoc
for that list item was dropped in favor of straight
blank-line paragraph (since it is not necessary when we
are not in a list item).
3. There is minor re-wording to integrate existing comments
and api-strbuf text. In each case, I took whichever
version was more descriptive, and eliminated any
redundancies. In one case, for strbuf_addstr, the api
documentation gave its inline definition; I eliminated
this as redundant with the actual definition, which can
be seen directly below the comment.
4. The functions in the header file are re-ordered to match
the ordering of the API documentation, under the
assumption that more thought went into the grouping
there.
Signed-off-by: Jeff King <peff@peff.net>
---
Documentation/technical/api-strbuf.txt | 351 -------------------------
strbuf.h | 458 ++++++++++++++++++++++++++++-----
2 files changed, 390 insertions(+), 419 deletions(-)
delete mode 100644 Documentation/technical/api-strbuf.txt
diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt
deleted file mode 100644
index cca6543..0000000
--- a/Documentation/technical/api-strbuf.txt
+++ /dev/null
@@ -1,351 +0,0 @@
-strbuf API
-==========
-
-strbuf's are meant to be used with all the usual C string and memory
-APIs. Given that the length of the buffer is known, it's often better to
-use the mem* functions than a str* one (memchr vs. strchr e.g.).
-Though, one has to be careful about the fact that str* functions often
-stop on NULs and that strbufs may have embedded NULs.
-
-A strbuf is NUL terminated for convenience, but no function in the
-strbuf API actually relies on the string being free of NULs.
-
-strbufs have some invariants that are very important to keep in mind:
-
-. The `buf` member is never NULL, so it can be used in any usual C
-string operations safely. strbuf's _have_ to be initialized either by
-`strbuf_init()` or by `= STRBUF_INIT` before the invariants, though.
-+
-Do *not* assume anything on what `buf` really is (e.g. if it is
-allocated memory or not), use `strbuf_detach()` to unwrap a memory
-buffer from its strbuf shell in a safe way. That is the sole supported
-way. This will give you a malloced buffer that you can later `free()`.
-+
-However, it is totally safe to modify anything in the string pointed by
-the `buf` member, between the indices `0` and `len-1` (inclusive).
-
-. The `buf` member is a byte array that has at least `len + 1` bytes
- allocated. The extra byte is used to store a `'\0'`, allowing the
- `buf` member to be a valid C-string. Every strbuf function ensure this
- invariant is preserved.
-+
-NOTE: It is OK to "play" with the buffer directly if you work it this
- way:
-+
-----
-strbuf_grow(sb, SOME_SIZE); <1>
-strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
-----
-<1> Here, the memory array starting at `sb->buf`, and of length
-`strbuf_avail(sb)` is all yours, and you can be sure that
-`strbuf_avail(sb)` is at least `SOME_SIZE`.
-+
-NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`.
-+
-Doing so is safe, though if it has to be done in many places, adding the
-missing API to the strbuf module is the way to go.
-+
-WARNING: Do _not_ assume that the area that is yours is of size `alloc
-- 1` even if it's true in the current implementation. Alloc is somehow a
-"private" member that should not be messed with. Use `strbuf_avail()`
-instead.
-
-Data structures
----------------
-
-* `struct strbuf`
-
-This is the string buffer structure. The `len` member can be used to
-determine the current length of the string, and `buf` member provides
-access to the string itself.
-
-Functions
----------
-
-* Life cycle
-
-`strbuf_init`::
-
- Initialize the structure. The second parameter can be zero or a bigger
- number to allocate memory, in case you want to prevent further reallocs.
-
-`strbuf_release`::
-
- Release a string buffer and the memory it used. You should not use the
- string buffer after using this function, unless you initialize it again.
-
-`strbuf_detach`::
-
- Detach the string from the strbuf and returns it; you now own the
- storage the string occupies and it is your responsibility from then on
- to release it with `free(3)` when you are done with it.
-
-`strbuf_attach`::
-
- Attach a string to a buffer. You should specify the string to attach,
- the current length of the string and the amount of allocated memory.
- The amount must be larger than the string length, because the string you
- pass is supposed to be a NUL-terminated string. This string _must_ be
- malloc()ed, and after attaching, the pointer cannot be relied upon
- anymore, and neither be free()d directly.
-
-`strbuf_swap`::
-
- Swap the contents of two string buffers.
-
-* Related to the size of the buffer
-
-`strbuf_avail`::
-
- Determine the amount of allocated but unused memory.
-
-`strbuf_grow`::
-
- Ensure that at least this amount of unused memory is available after
- `len`. This is used when you know a typical size for what you will add
- and want to avoid repetitive automatic resizing of the underlying buffer.
- This is never a needed operation, but can be critical for performance in
- some cases.
-
-`strbuf_setlen`::
-
- Set the length of the buffer to a given value. This function does *not*
- allocate new memory, so you should not perform a `strbuf_setlen()` to a
- length that is larger than `len + strbuf_avail()`. `strbuf_setlen()` is
- just meant as a 'please fix invariants from this strbuf I just messed
- with'.
-
-`strbuf_reset`::
-
- Empty the buffer by setting the size of it to zero.
-
-* Related to the contents of the buffer
-
-`strbuf_trim`::
-
- Strip whitespace from the beginning and end of a string.
- Equivalent to performing `strbuf_rtrim()` followed by `strbuf_ltrim()`.
-
-`strbuf_rtrim`::
-
- Strip whitespace from the end of a string.
-
-`strbuf_ltrim`::
-
- Strip whitespace from the beginning of a string.
-
-`strbuf_reencode`::
-
- Replace the contents of the strbuf with a reencoded form. Returns -1
- on error, 0 on success.
-
-`strbuf_tolower`::
-
- Lowercase each character in the buffer using `tolower`.
-
-`strbuf_cmp`::
-
- Compare two buffers. Returns an integer less than, equal to, or greater
- than zero if the first buffer is found, respectively, to be less than,
- to match, or be greater than the second buffer.
-
-* Adding data to the buffer
-
-NOTE: All of the functions in this section will grow the buffer as necessary.
-If they fail for some reason other than memory shortage and the buffer hadn't
-been allocated before (i.e. the `struct strbuf` was set to `STRBUF_INIT`),
-then they will free() it.
-
-`strbuf_addch`::
-
- Add a single character to the buffer.
-
-`strbuf_addchars`::
-
- Add a character the specified number of times to the buffer.
-
-`strbuf_insert`::
-
- Insert data to the given position of the buffer. The remaining contents
- will be shifted, not overwritten.
-
-`strbuf_remove`::
-
- Remove given amount of data from a given position of the buffer.
-
-`strbuf_splice`::
-
- Remove the bytes between `pos..pos+len` and replace it with the given
- data.
-
-`strbuf_add_commented_lines`::
-
- Add a NUL-terminated string to the buffer. Each line will be prepended
- by a comment character and a blank.
-
-`strbuf_add`::
-
- Add data of given length to the buffer.
-
-`strbuf_addstr`::
-
-Add a NUL-terminated string to the buffer.
-+
-NOTE: This function will *always* be implemented as an inline or a macro
-that expands to:
-+
-----
-strbuf_add(..., s, strlen(s));
-----
-+
-Meaning that this is efficient to write things like:
-+
-----
-strbuf_addstr(sb, "immediate string");
-----
-
-`strbuf_addbuf`::
-
- Copy the contents of another buffer at the end of the current one.
-
-`strbuf_adddup`::
-
- Copy part of the buffer from a given position till a given length to the
- end of the buffer.
-
-`strbuf_expand`::
-
- This function can be used to expand a format string containing
- placeholders. To that end, it parses the string and calls the specified
- function for every percent sign found.
-+
-The callback function is given a pointer to the character after the `%`
-and a pointer to the struct strbuf. It is expected to add the expanded
-version of the placeholder to the strbuf, e.g. to add a newline
-character if the letter `n` appears after a `%`. The function returns
-the length of the placeholder recognized and `strbuf_expand()` skips
-over it.
-+
-The format `%%` is automatically expanded to a single `%` as a quoting
-mechanism; callers do not need to handle the `%` placeholder themselves,
-and the callback function will not be invoked for this placeholder.
-+
-All other characters (non-percent and not skipped ones) are copied
-verbatim to the strbuf. If the callback returned zero, meaning that the
-placeholder is unknown, then the percent sign is copied, too.
-+
-In order to facilitate caching and to make it possible to give
-parameters to the callback, `strbuf_expand()` passes a context pointer,
-which can be used by the programmer of the callback as she sees fit.
-
-`strbuf_expand_dict_cb`::
-
- Used as callback for `strbuf_expand()`, expects an array of
- struct strbuf_expand_dict_entry as context, i.e. pairs of
- placeholder and replacement string. The array needs to be
- terminated by an entry with placeholder set to NULL.
-
-`strbuf_addbuf_percentquote`::
-
- Append the contents of one strbuf to another, quoting any
- percent signs ("%") into double-percents ("%%") in the
- destination. This is useful for literal data to be fed to either
- strbuf_expand or to the *printf family of functions.
-
-`strbuf_humanise_bytes`::
-
- Append the given byte size as a human-readable string (i.e. 12.23 KiB,
- 3.50 MiB).
-
-`strbuf_addf`::
-
- Add a formatted string to the buffer.
-
-`strbuf_commented_addf`::
-
- Add a formatted string prepended by a comment character and a
- blank to the buffer.
-
-`strbuf_fread`::
-
- Read a given size of data from a FILE* pointer to the buffer.
-+
-NOTE: The buffer is rewound if the read fails. If -1 is returned,
-`errno` must be consulted, like you would do for `read(3)`.
-`strbuf_read()`, `strbuf_read_file()` and `strbuf_getline()` has the
-same behaviour as well.
-
-`strbuf_read`::
-
- Read the contents of a given file descriptor. The third argument can be
- used to give a hint about the file size, to avoid reallocs.
-
-`strbuf_read_file`::
-
- Read the contents of a file, specified by its path. The third argument
- can be used to give a hint about the file size, to avoid reallocs.
-
-`strbuf_readlink`::
-
- Read the target of a symbolic link, specified by its path. The third
- argument can be used to give a hint about the size, to avoid reallocs.
-
-`strbuf_getline`::
-
- Read a line from a FILE *, overwriting the existing contents
- of the strbuf. The second argument specifies the line
- terminator character, typically `'\n'`.
- Reading stops after the terminator or at EOF. The terminator
- is removed from the buffer before returning. Returns 0 unless
- there was nothing left before EOF, in which case it returns `EOF`.
-
-`strbuf_getwholeline`::
-
- Like `strbuf_getline`, but keeps the trailing terminator (if
- any) in the buffer.
-
-`strbuf_getwholeline_fd`::
-
- Like `strbuf_getwholeline`, but operates on a file descriptor.
- It reads one character at a time, so it is very slow. Do not
- use it unless you need the correct position in the file
- descriptor.
-
-`strbuf_getcwd`::
-
- Set the buffer to the path of the current working directory.
-
-`strbuf_add_absolute_path`
-
- Add a path to a buffer, converting a relative path to an
- absolute one in the process. Symbolic links are not
- resolved.
-
-`stripspace`::
-
- Strip whitespace from a buffer. The second parameter controls if
- comments are considered contents to be removed or not.
-
-`strbuf_split_buf`::
-`strbuf_split_str`::
-`strbuf_split_max`::
-`strbuf_split`::
-
- Split a string or strbuf into a list of strbufs at a specified
- terminator character. The returned substrings include the
- terminator characters. Some of these functions take a `max`
- parameter, which, if positive, limits the output to that
- number of substrings.
-
-`strbuf_list_free`::
-
- Free a list of strbufs (for example, the return values of the
- `strbuf_split()` functions).
-
-`launch_editor`::
-
- Launch the user preferred editor to edit a file and fill the buffer
- with the file's contents upon the user completing their editing. The
- third argument can be used to set the environment which the editor is
- run in. If the buffer is NULL the editor is launched as usual but the
- file's contents are not read into the buffer upon completion.
diff --git a/strbuf.h b/strbuf.h
index 652b6c4..0a83f9a 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -1,22 +1,117 @@
#ifndef STRBUF_H
#define STRBUF_H
-/* See Documentation/technical/api-strbuf.txt */
+/**
+ * strbuf's are meant to be used with all the usual C string and memory
+ * APIs. Given that the length of the buffer is known, it's often better to
+ * use the mem* functions than a str* one (memchr vs. strchr e.g.).
+ * Though, one has to be careful about the fact that str* functions often
+ * stop on NULs and that strbufs may have embedded NULs.
+ *
+ * A strbuf is NUL terminated for convenience, but no function in the
+ * strbuf API actually relies on the string being free of NULs.
+ *
+ * strbufs have some invariants that are very important to keep in mind:
+ *
+ * . The `buf` member is never NULL, so it can be used in any usual C
+ * string operations safely. strbuf's _have_ to be initialized either by
+ * `strbuf_init()` or by `= STRBUF_INIT` before the invariants, though.
+ * +
+ * Do *not* assume anything on what `buf` really is (e.g. if it is
+ * allocated memory or not), use `strbuf_detach()` to unwrap a memory
+ * buffer from its strbuf shell in a safe way. That is the sole supported
+ * way. This will give you a malloced buffer that you can later `free()`.
+ * +
+ * However, it is totally safe to modify anything in the string pointed by
+ * the `buf` member, between the indices `0` and `len-1` (inclusive).
+ *
+ * . The `buf` member is a byte array that has at least `len + 1` bytes
+ * allocated. The extra byte is used to store a `'\0'`, allowing the
+ * `buf` member to be a valid C-string. Every strbuf function ensure this
+ * invariant is preserved.
+ * +
+ * NOTE: It is OK to "play" with the buffer directly if you work it this
+ * way:
+ * +
+ * ----
+ * strbuf_grow(sb, SOME_SIZE); <1>
+ * strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
+ * ----
+ * <1> Here, the memory array starting at `sb->buf`, and of length
+ * `strbuf_avail(sb)` is all yours, and you can be sure that
+ * `strbuf_avail(sb)` is at least `SOME_SIZE`.
+ * +
+ * NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`.
+ * +
+ * Doing so is safe, though if it has to be done in many places, adding the
+ * missing API to the strbuf module is the way to go.
+ * +
+ * WARNING: Do _not_ assume that the area that is yours is of size `alloc
+ * - 1` even if it's true in the current implementation. Alloc is somehow a
+ * "private" member that should not be messed with. Use `strbuf_avail()`
+ * instead.
+ */
-extern char strbuf_slopbuf[];
+/*
+ * Data Structures
+ * ---------------
+ */
+
+/**
+ * This is the string buffer structure. The `len` member can be used to
+ * determine the current length of the string, and `buf` member provides
+ * access to the string itself.
+ */
struct strbuf {
size_t alloc;
size_t len;
char *buf;
};
+extern char strbuf_slopbuf[];
#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
-/*----- strbuf life cycle -----*/
+/**
+ * Functions
+ * ---------
+ */
+
+/**
+ * * Life Cycle
+ */
+
+/**
+ * Initialize the structure. The second parameter can be zero or a bigger
+ * number to allocate memory, in case you want to prevent further reallocs.
+ */
extern void strbuf_init(struct strbuf *, size_t);
+
+/**
+ * Release a string buffer and the memory it used. You should not use the
+ * string buffer after using this function, unless you initialize it again.
+ */
extern void strbuf_release(struct strbuf *);
+
+/**
+ * Detach the string from the strbuf and returns it; you now own the
+ * storage the string occupies and it is your responsibility from then on
+ * to release it with `free(3)` when you are done with it.
+ */
extern char *strbuf_detach(struct strbuf *, size_t *);
+
+/**
+ * Attach a string to a buffer. You should specify the string to attach,
+ * the current length of the string and the amount of allocated memory.
+ * The amount must be larger than the string length, because the string you
+ * pass is supposed to be a NUL-terminated string. This string _must_ be
+ * malloc()ed, and after attaching, the pointer cannot be relied upon
+ * anymore, and neither be free()d directly.
+ */
extern void strbuf_attach(struct strbuf *, void *, size_t, size_t);
+
+/**
+ * Swap the contents of two string buffers.
+ */
static inline void strbuf_swap(struct strbuf *a, struct strbuf *b)
{
struct strbuf tmp = *a;
@@ -24,14 +119,35 @@ static inline void strbuf_swap(struct strbuf *a, struct strbuf *b)
*b = tmp;
}
-/*----- strbuf size related -----*/
+
+/**
+ * * Related to the size of the buffer
+ */
+
+/**
+ * Determine the amount of allocated but unused memory.
+ */
static inline size_t strbuf_avail(const struct strbuf *sb)
{
return sb->alloc ? sb->alloc - sb->len - 1 : 0;
}
+/**
+ * Ensure that at least this amount of unused memory is available after
+ * `len`. This is used when you know a typical size for what you will add
+ * and want to avoid repetitive automatic resizing of the underlying buffer.
+ * This is never a needed operation, but can be critical for performance in
+ * some cases.
+ */
extern void strbuf_grow(struct strbuf *, size_t);
+/**
+ * Set the length of the buffer to a given value. This function does *not*
+ * allocate new memory, so you should not perform a `strbuf_setlen()` to a
+ * length that is larger than `len + strbuf_avail()`. `strbuf_setlen()` is
+ * just meant as a 'please fix invariants from this strbuf I just messed
+ * with'.
+ */
static inline void strbuf_setlen(struct strbuf *sb, size_t len)
{
if (len > (sb->alloc ? sb->alloc - 1 : 0))
@@ -39,16 +155,285 @@ static inline void strbuf_setlen(struct strbuf *sb, size_t len)
sb->len = len;
sb->buf[len] = '\0';
}
+
+/**
+ * Empty the buffer by setting the size of it to zero.
+ */
#define strbuf_reset(sb) strbuf_setlen(sb, 0)
-/*----- content related -----*/
+
+/**
+ * * Related to the contents of the buffer
+ */
+
+/**
+ * Strip whitespace from the beginning and end of a string.
+ * Equivalent to performing `strbuf_rtrim()` followed by `strbuf_ltrim()`.
+ */
extern void strbuf_trim(struct strbuf *);
+
+/**
+ * Strip whitespace from the end of a string.
+ */
extern void strbuf_rtrim(struct strbuf *);
+
+/**
+ * Strip whitespace from the beginning of a string.
+ */
extern void strbuf_ltrim(struct strbuf *);
+
+/**
+ * Replace the contents of the strbuf with a reencoded form. Returns -1
+ * on error, 0 on success.
+ */
extern int strbuf_reencode(struct strbuf *sb, const char *from, const char *to);
+
+/**
+ * Lowercase each character in the buffer using `tolower`.
+ */
extern void strbuf_tolower(struct strbuf *sb);
+
+/**
+ * Compare two buffers. Returns an integer less than, equal to, or greater
+ * than zero if the first buffer is found, respectively, to be less than,
+ * to match, or be greater than the second buffer.
+ */
extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
+
+/**
+ * Adding data to the buffer
+ *
+ * NOTE: All of the functions in this section will grow the buffer as
+ * necessary. If they fail for some reason other than memory shortage and the
+ * buffer hadn't been allocated before (i.e. the `struct strbuf` was set to
+ * `STRBUF_INIT`), then they will free() it.
+ */
+
+/**
+ * Add a single character to the buffer.
+ */
+static inline void strbuf_addch(struct strbuf *sb, int c)
+{
+ strbuf_grow(sb, 1);
+ sb->buf[sb->len++] = c;
+ sb->buf[sb->len] = '\0';
+}
+
+/**
+ * Add a character the specified number of times to the buffer.
+ */
+extern void strbuf_addchars(struct strbuf *sb, int c, size_t n);
+
+/**
+ * Insert data to the given position of the buffer. The remaining contents
+ * will be shifted, not overwritten.
+ */
+extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t);
+
+/**
+ * Remove given amount of data from a given position of the buffer.
+ */
+extern void strbuf_remove(struct strbuf *, size_t pos, size_t len);
+
+/**
+ * Remove the bytes between `pos..pos+len` and replace it with the given
+ * data.
+ */
+extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
+ const void *, size_t);
+
+/**
+ * Add a NUL-terminated string to the buffer. Each line will be prepended
+ * by a comment character and a blank.
+ */
+extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
+
+
+/**
+ * Add data of given length to the buffer.
+ */
+extern void strbuf_add(struct strbuf *, const void *, size_t);
+
+/**
+ * Add a NUL-terminated string to the buffer.
+ *
+ * NOTE: This function will *always* be implemented as an inline or a macro
+ * using strlen, meaning that this is efficient to write things like:
+ *
+ * ----
+ * strbuf_addstr(sb, "immediate string");
+ * ----
+ *
+ */
+static inline void strbuf_addstr(struct strbuf *sb, const char *s)
+{
+ strbuf_add(sb, s, strlen(s));
+}
+
+/**
+ * Copy the contents of another buffer at the end of the current one.
+ */
+static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
+{
+ strbuf_grow(sb, sb2->len);
+ strbuf_add(sb, sb2->buf, sb2->len);
+}
+
+/**
+ * Copy part of the buffer from a given position till a given length to the
+ * end of the buffer.
+ */
+extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
+
+/**
+ * This function can be used to expand a format string containing
+ * placeholders. To that end, it parses the string and calls the specified
+ * function for every percent sign found.
+ *
+ * The callback function is given a pointer to the character after the `%`
+ * and a pointer to the struct strbuf. It is expected to add the expanded
+ * version of the placeholder to the strbuf, e.g. to add a newline
+ * character if the letter `n` appears after a `%`. The function returns
+ * the length of the placeholder recognized and `strbuf_expand()` skips
+ * over it.
+ *
+ * The format `%%` is automatically expanded to a single `%` as a quoting
+ * mechanism; callers do not need to handle the `%` placeholder themselves,
+ * and the callback function will not be invoked for this placeholder.
+ *
+ * All other characters (non-percent and not skipped ones) are copied
+ * verbatim to the strbuf. If the callback returned zero, meaning that the
+ * placeholder is unknown, then the percent sign is copied, too.
+ *
+ * In order to facilitate caching and to make it possible to give
+ * parameters to the callback, `strbuf_expand()` passes a context pointer,
+ * which can be used by the programmer of the callback as she sees fit.
+ */
+typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
+extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context);
+
+/**
+ * Used as callback for `strbuf_expand()`, expects an array of
+ * struct strbuf_expand_dict_entry as context, i.e. pairs of
+ * placeholder and replacement string. The array needs to be
+ * terminated by an entry with placeholder set to NULL.
+ */
+struct strbuf_expand_dict_entry {
+ const char *placeholder;
+ const char *value;
+};
+extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context);
+
+/**
+ * Append the contents of one strbuf to another, quoting any
+ * percent signs ("%") into double-percents ("%%") in the
+ * destination. This is useful for literal data to be fed to either
+ * strbuf_expand or to the *printf family of functions.
+ */
+extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
+
+/**
+ * Append the given byte size as a human-readable string (i.e. 12.23 KiB,
+ * 3.50 MiB).
+ */
+extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
+
+/**
+ * Add a formatted string to the buffer.
+ */
+__attribute__((format (printf,2,3)))
+extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
+
+/**
+ * Add a formatted string prepended by a comment character and a
+ * blank to the buffer.
+ */
+__attribute__((format (printf, 2, 3)))
+extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...);
+
+__attribute__((format (printf,2,0)))
+extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
+
+/**
+ * Read a given size of data from a FILE* pointer to the buffer.
+ *
+ * NOTE: The buffer is rewound if the read fails. If -1 is returned,
+ * `errno` must be consulted, like you would do for `read(3)`.
+ * `strbuf_read()`, `strbuf_read_file()` and `strbuf_getline()` has the
+ * same behaviour as well.
+ */
+extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
+
+/**
+ * Read the contents of a given file descriptor. The third argument can be
+ * used to give a hint about the file size, to avoid reallocs. If read fails,
+ * any partial read is undone */
+extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
+
+/**
+ * Read the contents of a file, specified by its path. The third argument
+ * can be used to give a hint about the file size, to avoid reallocs.
+ */
+extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
+
+/**
+ * Read the target of a symbolic link, specified by its path. The third
+ * argument can be used to give a hint about the size, to avoid reallocs.
+ */
+extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
+
+/**
+ * Set the buffer to the path of the current working directory.
+ */
+extern int strbuf_getcwd(struct strbuf *sb);
+
+/**
+ * Read a line from a FILE *, overwriting the existing contents
+ * of the strbuf. The second argument specifies the line
+ * terminator character, typically `'\n'`.
+ * Reading stops after the terminator or at EOF. The terminator
+ * is removed from the buffer before returning. Returns 0 unless
+ * there was nothing left before EOF, in which case it returns `EOF`.
+ */
+extern int strbuf_getline(struct strbuf *, FILE *, int);
+
+/**
+ * Like `strbuf_getline`, but keeps the trailing terminator (if
+ * any) in the buffer.
+ */
+extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
+
+/**
+ * Like `strbuf_getwholeline`, but operates on a file descriptor.
+ * It reads one character at a time, so it is very slow. Do not
+ * use it unless you need the correct position in the file
+ * descriptor.
+ */
+extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
+
+/**
+ * Add a path to a buffer, converting a relative path to an
+ * absolute one in the process. Symbolic links are not
+ * resolved.
+ */
+extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
+
+/**
+ * Strip whitespace from a buffer. The second parameter controls if
+ * comments are considered contents to be removed or not.
+ */
+extern void stripspace(struct strbuf *buf, int skip_comments);
+
+/**
+ * Launch the user preferred editor to edit a file and fill the buffer
+ * with the file's contents upon the user completing their editing. The
+ * third argument can be used to set the environment which the editor is
+ * run in. If the buffer is NULL the editor is launched as usual but the
+ * file's contents are not read into the buffer upon completion.
+ */
+extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
+
static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
{
if (strip_suffix_mem(sb->buf, &sb->len, suffix)) {
@@ -110,52 +495,6 @@ static inline struct strbuf **strbuf_split(const struct strbuf *sb,
*/
extern void strbuf_list_free(struct strbuf **);
-/*----- add data in your buffer -----*/
-static inline void strbuf_addch(struct strbuf *sb, int c)
-{
- strbuf_grow(sb, 1);
- sb->buf[sb->len++] = c;
- sb->buf[sb->len] = '\0';
-}
-
-extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t);
-extern void strbuf_remove(struct strbuf *, size_t pos, size_t len);
-
-/* splice pos..pos+len with given data */
-extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
- const void *, size_t);
-
-extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
-
-extern void strbuf_add(struct strbuf *, const void *, size_t);
-static inline void strbuf_addstr(struct strbuf *sb, const char *s)
-{
- strbuf_add(sb, s, strlen(s));
-}
-static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
-{
- strbuf_grow(sb, sb2->len);
- strbuf_add(sb, sb2->buf, sb2->len);
-}
-extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
-extern void strbuf_addchars(struct strbuf *sb, int c, size_t n);
-
-typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
-extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context);
-struct strbuf_expand_dict_entry {
- const char *placeholder;
- const char *value;
-};
-extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context);
-extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
-
-__attribute__((format (printf,2,3)))
-extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
-__attribute__((format (printf, 2, 3)))
-extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...);
-__attribute__((format (printf,2,0)))
-extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
-
extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
/*
@@ -170,28 +509,11 @@ static inline void strbuf_complete_line(struct strbuf *sb)
strbuf_addch(sb, '\n');
}
-extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
-/* XXX: if read fails, any partial read is undone */
-extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
-extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
-extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
-extern int strbuf_getcwd(struct strbuf *sb);
-
-extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
-extern int strbuf_getline(struct strbuf *, FILE *, int);
-extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
-
-extern void stripspace(struct strbuf *buf, int skip_comments);
-extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
-
extern int strbuf_branchname(struct strbuf *sb, const char *name);
extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
int reserved);
-extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
-
-extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
__attribute__((format (printf,1,2)))
extern int printf_ln(const char *fmt, ...);
--
2.2.0.454.g7eca6b7
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs
2014-12-12 21:27 ` Jeff King
2014-12-12 21:28 ` [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h Jeff King
@ 2014-12-12 21:28 ` Jeff King
2014-12-12 22:19 ` Junio C Hamano
2014-12-12 22:37 ` Jonathan Nieder
2014-12-12 21:30 ` [PATCH 3/4] strbuf.h: format asciidoc code blocks as 4-space indent Jeff King
` (2 subsequent siblings)
4 siblings, 2 replies; 49+ messages in thread
From: Jeff King @ 2014-12-12 21:28 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Using a hanging indent is much more readable. This means we
won't format as asciidoc anymore, but since we don't have a
working system for extracting these comments anyway, it's
probably more important to just make the source readable.
Signed-off-by: Jeff King <peff@peff.net>
---
strbuf.h | 74 ++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 37 insertions(+), 37 deletions(-)
diff --git a/strbuf.h b/strbuf.h
index 0a83f9a..8f63b38 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -13,44 +13,44 @@
*
* strbufs have some invariants that are very important to keep in mind:
*
- * . The `buf` member is never NULL, so it can be used in any usual C
- * string operations safely. strbuf's _have_ to be initialized either by
- * `strbuf_init()` or by `= STRBUF_INIT` before the invariants, though.
- * +
- * Do *not* assume anything on what `buf` really is (e.g. if it is
- * allocated memory or not), use `strbuf_detach()` to unwrap a memory
- * buffer from its strbuf shell in a safe way. That is the sole supported
- * way. This will give you a malloced buffer that you can later `free()`.
- * +
- * However, it is totally safe to modify anything in the string pointed by
- * the `buf` member, between the indices `0` and `len-1` (inclusive).
+ * - The `buf` member is never NULL, so it can be used in any usual C
+ * string operations safely. strbuf's _have_ to be initialized either by
+ * `strbuf_init()` or by `= STRBUF_INIT` before the invariants, though.
*
- * . The `buf` member is a byte array that has at least `len + 1` bytes
- * allocated. The extra byte is used to store a `'\0'`, allowing the
- * `buf` member to be a valid C-string. Every strbuf function ensure this
- * invariant is preserved.
- * +
- * NOTE: It is OK to "play" with the buffer directly if you work it this
- * way:
- * +
- * ----
- * strbuf_grow(sb, SOME_SIZE); <1>
- * strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
- * ----
- * <1> Here, the memory array starting at `sb->buf`, and of length
- * `strbuf_avail(sb)` is all yours, and you can be sure that
- * `strbuf_avail(sb)` is at least `SOME_SIZE`.
- * +
- * NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`.
- * +
- * Doing so is safe, though if it has to be done in many places, adding the
- * missing API to the strbuf module is the way to go.
- * +
- * WARNING: Do _not_ assume that the area that is yours is of size `alloc
- * - 1` even if it's true in the current implementation. Alloc is somehow a
- * "private" member that should not be messed with. Use `strbuf_avail()`
- * instead.
- */
+ * Do *not* assume anything on what `buf` really is (e.g. if it is
+ * allocated memory or not), use `strbuf_detach()` to unwrap a memory
+ * buffer from its strbuf shell in a safe way. That is the sole supported
+ * way. This will give you a malloced buffer that you can later `free()`.
+ *
+ * However, it is totally safe to modify anything in the string pointed by
+ * the `buf` member, between the indices `0` and `len-1` (inclusive).
+ *
+ * - The `buf` member is a byte array that has at least `len + 1` bytes
+ * allocated. The extra byte is used to store a `'\0'`, allowing the
+ * `buf` member to be a valid C-string. Every strbuf function ensure this
+ * invariant is preserved.
+ *
+ * NOTE: It is OK to "play" with the buffer directly if you work it this
+ * way:
+ *
+ * ----
+ * strbuf_grow(sb, SOME_SIZE); <1>
+ * strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
+ * ----
+ * <1> Here, the memory array starting at `sb->buf`, and of length
+ * `strbuf_avail(sb)` is all yours, and you can be sure that
+ * `strbuf_avail(sb)` is at least `SOME_SIZE`.
+ *
+ * NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`.
+ *
+ * Doing so is safe, though if it has to be done in many places, adding the
+ * missing API to the strbuf module is the way to go.
+ *
+ * WARNING: Do _not_ assume that the area that is yours is of size `alloc
+ * - 1` even if it's true in the current implementation. Alloc is somehow a
+ * "private" member that should not be messed with. Use `strbuf_avail()`
+ * instead.
+*/
/*
* Data Structures
--
2.2.0.454.g7eca6b7
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 3/4] strbuf.h: format asciidoc code blocks as 4-space indent
2014-12-12 21:27 ` Jeff King
2014-12-12 21:28 ` [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h Jeff King
2014-12-12 21:28 ` [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs Jeff King
@ 2014-12-12 21:30 ` Jeff King
2014-12-12 22:39 ` Jonathan Nieder
2014-12-12 21:32 ` [PATCH 4/4] strbuf.h: reorganize api function grouping headers Jeff King
2014-12-12 22:32 ` [PATCH] document string_list_clear Stefan Beller
4 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2014-12-12 21:30 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
This is much easier to read when the whole thing is stuffed
inside a comment block. And there is precedent for this
convention in markdown (and just in general ascii text).
Signed-off-by: Jeff King <peff@peff.net>
---
As a side note, I actually find markdown much more pleasant to read and
write than asciidoc. I think the output is not always as nice, as it
does not have some of the structured elements that let us produce nice
manpages, for example. But I wonder if it would be a better choice for
formatting API documentation.
Not something that is really relevant to this series, but just food for
thought if we do end up with an extract+format tool.
strbuf.h | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/strbuf.h b/strbuf.h
index 8f63b38..078b805 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -33,10 +33,9 @@
* NOTE: It is OK to "play" with the buffer directly if you work it this
* way:
*
- * ----
- * strbuf_grow(sb, SOME_SIZE); <1>
- * strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
- * ----
+ * strbuf_grow(sb, SOME_SIZE); <1>
+ * strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE);
+ *
* <1> Here, the memory array starting at `sb->buf`, and of length
* `strbuf_avail(sb)` is all yours, and you can be sure that
* `strbuf_avail(sb)` is at least `SOME_SIZE`.
@@ -261,9 +260,7 @@ extern void strbuf_add(struct strbuf *, const void *, size_t);
* NOTE: This function will *always* be implemented as an inline or a macro
* using strlen, meaning that this is efficient to write things like:
*
- * ----
- * strbuf_addstr(sb, "immediate string");
- * ----
+ * strbuf_addstr(sb, "immediate string");
*
*/
static inline void strbuf_addstr(struct strbuf *sb, const char *s)
--
2.2.0.454.g7eca6b7
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH 4/4] strbuf.h: reorganize api function grouping headers
2014-12-12 21:27 ` Jeff King
` (2 preceding siblings ...)
2014-12-12 21:30 ` [PATCH 3/4] strbuf.h: format asciidoc code blocks as 4-space indent Jeff King
@ 2014-12-12 21:32 ` Jeff King
2014-12-12 22:46 ` Jonathan Nieder
2014-12-12 22:32 ` [PATCH] document string_list_clear Stefan Beller
4 siblings, 1 reply; 49+ messages in thread
From: Jeff King @ 2014-12-12 21:32 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
The original API doc had something like:
Functions
---------
* Life cycle
... some life-cycle functions ...
* Related to the contents of the buffer
... functions related to contents ....
etc
This grouping can be hard to read in the comment sources,
given the "*" in the comment lines, and the amount of text
between each section.
Instead, let's make a flat list of groupings, and underline
each as a section header. That makes them standout, and
eliminates the weird half-phrase of "Related to...". Like:
Functions related to the contents of the buffer
-----------------------------------------------
Signed-off-by: Jeff King <peff@peff.net>
---
If you look at the original header file, these groupings actually did
exist (though we did not remotely follow them as functions were added),
and looked like:
/* ---- content related ---- */
I'd be happy with something like that, too, but went with the style that
matched the "Data Structures" header.
strbuf.h | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/strbuf.h b/strbuf.h
index 078b805..8649a0a 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -71,12 +71,8 @@ extern char strbuf_slopbuf[];
#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
/**
- * Functions
- * ---------
- */
-
-/**
- * * Life Cycle
+ * Life Cycle Functions
+ * --------------------
*/
/**
@@ -120,7 +116,8 @@ static inline void strbuf_swap(struct strbuf *a, struct strbuf *b)
/**
- * * Related to the size of the buffer
+ * Functions related to the size of the buffer
+ * -------------------------------------------
*/
/**
@@ -162,7 +159,8 @@ static inline void strbuf_setlen(struct strbuf *sb, size_t len)
/**
- * * Related to the contents of the buffer
+ * Functions related to the contents of the buffer
+ * -----------------------------------------------
*/
/**
--
2.2.0.454.g7eca6b7
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h
2014-12-12 21:28 ` [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h Jeff King
@ 2014-12-12 21:40 ` Jeff King
2014-12-12 22:16 ` Junio C Hamano
2014-12-12 22:30 ` Jonathan Nieder
2 siblings, 0 replies; 49+ messages in thread
From: Jeff King @ 2014-12-12 21:40 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Fri, Dec 12, 2014 at 04:28:00PM -0500, Jeff King wrote:
> 1. All comments created in this way are started with "/**"
> to indicate they are part of the API documentation. This
> may help later with extracting the text to pretty-print
> it.
By the way, two thoughts I had while working on this.
One, I wonder if it would look nicer to drop the leading " * " from our
comments, especially for long, free-form text blocks. Like:
/**
Data Structures
---------------
This is actual asciidoc that can be rendered. It's not _nearly_ as
ugly to leave the asciidoc intact if you avoid the leading asterisks.
*/
I also wondered if you could spell it as:
#ifdef API_DOCUMENTATION
... some asciidoc goes here...
#endif
but the preprocessor does still look at the contents. I didn't check the
standard, but I suspect an implementation doesn't _have_ to, but gcc
will warn about things like unmatched single-quotes in the content.
And two, the editor support for writing comments like this is not as
good. For instance, vim's "reformat paragraph" command considers the
whole comment to be the paragraph. If you're writing asciidoc inside
the comment field, this quickly becomes annoying. This is a minor issue
that can be fixed (I am sure there is probably a vim package to do it
better already, and that emacs people will tsk tsk and explain why their
editor is better), but I thought I would note it as a potential "con" of
this approach.
-Peff
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h
2014-12-12 21:28 ` [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h Jeff King
2014-12-12 21:40 ` Jeff King
@ 2014-12-12 22:16 ` Junio C Hamano
2014-12-12 22:30 ` Jonathan Nieder
2 siblings, 0 replies; 49+ messages in thread
From: Junio C Hamano @ 2014-12-12 22:16 UTC (permalink / raw)
To: Jeff King
Cc: Jonathan Nieder, Stefan Beller, git@vger.kernel.org,
Michael Haggerty
Jeff King <peff@peff.net> writes:
> +/**
> + * * Related to the contents of the buffer
> + */
> +
> +/**
> + * Strip whitespace from the beginning and end of a string.
> + * Equivalent to performing `strbuf_rtrim()` followed by `strbuf_ltrim()`.
> + */
> extern void strbuf_trim(struct strbuf *);
> +
> +/**
> + * Strip whitespace from the end of a string.
> + */
> extern void strbuf_rtrim(struct strbuf *);
> +
> +/**
> + * Strip whitespace from the beginning of a string.
> + */
> extern void strbuf_ltrim(struct strbuf *);
This part reminds me why I often find the current "out of header"
documentation when writing code _without_ the need for _learning_
the API. The corresponding part in the original is merely these:
/*----- content related -----*/
extern void strbuf_trim(struct strbuf *);
extern void strbuf_rtrim(struct strbuf *);
extern void strbuf_ltrim(struct strbuf *);
extern int strbuf_reencode(struct strbuf *sb, const char *from, const char *to);
...
It is a lot quicker, scanning this with eyeball, to notice that
there are three related "trim" functions and how they are spelled.
If I wanted to "trim from both ends", knew there were some ways to
"trim" but didn't remember if we had r/ltrim without trim, and/or
was not sure if the "both" version was was _trim or _btrim, scanning
a bland list tends to be much more pleasant.
When you are _learning_ the API, the format that spreads each
individual function into its own section with explanation would be
easier to read through.
Not a strong objection to the overall direction, but I think that we
need to be aware that we are making things harder for some use
cases.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs
2014-12-12 21:28 ` [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs Jeff King
@ 2014-12-12 22:19 ` Junio C Hamano
2014-12-12 22:37 ` Jonathan Nieder
1 sibling, 0 replies; 49+ messages in thread
From: Junio C Hamano @ 2014-12-12 22:19 UTC (permalink / raw)
To: Jeff King
Cc: Jonathan Nieder, Stefan Beller, git@vger.kernel.org,
Michael Haggerty
Jeff King <peff@peff.net> writes:
> Using a hanging indent is much more readable. This means we
> won't format as asciidoc anymore, but since we don't have a
> working system for extracting these comments anyway, it's
> probably more important to just make the source readable.
Yeah.
Those who want to strip the leading " * " to turn it into AsciiDoc
would need to also parse out the hanging indent and format into
AsciiDoc, which is not entirely an unreasonable thing to ask.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h
2014-12-12 21:28 ` [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h Jeff King
2014-12-12 21:40 ` Jeff King
2014-12-12 22:16 ` Junio C Hamano
@ 2014-12-12 22:30 ` Jonathan Nieder
2 siblings, 0 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-12 22:30 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Documentation/technical/api-strbuf.txt | 351 -------------------------
> strbuf.h | 458 ++++++++++++++++++++++++++++-----
> 2 files changed, 390 insertions(+), 419 deletions(-)
> delete mode 100644 Documentation/technical/api-strbuf.txt
Thanks. This looks very sensible. Some suggested tweaks below (see patch at
bottom).
> +++ b/strbuf.h
[...]
> +/**
> + * * Life Cycle
[...]
> +/**
> + * Adding data to the buffer
These were headings like
* Life Cycle
* Adding data to the buffer
Most ended up as ' * *' after the conversion, keeping the extra '*', but
'Adding data to the buffer' didn't.
After patch 4/4 they look the same again, so it doesn't matter.
[...]
> * NOTE: This function will *always* be implemented as an inline or a macro
> - * that expands to:
> - * +
> - * ----
> - * strbuf_add(..., s, strlen(s));
> - * ----
> - * +
> - * Meaning that this is efficient to write things like:
> + * using strlen, meaning that this is efficient to write things like:
> *
> * ----
> * strbuf_addstr(sb, "immediate string");
> * ----
Makes sense.
[...]
> /**
> * Read the contents of a given file descriptor. The third argument can be
> - * used to give a hint about the file size, to avoid reallocs.
> - */
> + * used to give a hint about the file size, to avoid reallocs. If read fails,
> + * any partial read is undone */
Missing period at end of sentence. "*/" should go on the next line.
[...]
> +extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
> +
> +/**
> + * Set the buffer to the path of the current working directory.
> + */
> +extern int strbuf_getcwd(struct strbuf *sb);
This snuck up a few lines --- it was between getwholeline_fd and
add_absolute_path before. I think it makes sense for getcwd to be
next to add_absolute_path.
[...]
> +extern void stripspace(struct strbuf *buf, int skip_comments);
> +
> +/**
> + * Launch the user preferred editor to edit a file and fill the buffer
> + * with the file's contents upon the user completing their editing. The
> + * third argument can be used to set the environment which the editor is
> + * run in. If the buffer is NULL the editor is launched as usual but the
> + * file's contents are not read into the buffer upon completion.
> + */
> +extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
split_* were before this before. Probably launch_editor belongs with
read_file and co instead, but during this conversion it makes sense to
just keep the order from before.
[...]
> - * `strbuf_split_buf`::
> - * `strbuf_split_str`::
> - * `strbuf_split_max`::
> - * `strbuf_split`::
> - *
> - * Split a string or strbuf into a list of strbufs at a specified
> - * terminator character. The returned substrings include the
> - * terminator characters. Some of these functions take a `max`
> - * parameter, which, if positive, limits the output to that
> - * number of substrings.
> - *
> - * `strbuf_list_free`::
> - *
> - * Free a list of strbufs (for example, the return values of the
> - * `strbuf_split()` functions).
> +/*
> + * Split str (of length slen) at the specified terminator character.
> + * Return a null-terminated array of pointers to strbuf objects
> + * holding the substrings. The substrings include the terminator,
> + * except for the last substring, which might be unterminated if the
[...]
> + */
> +extern struct strbuf **strbuf_split_buf(const char *, size_t,
> + int terminator, int max);
> +
> +/*
> + * Split a NUL-terminated string at the specified terminator
> + * character. See strbuf_split_buf() for more information.
> + */
> +static inline struct strbuf **strbuf_split_str(const char *str,
> + int terminator, int max)
> +{
> + return strbuf_split_buf(str, strlen(str), terminator, max);
> +}
> +
> +/*
> + * Split a strbuf at the specified terminator character. See
> + * strbuf_split_buf() for more information.
> + */
> +static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,
This is something that the flat file format did better. Would it work to
do something similar, for example by dropping the boilerplate comment
before the inline functions (not shown in the patch below)?
/**
* Split a string or strbuf into a list of strbufs at a specified
* terminator character. [...]
*/
extern struct strbuf **strbuf_split_buf(const char *, size_t, int terminator, int max);
static inline struct strbuf **strbuf_split_str(const char *str, int terminator, int max)
{
return strbuf_split_buf(str, strlen(str), terminator, max);
}
static inline struct strbuf **strbuf_split_max(const struct strbuf *sb, int terminator, int max)
{
return strbuf_split_buf(sb->buf, sb->len, terminator, max);
}
static inline struct strbuf **strbuf_split(const struct strbuf *sb, int terminator)
{
return strbuf_split_max(sb, terminator, 0);
}
/**
* Free a list of strbufs (for example, the return values of the
* `strbuf_split()` functions).
*/
extern void strbuf_list_free(struct strbuf **);
strbuf.h | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/strbuf.h b/strbuf.h
index 0a83f9a..108644e 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -202,7 +202,7 @@ extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
/**
- * Adding data to the buffer
+ * * Adding data to the buffer
*
* NOTE: All of the functions in this section will grow the buffer as
* necessary. If they fail for some reason other than memory shortage and the
@@ -368,7 +368,8 @@ extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
/**
* Read the contents of a given file descriptor. The third argument can be
* used to give a hint about the file size, to avoid reallocs. If read fails,
- * any partial read is undone */
+ * any partial read is undone.
+ */
extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
/**
@@ -384,11 +385,6 @@ extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
/**
- * Set the buffer to the path of the current working directory.
- */
-extern int strbuf_getcwd(struct strbuf *sb);
-
-/**
* Read a line from a FILE *, overwriting the existing contents
* of the strbuf. The second argument specifies the line
* terminator character, typically `'\n'`.
@@ -413,6 +409,11 @@ extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
/**
+ * Set the buffer to the path of the current working directory.
+ */
+extern int strbuf_getcwd(struct strbuf *sb);
+
+/**
* Add a path to a buffer, converting a relative path to an
* absolute one in the process. Symbolic links are not
* resolved.
@@ -425,15 +426,6 @@ extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
*/
extern void stripspace(struct strbuf *buf, int skip_comments);
-/**
- * Launch the user preferred editor to edit a file and fill the buffer
- * with the file's contents upon the user completing their editing. The
- * third argument can be used to set the environment which the editor is
- * run in. If the buffer is NULL the editor is launched as usual but the
- * file's contents are not read into the buffer upon completion.
- */
-extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
-
static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
{
if (strip_suffix_mem(sb->buf, &sb->len, suffix)) {
@@ -495,6 +487,15 @@ static inline struct strbuf **strbuf_split(const struct strbuf *sb,
*/
extern void strbuf_list_free(struct strbuf **);
+/**
+ * Launch the user preferred editor to edit a file and fill the buffer
+ * with the file's contents upon the user completing their editing. The
+ * third argument can be used to set the environment which the editor is
+ * run in. If the buffer is NULL the editor is launched as usual but the
+ * file's contents are not read into the buffer upon completion.
+ */
+extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
+
extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
/*
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH] document string_list_clear
2014-12-12 21:27 ` Jeff King
` (3 preceding siblings ...)
2014-12-12 21:32 ` [PATCH 4/4] strbuf.h: reorganize api function grouping headers Jeff King
@ 2014-12-12 22:32 ` Stefan Beller
4 siblings, 0 replies; 49+ messages in thread
From: Stefan Beller @ 2014-12-12 22:32 UTC (permalink / raw)
To: Jeff King
Cc: Jonathan Nieder, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
On Fri, Dec 12, 2014 at 04:27:26PM -0500, Jeff King wrote:
> On Fri, Dec 12, 2014 at 11:35:52AM -0800, Jonathan Nieder wrote:
>
> > If I were doing it, I would first de-asciidoc within technical/ and
> > then move into the header in a separate patch. Or first move with
> > asciidoc intact and then de-asciidoc in a separate patch. Combining
> > the two into a single patch is also fine. Please don't change wording
> > at the same time.
>
> Here's what I came up with. The first patch probably does more than
> you'd like (and more than I would have done if I were starting from
> scratch today). But I didn't want to get into undoing the stripping of
> each function-name list item that I showed earlier, as it would be a lot
> of tedious manual work. If we decide we want to keep those, I'm happy to
> do the work to restore them, but it didn't seem like a good tradeoff
> just to create an intermediate state to make the patch prettier.
>
> I did split out some of the other formatting decisions, though, so they
> can be evaluated individually.
>
> [1/4]: strbuf: migrate api-strbuf.txt documentation to strbuf.h
(optional nit):
The subject of this patch is slightly different than the others.
How about:
strbuf.h: integrate api-strbuf.txt documentation
> [2/4]: strbuf.h: drop asciidoc list formatting from API docs
> [3/4]: strbuf.h: format asciidoc code blocks as 4-space indent
> [4/4]: strbuf.h: reorganize api function grouping headers
>
> -Peff
I have reviewed the series and I personally like it as I am more
often in the learners/discovery stage than the fast lookup stage
as Junio mentioned.
Another inconsistency I found specifically related to the strbuf.h
documentation is the apparent changeing style.
At the beginning we have
extern void strbuf_attach(struct strbuf *, void *, size_t, size_t);
Even with the documentation attached, which size_t is the length and what the
amount of allocated memory? Later we have more explaining names, such as
extern struct strbuf **strbuf_split_buf(const char *, size_t,
int terminator, int max);
Please append the following patch to your series. I noticed this as
the text editor I use uses different colors for
/** comments starting with double stars used with i.e. doxygen */
/* random comments in the file */
Thanks,
Stefan
-----------8<------------------
From 5d0f98aba65e8b1415ebfcd8e06b67203e9305a7 Mon Sep 17 00:00:00 2001
From: Stefan Beller <sbeller@google.com>
Date: Fri, 12 Dec 2014 14:27:15 -0800
Subject: [PATCH] strbuf.h: Unify documentation comments beginnings
We want to preserve the meaning of "/**" to start a documentary
in depth comment, so all of the documenting comments should start with
a "/**".
Signed-off-by: Stefan Beller <sbeller@google.com>
---
strbuf.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/strbuf.h b/strbuf.h
index 8649a0a..95d49e1 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -438,7 +438,7 @@ static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
return 0;
}
-/*
+/**
* Split str (of length slen) at the specified terminator character.
* Return a null-terminated array of pointers to strbuf objects
* holding the substrings. The substrings include the terminator,
@@ -454,7 +454,7 @@ static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
extern struct strbuf **strbuf_split_buf(const char *, size_t,
int terminator, int max);
-/*
+/**
* Split a NUL-terminated string at the specified terminator
* character. See strbuf_split_buf() for more information.
*/
@@ -464,7 +464,7 @@ static inline struct strbuf **strbuf_split_str(const char *str,
return strbuf_split_buf(str, strlen(str), terminator, max);
}
-/*
+/**
* Split a strbuf at the specified terminator character. See
* strbuf_split_buf() for more information.
*/
@@ -474,7 +474,7 @@ static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,
return strbuf_split_buf(sb->buf, sb->len, terminator, max);
}
-/*
+/**
* Split a strbuf at the specified terminator character. See
* strbuf_split_buf() for more information.
*/
@@ -484,7 +484,7 @@ static inline struct strbuf **strbuf_split(const struct strbuf *sb,
return strbuf_split_max(sb, terminator, 0);
}
-/*
+/**
* Free a NULL-terminated list of strbufs (for example, the return
* values of the strbuf_split*() functions).
*/
@@ -492,7 +492,7 @@ extern void strbuf_list_free(struct strbuf **);
extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
-/*
+/**
* Append s to sb, with the characters '<', '>', '&' and '"' converted
* into XML entities.
*/
--
2.2.0.38.g71d6cb7
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs
2014-12-12 21:28 ` [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs Jeff King
2014-12-12 22:19 ` Junio C Hamano
@ 2014-12-12 22:37 ` Jonathan Nieder
1 sibling, 0 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-12 22:37 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
> Using a hanging indent is much more readable. This means we
> won't format as asciidoc anymore, but since we don't have a
> working system for extracting these comments anyway, it's
> probably more important to just make the source readable.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> strbuf.h | 74 ++++++++++++++++++++++++++++++++--------------------------------
> 1 file changed, 37 insertions(+), 37 deletions(-)
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Thanks.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 3/4] strbuf.h: format asciidoc code blocks as 4-space indent
2014-12-12 21:30 ` [PATCH 3/4] strbuf.h: format asciidoc code blocks as 4-space indent Jeff King
@ 2014-12-12 22:39 ` Jonathan Nieder
2014-12-14 17:42 ` Michael Haggerty
0 siblings, 1 reply; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-12 22:39 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
> This is much easier to read when the whole thing is stuffed
> inside a comment block. And there is precedent for this
> convention in markdown (and just in general ascii text).
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
> As a side note, I actually find markdown much more pleasant to read and
> write than asciidoc.
I do, too. Quoting in asciidoc is a nightmare.
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 4/4] strbuf.h: reorganize api function grouping headers
2014-12-12 21:32 ` [PATCH 4/4] strbuf.h: reorganize api function grouping headers Jeff King
@ 2014-12-12 22:46 ` Jonathan Nieder
0 siblings, 0 replies; 49+ messages in thread
From: Jonathan Nieder @ 2014-12-12 22:46 UTC (permalink / raw)
To: Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org,
Michael Haggerty
Jeff King wrote:
> If you look at the original header file, these groupings actually did
> exist (though we did not remotely follow them as functions were added),
> and looked like:
>
> /* ---- content related ---- */
>
> I'd be happy with something like that, too, but went with the style that
> matched the "Data Structures" header.
I'd be happy either way too.
> strbuf.h | 14 ++++++--------
> 1 file changed, 6 insertions(+), 8 deletions(-)
This is missing the "Adding data to the buffer" section.
Except for that,
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH 3/4] strbuf.h: format asciidoc code blocks as 4-space indent
2014-12-12 22:39 ` Jonathan Nieder
@ 2014-12-14 17:42 ` Michael Haggerty
0 siblings, 0 replies; 49+ messages in thread
From: Michael Haggerty @ 2014-12-14 17:42 UTC (permalink / raw)
To: Jonathan Nieder, Jeff King
Cc: Stefan Beller, Junio C Hamano, git@vger.kernel.org
On 12/12/2014 11:39 PM, Jonathan Nieder wrote:
> Jeff King wrote:
>
>> This is much easier to read when the whole thing is stuffed
>> inside a comment block. And there is precedent for this
>> convention in markdown (and just in general ascii text).
>>
>> Signed-off-by: Jeff King <peff@peff.net>
>> ---
>
> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
>
>> As a side note, I actually find markdown much more pleasant to read and
>> write than asciidoc.
>
> I do, too. Quoting in asciidoc is a nightmare.
Peff, thanks for working on this. I think it is a definite improvement.
I suggest that we accept the use of asciidoc/markdown's convention of
using backwards quotes to mark code snippets (especially identifier
names) within comments *anywhere* in our code base. For example, this
appears in refs.c:
/*
* Create a struct ref_entry object for the specified dirname.
* dirname is the name of the directory with a trailing slash
* (e.g., "refs/heads/") or "" for the top-level directory.
*/
I claim that it is more readable with a tiny bit of markup:
/*
* Create a `struct ref_entry` object for the specified `dirname`.
* `dirname` is the name of the directory with a trailing slash
* (e.g., "refs/heads/") or "" for the top-level directory.
*/
Marking up `struct ref_entry` helps make it clear that the two words
belong together, and marking up `dirname` makes it clear that we are
talking about a specific identifier (in this case, a function parameter).
Currently, comments use a mix of unadorned text, single-quoted text, and
double-quoted text when talking about code. I think the
asciidoc/markdown convention is clearer [1].
I think we shouldn't be pedantic about this. When a comment is readable
with no markup, there's no need to add markup. And "incorrect" markup
shouldn't by itself be reason to reject a patch. But in many examples, a
little bit of markup makes the text less ambiguous and easier to read.
Michael
[1] Yes, I see the irony in trying to improve a mixture of three
conventions by adding a fourth one.
--
Michael Haggerty
mhagger@alum.mit.edu
^ permalink raw reply [flat|nested] 49+ messages in thread
end of thread, other threads:[~2014-12-14 17:42 UTC | newest]
Thread overview: 49+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-06 1:51 [PATCH] document string_list_clear Stefan Beller
2014-12-06 2:04 ` Jonathan Nieder
2014-12-06 5:27 ` Jeff King
2014-12-06 5:30 ` Jeff King
2014-12-09 19:41 ` Junio C Hamano
2014-12-09 20:15 ` Jeff King
2014-12-09 20:21 ` Jonathan Nieder
2014-12-09 19:37 ` Junio C Hamano
2014-12-09 19:48 ` Stefan Beller
2014-12-09 20:17 ` Jonathan Nieder
2014-12-09 20:27 ` Jeff King
2014-12-09 20:32 ` Stefan Beller
2014-12-09 20:46 ` Jeff King
2014-12-09 22:23 ` Jonathan Nieder
2014-12-09 23:18 ` Junio C Hamano
2014-12-10 8:52 ` Jeff King
2014-12-10 8:43 ` Jeff King
2014-12-10 9:18 ` Jonathan Nieder
2014-12-12 9:16 ` Jeff King
2014-12-12 18:31 ` Jonathan Nieder
2014-12-12 19:17 ` Junio C Hamano
2014-12-12 19:19 ` Stefan Beller
2014-12-12 19:29 ` Jeff King
2014-12-12 19:24 ` Jeff King
2014-12-12 19:35 ` Jonathan Nieder
2014-12-12 21:27 ` Jeff King
2014-12-12 21:28 ` [PATCH 1/4] strbuf: migrate api-strbuf.txt documentation to strbuf.h Jeff King
2014-12-12 21:40 ` Jeff King
2014-12-12 22:16 ` Junio C Hamano
2014-12-12 22:30 ` Jonathan Nieder
2014-12-12 21:28 ` [PATCH 2/4] strbuf.h: drop asciidoc list formatting from API docs Jeff King
2014-12-12 22:19 ` Junio C Hamano
2014-12-12 22:37 ` Jonathan Nieder
2014-12-12 21:30 ` [PATCH 3/4] strbuf.h: format asciidoc code blocks as 4-space indent Jeff King
2014-12-12 22:39 ` Jonathan Nieder
2014-12-14 17:42 ` Michael Haggerty
2014-12-12 21:32 ` [PATCH 4/4] strbuf.h: reorganize api function grouping headers Jeff King
2014-12-12 22:46 ` Jonathan Nieder
2014-12-12 22:32 ` [PATCH] document string_list_clear Stefan Beller
2014-12-10 20:09 ` Michael Haggerty
2014-12-10 21:51 ` Jonathan Nieder
2014-12-10 22:28 ` Junio C Hamano
2014-12-10 22:37 ` Jonathan Nieder
2014-12-10 23:04 ` Junio C Hamano
2014-12-10 23:08 ` Jonathan Nieder
2014-12-09 22:49 ` Jonathan Nieder
2014-12-09 23:07 ` Stefan Beller
2014-12-09 23:15 ` Jonathan Nieder
2014-12-09 20:00 ` Jonathan Nieder
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).