- only print non-empty packages
[build.git] / parseSpec.c
1 /*
2  * Parses RPM spec file into Makefile fragment. See
3  *
4  * http://fedora.redhat.com/docs/drafts/rpm-guide-en/ch-programming-c.html
5  *
6  * Mark Huang <mlhuang@cs.princeton.edu>
7  * Copyright (C) 2006 The Trustees of Princeton University
8  *
9  * $Id: parseSpec.c,v 1.2 2006/03/08 21:48:42 mlhuang Exp $
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <libgen.h>
16 #include <rpm/rpmlib.h>
17 #include <rpm/rpmts.h>
18 #include <rpm/rpmcli.h>
19 #include <rpm/rpmbuild.h>
20 #include <rpm/rpmspec.h>
21
22 /* the structure describing the options we take and the defaults */
23 static struct poptOption optionsTable[] = {
24         { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
25           "Common options for all rpm modes and executables:",
26           NULL },
27
28         POPT_AUTOALIAS
29         POPT_AUTOHELP
30         POPT_TABLEEND
31 };
32
33 /* Stolen from rpm/build/spec.c:rpmspecQuery() */
34 Spec
35 rpmspecGet(rpmts ts, const char * arg)
36 {
37         char * buildRoot = NULL;
38         int recursing = 0;
39         char * passPhrase = "";
40         char *cookie = NULL;
41         int anyarch = 1;
42         int force = 1;
43
44         if (parseSpec(ts, arg, "/", buildRoot, recursing, passPhrase,
45                       cookie, anyarch, force)) {
46                 fprintf(stderr, "query of specfile %s failed, can't parse\n", arg);
47                 return NULL;
48         }
49
50         return rpmtsSpec(ts);
51 }
52
53 int
54 main(int argc, char *const argv[])
55 {
56         poptContext context;
57         rpmts ts = NULL;
58         int ec = 0;
59         Spec spec;
60         struct Source *source;
61         Package pkg;
62         const char *name, *version, *release, *arch, *unused;
63
64         /* Parse common options for all rpm modes and executables */
65         context = rpmcliInit(argc, argv, optionsTable);
66
67         /* Create transaction state */
68         ts = rpmtsCreate();
69
70         /* Parse spec file. The rpmcli functions don't allow you to
71          * access the Spec structure directly, so we call our own
72          * version of rpmSpecQuery() directly. */
73         spec = rpmspecGet(ts, argv[1]);
74         if (!spec)
75                 goto done;
76
77         /* Print sources */
78         for (source = spec->sources; source; source = source->next) {
79                 char fullSource[PATH_MAX];
80
81                 strncpy(fullSource, source->fullSource, sizeof(fullSource));
82                 printf("SOURCES += SOURCES/%s\n", basename(fullSource));
83         }
84
85         /* Get SRPM name from name of first package */ 
86         pkg = spec->packages;
87         name = version = release = NULL;
88         (void) headerNVR(pkg->header, &name, &version, &release);
89         if (name && version && release)
90                 printf("SRPM := SRPMS/%s-%s-%s.src.rpm\n",
91                        name, version, release);
92
93         /* Print non-empty packages */
94         for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
95                 name = version = release = arch = NULL;
96                 (void) headerNEVRA(pkg->header, &name, &unused, &version, &release, &arch);
97                 if (name && version && release && arch) {
98                         if (!pkg->fileList)
99                                 printf("# Empty\n# ");
100                         printf("RPMS += RPMS/%s/%s-%s-%s.%s.rpm\n",
101                                arch, name, version, release, arch);
102                 }
103         }
104
105         spec = freeSpec(spec);
106
107  done:
108         ts = rpmtsFree(ts);
109         context = rpmcliFini(context);
110         return ec;
111