]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/configuration.cc
Sync
[apt.git] / apt-pkg / contrib / configuration.cc
index 7694330f98ed4018ef9ffed6f3eed06ab2d0b8c8..b12fed6be67bade04e6bd05efc8b04a5ee6ecd99 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: configuration.cc,v 1.2 1998/07/09 05:12:33 jgg Exp $
+// $Id: configuration.cc,v 1.5 1998/09/26 05:34:26 jgg Exp $
 /* ######################################################################
 
    Configuration Class
                                                                        /*}}}*/
 // Include files                                                       /*{{{*/
 #ifdef __GNUG__
-#pragma implementation "pkglib/configuration.h"
+#pragma implementation "apt-pkg/configuration.h"
 #endif
-#include <pkglib/configuration.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
 #include <strutl.h>
 
 #include <stdio.h>
+#include <fstream.h>
                                                                        /*}}}*/
 
 Configuration *_config = new Configuration;
@@ -137,6 +139,39 @@ int Configuration::FindI(const char *Name,int Default)
    if (End == Itm->Value.c_str())
       return Default;
    
+   return Res;
+}
+                                                                       /*}}}*/
+// Configuration::FindB - Find a boolean type                          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Configuration::FindB(const char *Name,bool Default)
+{
+   Item *Itm = Lookup(Name,false);
+   if (Itm == 0 || Itm->Value.empty() == true)
+      return Default;
+   
+   char *End;
+   int Res = strtol(Itm->Value.c_str(),&End,0);
+   if (End == Itm->Value.c_str() || Res < 0 || Res > 1)
+   {
+      // Check for positives
+      if (strcasecmp(Itm->Value.c_str(),"no") == 0 ||
+         strcasecmp(Itm->Value.c_str(),"false") == 0 ||
+         strcasecmp(Itm->Value.c_str(),"without") == 0 ||
+         strcasecmp(Itm->Value.c_str(),"disable") == 0)
+        return false;
+      
+      // Check for negatives
+      if (strcasecmp(Itm->Value.c_str(),"yes") == 0 ||
+         strcasecmp(Itm->Value.c_str(),"true") == 0 ||
+         strcasecmp(Itm->Value.c_str(),"with") == 0 ||
+         strcasecmp(Itm->Value.c_str(),"enable") == 0)
+        return false;
+      
+      return Default;
+   }
+   
    return Res;
 }
                                                                        /*}}}*/
@@ -164,3 +199,197 @@ void Configuration::Set(const char *Name,int Value)
    Itm->Value = S;
 }
                                                                        /*}}}*/
+// Configuration::Exists - Returns true if the Name exists             /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Configuration::Exists(const char *Name)
+{
+   Item *Itm = Lookup(Name,false);
+   if (Itm == 0)
+      return false;
+   return true;
+}
+                                                                       /*}}}*/
+
+// ReadConfigFile - Read a configuration file                          /*{{{*/
+// ---------------------------------------------------------------------
+/* The configuration format is very much like the named.conf format
+   used in bind8, in fact this routine can parse most named.conf files. */
+bool ReadConfigFile(Configuration &Conf,string FName)
+{
+   // Open the stream for reading
+   ifstream F(FName.c_str(),ios::in | ios::nocreate);
+   if (!F != 0)
+      return _error->Errno("ifstream::ifstream","Opening configuration file %s",FName.c_str());
+   
+   char Buffer[300];
+   string LineBuffer;
+   
+   // Parser state
+   string ParentTag;
+   
+   int CurLine = 0;
+   bool InComment = false;
+   while (F.eof() == false)
+   {
+      F.getline(Buffer,sizeof(Buffer));
+      CurLine++;
+      _strtabexpand(Buffer,sizeof(Buffer));
+      _strstrip(Buffer);
+
+      // Multi line comment
+      if (InComment == true)
+      {
+        for (const char *I = Buffer; *I != 0; I++)
+        {
+           if (*I == '*' && I[1] == '/')
+           {
+              memmove(Buffer,I+2,strlen(I+2) + 1);
+              InComment = false;
+              break;
+           }       
+        }
+        if (InComment == true)
+           continue;
+      }
+      
+      // Discard single line comments
+      for (char *I = Buffer; *I != 0; I++)
+      {
+        if (*I == '/' && I[1] == '/')
+         {
+           *I = 0;
+           break;
+        }
+      }
+      
+      // Look for multi line comments
+      for (char *I = Buffer; *I != 0; I++)
+      {
+        if (*I == '/' && I[1] == '*')
+         {
+           InComment = true;
+           for (char *J = Buffer; *J != 0; J++)
+           {
+              if (*J == '*' && J[1] == '/')
+              {
+                 memmove(I,J+2,strlen(J+2) + 1);
+                 InComment = false;
+                 break;
+              }               
+           }
+           
+           if (InComment == true)
+           {
+              *I = 0;
+              break;
+           }       
+        }
+      }
+      
+      // Blank
+      if (Buffer[0] == 0)
+        continue;
+      
+      // We now have a valid line fragment
+      for (char *I = Buffer; *I != 0;)
+      {
+        if (*I == '{' || *I == ';' || *I == '}')
+        {
+           // Put the last fragement into the buffer
+           char *Start = Buffer;
+           char *Stop = I;
+           for (; Start != I && isspace(*Start) != 0; Start++);
+           for (; Stop != Start && isspace(Stop[-1]) != 0; Stop--);
+           if (LineBuffer.empty() == false && Stop - Start != 0)
+              LineBuffer += ' ';
+           LineBuffer += string(Start,Stop - Start);
+           
+           // Remove the fragment
+           char TermChar = *I;
+           memmove(Buffer,I + 1,strlen(I + 1) + 1);
+           I = Buffer;
+
+           // Move up a tag
+           if (TermChar == '}')
+           {
+              string::size_type Pos = ParentTag.rfind("::");
+              if (Pos == string::npos)
+                 ParentTag = string();
+              else
+                 ParentTag = string(ParentTag,0,Pos);
+           }
+           
+           // Syntax Error
+           if (TermChar == '{' && LineBuffer.empty() == true)
+              return _error->Error("Syntax error %s:%u: Block starts with no name.",FName.c_str(),CurLine);
+           
+           if (LineBuffer.empty() == true)
+              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 = string(LineBuffer,0,Pos);
+
+           // Go down a level
+           if (TermChar == '{')
+           {
+              if (ParentTag.empty() == true)
+                 ParentTag = Tag;
+              else
+                 ParentTag += string("::") + Tag;
+              Tag = string();
+           }
+
+           // We dont have a value to set
+           if (Pos == LineBuffer.length())
+           {
+              LineBuffer = string();
+              continue;
+           }
+           
+           // 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
+                 Item = ParentTag + "::" + Tag;
+           }
+           
+           // Set the item in the configuration class
+           Conf.Set(Item,Word);
+                           
+           // Empty the buffer
+           LineBuffer = string();
+        }
+        else
+           I++;
+      }
+
+      // Store the fragment
+      const char *Stripd = _strstrip(Buffer);
+      if (*Stripd != 0 && LineBuffer.empty() == false)
+        LineBuffer += " ";
+      LineBuffer += Stripd;
+   }
+   
+   return true;
+}
+                                                                       /*}}}*/