* [PATCH] Documentation: document the string-list macros.
@ 2010-09-05 17:51 Thiago Farina
2010-09-05 20:03 ` [demo/patch 0/3] " Jonathan Nieder
0 siblings, 1 reply; 6+ messages in thread
From: Thiago Farina @ 2010-09-05 17:51 UTC (permalink / raw)
To: git; +Cc: jrnieder
Add basic documentation about the string-list.h macros
that can be used to initialize the string_list structure.
Signed-off-by: Thiago Farina <tfransosi@gmail.com>
---
Documentation/technical/api-string-list.txt | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt
index 3f575bd..cec11b5 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -52,6 +52,18 @@ However, if you use the list to check if a certain string was added
already, you should not do that (using unsorted_string_list_has_string()),
because the complexity would be quadratic again (but with a worse factor).
+Macros
+------
+
+`STRING_LIST_INIT_NODUP`::
+
+ Initialize the members and set the `strdup_strings` member to 0.
+
+`STRING_LIST_INIT_DUP`::
+
+ Initialize the members and set the `strdup_strings` member to 1.
+
+
Functions
---------
--
1.7.2.3.313.gcd15
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [demo/patch 0/3] Re: [PATCH] Documentation: document the string-list macros.
2010-09-05 17:51 [PATCH] Documentation: document the string-list macros Thiago Farina
@ 2010-09-05 20:03 ` Jonathan Nieder
2010-09-05 20:04 ` [demo/PATCH 1/3] string-list: introduce string_list_init() Jonathan Nieder
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Jonathan Nieder @ 2010-09-05 20:03 UTC (permalink / raw)
To: Thiago Farina; +Cc: git
Thiago Farina wrote:
> --- a/Documentation/technical/api-string-list.txt
> +++ b/Documentation/technical/api-string-list.txt
> @@ -52,6 +52,18 @@ However, if you use the list to check if a certain string was added
> already, you should not do that (using unsorted_string_list_has_string()),
> because the complexity would be quadratic again (but with a worse factor).
>
> +Macros
> +------
> +
> +`STRING_LIST_INIT_NODUP`::
> +
> + Initialize the members and set the `strdup_strings` member to 0.
> +
> +`STRING_LIST_INIT_DUP`::
> +
> + Initialize the members and set the `strdup_strings` member to 1.
After reading that, one might be tempted to write
struct string_list x;
STRING_LIST_INIT_NODUP(x);
, no? In other words, I don't find the text very clear.
If you like working by example (like I do) then api-strbuf.txt might
give a good indication of how this sort of thing can be helpfully
documented.
Maybe something in this direction?
Patch #3 in particular is very rough and ought to be split up for
easier review. This is not meant for application, just to give an
idea.
Jonathan Nieder (3):
string-list: introduce string_list_init()
string-list: document ...
Make initialization of string_lists more consistent
Documentation/technical/api-string-list.txt | 18 +++++++++------
builtin/apply.c | 8 +++---
builtin/blame.c | 4 +-
builtin/clean.c | 2 +-
builtin/commit.c | 4 +-
builtin/fetch.c | 13 ++++-------
builtin/fmt-merge-msg.c | 13 ++++++-----
builtin/log.c | 9 ++-----
builtin/mailsplit.c | 1 +
builtin/notes.c | 4 +-
builtin/remote.c | 30 +++++++++++++-------------
builtin/shortlog.c | 25 ++++++++++++---------
diff-no-index.c | 1 +
mailmap.c | 17 +++++++++-----
mailmap.h | 2 +-
merge-recursive.c | 16 ++++++++------
notes.c | 4 +-
pretty.c | 5 ++-
reflog-walk.c | 1 +
resolve-undo.c | 8 +++---
revision.c | 7 ++++-
string-list.c | 28 +++++++++++++++++++++---
string-list.h | 4 +++
submodule.c | 4 +-
wt-status.c | 6 ++--
25 files changed, 137 insertions(+), 97 deletions(-)
--
1.7.2.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [demo/PATCH 1/3] string-list: introduce string_list_init()
2010-09-05 20:03 ` [demo/patch 0/3] " Jonathan Nieder
@ 2010-09-05 20:04 ` Jonathan Nieder
2010-09-05 20:06 ` [demo/PATCH 1/3] string-list: Document STRING_LIST_INIT_* and string_list_init() Jonathan Nieder
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Jonathan Nieder @ 2010-09-05 20:04 UTC (permalink / raw)
To: Thiago Farina; +Cc: git
Instead of asking callers to
memset(&list, 0, sizeof(list));
list.strdup_strings = strdup_strings;
we can take care of that ourselves, providing the flexibility
to change the details of string_list layout later if wanted.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
string-list.c | 7 +++++++
string-list.h | 1 +
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/string-list.c b/string-list.c
index 9b023a2..8e992a7 100644
--- a/string-list.c
+++ b/string-list.c
@@ -102,6 +102,13 @@ int for_each_string_list(struct string_list *list,
return ret;
}
+void string_list_init(struct string_list *list, int strdup_strings)
+{
+ list->items = NULL;
+ list->nr = list->alloc = 0;
+ list->strdup_strings = strdup_strings ? 1 : 0;
+}
+
void string_list_clear(struct string_list *list, int free_util)
{
if (list->items) {
diff --git a/string-list.h b/string-list.h
index 4946938..07e075c 100644
--- a/string-list.h
+++ b/string-list.h
@@ -15,6 +15,7 @@ struct string_list
#define STRING_LIST_INIT_NODUP { NULL, 0, 0, 0 }
#define STRING_LIST_INIT_DUP { NULL, 0, 0, 1 }
+void string_list_init(struct string_list *list, int strdup_strings);
void print_string_list(const struct string_list *p, const char *text);
void string_list_clear(struct string_list *list, int free_util);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [demo/PATCH 1/3] string-list: Document STRING_LIST_INIT_* and string_list_init()
2010-09-05 20:03 ` [demo/patch 0/3] " Jonathan Nieder
2010-09-05 20:04 ` [demo/PATCH 1/3] string-list: introduce string_list_init() Jonathan Nieder
@ 2010-09-05 20:06 ` Jonathan Nieder
2010-09-05 20:08 ` [demo/PATCH 3/3] Make initialization of string_lists more consistent Jonathan Nieder
2010-09-05 23:19 ` [demo/patch 0/3] Re: [PATCH] Documentation: document the string-list macros Thiago Farina
3 siblings, 0 replies; 6+ messages in thread
From: Jonathan Nieder @ 2010-09-05 20:06 UTC (permalink / raw)
To: Thiago Farina; +Cc: git
Clarify the modern ways to initialize a string_list. Text roughly
based on the analogous passage from api-strbuf.txt.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/technical/api-string-list.txt | 18 +++++++++++-------
1 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt
index 3f575bd..0f0e579 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -9,12 +9,17 @@ because it is not specific to paths.
The caller:
-. Allocates and clears a `struct string_list` variable.
+. Allocates a `struct string_list` variable
-. Initializes the members. You might want to set the flag `strdup_strings`
- if the strings should be strdup()ed. For example, this is necessary
- when you add something like git_path("..."), since that function returns
- a static buffer that will change with the next call to git_path().
+. Initializes the members. A string_list has to be initialized by
+ `string_list_init()` or by `= STRING_LIST_INIT_DUP` or
+ `= STRING_LIST_INIT_NODUP` before it can be used.
++
+Strings in lists initialized with the _DUP variant will be
+automatically strdup()ed on insertion and free()ed on removal.
+For example, this is necessary when you add something like
+git_path("..."), since that function returns a static buffer
+that will change with the next call to git_path().
+
If you need something advanced, you can manually malloc() the `items`
member (you need this if you add things later) and you should set the
@@ -34,10 +39,9 @@ member (you need this if you add things later) and you should set the
Example:
----
-struct string_list list;
+struct string_list list STRING_LIST_INIT_NODUP;
int i;
-memset(&list, 0, sizeof(struct string_list));
string_list_append(&list, "foo");
string_list_append(&list, "bar");
for (i = 0; i < list.nr; i++)
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [demo/PATCH 3/3] Make initialization of string_lists more consistent
2010-09-05 20:03 ` [demo/patch 0/3] " Jonathan Nieder
2010-09-05 20:04 ` [demo/PATCH 1/3] string-list: introduce string_list_init() Jonathan Nieder
2010-09-05 20:06 ` [demo/PATCH 1/3] string-list: Document STRING_LIST_INIT_* and string_list_init() Jonathan Nieder
@ 2010-09-05 20:08 ` Jonathan Nieder
2010-09-05 23:19 ` [demo/patch 0/3] Re: [PATCH] Documentation: document the string-list macros Thiago Farina
3 siblings, 0 replies; 6+ messages in thread
From: Jonathan Nieder @ 2010-09-05 20:08 UTC (permalink / raw)
To: Thiago Farina; +Cc: git
The strdup_strings member of a string_list should be constant
from when it is initialized until the string_list_clear() call,
or there can be memory leaks and double-free()ing. Clarify
some calling conventions to ensure this.
Actually it might be even better to have a completely distinct
string_list_dup type, so the compiler could catch that kind of
error, but this patch doesn't do that.
Possible portability hazard: this casts function pointers in
weird ways.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
but not intended for application yet
---
builtin/apply.c | 8 ++++----
builtin/blame.c | 4 ++--
builtin/clean.c | 2 +-
builtin/commit.c | 4 ++--
builtin/fetch.c | 13 +++++--------
builtin/fmt-merge-msg.c | 13 +++++++------
builtin/log.c | 9 +++------
builtin/mailsplit.c | 1 +
builtin/notes.c | 4 ++--
builtin/remote.c | 30 +++++++++++++++---------------
builtin/shortlog.c | 25 ++++++++++++++-----------
diff-no-index.c | 1 +
mailmap.c | 17 +++++++++++------
mailmap.h | 2 +-
merge-recursive.c | 16 +++++++++-------
notes.c | 4 ++--
pretty.c | 5 +++--
reflog-walk.c | 1 +
resolve-undo.c | 8 ++++----
revision.c | 7 +++++--
string-list.c | 21 +++++++++++++++++----
string-list.h | 3 +++
submodule.c | 4 ++--
wt-status.c | 6 +++---
24 files changed, 118 insertions(+), 90 deletions(-)
diff --git a/builtin/apply.c b/builtin/apply.c
index 23c18c5..e9f16ce 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -223,7 +223,7 @@ struct image {
* the case where more than one patches touch the same file.
*/
-static struct string_list fn_table;
+static struct string_list fn_table = STRING_LIST_INIT_NODUP;
static uint32_t hash_line(const char *cp, size_t len)
{
@@ -3560,7 +3560,7 @@ static int write_out_results(struct patch *list, int skipped_patch)
static struct lock_file lock_file;
-static struct string_list limit_by_name;
+static struct string_list limit_by_name = STRING_LIST_INIT_NODUP;
static int has_include;
static void add_name_limit(const char *name, int exclude)
{
@@ -3635,8 +3635,8 @@ static int apply_patch(int fd, const char *filename, int options)
struct patch *list = NULL, **listp = &list;
int skipped_patch = 0;
- /* FIXME - memory leak when using multiple patch files as inputs */
- memset(&fn_table, 0, sizeof(struct string_list));
+ string_list_clear(&fn_table, 0);
+ string_list_init(&fn_table, 0);
patch_input_file = filename;
read_patch_file(&buf, fd);
offset = 0;
diff --git a/builtin/blame.c b/builtin/blame.c
index 1015354..bc89a48 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -45,7 +45,7 @@ static int xdl_opts;
static enum date_mode blame_date_mode = DATE_ISO8601;
static size_t blame_date_width;
-static struct string_list mailmap;
+static struct string_list mailmap = STRING_LIST_INIT_DUP;
#ifndef DEBUG
#define DEBUG 0
@@ -2498,7 +2498,7 @@ parse_done:
sb.ent = ent;
sb.path = path;
- read_mailmap(&mailmap, NULL);
+ mailmap_read(&mailmap, NULL);
if (!incremental)
setup_pager();
diff --git a/builtin/clean.c b/builtin/clean.c
index b508d2c..c8798f5 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -44,7 +44,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
struct dir_struct dir;
static const char **pathspec;
struct strbuf buf = STRBUF_INIT;
- struct string_list exclude_list = { NULL, 0, 0, 0 };
+ struct string_list exclude_list = STRING_LIST_INIT_NODUP;
const char *qname;
char *seen = NULL;
struct option options[] = {
diff --git a/builtin/commit.c b/builtin/commit.c
index 66fdd22..ab9d974 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -205,6 +205,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
int i;
char *m;
+ assert(list->strdup_strings);
for (i = 0; pattern[i]; i++)
;
m = xcalloc(1, i);
@@ -379,8 +380,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
if (in_merge)
die("cannot do a partial commit during a merge.");
- memset(&partial, 0, sizeof(partial));
- partial.strdup_strings = 1;
+ string_list_init(&partial, 1);
if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
exit(1);
diff --git a/builtin/fetch.c b/builtin/fetch.c
index fab3fce..9a1c46c 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -732,7 +732,7 @@ static int get_one_remote_for_fetch(struct remote *remote, void *priv)
{
struct string_list *list = priv;
if (!remote->skip_default_update)
- string_list_append(list, remote->name);
+ string_list_append_take_ownership(list, (char *) remote->name);
return 0;
}
@@ -751,8 +751,8 @@ static int get_remote_group(const char *key, const char *value, void *priv)
int space = strcspn(value, " \t\n");
while (*value) {
if (space > 1) {
- string_list_append(g->list,
- xstrndup(value, space));
+ string_list_append_take_ownership(
+ g->list, xstrndup(value, space));
}
value += space + (value[space] != '\0');
space = strcspn(value, " \t\n");
@@ -774,7 +774,7 @@ static int add_remote_or_group(const char *name, struct string_list *list)
if (!remote_is_configured(name))
return 0;
remote = remote_get(name);
- string_list_append(list, remote->name);
+ string_list_append_take_ownership(list, (char *) remote->name);
}
return 1;
}
@@ -877,7 +877,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
int cmd_fetch(int argc, const char **argv, const char *prefix)
{
int i;
- struct string_list list = STRING_LIST_INIT_NODUP;
+ struct string_list list = STRING_LIST_INIT_DUP;
struct remote *remote;
int result = 0;
@@ -921,9 +921,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
}
}
- /* All names were strdup()ed or strndup()ed */
- list.strdup_strings = 1;
string_list_clear(&list, 0);
-
return result;
}
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index e7e12ee..621c074 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -30,12 +30,13 @@ struct src_data {
int head_status;
};
-void init_src_data(struct src_data *data)
+static void init_src_data(struct src_data *data)
{
- data->branch.strdup_strings = 1;
- data->tag.strdup_strings = 1;
- data->r_branch.strdup_strings = 1;
- data->generic.strdup_strings = 1;
+ string_list_init(&data->branch, 1);
+ string_list_init(&data->tag, 1);
+ string_list_init(&data->r_branch, 1);
+ string_list_init(&data->generic, 1);
+ data->head_status = 0;
}
static struct string_list srcs = STRING_LIST_INIT_DUP;
@@ -83,7 +84,7 @@ static int handle_line(char *line)
item = unsorted_string_list_lookup(&srcs, src);
if (!item) {
item = string_list_append(&srcs, src);
- item->util = xcalloc(1, sizeof(struct src_data));
+ item->util = xmalloc(sizeof(struct src_data));
init_src_data(item->util);
}
src_data = item->util;
diff --git a/builtin/log.c b/builtin/log.c
index eaa1ee0..7e8f0e2 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -521,9 +521,9 @@ static int auto_number = 1;
static char *default_attach = NULL;
-static struct string_list extra_hdr;
-static struct string_list extra_to;
-static struct string_list extra_cc;
+static struct string_list extra_hdr = STRING_LIST_INIT_DUP;
+static struct string_list extra_to = STRING_LIST_INIT_DUP;
+static struct string_list extra_cc = STRING_LIST_INIT_DUP;
static void add_header(const char *value)
{
@@ -1048,9 +1048,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
OPT_END()
};
- extra_hdr.strdup_strings = 1;
- extra_to.strdup_strings = 1;
- extra_cc.strdup_strings = 1;
git_config(git_format_config, NULL);
init_revisions(&rev, prefix);
rev.commit_format = CMIT_FMT_EMAIL;
diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c
index 99654d0..17f247b 100644
--- a/builtin/mailsplit.c
+++ b/builtin/mailsplit.c
@@ -108,6 +108,7 @@ static int populate_maildir_list(struct string_list *list, const char *path)
char *subs[] = { "cur", "new", NULL };
char **sub;
+ assert(list->strdup_strings);
for (sub = subs; *sub; ++sub) {
snprintf(name, sizeof(name), "%s/%s", path, *sub);
if ((dir = opendir(name)) == NULL) {
diff --git a/builtin/notes.c b/builtin/notes.c
index fbc347c..35e139f 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -363,8 +363,8 @@ struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd)
c->cmd = cmd;
c->enabled = 1;
c->combine = combine_notes_concatenate;
- c->refs = xcalloc(1, sizeof(struct string_list));
- c->refs->strdup_strings = 1;
+ c->refs = xmalloc(sizeof(struct string_list));
+ string_list_init(c->refs, 1);
c->refs_from_env = 0;
c->mode_from_env = 0;
if (rewrite_mode_env) {
diff --git a/builtin/remote.c b/builtin/remote.c
index 48e0a6b..9ab36ed 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -230,7 +230,7 @@ struct branch_info {
int rebase;
};
-static struct string_list branch_list;
+static struct string_list branch_list = STRING_LIST_INIT_NODUP;
static const char *abbrev_ref(const char *name, const char *prefix)
{
@@ -302,6 +302,10 @@ struct ref_states {
int queried;
};
+#define REF_STATES_INIT { NULL, \
+ STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, \
+ STRING_LIST_INIT_DUP, 0 }
+
static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)
{
struct ref *fetch_map = NULL, **tail = &fetch_map;
@@ -313,9 +317,9 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
die("Could not get fetch map for refspec %s",
states->remote->fetch_refspec[i]);
- states->new.strdup_strings = 1;
- states->tracked.strdup_strings = 1;
- states->stale.strdup_strings = 1;
+ assert(states->new.strdup_strings);
+ assert(states->tracked.strdup_strings);
+ assert(states->stale.strdup_strings);
for (ref = fetch_map; ref; ref = ref->next) {
unsigned char sha1[20];
if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
@@ -366,7 +370,7 @@ static int get_push_ref_states(const struct ref *remote_refs,
match_refs(local_refs, &push_map, remote->push_refspec_nr,
remote->push_refspec, MATCH_REFS_NONE);
- states->push.strdup_strings = 1;
+ assert(states->push.strdup_strings);
for (ref = push_map; ref; ref = ref->next) {
struct string_list_item *item;
struct push_info *info;
@@ -409,7 +413,7 @@ static int get_push_ref_states_noquery(struct ref_states *states)
if (remote->mirror)
return 0;
- states->push.strdup_strings = 1;
+ assert(states->push.strdup_strings);
if (!remote->push_refspec_nr) {
item = string_list_append(&states->push, "(matching)");
info = item->util = xcalloc(sizeof(struct push_info), 1);
@@ -442,7 +446,7 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat
refspec.force = 0;
refspec.pattern = 1;
refspec.src = refspec.dst = "refs/heads/*";
- states->heads.strdup_strings = 1;
+ assert(states->heads.strdup_strings);
get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
fetch_map, 1);
@@ -1043,7 +1047,7 @@ static int show(int argc, const char **argv)
OPT_BOOLEAN('n', NULL, &no_query, "do not query remotes"),
OPT_END()
};
- struct ref_states states;
+ struct ref_states states = REF_STATES_INIT;
struct string_list info_list = STRING_LIST_INIT_NODUP;
struct show_info info;
@@ -1056,7 +1060,6 @@ static int show(int argc, const char **argv)
if (!no_query)
query_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);
- memset(&states, 0, sizeof(states));
memset(&info, 0, sizeof(info));
info.states = &states;
info.list = &info_list;
@@ -1158,8 +1161,7 @@ static int set_head(int argc, const char **argv)
if (!opt_a && !opt_d && argc == 2) {
head_name = xstrdup(argv[1]);
} else if (opt_a && !opt_d && argc == 1) {
- struct ref_states states;
- memset(&states, 0, sizeof(states));
+ struct ref_states states = REF_STATES_INIT;
get_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);
if (!states.heads.nr)
result |= error("Cannot determine remote HEAD");
@@ -1219,12 +1221,11 @@ static int prune(int argc, const char **argv)
static int prune_remote(const char *remote, int dry_run)
{
int result = 0, i;
- struct ref_states states;
+ struct ref_states states = REF_STATES_INIT;
const char *dangling_msg = dry_run
? " %s will become dangling!\n"
: " %s has become dangling!\n";
- memset(&states, 0, sizeof(states));
get_remote_ref_states(remote, &states, GET_REF_STATES);
if (states.stale.nr) {
@@ -1483,10 +1484,9 @@ static int get_one_entry(struct remote *remote, void *priv)
static int show_all(void)
{
- struct string_list list = STRING_LIST_INIT_NODUP;
+ struct string_list list = STRING_LIST_INIT_DUP;
int result;
- list.strdup_strings = 1;
result = for_each_remote(get_one_entry, &list);
if (!result) {
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 2135b0d..5843c0a 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -16,9 +16,9 @@ static char const * const shortlog_usage[] = {
NULL
};
-static int compare_by_number(const void *a1, const void *a2)
+static int compare_by_number(const struct string_list_item *i1,
+ const struct string_list_item *i2)
{
- const struct string_list_item *i1 = a1, *i2 = a2;
const struct string_list *l1 = i1->util, *l2 = i2->util;
if (l1->nr < l2->nr)
@@ -84,9 +84,12 @@ static void insert_one_record(struct shortlog *log,
snprintf(namebuf + len, room, " <%.*s>", maillen, emailbuf);
}
+ assert(log->list.strdup_strings);
item = string_list_insert(&log->list, namebuf);
- if (item->util == NULL)
- item->util = xcalloc(1, sizeof(struct string_list));
+ if (!item->util) {
+ item->util = xmalloc(sizeof(struct string_list));
+ string_list_init(item->util, 1);
+ }
/* Skip any leading whitespace, including any blank lines. */
while (*oneline && isspace(*oneline))
@@ -115,7 +118,7 @@ static void insert_one_record(struct shortlog *log,
}
}
- string_list_append(item->util, buffer);
+ string_list_append_take_ownership(item->util, buffer);
}
static void read_from_stdin(struct shortlog *log)
@@ -236,10 +239,11 @@ static int parse_wrap_args(const struct option *opt, const char *arg, int unset)
void shortlog_init(struct shortlog *log)
{
memset(log, 0, sizeof(*log));
+ string_list_init(&log->list, 1);
+ string_list_init(&log->mailmap, 1);
- read_mailmap(&log->mailmap, &log->common_repo_prefix);
+ mailmap_read(&log->mailmap, &log->common_repo_prefix);
- log->list.strdup_strings = 1;
log->wrap = DEFAULT_WRAPLEN;
log->in1 = DEFAULT_INDENT1;
log->in2 = DEFAULT_INDENT2;
@@ -320,8 +324,7 @@ void shortlog_output(struct shortlog *log)
struct strbuf sb = STRBUF_INIT;
if (log->sort_by_number)
- qsort(log->list.items, log->list.nr, sizeof(struct string_list_item),
- compare_by_number);
+ sort_string_list_by(&log->list, compare_by_number);
for (i = 0; i < log->list.nr; i++) {
struct string_list *onelines = log->list.items[i].util;
@@ -343,14 +346,14 @@ void shortlog_output(struct shortlog *log)
putchar('\n');
}
- onelines->strdup_strings = 1;
+ assert(onelines->strdup_strings);
string_list_clear(onelines, 0);
free(onelines);
log->list.items[i].util = NULL;
}
strbuf_release(&sb);
- log->list.strdup_strings = 1;
+ assert(log->list.strdup_strings);
string_list_clear(&log->list, 1);
clear_mailmap(&log->mailmap);
}
diff --git a/diff-no-index.c b/diff-no-index.c
index ce9e783..68da01a 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -24,6 +24,7 @@ static int read_directory(const char *path, struct string_list *list)
if (!(dir = opendir(path)))
return error("Could not open directory %s", path);
+ assert(list->strdup_strings);
while ((e = readdir(dir)))
if (strcmp(".", e->d_name) && strcmp("..", e->d_name))
string_list_insert(list, e->d_name);
diff --git a/mailmap.c b/mailmap.c
index f80b701..b7f2796 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -33,6 +33,12 @@ static void free_mailmap_info(void *p, const char *s)
free(mi->email);
}
+static void init_mailmap_entry(struct mailmap_entry *p)
+{
+ p->name = p->email = NULL;
+ string_list_init(&p->namemap, 1);
+}
+
static void free_mailmap_entry(void *p, const char *s)
{
struct mailmap_entry *me = (struct mailmap_entry *)p;
@@ -41,7 +47,7 @@ static void free_mailmap_entry(void *p, const char *s)
free(me->name);
free(me->email);
- me->namemap.strdup_strings = 1;
+ assert(me->namemap.strdup_strings);
string_list_clear_func(&me->namemap, free_mailmap_info);
}
@@ -71,8 +77,7 @@ static void add_mapping(struct string_list *map,
/* create mailmap entry */
struct string_list_item *item = string_list_insert_at_index(map, index, old_email);
item->util = xmalloc(sizeof(struct mailmap_entry));
- memset(item->util, 0, sizeof(struct mailmap_entry));
- ((struct mailmap_entry *)item->util)->namemap.strdup_strings = 1;
+ init_mailmap_entry((struct mailmap_entry *)item->util);
}
me = (struct mailmap_entry *)map->items[index].util;
@@ -170,9 +175,9 @@ static int read_single_mailmap(struct string_list *map, const char *filename, ch
return 0;
}
-int read_mailmap(struct string_list *map, char **repo_abbrev)
+int mailmap_read(struct string_list *map, char **repo_abbrev)
{
- map->strdup_strings = 1;
+ assert(map->strdup_strings);
/* each failure returns 1, so >1 means both calls failed */
return read_single_mailmap(map, ".mailmap", repo_abbrev) +
read_single_mailmap(map, git_mailmap_file, repo_abbrev) > 1;
@@ -181,7 +186,7 @@ int read_mailmap(struct string_list *map, char **repo_abbrev)
void clear_mailmap(struct string_list *map)
{
debug_mm("mailmap: clearing %d entries...\n", map->nr);
- map->strdup_strings = 1;
+ assert(map->strdup_strings);
string_list_clear_func(map, free_mailmap_entry);
debug_mm("mailmap: cleared\n");
}
diff --git a/mailmap.h b/mailmap.h
index d5c3664..f0b3861 100644
--- a/mailmap.h
+++ b/mailmap.h
@@ -1,7 +1,7 @@
#ifndef MAILMAP_H
#define MAILMAP_H
-int read_mailmap(struct string_list *map, char **repo_abbrev);
+int mailmap_read(struct string_list *map, char **repo_abbrev);
void clear_mailmap(struct string_list *map);
int map_user(struct string_list *mailmap,
diff --git a/merge-recursive.c b/merge-recursive.c
index 20e1779..7a44e25 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -232,6 +232,9 @@ static int save_files_dirs(const unsigned char *sha1,
memcpy(newpath + baselen, path, len);
newpath[baselen + len] = '\0';
+ assert(o->current_directory_set.strdup_strings);
+ assert(o->current_file_set.strdup_strings);
+
if (S_ISDIR(mode))
string_list_insert(&o->current_directory_set, newpath);
else
@@ -277,10 +280,10 @@ static struct stage_data *insert_stage_data(const char *path,
*/
static struct string_list *get_unmerged(void)
{
- struct string_list *unmerged = xcalloc(1, sizeof(struct string_list));
+ struct string_list *unmerged = xmalloc(sizeof(struct string_list));
int i;
- unmerged->strdup_strings = 1;
+ string_list_init(unmerged, 1);
for (i = 0; i < active_nr; i++) {
struct string_list_item *item;
@@ -327,7 +330,8 @@ static struct string_list *get_renames(struct merge_options *o,
struct string_list *renames;
struct diff_options opts;
- renames = xcalloc(1, sizeof(struct string_list));
+ renames = xmalloc(sizeof(struct string_list));
+ string_list_init(renames, 0);
diff_setup(&opts);
DIFF_OPT_SET(&opts, RECURSIVE);
opts.detect_rename = DIFF_DETECT_RENAME;
@@ -1539,8 +1543,6 @@ void init_merge_options(struct merge_options *o)
if (o->verbosity >= 5)
o->buffer_output = 0;
strbuf_init(&o->obuf, 0);
- memset(&o->current_file_set, 0, sizeof(struct string_list));
- o->current_file_set.strdup_strings = 1;
- memset(&o->current_directory_set, 0, sizeof(struct string_list));
- o->current_directory_set.strdup_strings = 1;
+ string_list_init(&o->current_file_set, 1);
+ string_list_init(&o->current_directory_set, 1);
}
diff --git a/notes.c b/notes.c
index 7fd2035..2ab0bb1 100644
--- a/notes.c
+++ b/notes.c
@@ -70,7 +70,7 @@ struct non_note {
struct notes_tree default_notes_tree;
-static struct string_list display_notes_refs;
+static struct string_list display_notes_refs = STRING_LIST_INIT_DUP;
static struct notes_tree **display_notes_trees;
static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
@@ -958,8 +958,8 @@ void init_display_notes(struct display_notes_opt *opt)
{
char *display_ref_env;
int load_config_refs = 0;
- display_notes_refs.strdup_strings = 1;
+ assert(display_notes_refs.strdup_strings);
assert(!display_notes_trees);
if (!opt || !opt->suppress_default_notes) {
diff --git a/pretty.c b/pretty.c
index f85444b..89b37eb 100644
--- a/pretty.c
+++ b/pretty.c
@@ -434,8 +434,9 @@ static int mailmap_name(char *email, int email_len, char *name, int name_len)
{
static struct string_list *mail_map;
if (!mail_map) {
- mail_map = xcalloc(1, sizeof(*mail_map));
- read_mailmap(mail_map, NULL);
+ mail_map = xmalloc(sizeof(*mail_map));
+ string_list_init(mail_map, 1);
+ mailmap_read(mail_map, NULL);
}
return mail_map->nr && map_user(mail_map, email, email_len, name, name_len);
}
diff --git a/reflog-walk.c b/reflog-walk.c
index 4879615..a2ccdea 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -135,6 +135,7 @@ struct reflog_walk_info {
void init_reflog_walk(struct reflog_walk_info** info)
{
*info = xcalloc(sizeof(struct reflog_walk_info), 1);
+ string_list_init(&(*info)->complete_reflogs, 0);
}
int add_reflog_for_walk(struct reflog_walk_info *info,
diff --git a/resolve-undo.c b/resolve-undo.c
index 72b4612..6ba8538 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -15,8 +15,8 @@ void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
return;
if (!istate->resolve_undo) {
- resolve_undo = xcalloc(1, sizeof(*resolve_undo));
- resolve_undo->strdup_strings = 1;
+ resolve_undo = xmalloc(sizeof(*resolve_undo));
+ string_list_init(resolve_undo, 1);
istate->resolve_undo = resolve_undo;
}
resolve_undo = istate->resolve_undo;
@@ -56,8 +56,8 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)
char *endptr;
int i;
- resolve_undo = xcalloc(1, sizeof(*resolve_undo));
- resolve_undo->strdup_strings = 1;
+ resolve_undo = xmalloc(sizeof(*resolve_undo));
+ string_list_init(resolve_undo, 1);
while (size) {
struct string_list_item *lost;
diff --git a/revision.c b/revision.c
index b1c1890..e18522c 100644
--- a/revision.c
+++ b/revision.c
@@ -1319,8 +1319,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
struct strbuf buf = STRBUF_INIT;
revs->show_notes = 1;
revs->show_notes_given = 1;
- if (!revs->notes_opt.extra_notes_refs)
- revs->notes_opt.extra_notes_refs = xcalloc(1, sizeof(struct string_list));
+ if (!revs->notes_opt.extra_notes_refs) {
+ revs->notes_opt.extra_notes_refs = xmalloc(sizeof(struct string_list));
+ string_list_init(revs->notes_opt.extra_notes_refs, 0);
+ }
if (!prefixcmp(arg+13, "refs/"))
/* happy */;
else if (!prefixcmp(arg+13, "notes/"))
@@ -1328,6 +1330,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
else
strbuf_addstr(&buf, "refs/notes/");
strbuf_addstr(&buf, arg+13);
+ /* NEEDSWORK: leak. */
string_list_append(revs->notes_opt.extra_notes_refs,
strbuf_detach(&buf, NULL));
} else if (!strcmp(arg, "--no-notes")) {
diff --git a/string-list.c b/string-list.c
index 8e992a7..9684819 100644
--- a/string-list.c
+++ b/string-list.c
@@ -163,16 +163,29 @@ struct string_list_item *string_list_append(struct string_list *list, const char
return list->items + list->nr++;
}
-static int cmp_items(const void *a, const void *b)
+struct string_list_item *string_list_append_take_ownership(struct string_list *list, char *string)
+{
+ assert(list->strdup_strings);
+ ALLOC_GROW(list->items, list->nr + 1, list->alloc);
+ list->items[list->nr].string = string;
+ return list->items + list->nr++;
+}
+
+
+static int cmp_items(const struct string_list_item *one, const struct string_list_item *two)
{
- const struct string_list_item *one = a;
- const struct string_list_item *two = b;
return strcmp(one->string, two->string);
}
void sort_string_list(struct string_list *list)
{
- qsort(list->items, list->nr, sizeof(*list->items), cmp_items);
+ sort_string_list_by(list, cmp_items);
+}
+
+void sort_string_list_by(struct string_list *list, string_list_compare_func compare)
+{
+ qsort(list->items, list->nr, sizeof(*list->items),
+ (int(*)(const void *, const void *)) compare);
}
struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
diff --git a/string-list.h b/string-list.h
index 07e075c..d14f3e0 100644
--- a/string-list.h
+++ b/string-list.h
@@ -42,7 +42,10 @@ struct string_list_item *string_list_lookup(struct string_list *list, const char
/* Use these functions only on unsorted lists: */
struct string_list_item *string_list_append(struct string_list *list, const char *string);
+struct string_list_item *string_list_append_take_ownership(struct string_list *list, char *string);
void sort_string_list(struct string_list *list);
+typedef int (*string_list_compare_func)(const struct string_list_item *a, const struct string_list_item *b);
+void sort_string_list_by(struct string_list *list, string_list_compare_func compare);
int unsorted_string_list_has_string(struct string_list *list, const char *string);
struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
const char *string);
diff --git a/submodule.c b/submodule.c
index 91a4758..1c7ab8c 100644
--- a/submodule.c
+++ b/submodule.c
@@ -9,8 +9,8 @@
#include "refs.h"
#include "string-list.h"
-struct string_list config_name_for_path;
-struct string_list config_ignore_for_name;
+struct string_list config_name_for_path = STRING_LIST_INIT_NODUP;
+struct string_list config_ignore_for_name = STRING_LIST_INIT_NODUP;
static int add_submodule_odb(const char *path)
{
diff --git a/wt-status.c b/wt-status.c
index 54b6b03..0e137b8 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -44,9 +44,9 @@ void wt_status_prepare(struct wt_status *s)
s->reference = "HEAD";
s->fp = stdout;
s->index_file = get_index_file();
- s->change.strdup_strings = 1;
- s->untracked.strdup_strings = 1;
- s->ignored.strdup_strings = 1;
+ string_list_init(&s->change, 1);
+ string_list_init(&s->untracked, 1);
+ string_list_init(&s->ignored, 1);
}
static void wt_status_print_unmerged_header(struct wt_status *s)
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [demo/patch 0/3] Re: [PATCH] Documentation: document the string-list macros.
2010-09-05 20:03 ` [demo/patch 0/3] " Jonathan Nieder
` (2 preceding siblings ...)
2010-09-05 20:08 ` [demo/PATCH 3/3] Make initialization of string_lists more consistent Jonathan Nieder
@ 2010-09-05 23:19 ` Thiago Farina
3 siblings, 0 replies; 6+ messages in thread
From: Thiago Farina @ 2010-09-05 23:19 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git
On Sun, Sep 5, 2010 at 5:03 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Thiago Farina wrote:
>
>> --- a/Documentation/technical/api-string-list.txt
>> +++ b/Documentation/technical/api-string-list.txt
>> @@ -52,6 +52,18 @@ However, if you use the list to check if a certain string was added
>> already, you should not do that (using unsorted_string_list_has_string()),
>> because the complexity would be quadratic again (but with a worse factor).
>>
>> +Macros
>> +------
>> +
>> +`STRING_LIST_INIT_NODUP`::
>> +
>> + Initialize the members and set the `strdup_strings` member to 0.
>> +
>> +`STRING_LIST_INIT_DUP`::
>> +
>> + Initialize the members and set the `strdup_strings` member to 1.
>
> After reading that, one might be tempted to write
>
> struct string_list x;
> STRING_LIST_INIT_NODUP(x);
>
> , no? In other words, I don't find the text very clear.
>
Yeah, you are right.
> If you like working by example (like I do) then api-strbuf.txt might
> give a good indication of how this sort of thing can be helpfully
> documented.
>
I have looked into it :-)
> Maybe something in this direction?
>
> Patch #3 in particular is very rough
Oh yeah :)
> This is not meant for application, just to give an
> idea.
>
I like the idea. I will improve the Documentation based on or version.
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-09-05 23:19 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-05 17:51 [PATCH] Documentation: document the string-list macros Thiago Farina
2010-09-05 20:03 ` [demo/patch 0/3] " Jonathan Nieder
2010-09-05 20:04 ` [demo/PATCH 1/3] string-list: introduce string_list_init() Jonathan Nieder
2010-09-05 20:06 ` [demo/PATCH 1/3] string-list: Document STRING_LIST_INIT_* and string_list_init() Jonathan Nieder
2010-09-05 20:08 ` [demo/PATCH 3/3] Make initialization of string_lists more consistent Jonathan Nieder
2010-09-05 23:19 ` [demo/patch 0/3] Re: [PATCH] Documentation: document the string-list macros Thiago Farina
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).