print: improve indented printing api

- make sure all commit errors go to stderr
- make it a bit more api like
cute-signatures
Timo Teräs 2021-12-27 14:34:01 +02:00
parent 6117de6eae
commit a662047e2c
4 changed files with 68 additions and 42 deletions

View File

@ -63,10 +63,14 @@ struct apk_progress {
void apk_print_progress(struct apk_progress *p, size_t done, size_t total); void apk_print_progress(struct apk_progress *p, size_t done, size_t total);
struct apk_indent { struct apk_indent {
struct apk_out *out; FILE *f;
int x, indent; 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); 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_words(struct apk_indent *i, const char *text);
void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...) void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...)

View File

@ -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:"); apk_msg(out, "World updated, but the following packages are not removed due to:");
ctx->header = 1; ctx->header = 1;
} }
if (!ctx->indent.indent) { if (!ctx->indent.indent)
ctx->indent.x = printf(" %s:", ctx->name->name); apk_print_indented_group(&ctx->indent, 0, " %s:", ctx->name->name);
ctx->indent.indent = ctx->indent.x + 1; if (name_in_world(pkg0->name))
}
if (name_in_world(pkg0->name)) {
apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg0->name->name)); apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg0->name->name));
}
foreach_array_item(d, pkg0->provides) { foreach_array_item(d, pkg0->provides) {
if (!name_in_world(d->name)) continue; if (!name_in_world(d->name)) continue;
apk_print_indented(&ctx->indent, APK_BLOB_STR(d->name->name)); 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 not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx;
struct apk_provider *p; struct apk_provider *p;
ctx->indent = (struct apk_indent) { .out = out };
ctx->name = name; ctx->name = name;
ctx->matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES; 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) foreach_array_item(p, name->providers)
if (p->pkg->marked) if (p->pkg->marked)
print_not_deleted_pkg(p->pkg, NULL, NULL, ctx); print_not_deleted_pkg(p->pkg, NULL, NULL, ctx);
if (ctx->indent.indent) apk_print_indented_end(&ctx->indent);
printf("\n");
} }
static void delete_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, static void delete_pkg(struct apk_package *pkg0, struct apk_dependency *dep0,

View File

@ -133,14 +133,13 @@ static int dump_packages(struct apk_out *out, struct apk_changeset *changeset,
{ {
struct apk_change *change; struct apk_change *change;
struct apk_name *name; struct apk_name *name;
struct apk_indent indent = { .out = out, .indent = 2 }; struct apk_indent indent;
int match = 0; int match = 0;
apk_print_indented_init(&indent, out, 0);
foreach_array_item(change, changeset->changes) { foreach_array_item(change, changeset->changes) {
if (!cmp(change)) if (!cmp(change)) continue;
continue; if (!match) apk_print_indented_group(&indent, 2, "%s:\n", msg);
if (match == 0)
printf("%s:\n", msg);
if (change->new_pkg != NULL) if (change->new_pkg != NULL)
name = change->new_pkg->name; name = change->new_pkg->name;
else 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)); apk_print_indented(&indent, APK_BLOB_STR(name->name));
match++; match++;
} }
if (match) apk_print_indented_end(&indent);
printf("\n");
return match; return match;
} }
@ -308,11 +306,11 @@ int apk_solver_commit_changeset(struct apk_database *db,
"The following packages will be reinstalled"); "The following packages will be reinstalled");
if (download_size) { if (download_size) {
size_unit = apk_get_human_size(download_size, &humanized); 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); (long long)humanized, size_unit);
} }
size_unit = apk_get_human_size(llabs(size_diff), &humanized); 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, (long long)humanized,
size_unit, size_unit,
(size_diff < 0) ? (size_diff < 0) ?
@ -405,22 +403,15 @@ struct print_state {
static void label_start(struct print_state *ps, const char *text) static void label_start(struct print_state *ps, const char *text)
{ {
if (ps->label) { if (ps->label) {
printf(" %s:\n", ps->label); apk_print_indented_line(&ps->i, " %s:\n", ps->label);
ps->label = NULL; ps->label = NULL;
ps->i.x = ps->i.indent = 0;
ps->num_labels++; ps->num_labels++;
} }
if (ps->i.x == 0) { if (!ps->i.x) apk_print_indented_group(&ps->i, 0, " %s", text);
ps->i.x = printf(" %s", text);
ps->i.indent = ps->i.x + 1;
}
} }
static void label_end(struct print_state *ps) static void label_end(struct print_state *ps)
{ {
if (ps->i.x != 0) { apk_print_indented_end(&ps->i);
printf("\n");
ps->i.x = ps->i.indent = 0;
}
} }
static void print_pinning_errors(struct print_state *ps, struct apk_package *pkg, unsigned int tag) 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. * any other selected version. or all of them with -v.
*/ */
apk_err(out, "unable to select packages:");
/* Construct information about names */ /* Construct information about names */
foreach_array_item(change, changeset->changes) { foreach_array_item(change, changeset->changes) {
struct apk_package *pkg = change->new_pkg; 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 */ /* Analyze is package, and missing names referred to */
ps = (struct print_state) { ps = (struct print_state) {
.i.out = out,
.db = db, .db = db,
.world = world, .world = world,
}; };
apk_err(out, "unable to select packages:");
apk_print_indented_init(&ps.i, out, 1);
analyze_deps(&ps, world); analyze_deps(&ps, world);
foreach_array_item(change, changeset->changes) { foreach_array_item(change, changeset->changes) {
struct apk_package *pkg = change->new_pkg; 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); analyze_deps(&ps, pkg->depends);
} }
if (ps.num_labels == 0) if (!ps.num_labels)
printf(" Huh? Error reporter did not find the broken constraints.\n"); apk_print_indented_line(&ps.i, "Huh? Error reporter did not find the broken constraints.\n");
} }
int apk_solver_commit(struct apk_database *db, int apk_solver_commit(struct apk_database *db,

View File

@ -9,6 +9,7 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
@ -222,16 +223,52 @@ void apk_print_progress(struct apk_progress *p, size_t done, size_t total)
fputs("\e8\e[0K", out); 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) int apk_print_indented(struct apk_indent *i, apk_blob_t blob)
{ {
FILE *out = i->out->out;
if (i->x <= i->indent) if (i->x <= i->indent)
i->x += fprintf(out, "%*s" BLOB_FMT, i->indent - i->x, "", BLOB_PRINTF(blob)); i->x += fprintf(i->f, "%*s" BLOB_FMT, i->indent - i->x, "", BLOB_PRINTF(blob));
else if (i->x + blob.len + 1 >= apk_out_get_width(i->out)) else if (i->x + blob.len + 1 >= i->width)
i->x = fprintf(out, "\n%*s" BLOB_FMT, i->indent, "", BLOB_PRINTF(blob)) - 1; i->x = fprintf(i->f, "\n%*s" BLOB_FMT, i->indent, "", BLOB_PRINTF(blob)) - 1;
else else
i->x += fprintf(out, " " BLOB_FMT, BLOB_PRINTF(blob)); i->x += fprintf(i->f, " " BLOB_FMT, BLOB_PRINTF(blob));
i->out->last_change++;
return 0; return 0;
} }