Imported Upstream version 4.14.1
[platform/upstream/rpm.git] / build / parseFiles.c
1 /** \ingroup rpmbuild
2  * \file build/parseFiles.c
3  *  Parse %files section from spec file.
4  */
5
6 #include "system.h"
7
8 #include <rpm/rpmlog.h>
9 #include <rpm/rpmfileutil.h>
10 #include "build/rpmbuild_internal.h"
11 #include "debug.h"
12
13 int parseFiles(rpmSpec spec)
14 {
15     int nextPart, res = PART_ERROR;
16     Package pkg;
17     int rc, argc;
18     int arg;
19     const char ** argv = NULL;
20     const char *name = NULL;
21     int flag = PART_SUBNAME;
22     poptContext optCon = NULL;
23     struct poptOption optionsTable[] = {
24         { NULL, 'n', POPT_ARG_STRING, &name, 'n', NULL, NULL},
25         { NULL, 'f', POPT_ARG_STRING, NULL, 'f', NULL, NULL},
26         { 0, 0, 0, 0, 0, NULL, NULL}
27     };
28
29     /* XXX unmask %license while parsing %files */
30     rpmPushMacro(spec->macros, "license", NULL, "%%license", RMIL_SPEC);
31
32     if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
33         rpmlog(RPMLOG_ERR, _("line %d: Error parsing %%files: %s\n"),
34                  spec->lineNum, poptStrerror(rc));
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         rpmlog(RPMLOG_ERR, _("line %d: Bad option %s: %s\n"),
47                  spec->lineNum,
48                  poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
49                  spec->line);
50         goto exit;
51     }
52
53     if (poptPeekArg(optCon)) {
54         if (name == NULL)
55             name = poptGetArg(optCon);
56         if (poptPeekArg(optCon)) {
57             rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"),
58                      spec->lineNum,
59                      spec->line);
60             goto exit;
61         }
62     }
63
64     if (lookupPackage(spec, name, flag, &pkg))
65         goto exit;
66
67     /*
68      * This should be an error, but its surprisingly commonly abused for the
69      * effect of multiple -f arguments in versions that dont support it.
70      * Warn but preserve behavior, except for leaking memory.
71      */
72     if (pkg->fileList != NULL) {
73         rpmlog(RPMLOG_WARNING, _("line %d: multiple %%files for package '%s'\n"),
74                spec->lineNum, rpmstrPoolStr(pkg->pool, pkg->name));
75         pkg->fileList = argvFree(pkg->fileList);
76     }
77
78     for (arg=1; arg<argc; arg++) {
79         if (rstreq(argv[arg], "-f") && argv[arg+1]) {
80             char *file = rpmGetPath(argv[arg+1], NULL);
81             argvAdd(&(pkg->fileFile), file);
82             free(file);
83         }
84     }
85
86     pkg->fileList = argvNew();
87
88     if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
89         nextPart = PART_NONE;
90     } else if (rc < 0) {
91         goto exit;
92     } else {
93         while (! (nextPart = isPart(spec->line))) {
94             argvAdd(&(pkg->fileList), spec->line);
95             if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
96                 nextPart = PART_NONE;
97                 break;
98             } else if (rc < 0) {
99                 goto exit;
100             }
101         }
102     }
103     res = nextPart;
104
105 exit:
106     rpmPopMacro(NULL, "license");
107     free(argv);
108     poptFreeContext(optCon);
109         
110     return res;
111 }