macro expansion (and absolute path) in %files -f arg (#9508,#9091).
[platform/upstream/rpm.git] / build / parseFiles.c
1 /** \file build/parseFiles.c
2  *  Parse %files section from spec file.
3  */
4
5 #include "system.h"
6
7 #include "rpmbuild.h"
8
9 /* These have to be global scope to make up for *stupid* compilers */
10     /*@observer@*/ /*@null@*/ static const char *name = NULL;
11     /*@observer@*/ /*@null@*/ static const char *file = NULL;
12     static struct poptOption optionsTable[] = {
13         { NULL, 'n', POPT_ARG_STRING, &name, 'n',       NULL, NULL},
14         { NULL, 'f', POPT_ARG_STRING, &file, 'f',       NULL, NULL},
15         { 0, 0, 0, 0, 0,        NULL, NULL}
16     };
17
18 /** */
19 int parseFiles(Spec spec)
20 {
21     int nextPart;
22     Package pkg;
23     int rc, argc;
24     int arg;
25     const char **argv = NULL;
26     int flag = PART_SUBNAME;
27     poptContext optCon = NULL;
28
29     name = file = NULL;
30
31     if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
32         rpmError(RPMERR_BADSPEC, _("line %d: Error parsing %%files: %s"),
33                  spec->lineNum, poptStrerror(rc));
34         rc = RPMERR_BADSPEC;
35         goto exit;
36     }
37
38     optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
39     while ((arg = poptGetNextOpt(optCon)) > 0) {
40         if (arg == 'n') {
41             flag = PART_NAME;
42         }
43     }
44
45     if (arg < -1) {
46         rpmError(RPMERR_BADSPEC, _("line %d: Bad option %s: %s"),
47                  spec->lineNum,
48                  poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
49                  spec->line);
50         rc = RPMERR_BADSPEC;
51         goto exit;
52     }
53
54     if (poptPeekArg(optCon)) {
55         if (name == NULL)
56             name = poptGetArg(optCon);
57         if (poptPeekArg(optCon)) {
58             rpmError(RPMERR_BADSPEC, _("line %d: Too many names: %s"),
59                      spec->lineNum,
60                      spec->line);
61             rc = RPMERR_BADSPEC;
62             goto exit;
63         }
64     }
65
66     if (lookupPackage(spec, name, flag, &pkg)) {
67         rpmError(RPMERR_BADSPEC, _("line %d: Package does not exist: %s"),
68                  spec->lineNum, spec->line);
69         rc = RPMERR_BADSPEC;
70         goto exit;
71     }
72
73     if (pkg->fileList != NULL) {
74         rpmError(RPMERR_BADSPEC, _("line %d: Second %%files list"),
75                  spec->lineNum);
76         rc = RPMERR_BADSPEC;
77         goto exit;
78     }
79
80     if (file)  {
81     /* XXX not necessary as readline has expanded already, but won't hurt.  */
82         pkg->fileFile = rpmGetPath(file, NULL);
83     }
84
85     pkg->fileList = newStringBuf();
86     
87     if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
88         nextPart = PART_NONE;
89     } else {
90         if (rc)
91             goto exit;
92         while (! (nextPart = isPart(spec->line))) {
93             appendStringBuf(pkg->fileList, spec->line);
94             if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
95                 nextPart = PART_NONE;
96                 break;
97             }
98             if (rc)
99                 goto exit;
100         }
101     }
102     rc = nextPart;
103
104 exit:
105     if (argv)
106         FREE(argv);
107     if (optCon)
108         poptFreeContext(optCon);
109         
110     return rc;
111 }