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);
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, ...)

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:");
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,

View File

@ -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,

View File

@ -9,6 +9,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.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);
}
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;
}