commit: 70679e49ee7fadc209a87ae23860fedfd646dc10
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun May 5 18:12:27 2019 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun May 5 18:12:27 2019 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=70679e49
libq/atom: move atom_format here
move atom_print from qatom to libq/atom as atom_format so it can be
reused by multiple applets
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
libq/atom.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
libq/atom.h | 4 ++
qatom.c | 94 +----------------------------------------
3 files changed, 137 insertions(+), 97 deletions(-)
diff --git a/libq/atom.c b/libq/atom.c
index 5f4b137..8eb9ac6 100644
--- a/libq/atom.c
+++ b/libq/atom.c
@@ -13,6 +13,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include <ctype.h>
#include <xalloc.h>
@@ -569,12 +570,9 @@ implode_a1_ret:
/**
* Reconstructs an atom exactly like it was originally given (exploded).
*/
-static char _atom_buf[BUFSIZ];
char *
-atom_to_string(depend_atom *a)
+atom_to_string_r(char *buf, size_t buflen, depend_atom *a)
{
- char *buf = _atom_buf;
- size_t buflen = sizeof(_atom_buf);
size_t off = 0;
atom_usedep *ud;
@@ -606,3 +604,133 @@ atom_to_string(depend_atom *a)
return buf;
}
+
+/**
+ * Run printf on an atom. The format field takes the form:
+ * %{keyword}: Always display the field that matches "keyword" or <unset>
+ * %[keyword]: Only display the field when it's set (or pverbose)
+ * The possible "keywords" are:
+ * CATEGORY P PN PV PVR PF PR SLOT
+ * - these are all the standard portage variables (so see ebuild(5))
+ * pfx - the version qualifier if set (e.g. > < = !)
+ * sfx - the version qualifier if set (e.g. *)
+ */
+char *
+atom_format_r(
+ char *buf,
+ size_t buflen,
+ const char *format,
+ const depend_atom *atom,
+ int pverbose)
+{
+ char bracket;
+ const char *fmt;
+ const char *p;
+ size_t len;
+ bool showit;
+ char *ret;
+
+ if (!atom) {
+ snprintf(buf, buflen, "%s", "(NULL:atom)");
+ return buf;
+ }
+
+#define append_buf(B,L,FMT,...) \
+ { \
+ len = snprintf(B, L, FMT, __VA_ARGS__); \
+ L -= len; \
+ B += len; \
+ }
+ ret = buf;
+ p = format;
+ while (*p != '\0') {
+ fmt = strchr(p, '%');
+ if (fmt == NULL) {
+ if (buflen > 0)
+ *buf = '\0';
+ return buf;
+ } else if (fmt != p) {
+ append_buf(buf, buflen, "%.*s", (int)(fmt - p), p);
+ }
+
+ bracket = fmt[1];
+ if (bracket == '{' || bracket == '[') {
+ fmt += 2;
+ p = strchr(fmt, bracket == '{' ? '}' : ']');
+ if (p) {
+ len = p - fmt;
+ showit = (bracket == '{') || pverbose;
+#define HN(X) (X ? X : "<unset>")
+ if (!strncmp("CATEGORY", fmt, len)) {
+ if (showit || atom->CATEGORY)
+ append_buf(buf, buflen, "%s",
HN(atom->CATEGORY));
+ } else if (!strncmp("P", fmt, len)) {
+ if (showit || atom->P)
+ append_buf(buf, buflen, "%s",
HN(atom->P));
+ } else if (!strncmp("PN", fmt, len)) {
+ if (showit || atom->PN)
+ append_buf(buf, buflen, "%s",
HN(atom->PN));
+ } else if (!strncmp("PV", fmt, len)) {
+ if (showit || atom->PV)
+ append_buf(buf, buflen, "%s",
HN(atom->PV));
+ } else if (!strncmp("PVR", fmt, len)) {
+ if (showit || atom->PVR)
+ append_buf(buf, buflen, "%s",
HN(atom->PVR));
+ } else if (!strncmp("PF", fmt, len)) {
+ append_buf(buf, buflen, "%s", atom->PN);
+ if (atom->PV)
+ append_buf(buf, buflen, "-%s",
atom->PV);
+ if (atom->PR_int)
+ append_buf(buf, buflen,"-r%i",
atom->PR_int);
+ } else if (!strncmp("PR", fmt, len)) {
+ if (showit || atom->PR_int)
+ append_buf(buf, buflen, "r%i",
atom->PR_int);
+ } else if (!strncmp("SLOT", fmt, len)) {
+ if (showit || atom->SLOT)
+ append_buf(buf, buflen,
"%s%s%s%s%s",
+ atom->SLOT ?
":" : "<unset>",
+ atom->SLOT ?
atom->SLOT : "",
+ atom->SUBSLOT ?
"/" : "",
+ atom->SUBSLOT ?
atom->SUBSLOT : "",
+
atom_slotdep_str[atom->slotdep]);
+ } else if (!strncmp("REPO", fmt, len)) {
+ if (showit || atom->REPO)
+ append_buf(buf, buflen, "::%s",
HN(atom->REPO));
+ } else if (!strncmp("pfx", fmt, len)) {
+ if (showit || atom->pfx_op !=
ATOM_OP_NONE)
+ append_buf(buf, buflen, "%s",
+ atom->pfx_op ==
ATOM_OP_NONE ?
+ "<unset>" :
atom_op_str[atom->pfx_op]);
+ } else if (!strncmp("sfx", fmt, len)) {
+ if (showit || atom->sfx_op !=
ATOM_OP_NONE)
+ append_buf(buf, buflen, "%s",
+ atom->sfx_op ==
ATOM_OP_NONE ?
+ "<unset>" :
atom_op_str[atom->sfx_op]);
+ } else
+ append_buf(buf, buflen, "<BAD:%.*s>",
(int)len, fmt);
+ ++p;
+#undef HN
+ } else
+ p = fmt + 1;
+ } else
+ ++p;
+ }
+#undef append_buf
+
+ return ret;
+}
+
+/* versions that use an internal buffer, which is suitable for most
+ * scenarios */
+static char _atom_buf[BUFSIZ];
+char *
+atom_to_string(depend_atom *a)
+{
+ return atom_to_string_r(_atom_buf, sizeof(_atom_buf), a);
+}
+
+char *
+atom_format(const char *format, const depend_atom *atom, int pverbose)
+{
+ return atom_format_r(_atom_buf, sizeof(_atom_buf), format, atom,
pverbose);
+}
diff --git a/libq/atom.h b/libq/atom.h
index 291d637..51ea88e 100644
--- a/libq/atom.h
+++ b/libq/atom.h
@@ -92,6 +92,10 @@ depend_atom *atom_explode(const char *atom);
void atom_implode(depend_atom *atom);
int atom_compare(const depend_atom *a1, const depend_atom *a2);
int atom_compare_str(const char * const s1, const char * const s2);
+char *atom_to_string_r(char *buf, size_t buflen, depend_atom *a);
+char *atom_format_r(char *buf, size_t buflen,
+ const char *format, const depend_atom *atom, int pverbose);
char *atom_to_string(depend_atom *a);
+char *atom_format(const char *format, const depend_atom *atom, int pverbose);
#endif
diff --git a/qatom.c b/qatom.c
index e3d2b0b..8825055 100644
--- a/qatom.c
+++ b/qatom.c
@@ -31,97 +31,6 @@ static const char * const qatom_opts_help[] = {
};
#define qatom_usage(ret) usage(ret, QATOM_FLAGS, qatom_long_opts,
qatom_opts_help, NULL, lookup_applet_idx("qatom"))
-/* Run printf on an atom! The format field takes the form:
- * %{keyword}: Always display the field that matches "keyword"
- * %[keyword]: Only display the field when it's valid (or pverbose)
- * The possible "keywords" are:
- * CATEGORY P PN PV PVR PF PR SLOT
- * - these are all the standard portage variables (so see ebuild(5))
- * pfx - the version qualifier if set (e.g. > < = !)
- * sfx - the version qualifier if set (e.g. *)
- */
-static void
-qatom_printf(const char *format, const depend_atom *atom, int pverbose)
-{
- char bracket;
- const char *fmt, *p;
-
- if (!atom) {
- printf("(NULL:atom)");
- return;
- }
-
- p = format;
- while (*p != '\0') {
- fmt = strchr(p, '%');
- if (fmt == NULL) {
- printf("%s", p);
- return;
- } else if (fmt != p)
- printf("%.*s", (int)(fmt - p), p);
-
- bracket = fmt[1];
- if (bracket == '{' || bracket == '[') {
- fmt += 2;
- p = strchr(fmt, bracket == '{' ? '}' : ']');
- if (p) {
- size_t len = p - fmt;
- bool showit = (bracket == '{') || pverbose;
-#define HN(X) (X ? X : "<unset>")
- if (!strncmp("CATEGORY", fmt, len)) {
- if (showit || atom->CATEGORY)
- printf("%s",
HN(atom->CATEGORY));
- } else if (!strncmp("P", fmt, len)) {
- if (showit || atom->P)
- printf("%s", HN(atom->P));
- } else if (!strncmp("PN", fmt, len)) {
- if (showit || atom->PN)
- printf("%s", HN(atom->PN));
- } else if (!strncmp("PV", fmt, len)) {
- if (showit || atom->PV)
- printf("%s", HN(atom->PV));
- } else if (!strncmp("PVR", fmt, len)) {
- if (showit || atom->PVR)
- printf("%s", HN(atom->PVR));
- } else if (!strncmp("PF", fmt, len)) {
- printf("%s", atom->PN);
- if (atom->PV)
- printf("-%s", atom->PV);
- if (atom->PR_int)
- printf("-r%i", atom->PR_int);
- } else if (!strncmp("PR", fmt, len)) {
- if (showit || atom->PR_int)
- printf("r%i", atom->PR_int);
- } else if (!strncmp("SLOT", fmt, len)) {
- if (showit || atom->SLOT)
- printf("%s%s%s%s%s",
- atom->SLOT ?
":" : "<unset>",
- atom->SLOT ?
atom->SLOT : "",
- atom->SUBSLOT ?
"/" : "",
- atom->SUBSLOT ?
atom->SUBSLOT : "",
-
atom_slotdep_str[atom->slotdep]);
- } else if (!strncmp("REPO", fmt, len)) {
- if (showit || atom->REPO)
- printf("::%s", HN(atom->REPO));
- } else if (!strncmp("pfx", fmt, len)) {
- if (showit || atom->pfx_op !=
ATOM_OP_NONE)
- printf("%s", atom->pfx_op ==
ATOM_OP_NONE ?
- "<unset>" :
atom_op_str[atom->pfx_op]);
- } else if (!strncmp("sfx", fmt, len)) {
- if (showit || atom->sfx_op !=
ATOM_OP_NONE)
- printf("%s", atom->sfx_op ==
ATOM_OP_NONE ?
- "<unset>" :
atom_op_str[atom->sfx_op]);
- } else
- printf("<BAD:%.*s>", (int)len, fmt);
- ++p;
-#undef HN
- } else
- p = fmt + 1;
- } else
- ++p;
- }
-}
-
int qatom_main(int argc, char **argv)
{
enum qatom_atom { _EXPLODE=0, _COMPARE, _PRINT } action = _EXPLODE;
@@ -168,8 +77,7 @@ int qatom_main(int argc, char **argv)
atom_implode(atomc);
break;
case _EXPLODE:
- qatom_printf(format, atom, verbose);
- putchar('\n');
+ printf("%s\n", atom_format(format, atom, verbose));
break;
case _PRINT:
printf("%s\n", atom_to_string(atom));