diff --git a/src/apk_print.h b/src/apk_print.h index e97247b..c3e254a 100644 --- a/src/apk_print.h +++ b/src/apk_print.h @@ -63,10 +63,14 @@ struct apk_progress { void apk_print_progress(struct apk_progress *p, size_t done, size_t total); struct apk_indent { - struct apk_out *out; - int x, indent; + FILE *f; + unsigned int x, indent, width; }; +void apk_print_indented_init(struct apk_indent *i, struct apk_out *out, int err); +void apk_print_indented_line(struct apk_indent *i, const char *fmt, ...); +void apk_print_indented_group(struct apk_indent *i, int indent, const char *fmt, ...); +void apk_print_indented_end(struct apk_indent *i); int apk_print_indented(struct apk_indent *i, apk_blob_t blob); void apk_print_indented_words(struct apk_indent *i, const char *text); void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...) diff --git a/src/app_del.c b/src/app_del.c index f4c00fc..1df4cc9 100644 --- a/src/app_del.c +++ b/src/app_del.c @@ -68,14 +68,10 @@ static void print_not_deleted_pkg(struct apk_package *pkg0, struct apk_dependenc apk_msg(out, "World updated, but the following packages are not removed due to:"); ctx->header = 1; } - if (!ctx->indent.indent) { - ctx->indent.x = printf(" %s:", ctx->name->name); - ctx->indent.indent = ctx->indent.x + 1; - } - - if (name_in_world(pkg0->name)) { + if (!ctx->indent.indent) + apk_print_indented_group(&ctx->indent, 0, " %s:", ctx->name->name); + if (name_in_world(pkg0->name)) apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg0->name->name)); - } foreach_array_item(d, pkg0->provides) { if (!name_in_world(d->name)) continue; apk_print_indented(&ctx->indent, APK_BLOB_STR(d->name->name)); @@ -98,14 +94,13 @@ static void print_not_deleted_name(struct apk_database *db, const char *match, struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx; struct apk_provider *p; - ctx->indent = (struct apk_indent) { .out = out }; ctx->name = name; ctx->matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES; + apk_print_indented_init(&ctx->indent, out, 0); foreach_array_item(p, name->providers) if (p->pkg->marked) print_not_deleted_pkg(p->pkg, NULL, NULL, ctx); - if (ctx->indent.indent) - printf("\n"); + apk_print_indented_end(&ctx->indent); } static void delete_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, diff --git a/src/commit.c b/src/commit.c index a6b841c..6130f36 100644 --- a/src/commit.c +++ b/src/commit.c @@ -133,14 +133,13 @@ static int dump_packages(struct apk_out *out, struct apk_changeset *changeset, { struct apk_change *change; struct apk_name *name; - struct apk_indent indent = { .out = out, .indent = 2 }; + struct apk_indent indent; int match = 0; + apk_print_indented_init(&indent, out, 0); foreach_array_item(change, changeset->changes) { - if (!cmp(change)) - continue; - if (match == 0) - printf("%s:\n", msg); + if (!cmp(change)) continue; + if (!match) apk_print_indented_group(&indent, 2, "%s:\n", msg); if (change->new_pkg != NULL) name = change->new_pkg->name; else @@ -149,8 +148,7 @@ static int dump_packages(struct apk_out *out, struct apk_changeset *changeset, apk_print_indented(&indent, APK_BLOB_STR(name->name)); match++; } - if (match) - printf("\n"); + apk_print_indented_end(&indent); return match; } @@ -308,11 +306,11 @@ int apk_solver_commit_changeset(struct apk_database *db, "The following packages will be reinstalled"); if (download_size) { size_unit = apk_get_human_size(download_size, &humanized); - printf("Need to download %lld %s of packages.\n", + apk_msg(out, "Need to download %lld %s of packages.", (long long)humanized, size_unit); } size_unit = apk_get_human_size(llabs(size_diff), &humanized); - printf("After this operation, %lld %s of %s.\n", + apk_msg(out, "After this operation, %lld %s of %s.", (long long)humanized, size_unit, (size_diff < 0) ? @@ -405,22 +403,15 @@ struct print_state { static void label_start(struct print_state *ps, const char *text) { if (ps->label) { - printf(" %s:\n", ps->label); + apk_print_indented_line(&ps->i, " %s:\n", ps->label); ps->label = NULL; - ps->i.x = ps->i.indent = 0; ps->num_labels++; } - if (ps->i.x == 0) { - ps->i.x = printf(" %s", text); - ps->i.indent = ps->i.x + 1; - } + if (!ps->i.x) apk_print_indented_group(&ps->i, 0, " %s", text); } static void label_end(struct print_state *ps) { - if (ps->i.x != 0) { - printf("\n"); - ps->i.x = ps->i.indent = 0; - } + apk_print_indented_end(&ps->i); } static void print_pinning_errors(struct print_state *ps, struct apk_package *pkg, unsigned int tag) @@ -653,8 +644,6 @@ void apk_solver_print_errors(struct apk_database *db, * any other selected version. or all of them with -v. */ - apk_err(out, "unable to select packages:"); - /* Construct information about names */ foreach_array_item(change, changeset->changes) { struct apk_package *pkg = change->new_pkg; @@ -668,10 +657,11 @@ void apk_solver_print_errors(struct apk_database *db, /* Analyze is package, and missing names referred to */ ps = (struct print_state) { - .i.out = out, .db = db, .world = world, }; + apk_err(out, "unable to select packages:"); + apk_print_indented_init(&ps.i, out, 1); analyze_deps(&ps, world); foreach_array_item(change, changeset->changes) { struct apk_package *pkg = change->new_pkg; @@ -681,8 +671,8 @@ void apk_solver_print_errors(struct apk_database *db, analyze_deps(&ps, pkg->depends); } - if (ps.num_labels == 0) - printf(" Huh? Error reporter did not find the broken constraints.\n"); + if (!ps.num_labels) + apk_print_indented_line(&ps.i, "Huh? Error reporter did not find the broken constraints.\n"); } int apk_solver_commit(struct apk_database *db, diff --git a/src/print.c b/src/print.c index ba9d90f..187dcf4 100644 --- a/src/print.c +++ b/src/print.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -222,16 +223,52 @@ void apk_print_progress(struct apk_progress *p, size_t done, size_t total) fputs("\e8\e[0K", out); } +void apk_print_indented_init(struct apk_indent *i, struct apk_out *out, int err) +{ + *i = (struct apk_indent) { + .f = err ? out->err : out->out, + .width = apk_out_get_width(out), + }; + out->last_change++; +} + +void apk_print_indented_line(struct apk_indent *i, const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + vfprintf(i->f, fmt, va); + va_end(va); + i->x = i->indent = 0; +} + +void apk_print_indented_group(struct apk_indent *i, int indent, const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + i->x = vfprintf(i->f, fmt, va); + i->indent = indent ?: (i->x + 1); + if (fmt[strlen(fmt)-1] == '\n') i->x = 0; + va_end(va); +} + +void apk_print_indented_end(struct apk_indent *i) +{ + if (i->x) { + fprintf(i->f, "\n"); + i->x = i->indent = 0; + } +} + int apk_print_indented(struct apk_indent *i, apk_blob_t blob) { - FILE *out = i->out->out; if (i->x <= i->indent) - i->x += fprintf(out, "%*s" BLOB_FMT, i->indent - i->x, "", BLOB_PRINTF(blob)); - else if (i->x + blob.len + 1 >= apk_out_get_width(i->out)) - i->x = fprintf(out, "\n%*s" BLOB_FMT, i->indent, "", BLOB_PRINTF(blob)) - 1; + i->x += fprintf(i->f, "%*s" BLOB_FMT, i->indent - i->x, "", BLOB_PRINTF(blob)); + else if (i->x + blob.len + 1 >= i->width) + i->x = fprintf(i->f, "\n%*s" BLOB_FMT, i->indent, "", BLOB_PRINTF(blob)) - 1; else - i->x += fprintf(out, " " BLOB_FMT, BLOB_PRINTF(blob)); - i->out->last_change++; + i->x += fprintf(i->f, " " BLOB_FMT, BLOB_PRINTF(blob)); return 0; }