typo in BootstrapFS dependency
[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.7 2007/07/23 15:12:44 mef Exp $
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <libgen.h>
16 #include <errno.h>
17 #include <rpm/rpmlib.h>
18 #include <rpm/rpmts.h>
19 #include <rpm/rpmcli.h>
20 #include <rpm/rpmbuild.h>
21 #include <rpm/rpmspec.h>
22
23 /* the structure describing the options we take and the defaults */
24 static struct poptOption optionsTable[] = {
25         { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
26           "Common options for all rpm modes and executables:",
27           NULL },
28
29         POPT_AUTOALIAS
30         POPT_AUTOHELP
31         POPT_TABLEEND
32 };
33
34 /* Stolen from rpm/build/spec.c:rpmspecQuery() */
35 Spec
36 rpmspecGet(rpmts ts, const char * arg)
37 {
38         char * buildRoot = NULL;
39         int recursing = 0;
40         char * passPhrase = "";
41         char *cookie = NULL;
42         int anyarch = 1;
43         int force = 1;
44
45         if (parseSpec(ts, arg, "/", buildRoot, recursing, passPhrase,
46                       cookie, anyarch, force)) {
47                 fprintf(stderr, "query of specfile %s failed, can't parse\n", arg);
48                 return NULL;
49         }
50
51         return rpmtsSpec(ts);
52 }
53
54 int
55 main(int argc, char *argv[])
56 {
57         poptContext context;
58         rpmts ts = NULL;
59         int ec = 0;
60         Spec spec;
61         struct Source *source;
62         Package pkg;
63         const char *name, *version, *release, *arch, *unused;
64
65         /* BEGIN: support to pull out --target from the args list */
66         int  alen, i;
67         char *target = NULL;
68         int args = 1;
69         int tlen = strlen("--target");
70
71         /* walk argv list looking for --target */
72         while ((args+1)<argc) {
73           if(strncmp(argv[args],"--target",tlen)==0){
74             char **dash;
75
76             /* get arch component of the --target option */
77             dash = (char**)strchr(argv[args+1],'-');
78             if (dash != NULL) *dash=NULL;
79
80             /* copy arch component of --target option to target */
81             alen = strnlen(argv[args+1],32);
82             target = (char*)malloc(alen+1);
83             if (target == NULL) return errno;
84             strncpy(target,argv[args+1],alen);
85             target[alen]='\0';
86
87             /* change argc, argv to take out the "--target xxx" */
88             for (i=args;i<argc;i++) argv[i]=argv[i+2];
89             argc-=2;
90
91             break;
92           }
93           args++;
94         }
95         argv[1]=argv[argc-1];
96         argv[2]=0;
97         argc=2;
98         /* END: support to pull out --target from the args list */
99
100         /* Parse common options for all rpm modes and executables */
101         context = rpmcliInit(argc, argv, optionsTable);
102
103         /* Create transaction state */
104         ts = rpmtsCreate();
105
106         /* Parse spec file. The rpmcli functions don't allow you to
107          * access the Spec structure directly, so we call our own
108          * version of rpmSpecQuery() directly. */
109         spec = rpmspecGet(ts, argv[1]);
110         if (!spec)
111                 goto done;
112
113         /* Print sources */
114         for (source = spec->sources; source; source = source->next) {
115                 char fullSource[PATH_MAX];
116
117                 strncpy(fullSource, source->fullSource, sizeof(fullSource));
118                 printf("SOURCES += SOURCES/%s\n", basename(fullSource));
119         }
120
121         /* Get SRPM name from name of first package */ 
122         pkg = spec->packages;
123         name = version = release = NULL;
124         (void) headerNVR(pkg->header, &name, &version, &release);
125         if (name && version && release)
126                 printf("SRPM := SRPMS/%s-%s-%s.src.rpm\n",
127                        name, version, release);
128
129         /* Print non-empty packages */
130         for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
131                 name = version = release = arch = NULL;
132                 (void) headerNEVRA(pkg->header, &name, &unused, &version, &release, &arch);
133                 if (name && version && release && arch) {
134                         if (!pkg->fileList)
135                                 printf("# Empty\n# ");
136
137                         if (target != NULL) {
138                           if (strcmp(arch,target)!=0) {
139                             arch=target;
140                           }
141                         }
142                         printf("RPMS += RPMS/%s/%s-%s-%s.%s.rpm\n",
143                                arch, name, version, release, arch);
144                 }
145         }
146
147         spec = freeSpec(spec);
148
149  done:
150         ts = rpmtsFree(ts);
151         context = rpmcliFini(context);
152         return ec;
153