[pacman-dev] Improving -Qi/-Si code

Simon Gomizelj simongmzlj at gmail.com
Sat Dec 28 13:24:37 EST 2013

I've been working out-of-tree for a replacement for -Qi / -Si, which can
be found here: <https://github.com/vodik/alpm-dump> and I'm looking for
some feedback before I start integrating it into pacman.

For those not familiar with why I've decided to rewrite this, the
existing code is rather clumsy and makes some assumptions:

    string_display(_("Name           :"), alpm_pkg_get_name(pkg), cols);

The header is "Name", but the padding is embedded into the string. This
forces translation writers to also put the right paddings into their
translations, something which they shouldn't be burdened with.

Further, `string_display` actually needs to know how long "Name           :"
is so it can do proper line wrapping. The following lines need to be
indented properly. This ends up being recalculated for every header.

Instead, if we knew how wide the widest header would be ahead of time,
we no longer need to embed padding into translations and we no longer
need to calculate line lengths for each print operation.

This is what the code in the alpm-dump repository attempts to do.

The approach I've taken is have the printing function take an array of
const char *. Each index represents a field, like Name or Version. If
the index is NULL, its ignored, and if it has a value, it is printed
along side corresponding data from the package.

For example:

    static const char *sync_table[LAST_ENTRY] = {
        [ENTRY_REPOSITORY]   = "Repository",
        [ENTRY_NAME]         = "Name",
        [ENTRY_VERSION]      = "Version",
        [ENTRY_DESCRIPTION]  = "Description",
        [ENTRY_ARCHITECTURE] = "Architecture",

Calculating the max width means iterating across this table once looking
for the longest field length. Dumping a package is then a matter of
iterating across the table, printing the stored string and then the
value that corresponds to the array index.

    printf("%-*s : ", width, table[index]);

    switch(index) {
        case ENTRY_REPOSITORY:
            indentprint_r(alpm_db_get_name(alpm_pkg_get_db(pkg)), width, 0);
        case ENTRY_NAME:
            indentprint_r(alpm_pkg_get_name(pkg), width, 0);
        case ENTRY_VERSION:
            indentprint_r(alpm_pkg_get_version(pkg), width, 0);

And as an added bonus, alpm-dump is measurably faster than the current
code. Not that this matters that much. The current code isn't exactly
slow and is still much much faster than stdout is.

More information about the pacman-dev mailing list