]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/configuration.cc
Clean support
[apt.git] / apt-pkg / contrib / configuration.cc
index 82418f9c25de1b1e4e3551346fd4244cc79f18c2..e702c26e624e52cc9075dfb06f2141f6ead25c89 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: configuration.cc,v 1.7 1998/10/20 02:39:26 jgg Exp $
+// $Id: configuration.cc,v 1.12 1999/01/27 02:48:52 jgg Exp $
 /* ######################################################################
 
    Configuration Class
 /* ######################################################################
 
    Configuration Class
@@ -17,7 +17,7 @@
 #endif
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/error.h>
 #endif
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/error.h>
-#include <strutl.h>
+#include <apt-pkg/strutl.h>
 
 #include <stdio.h>
 #include <fstream.h>
 
 #include <stdio.h>
 #include <fstream.h>
@@ -33,7 +33,7 @@ Configuration::Configuration()
    Root = new Item;
 }
                                                                        /*}}}*/
    Root = new Item;
 }
                                                                        /*}}}*/
-// Configuration::Lookup - Lookup a single item                                                                        /*{{{*/
+// Configuration::Lookup - Lookup a single item                                /*{{{*/
 // ---------------------------------------------------------------------
 /* This will lookup a single item by name below another item. It is a 
    helper function for the main lookup function */
 // ---------------------------------------------------------------------
 /* This will lookup a single item by name below another item. It is a 
    helper function for the main lookup function */
@@ -43,10 +43,17 @@ Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
    int Res = 1;
    Item *I = Head->Child;
    Item **Last = &Head->Child;
    int Res = 1;
    Item *I = Head->Child;
    Item **Last = &Head->Child;
-   for (; I != 0; Last = &I->Next, I = I->Next)
-      if ((Res = stringcasecmp(I->Tag.begin(),I->Tag.end(),S,S + Len)) == 0)
-        break;
    
    
+   // Empty strings match nothing. They are used for lists.
+   if (Len != 0)
+   {
+      for (; I != 0; Last = &I->Next, I = I->Next)
+        if ((Res = stringcasecmp(I->Tag.begin(),I->Tag.end(),S,S + Len)) == 0)
+           break;
+   }
+   else
+      for (; I != 0; Last = &I->Next, I = I->Next);
+      
    if (Res == 0)
       return I;
    if (Create == false)
    if (Res == 0)
       return I;
    if (Create == false)
@@ -66,11 +73,14 @@ Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
    new items */
 Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
 {
    new items */
 Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
 {
+   if (Name == 0)
+      return Root->Child;
+   
    const char *Start = Name;
    const char *End = Start + strlen(Name);
    const char *TagEnd = Name;
    Item *Itm = Root;
    const char *Start = Name;
    const char *End = Start + strlen(Name);
    const char *TagEnd = Name;
    Item *Itm = Root;
-   for (; End - TagEnd > 2; TagEnd++)
+   for (; End - TagEnd >= 2; TagEnd++)
    {
       if (TagEnd[0] == ':' && TagEnd[1] == ':')
       {
    {
       if (TagEnd[0] == ':' && TagEnd[1] == ':')
       {
@@ -81,6 +91,13 @@ Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
       }
    }   
 
       }
    }   
 
+   // This must be a trailing ::, we create unique items in a list
+   if (End - Start == 0)
+   {
+      if (Create == false)
+        return 0;
+   }
+   
    Itm = Lookup(Itm,Start,End - Start,Create);
    return Itm;
 }
    Itm = Lookup(Itm,Start,End - Start,Create);
    return Itm;
 }
@@ -209,6 +226,42 @@ bool Configuration::Exists(const char *Name)
    return true;
 }
                                                                        /*}}}*/
    return true;
 }
                                                                        /*}}}*/
+// Configuration::Dump - Dump the config                               /*{{{*/
+// ---------------------------------------------------------------------
+/* Dump the entire configuration space */
+void Configuration::Dump()
+{
+   /* Write out all of the configuration directives by walking the 
+      configuration tree */
+   const Configuration::Item *Top = _config->Tree(0);
+   for (; Top != 0;)
+   {
+      clog << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
+      
+      if (Top->Child != 0)
+      {
+        Top = Top->Child;
+        continue;
+      }
+      
+      while (Top != 0 && Top->Next == 0)
+        Top = Top->Parent;
+      if (Top != 0)
+        Top = Top->Next;
+   }   
+}
+                                                                       /*}}}*/
+
+// Configuration::Item::FullTag - Return the fully scoped tag          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string Configuration::Item::FullTag() const
+{
+   if (Parent == 0 || Parent->Parent == 0)
+      return Tag;
+   return Parent->FullTag() + "::" + Tag;
+}
+                                                                       /*}}}*/
 
 // ReadConfigFile - Read a configuration file                          /*{{{*/
 // ---------------------------------------------------------------------
 
 // ReadConfigFile - Read a configuration file                          /*{{{*/
 // ---------------------------------------------------------------------
@@ -253,8 +306,14 @@ bool ReadConfigFile(Configuration &Conf,string FName)
       }
       
       // Discard single line comments
       }
       
       // Discard single line comments
+      bool InQuote = false;
       for (char *I = Buffer; *I != 0; I++)
       {
       for (char *I = Buffer; *I != 0; I++)
       {
+        if (*I == '"')
+           InQuote = !InQuote;
+        if (InQuote == true)
+           continue;
+        
         if (*I == '/' && I[1] == '/')
          {
            *I = 0;
         if (*I == '/' && I[1] == '/')
          {
            *I = 0;
@@ -265,6 +324,11 @@ bool ReadConfigFile(Configuration &Conf,string FName)
       // Look for multi line comments
       for (char *I = Buffer; *I != 0; I++)
       {
       // Look for multi line comments
       for (char *I = Buffer; *I != 0; I++)
       {
+        if (*I == '"')
+           InQuote = !InQuote;
+        if (InQuote == true)
+           continue;
+        
         if (*I == '/' && I[1] == '*')
          {
            InComment = true;
         if (*I == '/' && I[1] == '*')
          {
            InComment = true;
@@ -327,17 +391,11 @@ bool ReadConfigFile(Configuration &Conf,string FName)
               continue;
 
            // Parse off the tag
               continue;
 
            // Parse off the tag
-           string::size_type Pos = LineBuffer.find(' ');
-           if (Pos == string::npos)
-           {
-              if (TermChar == '{')
-                 Pos = LineBuffer.length();
-              else
-                 return _error->Error("Syntax error %s:%u: Tag with no value",FName.c_str(),CurLine);
-           }
+           string Tag;
+           const char *Pos = LineBuffer.c_str();
+           if (ParseQuoteWord(Pos,Tag) == false)
+              return _error->Error("Syntax error %s:%u: Malformed Tag",FName.c_str(),CurLine);     
            
            
-           string Tag = string(LineBuffer,0,Pos);
-
            // Go down a level
            if (TermChar == '{')
            {
            // Go down a level
            if (TermChar == '{')
            {
@@ -348,28 +406,27 @@ bool ReadConfigFile(Configuration &Conf,string FName)
               Tag = string();
            }
 
               Tag = string();
            }
 
-           // We dont have a value to set
-           if (Pos == LineBuffer.length())
+           // Parse off the word
+           string Word;
+           if (ParseCWord(Pos,Word) == false)
            {
            {
-              LineBuffer = string();
-              continue;
+              if (TermChar != '{')
+              {
+                 Word = Tag;
+                 Tag = "";
+              }               
            }
            
            }
            
-           // Parse off the word
-           string Word;
-           if (ParseCWord(LineBuffer.c_str()+Pos,Word) == false)
-              return _error->Error("Syntax error %s:%u: Malformed value",FName.c_str(),CurLine);
-              
            // Generate the item name
            string Item;
            if (ParentTag.empty() == true)
               Item = Tag;
            else
            {
            // Generate the item name
            string Item;
            if (ParentTag.empty() == true)
               Item = Tag;
            else
            {
-              if (Tag.empty() == true)
-                 Item = ParentTag;
-              else
+              if (TermChar != '{' || Tag.empty() == false)
                  Item = ParentTag + "::" + Tag;
                  Item = ParentTag + "::" + Tag;
+              else
+                 Item = ParentTag;
            }
            
            // Set the item in the configuration class
            }
            
            // Set the item in the configuration class