| |
fmt_code_t fmt_code;
|
| |
};
|
| |
|
| + |
/* Format handler function prototypes */
|
| + |
|
| + |
static struct sbuf *format_shlibs(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_shlib_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_categories(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_category_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_directories(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_directory_group(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_directory_keepflag(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_directory_path(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_directory_perms(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_directory_tryflag(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_directory_user(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_files(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_file_group(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_file_keepflag(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_file_path(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_file_perms(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_file_sha256(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_file_user(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_groups(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_group_gidstr(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_group_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_row_counter(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_licenses(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_license_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_message(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_options(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_option_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_option_value(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_users(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_user_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_user_uidstr(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_autoremove(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_comment(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_dependencies(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_dependency_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_dependency_origin(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_dependency_version(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_add_info(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_lock_status(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_license_logic(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_maintainer(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_name(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_origin(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_prefix(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_requirements(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_flatsize(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_install_tstamp(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_version(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_home_url(struct sbuf *, const void *, struct percent_esc *);
|
| + |
static struct sbuf *format_literal_percent(struct sbuf *, __unused const void *, __unused struct percent_esc *);
|
| + |
static struct sbuf *format_unknown(struct sbuf *, __unused const void *, __unused struct percent_esc *);
|
| + |
|
| + |
/* Other static function prototypes */
|
| + |
|
| + |
static void free_percent_esc(struct percent_esc *);
|
| + |
static struct percent_esc *new_percent_esc(struct percent_esc *);
|
| + |
|
| + |
static char *gen_format(char *, size_t, unsigned, const char *);
|
| + |
|
| + |
static struct sbuf *human_number(struct sbuf *, int64_t, struct percent_esc *);
|
| + |
static struct sbuf *string_val(struct sbuf *, const char *,
|
| + |
struct percent_esc *);
|
| + |
static struct sbuf *int_val(struct sbuf *, int64_t, struct percent_esc *);
|
| + |
static struct sbuf *bool_val(struct sbuf *, bool, struct percent_esc *);
|
| + |
static struct sbuf *mode_val(struct sbuf *, mode_t, struct percent_esc *);
|
| + |
static struct sbuf *list_count(struct sbuf *, int64_t, struct percent_esc *);
|
| + |
|
| + |
static struct percent_esc *set_list_defaults(struct percent_esc *, const char *,
|
| + |
const char *);
|
| + |
|
| + |
static struct sbuf *iterate_item(struct sbuf *, const struct pkg *, const char *,
|
| + |
const void *, int, unsigned);
|
| + |
|
| + |
static inline const char *field_modifier(const char *, struct percent_esc *);
|
| + |
static inline const char *field_width(const char *, struct percent_esc *);
|
| + |
static const char *parse_format(const char *, unsigned, struct percent_esc *);
|
| + |
|
| + |
static inline const char *maybe_read_hex_byte(struct sbuf *, const char *);
|
| + |
static inline const char *read_oct_byte(struct sbuf *, const char *);
|
| + |
static const char *process_escape(struct sbuf *, const char *);
|
| + |
|
| + |
static const char *process_format_trailer(struct sbuf *, const char *, const struct pkg *,
|
| + |
const void *, int, unsigned);
|
| + |
static const char *process_format_main(struct sbuf *, const char *, va_list);
|
| + |
|
| + |
|
| |
struct pkg_printf_fmt {
|
| |
char fmt_main;
|
| |
char fmt_sub;
|
| |
struct percent_esc *);
|
| |
};
|
| |
|
| - |
/* Format handler function prototypes */
|
| - |
|
| - |
static struct sbuf *format_shlibs(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_shlib_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_categories(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_category_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_directories(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_directory_group(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_directory_keepflag(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_directory_path(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_directory_perms(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_directory_tryflag(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_directory_user(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_files(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_file_group(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_file_keepflag(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_file_path(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_file_perms(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_file_sha256(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_file_user(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_groups(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_group_gidstr(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_group_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_row_counter(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_licenses(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_license_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_message(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_options(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_option_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_option_value(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_users(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_user_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_user_uidstr(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_autoremove(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_comment(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_dependencies(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_dependency_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_dependency_origin(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_dependency_version(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_add_info(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_lock_status(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_license_logic(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_maintainer(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_name(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_origin(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_prefix(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_requirements(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_flatsize(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_install_tstamp(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_version(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_home_url(struct sbuf *sbuf, const void *data, struct percent_esc *p);
|
| - |
static struct sbuf *format_literal_percent(struct sbuf *sbuf, __unused const void *data, __unused struct percent_esc *p);
|
| - |
|
| - |
/* These are in ASCII order: alphabetical with A-Z sorting before a-z */
|
| + |
/* These are in alphabetical order with A-Z sorting before a-z */
|
| |
static const struct pkg_printf_fmt fmt[] = {
|
| |
[PP_PKG_SHLIBS] =
|
| |
{ 'B', '\0', PP_PKG, &format_shlibs, },
|
| |
[true] = { "1", "yes", "true" },
|
| |
};
|
| |
|
| - |
static void
|
| - |
free_percent_esc(struct percent_esc *p)
|
| - |
{
|
| - |
if (p->item_fmt)
|
| - |
sbuf_delete(p->item_fmt);
|
| - |
if (p->sep_fmt)
|
| - |
sbuf_delete(p->sep_fmt);
|
| - |
free(p);
|
| - |
return;
|
| - |
}
|
| + |
/*
|
| + |
* Note: List values -- special behaviour with ? and # modifiers.
|
| + |
* Affects %B %C %D %F %G %L %O %U %d %r
|
| + |
*
|
| + |
* With ? -- Flag values. Boolean. %?X returns 0 if the %X list is
|
| + |
* empty, 1 otherwise.
|
| + |
*
|
| + |
* With # -- Count values. Integer. %#X returns the number of items in
|
| + |
* the %X list.
|
| + |
*/
|
| |
|
| - |
static struct percent_esc *
|
| - |
new_percent_esc(struct percent_esc *p)
|
| + |
/*
|
| + |
* %B -- Shared Libraries. List of shlibs required by binaries in the
|
| + |
* pkg. Optionally accepts per-field format in %{ %| %}, where %n is
|
| + |
* replaced by the shlib name. Default %{%Bn\n%|%}
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_shlibs(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
/* reset or alloc new */
|
| - |
if (p == NULL) {
|
| - |
p = calloc(1, sizeof(struct percent_esc));
|
| - |
if (p != NULL) {
|
| - |
p->item_fmt = sbuf_new_auto();
|
| - |
p->sep_fmt = sbuf_new_auto();
|
| - |
}
|
| - |
if (p == NULL || p->item_fmt == NULL || p->sep_fmt == NULL) {
|
| - |
/* out of memory */
|
| - |
free_percent_esc(p);
|
| - |
return NULL;
|
| + |
const struct pkg *pkg = data;
|
| + |
|
| + |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| + |
return (list_count(sbuf, pkg_list_count(pkg, PKG_SHLIBS), p));
|
| + |
else {
|
| + |
struct pkg_shlib *shlib;
|
| + |
int count;
|
| + |
|
| + |
set_list_defaults(p, "%Bn\n", "");
|
| + |
|
| + |
count = 1;
|
| + |
while (pkg_shlibs(pkg, &shlib) == EPKG_OK) {
|
| + |
if (count > 1)
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
shlib, count, PP_B);
|
| + |
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
shlib, count, PP_B);
|
| + |
count++;
|
| |
}
|
| - |
} else {
|
| - |
p->flags = 0;
|
| - |
p->width = 0;
|
| - |
sbuf_clear(p->item_fmt);
|
| - |
sbuf_clear(p->sep_fmt);
|
| - |
p->fmt_code = '\0';
|
| |
}
|
| - |
return (p);
|
| + |
return (sbuf);
|
| |
}
|
| |
|
| - |
static inline const char*
|
| - |
maybe_read_hex_byte(struct sbuf *sbuf, const char *f)
|
| + |
/*
|
| + |
* %Bn -- Shared Library name.
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_shlib_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
int val;
|
| + |
const struct pkg_shlib *shlib = data;
|
| |
|
| - |
/* Hex escapes are of the form \xNN -- always two hex digits */
|
| + |
return (string_val(sbuf, pkg_shlib_name(shlib), p));
|
| + |
}
|
| |
|
| - |
if (isxdigit(f[0]) && isxdigit(f[1])) {
|
| - |
switch(*f) {
|
| - |
case '0':
|
| - |
val = 0x0;
|
| - |
break;
|
| - |
case '1':
|
| - |
val = 0x10;
|
| - |
break;
|
| - |
case '2':
|
| - |
val = 0x20;
|
| - |
break;
|
| - |
case '3':
|
| - |
val = 0x30;
|
| - |
break;
|
| - |
case '4':
|
| - |
val = 0x40;
|
| - |
break;
|
| - |
case '5':
|
| - |
val = 0x50;
|
| - |
break;
|
| - |
case '6':
|
| - |
val = 0x60;
|
| - |
break;
|
| - |
case '7':
|
| - |
val = 0x70;
|
| - |
break;
|
| - |
case '8':
|
| - |
val = 0x80;
|
| - |
break;
|
| - |
case '9':
|
| - |
val = 0x90;
|
| - |
break;
|
| - |
case 'a':
|
| - |
case 'A':
|
| - |
val = 0xa0;
|
| - |
break;
|
| - |
case 'b':
|
| - |
case 'B':
|
| - |
val = 0xb0;
|
| - |
break;
|
| - |
case 'c':
|
| - |
case 'C':
|
| - |
val = 0xc0;
|
| - |
break;
|
| - |
case 'd':
|
| - |
case 'D':
|
| - |
val = 0xd0;
|
| - |
break;
|
| - |
case 'e':
|
| - |
case 'E':
|
| - |
val = 0xe0;
|
| - |
break;
|
| - |
case 'f':
|
| - |
case 'F':
|
| - |
val = 0xf0;
|
| - |
break;
|
| - |
}
|
| + |
/*
|
| + |
* %C -- Categories. List of Category names (strings). 1ary category
|
| + |
* is not distinguished -- look at the package origin for that.
|
| + |
* Optionally accepts per-field format in %{ %| %}, where %n is
|
| + |
* replaced by the category name. Default %{%Cn%|, %}
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_categories(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg *pkg = data;
|
| |
|
| - |
f++;
|
| + |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| + |
return (list_count(sbuf, pkg_list_count(pkg, PKG_CATEGORIES),
|
| + |
p));
|
| + |
else {
|
| + |
struct pkg_category *cat;
|
| + |
int count;
|
| |
|
| - |
switch(*f) {
|
| - |
case '0':
|
| - |
val += 0x0;
|
| - |
break;
|
| - |
case '1':
|
| - |
val += 0x1;
|
| - |
break;
|
| - |
case '2':
|
| - |
val += 0x2;
|
| - |
break;
|
| - |
case '3':
|
| - |
val += 0x3;
|
| - |
break;
|
| - |
case '4':
|
| - |
val += 0x4;
|
| - |
break;
|
| - |
case '5':
|
| - |
val += 0x5;
|
| - |
break;
|
| - |
case '6':
|
| - |
val += 0x6;
|
| - |
break;
|
| - |
case '7':
|
| - |
val += 0x7;
|
| - |
break;
|
| - |
case '8':
|
| - |
val += 0x8;
|
| - |
break;
|
| - |
case '9':
|
| - |
val += 0x9;
|
| - |
break;
|
| - |
case 'a':
|
| - |
case 'A':
|
| - |
val += 0xa;
|
| - |
break;
|
| - |
case 'b':
|
| - |
case 'B':
|
| - |
val += 0xb;
|
| - |
break;
|
| - |
case 'c':
|
| - |
case 'C':
|
| - |
val += 0xc;
|
| - |
break;
|
| - |
case 'd':
|
| - |
case 'D':
|
| - |
val += 0xd;
|
| - |
break;
|
| - |
case 'e':
|
| - |
case 'E':
|
| - |
val += 0xe;
|
| - |
break;
|
| - |
case 'f':
|
| - |
case 'F':
|
| - |
val += 0xf;
|
| - |
break;
|
| - |
}
|
| + |
set_list_defaults(p, "%Cn", ", ");
|
| |
|
| - |
sbuf_putc(sbuf, val);
|
| - |
} else {
|
| - |
/* Pass through unchanged if it's not a recognizable
|
| - |
hex byte. */
|
| - |
sbuf_putc(sbuf, '\\');
|
| - |
sbuf_putc(sbuf, 'x');
|
| + |
count = 1;
|
| + |
while (pkg_categories(pkg, &cat) == EPKG_OK) {
|
| + |
if (count > 1)
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
cat, count, PP_C);
|
| + |
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
cat, count, PP_C);
|
| + |
count++;
|
| + |
}
|
| |
}
|
| - |
return (f);
|
| + |
return (sbuf);
|
| |
}
|
| |
|
| - |
static inline const char*
|
| - |
read_oct_byte(struct sbuf *sbuf, const char *f)
|
| + |
/*
|
| + |
* %Cn -- Category name.
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_category_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
int val = 0;
|
| + |
const struct pkg_category *cat = data;
|
| |
|
| - |
/* Octal escapes are upto three octal digits: \N, \NN or \NNN
|
| - |
up to a max of \377. Note: this treats \400 as \40
|
| - |
followed by digit 0 passed through unchanged. */
|
| + |
return (string_val(sbuf, pkg_category_name(cat), p));
|
| + |
}
|
| |
|
| - |
while (val < 32) {
|
| - |
switch (*f) {
|
| - |
case '0':
|
| - |
val = val * 8 + 0;
|
| - |
break;
|
| - |
case '1':
|
| - |
val = val * 8 + 1;
|
| - |
break;
|
| - |
case '2':
|
| - |
val = val * 8 + 2;
|
| - |
break;
|
| - |
case '3':
|
| - |
val = val * 8 + 3;
|
| - |
break;
|
| - |
case '4':
|
| - |
val = val * 8 + 4;
|
| - |
break;
|
| - |
case '5':
|
| - |
val = val * 8 + 5;
|
| - |
break;
|
| - |
case '6':
|
| - |
val = val * 8 + 6;
|
| - |
break;
|
| - |
case '7':
|
| - |
val = val * 8 + 7;
|
| - |
break;
|
| - |
default: /* Non-octal digit */
|
| - |
goto done;
|
| - |
}
|
| + |
/*
|
| + |
* %D -- Directories. List of directory names (strings) possibly with
|
| + |
* other meta-data. Optionally accepts following per-field format in
|
| + |
* %{ %| %}, where %Dn is replaced by the directory name. Default
|
| + |
* %{%Dn\n%|%}
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_directories(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg *pkg = data;
|
| |
|
| - |
f++;
|
| - |
}
|
| - |
done:
|
| - |
f--; /* point at the last octal digit */
|
| - |
sbuf_putc(sbuf, val);
|
| + |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| + |
return (list_count(sbuf, pkg_list_count(pkg, PKG_DIRS), p));
|
| + |
else {
|
| + |
struct pkg_dir *dir;
|
| + |
int count;
|
| |
|
| - |
return (f);
|
| - |
}
|
| + |
set_list_defaults(p, "%Dn\n", "");
|
| |
|
| - |
static inline const char *
|
| - |
process_escape(struct sbuf *sbuf, const char *f)
|
| - |
{
|
| - |
f++; /* Eat the \ */
|
| + |
count = 1;
|
| + |
while (pkg_dirs(pkg, &dir) == EPKG_OK) {
|
| + |
if (count > 1)
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
dir, count, PP_D);
|
| |
|
| - |
switch (*f) {
|
| - |
case 'a':
|
| - |
sbuf_putc(sbuf, '\a');
|
| - |
break;
|
| - |
case 'b':
|
| - |
sbuf_putc(sbuf, '\b');
|
| - |
break;
|
| - |
case 'f':
|
| - |
sbuf_putc(sbuf, '\f');
|
| - |
break;
|
| - |
case 'n':
|
| - |
sbuf_putc(sbuf, '\n');
|
| - |
break;
|
| - |
case 't':
|
| - |
sbuf_putc(sbuf, '\t');
|
| - |
break;
|
| - |
case 'v':
|
| - |
sbuf_putc(sbuf, '\v');
|
| - |
break;
|
| - |
case '\'':
|
| - |
sbuf_putc(sbuf, '\'');
|
| - |
break;
|
| - |
case '"':
|
| - |
sbuf_putc(sbuf, '"');
|
| - |
break;
|
| - |
case '\\':
|
| - |
sbuf_putc(sbuf, '\\');
|
| - |
break;
|
| - |
case 'x': /* Hex escape: \xNN */
|
| - |
f++;
|
| - |
f = maybe_read_hex_byte(sbuf, f);
|
| - |
break;
|
| - |
case '0':
|
| - |
case '1':
|
| - |
case '2':
|
| - |
case '3':
|
| - |
case '4':
|
| - |
case '5':
|
| - |
case '6':
|
| - |
case '7': /* all fall through */
|
| - |
f = read_oct_byte(sbuf, f);
|
| - |
break;
|
| - |
default: /* If it's not a recognised escape,
|
| - |
pass it through unchanged */
|
| - |
sbuf_putc(sbuf, '\\');
|
| - |
sbuf_putc(sbuf, *f);
|
| - |
break;
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
dir, count, PP_D);
|
| + |
count++;
|
| + |
}
|
| |
}
|
| - |
|
| - |
return (f);
|
| + |
return (sbuf);
|
| |
}
|
| |
|
| - |
static char *
|
| - |
gen_format(char *buf, size_t buflen, unsigned flags, const char *tail)
|
| + |
/*
|
| + |
* %Dg -- Directory group. TODO: numeric gid
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_directory_group(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| |
{
|
| - |
int bp = 0;
|
| - |
size_t tlen;
|
| - |
|
| - |
/* We need the length of tail plus at least 3 characters '%'
|
| - |
'*' '\0' but maybe as many as 7 '%' '#' '-' '+' '\'' '*'
|
| - |
'\0' */
|
| - |
|
| - |
tlen = strlen(tail);
|
| - |
|
| - |
if (buflen - bp < tlen + 3)
|
| - |
return (NULL);
|
| - |
|
| - |
buf[bp++] = '%';
|
| - |
|
| - |
/* PP_ALTERNATE_FORM1 is not used by regular printf(3) */
|
| - |
|
| - |
if (flags & PP_ALTERNATE_FORM2)
|
| - |
buf[bp++] = '#';
|
| + |
const struct pkg_dir *dir = data;
|
| |
|
| - |
if (flags & PP_LEFT_ALIGN)
|
| - |
buf[bp++] = '-';
|
| - |
else if (flags & PP_ZERO_PAD)
|
| - |
buf[bp++] = '0';
|
| + |
return (string_val(sbuf, pkg_dir_gname(dir), p));
|
| + |
}
|
| |
|
| - |
if (buflen - bp < tlen + 2)
|
| - |
return (NULL);
|
| - |
|
| - |
if (flags & PP_EXPLICIT_PLUS)
|
| - |
buf[bp++] = '+';
|
| - |
else if (flags & PP_SPACE_FOR_PLUS)
|
| - |
buf[bp++] = ' ';
|
| + |
/*
|
| + |
* %Dk -- Directory Keep flag.
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_directory_keepflag(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg_dir *dir = data;
|
| + |
return (bool_val(sbuf, pkg_dir_keep(dir), p));
|
| + |
}
|
| |
|
| - |
if (flags & PP_THOUSANDS_SEP)
|
| - |
buf[bp++] = '\'';
|
| + |
/*
|
| + |
* %Dn -- Directory path name.
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_directory_path(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg_dir *dir = data;
|
| |
|
| - |
if (buflen - bp < tlen + 2)
|
| - |
return (NULL);
|
| + |
return (string_val(sbuf, pkg_dir_path(dir), p));
|
| + |
}
|
| |
|
| - |
/* The effect of 0 meaning 'zero fill' is indisinguishable
|
| - |
from 0 meaning 'a field width of zero' */
|
| + |
/*
|
| + |
* %Dp -- Directory permissions.
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_directory_perms(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg_dir *dir = data;
|
| |
|
| - |
buf[bp++] = '*';
|
| - |
buf[bp] = '\0';
|
| + |
return (mode_val(sbuf, pkg_dir_mode(dir), p));
|
| + |
}
|
| |
|
| - |
strlcat(buf, tail, sizeof(buf));
|
| + |
/*
|
| + |
* %Dt -- Directory Try flag.
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_directory_tryflag(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg_dir *dir = data;
|
| |
|
| - |
return (buf);
|
| + |
return (bool_val(sbuf, pkg_dir_try(dir), p));
|
| |
}
|
| |
|
| - |
|
| + |
/*
|
| + |
* %Du -- Directory user. TODO: numeric UID
|
| + |
*/
|
| |
static struct sbuf *
|
| - |
human_number(struct sbuf *sbuf, int64_t number, struct percent_esc *p)
|
| + |
format_directory_user(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| |
{
|
| - |
double num;
|
| - |
int divisor;
|
| - |
int scale;
|
| - |
bool bin_scale;
|
| + |
const struct pkg_dir *dir = data;
|
| |
|
| - |
#define MAXSCALE 7
|
| + |
return (string_val(sbuf, pkg_dir_uname(dir), p));
|
| + |
}
|
| |
|
| - |
const char bin_pfx[MAXSCALE][3] =
|
| - |
{ "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
|
| - |
const char si_pfx[MAXSCALE][2] =
|
| - |
{ "", "k", "M", "G", "T", "P", "E" };
|
| - |
char format[16];
|
| + |
/*
|
| + |
* %F -- Files. List of filenames (strings) possibly with other
|
| + |
* meta-data. Optionally accepts following per-field format in %{ %|
|
| + |
* %}, where %n is replaced by the filename, %s by the checksum, etc.
|
| + |
* Default %{%Fn\n%|%}
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_files(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg *pkg = data;
|
| |
|
| - |
bin_scale = ((p->flags & PP_ALTERNATE_FORM2) != 0);
|
| + |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| + |
return (list_count(sbuf, pkg_list_count(pkg, PKG_FILES), p));
|
| + |
else {
|
| + |
struct pkg_file *file;
|
| + |
int count;
|
| |
|
| - |
p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);
|
| + |
set_list_defaults(p, "%Fn\n", "");
|
| |
|
| - |
num = number;
|
| - |
divisor = bin_scale ? 1024 : 1000;
|
| + |
count = 1;
|
| + |
while (pkg_files(pkg, &file) == EPKG_OK) {
|
| + |
if (count > 1)
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
file, count, PP_F);
|
| |
|
| - |
for (scale = 0; scale < MAXSCALE; scale++) {
|
| - |
if (num <= divisor)
|
| - |
break;
|
| - |
num /= divisor;
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
file, count, PP_F);
|
| + |
count++;
|
| + |
}
|
| |
}
|
| - |
|
| - |
if (gen_format(format, sizeof(format), p->flags, ".3f %s") == NULL)
|
| - |
return (NULL);
|
| - |
|
| - |
sbuf_printf(sbuf, format, p->width, num,
|
| - |
bin_scale ? bin_pfx[scale] : si_pfx[scale]);
|
| - |
|
| |
return (sbuf);
|
| |
}
|
| |
|
| + |
/*
|
| + |
* %Fg -- File group.
|
| + |
*/
|
| |
static struct sbuf *
|
| - |
string_val(struct sbuf *sbuf, const char *str, struct percent_esc *p)
|
| + |
format_file_group(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
char format[16];
|
| - |
|
| - |
/* The '#' '?' '+' ' ' and '\'' modifiers have no meaning for
|
| - |
strings */
|
| + |
const struct pkg_file *file = data;
|
| |
|
| - |
p->flags &= ~(PP_ALTERNATE_FORM1 |
|
| - |
PP_ALTERNATE_FORM2 |
|
| - |
PP_EXPLICIT_PLUS |
|
| - |
PP_SPACE_FOR_PLUS |
|
| - |
PP_THOUSANDS_SEP);
|
| - |
|
| - |
if (gen_format(format, sizeof(format), p->flags, "s") == NULL)
|
| - |
return (NULL);
|
| - |
|
| - |
sbuf_printf(sbuf, format, p->width, str);
|
| - |
return (sbuf);
|
| - |
}
|
| + |
return (string_val(sbuf, pkg_file_gname(file), p));
|
| + |
}
|
| |
|
| + |
/*
|
| + |
* %Fk -- File Keep flag.
|
| + |
*/
|
| |
static struct sbuf *
|
| - |
int_val(struct sbuf *sbuf, int64_t value, struct percent_esc *p)
|
| + |
format_file_keepflag(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (human_number(sbuf, value, p));
|
| - |
else {
|
| - |
char format[16];
|
| - |
|
| - |
if (gen_format(format, sizeof(format), p->flags, PRId64)
|
| - |
== NULL)
|
| - |
return (NULL);
|
| + |
const struct pkg_file *file = data;
|
| |
|
| - |
sbuf_printf(sbuf, format, p->width, value);
|
| - |
}
|
| - |
return (sbuf);
|
| + |
return (bool_val(sbuf, pkg_file_keep(file), p));
|
| |
}
|
| |
|
| + |
/*
|
| + |
* %Fn -- File path name.
|
| + |
*/
|
| |
static struct sbuf *
|
| - |
bool_val(struct sbuf *sbuf, bool value, struct percent_esc *p)
|
| + |
format_file_path(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
int alternate;
|
| - |
|
| - |
if (p->flags & PP_ALTERNATE_FORM2)
|
| - |
alternate = 2;
|
| - |
else if (p->flags & PP_ALTERNATE_FORM1)
|
| - |
alternate = 1;
|
| - |
else
|
| - |
alternate = 0;
|
| - |
|
| - |
p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);
|
| + |
const struct pkg_file *file = data;
|
| |
|
| - |
return (string_val(sbuf, boolean_str[value][alternate], p));
|
| + |
return (string_val(sbuf, pkg_file_path(file), p));
|
| |
}
|
| |
|
| + |
/*
|
| + |
* %Fp -- File permissions.
|
| + |
*/
|
| |
static struct sbuf *
|
| - |
mode_val(struct sbuf *sbuf, mode_t mode, struct percent_esc *p)
|
| + |
format_file_perms(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
/* Print mode as an octal integer '%o' by default.
|
| - |
* PP_ALTERNATE_FORM2 generates '%#o' pased to regular
|
| - |
* printf(). PP_ALTERNATE_FORM1 will generate drwxr-x--- style
|
| - |
* from strmode(3). */
|
| - |
|
| - |
/* Does the mode include the bits that indicate the inode type? */
|
| - |
|
| - |
if (p->flags & PP_ALTERNATE_FORM1) {
|
| - |
char modebuf[12];
|
| - |
|
| - |
strmode(mode, modebuf);
|
| - |
|
| - |
return (string_val(sbuf, modebuf, p));
|
| - |
} else {
|
| - |
char format[16];
|
| - |
|
| - |
p->flags &= ~(PP_ALTERNATE_FORM1);
|
| - |
|
| - |
if (gen_format(format, sizeof(format), p->flags, PRIo16)
|
| - |
== NULL)
|
| - |
return (NULL);
|
| + |
const struct pkg_file *file = data;
|
| |
|
| - |
sbuf_printf(sbuf, format, p->width, mode);
|
| - |
}
|
| - |
return (sbuf);
|
| + |
return (mode_val(sbuf, pkg_file_mode(file), p));
|
| |
}
|
| |
|
| + |
/*
|
| + |
* %Fs -- File SHA256 Checksum.
|
| + |
*/
|
| |
static struct sbuf *
|
| - |
list_count(struct sbuf *sbuf, int64_t count, struct percent_esc *p)
|
| + |
format_file_sha256(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
/* Convert to 0 or 1 for %?X */
|
| - |
if (p->flags & PP_ALTERNATE_FORM1)
|
| - |
count = (count > 0);
|
| - |
|
| - |
/* Turn off %#X and %?X flags, then print as a normal integer */
|
| - |
p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);
|
| - |
|
| - |
return (int_val(sbuf, count, p));
|
| - |
}
|
| + |
const struct pkg_file *file = data;
|
| |
|
| - |
static struct percent_esc *
|
| - |
set_list_defaults(struct percent_esc *p, const char *item_fmt,
|
| - |
const char *sep_fmt)
|
| - |
{
|
| - |
if (sbuf_len(p->item_fmt) == 0) {
|
| - |
sbuf_cat(p->item_fmt, item_fmt);
|
| - |
sbuf_finish(p->item_fmt);
|
| - |
}
|
| - |
if (sbuf_len(p->sep_fmt) == 0) {
|
| - |
sbuf_cat(p->sep_fmt, sep_fmt);
|
| - |
sbuf_finish(p->sep_fmt);
|
| - |
}
|
| - |
return (p);
|
| + |
return (string_val(sbuf, pkg_file_cksum(file), p));
|
| |
}
|
| |
|
| + |
/*
|
| + |
* %Fu -- File user.
|
| + |
*/
|
| |
static struct sbuf *
|
| - |
iterate_item(struct sbuf *sbuf, const struct pkg *pkg, const void *data,
|
| - |
int count, const char *format, unsigned context)
|
| + |
format_file_user(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const char *f;
|
| + |
const struct pkg_file *file = data;
|
| |
|
| - |
/* Scan the format string and interpret any escapes */
|
| - |
for (f = format; f != '\0'; f++) {
|
| - |
switch(*f) {
|
| - |
case '%':
|
| - |
/* @@@@@@@@@@@@ */
|
| - |
break;
|
| - |
case '\\':
|
| - |
f = process_escape(sbuf, f);
|
| - |
break;
|
| - |
default:
|
| - |
sbuf_putc(sbuf, *f);
|
| - |
break;
|
| - |
}
|
| - |
if (f == NULL) {
|
| - |
sbuf_clear(sbuf);
|
| - |
break; /* Out of memory */
|
| - |
}
|
| - |
}
|
| - |
return (sbuf);
|
| + |
return (string_val(sbuf, pkg_file_uname(file), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* Note: List values -- special behaviour with ? and # modifiers.
|
| - |
* Affects %B %C %D %F %G %L %O %U %d %r
|
| - |
*
|
| - |
* With ? -- Flag values. Boolean. %?X returns 0 if the %X list is
|
| - |
* empty, 1 otherwise.
|
| - |
*
|
| - |
* With # -- Count values. Integer. %#X returns the number of items in
|
| - |
* the %X list.
|
| - |
*/
|
| - |
|
| - |
/*
|
| - |
* %B -- Shared Libraries. List of shlibs required by binaries in the
|
| - |
* pkg. Optionall accepts per-field format in %{ %| %}, where %n is
|
| - |
* replaced by the shlib name. Default %{%Bn\n%|%}
|
| + |
* %G -- Groups. list of string values. Optionally accepts following
|
| + |
* per-field format in %{ %| %} where %Gn will be replaced by each
|
| + |
* groupname or %#Gn by the gid or %Gg by the "gidstr" -- a line from
|
| + |
* /etc/group. Default %{%Gn\n%|%}
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_shlibs(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_groups(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| |
const struct pkg *pkg = data;
|
| |
|
| |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (list_count(sbuf, pkg_list_count(pkg, PKG_SHLIBS), p));
|
| + |
return (list_count(sbuf, pkg_list_count(pkg, PKG_GROUPS), p));
|
| |
else {
|
| - |
struct pkg_shlib *shlib;
|
| + |
struct pkg_group *group;
|
| |
int count;
|
| |
|
| - |
set_list_defaults(p, "%Bn\n", "");
|
| + |
set_list_defaults(p, "%Gn\n", "");
|
| |
|
| |
count = 1;
|
| - |
while (pkg_shlibs(pkg, &shlib) == EPKG_OK) {
|
| + |
while(pkg_groups(pkg, &group) == EPKG_OK) {
|
| |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, shlib, count,
|
| - |
sbuf_data(p->sep_fmt), PP_B);
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
group, count, PP_G);
|
| |
|
| - |
iterate_item(sbuf, pkg, shlib, count,
|
| - |
sbuf_data(p->item_fmt), PP_B);
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
group, count, PP_G);
|
| |
count++;
|
| |
}
|
| |
}
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Dg -- Directory group. TODO: numeric gid
|
| + |
* %On -- Option name.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_directory_group(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| + |
format_option_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_dir *dir = data;
|
| + |
const struct pkg_option *option = data;
|
| |
|
| - |
return (string_val(sbuf, pkg_dir_gname(dir), p));
|
| + |
return (string_val(sbuf, pkg_option_opt(option), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Dk -- Directory Keep flag.
|
| + |
* %Ov -- Option value.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_directory_keepflag(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| + |
format_option_value(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_dir *dir = data;
|
| - |
return (bool_val(sbuf, pkg_dir_keep(dir), p));
|
| + |
const struct pkg_option *option = data;
|
| + |
|
| + |
return (string_val(sbuf, pkg_option_value(option), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Dn -- Directory path name.
|
| + |
* %U -- Users. list of string values. Optionally accepts following
|
| + |
* per-field format in %{ %| %} where %Un will be replaced by each
|
| + |
* username or %#Un by the uid or %Uu by the uidstr -- a line from
|
| + |
* /etc/passwd. Default %{%Un\n%|%}
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_directory_path(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_users(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_dir *dir = data;
|
| + |
const struct pkg *pkg = data;
|
| |
|
| - |
return (string_val(sbuf, pkg_dir_path(dir), p));
|
| + |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| + |
return (list_count(sbuf, pkg_list_count(pkg, PKG_USERS), p));
|
| + |
else {
|
| + |
struct pkg_user *user;
|
| + |
int count;
|
| + |
|
| + |
set_list_defaults(p, "%Un\n", "");
|
| + |
|
| + |
count = 1;
|
| + |
while (pkg_users(pkg, &user) == EPKG_OK) {
|
| + |
if (count > 1)
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
user, count, PP_U);
|
| + |
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
user, count, PP_U);
|
| + |
count++;
|
| + |
}
|
| + |
}
|
| + |
return (sbuf);
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Dp -- Directory permissions.
|
| + |
* %Un -- User name.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_directory_perms(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| + |
format_user_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_dir *dir = data;
|
| + |
const struct pkg_user *user = data;
|
| |
|
| - |
return (mode_val(sbuf, pkg_dir_mode(dir), p));
|
| + |
return (string_val(sbuf, pkg_user_name(user), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Dt -- Directory Try flag.
|
| + |
* %Uu -- User uidstr (one line from /etc/passwd).
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_directory_tryflag(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| + |
format_user_uidstr(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_dir *dir = data;
|
| + |
const struct pkg_user *user = data;
|
| |
|
| - |
return (bool_val(sbuf, pkg_dir_try(dir), p));
|
| + |
return (string_val(sbuf, pkg_user_uidstr(user), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Du -- Directory user. TODO: numeric UID
|
| + |
* %a -- Autoremove flag. boolean. Accepts field-width, left-align.
|
| + |
* Standard form: 0, 1. Alternate form1: no, yes. Alternate form2:
|
| + |
* false, true
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_directory_user(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| + |
format_autoremove(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_dir *dir = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
bool automatic;
|
| |
|
| - |
return (string_val(sbuf, pkg_dir_uname(dir), p));
|
| + |
pkg_get(pkg, PKG_AUTOMATIC, &automatic);
|
| + |
return (bool_val(sbuf, automatic, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %F -- Files. List of filenames (strings) possibly with other
|
| - |
* meta-data. Optionally accepts following per-field format in %{ %|
|
| - |
* %}, where %n is replaced by the filename, %s by the checksum, etc.
|
| - |
* Default %{%Fn\n%|%}
|
| + |
* %c -- Comment. string. Accepts field-width, left-align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_files(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_comment(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
{
|
| + |
const struct pkg *pkg = data;
|
| + |
const char *comment;
|
| + |
|
| + |
pkg_get(pkg, PKG_COMMENT, &comment);
|
| + |
return (string_val(sbuf, comment, p));
|
| + |
}
|
| + |
|
| + |
/*
|
| + |
* %d -- Dependencies. List of pkgs. Can be optionally followed by
|
| + |
* per-field format string in %{ %| %} using any pkg_printf() *scalar*
|
| + |
* formats. Defaults to printing "%dn-%dv\n" for each dependency.
|
| + |
*/
|
| + |
static struct sbuf *
|
| + |
format_dependencies(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| |
const struct pkg *pkg = data;
|
| |
|
| |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (list_count(sbuf, pkg_list_count(pkg, PKG_FILES), p));
|
| + |
return (list_count(sbuf, pkg_list_count(pkg, PKG_DEPS), p));
|
| |
else {
|
| - |
struct pkg_file *file;
|
| + |
struct pkg_dep *dep;
|
| |
int count;
|
| |
|
| - |
set_list_defaults(p, "%Fn\n", "");
|
| + |
set_list_defaults(p, "%dn-%dv\n", "");
|
| |
|
| |
count = 1;
|
| - |
while (pkg_files(pkg, &file) == EPKG_OK) {
|
| + |
while (pkg_deps(pkg, &dep) == EPKG_OK) {
|
| |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, file, count,
|
| - |
sbuf_data(p->sep_fmt), PP_F);
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
dep, count, PP_d);
|
| |
|
| - |
iterate_item(sbuf, pkg, file, count,
|
| - |
sbuf_data(p->item_fmt), PP_F);
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
dep, count, PP_d);
|
| |
count++;
|
| |
}
|
| |
}
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Fg -- File group.
|
| + |
* %dn -- Dependency name or %rn -- Requirement name.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_file_group(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_dependency_name(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_file *file = data;
|
| + |
const struct pkg_dep *dep = data;
|
| |
|
| - |
return (string_val(sbuf, pkg_file_gname(file), p));
|
| + |
return (string_val(sbuf, pkg_dep_name(dep), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Fk -- File Keep flag.
|
| + |
* %do -- Dependency origin or %ro -- Requirement origin.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_file_keepflag(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_dependency_origin(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_file *file = data;
|
| + |
const struct pkg_dep *dep = data;
|
| |
|
| - |
return (bool_val(sbuf, pkg_file_keep(file), p));
|
| + |
return (string_val(sbuf, pkg_dep_origin(dep), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Fn -- File path name.
|
| + |
* %dv -- Dependency version or %rv -- Requirement version.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_file_path(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_dependency_version(struct sbuf *sbuf, const void *data,
|
| + |
struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_file *file = data;
|
| + |
const struct pkg_dep *dep = data;
|
| |
|
| - |
return (string_val(sbuf, pkg_file_path(file), p));
|
| + |
return (string_val(sbuf, pkg_dep_version(dep), p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Fp -- File permissions.
|
| + |
* %i -- Additional info. string. Accepts field-width, left-align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_file_perms(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_add_info(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_file *file = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
const char *info;
|
| |
|
| - |
return (mode_val(sbuf, pkg_file_mode(file), p));
|
| + |
pkg_get(pkg, PKG_INFOS, &info);
|
| + |
return (string_val(sbuf, info, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Fs -- File SHA256 Checksum.
|
| + |
* %k -- Locked flag. boolean. Accepts field-width, left-align.
|
| + |
* Standard form: 0, 1. Alternate form1: no, yes. Alternate form2:
|
| + |
* false, true
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_file_sha256(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_lock_status(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_file *file = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
bool locked;
|
| |
|
| - |
return (string_val(sbuf, pkg_file_cksum(file), p));
|
| + |
pkg_get(pkg, PKG_LOCKED, &locked);
|
| + |
return (bool_val(sbuf, locked, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Fu -- File user.
|
| + |
* %l -- Licence logic. string. Accepts field-width, left-align.
|
| + |
* Standard form: and, or, single. Alternate form 1: &, |, ''.
|
| + |
* Alternate form 2: &&, ||, ==
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_file_user(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_license_logic(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_file *file = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
lic_t licenselogic;
|
| + |
int alternate;
|
| + |
int llogic;
|
| |
|
| - |
return (string_val(sbuf, pkg_file_uname(file), p));
|
| + |
pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic);
|
| + |
|
| + |
switch (licenselogic) {
|
| + |
case LICENSE_SINGLE:
|
| + |
llogic = PP_LIC_SINGLE;
|
| + |
break;
|
| + |
case LICENSE_OR:
|
| + |
llogic = PP_LIC_OR;
|
| + |
break;
|
| + |
case LICENSE_AND:
|
| + |
llogic = PP_LIC_AND;
|
| + |
break;
|
| + |
}
|
| + |
|
| + |
if (p->flags & PP_ALTERNATE_FORM2)
|
| + |
alternate = 2;
|
| + |
else if (p->flags & PP_ALTERNATE_FORM1)
|
| + |
alternate = 1;
|
| + |
else
|
| + |
alternate = 0;
|
| + |
|
| + |
p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);
|
| + |
|
| + |
return (string_val(sbuf, liclog_str[llogic][alternate], p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %G -- Groups. list of string values. Optionally accepts following
|
| - |
* per-field format in %{ %| %} where %Gn will be replaced by each
|
| - |
* groupname or %#Gn by the gid or %Gg by the "gidstr" -- a line from
|
| - |
* /etc/group. Default %{%Gn\n%|%}
|
| + |
* %m -- Maintainer e-mail address. string. Accepts field-width, left-align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_groups(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_maintainer(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| |
const struct pkg *pkg = data;
|
| + |
const char *maintainer;
|
| |
|
| - |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (list_count(sbuf, pkg_list_count(pkg, PKG_GROUPS), p));
|
| - |
else {
|
| - |
struct pkg_group *group;
|
| - |
int count;
|
| - |
|
| - |
set_list_defaults(p, "%Gn\n", "");
|
| - |
|
| - |
count = 1;
|
| - |
while(pkg_groups(pkg, &group) == EPKG_OK) {
|
| - |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, group, count,
|
| - |
sbuf_data(p->sep_fmt), PP_G);
|
| - |
|
| - |
iterate_item(sbuf, pkg, group, count,
|
| - |
sbuf_data(p->item_fmt), PP_G);
|
| - |
count++;
|
| - |
}
|
| - |
}
|
| - |
return (sbuf);
|
| + |
pkg_get(pkg, PKG_MAINTAINER, &maintainer);
|
| + |
return (string_val(sbuf, maintainer, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Gg -- Group 'gidstr' (one line from /etc/group).
|
| + |
* %n -- Package name. string. Accepts field-width, left-align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_group_gidstr(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_group *group = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
const char *name;
|
| |
|
| - |
return (string_val(sbuf, pkg_group_gidstr(group), p));
|
| + |
pkg_get(pkg, PKG_NAME, &name);
|
| + |
return (string_val(sbuf, name, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Gn -- Group name.
|
| + |
* %o -- Package origin. string. Accepts field-width, left-align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_group_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_origin(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_group *group = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
const char *origin;
|
| |
|
| - |
return (string_val(sbuf, pkg_group_name(group), p));
|
| + |
pkg_get(pkg, PKG_ORIGIN, &origin);
|
| + |
return (string_val(sbuf, origin, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %I -- Row counter (integer*). Usually used only in per-field format.
|
| + |
* %p -- Installation prefix. string. Accepts field-width, left-align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_row_counter(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_prefix(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const int *counter = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
const char *prefix;
|
| |
|
| - |
return (int_val(sbuf, *counter, p));
|
| + |
pkg_get(pkg, PKG_PREFIX, &prefix);
|
| + |
return (string_val(sbuf, prefix, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %L -- Licences. List of string values. Optionally accepts
|
| - |
* following per-field format in %{ %| %} where %Ln is replaced by the
|
| - |
* license name and %l by the license logic. Default %{%n%| %l %}
|
| + |
* %r -- Requirements. List of pkgs. Can be optionally followed by
|
| + |
* per-field format string in %{ %| %} using any pkg_printf() *scalar*
|
| + |
* formats. Defaults to printing "%{%rn-%rv\n%|%}" for each dependency.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_licenses(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_requirements(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| |
const struct pkg *pkg = data;
|
| |
|
| |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (list_count(sbuf, pkg_list_count(pkg, PKG_LICENSES),
|
| - |
p));
|
| + |
return(list_count(sbuf, pkg_list_count(pkg, PKG_RDEPS), p));
|
| |
else {
|
| - |
struct pkg_license *lic;
|
| - |
int count;
|
| - |
lic_t license_logic;
|
| - |
|
| + |
struct pkg_dep *req;
|
| + |
int count;
|
| |
|
| - |
set_list_defaults(p, "%Ln", " %l ");
|
| - |
pkg_get(pkg, PKG_LICENSE_LOGIC, &license_logic);
|
| + |
set_list_defaults(p, "%rn-%rv\n", "");
|
| |
|
| |
count = 1;
|
| - |
while (pkg_licenses(pkg, &lic) == EPKG_OK) {
|
| + |
while (pkg_rdeps(pkg, &req) == EPKG_OK) {
|
| |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, lic, count,
|
| - |
sbuf_data(p->sep_fmt), PP_L);
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
|
| + |
req, count, PP_r);
|
| |
|
| - |
iterate_item(sbuf, pkg, lic, count,
|
| - |
sbuf_data(p->item_fmt), PP_L);
|
| + |
iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
|
| + |
req, count, PP_r);
|
| |
count++;
|
| |
}
|
| |
}
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Ln -- License name.
|
| + |
* %s -- Size of installed package. integer. Accepts field-width,
|
| + |
* left-align, zero-fill, space-for-plus, explicit-plus and
|
| + |
* alternate-form. Alternate form is a humanized number using decimal
|
| + |
* exponents (k, M, G). Alternate form 2, ditto, but using binary
|
| + |
* scale prefixes (ki, Mi, Gi etc.)
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_license_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_flatsize(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_license *license = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
int64_t flatsize;
|
| |
|
| - |
return (string_val(sbuf, pkg_license_name(license), p));
|
| + |
pkg_get(pkg, PKG_FLATSIZE, &flatsize);
|
| + |
return (int_val(sbuf, flatsize, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %M -- Pkg message. string. Accepts field-width, left-align
|
| + |
* %t -- Installation timestamp (Unix time). integer. Accepts
|
| + |
* field-width, left-align. Can be followed by optional strftime
|
| + |
* format string in %{ %}. Default is to print seconds-since-epoch as
|
| + |
* an integer applying our integer format modifiers.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_message(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_install_tstamp(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| |
const struct pkg *pkg = data;
|
| - |
const char *message;
|
| - |
|
| - |
pkg_get(pkg, PKG_MESSAGE, &message);
|
| - |
return (string_val(sbuf, message, p));
|
| - |
}
|
| + |
int64_t timestamp;
|
| |
|
| - |
/*
|
| - |
* %O -- Options. list of {option,value} tuples. Optionally accepts
|
| - |
* following per-field format in %{ %| %}, where %On is replaced by the
|
| - |
* option name and %Ov by the value. Default %{%On %Ov\n%|%}
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_options(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg *pkg = data;
|
| + |
pkg_get(pkg, PKG_TIME, ×tamp);
|
| |
|
| - |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (list_count(sbuf, pkg_list_count(pkg, PKG_OPTIONS), p));
|
| + |
if (sbuf_len(p->item_fmt) == 0)
|
| + |
return (int_val(sbuf, timestamp, p));
|
| |
else {
|
| - |
struct pkg_option *opt;
|
| - |
int count;
|
| - |
|
| - |
set_list_defaults(p, "%On %Ov\n", "");
|
| - |
|
| - |
count = 1;
|
| - |
while (pkg_options(pkg, &opt) == EPKG_OK) {
|
| - |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, opt, count,
|
| - |
sbuf_data(p->sep_fmt), PP_O);
|
| + |
char buf[1024];
|
| |
|
| - |
iterate_item(sbuf, pkg, opt, count,
|
| - |
sbuf_data(p->item_fmt), PP_O);
|
| - |
count++;
|
| - |
}
|
| + |
strftime(buf, sizeof(buf), sbuf_data(p->item_fmt),
|
| + |
localtime(×tamp));
|
| + |
sbuf_cat(sbuf, buf);
|
| |
}
|
| |
return (sbuf);
|
| |
}
|
| |
|
| |
/*
|
| - |
* %On -- Option name.
|
| + |
* %v -- Package version. string. Accepts field width, left align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_option_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_version(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_option *option = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
const char *version;
|
| |
|
| - |
return (string_val(sbuf, pkg_option_opt(option), p));
|
| + |
pkg_get(pkg, PKG_VERSION, &version);
|
| + |
return (string_val(sbuf, version, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Ov -- Option value.
|
| + |
* %w -- Home page URL. string. Accepts field width, left align
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_option_value(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_home_url(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_option *option = data;
|
| + |
const struct pkg *pkg = data;
|
| + |
const char *url;
|
| |
|
| - |
return (string_val(sbuf, pkg_option_value(option), p));
|
| + |
pkg_get(pkg, PKG_WWW, &url);
|
| + |
return (string_val(sbuf, url, p));
|
| |
}
|
| |
|
| |
/*
|
| - |
* %U -- Users. list of string values. Optionally accepts following
|
| - |
* per-field format in %{ %| %} where %Un will be replaced by each
|
| - |
* username or %#Un by the uid or %Uu by the uidstr -- a line from
|
| - |
* /etc/passwd. Default %{%Un\n%|%}
|
| + |
* %% -- Output a literal '%' character
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_users(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_literal_percent(struct sbuf *sbuf, __unused const void *data,
|
| + |
__unused struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
|
| - |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (list_count(sbuf, pkg_list_count(pkg, PKG_USERS), p));
|
| - |
else {
|
| - |
struct pkg_user *user;
|
| - |
int count;
|
| - |
|
| - |
set_list_defaults(p, "%Un\n", "");
|
| - |
|
| - |
count = 1;
|
| - |
while (pkg_users(pkg, &user) == EPKG_OK) {
|
| - |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, user, count,
|
| - |
sbuf_data(p->sep_fmt), PP_U);
|
| - |
|
| - |
iterate_item(sbuf, pkg, user, count,
|
| - |
sbuf_data(p->item_fmt), PP_U);
|
| - |
count++;
|
| - |
}
|
| - |
}
|
| + |
sbuf_putc(sbuf, '%');
|
| |
return (sbuf);
|
| |
}
|
| |
|
| |
/*
|
| - |
* %Un -- User name.
|
| + |
* Unknown format code -- return NULL to signal upper layers to pass
|
| + |
* the text through unchanged.
|
| |
*/
|
| |
static struct sbuf *
|
| - |
format_user_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
format_unknown(struct sbuf *sbuf, __unused const void *data,
|
| + |
__unused struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg_user *user = data;
|
| - |
|
| - |
return (string_val(sbuf, pkg_user_name(user), p));
|
| + |
sbuf_putc(sbuf, '%');
|
| + |
return (NULL);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %Uu -- User uidstr (one line from /etc/passwd).
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_user_uidstr(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg_user *user = data;
|
| + |
/* -------------------------------------------------------------- */
|
| |
|
| - |
return (string_val(sbuf, pkg_user_uidstr(user), p));
|
| + |
static void
|
| + |
free_percent_esc(struct percent_esc *p)
|
| + |
{
|
| + |
if (p->item_fmt)
|
| + |
sbuf_delete(p->item_fmt);
|
| + |
if (p->sep_fmt)
|
| + |
sbuf_delete(p->sep_fmt);
|
| + |
free(p);
|
| + |
return;
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %a -- Autoremove flag. boolean. Accepts field-width, left-align.
|
| - |
* Standard form: 0, 1. Alternate form1: no, yes. Alternate form2:
|
| - |
* false, true
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_autoremove(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
static struct percent_esc *
|
| + |
new_percent_esc(struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
bool automatic;
|
| - |
|
| - |
pkg_get(pkg, PKG_AUTOMATIC, &automatic);
|
| - |
return (bool_val(sbuf, automatic, p));
|
| + |
/* reset or alloc new */
|
| + |
if (p == NULL) {
|
| + |
p = calloc(1, sizeof(struct percent_esc));
|
| + |
if (p != NULL) {
|
| + |
p->item_fmt = sbuf_new_auto();
|
| + |
p->sep_fmt = sbuf_new_auto();
|
| + |
}
|
| + |
if (p == NULL || p->item_fmt == NULL || p->sep_fmt == NULL) {
|
| + |
/* out of memory */
|
| + |
free_percent_esc(p);
|
| + |
return NULL;
|
| + |
}
|
| + |
} else {
|
| + |
p->flags = 0;
|
| + |
p->width = 0;
|
| + |
sbuf_clear(p->item_fmt);
|
| + |
sbuf_clear(p->sep_fmt);
|
| + |
p->fmt_code = '\0';
|
| + |
}
|
| + |
return (p);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %c -- Comment. string. Accepts field-width, left-align
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_comment(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
static char *
|
| + |
gen_format(char *buf, size_t buflen, unsigned flags, const char *tail)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *comment;
|
| + |
int bp = 0;
|
| + |
size_t tlen;
|
| |
|
| - |
pkg_get(pkg, PKG_COMMENT, &comment);
|
| - |
return (string_val(sbuf, comment, p));
|
| - |
}
|
| + |
/* We need the length of tail plus at least 3 characters '%'
|
| + |
'*' '\0' but maybe as many as 7 '%' '#' '-' '+' '\'' '*'
|
| + |
'\0' */
|
| |
|
| - |
/*
|
| - |
* %d -- Dependencies. List of pkgs. Can be optionally followed by
|
| - |
* per-field format string in %{ %| %} using any pkg_printf() *scalar*
|
| - |
* formats. Defaults to printing "%dn-%dv\n" for each dependency.
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_dependencies(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg *pkg = data;
|
| + |
tlen = strlen(tail);
|
| |
|
| - |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return (list_count(sbuf, pkg_list_count(pkg, PKG_DEPS), p));
|
| - |
else {
|
| - |
struct pkg_dep *dep;
|
| - |
int count;
|
| + |
if (buflen - bp < tlen + 3)
|
| + |
return (NULL);
|
| |
|
| - |
set_list_defaults(p, "%dn-%dv\n", "");
|
| + |
buf[bp++] = '%';
|
| |
|
| - |
count = 1;
|
| - |
while (pkg_deps(pkg, &dep) == EPKG_OK) {
|
| - |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, dep, count,
|
| - |
sbuf_data(p->sep_fmt), PP_d);
|
| + |
/* PP_ALTERNATE_FORM1 is not used by regular printf(3) */
|
| |
|
| - |
iterate_item(sbuf, pkg, dep, count,
|
| - |
sbuf_data(p->item_fmt), PP_d);
|
| - |
count++;
|
| - |
}
|
| - |
}
|
| - |
return (sbuf);
|
| - |
}
|
| + |
if (flags & PP_ALTERNATE_FORM2)
|
| + |
buf[bp++] = '#';
|
| |
|
| - |
/*
|
| - |
* %dn -- Dependency name or %rn -- Requirement name.
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_dependency_name(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg_dep *dep = data;
|
| + |
if (flags & PP_LEFT_ALIGN)
|
| + |
buf[bp++] = '-';
|
| + |
else if (flags & PP_ZERO_PAD)
|
| + |
buf[bp++] = '0';
|
| |
|
| - |
return (string_val(sbuf, pkg_dep_name(dep), p));
|
| - |
}
|
| + |
if (buflen - bp < tlen + 2)
|
| + |
return (NULL);
|
| + |
|
| + |
if (flags & PP_EXPLICIT_PLUS)
|
| + |
buf[bp++] = '+';
|
| + |
else if (flags & PP_SPACE_FOR_PLUS)
|
| + |
buf[bp++] = ' ';
|
| |
|
| - |
/*
|
| - |
* %do -- Dependency origin or %ro -- Requirement origin.
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_dependency_origin(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg_dep *dep = data;
|
| + |
if (flags & PP_THOUSANDS_SEP)
|
| + |
buf[bp++] = '\'';
|
| |
|
| - |
return (string_val(sbuf, pkg_dep_origin(dep), p));
|
| - |
}
|
| + |
if (buflen - bp < tlen + 2)
|
| + |
return (NULL);
|
| |
|
| - |
/*
|
| - |
* %dv -- Dependency version or %rv -- Requirement version.
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_dependency_version(struct sbuf *sbuf, const void *data,
|
| - |
struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg_dep *dep = data;
|
| + |
/* The effect of 0 meaning 'zero fill' is indisinguishable
|
| + |
from 0 meaning 'a field width of zero' */
|
| |
|
| - |
return (string_val(sbuf, pkg_dep_version(dep), p));
|
| - |
}
|
| + |
buf[bp++] = '*';
|
| + |
buf[bp] = '\0';
|
| |
|
| - |
/*
|
| - |
* %i -- Additional info. string. Accepts field-width, left-align
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_add_info(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *info;
|
| + |
strlcat(buf, tail, sizeof(buf));
|
| |
|
| - |
pkg_get(pkg, PKG_INFOS, &info);
|
| - |
return (string_val(sbuf, info, p));
|
| + |
return (buf);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %k -- Locked flag. boolean. Accepts field-width, left-align.
|
| - |
* Standard form: 0, 1. Alternate form1: no, yes. Alternate form2:
|
| - |
* false, true
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_lock_status(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
bool locked;
|
| - |
|
| - |
pkg_get(pkg, PKG_LOCKED, &locked);
|
| - |
return (bool_val(sbuf, locked, p));
|
| - |
}
|
| |
|
| - |
/*
|
| - |
* %l -- Licence logic. string. Accepts field-width, left-align.
|
| - |
* Standard form: and, or, single. Alternate form 1: &, |, ''.
|
| - |
* Alternate form 2: &&, ||, ==
|
| - |
*/
|
| |
static struct sbuf *
|
| - |
format_license_logic(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
human_number(struct sbuf *sbuf, int64_t number, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
lic_t licenselogic;
|
| - |
int alternate;
|
| - |
int llogic;
|
| + |
double num;
|
| + |
int divisor;
|
| + |
int scale;
|
| + |
bool bin_scale;
|
| |
|
| - |
pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic);
|
| + |
#define MAXSCALE 7
|
| |
|
| - |
switch (licenselogic) {
|
| - |
case LICENSE_SINGLE:
|
| - |
llogic = PP_LIC_SINGLE;
|
| - |
break;
|
| - |
case LICENSE_OR:
|
| - |
llogic = PP_LIC_OR;
|
| - |
break;
|
| - |
case LICENSE_AND:
|
| - |
llogic = PP_LIC_AND;
|
| - |
break;
|
| - |
}
|
| + |
const char bin_pfx[MAXSCALE][3] =
|
| + |
{ "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
|
| + |
const char si_pfx[MAXSCALE][2] =
|
| + |
{ "", "k", "M", "G", "T", "P", "E" };
|
| + |
char format[16];
|
| |
|
| - |
if (p->flags & PP_ALTERNATE_FORM2)
|
| - |
alternate = 2;
|
| - |
else if (p->flags & PP_ALTERNATE_FORM1)
|
| - |
alternate = 1;
|
| - |
else
|
| - |
alternate = 0;
|
| + |
bin_scale = ((p->flags & PP_ALTERNATE_FORM2) != 0);
|
| |
|
| |
p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);
|
| |
|
| - |
return (string_val(sbuf, liclog_str[llogic][alternate], p));
|
| - |
}
|
| + |
num = number;
|
| + |
divisor = bin_scale ? 1024 : 1000;
|
| |
|
| - |
/*
|
| - |
* %m -- Maintainer e-mail address. string. Accepts field-width, left-align
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_maintainer(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *maintainer;
|
| + |
for (scale = 0; scale < MAXSCALE; scale++) {
|
| + |
if (num <= divisor)
|
| + |
break;
|
| + |
num /= divisor;
|
| + |
}
|
| |
|
| - |
pkg_get(pkg, PKG_MAINTAINER, &maintainer);
|
| - |
return (string_val(sbuf, maintainer, p));
|
| - |
}
|
| + |
if (gen_format(format, sizeof(format), p->flags, ".3f %s") == NULL)
|
| + |
return (NULL);
|
| |
|
| - |
/*
|
| - |
* %n -- Package name. string. Accepts field-width, left-align
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *name;
|
| + |
sbuf_printf(sbuf, format, p->width, num,
|
| + |
bin_scale ? bin_pfx[scale] : si_pfx[scale]);
|
| |
|
| - |
pkg_get(pkg, PKG_NAME, &name);
|
| - |
return (string_val(sbuf, name, p));
|
| + |
return (sbuf);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %o -- Package origin. string. Accepts field-width, left-align
|
| - |
*/
|
| |
static struct sbuf *
|
| - |
format_origin(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
string_val(struct sbuf *sbuf, const char *str, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *origin;
|
| + |
char format[16];
|
| |
|
| - |
pkg_get(pkg, PKG_ORIGIN, &origin);
|
| - |
return (string_val(sbuf, origin, p));
|
| - |
}
|
| + |
/* The '#' '?' '+' ' ' and '\'' modifiers have no meaning for
|
| + |
strings */
|
| |
|
| - |
/*
|
| - |
* %p -- Installation prefix. string. Accepts field-width, left-align
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_prefix(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| - |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *prefix;
|
| + |
p->flags &= ~(PP_ALTERNATE_FORM1 |
|
| + |
PP_ALTERNATE_FORM2 |
|
| + |
PP_EXPLICIT_PLUS |
|
| + |
PP_SPACE_FOR_PLUS |
|
| + |
PP_THOUSANDS_SEP);
|
| |
|
| - |
pkg_get(pkg, PKG_PREFIX, &prefix);
|
| - |
return (string_val(sbuf, prefix, p));
|
| + |
if (gen_format(format, sizeof(format), p->flags, "s") == NULL)
|
| + |
return (NULL);
|
| + |
|
| + |
sbuf_printf(sbuf, format, p->width, str);
|
| + |
return (sbuf);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %r -- Requirements. List of pkgs. Can be optionally followed by
|
| - |
* per-field format string in %{ %| %} using any pkg_printf() *scalar*
|
| - |
* formats. Defaults to printing "%{%rn-%rv\n%|%}" for each dependency.
|
| - |
*/
|
| |
static struct sbuf *
|
| - |
format_requirements(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
int_val(struct sbuf *sbuf, int64_t value, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
|
| |
if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
|
| - |
return(list_count(sbuf, pkg_list_count(pkg, PKG_RDEPS), p));
|
| + |
return (human_number(sbuf, value, p));
|
| |
else {
|
| - |
struct pkg_dep *req;
|
| - |
int count;
|
| - |
|
| - |
set_list_defaults(p, "%rn-%rv\n", "");
|
| + |
char format[16];
|
| |
|
| - |
count = 1;
|
| - |
while (pkg_rdeps(pkg, &req) == EPKG_OK) {
|
| - |
if (count > 1)
|
| - |
iterate_item(sbuf, pkg, req, count,
|
| - |
sbuf_data(p->sep_fmt), PP_r);
|
| + |
if (gen_format(format, sizeof(format), p->flags, PRId64)
|
| + |
== NULL)
|
| + |
return (NULL);
|
| |
|
| - |
iterate_item(sbuf, pkg, req, count,
|
| - |
sbuf_data(p->item_fmt), PP_r);
|
| - |
count++;
|
| - |
}
|
| + |
sbuf_printf(sbuf, format, p->width, value);
|
| |
}
|
| |
return (sbuf);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %s -- Size of installed package. integer. Accepts field-width,
|
| - |
* left-align, zero-fill, space-for-plus, explicit-plus and
|
| - |
* alternate-form. Alternate form is a humanized number using decimal
|
| - |
* exponents (k, M, G). Alternate form 2, ditto, but using binary
|
| - |
* scale prefixes (ki, Mi, Gi etc.)
|
| - |
*/
|
| |
static struct sbuf *
|
| - |
format_flatsize(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
bool_val(struct sbuf *sbuf, bool value, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
int64_t flatsize;
|
| + |
int alternate;
|
| |
|
| - |
pkg_get(pkg, PKG_FLATSIZE, &flatsize);
|
| - |
return (int_val(sbuf, flatsize, p));
|
| + |
if (p->flags & PP_ALTERNATE_FORM2)
|
| + |
alternate = 2;
|
| + |
else if (p->flags & PP_ALTERNATE_FORM1)
|
| + |
alternate = 1;
|
| + |
else
|
| + |
alternate = 0;
|
| + |
|
| + |
p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);
|
| + |
|
| + |
return (string_val(sbuf, boolean_str[value][alternate], p));
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %t -- Installation timestamp (Unix time). integer. Accepts
|
| - |
* field-width, left-align. Can be followed by optional strftime
|
| - |
* format string in %{ %}. Default is to print seconds-since-epoch as
|
| - |
* an integer applying our integer format modifiers.
|
| - |
*/
|
| |
static struct sbuf *
|
| - |
format_install_tstamp(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
mode_val(struct sbuf *sbuf, mode_t mode, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
int64_t timestamp;
|
| + |
/* Print mode as an octal integer '%o' by default.
|
| + |
* PP_ALTERNATE_FORM2 generates '%#o' pased to regular
|
| + |
* printf(). PP_ALTERNATE_FORM1 will generate drwxr-x--- style
|
| + |
* from strmode(3). */
|
| |
|
| - |
pkg_get(pkg, PKG_TIME, ×tamp);
|
| + |
/* Does the mode include the bits that indicate the inode type? */
|
| |
|
| - |
if (sbuf_len(p->item_fmt) == 0)
|
| - |
return (int_val(sbuf, timestamp, p));
|
| - |
else {
|
| - |
char buf[1024];
|
| + |
if (p->flags & PP_ALTERNATE_FORM1) {
|
| + |
char modebuf[12];
|
| |
|
| - |
strftime(buf, sizeof(buf), sbuf_data(p->item_fmt),
|
| - |
localtime(×tamp));
|
| - |
sbuf_cat(sbuf, buf);
|
| + |
strmode(mode, modebuf);
|
| + |
|
| + |
return (string_val(sbuf, modebuf, p));
|
| + |
} else {
|
| + |
char format[16];
|
| + |
|
| + |
p->flags &= ~(PP_ALTERNATE_FORM1);
|
| + |
|
| + |
if (gen_format(format, sizeof(format), p->flags, PRIo16)
|
| + |
== NULL)
|
| + |
return (NULL);
|
| + |
|
| + |
sbuf_printf(sbuf, format, p->width, mode);
|
| |
}
|
| |
return (sbuf);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %v -- Package version. string. Accepts field width, left align
|
| - |
*/
|
| |
static struct sbuf *
|
| - |
format_version(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
list_count(struct sbuf *sbuf, int64_t count, struct percent_esc *p)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *version;
|
| + |
/* Convert to 0 or 1 for %?X */
|
| + |
if (p->flags & PP_ALTERNATE_FORM1)
|
| + |
count = (count > 0);
|
| |
|
| - |
pkg_get(pkg, PKG_VERSION, &version);
|
| - |
return (string_val(sbuf, version, p));
|
| + |
/* Turn off %#X and %?X flags, then print as a normal integer */
|
| + |
p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);
|
| + |
|
| + |
return (int_val(sbuf, count, p));
|
| + |
}
|
| + |
|
| + |
static struct percent_esc *
|
| + |
set_list_defaults(struct percent_esc *p, const char *item_fmt,
|
| + |
const char *sep_fmt)
|
| + |
{
|
| + |
if (sbuf_len(p->item_fmt) == 0) {
|
| + |
sbuf_cat(p->item_fmt, item_fmt);
|
| + |
sbuf_finish(p->item_fmt);
|
| + |
}
|
| + |
if (sbuf_len(p->sep_fmt) == 0) {
|
| + |
sbuf_cat(p->sep_fmt, sep_fmt);
|
| + |
sbuf_finish(p->sep_fmt);
|
| + |
}
|
| + |
return (p);
|
| |
}
|
| |
|
| - |
/*
|
| - |
* %w -- Home page URL. string. Accepts field width, left align
|
| - |
*/
|
| |
static struct sbuf *
|
| - |
format_home_url(struct sbuf *sbuf, const void *data, struct percent_esc *p)
|
| + |
iterate_item(struct sbuf *sbuf, const struct pkg *pkg, const char *format,
|
| + |
const void *data, int count, unsigned context)
|
| |
{
|
| - |
const struct pkg *pkg = data;
|
| - |
const char *url;
|
| - |
|
| - |
pkg_get(pkg, PKG_WWW, &url);
|
| - |
return (string_val(sbuf, url, p));
|
| - |
}
|
| + |
const char *f;
|
| |
|
| - |
/*
|
| - |
* %% -- Output a literal '%' character
|
| - |
*/
|
| - |
static struct sbuf *
|
| - |
format_literal_percent(struct sbuf *sbuf, __unused const void *data,
|
| - |
__unused struct percent_esc *p)
|
| - |
{
|
| - |
sbuf_putc(sbuf, '%');
|
| + |
/* Scan the format string and interpret any escapes */
|
| + |
for (f = format; f != '\0'; f++) {
|
| + |
switch(*f) {
|
| + |
case '%':
|
| + |
f = process_format_trailer(sbuf, f, pkg, data, count, context);
|
| + |
break;
|
| + |
case '\\':
|
| + |
f = process_escape(sbuf, f);
|
| + |
break;
|
| + |
default:
|
| + |
sbuf_putc(sbuf, *f);
|
| + |
break;
|
| + |
}
|
| + |
if (f == NULL) {
|
| + |
sbuf_clear(sbuf);
|
| + |
break; /* Out of memory */
|
| + |
}
|
| + |
}
|
| |
return (sbuf);
|
| |
}
|
| |
|
| - |
static const char *
|
| - |
parse_escape(const char *f, unsigned context, struct percent_esc *p)
|
| + |
static inline const char *
|
| + |
field_modifier(const char *f, struct percent_esc *p)
|
| |
{
|
| - |
bool done = false;
|
| - |
fmt_code_t fmt_code;
|
| - |
|
| - |
f++; /* Eat the % */
|
| + |
bool done;
|
| |
|
| |
/* Field modifiers, if any:
|
| |
'#' alternate form
|
| |
case '+':
|
| |
p->flags |= PP_EXPLICIT_PLUS;
|
| |
break;
|
| - |
case ' ':
|
| - |
p->flags |= PP_SPACE_FOR_PLUS;
|
| + |
case ' ':
|
| + |
p->flags |= PP_SPACE_FOR_PLUS;
|
| + |
break;
|
| + |
case '0':
|
| + |
p->flags |= PP_ZERO_PAD;
|
| + |
break;
|
| + |
case '\'':
|
| + |
p->flags |= PP_THOUSANDS_SEP;
|
| + |
break;
|
| + |
default:
|
| + |
done = true;
|
| + |
break;
|
| + |
}
|
| + |
if (!done)
|
| + |
f++;
|
| + |
}
|
| + |
return (f);
|
| + |
}
|
| + |
|
| + |
static inline const char *
|
| + |
field_width(const char *f, struct percent_esc *p)
|
| + |
{
|
| + |
bool done;
|
| + |
|
| + |
/* Field width, if any -- some number of decimal digits.
|
| + |
Note: field width set to zero could be interpreted as using
|
| + |
0 to request zero padding: it doesn't matter which -- the
|
| + |
result on output is exactly the same. */
|
| + |
|
| + |
done = false;
|
| + |
while (!done) {
|
| + |
switch(*f) {
|
| + |
case '0':
|
| + |
p->width = p->width * 10 + 0;
|
| + |
break;
|
| + |
case '1':
|
| + |
p->width = p->width * 10 + 1;
|
| + |
break;
|
| + |
case '2':
|
| + |
p->width = p->width * 10 + 2;
|
| + |
break;
|
| + |
case '3':
|
| + |
p->width = p->width * 10 + 3;
|
| + |
break;
|
| + |
case '4':
|
| + |
p->width = p->width * 10 + 4;
|
| + |
break;
|
| + |
case '5':
|
| + |
p->width = p->width * 10 + 5;
|
| + |
break;
|
| + |
case '6':
|
| + |
p->width = p->width * 10 + 6;
|
| + |
break;
|
| + |
case '7':
|
| + |
p->width = p->width * 10 + 7;
|
| + |
break;
|
| + |
case '8':
|
| + |
p->width = p->width * 10 + 8;
|
| + |
break;
|
| + |
case '9':
|
| + |
p->width = p->width * 10 + 9;
|
| + |
break;
|
| + |
default:
|
| + |
done = true;
|
| + |
break;
|
| + |
}
|
| + |
if (!done)
|
| + |
f++;
|
| + |
}
|
| + |
return (f);
|
| + |
}
|
| + |
|
| + |
static inline const char *
|
| + |
format_trailer(const char *f, struct percent_esc *p)
|
| + |
{
|
| + |
|
| + |
/* is the trailer even present? */
|
| + |
|
| + |
if (f[0] == '%' && f[1] == '{') {
|
| + |
bool sep = false;
|
| + |
bool done = false;
|
| + |
const char *f1;
|
| + |
const char *f2;
|
| + |
|
| + |
f1 = f + 2;
|
| + |
|
| + |
for (f2 = f1; *f2 != '\0'; f2++) {
|
| + |
if (f2[0] == '%' && ( f2[1] == '}' || f2[1] == '|')) {
|
| + |
if (f2[1] == '|')
|
| + |
sep = true;
|
| + |
else
|
| + |
done = true;
|
| + |
f1 = f2 + 2;
|
| + |
break;
|
| + |
}
|
| + |
sbuf_putc(p->item_fmt, *f2);
|
| + |
}
|
| + |
|
| + |
|
| + |
if (sep) {
|
| + |
sep = false;
|
| + |
|
| + |
for (f2 = f1; *f2 != '\0'; f2++) {
|
| + |
if (f2[0] == '%' && f2[1] == '}') {
|
| + |
done = true;
|
| + |
f1 = f2 + 2;
|
| + |
break;
|
| + |
}
|
| + |
sbuf_putc(p->sep_fmt, *f2);
|
| + |
}
|
| + |
|
| + |
}
|
| + |
|
| + |
if (done) {
|
| + |
sbuf_finish(p->item_fmt);
|
| + |
sbuf_finish(p->sep_fmt);
|
| + |
f = f1;
|
| + |
} else {
|
| + |
sbuf_clear(p->item_fmt);
|
| + |
sbuf_clear(p->sep_fmt);
|
| + |
}
|
| + |
}
|
| + |
|
| + |
return (f);
|
| + |
}
|
| + |
|
| + |
static const char *
|
| + |
parse_format(const char *f, unsigned context, struct percent_esc *p)
|
| + |
{
|
| + |
bool done;
|
| + |
fmt_code_t fmt_code;
|
| + |
|
| + |
f++; /* Eat the % */
|
| + |
|
| + |
f = field_modifier(f, p);
|
| + |
|
| + |
f = field_width(f, p);
|
| + |
|
| + |
/* The next character or two will be a format code -- look
|
| + |
these up in the fmt table to make sure they are allowed in
|
| + |
context. This could be optimized since the format codes
|
| + |
are arranged alphabetically in the fmt[] array. */
|
| + |
|
| + |
done = false;
|
| + |
for (fmt_code = PP_PKG_SHLIBS; fmt_code < PP_END_MARKER; fmt_code++) {
|
| + |
if ((fmt[fmt_code].context & context) == context &&
|
| + |
fmt[fmt_code].fmt_main == f[0] &&
|
| + |
(fmt[fmt_code].fmt_sub == '\0' ||
|
| + |
fmt[fmt_code].fmt_sub == f[1])) {
|
| + |
p->fmt_code = fmt_code;
|
| + |
f++;
|
| + |
if (fmt[fmt_code].fmt_sub != '\0')
|
| + |
f++;
|
| + |
done = true;
|
| + |
break;
|
| + |
}
|
| + |
}
|
| + |
|
| + |
/* Not a recognised format code -- mark for pass through */
|
| + |
|
| + |
if (!done) {
|
| + |
p->fmt_code = PP_UNKNOWN;
|
| + |
return (f); /* Caller will rewind */
|
| + |
}
|
| + |
|
| + |
/* Does this format take a trailing list item/separator format
|
| + |
like %{...%|...%} ? It's only the list-valued items that
|
| + |
do, and they are *only* valid in PP_PKG context. Also,
|
| + |
they only take the trailing stuff in the absence of %?X or
|
| + |
%#X modifiers. */
|
| + |
|
| + |
if ((fmt[p->fmt_code].context & PP_PKG) == PP_PKG ||
|
| + |
(p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) != 0)
|
| + |
return (f);
|
| + |
|
| + |
f = format_trailer(f, p);
|
| + |
|
| + |
return (f);
|
| + |
}
|
| + |
|
| + |
static inline const char*
|
| + |
maybe_read_hex_byte(struct sbuf *sbuf, const char *f)
|
| + |
{
|
| + |
int val;
|
| + |
|
| + |
/* Hex escapes are of the form \xNN -- always two hex digits */
|
| + |
|
| + |
if (isxdigit(f[0]) && isxdigit(f[1])) {
|
| + |
switch(*f) {
|
| + |
case '0':
|
| + |
val = 0x0;
|
| + |
break;
|
| + |
case '1':
|
| + |
val = 0x10;
|
| + |
break;
|
| + |
case '2':
|
| + |
val = 0x20;
|
| + |
break;
|
| + |
case '3':
|
| + |
val = 0x30;
|
| + |
break;
|
| + |
case '4':
|
| + |
val = 0x40;
|
| + |
break;
|
| + |
case '5':
|
| + |
val = 0x50;
|
| + |
break;
|
| + |
case '6':
|
| + |
val = 0x60;
|
| + |
break;
|
| + |
case '7':
|
| + |
val = 0x70;
|
| + |
break;
|
| + |
case '8':
|
| + |
val = 0x80;
|
| + |
break;
|
| + |
case '9':
|
| + |
val = 0x90;
|
| + |
break;
|
| + |
case 'a':
|
| + |
case 'A':
|
| + |
val = 0xa0;
|
| + |
break;
|
| + |
case 'b':
|
| + |
case 'B':
|
| + |
val = 0xb0;
|
| + |
break;
|
| + |
case 'c':
|
| + |
case 'C':
|
| + |
val = 0xc0;
|
| + |
break;
|
| + |
case 'd':
|
| + |
case 'D':
|
| + |
val = 0xd0;
|
| + |
break;
|
| + |
case 'e':
|
| + |
case 'E':
|
| + |
val = 0xe0;
|
| + |
break;
|
| + |
case 'f':
|
| + |
case 'F':
|
| + |
val = 0xf0;
|
| + |
break;
|
| + |
}
|
| + |
|
| + |
f++;
|
| + |
|
| + |
switch(*f) {
|
| + |
case '0':
|
| + |
val += 0x0;
|
| + |
break;
|
| + |
case '1':
|
| + |
val += 0x1;
|
| + |
break;
|
| + |
case '2':
|
| + |
val += 0x2;
|
| + |
break;
|
| + |
case '3':
|
| + |
val += 0x3;
|
| + |
break;
|
| + |
case '4':
|
| + |
val += 0x4;
|
| + |
break;
|
| + |
case '5':
|
| + |
val += 0x5;
|
| + |
break;
|
| + |
case '6':
|
| + |
val += 0x6;
|
| + |
break;
|
| + |
case '7':
|
| + |
val += 0x7;
|
| + |
break;
|
| + |
case '8':
|
| + |
val += 0x8;
|
| + |
break;
|
| + |
case '9':
|
| + |
val += 0x9;
|
| + |
break;
|
| + |
case 'a':
|
| + |
case 'A':
|
| + |
val += 0xa;
|
| + |
break;
|
| + |
case 'b':
|
| + |
case 'B':
|
| + |
val += 0xb;
|
| + |
break;
|
| + |
case 'c':
|
| + |
case 'C':
|
| + |
val += 0xc;
|
| |
break;
|
| - |
case '0':
|
| - |
p->flags |= PP_ZERO_PAD;
|
| + |
case 'd':
|
| + |
case 'D':
|
| + |
val += 0xd;
|
| |
break;
|
| - |
case '\'':
|
| - |
p->flags |= PP_THOUSANDS_SEP;
|
| + |
case 'e':
|
| + |
case 'E':
|
| + |
val += 0xe;
|
| |
break;
|
| - |
default:
|
| - |
done = true;
|
| + |
case 'f':
|
| + |
case 'F':
|
| + |
val += 0xf;
|
| |
break;
|
| |
}
|
| - |
if (!done)
|
| - |
f++;
|
| + |
|
| + |
sbuf_putc(sbuf, val);
|
| + |
} else {
|
| + |
/* Pass through unchanged if it's not a recognizable
|
| + |
hex byte. */
|
| + |
sbuf_putc(sbuf, '\\');
|
| + |
sbuf_putc(sbuf, 'x');
|
| |
}
|
| + |
return (f);
|
| + |
}
|
| |
|
| - |
/* Field width, if any -- some number of decimal digits.
|
| - |
Note: field width set to zero could be interpreted as using
|
| - |
0 to request zero padding: it doesn't matter which -- the
|
| - |
result on output is exactly the same. */
|
| + |
static inline const char*
|
| + |
read_oct_byte(struct sbuf *sbuf, const char *f)
|
| + |
{
|
| + |
int val = 0;
|
| |
|
| - |
done = false;
|
| - |
while (!done) {
|
| - |
switch(*f) {
|
| + |
/* Octal escapes are upto three octal digits: \N, \NN or \NNN
|
| + |
up to a max of \377. Note: this treats \400 as \40
|
| + |
followed by character 0 passed through unchanged. */
|
| + |
|
| + |
while (val < 32) {
|
| + |
switch (*f) {
|
| |
case '0':
|
| - |
p->width = p->width * 10 + 0;
|
| + |
val = val * 8 + 0;
|
| |
break;
|
| |
case '1':
|
| - |
p->width = p->width * 10 + 1;
|
| + |
val = val * 8 + 1;
|
| |
break;
|
| |
case '2':
|
| - |
p->width = p->width * 10 + 2;
|
| + |
val = val * 8 + 2;
|
| |
break;
|
| |
case '3':
|
| - |
p->width = p->width * 10 + 3;
|
| + |
val = val * 8 + 3;
|
| |
break;
|
| |
case '4':
|
| - |
p->width = p->width * 10 + 4;
|
| + |
val = val * 8 + 4;
|
| |
break;
|
| |
case '5':
|
| - |
p->width = p->width * 10 + 5;
|
| + |
val = val * 8 + 5;
|
| |
break;
|
| |
case '6':
|
| - |
p->width = p->width * 10 + 6;
|
| + |
val = val * 8 + 6;
|
| |
break;
|
| |
case '7':
|
| - |
p->width = p->width * 10 + 7;
|
| - |
break;
|
| - |
case '8':
|
| - |
p->width = p->width * 10 + 8;
|
| - |
break;
|
| - |
case '9':
|
| - |
p->width = p->width * 10 + 9;
|
| - |
break;
|
| - |
default:
|
| - |
done = true;
|
| + |
val = val * 8 + 7;
|
| |
break;
|
| + |
default: /* Non-octal digit */
|
| + |
goto done;
|
| |
}
|
| - |
if (!done)
|
| - |
f++;
|
| - |
}
|
| |
|
| - |
/* The next character or two will be a format code -- look
|
| - |
these up in the fmt table to make sure they are allowed in
|
| - |
context. This could be optimized (but you know what they
|
| - |
say about premature optimization) since the format codes
|
| - |
are arranged alphabetically in the fmt[] array. */
|
| + |
f++;
|
| + |
}
|
| + |
done:
|
| + |
f--; /* point at the last octal digit */
|
| + |
sbuf_putc(sbuf, val);
|
| |
|
| - |
done = false;
|
| - |
for (fmt_code = PP_PKG_SHLIBS; fmt_code < PP_END_MARKER; fmt_code++) {
|
| - |
if ((fmt[fmt_code].context & context) == context &&
|
| - |
fmt[fmt_code].fmt_main == f[0] &&
|
| - |
(fmt[fmt_code].fmt_sub == '\0' ||
|
| - |
fmt[fmt_code].fmt_sub == f[1])) {
|
| - |
p->fmt_code = fmt_code;
|
| - |
done = true;
|
| - |
break;
|
| - |
}
|
| - |
}
|
| + |
return (f);
|
| + |
}
|
| |
|
| - |
/* Not a recognised format code -- mark for pass through */
|
| + |
static const char *
|
| + |
process_escape(struct sbuf *sbuf, const char *f)
|
| + |
{
|
| + |
f++; /* Eat the \ */
|
| |
|
| - |
if (!done) {
|
| - |
p->fmt_code = PP_END_MARKER;
|
| - |
return (f); /* Caller will rewind */
|
| + |
switch (*f) {
|
| + |
case 'a':
|
| + |
sbuf_putc(sbuf, '\a');
|
| + |
break;
|
| + |
case 'b':
|
| + |
sbuf_putc(sbuf, '\b');
|
| + |
break;
|
| + |
case 'f':
|
| + |
sbuf_putc(sbuf, '\f');
|
| + |
break;
|
| + |
case 'n':
|
| + |
sbuf_putc(sbuf, '\n');
|
| + |
break;
|
| + |
case 't':
|
| + |
sbuf_putc(sbuf, '\t');
|
| + |
break;
|
| + |
case 'v':
|
| + |
sbuf_putc(sbuf, '\v');
|
| + |
break;
|
| + |
case '\'':
|
| + |
sbuf_putc(sbuf, '\'');
|
| + |
break;
|
| + |
case '"':
|
| + |
sbuf_putc(sbuf, '"');
|
| + |
break;
|
| + |
case '\\':
|
| + |
sbuf_putc(sbuf, '\\');
|
| + |
break;
|
| + |
case 'x': /* Hex escape: \xNN */
|
| + |
f++;
|
| + |
f = maybe_read_hex_byte(sbuf, f);
|
| + |
break;
|
| + |
case '0':
|
| + |
case '1':
|
| + |
case '2':
|
| + |
case '3':
|
| + |
case '4':
|
| + |
case '5':
|
| + |
case '6':
|
| + |
case '7': /* all fall through */
|
| + |
f = read_oct_byte(sbuf, f);
|
| + |
break;
|
| + |
default: /* If it's not a recognised escape,
|
| + |
pass it through unchanged */
|
| + |
sbuf_putc(sbuf, '\\');
|
| + |
sbuf_putc(sbuf, *f);
|
| + |
break;
|
| |
}
|
| |
|
| - |
/* Does this format take a trailing list item/separator format
|
| - |
like %{...%|...%} ? It's only the list-valued items that
|
| - |
do, and they are *only* valid in PP_PKG context. Also,
|
| - |
they only take the trailing stuff in the absence of %?X or
|
| - |
%#X modifiers. */
|
| + |
return (f);
|
| + |
}
|
| |
|
| - |
if (fmt[p->fmt_code].context != PP_PKG ||
|
| - |
(p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) != 0)
|
| - |
return (f);
|
| + |
static const char *
|
| + |
process_format_trailer(struct sbuf *sbuf, const char *f, const struct pkg *pkg,
|
| + |
const void *data, int count, unsigned context)
|
| + |
{
|
| + |
const char *fstart;
|
| + |
struct sbuf *s;
|
| + |
struct percent_esc *p;
|
| |
|
| - |
/* ... and is the trailer present if so? */
|
| + |
p = new_percent_esc(NULL);
|
| |
|
| - |
if (f[0] == '%' && f[1] == '{') {
|
| - |
const char *f2;
|
| - |
bool item = false;
|
| - |
bool sep = false;
|
| + |
if (p == NULL)
|
| + |
return (NULL); /* Out of memory */
|
| |
|
| - |
for (f2 = f + 2; *f2 != '\0'; f2++) {
|
| - |
if (f2[0] == '%' && ( f2[1] == '}' || f2[1] == '|')) {
|
| - |
if (f2[1] == '|')
|
| - |
sep = true;
|
| - |
break;
|
| - |
}
|
| - |
sbuf_putc(p->item_fmt, *f2);
|
| - |
}
|
| - |
if (item) {
|
| - |
sbuf_finish(p->item_fmt);
|
| - |
f = f2 + 1;
|
| - |
|
| - |
if (sep) {
|
| - |
sep = false;
|
| - |
|
| - |
for (f2 = f; *f2 != '\0'; f2++) {
|
| - |
if (f2[0] == '%' && f2[1] == '}') {
|
| - |
sep = true;
|
| - |
break;
|
| - |
}
|
| - |
sbuf_putc(p->sep_fmt, *f2);
|
| - |
}
|
| + |
fstart = f;
|
| + |
f = parse_format(f, context, p);
|
| + |
|
| + |
if (p->fmt_code == PP_ROW_COUNTER)
|
| + |
s = fmt[p->fmt_code].fmt_handler(sbuf, &count, p);
|
| + |
else if (p->fmt_code > PP_LAST_FORMAT)
|
| + |
s = fmt[p->fmt_code].fmt_handler(sbuf, NULL, p);
|
| + |
else if (fmt[p->fmt_code].context & context)
|
| + |
s = fmt[p->fmt_code].fmt_handler(sbuf, data, p);
|
| + |
else
|
| + |
s = fmt[p->fmt_code].fmt_handler(sbuf, pkg, p);
|
| |
|
| - |
if (sep) {
|
| - |
sbuf_finish(p->sep_fmt);
|
| - |
f = f2 + 1;
|
| - |
} else {
|
| - |
sbuf_clear(p->item_fmt);
|
| - |
sbuf_clear(p->sep_fmt);
|
| - |
}
|
| - |
}
|
| - |
} else {
|
| - |
sbuf_clear(p->item_fmt);
|
| - |
sbuf_clear(p->sep_fmt);
|
| - |
}
|
| - |
}
|
| + |
|
| + |
if (s == NULL)
|
| + |
f = fstart; /* Pass through unprocessed on error */
|
| + |
|
| + |
free_percent_esc(p);
|
| |
|
| |
return (f);
|
| |
}
|
| |
|
| |
static const char *
|
| - |
process_format(struct sbuf *sbuf, const char *f, va_list ap)
|
| + |
process_format_main(struct sbuf *sbuf, const char *f, va_list ap)
|
| |
{
|
| |
const char *fstart;
|
| |
struct sbuf *s;
|
| - |
struct percent_esc *p = new_percent_esc(NULL);
|
| + |
struct percent_esc *p;
|
| |
void *data;
|
| |
|
| + |
p = new_percent_esc(NULL);
|
| + |
|
| |
if (p == NULL)
|
| |
return (NULL); /* Out of memory */
|
| |
|
| |
fstart = f;
|
| - |
f = parse_escape(f, PP_PKG, p);
|
| + |
f = parse_format(f, PP_PKG, p);
|
| |
|
| |
if (p->fmt_code <= PP_LAST_FORMAT)
|
| |
data = va_arg(ap, void *);
|
| |
else
|
| |
data = NULL;
|
| |
|
| - |
/* FFR. Replace this monster switch statement by function
|
| - |
* pointers in fmt array. */
|
| - |
switch (p->fmt_code) {
|
| - |
case PP_PKG_SHLIBS: /* list */
|
| - |
s = format_shlibs(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_SHLIB_NAME:
|
| - |
s = format_shlib_name(sbuf, (struct pkg_shlib *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_CATEGORIES: /* list */
|
| - |
s = format_categories(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_CATEGORY_NAME:
|
| - |
s = format_category_name(sbuf, (struct pkg_category *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DIRECTORIES: /* list */
|
| - |
s = format_directories(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DIRECTORY_GROUP:
|
| - |
s = format_directory_group(sbuf, (struct pkg_dir *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DIRECTORY_KEEPFLAG:
|
| - |
s = format_directory_keepflag(sbuf, (struct pkg_dir *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DIRECTORY_PATH:
|
| - |
s = format_directory_path(sbuf, (struct pkg_dir *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DIRECTORY_PERMS:
|
| - |
s = format_directory_perms(sbuf, (struct pkg_dir *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DIRECTORY_TRYFLAG:
|
| - |
s = format_directory_tryflag(sbuf, (struct pkg_dir *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DIRECTORY_USER:
|
| - |
s = format_directory_user(sbuf, (struct pkg_dir *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FILES: /* list */
|
| - |
s = format_files(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FILE_GROUP:
|
| - |
s = format_file_group(sbuf, (struct pkg_file *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FILE_KEEPFLAG:
|
| - |
s = format_file_keepflag(sbuf, (struct pkg_file *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FILE_PATH:
|
| - |
s = format_file_path(sbuf, (struct pkg_file *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FILE_PERMS:
|
| - |
s = format_file_perms(sbuf, (struct pkg_file *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FILE_SHA256:
|
| - |
s = format_file_sha256(sbuf, (struct pkg_file *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FILE_USER:
|
| - |
s = format_file_user(sbuf, (struct pkg_file *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_GROUPS: /* list */
|
| - |
s = format_groups(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_GROUP_GIDSTR:
|
| - |
s = format_group_gidstr(sbuf, (struct pkg_group *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_GROUP_NAME:
|
| - |
s = format_group_name(sbuf, (struct pkg_group *) data, p);
|
| - |
break;
|
| - |
case PP_ROW_COUNTER:
|
| - |
s = format_row_counter(sbuf, (int *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_LICENSES: /* list */
|
| - |
s = format_licenses(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_LICENSE_NAME:
|
| - |
s = format_license_name(sbuf, (struct pkg_license *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_MESSAGE:
|
| - |
s = format_message(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_OPTIONS: /* list */
|
| - |
s = format_options(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_OPTION_NAME:
|
| - |
s = format_option_name(sbuf, (struct pkg_option *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_OPTION_VALUE:
|
| - |
s = format_option_value(sbuf, (struct pkg_option *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_USERS: /* list */
|
| - |
s = format_users(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_USER_NAME:
|
| - |
s = format_user_name(sbuf, (struct pkg_user *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_USER_UIDSTR:
|
| - |
s = format_user_uidstr(sbuf, (struct pkg_user *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_AUTOREMOVE:
|
| - |
s = format_autoremove(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_COMMENT:
|
| - |
s = format_comment(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DEPENDENCIES: /* list */
|
| - |
s = format_dependencies(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DEPENDENCY_NAME:
|
| - |
s = format_dependency_name(sbuf, (struct pkg_dep *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DEPENDENCY_ORIGIN:
|
| - |
s = format_dependency_origin(sbuf, (struct pkg_dep *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_DEPENDENCY_VERSION:
|
| - |
s = format_dependency_version(sbuf, (struct pkg_dep *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_ADDITIONAL_INFO:
|
| - |
s = format_add_info(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_LOCK_STATUS:
|
| - |
s = format_lock_status(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_LICENSE_LOGIC:
|
| - |
s = format_license_logic(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_MAINTAINER:
|
| - |
s = format_maintainer(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_NAME:
|
| - |
s = format_name(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_ORIGIN:
|
| - |
s = format_origin(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_PREFIX:
|
| - |
s = format_prefix(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_REQUIREMENTS: /* list */
|
| - |
s = format_requirements(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_REQUIREMENT_NAME: /* printing as dependency */
|
| - |
s = format_dependency_name(sbuf, (struct pkg_dep *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_REQUIREMENT_ORIGIN: /* printing as dependency */
|
| - |
s = format_dependency_origin(sbuf, (struct pkg_dep *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_REQUIREMENT_VERSION: /* printing as dependency */
|
| - |
s = format_dependency_version(sbuf, (struct pkg_dep *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_FLATSIZE:
|
| - |
s = format_flatsize(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_INSTALL_TIMESTAMP:
|
| - |
s = format_install_tstamp(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_VERSION:
|
| - |
s = format_version(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_PKG_HOME_PAGE:
|
| - |
s = format_home_url(sbuf, (struct pkg *) data, p);
|
| - |
break;
|
| - |
case PP_LITERAL_PERCENT:
|
| - |
s = format_literal_percent(sbuf, NULL, NULL);
|
| - |
break;
|
| - |
default:
|
| - |
/* If it's not a known escape, pass through unchanged */
|
| - |
sbuf_putc(sbuf, '%');
|
| - |
s = NULL;
|
| - |
break;
|
| - |
}
|
| + |
s = fmt[p->fmt_code].fmt_handler(sbuf, data, p);
|
| |
|
| |
if (s == NULL)
|
| |
f = fstart; /* Pass through unprocessed on error */
|