Skip to content

Commit

Permalink
Merge branch 'ph/strbuf' into kh/commit
Browse files Browse the repository at this point in the history
* ph/strbuf:
  Clean up stripspace a bit, use strbuf even more.
  Add strbuf_read_file().
  rerere: Fix use of an empty strbuf.buf
  Small cache_tree_write refactor.
  Make builtin-rerere use of strbuf nicer and more efficient.
  Add strbuf_cmp.
  strbuf_setlen(): do not barf on setting length of an empty buffer to 0
  sq_quote_argv and add_to_string rework with strbuf's.
  Full rework of quote_c_style and write_name_quoted.
  Rework unquote_c_style to work on a strbuf.
  strbuf API additions and enhancements.
  nfv?asprintf are broken without va_copy, workaround them.
  Fix the expansion pattern of the pseudo-static path buffer.
  • Loading branch information
Junio C Hamano committed Sep 27, 2007
2 parents 0f729f2 + 6d69b6f commit a17ba31
Show file tree
Hide file tree
Showing 31 changed files with 731 additions and 898 deletions.
5 changes: 2 additions & 3 deletions archive-tar.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,15 +238,14 @@ static int write_tar_entry(const unsigned char *sha1,
const char *filename, unsigned mode, int stage)
{
static struct strbuf path = STRBUF_INIT;
int filenamelen = strlen(filename);
void *buffer;
enum object_type type;
unsigned long size;

strbuf_grow(&path, MAX(PATH_MAX, baselen + filenamelen + 1));
strbuf_reset(&path);
strbuf_grow(&path, PATH_MAX);
strbuf_add(&path, base, baselen);
strbuf_add(&path, filename, filenamelen);
strbuf_addstr(&path, filename);
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
strbuf_addch(&path, '/');
buffer = NULL;
Expand Down
200 changes: 92 additions & 108 deletions builtin-apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,14 @@ static void say_patch_name(FILE *output, const char *pre, struct patch *patch, c
fputs(pre, output);
if (patch->old_name && patch->new_name &&
strcmp(patch->old_name, patch->new_name)) {
write_name_quoted(NULL, 0, patch->old_name, 1, output);
quote_c_style(patch->old_name, NULL, output, 0);
fputs(" => ", output);
write_name_quoted(NULL, 0, patch->new_name, 1, output);
}
else {
quote_c_style(patch->new_name, NULL, output, 0);
} else {
const char *n = patch->new_name;
if (!n)
n = patch->old_name;
write_name_quoted(NULL, 0, n, 1, output);
quote_c_style(n, NULL, output, 0);
}
fputs(post, output);
}
Expand Down Expand Up @@ -231,35 +230,33 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
{
int len;
const char *start = line;
char *name;

if (*line == '"') {
struct strbuf name;

/* Proposed "new-style" GNU patch/diff format; see
* http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
*/
name = unquote_c_style(line, NULL);
if (name) {
char *cp = name;
while (p_value) {
strbuf_init(&name, 0);
if (!unquote_c_style(&name, line, NULL)) {
char *cp;

for (cp = name.buf; p_value; p_value--) {
cp = strchr(cp, '/');
if (!cp)
break;
cp++;
p_value--;
}
if (cp) {
/* name can later be freed, so we need
* to memmove, not just return cp
*/
memmove(name, cp, strlen(cp) + 1);
strbuf_remove(&name, 0, cp - name.buf);
free(def);
return name;
}
else {
free(name);
name = NULL;
return name.buf;
}
}
strbuf_release(&name);
}

for (;;) {
Expand Down Expand Up @@ -567,29 +564,30 @@ static const char *stop_at_slash(const char *line, int llen)
*/
static char *git_header_name(char *line, int llen)
{
int len;
const char *name;
const char *second = NULL;
size_t len;

line += strlen("diff --git ");
llen -= strlen("diff --git ");

if (*line == '"') {
const char *cp;
char *first = unquote_c_style(line, &second);
if (!first)
return NULL;
struct strbuf first;
struct strbuf sp;

strbuf_init(&first, 0);
strbuf_init(&sp, 0);

if (unquote_c_style(&first, line, &second))
goto free_and_fail1;

/* advance to the first slash */
cp = stop_at_slash(first, strlen(first));
if (!cp || cp == first) {
/* we do not accept absolute paths */
free_first_and_fail:
free(first);
return NULL;
}
len = strlen(cp+1);
memmove(first, cp+1, len+1); /* including NUL */
cp = stop_at_slash(first.buf, first.len);
/* we do not accept absolute paths */
if (!cp || cp == first.buf)
goto free_and_fail1;
strbuf_remove(&first, 0, cp + 1 - first.buf);

/* second points at one past closing dq of name.
* find the second name.
Expand All @@ -598,69 +596,71 @@ static char *git_header_name(char *line, int llen)
second++;

if (line + llen <= second)
goto free_first_and_fail;
goto free_and_fail1;
if (*second == '"') {
char *sp = unquote_c_style(second, NULL);
if (!sp)
goto free_first_and_fail;
cp = stop_at_slash(sp, strlen(sp));
if (!cp || cp == sp) {
free_both_and_fail:
free(sp);
goto free_first_and_fail;
}
if (unquote_c_style(&sp, second, NULL))
goto free_and_fail1;
cp = stop_at_slash(sp.buf, sp.len);
if (!cp || cp == sp.buf)
goto free_and_fail1;
/* They must match, otherwise ignore */
if (strcmp(cp+1, first))
goto free_both_and_fail;
free(sp);
return first;
if (strcmp(cp + 1, first.buf))
goto free_and_fail1;
strbuf_release(&sp);
return first.buf;
}

/* unquoted second */
cp = stop_at_slash(second, line + llen - second);
if (!cp || cp == second)
goto free_first_and_fail;
goto free_and_fail1;
cp++;
if (line + llen - cp != len + 1 ||
memcmp(first, cp, len))
goto free_first_and_fail;
return first;
if (line + llen - cp != first.len + 1 ||
memcmp(first.buf, cp, first.len))
goto free_and_fail1;
return first.buf;

free_and_fail1:
strbuf_release(&first);
strbuf_release(&sp);
return NULL;
}

/* unquoted first name */
name = stop_at_slash(line, llen);
if (!name || name == line)
return NULL;

name++;

/* since the first name is unquoted, a dq if exists must be
* the beginning of the second name.
*/
for (second = name; second < line + llen; second++) {
if (*second == '"') {
const char *cp = second;
struct strbuf sp;
const char *np;
char *sp = unquote_c_style(second, NULL);

if (!sp)
return NULL;
np = stop_at_slash(sp, strlen(sp));
if (!np || np == sp) {
free_second_and_fail:
free(sp);
return NULL;
}

strbuf_init(&sp, 0);
if (unquote_c_style(&sp, second, NULL))
goto free_and_fail2;

np = stop_at_slash(sp.buf, sp.len);
if (!np || np == sp.buf)
goto free_and_fail2;
np++;
len = strlen(np);
if (len < cp - name &&

len = sp.buf + sp.len - np;
if (len < second - name &&
!strncmp(np, name, len) &&
isspace(name[len])) {
/* Good */
memmove(sp, np, len + 1);
return sp;
strbuf_remove(&sp, 0, np - sp.buf);
return sp.buf;
}
goto free_second_and_fail;

free_and_fail2:
strbuf_release(&sp);
return NULL;
}
}

Expand Down Expand Up @@ -1378,61 +1378,50 @@ static const char minuses[]= "--------------------------------------------------

static void show_stats(struct patch *patch)
{
const char *prefix = "";
char *name = patch->new_name;
char *qname = NULL;
int len, max, add, del, total;

if (!name)
name = patch->old_name;
struct strbuf qname;
char *cp = patch->new_name ? patch->new_name : patch->old_name;
int max, add, del;

if (0 < (len = quote_c_style(name, NULL, NULL, 0))) {
qname = xmalloc(len + 1);
quote_c_style(name, qname, NULL, 0);
name = qname;
}
strbuf_init(&qname, 0);
quote_c_style(cp, &qname, NULL, 0);

/*
* "scale" the filename
*/
len = strlen(name);
max = max_len;
if (max > 50)
max = 50;
if (len > max) {
char *slash;
prefix = "...";
max -= 3;
name += len - max;
slash = strchr(name, '/');
if (slash)
name = slash;

if (qname.len > max) {
cp = strchr(qname.buf + qname.len + 3 - max, '/');
if (!cp)
cp = qname.buf + qname.len + 3 - max;
strbuf_splice(&qname, 0, cp - qname.buf, "...", 3);
}

if (patch->is_binary) {
printf(" %-*s | Bin\n", max, qname.buf);
strbuf_release(&qname);
return;
}
len = max;

printf(" %-*s |", max, qname.buf);
strbuf_release(&qname);

/*
* scale the add/delete
*/
max = max_change;
if (max + len > 70)
max = 70 - len;

max = max + max_change > 70 ? 70 - max : max_change;
add = patch->lines_added;
del = patch->lines_deleted;
total = add + del;

if (max_change > 0) {
total = (total * max + max_change / 2) / max_change;
int total = ((add + del) * max + max_change / 2) / max_change;
add = (add * max + max_change / 2) / max_change;
del = total - add;
}
if (patch->is_binary)
printf(" %s%-*s | Bin\n", prefix, len, name);
else
printf(" %s%-*s |%5d %.*s%.*s\n", prefix,
len, name, patch->lines_added + patch->lines_deleted,
add, pluses, del, minuses);
free(qname);
printf("%5d %.*s%.*s\n", patch->lines_added + patch->lines_deleted,
add, pluses, del, minuses);
}

static int read_old_data(struct stat *st, const char *path, struct strbuf *buf)
Expand Down Expand Up @@ -2227,13 +2216,8 @@ static void numstat_patch_list(struct patch *patch)
if (patch->is_binary)
printf("-\t-\t");
else
printf("%d\t%d\t",
patch->lines_added, patch->lines_deleted);
if (line_termination && quote_c_style(name, NULL, NULL, 0))
quote_c_style(name, NULL, stdout, 0);
else
fputs(name, stdout);
putchar(line_termination);
printf("%d\t%d\t", patch->lines_added, patch->lines_deleted);
write_name_quoted(name, stdout, line_termination);
}
}

Expand Down
3 changes: 1 addition & 2 deletions builtin-blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -1430,8 +1430,7 @@ static void get_commit_info(struct commit *commit,
static void write_filename_info(const char *path)
{
printf("filename ");
write_name_quoted(NULL, 0, path, 1, stdout);
putchar('\n');
write_name_quoted(path, stdout, '\n');
}

/*
Expand Down
2 changes: 1 addition & 1 deletion builtin-check-attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
else if (ATTR_UNSET(value))
value = "unspecified";

write_name_quoted("", 0, argv[i], 1, stdout);
quote_c_style(argv[i], NULL, stdout, 0);
printf(": %s: %s\n", argv[j+1], value);
}
}
Expand Down
Loading

0 comments on commit a17ba31

Please sign in to comment.