Compare commits
1 commit
master
...
andrew/pfo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7dc2266c2f |
8 changed files with 500 additions and 0 deletions
|
@ -2913,6 +2913,9 @@ int alpm_capabilities(void);
|
||||||
/* End of libalpm_api */
|
/* End of libalpm_api */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
size_t alpm_info_print_pkg(const char *format, alpm_pkg_t *pkg);
|
||||||
|
size_t alpm_info_print_pkgs(const char *format, alpm_list_t *pkgs);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
226
lib/libalpm/info.c
Normal file
226
lib/libalpm/info.c
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "alpm.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "mfmt.h"
|
||||||
|
|
||||||
|
typedef enum field_t {
|
||||||
|
FILENAME,
|
||||||
|
NAME,
|
||||||
|
BASE,
|
||||||
|
DESCRIPTION,
|
||||||
|
VERSION,
|
||||||
|
ORIGIN,
|
||||||
|
REASON,
|
||||||
|
LICENSE,
|
||||||
|
GROUP,
|
||||||
|
|
||||||
|
DEPENDS,
|
||||||
|
OPTDEPENDS,
|
||||||
|
CONFLICTS,
|
||||||
|
PROVIDES,
|
||||||
|
REPLACES,
|
||||||
|
REQUIREDBY,
|
||||||
|
|
||||||
|
DELTAS,
|
||||||
|
FILES,
|
||||||
|
BACKUP,
|
||||||
|
DB,
|
||||||
|
VALIDATION,
|
||||||
|
URL,
|
||||||
|
BUILDDATE,
|
||||||
|
INSTALLDATE,
|
||||||
|
PACKAGER,
|
||||||
|
MD5SUM,
|
||||||
|
SHA256SUM,
|
||||||
|
ARCH,
|
||||||
|
SIZE,
|
||||||
|
ISIZE,
|
||||||
|
BASE64SIG,
|
||||||
|
|
||||||
|
UNKNOWN,
|
||||||
|
} field_t;
|
||||||
|
|
||||||
|
static struct field_map_t {
|
||||||
|
const char *input;
|
||||||
|
field_t field;
|
||||||
|
} field_map[] = {
|
||||||
|
{"filename", FILENAME},
|
||||||
|
{"name", NAME},
|
||||||
|
{"base", BASE},
|
||||||
|
{"description", DESCRIPTION},
|
||||||
|
{"version", VERSION},
|
||||||
|
|
||||||
|
{"license", LICENSE},
|
||||||
|
{"group", GROUP},
|
||||||
|
{"groups", GROUP},
|
||||||
|
|
||||||
|
{"depends", DEPENDS},
|
||||||
|
{"optdepends", OPTDEPENDS},
|
||||||
|
{"conflicts", CONFLICTS},
|
||||||
|
{"provides", PROVIDES},
|
||||||
|
{"replaces", REPLACES},
|
||||||
|
{"requiredby", REQUIREDBY},
|
||||||
|
|
||||||
|
{"url", URL},
|
||||||
|
{"builddate", BUILDDATE},
|
||||||
|
{"installdate", INSTALLDATE},
|
||||||
|
{"packager", PACKAGER},
|
||||||
|
{"md5sum", MD5SUM},
|
||||||
|
{"sha256sum", SHA256SUM},
|
||||||
|
{"arch", ARCH},
|
||||||
|
{"size", SIZE},
|
||||||
|
{"isize", ISIZE},
|
||||||
|
{"base64sig", BASE64SIG},
|
||||||
|
|
||||||
|
{NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *_alpm_hr_size(off_t bytes, char *dest)
|
||||||
|
{
|
||||||
|
static const char *suff[] = {"B", "K", "M", "G", "T", "P", "E", NULL};
|
||||||
|
float hrsize;
|
||||||
|
int s = 0;
|
||||||
|
while((bytes >= 1000000 || bytes <= -1000000) && suff[s + 1]) {
|
||||||
|
bytes /= 1024;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
hrsize = bytes;
|
||||||
|
if((hrsize >= 1000 || hrsize <= -1000) && suff[s + 1]) {
|
||||||
|
hrsize /= 1024;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
sprintf(dest, "%.2f %s", hrsize, suff[s]);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static field_t _alpm_info_lookup_field(const char *name) {
|
||||||
|
struct field_map_t *m;
|
||||||
|
for(m = field_map; m->input; m++) {
|
||||||
|
if(strcmp(name, m->input) == 0) { return m->field; }
|
||||||
|
}
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _alpm_info_print_str(mfmt_token_callback_t *t, const char *str, FILE *f) {
|
||||||
|
return mfmt_render_str(t, str ? str : "NULL", f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _alpm_info_print_size(mfmt_token_callback_t *t, const off_t s, FILE *f) {
|
||||||
|
if(s) {
|
||||||
|
char hrsize[50];
|
||||||
|
if(t->conversion == 'd') {
|
||||||
|
snprintf(hrsize, 50, "%lld", (long long)s);
|
||||||
|
} else {
|
||||||
|
_alpm_hr_size(s, hrsize);
|
||||||
|
}
|
||||||
|
return mfmt_render_str(t, hrsize, f);
|
||||||
|
} else {
|
||||||
|
return mfmt_render_str(t, "NULL", f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _alpm_info_print_strlist(mfmt_token_callback_t *t, alpm_list_t *l, FILE *f) {
|
||||||
|
if(l) {
|
||||||
|
size_t len = 0;
|
||||||
|
while(l) {
|
||||||
|
len += mfmt_render_str(t, l->data, f) + 1;
|
||||||
|
fputc('\n', f);
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
} else {
|
||||||
|
return mfmt_render_str(t, "NULL", f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _alpm_info_print_deplist(mfmt_token_callback_t *t, alpm_list_t *l, FILE *f) {
|
||||||
|
if(l) {
|
||||||
|
size_t len = 0;
|
||||||
|
while(l) {
|
||||||
|
char *s = alpm_dep_compute_string(l->data);
|
||||||
|
len += mfmt_render_str(t, s, f) + 1;
|
||||||
|
fputc('\n', f);
|
||||||
|
l = l->next;
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
} else {
|
||||||
|
return mfmt_render_str(t, "NULL", f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _alpm_info_print_timestamp(mfmt_token_callback_t *t, const alpm_time_t s, FILE *f) {
|
||||||
|
if(s) {
|
||||||
|
char datestr[50] = "";
|
||||||
|
if(strftime(datestr, 50, " %c", localtime(&s)) == 0) { return 0; }
|
||||||
|
return mfmt_render_str(t, datestr + 1, f);
|
||||||
|
} else {
|
||||||
|
return mfmt_render_str(t, "NULL", f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _alpm_info_process_token(FILE *f, mfmt_token_callback_t *t, void *ctx, void *arg) {
|
||||||
|
alpm_pkg_t *p = arg;
|
||||||
|
(void)ctx;
|
||||||
|
switch(_alpm_info_lookup_field(t->name)) {
|
||||||
|
case NAME: return _alpm_info_print_str(t, alpm_pkg_get_name(p), f);
|
||||||
|
case DESCRIPTION: return _alpm_info_print_str(t, alpm_pkg_get_desc(p), f);
|
||||||
|
case PACKAGER: return _alpm_info_print_str(t, alpm_pkg_get_packager(p), f);
|
||||||
|
case MD5SUM: return _alpm_info_print_str(t, alpm_pkg_get_md5sum(p), f);
|
||||||
|
case FILENAME: return _alpm_info_print_str(t, alpm_pkg_get_filename(p), f);
|
||||||
|
case BASE: return _alpm_info_print_str(t, alpm_pkg_get_base(p), f);
|
||||||
|
case VERSION: return _alpm_info_print_str(t, alpm_pkg_get_version(p), f);
|
||||||
|
case URL: return _alpm_info_print_str(t, alpm_pkg_get_url(p), f);
|
||||||
|
case SHA256SUM: return _alpm_info_print_str(t, alpm_pkg_get_sha256sum(p), f);
|
||||||
|
case ARCH: return _alpm_info_print_str(t, alpm_pkg_get_arch(p), f);
|
||||||
|
case BASE64SIG: return _alpm_info_print_str(t, alpm_pkg_get_base64_sig(p), f);
|
||||||
|
|
||||||
|
case SIZE: return _alpm_info_print_size(t, alpm_pkg_get_size(p), f);
|
||||||
|
case ISIZE: return _alpm_info_print_size(t, alpm_pkg_get_isize(p), f);
|
||||||
|
|
||||||
|
case BUILDDATE: return _alpm_info_print_timestamp(t, alpm_pkg_get_builddate(p), f);
|
||||||
|
case INSTALLDATE: return _alpm_info_print_timestamp(t, alpm_pkg_get_installdate(p), f);
|
||||||
|
|
||||||
|
case DEPENDS: return _alpm_info_print_deplist(t, alpm_pkg_get_depends(p), f);
|
||||||
|
case OPTDEPENDS: return _alpm_info_print_deplist(t, alpm_pkg_get_optdepends(p), f);
|
||||||
|
case CONFLICTS: return _alpm_info_print_deplist(t, alpm_pkg_get_conflicts(p), f);
|
||||||
|
case PROVIDES: return _alpm_info_print_deplist(t, alpm_pkg_get_provides(p), f);
|
||||||
|
case REPLACES: return _alpm_info_print_deplist(t, alpm_pkg_get_replaces(p), f);
|
||||||
|
case REQUIREDBY: {
|
||||||
|
alpm_list_t *rb = alpm_pkg_compute_requiredby(p);
|
||||||
|
size_t len = _alpm_info_print_strlist(t, rb, f);
|
||||||
|
FREELIST(rb);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: errno = EINVAL; return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SYMEXPORT alpm_info_print_pkg(const char *format, alpm_pkg_t *pkg) {
|
||||||
|
alpm_list_t l = {
|
||||||
|
.data = pkg,
|
||||||
|
.next = NULL,
|
||||||
|
};
|
||||||
|
l.prev = &l;
|
||||||
|
return alpm_info_print_pkgs(format, &l);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SYMEXPORT alpm_info_print_pkgs(const char *format, alpm_list_t *pkgs) {
|
||||||
|
mfmt_t *mfmt = mfmt_parse(format, _alpm_info_process_token, NULL);
|
||||||
|
size_t len = 0;
|
||||||
|
if(mfmt == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(alpm_list_t *i = pkgs; i; i = i->next) {
|
||||||
|
size_t plen = mfmt_printf(mfmt, i->data, stdout);
|
||||||
|
if(plen == 0) { return 0; }
|
||||||
|
len += plen;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ts=2 sw=2 et: */
|
|
@ -28,5 +28,7 @@ libalpm_sources = files('''
|
||||||
sync.h sync.c
|
sync.h sync.c
|
||||||
trans.h trans.c
|
trans.h trans.c
|
||||||
util.h util.c
|
util.h util.c
|
||||||
|
info.c
|
||||||
|
mfmt.c mfmt.h
|
||||||
version.c
|
version.c
|
||||||
'''.split())
|
'''.split())
|
||||||
|
|
193
lib/libalpm/mfmt.c
Normal file
193
lib/libalpm/mfmt.c
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "mfmt.h"
|
||||||
|
|
||||||
|
char *_mfmt_find_unescaped_char(char *haystack, char needle) {
|
||||||
|
while(1) {
|
||||||
|
haystack = strchrnul(haystack, needle);
|
||||||
|
if(*haystack && *(haystack + 1) == needle) { haystack += 2; continue; }
|
||||||
|
else { break; }
|
||||||
|
}
|
||||||
|
return haystack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _mfmt_brace_dedup(char *str) {
|
||||||
|
char *c = str, *end = str + strlen(str);
|
||||||
|
while((c = strchr(c, '{'))) {
|
||||||
|
memmove(c, c + 1, end - c);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = str;
|
||||||
|
while((c = strchr(c, '}'))) {
|
||||||
|
memmove(c, c + 1, end - c);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mfmt_t *mfmt_parse(const char *tmpl, mfmt_callback_t *cb, void *ctx) {
|
||||||
|
mfmt_t *mfmt;
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
mfmt = calloc(sizeof(mfmt_t), 1);
|
||||||
|
if(mfmt == NULL) { return NULL; }
|
||||||
|
|
||||||
|
mfmt->cb = cb;
|
||||||
|
mfmt->ctx = ctx;
|
||||||
|
|
||||||
|
for(c = (char*) tmpl; c && *c; ) {
|
||||||
|
mfmt->token_count++;
|
||||||
|
if(*c == '{' && *(c + 1) != '{') {
|
||||||
|
/* replacement */
|
||||||
|
if(!*(c = _mfmt_find_unescaped_char(c + 1, '}'))) {
|
||||||
|
errno = EINVAL;
|
||||||
|
free(mfmt);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* literal */
|
||||||
|
c = _mfmt_find_unescaped_char(c, '{');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((mfmt->tokens = calloc(sizeof(mfmt_token_t), mfmt->token_count)) == NULL) {
|
||||||
|
free(mfmt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
for(c = (char*) tmpl, i = 0; c && *c; i++) {
|
||||||
|
if(*c == '{' && *(c + 1) != '{') {
|
||||||
|
/* replacement */
|
||||||
|
mfmt_token_callback_t *t = &mfmt->tokens[i].callback;
|
||||||
|
char *end = _mfmt_find_unescaped_char(c + 1, '}');
|
||||||
|
t->type = MFMT_TOKEN_CALLBACK;
|
||||||
|
t->name = strndup(c + 1, end - c - 1);
|
||||||
|
c = end + 1;
|
||||||
|
} else {
|
||||||
|
/* literal */
|
||||||
|
char *end = _mfmt_find_unescaped_char(c, '{');
|
||||||
|
mfmt_token_literal_t *t = &mfmt->tokens[i].literal;
|
||||||
|
t->type = MFMT_TOKEN_LITERAL;
|
||||||
|
t->string = strndup(c, end - c);
|
||||||
|
_mfmt_brace_dedup(t->string);
|
||||||
|
c = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mfmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_printf(mfmt_t *mfmt, void *args, FILE *f) {
|
||||||
|
size_t len = 0;
|
||||||
|
size_t i;
|
||||||
|
for(i = 0; i < mfmt->token_count; i++) {
|
||||||
|
mfmt_token_t *t = &mfmt->tokens[i];
|
||||||
|
switch(t->base.type) {
|
||||||
|
case MFMT_TOKEN_LITERAL:
|
||||||
|
len += fputs(t->literal.string, f);
|
||||||
|
break;
|
||||||
|
case MFMT_TOKEN_CALLBACK:
|
||||||
|
len += mfmt->cb(f, &t->callback, mfmt->ctx, args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _mfmt_printf_close(mfmt_t *mfmt, void *args, FILE *f) {
|
||||||
|
if(f) {
|
||||||
|
size_t len = mfmt_printf(mfmt, args, f);
|
||||||
|
fclose(f);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_printd(mfmt_t *mfmt, void *args, int fd) {
|
||||||
|
return _mfmt_printf_close(mfmt, args, fdopen(fd, "w"));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_printb(mfmt_t *mfmt, void *args, char *buf, size_t buflen) {
|
||||||
|
return _mfmt_printf_close(mfmt, args, fmemopen(buf, buflen, "w"));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_prints(mfmt_t *mfmt, void *args, char **buf, size_t *buflen) {
|
||||||
|
return _mfmt_printf_close(mfmt, args, open_memstream(buf, buflen));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_fmt(const char *tmpl, mfmt_val_t *args, FILE *f) {
|
||||||
|
mfmt_t *mfmt = mfmt_parse(tmpl, NULL, NULL);
|
||||||
|
size_t len;
|
||||||
|
for(size_t i = 0; i < mfmt->token_count; i++) {
|
||||||
|
mfmt_token_t *t = &mfmt->tokens[i];
|
||||||
|
switch(t->base.type) {
|
||||||
|
case MFMT_TOKEN_LITERAL:
|
||||||
|
len += fputs(t->literal.string, f);
|
||||||
|
break;
|
||||||
|
case MFMT_TOKEN_CALLBACK:
|
||||||
|
/* fprintf(stderr, "token: %s\n", t->callback.name); */
|
||||||
|
if(t->callback.name[0]) {
|
||||||
|
for(mfmt_val_t *v = args; v; v++) {
|
||||||
|
/* fprintf(stderr, "val: %s\n", v->name); */
|
||||||
|
if(strcmp(v->name, t->callback.name) == 0) {
|
||||||
|
len += fputs(v->string, f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
len += fputs(args->string, f);
|
||||||
|
args++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_mfmt(mfmt_t *mfmt, mfmt_val_t *args, FILE *f) {
|
||||||
|
size_t len;
|
||||||
|
for(size_t i = 0; i < mfmt->token_count; i++) {
|
||||||
|
mfmt_token_t *t = &mfmt->tokens[i];
|
||||||
|
switch(t->base.type) {
|
||||||
|
case MFMT_TOKEN_LITERAL:
|
||||||
|
len += fputs(t->literal.string, f);
|
||||||
|
break;
|
||||||
|
case MFMT_TOKEN_CALLBACK:
|
||||||
|
/* fprintf(stderr, "token: %s\n", t->callback.name); */
|
||||||
|
if(t->callback.name[0]) {
|
||||||
|
for(mfmt_val_t *v = args; v; v++) {
|
||||||
|
/* fprintf(stderr, "val: %s\n", v->name); */
|
||||||
|
if(strcmp(v->name, t->callback.name) == 0) {
|
||||||
|
len += fputs(v->string, f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
len += fputs(args->string, f);
|
||||||
|
args++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_render_int(mfmt_token_callback_t *t, const intmax_t i, FILE *f) {
|
||||||
|
(void)t;
|
||||||
|
return fprintf(f, "%jd", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mfmt_render_str(mfmt_token_callback_t *t, const char *str, FILE *f) {
|
||||||
|
(void)t;
|
||||||
|
return fputs(str, f);
|
||||||
|
}
|
66
lib/libalpm/mfmt.h
Normal file
66
lib/libalpm/mfmt.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
typedef enum mfmt_token_type_t {
|
||||||
|
MFMT_TOKEN_LITERAL,
|
||||||
|
MFMT_TOKEN_CALLBACK,
|
||||||
|
} mfmt_token_type_t;
|
||||||
|
|
||||||
|
typedef struct mfmt_token_literal_t {
|
||||||
|
mfmt_token_type_t type;
|
||||||
|
char *string;
|
||||||
|
} mfmt_token_literal_t;
|
||||||
|
|
||||||
|
typedef struct mfmt_token_base_t {
|
||||||
|
mfmt_token_type_t type;
|
||||||
|
} mfmt_token_base_t;
|
||||||
|
|
||||||
|
typedef struct mfmt_token_callback_t {
|
||||||
|
mfmt_token_type_t type;
|
||||||
|
|
||||||
|
size_t position;
|
||||||
|
char *name;
|
||||||
|
size_t width;
|
||||||
|
size_t precision;
|
||||||
|
char align;
|
||||||
|
char fill;
|
||||||
|
char conversion;
|
||||||
|
int sign;
|
||||||
|
} mfmt_token_callback_t;
|
||||||
|
|
||||||
|
typedef union mfmt_token_t {
|
||||||
|
mfmt_token_base_t base;
|
||||||
|
mfmt_token_literal_t literal;
|
||||||
|
mfmt_token_callback_t callback;
|
||||||
|
} mfmt_token_t;
|
||||||
|
|
||||||
|
typedef size_t (mfmt_callback_t)(FILE *f, mfmt_token_callback_t *token, void *ctx, void *args);
|
||||||
|
|
||||||
|
typedef struct mfmt_t {
|
||||||
|
mfmt_callback_t *cb;
|
||||||
|
void *ctx;
|
||||||
|
size_t token_count;
|
||||||
|
mfmt_token_t *tokens;
|
||||||
|
} mfmt_t;
|
||||||
|
|
||||||
|
typedef struct mfmt_val_t {
|
||||||
|
const char *name;
|
||||||
|
const char *string;
|
||||||
|
} mfmt_val_t;
|
||||||
|
|
||||||
|
mfmt_t *mfmt_parse(const char *tmpl, mfmt_callback_t *cb, void *ctx);
|
||||||
|
size_t mfmt_printf(mfmt_t *mfmt, void *args, FILE *f);
|
||||||
|
size_t mfmt_printd(mfmt_t *mfmt, void *args, int fd);
|
||||||
|
size_t mfmt_printb(mfmt_t *mfmt, void *args, char *buf, size_t buflen);
|
||||||
|
size_t mfmt_prints(mfmt_t *mfmt, void *args, char **buf, size_t *buflen);
|
||||||
|
void mfmt_free(mfmt_t *mfmt);
|
||||||
|
|
||||||
|
size_t mfmt_render_int(mfmt_token_callback_t *token, intmax_t i, FILE *f);
|
||||||
|
size_t mfmt_render_uint(mfmt_token_callback_t *token, uintmax_t i, FILE *f);
|
||||||
|
size_t mfmt_render_str(mfmt_token_callback_t *token, const char *str, FILE *f);
|
||||||
|
|
||||||
|
size_t mfmt_formatf(const char *tmpl, mfmt_callback_t *cb, void *ctx, FILE *f);
|
||||||
|
size_t mfmt_formatd(const char *tmpl, mfmt_callback_t *cb, void *ctx, int fd);
|
||||||
|
size_t mfmt_formatb(const char *tmpl, mfmt_callback_t *cb, void *ctx, char *buf, size_t buflen);
|
||||||
|
size_t mfmt_formats(const char *tmpl, mfmt_callback_t *cb, void *ctx, char **buf);
|
|
@ -58,6 +58,7 @@ typedef struct __config_t {
|
||||||
unsigned short color;
|
unsigned short color;
|
||||||
unsigned short disable_dl_timeout;
|
unsigned short disable_dl_timeout;
|
||||||
char *print_format;
|
char *print_format;
|
||||||
|
char *pformat;
|
||||||
/* unfortunately, we have to keep track of paths both here and in the library
|
/* unfortunately, we have to keep track of paths both here and in the library
|
||||||
* because they can come from both the command line or config file, and we
|
* because they can come from both the command line or config file, and we
|
||||||
* need to ensure we get the order of preference right. */
|
* need to ensure we get the order of preference right. */
|
||||||
|
@ -172,6 +173,7 @@ enum {
|
||||||
OP_ASEXPLICIT,
|
OP_ASEXPLICIT,
|
||||||
OP_ARCH,
|
OP_ARCH,
|
||||||
OP_PRINTFORMAT,
|
OP_PRINTFORMAT,
|
||||||
|
OP_PFORMAT,
|
||||||
OP_GPGDIR,
|
OP_GPGDIR,
|
||||||
OP_DBONLY,
|
OP_DBONLY,
|
||||||
OP_FORCE,
|
OP_FORCE,
|
||||||
|
|
|
@ -651,6 +651,9 @@ static int parsearg_trans(int opt)
|
||||||
free(config->print_format);
|
free(config->print_format);
|
||||||
config->print_format = strdup(optarg);
|
config->print_format = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case OP_PFORMAT:
|
||||||
|
config->pformat = strdup(optarg);
|
||||||
|
break;
|
||||||
case OP_ASSUMEINSTALLED:
|
case OP_ASSUMEINSTALLED:
|
||||||
parsearg_util_addlist(&(config->assumeinstalled));
|
parsearg_util_addlist(&(config->assumeinstalled));
|
||||||
break;
|
break;
|
||||||
|
@ -944,6 +947,7 @@ static int parseargs(int argc, char *argv[])
|
||||||
{"asexplicit", no_argument, 0, OP_ASEXPLICIT},
|
{"asexplicit", no_argument, 0, OP_ASEXPLICIT},
|
||||||
{"arch", required_argument, 0, OP_ARCH},
|
{"arch", required_argument, 0, OP_ARCH},
|
||||||
{"print-format", required_argument, 0, OP_PRINTFORMAT},
|
{"print-format", required_argument, 0, OP_PRINTFORMAT},
|
||||||
|
{"pformat" , required_argument, 0, OP_PFORMAT},
|
||||||
{"gpgdir", required_argument, 0, OP_GPGDIR},
|
{"gpgdir", required_argument, 0, OP_GPGDIR},
|
||||||
{"dbonly", no_argument, 0, OP_DBONLY},
|
{"dbonly", no_argument, 0, OP_DBONLY},
|
||||||
{"color", required_argument, 0, OP_COLOR},
|
{"color", required_argument, 0, OP_COLOR},
|
||||||
|
|
|
@ -1168,6 +1168,10 @@ double humanize_size(off_t bytes, const char target_unit, int precision,
|
||||||
void print_packages(const alpm_list_t *packages)
|
void print_packages(const alpm_list_t *packages)
|
||||||
{
|
{
|
||||||
const alpm_list_t *i;
|
const alpm_list_t *i;
|
||||||
|
if(config->pformat) {
|
||||||
|
alpm_info_print_pkgs(config->pformat, (alpm_list_t*) packages);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(!config->print_format) {
|
if(!config->print_format) {
|
||||||
config->print_format = strdup("%l");
|
config->print_format = strdup("%l");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue