]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/configuration.cc
More MD5
[apt.git] / apt-pkg / contrib / configuration.cc
index fa07ed35ae1c7df90e22e00f0b1abe61138b4bb7..1c58b9881e6bea81bf24e8d067dc618edf2e8fc7 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: configuration.cc,v 1.8 1998/10/22 04:56:45 jgg Exp $
+// $Id: configuration.cc,v 1.13 1999/07/02 23:17:00 jgg Exp $
 /* ######################################################################
 
    Configuration Class
@@ -17,7 +17,7 @@
 #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>
@@ -43,10 +43,17 @@ Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
    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)
@@ -73,7 +80,7 @@ Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
    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] == ':')
       {
@@ -84,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;
 }
@@ -212,6 +226,31 @@ bool Configuration::Exists(const char *Name)
    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          /*{{{*/
 // ---------------------------------------------------------------------
@@ -237,6 +276,8 @@ bool ReadConfigFile(Configuration &Conf,string FName)
    
    char Buffer[300];
    string LineBuffer;
+   string Stack[100];
+   unsigned int StackPos = 0;
    
    // Parser state
    string ParentTag;
@@ -267,8 +308,14 @@ bool ReadConfigFile(Configuration &Conf,string FName)
       }
       
       // Discard single line comments
+      bool InQuote = false;
       for (char *I = Buffer; *I != 0; I++)
       {
+        if (*I == '"')
+           InQuote = !InQuote;
+        if (InQuote == true)
+           continue;
+        
         if (*I == '/' && I[1] == '/')
          {
            *I = 0;
@@ -279,6 +326,11 @@ bool ReadConfigFile(Configuration &Conf,string FName)
       // 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;
@@ -326,11 +378,10 @@ bool ReadConfigFile(Configuration &Conf,string FName)
            // Move up a tag
            if (TermChar == '}')
            {
-              string::size_type Pos = ParentTag.rfind("::");
-              if (Pos == string::npos)
+              if (StackPos == 0)
                  ParentTag = string();
               else
-                 ParentTag = string(ParentTag,0,Pos);
+                 ParentTag = Stack[--StackPos];
            }
            
            // Syntax Error
@@ -341,20 +392,16 @@ bool ReadConfigFile(Configuration &Conf,string FName)
               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 == '{')
            {
+              if (StackPos <= 100)
+                 Stack[StackPos++] = ParentTag;
               if (ParentTag.empty() == true)
                  ParentTag = Tag;
               else
@@ -362,28 +409,27 @@ bool ReadConfigFile(Configuration &Conf,string FName)
               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
            {
-              if (Tag.empty() == true)
-                 Item = ParentTag;
-              else
+              if (TermChar != '{' || Tag.empty() == false)
                  Item = ParentTag + "::" + Tag;
+              else
+                 Item = ParentTag;
            }
            
            // Set the item in the configuration class