1151211Sjoel/*
2151211Sjoel * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3151211Sjoel * Distributed under the terms of the MIT License.
4151211Sjoel */
5151211Sjoel
6151211Sjoel
7151211Sjoel#include "Dependency.h"
8151211Sjoel
9151211Sjoel#include <stdlib.h>
10151211Sjoel#include <string.h>
11151211Sjoel
12151211Sjoel#include <AutoDeleter.h>
13151211Sjoel
14151211Sjoel#include "Version.h"
15151211Sjoel
16151211Sjoel
17151211SjoelDependency::Dependency(::Package* package)
18151211Sjoel	:
19151211Sjoel	fPackage(package),
20151211Sjoel	fFamily(NULL),
21151211Sjoel	fResolvable(NULL),
22151211Sjoel	fName(),
23151211Sjoel	fFileName(),
24151211Sjoel	fVersion(NULL),
25151211Sjoel	fVersionOperator(B_PACKAGE_RESOLVABLE_OP_EQUAL)
26151211Sjoel{
27152984Sjoel}
28151211Sjoel
29151211Sjoel
30151211SjoelDependency::~Dependency()
31151211Sjoel{
32151211Sjoel	delete fVersion;
33151211Sjoel}
34152984Sjoel
35152984Sjoel
36152984Sjoelstatus_t
37151211SjoelDependency::Init(const char* name)
38151211Sjoel{
39152984Sjoel	if (!fName.SetTo(name))
40151211Sjoel		return B_NO_MEMORY;
41152984Sjoel
42152984Sjoel	// If the name contains a ':', replace it with '~' in the file name. We do
43152984Sjoel	// that so that a path containing the symlink can be used in colon-separated
44152984Sjoel	// search paths.
45152984Sjoel	if (strchr(name, ':') != NULL) {
46152984Sjoel		char* fileName = strdup(name);
47152984Sjoel		if (fileName == NULL)
48151211Sjoel			return B_NO_MEMORY;
49152984Sjoel		MemoryDeleter fileNameDeleter(fileName);
50152984Sjoel
51152984Sjoel		char* remainder = fileName;
52152984Sjoel		while (char* colon = strchr(remainder, ':')) {
53152984Sjoel			*colon = '~';
54152984Sjoel			remainder = colon + 1;
55152984Sjoel		}
56151211Sjoel
57151211Sjoel		if (!fFileName.SetTo(fileName))
58151211Sjoel			return B_NO_MEMORY;
59151211Sjoel	} else
60151211Sjoel		fFileName = fName;
61151211Sjoel
62151211Sjoel	return B_OK;
63151211Sjoel}
64151211Sjoel
65151211Sjoel
66151211Sjoelvoid
67151211SjoelDependency::SetVersionRequirement(BPackageResolvableOperator op,
68151211Sjoel	Version* version)
69151211Sjoel{
70151211Sjoel	fVersionOperator = op;
71151211Sjoel	fVersion = version;
72151211Sjoel}
73151211Sjoel
74151211Sjoel
75151211Sjoelbool
76151211SjoelDependency::ResolvableVersionMatches(Version* resolvableVersion) const
77151211Sjoel{
78151211Sjoel	if (fVersion == NULL)
79151211Sjoel		return true;
80151211Sjoel
81151211Sjoel	return resolvableVersion != NULL
82151211Sjoel		&& resolvableVersion->Compare(fVersionOperator, *fVersion);
83151211Sjoel}
84151211Sjoel
85151211Sjoel
86151211Sjoelbool
87151211SjoelDependency::ResolvableCompatibleVersionMatches(Version* resolvableVersion) const
88151211Sjoel{
89151211Sjoel	if (fVersion == NULL)
90151211Sjoel		return true;
91151211Sjoel
92151211Sjoel	// Only compare the versions, if the operator indicates that our version is
93151211Sjoel	// some kind of minimum required version. Only in that case the resolvable's
94151211Sjoel	// actual version is required to be greater (or equal) and the backwards
95151211Sjoel	// compatibility check makes sense.
96151211Sjoel	if (fVersionOperator == B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL
97151211Sjoel		|| fVersionOperator == B_PACKAGE_RESOLVABLE_OP_GREATER) {
98151211Sjoel		return resolvableVersion != NULL
99151211Sjoel			&& fVersion->Compare(*resolvableVersion) >= 0;
100151211Sjoel	}
101151211Sjoel
102151211Sjoel	return true;
103151211Sjoel}
104151211Sjoel