[haiku-commits] r40313 - in haiku/trunk: headers/os/package src/kits/package

  • From: zooey@xxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 29 Jan 2011 00:36:08 +0100 (CET)

Author: zooey
Date: 2011-01-29 00:36:08 +0100 (Sat, 29 Jan 2011)
New Revision: 40313
Changeset: http://dev.haiku-os.org/changeset/40313

Modified:
   haiku/trunk/headers/os/package/PackageInfo.h
   haiku/trunk/src/kits/package/PackageInfo.cpp
Log:
Completed PackageInfo-parser and fleshed out BPackageVersion, BPackageProvision 
and BPackageRequirement.


Modified: haiku/trunk/headers/os/package/PackageInfo.h
===================================================================
--- haiku/trunk/headers/os/package/PackageInfo.h        2011-01-28 22:36:13 UTC 
(rev 40312)
+++ haiku/trunk/headers/os/package/PackageInfo.h        2011-01-28 23:36:08 UTC 
(rev 40313)
@@ -18,12 +18,12 @@
 
 enum BPackageInfoIndex {
        B_PACKAGE_INFO_NAME = 0,
-       B_PACKAGE_INFO_SUMMARY,                 // single line, 72 chars max
+       B_PACKAGE_INFO_SUMMARY,                 // single line, 70 chars max
        B_PACKAGE_INFO_DESCRIPTION,             // multiple lines possible
        B_PACKAGE_INFO_VENDOR,                  // e.g. "Haiku Project"
        B_PACKAGE_INFO_PACKAGER,                // e-mail address preferred
        B_PACKAGE_INFO_ARCHITECTURE,
-       B_PACKAGE_INFO_VERSION,
+       B_PACKAGE_INFO_VERSION,                 // <major>[.<minor>[.<micro>]]
        B_PACKAGE_INFO_COPYRIGHTS,              // list
        B_PACKAGE_INFO_LICENSES,                // list
        B_PACKAGE_INFO_PROVIDES,                // list
@@ -34,7 +34,7 @@
 
 
 enum BPackageArchitecture {
-       B_PACKAGE_ARCHITECTURE_NONE = 0,
+       B_PACKAGE_ARCHITECTURE_ANY = 0,
        B_PACKAGE_ARCHITECTURE_X86,
        B_PACKAGE_ARCHITECTURE_X86_GCC2,
        //
@@ -44,29 +44,76 @@
 
 class BPackageVersion {
 public:
-                       void                            MakeEmpty() {}
+                                                               
BPackageVersion();
+                                                               
BPackageVersion(const BString& major,
+                                                                       const 
BString& minor, const BString& micro,
+                                                                       uint8 
release);
+
+                       status_t                        InitCheck() const;
+
+                       void                            
GetVersionString(BString& string) const;
+
+                       void                            SetTo(const BString& 
major,
+                                                                       const 
BString& minor, const BString& micro,
+                                                                       uint8 
release);
+                       void                            Clear();
+
+                       int                                     Compare(const 
BPackageVersion& other) const;
+                                                                       // does 
a natural compare over major, minor
+                                                                       // and 
micro, finally comparing release
+
+private:
+                       BString                         fMajor;
+                       BString                         fMinor;
+                       BString                         fMicro;
+                       uint8                           fRelease;
 };
 
 
 class BPackageProvision {
 public:
-                       int                                     Compare(const 
BPackageProvision& other) const
-                       {
-                               return fX.Compare(other.fX);
-                       }
+                                                               
BPackageProvision();
+                                                               
BPackageProvision(const BString& name,
+                                                                       const 
BPackageVersion& version
+                                                                               
= BPackageVersion());
+
+                       status_t                        InitCheck() const;
+
+                       void                            
GetProvisionString(BString& string) const;
+
+                       void                            SetTo(const BString& 
name,
+                                                                       const 
BPackageVersion& version
+                                                                               
= BPackageVersion());
+                       void                            Clear();
+
 private:
-                       BString fX;
+                       BString                         fName;
+                       BPackageVersion         fVersion;
 };
 
 
 class BPackageRequirement {
 public:
-                       int                                     Compare(const 
BPackageRequirement& other) const
-                       {
-                               return fX.Compare(other.fX);
-                       }
+                                                               
BPackageRequirement();
+                                                               
BPackageRequirement(const BString& name,
+                                                                       const 
BString& _operator = "",
+                                                                       const 
BPackageVersion& version
+                                                                               
= BPackageVersion());
+
+                       status_t                        InitCheck() const;
+
+                       void                            
GetRequirementString(BString& string) const;
+
+                       void                            SetTo(const BString& 
name,
+                                                                       const 
BString& _operator = "",
+                                                                       const 
BPackageVersion& version
+                                                                               
= BPackageVersion());
+                       void                            Clear();
+
 private:
-                       BString fX;
+                       BString                         fName;
+                       BString                         fOperator;
+                       BPackageVersion         fVersion;
 };
 
 
@@ -126,31 +173,29 @@
 
                        void                            ClearCopyrights();
                        status_t                        AddCopyright(const 
BString& copyright);
-                       status_t                        RemoveCopyright(const 
BString& copyright);
 
                        void                            ClearLicenses();
                        status_t                        AddLicense(const 
BString& license);
-                       status_t                        RemoveLicense(const 
BString& license);
 
                        void                            ClearProvisions();
                        status_t                        AddProvision(
                                                                        const 
BPackageProvision& provision);
-                       status_t                        RemoveProvision(
-                                                                       const 
BPackageProvision& provision);
 
                        void                            ClearRequirements();
                        status_t                        AddRequirement(
                                                                        const 
BPackageRequirement& requirement);
-                       status_t                        RemoveRequirement(
-                                                                       const 
BPackageRequirement& requirement);
 
-                       void                            MakeEmpty();
+                       void                            Clear();
 
 public:
        static  status_t                        GetElementName(
                                                                        
BPackageInfoIndex index,
                                                                        const 
char** name);
 
+       static  status_t                        GetArchitectureName(
+                                                                       
BPackageArchitecture arch,
+                                                                       const 
char** name);
+
 private:
                        class Parser;
        friend  class Parser;

Modified: haiku/trunk/src/kits/package/PackageInfo.cpp
===================================================================
--- haiku/trunk/src/kits/package/PackageInfo.cpp        2011-01-28 22:36:13 UTC 
(rev 40312)
+++ haiku/trunk/src/kits/package/PackageInfo.cpp        2011-01-28 23:36:08 UTC 
(rev 40313)
@@ -1,4 +1,3 @@
-#include <stdio.h>
 /*
  * Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
  * Distributed under the terms of the MIT License.
@@ -17,7 +16,12 @@
 #include <Entry.h>
 #include <String.h>
 
+#include <NaturalCompare.h>
 
+
+using BPrivate::NaturalCompare;
+
+
 namespace BPackageKit {
 
 
@@ -37,7 +41,6 @@
        TOKEN_OPEN_BRACKET,
        TOKEN_CLOSE_BRACKET,
        TOKEN_COMMA,
-       TOKEN_SEMICOLON,
        TOKEN_COLON,
        //
        TOKEN_EOF,
@@ -73,16 +76,24 @@
                        struct Token;
 
                        Token                           _NextToken();
+                       void                            _RewindTo(const Token& 
token);
+
                        void                            
_ParseStringValue(BString* value);
                        void                            _ParseArchitectureValue(
                                                                        
BPackageArchitecture* value);
+                       void                            
_ParseVersionValue(BPackageVersion* value,
+                                                                       bool 
releaseIsOptional);
+                       void                            
_ParseStringList(BObjectList<BString>* value);
+                       void                            _ParseProvisionList(
+                                                                       
BObjectList<BPackageProvision>* value);
+                       void                            _ParseRequirementList(
+                                                                       
BObjectList<BPackageRequirement>* value);
+
                        void                            _Parse(BPackageInfo* 
packageInfo);
 
 private:
                        ParseErrorListener*     fListener;
-
                        const char*                     fPos;
-                       int                                     fCurrentLine;
 };
 
 
@@ -140,8 +151,7 @@
 BPackageInfo::Parser::Parser(ParseErrorListener* listener)
        :
        fListener(listener),
-       fPos(NULL),
-       fCurrentLine(0)
+       fPos(NULL)
 {
 }
 
@@ -154,7 +164,6 @@
                return B_BAD_VALUE;
 
        fPos = packageInfoString.String();
-       fCurrentLine = 1;
 
        try {
                _Parse(packageInfo);
@@ -164,7 +173,7 @@
                        int line = 1;
                        int column;
                        int32 offset = error.pos - packageInfoString.String();
-                       int32 newlinePos = packageInfoString.FindLast('\n', 
offset);
+                       int32 newlinePos = packageInfoString.FindLast('\n', 
offset - 1);
                        if (newlinePos < 0)
                                column = offset;
                        else {
@@ -178,6 +187,10 @@
                        fListener->OnError(error.message, line, column);
                }
                return B_BAD_DATA;
+       } catch (const std::bad_alloc& e) {
+               if (fListener != NULL)
+                       fListener->OnError("out of memory", 0, 0);
+               return B_NO_MEMORY;
        }
 
        return B_OK;
@@ -188,20 +201,15 @@
 BPackageInfo::Parser::_NextToken()
 {
        // eat any whitespace or comments
-printf("1: %p\n", fPos);
        bool inComment = false;
        while ((inComment && *fPos != '\0') || isspace(*fPos) || *fPos == '#') {
-printf("1b: %p\n", fPos);
                if (*fPos == '#')
                        inComment = true;
-               else if (*fPos == '\n') {
+               else if (*fPos == '\n')
                        inComment = false;
-                       fCurrentLine++;
-               }
                fPos++;
        }
 
-printf("2: %p\n", fPos);
        const char* tokenPos = fPos;
        switch (*fPos) {
                case '\0':
@@ -215,10 +223,6 @@
                        fPos++;
                        return Token(TOKEN_COMMA, tokenPos);
 
-               case ';':
-                       fPos++;
-                       return Token(TOKEN_SEMICOLON, tokenPos);
-
                case '[':
                        fPos++;
                        return Token(TOKEN_OPEN_BRACKET, tokenPos);
@@ -231,22 +235,22 @@
                        fPos++;
                        if (*fPos == '=') {
                                fPos++;
-                               return Token(TOKEN_OPERATOR_LESS_EQUAL, 
tokenPos);
+                               return Token(TOKEN_OPERATOR_LESS_EQUAL, 
tokenPos, 2);
                        }
-                       return Token(TOKEN_OPERATOR_LESS, tokenPos);
+                       return Token(TOKEN_OPERATOR_LESS, tokenPos, 1);
 
                case '=':
                        fPos++;
                        if (*fPos == '=') {
                                fPos++;
-                               return Token(TOKEN_OPERATOR_EQUAL, tokenPos);
+                               return Token(TOKEN_OPERATOR_EQUAL, tokenPos, 2);
                        }
-                       return Token(TOKEN_OPERATOR_ASSIGN, tokenPos);
+                       return Token(TOKEN_OPERATOR_ASSIGN, tokenPos, 1);
 
                case '!':
                        if (fPos[1] == '=') {
                                fPos += 2;
-                               return Token(TOKEN_OPERATOR_NOT_EQUAL, 
tokenPos);
+                               return Token(TOKEN_OPERATOR_NOT_EQUAL, 
tokenPos, 2);
                        }
                        break;
 
@@ -254,9 +258,9 @@
                        fPos++;
                        if (*fPos == '=') {
                                fPos++;
-                               return Token(TOKEN_OPERATOR_GREATER_EQUAL, 
tokenPos);
+                               return Token(TOKEN_OPERATOR_GREATER_EQUAL, 
tokenPos, 2);
                        }
-                       return Token(TOKEN_OPERATOR_GREATER, tokenPos);
+                       return Token(TOKEN_OPERATOR_GREATER, tokenPos, 1);
 
                case '"':
                {
@@ -269,8 +273,6 @@
                                        lastWasEscape = false;
                                else if (*fPos == '\\')
                                        lastWasEscape = true;
-                               else if (*fPos == '\n')
-                                       fCurrentLine++;
                                fPos++;
                        }
                        if (*fPos != '"')
@@ -298,6 +300,13 @@
 
 
 void
+BPackageInfo::Parser::_RewindTo(const Token& token)
+{
+       fPos = token.pos;
+}
+
+
+void
 BPackageInfo::Parser::_ParseStringValue(BString* value)
 {
        Token string = _NextToken();
@@ -333,6 +342,165 @@
 
 
 void
+BPackageInfo::Parser::_ParseVersionValue(BPackageVersion* value,
+       bool releaseIsOptional)
+{
+       Token word = _NextToken();
+       if (word.type != TOKEN_WORD)
+               throw ParseError("expected word (a version)", word.pos);
+
+       uint8 release = 0;
+       int32 lastDashPos = word.text.FindLast('-');
+       if (lastDashPos < 0) {
+               if (!releaseIsOptional) {
+                       throw ParseError("expected release number (-<number> 
suffix)",
+                               word.pos + word.text.Length());
+               }
+       } else {
+               int number = atoi(word.text.String() + lastDashPos + 1);
+               if (number <= 0 || number > 99) {
+                       throw ParseError("release number must be from 1-99",
+                               word.pos + word.text.Length());
+               }
+               release = number;
+               word.text.Truncate(lastDashPos);
+       }
+
+       BString major;
+       BString minor;
+       BString micro;
+       int32 firstDotPos = word.text.FindFirst('.');
+       if (firstDotPos < 0)
+               major = word.text;
+       else {
+               word.text.CopyInto(major, 0, firstDotPos);
+               int32 secondDotPos = word.text.FindFirst('.', firstDotPos + 1);
+               if (secondDotPos == firstDotPos + 1)
+                       throw ParseError("expected minor version", word.pos + 
secondDotPos);
+
+               if (secondDotPos < 0)
+                       word.text.CopyInto(minor, firstDotPos + 1, 
word.text.Length());
+               else {
+                       word.text.CopyInto(minor, firstDotPos + 1,
+                               secondDotPos - firstDotPos + 1);
+                       word.text.CopyInto(micro, secondDotPos + 1, 
word.text.Length());
+               }
+       }
+
+       value->SetTo(major, minor, micro, release);
+}
+
+
+void
+BPackageInfo::Parser::_ParseStringList(BObjectList<BString>* value)
+{
+       Token openBracket = _NextToken();
+       if (openBracket.type != TOKEN_OPEN_BRACKET)
+               throw ParseError("expected start of list ('[')", 
openBracket.pos);
+
+       bool needComma = false;
+       while (true) {
+               Token token = _NextToken();
+               if (token.type == TOKEN_CLOSE_BRACKET)
+                       return;
+
+               if (needComma) {
+                       if (token.type != TOKEN_COMMA)
+                               throw ParseError("expected comma", token.pos);
+                       token = _NextToken();
+               } else
+                       needComma = true;
+
+               if (token.type != TOKEN_QUOTED_STRING && token.type != 
TOKEN_WORD)
+                       throw ParseError("expected quoted-string or word", 
token.pos);
+
+               value->AddItem(new BString(token.text));
+       }
+}
+
+
+void
+BPackageInfo::Parser::_ParseProvisionList(BObjectList<BPackageProvision>* 
value)
+{
+       Token openBracket = _NextToken();
+       if (openBracket.type != TOKEN_OPEN_BRACKET)
+               throw ParseError("expected start of list ('[')", 
openBracket.pos);
+
+       bool needComma = false;
+       while (true) {
+               Token name = _NextToken();
+               if (name.type == TOKEN_CLOSE_BRACKET)
+                       return;
+
+               if (needComma) {
+                       if (name.type != TOKEN_COMMA)
+                               throw ParseError("expected comma", name.pos);
+                       name = _NextToken();
+               } else
+                       needComma = true;
+
+               if (name.type != TOKEN_WORD)
+                       throw ParseError("expected word (a provision name)", 
name.pos);
+
+               BPackageVersion version;
+               Token op = _NextToken();
+               if (op.type == TOKEN_OPERATOR_ASSIGN)
+                       _ParseVersionValue(&version, true);
+               else if (op.type == TOKEN_COMMA || op.type == 
TOKEN_CLOSE_BRACKET)
+                       _RewindTo(op);
+               else
+                       throw ParseError("expected '=', comma or ']'", op.pos);
+
+               value->AddItem(new BPackageProvision(name.text, version));
+       }
+}
+
+
+void
+BPackageInfo::Parser::_ParseRequirementList(
+       BObjectList<BPackageRequirement>* value)
+{
+       Token openBracket = _NextToken();
+       if (openBracket.type != TOKEN_OPEN_BRACKET)
+               throw ParseError("expected start of list ('[')", 
openBracket.pos);
+
+       bool needComma = false;
+       while (true) {
+               Token name = _NextToken();
+               if (name.type == TOKEN_CLOSE_BRACKET)
+                       return;
+
+               if (needComma) {
+                       if (name.type != TOKEN_COMMA)
+                               throw ParseError("expected comma", name.pos);
+                       name = _NextToken();
+               } else
+                       needComma = true;
+
+               if (name.type != TOKEN_WORD)
+                       throw ParseError("expected word (a requirement name)", 
name.pos);
+
+               BPackageVersion version;
+               Token op = _NextToken();
+               if (op.type == TOKEN_OPERATOR_LESS
+                       || op.type == TOKEN_OPERATOR_LESS_EQUAL
+                       || op.type == TOKEN_OPERATOR_EQUAL
+                       || op.type == TOKEN_OPERATOR_GREATER_EQUAL
+                       || op.type == TOKEN_OPERATOR_GREATER)
+                       _ParseVersionValue(&version, true);
+               else if (op.type == TOKEN_COMMA || op.type == 
TOKEN_CLOSE_BRACKET)
+                       _RewindTo(op);
+               else {
+                       throw ParseError(
+                               "expected '<', '<=', '==', '>=', '>', comma or 
']'", op.pos);
+               }
+
+               value->AddItem(new BPackageRequirement(name.text, op.text, 
version));
+       }
+}
+
+
+void
 BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
 {
        bool seen[B_PACKAGE_INFO_ENUM_COUNT];
@@ -343,11 +511,11 @@
 
        while (Token t = _NextToken()) {
                if (t.type != TOKEN_WORD)
-                       throw ParseError("expected word [a variable name]", 
t.pos);
+                       throw ParseError("expected word (a variable name)", 
t.pos);
 
                Token opAssign = _NextToken();
                if (opAssign.type != TOKEN_OPERATOR_ASSIGN) {
-                       throw ParseError("expected assignment operator ['=']",
+                       throw ParseError("expected assignment operator ('=')",
                                opAssign.pos);
                }
 
@@ -417,75 +585,70 @@
                        _ParseArchitectureValue(&architecture);
                        packageInfo->SetArchitecture(architecture);
                        seen[B_PACKAGE_INFO_ARCHITECTURE] = true;
+               } else if (t.text.ICompare(names[B_PACKAGE_INFO_VERSION]) == 0) 
{
+                       if (seen[B_PACKAGE_INFO_VERSION]) {
+                               BString error = 
BString(names[B_PACKAGE_INFO_VERSION])
+                                       << " already seen!";
+                               throw ParseError(error, t.pos);
+                       }
+
+                       BPackageVersion version;
+                       _ParseVersionValue(&version, false);
+                       packageInfo->SetVersion(version);
+                       seen[B_PACKAGE_INFO_VERSION] = true;
+               } else if (t.text.ICompare(names[B_PACKAGE_INFO_COPYRIGHTS]) == 
0) {
+                       if (seen[B_PACKAGE_INFO_COPYRIGHTS]) {
+                               BString error = 
BString(names[B_PACKAGE_INFO_COPYRIGHTS])
+                                       << " already seen!";
+                               throw ParseError(error, t.pos);
+                       }
+
+                       BObjectList<BString> copyrights;
+                       _ParseStringList(&copyrights);
+                       int count = copyrights.CountItems();
+                       for (int i = 0; i < count; ++i)
+                               
packageInfo->AddCopyright(*(copyrights.ItemAt(i)));
+                       seen[B_PACKAGE_INFO_COPYRIGHTS] = true;
+               } else if (t.text.ICompare(names[B_PACKAGE_INFO_LICENSES]) == 
0) {
+                       if (seen[B_PACKAGE_INFO_LICENSES]) {
+                               BString error = 
BString(names[B_PACKAGE_INFO_LICENSES])
+                                       << " already seen!";
+                               throw ParseError(error, t.pos);
+                       }
+
+                       BObjectList<BString> licenses;
+                       _ParseStringList(&licenses);
+                       int count = licenses.CountItems();
+                       for (int i = 0; i < count; ++i)
+                               packageInfo->AddLicense(*(licenses.ItemAt(i)));
+                       seen[B_PACKAGE_INFO_LICENSES] = true;
+               } else if (t.text.ICompare(names[B_PACKAGE_INFO_PROVIDES]) == 
0) {
+                       if (seen[B_PACKAGE_INFO_PROVIDES]) {
+                               BString error = 
BString(names[B_PACKAGE_INFO_PROVIDES])
+                                       << " already seen!";
+                               throw ParseError(error, t.pos);
+                       }
+
+                       BObjectList<BPackageProvision> provisions;
+                       _ParseProvisionList(&provisions);
+                       int count = provisions.CountItems();
+                       for (int i = 0; i < count; ++i)
+                               
packageInfo->AddProvision(*(provisions.ItemAt(i)));
+                       seen[B_PACKAGE_INFO_PROVIDES] = true;
+               } else if (t.text.ICompare(names[B_PACKAGE_INFO_REQUIRES]) == 
0) {
+                       if (seen[B_PACKAGE_INFO_REQUIRES]) {
+                               BString error = 
BString(names[B_PACKAGE_INFO_REQUIRES])
+                                       << " already seen!";
+                               throw ParseError(error, t.pos);
+                       }
+
+                       BObjectList<BPackageRequirement> requirements;
+                       _ParseRequirementList(&requirements);
+                       int count = requirements.CountItems();
+                       for (int i = 0; i < count; ++i)
+                               
packageInfo->AddRequirement(*(requirements.ItemAt(i)));
+                       seen[B_PACKAGE_INFO_REQUIRES] = true;
                }
-//             } else if (t.text.ICompare(names[B_PACKAGE_INFO_VERSION]) == 0) 
{
-//                     if (seen[B_PACKAGE_INFO_VERSION]) {
-//                             BString error = 
BString(names[B_PACKAGE_INFO_VERSION])
-//                                     << " already seen!";
-//                             throw ParseError(error, t.pos);
-//                     }
-//
-//                     BPackageVersion version;
-//                     _ParseVersionValue(&version);
-//                     packageInfo->SetVersion(version);
-//                     seen[B_PACKAGE_INFO_VERSION] = true;
-//             } else if (t.text.ICompare(names[B_PACKAGE_INFO_COPYRIGHTS]) == 
0) {
-//                     if (seen[B_PACKAGE_INFO_COPYRIGHTS]) {
-//                             BString error = 
BString(names[B_PACKAGE_INFO_COPYRIGHTS])
-//                                     << " already seen!";
-//                             throw ParseError(error, t.pos);
-//                     }
-//
-//                     BObjectList<BString> copyrights;
-//                     _ParseStringList(&copyrights);
-//                     int count = copyrights.CountItems();
-//                     for (int i = 0; i < count; ++i)
-//                             
packageInfo->AddCopyright(*(copyrights.ItemAt(i)));
-//                     seen[B_PACKAGE_INFO_COPYRIGHTS] = true;
-//             } else if (t.text.ICompare(names[B_PACKAGE_INFO_LICENSES]) == 
0) {
-//                     if (seen[B_PACKAGE_INFO_LICENSES]) {
-//                             BString error = 
BString(names[B_PACKAGE_INFO_LICENSES])
-//                                     << " already seen!";
-//                             throw ParseError(error, t.pos);
-//                     }
-//
-//                     BObjectList<BString> licenses;
-//                     _ParseStringList(&licenses);
-//                     int count = licenses.CountItems();
-//                     for (int i = 0; i < count; ++i)
-//                             packageInfo->AddLicense(*(licenses.ItemAt(i)));
-//                     seen[B_PACKAGE_INFO_LICENSES] = true;
-//             } else if (t.text.ICompare(names[B_PACKAGE_INFO_PROVIDES]) == 
0) {
-//                     if (seen[B_PACKAGE_INFO_PROVIDES]) {
-//                             BString error = 
BString(names[B_PACKAGE_INFO_PROVIDES])
-//                                     << " already seen!";
-//                             throw ParseError(error, t.pos);
-//                     }
-//
-//                     BObjectList<BPackageProvision> provisions;
-//                     _ParseProvisionList(&provisions);
-//                     int count = provisions.CountItems();
-//                     for (int i = 0; i < count; ++i)
-//                             
packageInfo->AddProvision(*(provisions.ItemAt(i)));
-//                     seen[B_PACKAGE_INFO_PROVIDES] = true;
-//             } else if (t.text.ICompare(names[B_PACKAGE_INFO_REQUIRES]) == 
0) {
-//                     if (seen[B_PACKAGE_INFO_REQUIRES]) {
-//                             BString error = 
BString(names[B_PACKAGE_INFO_REQUIRES])
-//                                     << " already seen!";
-//                             throw ParseError(error, t.pos);
-//                     }
-//
-//                     BObjectList<BPackageRequirement> requirements;
-//                     _ParseRequirementList(&requirements);
-//                     int count = requirements.CountItems();
-//                     for (int i = 0; i < count; ++i)
-//                             
packageInfo->AddRequirement(*(requirements.ItemAt(i)));
-//                     seen[B_PACKAGE_INFO_REQUIRES] = true;
-//             }
-
-               Token semicolon = _NextToken();
-               if (semicolon.type != TOKEN_SEMICOLON)
-                       throw ParseError("expected semicolon [';']", 
semicolon.pos);
        }
 
        for (int i = 0; i < B_PACKAGE_INFO_ENUM_COUNT; ++i) {
@@ -497,6 +660,197 @@
 }
 
 
+BPackageVersion::BPackageVersion()
+{
+}
+
+
+BPackageVersion::BPackageVersion(const BString& major, const BString& minor,
+       const BString& micro, uint8 release)
+       :
+       fMajor(major),
+       fMinor(minor),
+       fMicro(micro),
+       fRelease(release)
+{
+}
+
+
+status_t
+BPackageVersion::InitCheck() const
+{
+       return fMajor.Length() > 0 ? B_OK : B_NO_INIT;
+}
+
+
+int
+BPackageVersion::Compare(const BPackageVersion& other) const
+{
+       int majorDiff = NaturalCompare(fMajor.String(), other.fMajor.String());
+       if (majorDiff != 0)
+               return majorDiff;
+
+       int minorDiff = NaturalCompare(fMinor.String(), other.fMinor.String());
+       if (minorDiff != 0)
+               return minorDiff;
+
+       int microDiff = NaturalCompare(fMicro.String(), other.fMicro.String());
+       if (microDiff != 0)
+               return microDiff;
+
+       return (int)fRelease - (int)other.fRelease;
+}
+
+
+void
+BPackageVersion::GetVersionString(BString& string) const
+{
+       string = fMajor;
+
+       if (fMinor.Length() > 0) {
+               string << '.' << fMinor;
+               if (fMicro.Length() > 0)
+                       string << '.' << fMicro;
+       }
+
+       if (fRelease > 0)
+               string << '-' << fRelease;
+}
+
+
+void
+BPackageVersion::SetTo(const BString& major, const BString& minor,
+       const BString& micro, uint8 release)
+{
+       fMajor = major;
+       fMinor = minor;
+       fMicro = micro;
+       fRelease = release;
+}
+
+
+void
+BPackageVersion::Clear()
+{
+       fMajor.Truncate(0);
+       fMinor.Truncate(0);
+       fMicro.Truncate(0);
+       fRelease = 0;
+}
+
+
+BPackageProvision::BPackageProvision()
+{
+}
+
+
+BPackageProvision::BPackageProvision(const BString& name,
+       const BPackageVersion& version)
+       :
+       fName(name),
+       fVersion(version)
+{
+}
+
+
+status_t
+BPackageProvision::InitCheck() const
+{
+       return fName.Length() > 0 ? B_OK : B_NO_INIT;
+}
+
+
+void
+BPackageProvision::GetProvisionString(BString& string) const
+{
+       string = fName;
+
+       if (fVersion.InitCheck() == B_OK) {
+               string << '=';
+               fVersion.GetVersionString(string);
+       }
+}
+
+
+void
+BPackageProvision::SetTo(const BString& name, const BPackageVersion& version)
+{
+       fName = name;
+       fVersion = version;
+}
+
+
+void
+BPackageProvision::Clear()
+{
+       fName.Truncate(0);
+       fVersion.Clear();
+}
+
+
+BPackageRequirement::BPackageRequirement()
+{
+}
+
+
+BPackageRequirement::BPackageRequirement(const BString& name,
+       const BString& _operator, const BPackageVersion& version)
+       :
+       fName(name),
+       fOperator(_operator),
+       fVersion(version)
+{
+}
+
+
+status_t
+BPackageRequirement::InitCheck() const
+{
+       if (fName.Length() == 0)
+               return B_NO_INIT;
+
+       // either both or none of operator and version must be set
+       if (fOperator.Length() == 0 && fVersion.InitCheck() == B_OK)
+               return B_NO_INIT;
+
+       if (fOperator.Length() > 0 && fVersion.InitCheck() != B_OK)
+               return B_NO_INIT;
+
+       return B_OK;
+}
+
+
+void
+BPackageRequirement::GetRequirementString(BString& string) const
+{
+       string = fName;
+
+       if (fVersion.InitCheck() == B_OK) {
+               string << fOperator;
+               fVersion.GetVersionString(string);
+       }
+}
+
+
+void
+BPackageRequirement::SetTo(const BString& name, const BString& _operator,
+       const BPackageVersion& version)
+{
+       fName = name;
+       fOperator = _operator;
+       fVersion = version;
+}
+
+
+void
+BPackageRequirement::Clear()
+{
+       fName.Truncate(0);
+       fOperator.Truncate(0);
+       fVersion.Clear();
+}
+
+
 const char* BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
        "name",
        "summary",
@@ -514,7 +868,7 @@
 
 const char*
 BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
-       "no_arch",
+       "any",
        "x86",
        "x86_gcc2",
 };
@@ -522,7 +876,7 @@
 
 BPackageInfo::BPackageInfo()
        :
-       fArchitecture(B_PACKAGE_ARCHITECTURE_NONE),
+       fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT),
        fCopyrights(5, true),
        fLicenses(5, true),
        fProvisions(20, true),
@@ -573,7 +927,7 @@
 BPackageInfo::ReadFromConfigString(const BString& packageInfoString,
        ParseErrorListener* listener)
 {
-       MakeEmpty();
+       Clear();
 
        Parser parser(listener);
        return parser.Parse(packageInfoString, this);
@@ -583,7 +937,15 @@
 status_t
 BPackageInfo::InitCheck() const
 {
-       // TODO
+       if (fName.Length() == 0 || fSummary.Length() == 0
+               || fDescription.Length() == 0 || fVendor.Length() == 0
+               || fPackager.Length() == 0
+               || fArchitecture == B_PACKAGE_ARCHITECTURE_ENUM_COUNT
+               || fVersion.InitCheck() != B_OK
+               || fCopyrights.IsEmpty() || fLicenses.IsEmpty()
+               || fProvisions.IsEmpty() || fRequirements.IsEmpty())
+               return B_NO_INIT;
+
        return B_OK;
 }
 
@@ -732,21 +1094,6 @@
 }
 
 
-status_t
-BPackageInfo::RemoveCopyright(const BString& copyright)
-{
-       int32 count = fCopyrights.CountItems();
-       for (int i = 0; i < count; ++i) {
-               if (fCopyrights.ItemAt(i)->Compare(copyright) == 0) {
-                       delete fCopyrights.RemoveItemAt(i);
-                       return B_OK;
-               }
-       }
-
-       return B_NAME_NOT_FOUND;
-}
-
-
 void
 BPackageInfo::ClearLicenses()
 {
@@ -765,18 +1112,22 @@
 }
 
 
+void
+BPackageInfo::ClearProvisions()
+{
+       fProvisions.MakeEmpty();
+}
+
+
 status_t
-BPackageInfo::RemoveLicense(const BString& license)
+BPackageInfo::AddProvision(const BPackageProvision& provision)
 {
-       int32 count = fLicenses.CountItems();
-       for (int i = 0; i < count; ++i) {
-               if (fLicenses.ItemAt(i)->Compare(license) == 0) {
-                       delete fLicenses.RemoveItemAt(i);
-                       return B_OK;
-               }
-       }
+       BPackageProvision* newProvision
+               = new (std::nothrow) BPackageProvision(provision);
+       if (newProvision == NULL)
+               return B_NO_MEMORY;
 
-       return B_NAME_NOT_FOUND;
+       return fProvisions.AddItem(newProvision) ? B_OK : B_ERROR;
 }
 
 
@@ -799,65 +1150,16 @@
 }
 
 
-status_t
-BPackageInfo::RemoveRequirement(const BPackageRequirement& requirement)
-{
-       int32 count = fRequirements.CountItems();
-       for (int i = 0; i < count; ++i) {
-               if (fRequirements.ItemAt(i)->Compare(requirement)) {
-                       delete fRequirements.RemoveItemAt(i);
-                       return B_OK;
-               }
-       }
-
-       return B_NAME_NOT_FOUND;
-}
-
-
 void
-BPackageInfo::ClearProvisions()
+BPackageInfo::Clear()
 {
-       fProvisions.MakeEmpty();
-}
-
-
-status_t
-BPackageInfo::AddProvision(const BPackageProvision& provision)
-{
-       BPackageProvision* newProvision
-               = new (std::nothrow) BPackageProvision(provision);
-       if (newProvision == NULL)
-               return B_NO_MEMORY;
-
-       return fProvisions.AddItem(newProvision) ? B_OK : B_ERROR;
-}
-
-
-status_t

[... truncated: 47 lines follow ...]

Other related posts:

  • » [haiku-commits] r40313 - in haiku/trunk: headers/os/package src/kits/package - zooey