summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/CMakeLists.txt7
-rw-r--r--ext/libsolvext.ver4
-rw-r--r--ext/repo_haiku.cpp266
-rw-r--r--ext/repo_haiku.h35
4 files changed, 312 insertions, 0 deletions
diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt
index bcd4f81..63e0dee 100644
--- a/ext/CMakeLists.txt
+++ b/ext/CMakeLists.txt
@@ -78,6 +78,13 @@ IF (ENABLE_CUDFREPO)
repo_cudf.h)
ENDIF (ENABLE_CUDFREPO)
+IF (ENABLE_HAIKU)
+ SET (libsolvext_SRCS ${libsolvext_SRCS}
+ repo_haiku.cpp)
+ SET (libsolvext_HEADERS ${libsolvext_HEADERS}
+ repo_haiku.h)
+ENDIF (ENABLE_HAIKU)
+
SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
SET (CMAKE_SHARED_LINKER_FLAGS "${LINK_FLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/ext/libsolvext.ver")
diff --git a/ext/libsolvext.ver b/ext/libsolvext.ver
index 9817339..bb0270a 100644
--- a/ext/libsolvext.ver
+++ b/ext/libsolvext.ver
@@ -12,6 +12,10 @@ SOLV_1.0 {
repo_add_debdb;
repo_add_debpackages;
repo_add_deltainfoxml;
+ repo_add_haiku_installed_packages;
+ repo_add_haiku_package;
+ repo_add_haiku_package_info;
+ repo_add_haiku_packages;
repo_add_helix;
repo_add_mdk;
repo_add_mdk_info;
diff --git a/ext/repo_haiku.cpp b/ext/repo_haiku.cpp
new file mode 100644
index 0000000..139bf50
--- /dev/null
+++ b/ext/repo_haiku.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2011-2013, Ingo Weinhold <ingo_weinhold@gmx.de>
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+#include <package/PackageInfo.h>
+#include <package/PackageInfoSet.h>
+#include <package/PackageRoster.h>
+#include <package/PackageVersion.h>
+#include <package/RepositoryCache.h>
+#include <package/RepositoryConfig.h>
+
+#include "repo_haiku.h"
+
+using namespace BPackageKit;
+using namespace BPackageKit::BHPKG;
+
+static BString haiku_version_to_string(const BPackageVersion &version)
+{
+ if (version.InitCheck() != B_OK)
+ return BString();
+
+ // compose ":<major>.<minor>.<micro>" (empty epoch)
+ BString string(":");
+ string << version.Major();
+ if (!version.Minor().IsEmpty())
+ {
+ string << '.' << version.Minor();
+ if (!version.Micro().IsEmpty())
+ string << '.' << version.Micro();
+ }
+
+ // append pre-release -- separate it with '/' to keep pool_evrcmp_str() happy
+ // (it expects only the release to be separated by '-')
+ if (!version.PreRelease().IsEmpty())
+ string << '/' << version.PreRelease();
+
+ // append revision
+ if (version.Revision() != 0)
+ string << '-' << version.Revision();
+
+ return string;
+}
+
+static void add_dependency(Repo *repo, Offset &dependencies, const char *name,
+ const char *version, int flags, const char* compatVersion = NULL)
+{
+ Pool *pool = repo->pool;
+
+ Id dependency = pool_str2id(pool, name, 1);
+
+ if (version && version[0] != '\0')
+ {
+ Id versionId = pool_str2id(pool, version, 1);
+
+ if (compatVersion && compatVersion[0] != '\0')
+ {
+ versionId = pool_rel2id(pool, pool_str2id(pool, compatVersion, 1),
+ versionId, REL_COMPAT, 1);
+ versionId = MAKERELDEP(versionId);
+ }
+
+ dependency = pool_rel2id(pool, dependency, versionId, flags, 1);
+ }
+
+ dependencies = repo_addid_dep(repo, dependencies, dependency, 0);
+}
+
+static void add_dependency(Repo *repo, Offset &dependencies, const char *name,
+ const BPackageVersion &version, int flags)
+{
+ add_dependency(repo, dependencies, name, haiku_version_to_string(version),
+ flags);
+}
+
+static void add_resolvables(Repo *repo, Offset &dependencies,
+ const BObjectList<BPackageResolvable> &resolvables)
+{
+ for (int32 i = 0; BPackageResolvable *resolvable = resolvables.ItemAt(i); i++)
+ {
+ add_dependency(repo, dependencies, resolvable->Name(),
+ haiku_version_to_string(resolvable->Version()), REL_EQ,
+ haiku_version_to_string(resolvable->CompatibleVersion()));
+ }
+}
+
+static void add_resolvable_expressions(Repo *repo, Offset &dependencies,
+ const BObjectList<BPackageResolvableExpression> &expressions)
+{
+ for (int32 i = 0;
+ BPackageResolvableExpression *expression = expressions.ItemAt(i); i++)
+ {
+ // It is possible that no version is specified. In that case any version
+ // is acceptable.
+ if (expression->Version().InitCheck() != B_OK)
+ {
+ BPackageVersion version;
+ add_dependency(repo, dependencies, expression->Name(), NULL, 0);
+ continue;
+ }
+
+ int flags = 0;
+ switch (expression->Operator())
+ {
+ case B_PACKAGE_RESOLVABLE_OP_LESS:
+ flags |= REL_LT;
+ break;
+ case B_PACKAGE_RESOLVABLE_OP_LESS_EQUAL:
+ flags |= REL_LT | REL_EQ;
+ break;
+ case B_PACKAGE_RESOLVABLE_OP_EQUAL:
+ flags |= REL_EQ;
+ break;
+ case B_PACKAGE_RESOLVABLE_OP_NOT_EQUAL:
+ break;
+ case B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL:
+ flags |= REL_GT | REL_EQ;
+ break;
+ case B_PACKAGE_RESOLVABLE_OP_GREATER:
+ flags |= REL_GT;
+ break;
+ }
+
+ add_dependency(repo, dependencies, expression->Name(),
+ expression->Version(), flags);
+ }
+}
+
+static void add_replaces_list(Repo *repo, Offset &dependencies,
+ const BStringList &packageNames)
+{
+ int32 count = packageNames.CountStrings();
+ for (int32 i = 0; i < count; i++)
+ {
+ const BString &packageName = packageNames.StringAt(i);
+ add_dependency(repo, dependencies, packageName, BPackageVersion(), 0);
+ }
+}
+
+static Id add_package_info_to_repo(Repo *repo, Repodata *repoData,
+ const BPackageInfo &packageInfo)
+{
+ Pool *pool = repo->pool;
+
+ Id solvableId = repo_add_solvable(repo);
+ Solvable *solvable = pool_id2solvable(pool, solvableId);
+ // Prepend "pkg:" to package name, so "provides" don't match unless explicitly
+ // specified this way.
+ BString name("pkg:");
+ name << packageInfo.Name();
+ solvable->name = pool_str2id(pool, name, 1);
+ if (packageInfo.Architecture() == B_PACKAGE_ARCHITECTURE_ANY)
+ solvable->arch = ARCH_NOARCH;
+ else
+ solvable->arch = pool_str2id(pool,
+ BPackageInfo::kArchitectureNames[packageInfo.Architecture()], 1);
+ solvable->evr = pool_str2id(pool,
+ haiku_version_to_string(packageInfo.Version()), 1);
+ solvable->vendor = pool_str2id(pool, packageInfo.Vendor(), 1);
+ repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_SUMMARY,
+ packageInfo.Summary());
+ repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_DESCRIPTION,
+ packageInfo.Description());
+ repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_PACKAGER,
+ packageInfo.Packager());
+
+ if (!packageInfo.Checksum().IsEmpty())
+ repodata_set_checksum(repoData, solvable - pool->solvables,
+ SOLVABLE_CHECKSUM, REPOKEY_TYPE_SHA256, packageInfo.Checksum());
+
+ solvable->provides = repo_addid_dep(repo, solvable->provides,
+ pool_rel2id(pool, solvable->name, solvable->evr, REL_EQ, 1), 0);
+
+ add_resolvables(repo, solvable->provides, packageInfo.ProvidesList());
+ add_resolvable_expressions(repo, solvable->requires,
+ packageInfo.RequiresList());
+ add_resolvable_expressions(repo, solvable->supplements,
+ packageInfo.SupplementsList());
+ add_resolvable_expressions(repo, solvable->conflicts,
+ packageInfo.ConflictsList());
+ add_resolvable_expressions(repo, solvable->enhances,
+ packageInfo.FreshensList());
+ add_replaces_list(repo, solvable->obsoletes, packageInfo.ReplacesList());
+ // TODO: Check whether freshens and replaces does indeed work as intended
+ // here.
+
+ // TODO: copyrights, licenses, URLs, source URLs
+
+ return solvableId;
+}
+
+static void add_installed_packages(Repo *repo, Repodata *repoData,
+ BPackageInstallationLocation location)
+{
+ BPackageRoster roster;
+ BPackageInfoSet packageInfos;
+ if (roster.GetActivePackages(location, packageInfos) == B_OK)
+ {
+ BRepositoryCache::Iterator it = packageInfos.GetIterator();
+ while (const BPackageInfo *packageInfo = it.Next())
+ add_package_info_to_repo(repo, repoData, *packageInfo);
+ }
+}
+
+int repo_add_haiku_installed_packages(Repo *repo, const char *rootdir,
+ int flags)
+{
+ Repodata *repoData = repo_add_repodata(repo, flags);
+
+ add_installed_packages(repo, repoData,
+ B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
+ add_installed_packages(repo, repoData,
+ B_PACKAGE_INSTALLATION_LOCATION_COMMON);
+ add_installed_packages(repo, repoData, B_PACKAGE_INSTALLATION_LOCATION_HOME);
+
+ if (!(flags & REPO_NO_INTERNALIZE))
+ repodata_internalize(repoData);
+
+ return 0;
+}
+
+Id repo_add_haiku_package(Repo *repo, const char *hpkgPath, int flags)
+{
+ BPackageInfo packageInfo;
+ if (packageInfo.ReadFromPackageFile(hpkgPath) != B_OK)
+ return 0;
+
+ return repo_add_haiku_package_info(repo, packageInfo, flags);
+}
+
+int repo_add_haiku_packages(Repo *repo, const char *repoName, int flags)
+{
+ BPackageRoster roster;
+ BRepositoryCache cache;
+ if (roster.GetRepositoryCache(repoName, &cache) != B_OK)
+ return 0;
+
+ Repodata *repoData = repo_add_repodata(repo, flags);
+
+ BRepositoryCache::Iterator it = cache.GetIterator();
+ while (const BPackageInfo *packageInfo = it.Next())
+ add_package_info_to_repo(repo, repoData, *packageInfo);
+
+ if (!(flags & REPO_NO_INTERNALIZE))
+ repodata_internalize(repoData);
+
+ return 0;
+}
+
+Id repo_add_haiku_package_info(Repo *repo,
+ const BPackageKit::BPackageInfo &packageInfo, int flags)
+{
+ if (packageInfo.InitCheck() != B_OK)
+ return 0;
+
+ Repodata *repoData = repo_add_repodata(repo, flags);
+
+ Id id = add_package_info_to_repo(repo, repoData, packageInfo);
+
+ if (!(flags & REPO_NO_INTERNALIZE))
+ repodata_internalize(repoData);
+
+ return id;
+}
diff --git a/ext/repo_haiku.h b/ext/repo_haiku.h
new file mode 100644
index 0000000..6770666
--- /dev/null
+++ b/ext/repo_haiku.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011-2013, Ingo Weinhold <ingo_weinhold@gmx.de>
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+#ifndef REPO_HAIKU_H
+#define REPO_HAIKU_H
+
+#include "repo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int repo_add_haiku_installed_packages(Repo *repo, const char *rootdir,
+ int flags);
+Id repo_add_haiku_package(Repo *repo, const char *hpkgPath, int flags);
+int repo_add_haiku_packages(Repo *repo, const char *repoName, int flags);
+
+#ifdef __cplusplus
+
+namespace BPackageKit {
+ class BPackageInfo;
+}
+
+Id repo_add_haiku_package_info(Repo *repo,
+ const BPackageKit::BPackageInfo &packageInfo, int flags);
+
+} /* extern "C" */
+
+#endif /*__cplusplus*/
+
+#endif /* REPO_HAIKU_H */