rpm 5.3.7

build/parseReqs.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include <rpmio.h>
00009 #include <rpmiotypes.h>
00010 #include <rpmlog.h>
00011 #define _RPMEVR_INTERNAL
00012 #include "rpmbuild.h"
00013 #include "debug.h"
00014 
00015 /*@access EVR_t @*/
00016 
00017 #define SKIPWHITE(_x)   {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
00018 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
00019 
00020 rpmRC parseRCPOT(Spec spec, Package pkg, const char *field, rpmTag tagN,
00021                rpmuint32_t index, rpmsenseFlags tagflags)
00022 {
00023     EVR_t evr = alloca(sizeof(*evr));
00024     const char *r, *re, *v, *ve;
00025     char * N = NULL;
00026     char * EVR = NULL;
00027     rpmsenseFlags Flags;
00028     Header h;
00029     rpmRC rc = RPMRC_FAIL;      /* assume failure */
00030     int ix;
00031 
00032     switch (tagN) {
00033     case RPMTAG_PROVIDEFLAGS:
00034         tagflags |= RPMSENSE_PROVIDES;
00035         h = pkg->header;
00036         break;
00037     case RPMTAG_OBSOLETEFLAGS:
00038         tagflags |= RPMSENSE_OBSOLETES;
00039         h = pkg->header;
00040         break;
00041     case RPMTAG_CONFLICTFLAGS:
00042         tagflags |= RPMSENSE_CONFLICTS;
00043         h = pkg->header;
00044         break;
00045     case RPMTAG_BUILDCONFLICTS:
00046         tagflags |= RPMSENSE_CONFLICTS;
00047         h = spec->sourceHeader;
00048         break;
00049     case RPMTAG_PREREQ:
00050         tagflags |= RPMSENSE_ANY;
00051         h = pkg->header;
00052         break;
00053     case RPMTAG_TRIGGERPREIN:
00054         tagflags |= RPMSENSE_TRIGGERPREIN;
00055         h = pkg->header;
00056         break;
00057     case RPMTAG_TRIGGERIN:
00058         tagflags |= RPMSENSE_TRIGGERIN;
00059         h = pkg->header;
00060         break;
00061     case RPMTAG_TRIGGERPOSTUN:
00062         tagflags |= RPMSENSE_TRIGGERPOSTUN;
00063         h = pkg->header;
00064         break;
00065     case RPMTAG_TRIGGERUN:
00066         tagflags |= RPMSENSE_TRIGGERUN;
00067         h = pkg->header;
00068         break;
00069     case RPMTAG_BUILDSUGGESTS:
00070     case RPMTAG_BUILDENHANCES:
00071         tagflags |= RPMSENSE_MISSINGOK;
00072         h = spec->sourceHeader;
00073         break;
00074     case RPMTAG_BUILDPREREQ:
00075     case RPMTAG_BUILDREQUIRES:
00076         tagflags |= RPMSENSE_ANY;
00077         h = spec->sourceHeader;
00078         break;
00079     case RPMTAG_BUILDPROVIDES:
00080         tagflags |= RPMSENSE_PROVIDES;
00081         h = spec->sourceHeader;
00082         break;
00083     case RPMTAG_BUILDOBSOLETES:
00084         tagflags |= RPMSENSE_OBSOLETES;
00085         h = spec->sourceHeader;
00086         break;
00087     default:
00088     case RPMTAG_REQUIREFLAGS:
00089         tagflags |= RPMSENSE_ANY;
00090         h = pkg->header;
00091         break;
00092     }
00093 
00094     for (r = field; *r != '\0'; r = re) {
00095         size_t nr;
00096         SKIPWHITE(r);
00097         if (*r == '\0')
00098             break;
00099 
00100         Flags = (tagflags & ~RPMSENSE_SENSEMASK);
00101 
00102         re = r;
00103         SKIPNONWHITE(re);
00104         N = xmalloc((re-r) + 1);
00105         strncpy(N, r, (re-r));
00106         N[re-r] = '\0';
00107 
00108         /* N must begin with alphanumeric, _, or /, or a macro. */
00109         nr = strlen(N);
00110         ix = 0;
00111         if (N[ix] == '!')
00112             ix++;
00113         if (!(xisalnum(N[ix]) || N[ix] == '_' || N[ix] == '/'
00114          || (nr > 5 && N[ix] == '%' && N[ix+1] == '{' && N[nr-1] == '}')))
00115         {
00116             rpmlog(RPMLOG_ERR,
00117                      _("line %d: Dependency \"%s\" must begin with alpha-numeric, '_' or '/': %s\n"),
00118                      spec->lineNum, N, spec->line);
00119             goto exit;
00120         }
00121 
00122         /* Parse EVR */
00123         v = re;
00124         SKIPWHITE(v);
00125         ve = v;
00126         SKIPNONWHITE(ve);
00127 
00128         re = v; /* ==> next token (if no EVR found) starts here */
00129 
00130         /* Check for possible logical operator */
00131         if (ve > v) {
00132 /*@-mods@*/
00133             rpmsenseFlags F = rpmEVRflags(v, &ve);
00134 /*@=mods@*/
00135             if (F && r[0] == '/') {
00136                 rpmlog(RPMLOG_ERR,
00137                          _("line %d: Versioned file name not permitted: %s\n"),
00138                          spec->lineNum, spec->line);
00139                 goto exit;
00140             }
00141             if (F) {
00142                 /* now parse EVR */
00143                 v = ve;
00144                 SKIPWHITE(v);
00145                 ve = v;
00146                 SKIPNONWHITE(ve);
00147             }
00148             Flags &= ~RPMSENSE_SENSEMASK;
00149             Flags |= F;
00150         }
00151 
00152         if (Flags & RPMSENSE_SENSEMASK) {
00153             char * t;
00154 
00155             EVR = t = xmalloc((ve-v) + 1);
00156             nr = 0;
00157             while (v < ve && *v != '\0')
00158             switch ((int)*v) {
00159             case '-':   nr++;   /*@fallthrough@*/
00160             default:    *t++ = *v++;    break;
00161             }
00162             *t = '\0';
00163 
00164             if (*EVR == '\0') {
00165                 rpmlog(RPMLOG_ERR, _("line %d: %s must be specified: %s\n"),
00166                         spec->lineNum, "EVR", spec->line);
00167                 goto exit;
00168             }
00169             if (nr > 1) {
00170                 rpmlog(RPMLOG_ERR, _("line %d: Illegal char '-' in %s: %s\n"),
00171                         spec->lineNum, "EVR", spec->line);
00172                 goto exit;
00173             }
00174             /* EVR must be parseable (or a macro). */
00175             ix = 0;
00176             nr = strlen(EVR);
00177             if (!(nr > 3 && EVR[0] == '%' && EVR[1] == '{' && EVR[nr-1] == '}'))
00178             {
00179                 memset(evr, 0, sizeof(*evr));
00180                 ix = rpmEVRparse(xstrdup(EVR), evr);
00181                 evr->str = _free(evr->str);
00182             }
00183             if (ix != 0) {
00184                 rpmlog(RPMLOG_ERR, _("line %d: %s does not parse: %s\n"),
00185                          spec->lineNum, "EVR", spec->line);
00186                 goto exit;
00187             }
00188             re = ve;    /* ==> next token after EVR string starts here */
00189         } else
00190             EVR = NULL;
00191 
00192         (void) addReqProv(spec, h, tagN, N, EVR, Flags, index);
00193 
00194         N = _free(N);
00195         EVR = _free(EVR);
00196 
00197     }
00198     rc = RPMRC_OK;
00199 
00200 exit:
00201     N = _free(N);
00202     EVR = _free(EVR);
00203     return rc;
00204 }