1/*
2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "Dependency.h"
8
9#include <stdlib.h>
10#include <string.h>
11
12#include <AutoDeleter.h>
13
14#include "Version.h"
15
16
17Dependency::Dependency(::Package* package)
18	:
19	fPackage(package),
20	fFamily(NULL),
21	fResolvable(NULL),
22	fName(),
23	fFileName(),
24	fVersion(NULL),
25	fVersionOperator(B_PACKAGE_RESOLVABLE_OP_EQUAL)
26{
27}
28
29
30Dependency::~Dependency()
31{
32	delete fVersion;
33}
34
35
36status_t
37Dependency::Init(const char* name)
38{
39	if (!fName.SetTo(name))
40		return B_NO_MEMORY;
41
42	// If the name contains a ':', replace it with '~' in the file name. We do
43	// that so that a path containing the symlink can be used in colon-separated
44	// search paths.
45	if (strchr(name, ':') != NULL) {
46		char* fileName = strdup(name);
47		if (fileName == NULL)
48			return B_NO_MEMORY;
49		MemoryDeleter fileNameDeleter(fileName);
50
51		char* remainder = fileName;
52		while (char* colon = strchr(remainder, ':')) {
53			*colon = '~';
54			remainder = colon + 1;
55		}
56
57		if (!fFileName.SetTo(fileName))
58			return B_NO_MEMORY;
59	} else
60		fFileName = fName;
61
62	return B_OK;
63}
64
65
66void
67Dependency::SetVersionRequirement(BPackageResolvableOperator op,
68	Version* version)
69{
70	fVersionOperator = op;
71	fVersion = version;
72}
73
74
75bool
76Dependency::ResolvableVersionMatches(Version* resolvableVersion) const
77{
78	if (fVersion == NULL)
79		return true;
80
81	return resolvableVersion != NULL
82		&& resolvableVersion->Compare(fVersionOperator, *fVersion);
83}
84
85
86bool
87Dependency::ResolvableCompatibleVersionMatches(Version* resolvableVersion) const
88{
89	if (fVersion == NULL)
90		return true;
91
92	// Only compare the versions, if the operator indicates that our version is
93	// some kind of minimum required version. Only in that case the resolvable's
94	// actual version is required to be greater (or equal) and the backwards
95	// compatibility check makes sense.
96	if (fVersionOperator == B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL
97		|| fVersionOperator == B_PACKAGE_RESOLVABLE_OP_GREATER) {
98		return resolvableVersion != NULL
99			&& fVersion->Compare(*resolvableVersion) >= 0;
100	}
101
102	return true;
103}
104