Ver Fonte

2009-10-17 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Fixed the bug that Netrc::parse() cannot recognize comment line.
	* src/Netrc.cc
	* src/Util.h
	* test/NetrcTest.cc
	* test/sample.netrc
Tatsuhiro Tsujikawa há 16 anos atrás
pai
commit
10e371c25a
5 ficheiros alterados com 108 adições e 37 exclusões
  1. 8 0
      ChangeLog
  2. 63 36
      src/Netrc.cc
  3. 31 0
      src/Util.h
  4. 3 1
      test/NetrcTest.cc
  5. 3 0
      test/sample.netrc

+ 8 - 0
ChangeLog

@@ -1,3 +1,11 @@
+2009-10-17  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Fixed the bug that Netrc::parse() cannot recognize comment line.
+	* src/Netrc.cc
+	* src/Util.h
+	* test/NetrcTest.cc
+	* test/sample.netrc
+
 2009-10-13  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Fixed typo

+ 63 - 36
src/Netrc.cc

@@ -36,10 +36,12 @@
 
 #include <fstream>
 #include <algorithm>
+#include <vector>
 
 #include "DlAbortEx.h"
 #include "StringFormat.h"
 #include "A2STR.h"
+#include "Util.h"
 
 namespace aria2 {
 
@@ -55,21 +57,9 @@ const std::string Netrc::ACCOUNT("account");
 
 const std::string Netrc::MACDEF("macdef");
 
-std::string Netrc::getRequiredNextToken(std::ifstream& f) const
-{
-  std::string token;
-  if(f >> token) {
-    return token;
-  } else {
-    throw DL_ABORT_EX
-      ("Netrc:parse error. EOF reached where a token expected.");
-  }
-}
-
 void Netrc::skipMacdef(std::ifstream& f) const
 {
   std::string line;
-  getline(f, line);
   while(getline(f, line)) {
     if(line == A2STR::CR_C || line.empty()) {
       break;
@@ -87,33 +77,70 @@ void Netrc::parse(const std::string& path)
       (StringFormat("File not found: %s", path.c_str()).str());
   }
 
+  enum STATE {
+    GET_TOKEN,
+    SET_MACHINE,
+    SET_LOGIN,
+    SET_PASSWORD,
+    SET_ACCOUNT,
+    SET_MACDEF
+  };
   AuthenticatorHandle authenticator;
-  std::string token;
-  while(f >> token) {
-    if(token == Netrc::MACHINE) {
-      storeAuthenticator(authenticator);
-      authenticator.reset(new Authenticator());
-      authenticator->setMachine(getRequiredNextToken(f));
-    } else if(token == Netrc::DEFAULT) {
-      storeAuthenticator(authenticator);
-      authenticator.reset(new DefaultAuthenticator());
-    } else {
-      if(authenticator.isNull()) {
-	throw DL_ABORT_EX
-	  ("Netrc:parse error. %s encounterd where 'machine' or 'default' expected.");
-      }
-      if(token == Netrc::LOGIN) {
-	authenticator->setLogin(getRequiredNextToken(f));
-      } else if(token == Netrc::PASSWORD) {
-	authenticator->setPassword(getRequiredNextToken(f));
-      } else if(token == Netrc::ACCOUNT) {
-	authenticator->setAccount(getRequiredNextToken(f));
-      } else if(token == Netrc::MACDEF) {
-	getRequiredNextToken(f);
-	skipMacdef(f);
-      }
+  std::string line;
+  STATE state = GET_TOKEN;
+  while(getline(f, line)) {
+    if(Util::startsWith(line, "#")) {
+      continue;
+    }
+    std::vector<std::string> tokens;
+    Util::split(line, std::back_inserter(tokens), " \t", true);
+    for(std::vector<std::string>::const_iterator iter = tokens.begin();
+	iter != tokens.end(); ++iter) {
+      const std::string& token = *iter;
+      if(state == GET_TOKEN) {
+	if(token == Netrc::MACHINE) {
+	  storeAuthenticator(authenticator);
+	  authenticator.reset(new Authenticator());
+	  state = SET_MACHINE;
+	} else if(token == Netrc::DEFAULT) {
+	  storeAuthenticator(authenticator);
+	  authenticator.reset(new DefaultAuthenticator());
+	} else {
+	  if(authenticator.isNull()) {
+	    throw DL_ABORT_EX
+	      (StringFormat("Netrc:parse error. %s encounterd where 'machine'"
+			    " or 'default' expected.", token.c_str()).str());
+	  }
+	  if(token == Netrc::LOGIN) {
+	    state = SET_LOGIN;
+	  } else if(token == Netrc::PASSWORD) {
+	    state = SET_PASSWORD;
+	  } else if(token == Netrc::ACCOUNT) {
+	    state = SET_ACCOUNT;
+	  } else if(token == Netrc::MACDEF) {
+	    state = SET_MACDEF;
+	  }
+	}
+      } else {
+	if(state == SET_MACHINE) {
+	  authenticator->setMachine(token);
+	} else if(state == SET_LOGIN) {
+	  authenticator->setLogin(token);
+	} else if(state == SET_PASSWORD) {
+	  authenticator->setPassword(token);
+	} else if(state == SET_ACCOUNT) {
+	  authenticator->setAccount(token);
+	} else if(state == SET_MACDEF) {
+	  skipMacdef(f);
+	}
+	state = GET_TOKEN;
+      }	
     }
   }
+  if(state != GET_TOKEN) {
+    throw DL_ABORT_EX
+      ("Netrc:parse error. EOF reached where a token expected.");
+  }
   storeAuthenticator(authenticator);
 }
 

+ 31 - 0
src/Util.h

@@ -140,6 +140,37 @@ public:
   static void slice(std::deque<std::string>& result, const std::string& src,
 		    char delim, bool trim = false);
   
+  template<typename OutputIterator>
+  static OutputIterator split(const std::string& src, OutputIterator out,
+			      const std::string& delims, bool doTrim = false)
+  {
+    std::string::size_type p = 0;
+    while(1) {
+      std::string::size_type np = src.find_first_of(delims, p);
+      if(np == std::string::npos) {
+	std::string term = src.substr(p);
+	if(doTrim) {
+	  term = trim(term);
+	}
+	if(!term.empty()) {
+	  *out = term;
+	  ++out;
+	}
+	break;
+      }
+      std::string term = src.substr(p, np-p);
+      if(doTrim) {
+	term = trim(term);
+      }
+      p = np+1;
+      if(!term.empty()) {
+	*out = term;
+	++out;
+      }
+    }
+    return out;
+  }
+
   static const std::string DEFAULT_TRIM_CHARSET;
 
   static std::string trim(const std::string& src,

+ 3 - 1
test/NetrcTest.cc

@@ -1,8 +1,10 @@
 #include "Netrc.h"
-#include "Exception.h"
+
 #include <iostream>
 #include <cppunit/extensions/HelperMacros.h>
 
+#include "Exception.h"
+
 namespace aria2 {
 
 class NetrcTest : public CppUnit::TestFixture {

+ 3 - 0
test/sample.netrc

@@ -1,3 +1,4 @@
+#sample netrc file for unit testing
 machine host1
 login tujikawa
 password tujikawapassword
@@ -9,5 +10,7 @@ machine host2
 login aria2
 password aria2password
 account aria2account
+macdef init
 
+#another comment line
 default login anonymous password ARIA2@USER account ARIA2@ACCT