rpm  5.2.1
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     const char *r, *re, *v, *ve;
00024     char * N, * EVR;
00025     rpmsenseFlags Flags;
00026     Header h;
00027 
00028     switch (tagN) {
00029     case RPMTAG_PROVIDEFLAGS:
00030         tagflags |= RPMSENSE_PROVIDES;
00031         h = pkg->header;
00032         break;
00033     case RPMTAG_OBSOLETEFLAGS:
00034         tagflags |= RPMSENSE_OBSOLETES;
00035         h = pkg->header;
00036         break;
00037     case RPMTAG_CONFLICTFLAGS:
00038         tagflags |= RPMSENSE_CONFLICTS;
00039         h = pkg->header;
00040         break;
00041     case RPMTAG_BUILDCONFLICTS:
00042         tagflags |= RPMSENSE_CONFLICTS;
00043         h = spec->sourceHeader;
00044         break;
00045     case RPMTAG_PREREQ:
00046         tagflags |= RPMSENSE_ANY;
00047         h = pkg->header;
00048         break;
00049     case RPMTAG_TRIGGERPREIN:
00050         tagflags |= RPMSENSE_TRIGGERPREIN;
00051         h = pkg->header;
00052         break;
00053     case RPMTAG_TRIGGERIN:
00054         tagflags |= RPMSENSE_TRIGGERIN;
00055         h = pkg->header;
00056         break;
00057     case RPMTAG_TRIGGERPOSTUN:
00058         tagflags |= RPMSENSE_TRIGGERPOSTUN;
00059         h = pkg->header;
00060         break;
00061     case RPMTAG_TRIGGERUN:
00062         tagflags |= RPMSENSE_TRIGGERUN;
00063         h = pkg->header;
00064         break;
00065     case RPMTAG_BUILDSUGGESTS:
00066     case RPMTAG_BUILDENHANCES:
00067         tagflags |= RPMSENSE_MISSINGOK;
00068         h = spec->sourceHeader;
00069         break;
00070     case RPMTAG_BUILDPREREQ:
00071     case RPMTAG_BUILDREQUIRES:
00072         tagflags |= RPMSENSE_ANY;
00073         h = spec->sourceHeader;
00074         break;
00075     case RPMTAG_BUILDPROVIDES:
00076         tagflags |= RPMSENSE_PROVIDES;
00077         h = spec->sourceHeader;
00078         break;
00079     case RPMTAG_BUILDOBSOLETES:
00080         tagflags |= RPMSENSE_OBSOLETES;
00081         h = spec->sourceHeader;
00082         break;
00083     default:
00084     case RPMTAG_REQUIREFLAGS:
00085         tagflags |= RPMSENSE_ANY;
00086         h = pkg->header;
00087         break;
00088     }
00089 
00090     for (r = field; *r != '\0'; r = re) {
00091         size_t nr;
00092         SKIPWHITE(r);
00093         if (*r == '\0')
00094             break;
00095 
00096         Flags = (tagflags & ~RPMSENSE_SENSEMASK);
00097 
00098         /* Tokens must begin with alphanumeric, _, or / */
00099         nr = strlen(r);
00100         if (!(xisalnum(r[0]) || r[0] == '_' || r[0] == '/'
00101          || (nr > 2 && r[0] == '!')
00102          || (nr > 3 && r[0] == '%' && r[1] == '{' && r[nr-1] == '}')))
00103         {
00104             rpmlog(RPMLOG_ERR,
00105                      _("line %d: Dependency \"%s\" must begin with alpha-numeric, '_' or '/': %s\n"),
00106                      spec->lineNum, spec->line, r);
00107             return RPMRC_FAIL;
00108         }
00109 
00110         re = r;
00111         SKIPNONWHITE(re);
00112         N = xmalloc((re-r) + 1);
00113         strncpy(N, r, (re-r));
00114         N[re-r] = '\0';
00115 
00116         /* Parse EVR */
00117         v = re;
00118         SKIPWHITE(v);
00119         ve = v;
00120         SKIPNONWHITE(ve);
00121 
00122         re = v; /* ==> next token (if no EVR found) starts here */
00123 
00124         /* Check for possible logical operator */
00125         if (ve > v) {
00126 /*@-mods@*/
00127             rpmsenseFlags F = rpmEVRflags(v, &ve);
00128 /*@=mods@*/
00129             if (F && r[0] == '/') {
00130                 rpmlog(RPMLOG_ERR,
00131                          _("line %d: Versioned file name not permitted: %s\n"),
00132                          spec->lineNum, spec->line);
00133                 return RPMRC_FAIL;
00134             }
00135             if (F) {
00136                 /* now parse EVR */
00137                 v = ve;
00138                 SKIPWHITE(v);
00139                 ve = v;
00140                 SKIPNONWHITE(ve);
00141             }
00142             Flags &= ~RPMSENSE_SENSEMASK;
00143             Flags |= F;
00144         }
00145 
00146         if (Flags & RPMSENSE_SENSEMASK) {
00147             if (*v == '\0' || ve == v) {
00148                 rpmlog(RPMLOG_ERR, _("line %d: Version required: %s\n"),
00149                         spec->lineNum, spec->line);
00150                 return RPMRC_FAIL;
00151             }
00152             EVR = xmalloc((ve-v) + 1);
00153             strncpy(EVR, v, (ve-v));
00154             EVR[ve-v] = '\0';
00155             re = ve;    /* ==> next token after EVR string starts here */
00156         } else
00157             EVR = NULL;
00158 
00159         /* Make sure that EVR is parseable during install. */
00160         if (EVR != NULL) {
00161             EVR_t evr = memset(alloca(sizeof(*evr)), 0, sizeof(*evr));
00162             int xx = rpmEVRparse(xstrdup(EVR), evr);
00163 
00164             evr->str = _free(evr->str);
00165             if (xx != 0) {
00166                 rpmlog(RPMLOG_ERR,
00167                          _("line %d: EVR does not parse: %s\n"),
00168                          spec->lineNum, spec->line);
00169                 N = _free(N);
00170                 EVR = _free(EVR);
00171                 return RPMRC_FAIL;
00172             }
00173         }
00174 
00175         (void) addReqProv(spec, h, tagN, N, EVR, Flags, index);
00176 
00177         N = _free(N);
00178         EVR = _free(EVR);
00179 
00180     }
00181 
00182     return RPMRC_OK;
00183 }