Socket/Protocols/INet: Updated INet4SocketAddress to use INet4Address
g0dil [Fri, 27 Jul 2007 13:36:28 +0000 (13:36 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@360 270642c3-0616-0410-b53a-bc976706d245

Examples/TCPClientServer/client.cc
Examples/TCPClientServer/server.cc
Socket/Protocols/INet/INet4Address.test.cc
Socket/Protocols/INet/INetAddressing.cc
Socket/Protocols/INet/INetAddressing.cci
Socket/Protocols/INet/INetAddressing.ct
Socket/Protocols/INet/INetAddressing.hh
Socket/Protocols/INet/INetAddressing.test.cc
Socket/Protocols/INet/TCPSocketHandle.test.cc
Socket/Protocols/INet/UDPSocketHandle.test.cc
doclib/dot-munge.pl

index 12fb87a..0323d94 100644 (file)
@@ -31,7 +31,7 @@ int main(int argc, char const * argv[])
     try {
         for (int i=0; i<=1000; i++) {
             senf::TCPv4ClientSocketHandle sock;
-            sock.connect(senf::INet4SocketAddress("127.0.0.1", 4243));
+            sock.connect(senf::INet4SocketAddress("127.0.0.1:4243"));
             sock.protocol().linger(true);
             
             std::stringstream s;
index dc53e5e..54a2040 100644 (file)
@@ -38,7 +38,7 @@ class Server
     senf::TCPv4ServerSocketHandle serverSock;
 
 public:
-    Server(std::string const & host, unsigned int port)
+    Server(senf::INet4Address const & host, unsigned int port)
         : serverSock(senf::INet4SocketAddress(host, port)) {}
     
     void run() 
@@ -75,7 +75,7 @@ private:
 int main(int argc, char const * argv[])
 {
     try {
-        Server myServer ("127.0.0.1", 4243);
+        Server myServer (senf::INet4Address::Loopback, 4243);
         myServer.run();
     }
     catch (std::exception const & ex) {
index 186202f..36e84f4 100644 (file)
@@ -39,6 +39,7 @@ BOOST_AUTO_UNIT_TEST(inet4Address)
 {
     senf::INet4Address addr (senf::INet4Address::from_string("127.0.0.1"));
     BOOST_CHECK_EQUAL( addr, senf::INet4Address::Loopback );
+    BOOST_CHECK( addr != senf::INet4Address::Broadcast );
 
     addr = senf::INet4Address::from_string("localhost");
     BOOST_CHECK_EQUAL( addr, senf::INet4Address::Loopback );
index 5f58af8..d768c7d 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // senf::INet4Address
 
-prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & host, unsigned port)
+prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & addr)
 {
     clear();
-    /** \todo  gethostbyname support */
-    if (::inet_aton(host.c_str(), &addr_.sin_addr) == 0)
-        throw InvalidINetAddressException();
-    addr_.sin_port = htons(port);
+    unsigned i = addr.find(':');
+    if (i == std::string::npos)
+        throw SyntaxException();
+    address(INet4Address::from_string(std::string(addr,0,i)));
+    try {
+        port(boost::lexical_cast< ::u_int16_t >(std::string(addr,i+1)));
+    }
+    catch (boost::bad_lexical_cast const &) {
+        throw SyntaxException();
+    }
 }
 
-prefix_ std::string senf::INet4SocketAddress::str()
-    const
+prefix_ senf::INet4SocketAddress::INet4SocketAddress(INet4Address const & addr, unsigned p)
 {
-    std::stringstream s;
-    s << host() << ':' << port();
-    return s.str();
+    clear();
+    address(addr);
+    port(p);
 }
 
 prefix_ void senf::INet4SocketAddress::clear()
@@ -66,38 +71,19 @@ prefix_ void senf::INet4SocketAddress::clear()
     addr_.sin_family = AF_INET;
 }
 
-prefix_ void senf::INet4SocketAddress::assignString(std::string const & address)
-{
-    clear();
-    unsigned i = address.find(':');
-    if (i == std::string::npos)
-        throw InvalidINetAddressException();
-    // The temporary string in the next expr is guaranteed to live
-    // until end-of-statement
-    if (::inet_aton(std::string(address,0,i).c_str(), &addr_.sin_addr) == 0)
-        throw InvalidINetAddressException();
-    try {
-        // Replace lexical_cast with strtoul ?
-        addr_.sin_port = htons(boost::lexical_cast< ::u_int16_t >(std::string(address,i+1)));
-    }
-    catch (boost::bad_lexical_cast const &) {
-        throw InvalidINetAddressException();
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // senf::INet6Address
 
 prefix_ senf::INet6Address::INet6Address(std::string const & addr)
 {
     if (inet_pton(AF_INET6,addr.c_str(),&addr_) <= 0)
-        throw InvalidINetAddressException();
+        throw SyntaxException();
 }
 
 prefix_ senf::INet6Address::INet6Address(char const * addr)
 {
     if (inet_pton(AF_INET6,addr,&addr_) <= 0)
-        throw InvalidINetAddressException();
+        throw SyntaxException();
 }
 
 prefix_ void senf::INet6Address::clear()
@@ -185,28 +171,28 @@ prefix_ void senf::INet6SocketAddress::assignAddr(std::string const & addr)
         || inet_pton(AF_INET6, std::string(boost::begin(*token),boost::end(*token)).c_str(),
                      &sockaddr_.sin6_addr) <= 0
         || ++token == tokens.end())
-        throw InvalidINetAddressException();
+        throw SyntaxException();
     if (*token == "@") {
         if (++token == tokens.end())
-            throw InvalidINetAddressException();
+            throw SyntaxException();
         assignIface(std::string(boost::begin(*token),boost::end(*token)));
         if (++token == tokens.end()
             || *token != "]")
-            throw InvalidINetAddressException();
+            throw SyntaxException();
     } else if (*token != "]")
-        throw InvalidINetAddressException();
+        throw SyntaxException();
     if (++token == tokens.end()
         || *boost::begin(*token) != ':')
-        throw InvalidINetAddressException();
+        throw SyntaxException();
     try {
         sockaddr_.sin6_port = htons(
             boost::lexical_cast<unsigned>(std::string(boost::next(boost::begin(*token)),
                                                       boost::end(*token))));
     } catch(boost::bad_lexical_cast const &) {
-        throw InvalidINetAddressException();
+        throw SyntaxException();
     }
     if (++token != tokens.end())
-        throw InvalidINetAddressException();
+        throw SyntaxException();
 }
 
 prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface)
@@ -216,7 +202,7 @@ prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface)
     else {
         sockaddr_.sin6_scope_id = if_nametoindex(iface.c_str());
         if (sockaddr_.sin6_scope_id == 0)
-            throw InvalidINetAddressException();
+            throw SyntaxException();
     }
 }
 
index 4b28057..f0e039d 100644 (file)
@@ -38,16 +38,6 @@ prefix_ senf::INet4SocketAddress::INet4SocketAddress()
     clear();
 }
 
-prefix_ senf::INet4SocketAddress::INet4SocketAddress(char const * address)
-{
-    assignString(address);
-}
-
-prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & address)
-{
-    assignString(address);
-}
-
 prefix_ bool senf::INet4SocketAddress::operator==(INet4SocketAddress const & other)
     const
 {
@@ -55,11 +45,10 @@ prefix_ bool senf::INet4SocketAddress::operator==(INet4SocketAddress const & oth
         addr_.sin_addr.s_addr == other.addr_.sin_addr.s_addr;
 }
 
-prefix_ std::string senf::INet4SocketAddress::host()
+prefix_ senf::INet4Address senf::INet4SocketAddress::address()
     const
 {
-    char buffer[128];
-    return std::string(::inet_ntop(AF_INET,&addr_.sin_addr,buffer,128));
+    return INet4Address::from_inaddr(addr_.sin_addr.s_addr);
 }
 
 prefix_ unsigned senf::INet4SocketAddress::port()
@@ -68,6 +57,22 @@ prefix_ unsigned senf::INet4SocketAddress::port()
     return ntohs(addr_.sin_port);
 }
 
+prefix_ bool senf::INet4SocketAddress::boolean_test()
+    const
+{
+    return port() || address();
+}
+
+prefix_ void senf::INet4SocketAddress::address(INet4Address const & addr)
+{
+    addr_.sin_addr.s_addr = addr.inaddr();
+}
+
+prefix_ void senf::INet4SocketAddress::port(unsigned p)
+{
+    addr_.sin_port = htons(p);
+}
+
 prefix_ struct sockaddr * senf::INet4SocketAddress::sockaddr_p()
 {
     return reinterpret_cast<struct sockaddr *>(&addr_);
@@ -87,7 +92,7 @@ prefix_ unsigned senf::INet4SocketAddress::sockaddr_len()
 
 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr)
 {
-    os << addr.str();
+    os << addr.address() << ":" << addr.port();
     return os;
 }
 
index db187b3..d2782a0 100644 (file)
@@ -39,7 +39,7 @@ prefix_ senf::INet6Address::INet6Address(Range const & range)
     for (; p!=p_end && i!=i_end; ++p, ++i)
         *p = *i;
     if (p!=p_end || i!=i_end)
-        throw InvalidINetAddressException();
+        throw SyntaxException();
 }
 
 ///////////////////////////////ct.e////////////////////////////////////////
index e235cd4..79ccb52 100644 (file)
 #include <string>
 #include <exception>
 #include <netinet/in.h>
+#include <boost/operators.hpp>
 #include "Socket/SocketPolicy.hh"
 #include "Socket/ClientSocketHandle.hh"
 #include "Socket/CommunicationPolicy.hh"
 #include "Socket/Protocols/GenericAddressingPolicy.hh"
+#include "INet4Address.hh"
 
 //#include "INetAddressing.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -48,42 +50,45 @@ namespace senf {
 
         INet4Address wraps the standard sockaddr_in datatype. It provides simple accessor methods
         to access the host and port. It does \e not integrate \c gethostbyname or DNS lookup.
-
-        \todo Implement real INet4Address datatype and rename this one to INet4SockAddress ...
-        \todo Implement more complete interface
-        \todo  gethostbyname support ?
+        
+        \implementation This implementation is based on sockaddr_in, which is needed since it needs
+            to provide a non-const struct sockaddr * for legacy compatibility.
      */
     class INet4SocketAddress
+        : public boost::equality_comparable<INet4SocketAddress>, 
+          public senf::ComparableSafeBool<INet4SocketAddress>
     {
     public:
         INet4SocketAddress();
-        INet4SocketAddress(char const * address); ///< Set address and port
-                                        /**< See INet4SocketAddress(std::string)
-                                             \throws InvalidINetAddressException */
-        INet4SocketAddress(std::string const & address); ///< Set address and port
+        explicit INet4SocketAddress(std::string const & address); ///< Set address and port
                                         /**< This constructor expects a string of the form
-                                             'xxx.xxx.xxx.xxx:pppp'. The constructor will use this
-                                             value to initialize the host and port members. This
-                                             constructor does \e only support numeric ip addresses
-                                             not hostnames
-                                             \param[in] address Address and port
-                                             \throws InvalidINetAddressException */
-        INet4SocketAddress(std::string const & host, unsigned port); 
+                                             'host:port'. The constructor will use this value to
+                                             initialize the host and port members. Since it uses the
+                                             INet4Address::from_string constructor, this call may
+                                             block while waiting for the resolver.
+                                             \throws SyntaxException if the 'host:port' syntax is
+                                                 not obeyed.
+                                             \throws INet4Address::SyntaxException if the host part
+                                                 cannot be converted to an IP address. */
+
+        INet4SocketAddress(INet4Address const & addr, unsigned port); 
                                         ///< Set address and port explicitly
-                                        /**< \param[in] host ip address in dotted-quad notation
-                                             \param[in] port port number
-                                             \throws InvalidINetAddressException */
-
+                                        /**< \param[in] addr IP address
+                                             \param[in] port port number */
 
         bool operator==(INet4SocketAddress const & other) const;
                                         ///< Check INet4SocketAddress for equality
 
-        std::string str() const;        ///< Return "address:port" string
-        std::string host() const;       ///< Return address in doted quad notation
-        unsigned port() const;          ///< Return portnumber
+        INet4Address address() const;   ///< Return address
+        unsigned port() const;          ///< Return port number
+
+        bool boolean_test() const;      ///< \c true, if address is empty (i.e. 0.0.0.0:0)
 
         void clear();                   ///< Clear address/port to 0.0.0.0:0
 
+        void address(INet4Address const & addr); ///< Set address
+        void port(unsigned p);          ///< Set port number
+
         /// \name Generic Address Interface
         /// @{
 
@@ -93,15 +98,17 @@ namespace senf {
 
         /// @}
 
-    private:
-        void assignString(std::string const & addr);
+        struct SyntaxException : public std::exception
+        { virtual char const * what() const throw() 
+                { return "Invalid IpV4 socket address syntax"; } };
 
+    private:
         struct ::sockaddr_in addr_;
     };
 
     /** \brief Write address and port to os
 
-        \related INet4Address
+        \related INet4SocketAddress
      */
     std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr);
 
@@ -160,6 +167,9 @@ namespace senf {
                                         ///< Get const pointer to internal address repr
         unsigned addr_len() const;      ///< Size of an IPv6 address (16 bytes)
 
+        struct SyntaxException : public std::exception
+        { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
+
     protected:
 
     private:
@@ -256,6 +266,10 @@ namespace senf {
 
         ///@}
 
+        struct SyntaxException : public std::exception
+        { virtual char const * what() const throw() 
+                { return "Invalid IpV6 socket address syntax"; } };
+
     protected:
 
     private:
@@ -269,14 +283,6 @@ namespace senf {
      */
     std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr);
 
-    /** \brief Signal invalid INet address syntax
-
-        \related INet4Address
-        \relatesalso INet6Address
-     */
-    struct InvalidINetAddressException : public std::exception
-    { char const * what() const throw() { return "invalid inet address"; } };
-
     /// @}
 
     /// \addtogroup policy_impl_group
index 317c077..c8c8024 100644 (file)
 BOOST_AUTO_UNIT_TEST(inet4Address)
 {
     using senf::INet4SocketAddress;
-    using senf::InvalidINetAddressException;
+    using senf::INet4Address;
 
     {
         INet4SocketAddress addr;
+        
+        BOOST_CHECK( ! addr );
 
-        addr = "127.0.0.1:12345";
+        addr = INet4SocketAddress("127.0.0.1:12345");
+        BOOST_CHECK ( addr != INet4SocketAddress() );
     }
 
     {
         INet4SocketAddress addr1("127.0.0.1:12345");
-        INet4SocketAddress addr2(std::string("127.0.0.1:12345"));
-        INet4SocketAddress addr3("127.0.0.1",12345);
+        INet4SocketAddress addr3(INet4Address::Loopback,12345);
     }
 
-    BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345"), INet4SocketAddress("127.0.0.1",12345) );
+    BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345"), 
+                       INet4SocketAddress(INet4Address::Loopback,12345) );
 
-    BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1"), InvalidINetAddressException );
-    BOOST_CHECK_THROW( INet4SocketAddress("foo@bar:12345"), InvalidINetAddressException );
-    BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1:1234a"), InvalidINetAddressException );
-    BOOST_CHECK_THROW( INet4SocketAddress("foo@bar",12345), InvalidINetAddressException );
+    BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1"), INet4SocketAddress::SyntaxException );
+    BOOST_CHECK_THROW( INet4SocketAddress("foo@bar:12345"), INet4Address::SyntaxException );
+    BOOST_CHECK_THROW( INet4SocketAddress("127.0.0.1:1234a"), INet4SocketAddress::SyntaxException );
 
-    BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").host(), "127.0.0.1" );
+    BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").address(), INet4Address::Loopback );
     BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").port(), 12345u );
-    BOOST_CHECK_EQUAL( INet4SocketAddress("127.0.0.1:12345").str(), "127.0.0.1:12345" );
+    BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(INet4SocketAddress("127.0.0.1:12345")),
+                       "127.0.0.1:12345" );
 
     {
         INet4SocketAddress addr("127.0.0.1:12345");
@@ -79,7 +82,6 @@ BOOST_AUTO_UNIT_TEST(inet6Address)
 {
     using senf::INet6Address;
     using senf::INet6SocketAddress;
-    using senf::InvalidINetAddressException;
 
     {
         INet6Address addr1 ("0102:0304:0506:0708:090A:0B0C:0D0E:0F00");
@@ -109,15 +111,15 @@ BOOST_AUTO_UNIT_TEST(inet6Address)
         addr1.clear();
         addr2 = "::";
         BOOST_CHECK_EQUAL( addr1, addr2 );
-        BOOST_CHECK_THROW( addr1 = "", InvalidINetAddressException );
+        BOOST_CHECK_THROW( addr1 = "", INet6Address::SyntaxException );
         BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr1), "::" );
         unsigned char data[] = { 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x21, 0 };
         INet6Address addr3 (std::make_pair(&data[0],&data[0]+sizeof(data)-1));
         BOOST_CHECK_EQUAL( addr3, "1200::21" );
         BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data))),
-                           InvalidINetAddressException );
+                           INet6Address::SyntaxException );
         BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data)-2)),
-                           InvalidINetAddressException );
+                           INet6Address::SyntaxException );
     }
 
     {
@@ -148,9 +150,9 @@ BOOST_AUTO_UNIT_TEST(inet6Address)
         BOOST_CHECK_EQUAL( addr.port(), 100u );
         addr.host("::2");
         BOOST_CHECK_EQUAL( addr.host(), "::2" );
-        BOOST_CHECK_THROW( addr = "", InvalidINetAddressException );
-        BOOST_CHECK_THROW( addr = "[::1]", InvalidINetAddressException );
-        BOOST_CHECK_THROW( addr = "[::1]1234", InvalidINetAddressException );
+        BOOST_CHECK_THROW( addr = "", INet6SocketAddress::SyntaxException );
+        BOOST_CHECK_THROW( addr = "[::1]", INet6SocketAddress::SyntaxException );
+        BOOST_CHECK_THROW( addr = "[::1]1234", INet6SocketAddress::SyntaxException );
         addr = "[12::21@lo]:12345";
         BOOST_CHECK_EQUAL( addr.address(), "[12::21@lo]:12345" );
         BOOST_CHECK_EQUAL( addr.host(), "12::21" );
index 279f4a1..25a476d 100644 (file)
@@ -156,18 +156,20 @@ BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle)
     {
         senf::TCPv4ClientSocketHandle sock;
 
-        BOOST_CHECK_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")), senf::SystemException );
-        BOOST_CHECK_THROW( sock.protocol().connect("127.0.0.1:12345"), senf::SystemException );
+        BOOST_CHECK_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")), 
+                           senf::SystemException );
+        BOOST_CHECK_THROW( sock.protocol().connect(senf::INet4SocketAddress("127.0.0.1:12345")),
+                           senf::SystemException );
     }
 
     try {
         alarm(10);
         start(server_v4);
         senf::TCPv4ClientSocketHandle sock;
-        BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") );
-        BOOST_CHECK_NO_THROW( sock.connect("127.0.0.1:12345") );
-        BOOST_CHECK( sock.peer() == "127.0.0.1:12345" );
-        BOOST_CHECK( sock.local() == "127.0.0.1:23456" );
+        BOOST_CHECK_NO_THROW( sock.bind(senf::INet4SocketAddress("127.0.0.1:23456")) );
+        BOOST_CHECK_NO_THROW( sock.connect(senf::INet4SocketAddress("127.0.0.1:12345")) );
+        BOOST_CHECK( sock.peer() == senf::INet4SocketAddress("127.0.0.1:12345") );
+        BOOST_CHECK( sock.local() == senf::INet4SocketAddress("127.0.0.1:23456") );
         BOOST_CHECK( sock.blocking() );
         BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
         BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
@@ -340,7 +342,7 @@ BOOST_AUTO_UNIT_TEST(tcpv4ServerSocketHandle)
     try {
         alarm(10);
         BOOST_CHECKPOINT("Opening server socket");
-        senf::TCPv4ServerSocketHandle server ("127.0.0.1:12346");
+        senf::TCPv4ServerSocketHandle server (senf::INet4SocketAddress("127.0.0.1:12346"));
         BOOST_CHECKPOINT("Starting client");
         start(client_v4);
 
index f9e937f..f251e45 100644 (file)
@@ -142,16 +142,17 @@ BOOST_AUTO_UNIT_TEST(udpv4ClientSocketHandle)
         alarm(10);
         start(server_v4);
         senf::UDPv4ClientSocketHandle sock;
-        BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") );
-        BOOST_CHECK( sock.local() == "127.0.0.1:23456" );
+        BOOST_CHECK_NO_THROW( sock.bind(senf::INet4SocketAddress("127.0.0.1:23456")) );
+        BOOST_CHECK( sock.local() == senf::INet4SocketAddress("127.0.0.1:23456") );
         BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
         BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
         BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
         BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
-        BOOST_CHECK_NO_THROW( sock.writeto("127.0.0.1:12345", std::string("TEST-WRITE")) );
+        BOOST_CHECK_NO_THROW( sock.writeto(senf::INet4SocketAddress("127.0.0.1:12345"),
+                                           std::string("TEST-WRITE")) );
         BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" );
         BOOST_CHECK_NO_THROW( sock.protocol().timestamp() );
-        sock.writeto("127.0.0.1:12345","QUIT");
+        sock.writeto(senf::INet4SocketAddress("127.0.0.1:12345"),"QUIT");
         sleep(1);
         stop();
         sleep(1);
index d11a556..550a3a2 100755 (executable)
@@ -4,9 +4,9 @@
 s/fontsize=10/fontsize=8/g; 
 
 # Wrap long labels (templates)
-if (/label=\"([^"]*)\"/) {                                 #"])){ # To make emacs happy ...
+if (/label=\"([^"]*)\"/) {                                  #"])){ # To make emacs happy ...
     $pre=$`; 
-    $post=$';                                              #'     # To make emacs happy ...
+    $post=$';                                               #';    # To make emacs happy ...
     $label=$1;
 
     # Break at each komma
@@ -14,15 +14,15 @@ if (/label=\"([^"]*)\"/) {                              #"])){ # To make emacs happy ...
 
     # If more than one '<' is in the label, break after each '<'
     if (($label=~tr/</</)>1) { 
-       $label=~s/</<\\r\\ \\ \\ \\ \\ \\ \\ \\ /g;
+        $label=~s/</<\\r\\ \\ \\ \\ \\ \\ \\ \\ /g;
     }
 
     # If at least one break is in there ...
     if ($label=~/\\r/) {
-       # Make last line flush right
-       $label.="\\r";
-       # and first line flush left
-       $label=~s/\\r/\\l/;
+        # Make last line flush right
+        $label.="\\r";
+        # and first line flush left
+        $label=~s/\\r/\\ \\ \\ \\ \\ \\ \\ \\ \\l/;
     }
     print "${pre}label=\"${label}\"${post}";
 } else {