Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 May 2014 10:42:26 +0000 (UTC)
From:      Veniamin Gvozdikov <vg@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r352804 - head/textproc/ctpp2/files
Message-ID:  <201405021042.s42AgQUk089278@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: vg
Date: Fri May  2 10:42:25 2014
New Revision: 352804
URL: http://svnweb.freebsd.org/changeset/ports/352804
QAT: https://qat.redports.org/buildarchive/r352804/

Log:
  * Fix build on FreeBSD 10 with clang 3.3
  * Split patch from PR
  
  PR:		ports/189134
  Submitted by:	Shambler <shambler@gmx.us>

Added:
  head/textproc/ctpp2/files/patch-include-CDT.hpp   (contents, props changed)
  head/textproc/ctpp2/files/patch-src-CDT.cpp   (contents, props changed)
  head/textproc/ctpp2/files/patch-src-CTPP2Util.cpp   (contents, props changed)
  head/textproc/ctpp2/files/patch-src-CTPP2VM.cpp   (contents, props changed)
  head/textproc/ctpp2/files/patch-tests-CDTTest.cpp   (contents, props changed)
Modified:
  head/textproc/ctpp2/files/patch-src-CTPP2FileSourceLoader.cpp

Added: head/textproc/ctpp2/files/patch-include-CDT.hpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/textproc/ctpp2/files/patch-include-CDT.hpp	Fri May  2 10:42:25 2014	(r352804)
@@ -0,0 +1,348 @@
+--- include/CDT.hpp.orig	2012-11-11 01:45:43.000000000 +0400
++++ include/CDT.hpp	2014-05-02 18:06:25.481307400 +0400
+@@ -48,13 +48,16 @@
+ 
+ #define C_MAX_SPRINTF_LENGTH 128
+ 
++class CTPP2DECL CDTConstIterator;
++class CTPP2DECL CDTIterator;
++
+ /**
+   @class CDT CDT.hpp <CDT.hpp>
+   @brief Common Data Type
+ */
+ class CTPP2DECL CDT
+ {
+-private:
++public:
+ 	/**
+ 	  @var typedef STLW::string<CDT> String
+ 	  @brief internal string definition
+@@ -72,7 +75,7 @@
+ 	  @brief internal hash definition
+ 	*/
+ 	typedef STLW::map<String, CDT>  Map;
+-public:
++
+ 	/**
+ 	  @enum eValType CDT.hpp <CDT.hpp>
+ 	  @brief Describes type of stored value
+@@ -1768,172 +1771,39 @@
+ 		virtual ~SortingComparator() throw();
+ 	};
+ 
+-	// FWD
+-	class CTPP2DECL ConstIterator;
+-
+-	/**
+-	  @class Iterator CDT.hpp <CDT.hpp>
+-	  @brief CDT[HASH] forward iterator
+-	*/
+-	class CTPP2DECL Iterator
+-	{
+-	private:
+-		friend class CDT;
+-		friend class ConstIterator;
+-
+-		/** Hash iterator */
+-		CDT::Map::iterator itMap;
+-
+-		/**
+-		  @brief Constructor
+-		  @param itIMap - map iterator
+-		*/
+-		Iterator(CDT::Map::iterator itIMap);
+-	public:
+-		/**
+-		  @brief Copy constructor
+-		  @param oRhs - object to copy
+-		*/
+-		Iterator(const Iterator & oRhs);
+-
+-		/**
+-		  @brief Operator =
+-		  @param oRhs - object to copy
+-		*/
+-		Iterator & operator=(const Iterator & oRhs);
+-
+-		/**
+-		  @brief Pre-increment operator ++
+-		*/
+-		Iterator & operator++();
+-
+-		/**
+-		  @brief Post-increment operator ++
+-		*/
+-		Iterator operator++(int);
+-
+-		/**
+-		  @brief Access operator
+-		  @return Pair of key => value
+-		*/
+-		STLW::pair<const STLW::string, CDT> * operator->();
+-
+-		/**
+-		  @brief Comparison operator
+-		  @param oRhs - object to compare
+-		  @return true if objects are equal
+-		*/
+-		bool operator ==(const Iterator & oRhs);
+-
+-		/**
+-		  @brief Comparison operator
+-		  @param oRhs - object to compare
+-		  @return true if objects are NOT equal
+-		*/
+-		bool operator !=(const Iterator & oRhs);
+-	};
+-
+ 	/**
+ 	  @brief Get iterator pointed to start of hash
+ 	*/
+-	Iterator Begin();
++	CDTIterator Begin();
+ 
+ 	/**
+ 	  @brief Get iterator pointed to end of hash
+ 	*/
+-	Iterator End();
++	CDTIterator End();
+ 
+ 	/**
+ 	  @brief Find element in hash
+ 	  @param sKey - element name
+ 	  @return Iterator pointed to element or to end of hash if nothing found
+ 	*/
+-	Iterator Find(const STLW::string & sKey);
+-
+-	/**
+-	  @class ConstIterator CDT.hpp <CDT.hpp>
+-	  @brief CDT[HASH] forward constant iterator
+-	*/
+-	class CTPP2DECL ConstIterator
+-	{
+-	private:
+-		friend class CDT;
+-
+-		/** Hash iterator */
+-		CDT::Map::const_iterator itMap;
+-
+-	public:
+-		/**
+-		  @brief Copy constructor
+-		  @param oRhs - object to copy
+-		*/
+-		ConstIterator(const ConstIterator & oRhs);
+-
+-		/**
+-		  @brief Type cast constructor
+-		  @param oRhs - object to copy
+-		*/
+-		ConstIterator(const Iterator & oRhs);
+-
+-		/**
+-		  @brief Operator =
+-		  @param oRhs - object to copy
+-		*/
+-		ConstIterator & operator=(const ConstIterator & oRhs);
+-
+-		/**
+-		  @brief Operator =
+-		  @param oRhs - object to copy
+-		*/
+-		ConstIterator & operator=(const Iterator & oRhs);
+-
+-		/**
+-		  @brief Pre-increment operator ++
+-		*/
+-		ConstIterator & operator++();
+-
+-		/**
+-		  @brief Post-increment operator ++
+-		*/
+-		ConstIterator operator++(int);
+-
+-		/**
+-		  @brief Access operator
+-		  @return Pair of key => value
+-		*/
+-		const STLW::pair<const STLW::string, CDT> * operator->() const;
+-
+-		/**
+-		  @brief Comparison operator
+-		  @param oRhs - object to compare
+-		  @return true if objects are equal
+-		*/
+-		bool operator ==(const ConstIterator & oRhs) const;
+-
+-		/**
+-		  @brief Comparison operator
+-		  @param oRhs - object to compare
+-		  @return true if objects are NOT equal
+-		*/
+-		bool operator !=(const ConstIterator & oRhs) const;
+-	};
++	CDTIterator Find(const STLW::string & sKey);
+ 
+ 	/**
+ 	  @brief Get constant iterator pointed to start of hash
+ 	*/
+-	ConstIterator Begin() const;
++	CDTConstIterator Begin() const;
+ 
+ 	/**
+ 	  @brief Get constant iterator pointed to end of hash
+ 	*/
+-	ConstIterator End() const;
++	CDTConstIterator End() const;
+ 
+ 	/**
+ 	  @brief Find element in hash
+ 	  @param sKey - element name
+ 	  @return Iterator pointed to element or to end of hash if nothing found
+ 	*/
+-	ConstIterator Find(const STLW::string & sKey) const;
++	CDTConstIterator Find(const STLW::string & sKey) const;
+ 
+ 	/**
+ 	  @brief Try to cast value to integer or to IEEE floating point value
+@@ -2009,6 +1879,139 @@
+ 
+ };
+ 
++
++/**
++  @class CDTIterator CDT.hpp <CDT.hpp>
++  @brief CDT[HASH] forward iterator
++*/
++class CTPP2DECL CDTIterator
++{
++private:
++	friend class CDT;
++	friend class CDTConstIterator;
++
++	/** Hash iterator */
++	CDT::Map::iterator itMap;
++
++	/**
++	  @brief Constructor
++	  @param itIMap - map iterator
++	*/
++	CDTIterator(CDT::Map::iterator itIMap);
++public:
++	/**
++	  @brief Copy constructor
++	  @param oRhs - object to copy
++	*/
++	CDTIterator(const CDTIterator & oRhs);
++
++	/**
++	  @brief Operator =
++	  @param oRhs - object to copy
++	*/
++	CDTIterator & operator=(const CDTIterator & oRhs);
++
++	/**
++	  @brief Pre-increment operator ++
++	*/
++	CDTIterator & operator++();
++
++	/**
++	  @brief Post-increment operator ++
++	*/
++	CDTIterator operator++(int);
++
++	/**
++	  @brief Access operator
++	  @return Pair of key => value
++	*/
++	STLW::pair<const STLW::string, CDT> * operator->();
++
++	/**
++	  @brief Comparison operator
++	  @param oRhs - object to compare
++	  @return true if objects are equal
++	*/
++	bool operator ==(const CDTIterator & oRhs);
++
++	/**
++	  @brief Comparison operator
++	  @param oRhs - object to compare
++	  @return true if objects are NOT equal
++	*/
++	bool operator !=(const CDTIterator & oRhs);
++};
++
++
++/**
++  @class CDTConstIterator CDT.hpp <CDT.hpp>
++  @brief CDT[HASH] forward constant iterator
++*/
++class CTPP2DECL CDTConstIterator
++{
++private:
++	friend class CDT;
++
++	/** Hash iterator */
++	CDT::Map::const_iterator itMap;
++
++public:
++	/**
++	  @brief Copy constructor
++	  @param oRhs - object to copy
++	*/
++	CDTConstIterator(const CDTConstIterator & oRhs);
++
++	/**
++	  @brief Type cast constructor
++	  @param oRhs - object to copy
++	*/
++	CDTConstIterator(const CDTIterator & oRhs);
++
++	/**
++	  @brief Operator =
++	  @param oRhs - object to copy
++	*/
++	CDTConstIterator & operator=(const CDTConstIterator & oRhs);
++
++	/**
++	  @brief Operator =
++	  @param oRhs - object to copy
++	*/
++	CDTConstIterator & operator=(const CDTIterator & oRhs);
++
++	/**
++	  @brief Pre-increment operator ++
++	*/
++	CDTConstIterator & operator++();
++
++	/**
++	  @brief Post-increment operator ++
++	*/
++	CDTConstIterator operator++(int);
++
++	/**
++	  @brief Access operator
++	  @return Pair of key => value
++	*/
++	const STLW::pair<const STLW::string, CDT> * operator->() const;
++
++	/**
++	  @brief Comparison operator
++	  @param oRhs - object to compare
++	  @return true if objects are equal
++	*/
++	bool operator ==(const CDTConstIterator & oRhs) const;
++
++	/**
++	  @brief Comparison operator
++	  @param oRhs - object to compare
++	  @return true if objects are NOT equal
++	*/
++	bool operator !=(const CDTConstIterator & oRhs) const;
++};
++
++
+ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Realization

Added: head/textproc/ctpp2/files/patch-src-CDT.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/textproc/ctpp2/files/patch-src-CDT.cpp	Fri May  2 10:42:25 2014	(r352804)
@@ -0,0 +1,216 @@
+--- src/CDT.cpp.orig	2012-11-10 23:38:03.000000000 +0400
++++ src/CDT.cpp	2014-05-02 18:06:25.502508698 +0400
+@@ -108,17 +108,17 @@
+ //
+ // Constructor
+ //
+-CDT::Iterator::Iterator(CDT::Map::iterator itIMap): itMap(itIMap) { ;; }
++CDTIterator::CDTIterator(CDT::Map::iterator itIMap): itMap(itIMap) { ;; }
+ 
+ //
+ // Copy constructor
+ //
+-CDT::Iterator::Iterator(const CDT::Iterator & oRhs): itMap(oRhs.itMap) { ;; }
++CDTIterator::CDTIterator(const CDTIterator & oRhs): itMap(oRhs.itMap) { ;; }
+ 
+ //
+ // Operator =
+ //
+-CDT::Iterator & CDT::Iterator::operator=(const CDT::Iterator & oRhs)
++CDTIterator & CDTIterator::operator=(const CDTIterator & oRhs)
+ {
+ 	if (this != &oRhs) { itMap = oRhs.itMap; }
+ 
+@@ -128,7 +128,7 @@
+ //
+ // Pre-increment operator ++
+ //
+-CDT::Iterator & CDT::Iterator::operator++()
++CDTIterator & CDTIterator::operator++()
+ {
+ 	++itMap;
+ 
+@@ -138,9 +138,9 @@
+ //
+ // Post-increment operator ++
+ //
+-CDT::Iterator CDT::Iterator::operator++(int)
++CDTIterator CDTIterator::operator++(int)
+ {
+-	Iterator oTMP = *this;
++	CDTIterator oTMP = *this;
+ 
+ 	++itMap;
+ 
+@@ -150,46 +150,46 @@
+ //
+ // Access operator
+ //
+-STLW::pair<const STLW::string, CDT> * CDT::Iterator::operator->() { return &(*itMap); }
++STLW::pair<const STLW::string, CDT> * CDTIterator::operator->() { return &(*itMap); }
+ 
+ //
+ // Comparison operator
+ //
+-bool CDT::Iterator::operator ==(const CDT::Iterator & oRhs) { return (itMap == oRhs.itMap); }
++bool CDTIterator::operator ==(const CDTIterator & oRhs) { return (itMap == oRhs.itMap); }
+ 
+ //
+ // Comparison operator
+ //
+-bool CDT::Iterator::operator !=(const CDT::Iterator & oRhs) { return (itMap != oRhs.itMap); }
++bool CDTIterator::operator !=(const CDTIterator & oRhs) { return (itMap != oRhs.itMap); }
+ 
+ //
+ // Get iterator pointed to start of hash
+ //
+-CDT::Iterator CDT::Begin()
++CDTIterator CDT::Begin()
+ {
+ 	if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+ 
+-return Iterator(u.p_data -> u.m_data -> begin());
++return CDTIterator(u.p_data -> u.m_data -> begin());
+ }
+ 
+ //
+ // Get iterator pointed to end of hash
+ //
+-CDT::Iterator CDT::End()
++CDTIterator CDT::End()
+ {
+ 	if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+ 
+-	return Iterator(u.p_data -> u.m_data -> end());
++	return CDTIterator(u.p_data -> u.m_data -> end());
+ }
+ 
+ //
+ // Find element in hash
+ //
+-CDT::Iterator CDT::Find(const STLW::string & sKey)
++CDTIterator CDT::Find(const STLW::string & sKey)
+ {
+ 	if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+ 
+-return Iterator(u.p_data -> u.m_data -> find(sKey));
++return CDTIterator(u.p_data -> u.m_data -> find(sKey));
+ }
+ 
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+@@ -200,17 +200,17 @@
+ //
+ // Copy constructor
+ //
+-CDT::ConstIterator::ConstIterator(const CDT::ConstIterator & oRhs): itMap(oRhs.itMap) { ;; }
++CDTConstIterator::CDTConstIterator(const CDTConstIterator & oRhs): itMap(oRhs.itMap) { ;; }
+ 
+ //
+ // Type cast constructor
+ //
+-CDT::ConstIterator::ConstIterator(const CDT::Iterator & oRhs): itMap(oRhs.itMap) { ;; }
++CDTConstIterator::CDTConstIterator(const CDTIterator & oRhs): itMap(oRhs.itMap) { ;; }
+ 
+ //
+ // Operator =
+ //
+-CDT::ConstIterator & CDT::ConstIterator::operator=(const ConstIterator & oRhs)
++CDTConstIterator & CDTConstIterator::operator=(const CDTConstIterator & oRhs)
+ {
+ 	if (this != &oRhs) { itMap = oRhs.itMap; }
+ 
+@@ -220,7 +220,7 @@
+ //
+ // Operator =
+ //
+-CDT::ConstIterator & CDT::ConstIterator::operator=(const CDT::Iterator & oRhs)
++CDTConstIterator & CDTConstIterator::operator=(const CDTIterator & oRhs)
+ {
+ 	itMap = oRhs.itMap;
+ 
+@@ -230,7 +230,7 @@
+ //
+ // Pre-increment operator ++
+ //
+-CDT::ConstIterator & CDT::ConstIterator::operator++()
++CDTConstIterator & CDTConstIterator::operator++()
+ {
+ 	++itMap;
+ 
+@@ -240,9 +240,9 @@
+ //
+ // Post-increment operator ++
+ //
+-CDT::ConstIterator CDT::ConstIterator::operator++(int)
++CDTConstIterator CDTConstIterator::operator++(int)
+ {
+-	ConstIterator oTMP = *this;
++	CDTConstIterator oTMP = *this;
+ 
+ 	++itMap;
+ 
+@@ -252,46 +252,46 @@
+ //
+ // Access operator
+ //
+-const STLW::pair<const STLW::string, CDT> * CDT::ConstIterator::operator->() const { return &(*itMap); }
++const STLW::pair<const STLW::string, CDT> * CDTConstIterator::operator->() const { return &(*itMap); }
+ 
+ //
+ // Comparison operator
+ //
+-bool CDT::ConstIterator::operator ==(const CDT::ConstIterator & oRhs) const { return (itMap == oRhs.itMap); }
++bool CDTConstIterator::operator ==(const CDTConstIterator & oRhs) const { return (itMap == oRhs.itMap); }
+ 
+ //
+ // Comparison operator
+ //
+-bool CDT::ConstIterator::operator !=(const CDT::ConstIterator & oRhs) const { return (itMap != oRhs.itMap); }
++bool CDTConstIterator::operator !=(const CDTConstIterator & oRhs) const { return (itMap != oRhs.itMap); }
+ 
+ //
+ // Get constant iterator pointed to start of hash
+ //
+-CDT::ConstIterator CDT::Begin() const
++CDTConstIterator CDT::Begin() const
+ {
+ 	if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+ 
+-return ConstIterator(u.p_data -> u.m_data -> begin());
++return CDTConstIterator(u.p_data -> u.m_data -> begin());
+ }
+ 
+ //
+ // Get constant iterator pointed to end of hash
+ //
+-CDT::ConstIterator CDT::End() const
++CDTConstIterator CDT::End() const
+ {
+ 	if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+ 
+-return ConstIterator(u.p_data -> u.m_data -> end());
++return CDTConstIterator(u.p_data -> u.m_data -> end());
+ }
+ 
+ //
+ // Find element in hash
+ //
+-CDT::ConstIterator CDT::Find(const STLW::string & sKey) const
++CDTConstIterator CDT::Find(const STLW::string & sKey) const
+ {
+ 	if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+ 
+-return ConstIterator(u.p_data -> u.m_data -> find(sKey));
++return CDTConstIterator(u.p_data -> u.m_data -> find(sKey));
+ }
+ 
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+@@ -4138,7 +4138,7 @@
+ 
+ 		case HASH_VAL:
+ 			{
+-				ConstIterator itHash = oData.Begin();
++				CDTConstIterator itHash = oData.Begin();
+ 				if (itHash == oData.End())
+ 				{
+ 					if (!bGlobalScope) { sResult += "{ }"; }

Modified: head/textproc/ctpp2/files/patch-src-CTPP2FileSourceLoader.cpp
==============================================================================
--- head/textproc/ctpp2/files/patch-src-CTPP2FileSourceLoader.cpp	Fri May  2 10:15:13 2014	(r352803)
+++ head/textproc/ctpp2/files/patch-src-CTPP2FileSourceLoader.cpp	Fri May  2 10:42:25 2014	(r352804)
@@ -1,5 +1,5 @@
---- src/CTPP2FileSourceLoader.cpp.orig	2013-11-16 14:26:59.000000000 +0100
-+++ src/CTPP2FileSourceLoader.cpp	2013-11-16 14:27:17.000000000 +0100
+--- src/CTPP2FileSourceLoader.cpp.orig	2012-08-02 11:22:44.000000000 +0400
++++ src/CTPP2FileSourceLoader.cpp	2014-05-02 18:06:25.511300597 +0400
 @@ -38,6 +38,7 @@
  #include <errno.h>
  #include <stdio.h>

Added: head/textproc/ctpp2/files/patch-src-CTPP2Util.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/textproc/ctpp2/files/patch-src-CTPP2Util.cpp	Fri May  2 10:42:25 2014	(r352804)
@@ -0,0 +1,11 @@
+--- src/CTPP2Util.cpp.orig	2012-08-02 11:22:44.000000000 +0400
++++ src/CTPP2Util.cpp	2014-05-02 18:06:25.511300597 +0400
+@@ -751,7 +751,7 @@
+ 		case CDT::HASH_VAL:
+ 			{
+ 				oResult.Write("{", 1);
+-				CDT::ConstIterator itCDTCArray = oCDT.Begin();
++				CDTConstIterator itCDTCArray = oCDT.Begin();
+ 				while (itCDTCArray != oCDT.End())
+ 				{
+ 					oResult.Write("\"", 1);

Added: head/textproc/ctpp2/files/patch-src-CTPP2VM.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/textproc/ctpp2/files/patch-src-CTPP2VM.cpp	Fri May  2 10:42:25 2014	(r352804)
@@ -0,0 +1,11 @@
+--- src/CTPP2VM.cpp.orig	2012-08-02 11:22:44.000000000 +0400
++++ src/CTPP2VM.cpp	2014-05-02 18:06:25.521278402 +0400
+@@ -1440,7 +1440,7 @@
+ 
+                                             if (oRegs[iSrcReg].GetType() == CDT::HASH_VAL)
+                                             {
+-                                                CDT::Iterator it = oRegs[iSrcReg].Begin();
++                                                CDTIterator it = oRegs[iSrcReg].Begin();
+                                                 for (INT_32 iI = 0; iI < iIdx; ++iI) { ++it; }
+ #ifdef _DEBUG
+ fprintf(stderr, "(`%s`): %s\n", it->first.c_str(), it->second.GetString().c_str());

Added: head/textproc/ctpp2/files/patch-tests-CDTTest.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/textproc/ctpp2/files/patch-tests-CDTTest.cpp	Fri May  2 10:42:25 2014	(r352804)
@@ -0,0 +1,20 @@
+--- tests/CDTTest.cpp.orig	2012-08-02 11:22:44.000000000 +0400
++++ tests/CDTTest.cpp	2014-05-02 18:06:25.531285819 +0400
+@@ -590,7 +590,7 @@
+ 
+ 	fprintf(stderr, "Get HASH values: %s\n", oCDT_array.GetHashValues().Dump().c_str());
+ 
+-	CDT::Iterator itCDTArray = oCDT_array.Begin();
++	CDTIterator itCDTArray = oCDT_array.Begin();
+ 	while (itCDTArray != oCDT_array.End())
+ 	{
+ 		fprintf(stderr, "oCDT_array[\"%s\"] => %s\n", itCDTArray -> first.c_str(), itCDTArray -> second.GetString().c_str());
+@@ -598,7 +598,7 @@
+ 		++itCDTArray;
+ 	}
+ 
+-	CDT::ConstIterator itCDTCArray = oCDT_array.Begin();
++	CDTConstIterator itCDTCArray = oCDT_array.Begin();
+ 	while (itCDTCArray != oCDT_array.End())
+ 	{
+ 		fprintf(stderr, "oCDT_array[\"%s\"] => %s\n", itCDTCArray -> first.c_str(), itCDTCArray -> second.GetString().c_str());



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405021042.s42AgQUk089278>