rpm  5.4.10
parseReqs.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #include <rpmio.h>
9 #include <rpmiotypes.h>
10 #include <rpmlog.h>
11 #define _RPMEVR_INTERNAL
12 #include "rpmbuild.h"
13 #include "debug.h"
14 
15 /*@access EVR_t @*/
16 
17 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
18 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
19 
20 rpmRC parseRCPOT(Spec spec, Package pkg, const char *field, rpmTag tagN,
21  rpmuint32_t index, rpmsenseFlags tagflags)
22 {
23  EVR_t evr = alloca(sizeof(*evr));
24  const char *r, *re, *v, *ve;
25  char * N = NULL;
26  char * EVR = NULL;
27  rpmsenseFlags Flags;
28  Header h;
29  rpmRC rc = RPMRC_FAIL; /* assume failure */
30  int ix;
31 
32  switch (tagN) {
34  tagflags |= RPMSENSE_PROVIDES;
35  h = pkg->header;
36  break;
38  tagflags |= RPMSENSE_OBSOLETES;
39  h = pkg->header;
40  break;
42  tagflags |= RPMSENSE_CONFLICTS;
43  h = pkg->header;
44  break;
46  tagflags |= RPMSENSE_CONFLICTS;
47  h = spec->sourceHeader;
48  break;
49  case RPMTAG_PREREQ:
50  tagflags |= RPMSENSE_ANY;
51  h = pkg->header;
52  break;
54  tagflags |= RPMSENSE_TRIGGERPREIN;
55  h = pkg->header;
56  break;
57  case RPMTAG_TRIGGERIN:
58  tagflags |= RPMSENSE_TRIGGERIN;
59  h = pkg->header;
60  break;
62  tagflags |= RPMSENSE_TRIGGERPOSTUN;
63  h = pkg->header;
64  break;
65  case RPMTAG_TRIGGERUN:
66  tagflags |= RPMSENSE_TRIGGERUN;
67  h = pkg->header;
68  break;
70  tagflags |= (RPMSENSE_TRIGGERTRANS | RPMSENSE_TRIGGERPREIN);
71  h = pkg->header;
72  break;
74  tagflags |= (RPMSENSE_TRIGGERTRANS | RPMSENSE_TRIGGERUN);
75  h = pkg->header;
76  break;
78  tagflags |= (RPMSENSE_TRIGGERTRANS | RPMSENSE_TRIGGERIN);
79  h = pkg->header;
80  break;
82  tagflags |= (RPMSENSE_TRIGGERTRANS | RPMSENSE_TRIGGERPOSTUN);
83  h = pkg->header;
84  break;
87  tagflags |= RPMSENSE_MISSINGOK;
88  h = spec->sourceHeader;
89  break;
90  case RPMTAG_BUILDPREREQ:
92  tagflags |= RPMSENSE_ANY;
93  h = spec->sourceHeader;
94  break;
96  tagflags |= RPMSENSE_PROVIDES;
97  h = spec->sourceHeader;
98  break;
100  tagflags |= RPMSENSE_OBSOLETES;
101  h = spec->sourceHeader;
102  break;
103  default:
104  case RPMTAG_REQUIREFLAGS:
105  tagflags |= RPMSENSE_ANY;
106  h = pkg->header;
107  break;
108  }
109 
110  for (r = field; *r != '\0'; r = re) {
111  size_t nr;
112  SKIPWHITE(r);
113  if (*r == '\0')
114  break;
115 
116  Flags = (tagflags & ~RPMSENSE_SENSEMASK);
117 
118  re = r;
119  SKIPNONWHITE(re);
120  N = xmalloc((re-r) + 1);
121  strncpy(N, r, (re-r));
122  N[re-r] = '\0';
123 
124  /* N must begin with alphanumeric, _, or /, or a macro. */
125  nr = strlen(N);
126  ix = 0;
127  if (N[ix] == '!')
128  ix++;
129  if (!(xisalnum(N[ix]) || N[ix] == '_' || N[ix] == '/' || N[ix] == '^'
130  || (nr > 5 && N[ix] == '%' && N[ix+1] == '{' && N[nr-1] == '}')))
131  {
133  _("line %d: Dependency \"%s\" must begin with alpha-numeric, '_' or '/': %s\n"),
134  spec->lineNum, N, spec->line);
135  goto exit;
136  }
137 
138  /* Parse EVR */
139  v = re;
140  SKIPWHITE(v);
141  ve = v;
142  SKIPNONWHITE(ve);
143 
144  re = v; /* ==> next token (if no EVR found) starts here */
145 
146  /* Check for possible logical operator */
147  if (ve > v) {
148 /*@-mods@*/
149  rpmsenseFlags F = rpmEVRflags(v, &ve);
150 /*@=mods@*/
151  if (F && r[0] == '/') {
153  _("line %d: Versioned file name not permitted: %s\n"),
154  spec->lineNum, spec->line);
155  goto exit;
156  }
157  if (F) {
158  /* now parse EVR */
159  v = ve;
160  SKIPWHITE(v);
161  ve = v;
162  SKIPNONWHITE(ve);
163  }
164  Flags &= ~RPMSENSE_SENSEMASK;
165  Flags |= F;
166  }
167 
168  if (Flags & RPMSENSE_SENSEMASK) {
169  char * t;
170 
171  EVR = t = xmalloc((ve-v) + 1);
172  nr = 0;
173  while (v < ve && *v != '\0')
174  switch ((int)*v) {
175  case '-': nr++; /*@fallthrough@*/
176  default: *t++ = *v++; break;
177  }
178  *t = '\0';
179 
180  if (*EVR == '\0') {
181  rpmlog(RPMLOG_ERR, _("line %d: %s must be specified: %s\n"),
182  spec->lineNum, "EVR", spec->line);
183  goto exit;
184  }
185  if (nr > 1) {
186  rpmlog(RPMLOG_ERR, _("line %d: Illegal char '-' in %s: %s\n"),
187  spec->lineNum, "EVR", spec->line);
188  goto exit;
189  }
190  /* EVR must be parseable (or a macro). */
191  ix = 0;
192  nr = strlen(EVR);
193  if (!(nr > 3 && EVR[0] == '%' && EVR[1] == '{' && EVR[nr-1] == '}'))
194  {
195  memset(evr, 0, sizeof(*evr));
196  ix = rpmEVRparse(EVR, evr);
197  evr->str = _free(evr->str);
198  }
199  if (ix != 0) {
200  rpmlog(RPMLOG_ERR, _("line %d: %s does not parse: %s\n"),
201  spec->lineNum, "EVR", spec->line);
202  goto exit;
203  }
204  re = ve; /* ==> next token after EVR string starts here */
205  } else
206  EVR = NULL;
207 
208  (void) addReqProv(spec, h, tagN, N, EVR, Flags, index);
209 
210  N = _free(N);
211  EVR = _free(EVR);
212 
213  }
214  rc = RPMRC_OK;
215 
216 exit:
217  N = _free(N);
218  EVR = _free(EVR);
219  return rc;
220 }
#define RPMSENSE_SENSEMASK
Definition: rpmevr.h:74
static int xisalnum(int c)
Definition: rpmiotypes.h:440
int addReqProv(Spec spec, Header h, rpmTag tagN, const char *N, const char *EVR, rpmsenseFlags Flags, rpmuint32_t index)
Add dependency to header, filtering duplicates.
Definition: reqprov.c:16
The Header data structure.
Header sourceHeader
Definition: rpmspec.h:166
int rpmEVRparse(const char *evrstr, EVR_t evr)
Split EVR string into epoch, version, and release components.
Definition: rpmevr.c:179
struct EVR_s * EVR_t
Definition: rpmevr.h:20
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
rpmsenseFlags rpmEVRflags(const char *op, const char **end)
Return comparison operator sense flags.
Definition: rpmevr.c:400
#define SKIPWHITE(_x)
Definition: parseReqs.c:17
char * alloca()
Yet Another syslog(3) API clone.
Header header
Definition: rpmspec.h:210
unsigned int rpmuint32_t
Definition: rpmiotypes.h:25
char * line
Definition: rpmspec.h:133
enum evrFlags_e rpmsenseFlags
Definition: rpmevr.h:72
The structure used to store values parsed from a spec file.
Definition: rpmspec.h:108
enum rpmRC_e rpmRC
RPM return codes.
This is the only module users of librpmbuild should need to include.
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
rpmRC parseRCPOT(Spec spec, Package pkg, const char *field, rpmTag tagN, rpmuint32_t index, rpmsenseFlags tagflags)
Parse dependency relations from spec file and/or autogenerated output buffer.
Definition: parseReqs.c:20
int lineNum
Definition: rpmspec.h:134
#define SKIPNONWHITE(_x)
Definition: parseReqs.c:18
#define _(Text)
Definition: system.h:30
The structure used to store values for a package.
Definition: rpmspec.h:207
#define xmalloc
Definition: system.h:33
enum rpmTag_e rpmTag
Definition: rpmtag.h:471