Download raw body.
got_patch_progress_cb: handle offsets and errors too
On Wed, Mar 16, 2022 at 07:30:12PM +0100, Omar Polo wrote:
> blob - 6e4f19aa3e9703b1e7a3b57f3d76fe41a2b801ac
> blob + 453af5ad8978ba78acf573f3beb5d5f0d2092688
> --- got/got.c
> +++ got/got.c
> @@ -7186,13 +7186,32 @@ patch_from_stdin(int *patchfd)
> }
>
> static const struct got_error *
> -patch_progress(void *arg, const char *old, const char *new, unsigned char mode)
> +patch_progress(void *arg, const char *old, const char *new,
> + unsigned char mode, const struct got_patch_hunk_head *head)
> {
> + struct got_patch_hunk *h;
> const char *path = new == NULL ? old : new;
>
> while (*path == '/')
> path++;
> printf("%c %s\n", mode, path);
> +
> + STAILQ_FOREACH(h, head, entries) {
> + if (h->offset != 0 || h->err != NULL) {
> + printf("@@ -%ld", h->old_from);
> + if (h->old_lines != 1)
> + printf(",%ld", h->old_lines);
> + printf(" +%ld", h->new_from);
> + if (h->new_lines != 1)
> + printf(",%ld", h->new_lines);
> + printf(" @@ ");
> + }
> + if (h->offset != 0)
> + printf("applied with offset %ld\n", h->offset);
> + if (h->err != NULL)
> + printf("%s\n", h->err->msg);
Instead of running so many printf calls, can we build a string and
do just one printf?
You do not have to omit the ,1 cases, I would just print them.
It does not hurt to write ,1 explicitly.
I doubt everyone will know that ,1 is implied if omitted.
> + }
> +
> return NULL;
> }
>
> blob - 391c0cf0a69178e759d03ba7c752062f5752dfc6
> blob + 5b5f8d153e01e5595219bcda45f025ba7289bbbb
> --- include/got_patch.h
> +++ include/got_patch.h
> @@ -14,13 +14,28 @@
> * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> */
>
> +STAILQ_HEAD(got_patch_hunk_head, got_patch_hunk);
> +struct got_patch_hunk {
> + STAILQ_ENTRY(got_patch_hunk) entries;
> + const struct got_error *err;
> + long offset;
> + long old_from;
> + long old_lines;
> + long new_from;
> + long new_lines;
> + size_t len;
> + size_t cap;
> + char **lines;
> +};
If a callback messes with the STAILQ part of the struct, the code
in lib/patch.c could crash.
Are you sure you want to send this internal struct to the progress callback,
instead of a smaller struct that has copies of the required fields?
> +
> /*
> * A callback that gets invoked during the patch application.
> *
> - * Receives the old and new path and a status code.
> + * Receives the old and new path, a status code and the hunks.
> */
> typedef const struct got_error *(*got_patch_progress_cb)(void *,
> - const char *, const char *, unsigned char);
> + const char *, const char *, unsigned char,
> + const struct got_patch_hunk_head *);
>
> /*
> * Apply the (already opened) patch to the repository and register the
> blob - 58d4125553be6fd56d2408805b9c001d9c08c698
> blob + 9eab8fa2fd1714e2fa85193a6843cc5480466f4d
> --- lib/patch.c
> +++ lib/patch.c
> @@ -54,26 +54,16 @@
>
> #define MIN(a, b) ((a) < (b) ? (a) : (b))
>
> -struct got_patch_hunk {
> - STAILQ_ENTRY(got_patch_hunk) entries;
> - long old_from;
> - long old_lines;
> - long new_from;
> - long new_lines;
> - size_t len;
> - size_t cap;
> - char **lines;
> -};
> -
> struct got_patch {
> char *old;
> char *new;
> - STAILQ_HEAD(, got_patch_hunk) head;
> + struct got_patch_hunk_head head;
> };
>
> struct patch_args {
> got_patch_progress_cb progress_cb;
> void *progress_arg;
> + struct got_patch_hunk_head *head;
> };
>
> static const struct got_error *
> @@ -344,11 +334,8 @@ test_hunk(FILE *orig, struct got_patch_hunk *h)
> case '-':
> linelen = getline(&line, &linesize, orig);
> if (linelen == -1) {
> - if (ferror(orig))
> - err = got_error_from_errno("getline");
Possible errors from getline() are EINVAL and EOVERFLOW, and various
others including ENOMEM.
Is it really fine to hide any such error behind GOT_ERR_PATCH_DONT_APPLY?
> - else
> - err = got_error(
> - GOT_ERR_PATCH_DONT_APPLY);
> + err = got_ferror(orig,
> + GOT_ERR_PATCH_DONT_APPLY);
> goto done;
> }
> if (strcmp(h->lines[i]+1, line)) {
got_patch_progress_cb: handle offsets and errors too