summaryrefslogtreecommitdiff
path: root/build/parseReqs.c
blob: 87241ade21b13f404d29a12771248de10d2588a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <string.h>

#include "spec.h"
#include "rpmlib.h"
#include "reqprov.h"

static struct ReqComp {
    char *token;
    int sense;
} ReqComparisons[] = {
    { "<=", RPMSENSE_LESS | RPMSENSE_EQUAL},
    { "<=S", RPMSENSE_LESS | RPMSENSE_EQUAL | RPMSENSE_SERIAL},
    { "=<", RPMSENSE_LESS | RPMSENSE_EQUAL},
    { "=<S", RPMSENSE_LESS | RPMSENSE_EQUAL | RPMSENSE_SERIAL},
    { "<", RPMSENSE_LESS},
    { "<S", RPMSENSE_LESS | RPMSENSE_SERIAL},

    { "=", RPMSENSE_EQUAL},
    { "=S", RPMSENSE_EQUAL | RPMSENSE_SERIAL},
    
    { ">=", RPMSENSE_GREATER | RPMSENSE_EQUAL},
    { ">=S", RPMSENSE_GREATER | RPMSENSE_EQUAL | RPMSENSE_SERIAL},
    { "=>", RPMSENSE_GREATER | RPMSENSE_EQUAL},
    { "=>S", RPMSENSE_GREATER | RPMSENSE_EQUAL | RPMSENSE_SERIAL},
    { ">", RPMSENSE_GREATER},
    { ">S", RPMSENSE_GREATER | RPMSENSE_SERIAL},
    { NULL, 0 },
};

int parseRequiresConflicts(Spec spec, Package pkg, char *field, int tag)
{
    char buf[BUFSIZ], *bufp, *version, *name;
    int flags;
    char *req = NULL;
    struct ReqComp *rc;

    strcpy(buf, field);
    bufp = buf;

    while (req || (req = strtok(bufp, " ,\t\n"))) {
	bufp = NULL;
	
	if (tag == RPMTAG_CONFLICTFLAGS) {
	    if (req[0] == '/') {
		rpmError(RPMERR_BADSPEC,
			 "line %d: No file names in Conflicts: %s",
			 spec->lineNum, spec->line);
		return RPMERR_BADSPEC;
	    }
	    flags = RPMSENSE_CONFLICTS;
	    name = "Conflicts";
	} else if (tag == RPMTAG_PREREQ) {
	    flags = RPMSENSE_PREREQ;
	    name = "PreReq";
	} else {
	    flags = RPMSENSE_ANY;
	    name = "Requires";
	}

	if ((version = strtok(NULL, " ,\t\n"))) {
	    rc = ReqComparisons;
	    while (rc->token && strcmp(version, rc->token)) {
		rc++;
	    }
	    if (rc->token) {
		if (req[0] == '/') {
		    rpmError(RPMERR_BADSPEC,
			     "line %d: No versions on file names in %s: %s",
			     spec->lineNum, name, spec->line);
		    return RPMERR_BADSPEC;
		}
		if (tag == RPMTAG_PREREQ) {
		    rpmError(RPMERR_BADSPEC,
			     "line %d: No versions in PreReq: %s",
			     spec->lineNum, spec->line);
		    return RPMERR_BADSPEC;
		}
		/* read a version */
		flags |= rc->sense;
		version = strtok(NULL, " ,\t\n");
	    }
	}

	if ((flags & RPMSENSE_SENSEMASK) && !version) {
	    rpmError(RPMERR_BADSPEC,
		     "line %d: Version required in %s: %s",
		     spec->lineNum, name, spec->line);
	    return RPMERR_BADSPEC;
	}

	addReqProv(spec, pkg, flags, req,
		   (flags & RPMSENSE_SENSEMASK) ? version : NULL);

	/* If there is no sense, we just read the next token */
	req = (flags & RPMSENSE_SENSEMASK) ? NULL : version;
    }

    return 0;
}

int parseProvidesObsoletes(Spec spec, Package pkg, char *field, int tag)
{
    char *prov, buf[BUFSIZ], *line;
    int flags;

    flags = (tag == RPMTAG_PROVIDES) ? RPMSENSE_PROVIDES : RPMSENSE_OBSOLETES;

    strcpy(buf, field);
    line = buf;
    
    while ((prov = strtok(line, " ,\t\n"))) {
	if (prov[0] == '/') {
	    rpmError(RPMERR_BADSPEC,
		     "line %d: No file names in %s: %s",
		     spec->lineNum,
		     (tag == RPMTAG_PROVIDES) ? "Provides" : "Obsoletes",
		     spec->line);
	    return RPMERR_BADSPEC;
	}
	addReqProv(spec, pkg, flags, prov, NULL);
	line = NULL;
    }

    return 0;
}