From f55a958ff2251f0061ab907157c99a350e56025f Mon Sep 17 00:00:00 2001
From: Arch Librarian <arch@canonical.com>
Date: Mon, 20 Sep 2004 16:50:37 +0000
Subject: Checkpoint Author: jgg Date: 1998-07-04 05:57:34 GMT Checkpoint

---
 apt-pkg/deb/deblistparser.cc | 255 +++++++++++++++++++++++++++++++++++++++++++
 apt-pkg/deb/deblistparser.h  |  51 +++++++++
 2 files changed, 306 insertions(+)
 create mode 100644 apt-pkg/deb/deblistparser.cc
 create mode 100644 apt-pkg/deb/deblistparser.h

(limited to 'apt-pkg/deb')

diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
new file mode 100644
index 000000000..28298aa36
--- /dev/null
+++ b/apt-pkg/deb/deblistparser.cc
@@ -0,0 +1,255 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: deblistparser.cc,v 1.1 1998/07/04 05:58:08 jgg Exp $
+/* ######################################################################
+   
+   Package Cache Generator - Generator for the cache structure.
+   
+   This builds the cache structure from the abstract package list parser. 
+   
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <pkglib/deblistparser.h>
+#include <pkglib/error.h>
+#include <system.h>
+									/*}}}*/
+
+// ListParser::debListParser - Constructor				/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+debListParser::debListParser(File &File) : Tags(File)
+{
+   Step();
+}
+									/*}}}*/
+// ListParser::FindTag - Find the tag and return a string		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string debListParser::FindTag(const char *Tag)
+{
+   const char *Start;
+   const char *Stop;
+   if (Section.Find(Tag,Start,Stop) == false)
+      return string();
+   return string(Start,Stop - Start);
+}
+									/*}}}*/
+// ListParser::UniqFindTagWrite - Find the tag and write a unq string	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned long debListParser::UniqFindTagWrite(const char *Tag)
+{
+   const char *Start;
+   const char *Stop;
+   if (Section.Find(Tag,Start,Stop) == false)
+      return 0;
+   return WriteUniqString(Start,Stop - Start);
+}
+									/*}}}*/
+// ListParser::HandleFlag - Sets a flag variable based on a tag		/*{{{*/
+// ---------------------------------------------------------------------
+/* This checks the tag for true/false yes/no etc */
+bool debListParser::HandleFlag(const char *Tag,unsigned long &Flags,
+			       unsigned long Flag)
+{
+   const char *Start;
+   const char *Stop;
+   if (Section.Find(Tag,Start,Stop) == false)
+      return true;
+   
+   int Set = 2;
+   if (strncasecmp(Start,"yes",Stop - Start) == 0)
+      Set = 1;
+   if (strncasecmp(Start,"true",Stop - Start) == 0)
+      Set = 1;
+   if (strncasecmp(Start,"no",Stop - Start) == 0)
+      Set = 0;
+   if (strncasecmp(Start,"false",Stop - Start) == 0)
+      Set = 0;
+   if (Set == 2)
+   {
+      _error->Warning("Unknown flag value");
+      return true;
+   }
+   
+   if (Set == 0)
+      Flags &= ~Flag;
+   if (Set == 1)
+      Flags |= Flag;
+   return true;
+}
+									/*}}}*/
+// ListParser::Package - Return the package name			/*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the name of the package this section describes */
+string debListParser::Package()
+{
+   string Result = FindTag("Package");
+   if (Result.empty() == true)
+      _error->Error("Encoutered a section with no Package: header");
+   return Result;
+}
+									/*}}}*/
+// ListParser::Version - Return the version string			/*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the string describing the version in debian form,
+   epoch:upstream-release. If this returns the blank string then the 
+   entry is assumed to only describe package properties */
+string debListParser::Version()
+{
+   return FindTag("Version");
+}
+									/*}}}*/
+// ListParser::NewPackage - Fill in the package structure		/*{{{*/
+// ---------------------------------------------------------------------
+/* This is called when a new package structure is created. It must fill
+   in the static package information. */
+bool debListParser::NewPackage(pkgCache::PkgIterator Pkg)
+{
+   // Debian doesnt have anything, everything is condionally megered
+   return true;
+}
+									/*}}}*/
+// ListParser::NewVersion - Fill in the version structure		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debListParser::NewVersion(pkgCache::VerIterator Ver)
+{   
+   return true;
+}
+									/*}}}*/
+// ListParser::UsePackage - Update a package structure			/*{{{*/
+// ---------------------------------------------------------------------
+/* This is called to update the package with any new information 
+   that might be found in the section */
+bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
+			       pkgCache::VerIterator Ver)
+{
+   if (Pkg->Section == 0)
+      if ((Pkg->Section = UniqFindTagWrite("Section")) == 0)
+	 return false;
+   if (HandleFlag("Essential",Pkg->Flags,pkgCache::Essential) == false)
+      return false;
+   if (HandleFlag("Immediate-Configure",Pkg->Flags,pkgCache::ImmediateConf) == false)
+      return false;
+   if (ParseStatus(Pkg,Ver) == false)
+      return false;
+   return true;
+}
+									/*}}}*/
+// ListParser::ParseStatus - Parse the status feild			/*{{{*/
+// ---------------------------------------------------------------------
+/* Status lines are of the form,
+     Status: want flag status
+   want = unknown, install, hold, deinstall, purge
+   flag = ok, reinstreq, hold, hold-reinstreq
+   status = not-installed, unpacked, half-configured, uninstalled,
+            half-installed, config-files, post-inst-failed, 
+            removal-failed, installed
+   
+   Some of the above are obsolete (I think?) flag = hold-* and 
+   status = post-inst-failed, removal-failed at least.
+ */
+bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
+				pkgCache::VerIterator Ver)
+{
+   const char *Start;
+   const char *Stop;
+   if (Section.Find("Status",Start,Stop) == false)
+      return true;
+   
+   // Isolate the first word
+   const char *I = Start;
+   for(; I < Stop && *I != ' '; I++);
+   if (I >= Stop || *I != ' ')
+      return _error->Error("Malformed Status line");
+
+   // Process the want field
+   WordList WantList[] = {{"unknown",pkgCache::Unknown},
+                          {"install",pkgCache::Install},
+                          {"hold",pkgCache::Hold},
+                          {"deinstall",pkgCache::DeInstall},
+                          {"purge",pkgCache::Purge}};
+   if (GrabWord(string(Start,I-Start),WantList,
+		_count(WantList),Pkg->SelectedState) == false)
+      return _error->Error("Malformed 1st word in the Status line");
+
+   // Isloate the next word
+   I++;
+   Start = I;
+   for(; I < Stop && *I != ' '; I++);
+   if (I >= Stop || *I != ' ')
+      return _error->Error("Malformed status line, no 2nd word");
+
+   // Process the flag field
+   WordList FlagList[] = {{"ok",pkgCache::Ok},
+                          {"reinstreq",pkgCache::ReInstReq},
+                          {"hold",pkgCache::HoldInst},
+                          {"hold-reinstreq",pkgCache::HoldReInstReq}};
+   if (GrabWord(string(Start,I-Start),FlagList,
+		_count(FlagList),Pkg->InstState) == false)
+      return _error->Error("Malformed 2nd word in the Status line");
+
+   // Isloate the last word
+   I++;
+   Start = I;
+   for(; I < Stop && *I != ' '; I++);
+   if (I != Stop)
+      return _error->Error("Malformed Status line, no 3rd word");
+
+   // Process the flag field
+   WordList StatusList[] = {{"not-installed",pkgCache::NotInstalled},
+                            {"unpacked",pkgCache::UnPacked},
+                            {"half-configured",pkgCache::HalfConfigured},
+                            {"installed",pkgCache::Installed},
+                            {"uninstalled",pkgCache::UnInstalled},
+                            {"half-installed",pkgCache::HalfInstalled},
+                            {"config-files",pkgCache::ConfigFiles},
+                            {"post-inst-failed",pkgCache::HalfConfigured},
+                            {"removal-failed",pkgCache::HalfInstalled}};
+   if (GrabWord(string(Start,I-Start),StatusList,
+		_count(StatusList),Pkg->CurrentState) == false)
+      return _error->Error("Malformed 3rd word in the Status line");
+
+   /* A Status line marks the package as indicating the current
+      version as well. Only if it is actually installed.. Otherwise
+      the interesting dpkg handling of the status file creates bogus 
+      entries. */
+   if (!(Pkg->CurrentState == pkgCache::NotInstalled ||
+	 Pkg->CurrentState == pkgCache::ConfigFiles))
+   {
+      if (Ver.end() == true)
+	 _error->Warning("Encountered status field in a non-version description");
+      else
+	 Pkg->CurrentVer = Ver.Index();
+   }
+   
+   return true;
+}
+									/*}}}*/
+// ListParser::GrabWord - Matches a word and returns			/*{{{*/
+// ---------------------------------------------------------------------
+/* Looks for a word in a list of words - for ParseStatus */
+bool debListParser::GrabWord(string Word,WordList *List,int Count,
+			     unsigned char &Out)
+{
+   for (int C = 0; C != Count; C++)
+   {
+      if (strcasecmp(Word.c_str(),List[C].Str) == 0)
+      {
+	 Out = List[C].Val;
+	 return true;
+      }
+   }
+   return false;
+}
+									/*}}}*/
+// ListParser::Step - Move to the next section in the file		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debListParser::Step()
+{
+   return Tags.Step(Section);
+}
+									/*}}}*/
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
new file mode 100644
index 000000000..30eb869ad
--- /dev/null
+++ b/apt-pkg/deb/deblistparser.h
@@ -0,0 +1,51 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: deblistparser.h,v 1.1 1998/07/04 05:58:08 jgg Exp $
+/* ######################################################################
+   
+   Debian Package List Parser - This implements the abstract parser 
+   interface for Debian package files
+   
+   ##################################################################### */
+									/*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_DEBLISTPARSER_H
+#define PKGLIB_DEBLISTPARSER_H
+
+#include <pkglib/pkgcachegen.h>
+#include <pkglib/tagfile.h>
+
+class debListParser : public pkgCacheGenerator::ListParser
+{
+   pkgTagFile Tags;
+   pkgTagSection Section;
+   
+   // Parser Helper
+   struct WordList
+   {
+      char *Str;
+      unsigned char Val;
+   };
+   
+   string FindTag(const char *Tag);
+   unsigned long UniqFindTagWrite(const char *Tag);
+   bool HandleFlag(const char *Tag,unsigned long &Flags,unsigned long Flag);
+   bool ParseStatus(pkgCache::PkgIterator Pkg,pkgCache::VerIterator Ver);
+   bool GrabWord(string Word,WordList *List,int Count,unsigned char &Out);
+   
+   public:
+   
+   // These all operate against the current section
+   virtual string Package();
+   virtual string Version();
+   virtual bool NewVersion(pkgCache::VerIterator Ver);
+   virtual bool NewPackage(pkgCache::PkgIterator Pkg);
+   virtual bool UsePackage(pkgCache::PkgIterator Pkg,
+			   pkgCache::VerIterator Ver);
+
+   virtual bool Step();
+   
+   debListParser(File &File);
+};
+
+#endif
-- 
cgit v1.2.3