Johannes Schindelin <johannes.schindelin@xxxxxx> writes: > It is technically allowed, as per C89, for functions' return type to > be complete structs (i.e. *not* just pointers to structs), but it is > bad practice. Not necessarily. > This is a very late attempt to contain the damage done by this developer > in 6d297f8 (Status update on merge-recursive in C, 2006-07-08) which > introduced such a return type. > > It will also help the current effort to libify merge-recursive.c, as > it will allow us to return proper error codes later. But this part of the motivation does make sense. Having to pass an extra int &error_code field, only because the return value is already used for something else, is a lot more weird. > Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> > --- > merge-recursive.c | 93 ++++++++++++++++++++++++++++++------------------------- > 1 file changed, 50 insertions(+), 43 deletions(-) > > diff --git a/merge-recursive.c b/merge-recursive.c > index c4ece96..d56651c9 100644 > --- a/merge-recursive.c > +++ b/merge-recursive.c > @@ -888,47 +888,47 @@ static int merge_3way(struct merge_options *o, > return merge_status; > } > > -static struct merge_file_info merge_file_1(struct merge_options *o, > +static int merge_file_1(struct merge_options *o, > const struct diff_filespec *one, > const struct diff_filespec *a, > const struct diff_filespec *b, > const char *branch1, > - const char *branch2) > + const char *branch2, > + struct merge_file_info *result) > { > - struct merge_file_info result; > - result.merge = 0; > - result.clean = 1; > + result->merge = 0; > + result->clean = 1; > > if ((S_IFMT & a->mode) != (S_IFMT & b->mode)) { > - result.clean = 0; > + result->clean = 0; > if (S_ISREG(a->mode)) { > - result.mode = a->mode; > - hashcpy(result.sha, a->sha1); > + result->mode = a->mode; > + hashcpy(result->sha, a->sha1); > } else { > - result.mode = b->mode; > - hashcpy(result.sha, b->sha1); > + result->mode = b->mode; > + hashcpy(result->sha, b->sha1); > } > } else { > if (!sha_eq(a->sha1, one->sha1) && !sha_eq(b->sha1, one->sha1)) > - result.merge = 1; > + result->merge = 1; > > /* > * Merge modes > */ > if (a->mode == b->mode || a->mode == one->mode) > - result.mode = b->mode; > + result->mode = b->mode; > else { > - result.mode = a->mode; > + result->mode = a->mode; > if (b->mode != one->mode) { > - result.clean = 0; > - result.merge = 1; > + result->clean = 0; > + result->merge = 1; > } > } > > if (sha_eq(a->sha1, b->sha1) || sha_eq(a->sha1, one->sha1)) > - hashcpy(result.sha, b->sha1); > + hashcpy(result->sha, b->sha1); > else if (sha_eq(b->sha1, one->sha1)) > - hashcpy(result.sha, a->sha1); > + hashcpy(result->sha, a->sha1); > else if (S_ISREG(a->mode)) { > mmbuffer_t result_buf; > int merge_status; > @@ -940,62 +940,63 @@ static struct merge_file_info merge_file_1(struct merge_options *o, > die(_("Failed to execute internal merge")); > > if (write_sha1_file(result_buf.ptr, result_buf.size, > - blob_type, result.sha)) > + blob_type, result->sha)) > die(_("Unable to add %s to database"), > a->path); > > free(result_buf.ptr); > - result.clean = (merge_status == 0); > + result->clean = (merge_status == 0); > } else if (S_ISGITLINK(a->mode)) { > - result.clean = merge_submodule(result.sha, > + result->clean = merge_submodule(result->sha, > one->path, one->sha1, > a->sha1, b->sha1, > !o->call_depth); > } else if (S_ISLNK(a->mode)) { > - hashcpy(result.sha, a->sha1); > + hashcpy(result->sha, a->sha1); > > if (!sha_eq(a->sha1, b->sha1)) > - result.clean = 0; > + result->clean = 0; > } else > die(_("BUG: unsupported object type in the tree")); > } > > - return result; > + return 0; > } > > -static struct merge_file_info > -merge_file_special_markers(struct merge_options *o, > +static int merge_file_special_markers(struct merge_options *o, > const struct diff_filespec *one, > const struct diff_filespec *a, > const struct diff_filespec *b, > const char *branch1, > const char *filename1, > const char *branch2, > - const char *filename2) > + const char *filename2, > + struct merge_file_info *mfi) > { > char *side1 = NULL; > char *side2 = NULL; > - struct merge_file_info mfi; > + int ret; > > if (filename1) > side1 = xstrfmt("%s:%s", branch1, filename1); > if (filename2) > side2 = xstrfmt("%s:%s", branch2, filename2); > > - mfi = merge_file_1(o, one, a, b, > - side1 ? side1 : branch1, side2 ? side2 : branch2); > + ret = merge_file_1(o, one, a, b, > + side1 ? side1 : branch1, side2 ? side2 : branch2, mfi); > free(side1); > free(side2); > - return mfi; > + return ret; > } > > -static struct merge_file_info merge_file_one(struct merge_options *o, > +static int merge_file_one(struct merge_options *o, > const char *path, > const unsigned char *o_sha, int o_mode, > const unsigned char *a_sha, int a_mode, > const unsigned char *b_sha, int b_mode, > const char *branch1, > - const char *branch2) > + const char *branch2, > + struct merge_file_info *mfi) > { > struct diff_filespec one, a, b; > > @@ -1006,7 +1007,7 @@ static struct merge_file_info merge_file_one(struct merge_options *o, > a.mode = a_mode; > hashcpy(b.sha1, b_sha); > b.mode = b_mode; > - return merge_file_1(o, &one, &a, &b, branch1, branch2); > + return merge_file_1(o, &one, &a, &b, branch1, branch2, mfi); > } > > static void handle_change_delete(struct merge_options *o, > @@ -1179,11 +1180,14 @@ static void conflict_rename_rename_1to2(struct merge_options *o, > struct merge_file_info mfi; > struct diff_filespec other; > struct diff_filespec *add; > - mfi = merge_file_one(o, one->path, > + > + if (merge_file_one(o, one->path, > one->sha1, one->mode, > a->sha1, a->mode, > b->sha1, b->mode, > - ci->branch1, ci->branch2); > + ci->branch1, ci->branch2, &mfi) < 0) > + return; > + > /* > * FIXME: For rename/add-source conflicts (if we could detect > * such), this is wrong. We should instead find a unique > @@ -1237,12 +1241,13 @@ static void conflict_rename_rename_2to1(struct merge_options *o, > remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path)); > remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path)); > > - mfi_c1 = merge_file_special_markers(o, a, c1, &ci->ren1_other, > + if (merge_file_special_markers(o, a, c1, &ci->ren1_other, > o->branch1, c1->path, > - o->branch2, ci->ren1_other.path); > - mfi_c2 = merge_file_special_markers(o, b, &ci->ren2_other, c2, > + o->branch2, ci->ren1_other.path, &mfi_c1) < 0 || > + merge_file_special_markers(o, b, &ci->ren2_other, c2, > o->branch1, ci->ren2_other.path, > - o->branch2, c2->path); > + o->branch2, c2->path, &mfi_c2) < 0) > + return; > > if (o->call_depth) { > /* > @@ -1463,10 +1468,11 @@ static int process_renames(struct merge_options *o, > ren1_dst, branch2); > if (o->call_depth) { > struct merge_file_info mfi; > - mfi = merge_file_one(o, ren1_dst, null_sha1, 0, > + if (merge_file_one(o, ren1_dst, null_sha1, 0, > ren1->pair->two->sha1, ren1->pair->two->mode, > dst_other.sha1, dst_other.mode, > - branch1, branch2); > + branch1, branch2, &mfi) < 0) > + return -1; > output(o, 1, _("Adding merged %s"), ren1_dst); > update_file(o, 0, mfi.sha, mfi.mode, ren1_dst); > try_merge = 0; > @@ -1622,9 +1628,10 @@ static int merge_content(struct merge_options *o, > if (dir_in_way(path, !o->call_depth)) > df_conflict_remains = 1; > } > - mfi = merge_file_special_markers(o, &one, &a, &b, > + if (merge_file_special_markers(o, &one, &a, &b, > o->branch1, path1, > - o->branch2, path2); > + o->branch2, path2, &mfi) < 0) > + return -1; > > if (mfi.clean && !df_conflict_remains && > sha_eq(mfi.sha, a_sha) && mfi.mode == a_mode) { -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html