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

Reply via email to