[haiku-commits] haiku: hrev46301 - src/tools/update_package_requires src/kits/package build/jam

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 30 Oct 2013 02:16:30 +0100 (CET)

hrev46301 adds 4 changesets to branch 'master'
old head: f87dd6dceb506ad3c779cd5c095270abf1c051e0
new head: 577411006e688240df57ccb1e358cacf4651a4ce
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=5774110+%5Ef87dd6d

----------------------------------------------------------------------------

79d2983: BPackageInfo::StringBuilder: Fix string escaping

690bccd: BPackageInfo::StringBuilder: Fix writing non-string lists
  
  Even a list with only one element needs to be enclosed in {...}.

a4bdd98: BPackageInfo::Parser: Fix parsing the requires operator
  
  For entries without operator (and version) an invalid enum value would
  be used for the resulting BPackageResolvableExpression. Now it's
  B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT in that case.

5774110: Update requires entries for the packages we build
  
  * Add build tool update_package_requires. Given a package info file and
    a repository cache file, it updates the minimum versions of the
    requires entries of the package info file according to what is
    provided by the repository.
  * PreprocessPackageInfo rule: Use update_package_requires (with the
    HaikuPorts repository file).

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

6 files changed, 223 insertions(+), 19 deletions(-)
build/jam/PackageRules                           |  18 +-
src/kits/package/PackageInfoParser.cpp           |   8 +-
src/kits/package/PackageInfoStringBuilder.h      |  25 ++-
src/tools/Jamfile                                |   3 +-
src/tools/update_package_requires/Jamfile        |  11 ++
.../update_package_requires.cpp                  | 177 +++++++++++++++++++

############################################################################

Commit:      79d29839bf2baca4ca1f75b209994796fe23ddaa
URL:         http://cgit.haiku-os.org/haiku/commit/?id=79d2983
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Oct 30 00:50:00 2013 UTC

BPackageInfo::StringBuilder: Fix string escaping

----------------------------------------------------------------------------

diff --git a/src/kits/package/PackageInfoStringBuilder.h 
b/src/kits/package/PackageInfoStringBuilder.h
index a21aa5e..db3b988 100644
--- a/src/kits/package/PackageInfoStringBuilder.h
+++ b/src/kits/package/PackageInfoStringBuilder.h
@@ -282,7 +282,11 @@ private:
 
                                replacement[0] = '\\';
                                _Write(replacement, 2);
+                               start = ++end;
                        }
+
+                       if (start < end)
+                               _Write(start, end - start);
                } else
                        _Write(data);
 

############################################################################

Commit:      690bccd46abf943e5e269d27863bf531ad0d13a5
URL:         http://cgit.haiku-os.org/haiku/commit/?id=690bccd
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Oct 30 00:51:23 2013 UTC

BPackageInfo::StringBuilder: Fix writing non-string lists

Even a list with only one element needs to be enclosed in {...}.

----------------------------------------------------------------------------

diff --git a/src/kits/package/PackageInfoStringBuilder.h 
b/src/kits/package/PackageInfoStringBuilder.h
index db3b988..4e4c33d 100644
--- a/src/kits/package/PackageInfoStringBuilder.h
+++ b/src/kits/package/PackageInfoStringBuilder.h
@@ -130,21 +130,16 @@ private:
                // encapsulating the stringification via templates seems to 
result in
                // an Internal Compiler Error with gcc 2.
 
-               int32 count = value.CountItems();
-               if (count == 1) {
-                       _WriteListElement(value.ItemAt(0));
-               } else {
-                       _Write("{\n", 2);
-
-                       int32 count = value.CountItems();
-                       for (int32 i = 0; i < count; i++) {
-                               _Write('\t');
-                               _WriteListElement(value.ItemAt(i));
-                               _Write('\n');
-                       }
+               _Write("{\n", 2);
 
-                       _Write('}');
+               int32 count = value.CountItems();
+               for (int32 i = 0; i < count; i++) {
+                       _Write('\t');
+                       _WriteListElement(value.ItemAt(i));
+                       _Write('\n');
                }
+
+               _Write('}');
        }
 
        template<typename Value>

############################################################################

Commit:      a4bdd98c7a118f9eab1b3c4e3334a8fcb8d5df74
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a4bdd98
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Oct 30 01:07:56 2013 UTC

BPackageInfo::Parser: Fix parsing the requires operator

For entries without operator (and version) an invalid enum value would
be used for the resulting BPackageResolvableExpression. Now it's
B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT in that case.

----------------------------------------------------------------------------

diff --git a/src/kits/package/PackageInfoParser.cpp 
b/src/kits/package/PackageInfoParser.cpp
index 377e8e8..1bdc870 100644
--- a/src/kits/package/PackageInfoParser.cpp
+++ b/src/kits/package/PackageInfoParser.cpp
@@ -600,6 +600,7 @@ BPackageInfo::Parser::_ParseResolvableExprList(
 
                        BPackageVersion version;
                        Token op = parser._NextToken();
+                       BPackageResolvableOperator resolvableOperator;
                        if (op.type == TOKEN_OPERATOR_LESS
                                || op.type == TOKEN_OPERATOR_LESS_EQUAL
                                || op.type == TOKEN_OPERATOR_EQUAL
@@ -621,18 +622,19 @@ BPackageInfo::Parser::_ParseResolvableExprList(
                                        } else
                                                parser._RewindTo(base);
                                }
+
+                               resolvableOperator = 
(BPackageResolvableOperator)
+                                       (op.type - TOKEN_OPERATOR_LESS);
                        } else if (op.type == TOKEN_ITEM_SEPARATOR
                                || op.type == TOKEN_CLOSE_BRACE) {
                                parser._RewindTo(op);
+                               resolvableOperator = 
B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT;
                        } else {
                                throw ParseError(
                                        "expected '<', '<=', '==', '!=', '>=', 
'>', comma or '}'",
                                        op.pos);
                        }
 
-                       BPackageResolvableOperator resolvableOperator
-                               = (BPackageResolvableOperator)(op.type - 
TOKEN_OPERATOR_LESS);
-
                        value->AddItem(new 
BPackageResolvableExpression(token.text,
                                resolvableOperator, version));
                }

############################################################################

Revision:    hrev46301
Commit:      577411006e688240df57ccb1e358cacf4651a4ce
URL:         http://cgit.haiku-os.org/haiku/commit/?id=5774110
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Oct 30 01:15:45 2013 UTC

Update requires entries for the packages we build

* Add build tool update_package_requires. Given a package info file and
  a repository cache file, it updates the minimum versions of the
  requires entries of the package info file according to what is
  provided by the repository.
* PreprocessPackageInfo rule: Use update_package_requires (with the
  HaikuPorts repository file).

----------------------------------------------------------------------------

diff --git a/build/jam/PackageRules b/build/jam/PackageRules
index 23abfa4..ea0a6ae 100644
--- a/build/jam/PackageRules
+++ b/build/jam/PackageRules
@@ -58,14 +58,23 @@ rule PreprocessPackageInfo source : directory : architecture
        }
 
        local revisionFile = [ DetermineHaikuRevision ] ;
+       local updateRequiresFiles ;
+       local haikuPortsRepositoryFile ;
+       if ! $(HAIKU_BOOTSTRAP_BUILD) {
+               updateRequiresFiles =
+                       <build>update_package_requires
+                       [ on <repository>HaikuPorts return 
$(HAIKU_REPOSITORY_CACHE_FILE) ]
+                       ;
+       }
 
        MakeLocate $(target) : $(directory) ;
-       Depends $(target) : $(source) $(revisionFile) ;
+       Depends $(target) : $(source) $(revisionFile) $(updateRequiresFiles) ;
 
        CCDEFS on $(target) = [ FDefines $(defines) ] ;
        HAIKU_SED_REPLACEMENTS on $(target) = "-e s,$(sedReplacements),g" ;
 
-       PreprocessPackageInfo1 $(target) : $(source) $(revisionFile) ;
+       PreprocessPackageInfo1 $(target) : $(source) $(revisionFile)
+               $(updateRequiresFiles) ;
 
        return $(target) ;
 }
@@ -77,6 +86,11 @@ actions PreprocessPackageInfo1
        sed $(HAIKU_SED_REPLACEMENTS) \
                        -e s,%HAIKU_VERSION%,$(HAIKU_VERSION)_${revision:-0}-1, 
< $(2[1]) \
                | $(HOST_CC) -E -w $(CCDEFS) - -o $(1)
+
+       if [ -n "$(2[4]:E)" ]; then
+               $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
+               "$(2[3])" "$(1)" "$(2[4])" || exit 1
+       fi
 }
 
 
diff --git a/src/tools/Jamfile b/src/tools/Jamfile
index e540625..f4014ed 100644
--- a/src/tools/Jamfile
+++ b/src/tools/Jamfile
@@ -109,7 +109,8 @@ SubInclude HAIKU_TOP src tools remote_disk_server ;
 SubInclude HAIKU_TOP src tools resattr ;
 SubInclude HAIKU_TOP src tools rman ;
 SubInclude HAIKU_TOP src tools translation ;
+SubInclude HAIKU_TOP src tools unflatten ;
 SubInclude HAIKU_TOP src tools unzip ;
+SubInclude HAIKU_TOP src tools update_package_requires ;
 SubInclude HAIKU_TOP src tools vmdkimage ;
-SubInclude HAIKU_TOP src tools unflatten ;
 SubInclude HAIKU_TOP src tools zip ;
diff --git a/src/tools/update_package_requires/Jamfile 
b/src/tools/update_package_requires/Jamfile
new file mode 100644
index 0000000..d24f405
--- /dev/null
+++ b/src/tools/update_package_requires/Jamfile
@@ -0,0 +1,11 @@
+SubDir HAIKU_TOP src tools update_package_requires ;
+
+UsePrivateBuildHeaders shared ;
+
+USES_BE_API on <build>update_package_requires = true ;
+
+BuildPlatformMain <build>update_package_requires :
+       update_package_requires.cpp
+       :
+       libpackage_build.so $(HOST_LIBBE) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
+       ;
diff --git a/src/tools/update_package_requires/update_package_requires.cpp 
b/src/tools/update_package_requires/update_package_requires.cpp
new file mode 100644
index 0000000..ea944d5
--- /dev/null
+++ b/src/tools/update_package_requires/update_package_requires.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <list>
+#include <map>
+
+#include <package/PackageInfo.h>
+#include <package/PackageResolvable.h>
+#include <package/PackageResolvableExpression.h>
+#include <package/RepositoryCache.h>
+
+
+using namespace BPackageKit;
+
+
+typedef std::list<BPackageResolvable*> ProvidesList;
+
+
+static const char* sProgramName = "update_package_requires";
+
+
+#define DIE(result, msg...)                                                    
                                \
+do {                                                                           
                                                \
+       fprintf(stderr, "*** " msg);                                            
                        \
+       fprintf(stderr, " : %s\n", strerror(result));                           
        \
+       exit(5);                                                                
                                                \
+} while(0)
+
+
+static void
+print_usage_and_exit(bool error)
+{
+       fprintf(error ? stderr : stdout,
+               "Usage: %s <package info> <repository>\n"
+               "Updates the versions in the \"requires\" list of the given 
package\n"
+               "info file using the available package information from the 
given\n"
+               "repository cache file <repository>.\n",
+               sProgramName);
+       exit(error ? 1 : 0);
+}
+
+
+static void
+update_requires_expression(BPackageResolvableExpression& expression,
+       const ProvidesList& providesList)
+{
+       // find the best-matching provides
+       BPackageResolvable* bestProvides = NULL;
+       for (ProvidesList::const_iterator it = providesList.begin();
+               it != providesList.end(); ++it) {
+               BPackageResolvable* provides = *it;
+               if (!expression.Matches(*provides))
+                       continue;
+
+               if (bestProvides == NULL || bestProvides->Version().InitCheck() 
!= B_OK
+                       || (provides->Version().InitCheck() == B_OK
+                               && 
provides->Version().Compare(bestProvides->Version()) > 0)) {
+                       bestProvides = provides;
+               }
+       }
+
+       if (bestProvides == NULL || bestProvides->Version().InitCheck() != B_OK)
+               return;
+
+       // Update the expression. Enforce the minimum found version, if the 
requires
+       // has no version requirement or also a minimum. Otherwise enforce the 
exact
+       // version found.
+       BPackageResolvableOperator newOperator = B_PACKAGE_RESOLVABLE_OP_EQUAL;
+       switch (expression.Operator()) {
+               case B_PACKAGE_RESOLVABLE_OP_LESS:
+               case B_PACKAGE_RESOLVABLE_OP_LESS_EQUAL:
+               case B_PACKAGE_RESOLVABLE_OP_EQUAL:
+               case B_PACKAGE_RESOLVABLE_OP_NOT_EQUAL:
+                       break;
+               case B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL:
+               case B_PACKAGE_RESOLVABLE_OP_GREATER:
+               case B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT:
+                       newOperator = B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL;
+                       break;
+       }
+
+       expression.SetTo(expression.Name(), newOperator, 
bestProvides->Version());
+}
+
+
+int
+main(int argc, const char* const* argv)
+{
+       if (argc != 3)
+               print_usage_and_exit(true);
+
+       if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
+               print_usage_and_exit(false);
+
+       const char* const packageInfoPath = argv[1];
+       const char* const repositoryCachePath = argv[2];
+
+       // read the repository cache
+       BRepositoryCache repositoryCache;
+       status_t error = repositoryCache.SetTo(repositoryCachePath);
+       if (error != B_OK) {
+               DIE(error, "failed to read repository cache file \"%s\"",
+                       repositoryCachePath);
+       }
+
+       // create a map for all provides (name -> resolvable list)
+       typedef std::map<BString, ProvidesList> ProvidesMap;
+
+       ProvidesMap providesMap;
+
+       for (BRepositoryCache::Iterator it = repositoryCache.GetIterator();
+               const BPackageInfo* info = it.Next();) {
+               const BObjectList<BPackageResolvable>& provides = 
info->ProvidesList();
+               int32 count = provides.CountItems();
+               for (int32 i = 0; i < count; i++) {
+                       BPackageResolvable* resolvable = provides.ItemAt(i);
+                       ProvidesList& providesList = 
providesMap[resolvable->Name()];
+                       providesList.push_back(resolvable);
+               }
+       }
+
+       // load the package info
+       BPackageInfo packageInfo;
+       error = packageInfo.ReadFromConfigFile(packageInfoPath);
+       if (error != B_OK)
+               DIE(error, "failed to read package info file \"%s\"", 
packageInfoPath);
+
+       // clone the package info's requires list
+       typedef std::list<BPackageResolvableExpression> RequiresList;
+       RequiresList requiresList;
+       int32 requiresCount = packageInfo.RequiresList().CountItems();
+       for (int32 i = 0; i < requiresCount; i++)
+               requiresList.push_back(*packageInfo.RequiresList().ItemAt(i));
+
+       // rebuild the requires list with updated versions
+       packageInfo.ClearRequiresList();
+       for (RequiresList::iterator it = requiresList.begin();
+               it != requiresList.end(); ++it) {
+               BPackageResolvableExpression expression = *it;
+               ProvidesMap::iterator foundIt = 
providesMap.find(expression.Name());
+               if (foundIt != providesMap.end())
+                       update_requires_expression(expression, foundIt->second);
+
+               error = packageInfo.AddRequires(expression);
+               if (error != B_OK)
+                       DIE(error, "failed to add requires item to package 
info");
+       }
+
+       // write updated package info
+       BString configString;
+       error = packageInfo.GetConfigString(configString);
+       if (error != B_OK)
+               DIE(error, "failed to get updated package info string");
+
+       FILE* file = fopen(packageInfoPath, "w");
+       if (file == NULL) {
+               DIE(errno, "failed to open package info file \"%s\" for 
writing",
+                       packageInfoPath);
+       }
+
+       if (fwrite(configString.String(), configString.Length(), 1, file) != 1) 
{
+               DIE(errno, "failed to write updated package info file \"%s\"",
+                       packageInfoPath);
+       }
+
+       fclose(file);
+
+       return 0;
+}


Other related posts:

  • » [haiku-commits] haiku: hrev46301 - src/tools/update_package_requires src/kits/package build/jam - ingo_weinhold