aboutsummaryrefslogtreecommitdiff
blob: c1af10dec83169659aeaf8173a3e700bec6ae98c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
 * Copyright 2005-2019 Gentoo Foundation
 * Distributed under the terms of the GNU General Public License v2
 *
 * Copyright 2005-2008 Ned Ludd        - <solar@gentoo.org>
 * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
 */

#include "main.h"

#include <stdlib.h>
#include <stdbool.h>

#include "atom.h"
#include "applets.h"

#define QATOM_FORMAT "%{CATEGORY} %{PN} %{PV} %[PR] %[SLOT] %[pfx] %[sfx]"

#define QATOM_FLAGS "F:c" COMMON_FLAGS
static struct option const qatom_long_opts[] = {
	{"format",     a_argument, NULL, 'F'},
	{"compare",   no_argument, NULL, 'c'},
	COMMON_LONG_OPTS
};
static const char * const qatom_opts_help[] = {
	"Custom output format (default: " QATOM_FORMAT ")",
	"Compare two atoms",
	COMMON_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", atom->SLOT ? atom->SLOT : "-");
				} 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)
						fputs(atom->pfx_op == ATOM_OP_NONE ?
								"-" : atom_op_str[atom->pfx_op], stdout);
				} else if (!strncmp("sfx", fmt, len)) {
					if (showit || atom->sfx_op != ATOM_OP_NONE)
						fputs(atom->sfx_op == ATOM_OP_NONE ?
								"-" : atom_op_str[atom->sfx_op], stdout);
				} 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 } action = _EXPLODE;
	const char *format = QATOM_FORMAT;
	depend_atom *atom;
	int i;

	while ((i = GETOPT_LONG(QATOM, qatom, "")) != -1) {
		switch (i) {
		case 'F': format = optarg; break;
		case 'c': action = _COMPARE; break;
		COMMON_GETOPTS_CASES(qatom)
		}
	}

	if (argc == optind)
		qatom_usage(EXIT_FAILURE);

	if (action == _COMPARE && (argc - optind) % 2)
		err("compare needs even number of arguments");

	for (i = optind; i < argc; ++i) {
		switch (action) {
		case _COMPARE:
			printf("%s %s %s\n", argv[i],
					booga[atom_compare_str(argv[i], argv[i+1])], argv[i+1]);
			++i;
			break;
		case _EXPLODE:
			atom = atom_explode(argv[i]);
			qatom_printf(format, atom, verbose);
			putchar('\n');
			atom_implode(atom);
			break;
		}
	}

	return EXIT_SUCCESS;
}