<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl

$verbose=0;
$verbose=1 if($#ARGV==0 &amp;&amp; $ARGV[0] eq "-v");

$html=0;
$html=1 if($#ARGV==0 &amp;&amp; $ARGV[0] eq "-html");

die "Usage: $0 [-v | -html] &lt; &lt;error-log-file&gt;\n" if($#ARGV&gt;0 || ($#ARGV==0 &amp;&amp; !$verbose &amp;&amp; !$html));


# Read in each line from the error log and store them

%errors=();
%errorids=();
%errortypes=();

while(&lt;STDIN&gt;)
  {
   s%\r*\n%%;

   undef $errorid;

   if(m%nodes ([0-9]+) and ([0-9]+) in way ([0-9]+)%i) # Special case pair of nodes and a way
     {
      $errorid="($1 $2 $3)";
      $errortype="N2W";
      s%nodes [0-9]+ and [0-9]+ in way [0-9]+%nodes &lt;node-id1&gt; and &lt;node-id2&gt; in way &lt;way-id&gt;%;
     }

   elsif(m%node ([0-9]+) in way ([0-9]+)%i) # Special case node and a way
     {
      $errorid="($1 $2)";
      $errortype="NW";
      s%Node [0-9]+ in way [0-9]+%Node &lt;node-id&gt; in way &lt;way-id&gt;%;
     }

   elsif(m%nodes ([0-9]+) and ([0-9]+)%i) # Special case pair of nodes
     {
      $errorid="($1 $2)";
      $errortype="N2";
      s%nodes [0-9]+ and [0-9]+%nodes &lt;node-id1&gt; and &lt;node-id2&gt;%;
     }

   elsif(m%Segment (contains|connects) node ([0-9]+)%) # Special case node
     {
      $errorid=$2;
      $errortype="N";
      s%node [0-9]+%node &lt;node-id&gt;%;
     }

   elsif(m%Relation ([0-9]+).* contains Node ([0-9]+)%) # Special case relation/node
     {
      $errorid="($1 $2)";
      $errortype="RN";
      s%Relation [0-9]+%Relation &lt;relation-id&gt;%;
      s%Node [0-9]+%node &lt;node-id&gt;%;
     }

   elsif(m%Relation ([0-9]+).* contains Way ([0-9]+)%) # Generic case relation/way
     {
      $errorid="($1 $2)";
      $errortype="RW";
      s%Relation [0-9]+%Relation &lt;relation-id&gt;%;
      s%Way [0-9]+%way &lt;way-id&gt;%;
     }

   elsif(!m%Way ([0-9]+)% &amp;&amp; !m%Relation ([0-9]+)% &amp;&amp; m%Node ([0-9]+)%) # Generic node
     {
      $errorid=$1;
      $errortype="N";
      s%Node [0-9]+%Node &lt;node-id&gt;%;
     }

   elsif(!m%Node ([0-9]+)% &amp;&amp; !m%Relation ([0-9]+)% &amp;&amp; m%Way ([0-9]+)%) # Generic way
     {
      $errorid=$1;
      $errortype="W";
      s%Way [0-9]+%Way &lt;way-id&gt;%;
     }

   elsif(!m%Node ([0-9]+)% &amp;&amp; !m%Way ([0-9]+)% &amp;&amp; m%Relation ([0-9]+)%) # Generic relation
     {
      $errorid=$1;
      $errortype="R";
      s%Relation [0-9]+%Relation &lt;relation-id&gt;%;
     }

   else
     {
      $errorid="ERROR";
      $errortype="E";
      warn "Unrecognised error message '$_'\n";
     }

   $errors{$_}++;

   if($verbose || $html)
     {
      if(defined $errorids{$_})
        {
         push(@{$errorids{$_}},$errorid);
        }
      else
        {
         $errorids{$_}=[$errorid];
        }
     }

   if($html)
     {
      $errortypes{$_}=$errortype;
     }
  }


# Print out the results as text

if( ! $html )
  {

   foreach $error (sort { if ( $errors{$b} == $errors{$a} ) { return $errors{$a} cmp $errors{$b} }
                          else                              { return $errors{$b} &lt;=&gt; $errors{$a} } } (keys %errors))
     {
      printf "%9d : $error\n",$errors{$error};

      if($verbose)
        {
         @ids=sort({ return $a &lt;=&gt; $b } @{$errorids{$error}});

         print "            ".join(",",@ids)."\n";
        }
     }

  }

# Print out the results as HTML

else
  {

   print "&lt;!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"&gt;\n".
         "&lt;HTML&gt;\n".
         "\n".
         "&lt;HEAD&gt;\n".
         "&lt;TITLE&gt;Routino Error Log File Summary&lt;/TITLE&gt;\n".
         "&lt;META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"&gt;\n".
         "&lt;STYLE type=\"text/css\"&gt;\n".
         "&lt;!--\n".
         "   body {font-family: sans-serif; font-size: 12px;}\n".
         "   h1   {font-family: sans-serif; font-size: 14px; font-style: bold;}\n".
         "   h2   {font-family: sans-serif; font-size: 13px; font-style: bold;}\n".
         "   h3   {font-family: sans-serif; font-size: 12px; font-style: bold;}\n".
         "--&gt;\n".
         "&lt;/STYLE&gt;\n".
         "&lt;/HEAD&gt;\n".
         "\n".
         "&lt;BODY&gt;\n".
         "\n".
         "&lt;h1&gt;Routino Error Log File Summary&lt;/h1&gt;\n".
         "\n".
         "This HTML file contains a summary of the Routino OSM parser error log file with\n".
         "links to the OSM website that allow browsing each of the nodes, ways or relations\n".
         "that are responsible for the error messages.\n".
         "\n";

   %errortypeorder=(
                    "N"   , 1,
                    "NW"  , 2,
                    "N2W" , 3,
                    "N2"  , 4,
                    "W"   , 5,
                    "R"   , 6,
                    "RN"  , 7,
                    "RW"  , 8,
                    "E"   , 9
                   );

   %errortypelabel=(
                    "N"   , "Nodes",
                    "NW"  , "Node in a Way",
                    "N2W" , "Node Pairs in a Way",
                    "N2"  , "Node Pairs",
                    "W"   , "Ways",
                    "R"   , "Relations",
                    "RN"  , "Relations/Nodes",
                    "RW"  , "Relations/Ways",
                    "E"   , "ERROR"
                   );

   $lasterrortype="";

   foreach $error (sort { if    ( $errortypes{$b} ne $errortypes{$a} ) { return $errortypeorder{$errortypes{$a}} &lt;=&gt; $errortypeorder{$errortypes{$b}} }
                          elsif ( $errors{$b}     == $errors{$a} )     { return $errors{$a} cmp $errors{$b} }
                          else                                         { return $errors{$b} &lt;=&gt; $errors{$a} } } (keys %errors))
     {
      $errorhtml=$error;

      $errorhtml =~ s/&amp;/&amp;amp;/g;
      $errorhtml =~ s/&lt;/&amp;lt;/g;
      $errorhtml =~ s/&gt;/&amp;gt;/g;

      if($errortypes{$error} ne $lasterrortype)
        {
         print "&lt;h2&gt;$errortypelabel{$errortypes{$error}}&lt;/h2&gt;\n";
         $lasterrortype=$errortypes{$error};
        }

      print "&lt;h3&gt;$errorhtml&lt;/h3&gt;\n";

      if($errors{$error}&gt;100)
        {
         print "$errors{$error} occurences (not listed).\n";
        }
      else
        {
         @ids=sort({ return $a &lt;=&gt; $b } @{$errorids{$error}});

         $first=1;

         foreach $id (@ids)
           {
            if($first)
              {
               print "$errortypelabel{$errortypes{$error}}:\n";
              }
            else
              {
               print ",";
              }

            $first=0;

            print "&lt;a href=\"http://www.openstreetmap.org/browse/node/$id\"&gt;$id&lt;/a&gt;" if($errortypes{$error} eq "N");
            print "&lt;a href=\"http://www.openstreetmap.org/browse/way/$id\"&gt;$id&lt;/a&gt;" if($errortypes{$error} eq "W");
            print "&lt;a href=\"http://www.openstreetmap.org/browse/relation/$id\"&gt;$id&lt;/a&gt;" if($errortypes{$error} eq "R");

            if($errortypes{$error} eq "NW" || $errortypes{$error} eq "N2" || $errortypes{$error} eq "RN" || $errortypes{$error} eq "RW")
              {
               $id =~ m%\(([0-9]+) ([0-9]+)\)%;
               print "(&lt;a href=\"http://www.openstreetmap.org/browse/node/$1\"&gt;$1&lt;/a&gt; &lt;a href=\"http://www.openstreetmap.org/browse/way/$2\"&gt;$2&lt;/a&gt;)" if($errortypes{$error} eq "NW");
               print "(&lt;a href=\"http://www.openstreetmap.org/browse/node/$1\"&gt;$1&lt;/a&gt; &lt;a href=\"http://www.openstreetmap.org/browse/node/$2\"&gt;$2&lt;/a&gt;)" if($errortypes{$error} eq "N2");
               print "(&lt;a href=\"http://www.openstreetmap.org/browse/relation/$1\"&gt;$1&lt;/a&gt; &lt;a href=\"http://www.openstreetmap.org/browse/node/$2\"&gt;$2&lt;/a&gt;)" if($errortypes{$error} eq "RN");
               print "(&lt;a href=\"http://www.openstreetmap.org/browse/relation/$1\"&gt;$1&lt;/a&gt; &lt;a href=\"http://www.openstreetmap.org/browse/way/$2\"&gt;$2&lt;/a&gt;)" if($errortypes{$error} eq "RW");
              }

            if($errortypes{$error} eq "N2W")
              {
               $id =~ m%\(([0-9]+) ([0-9]+) ([0-9]+)\)%;
               print "(&lt;a href=\"http://www.openstreetmap.org/browse/node/$1\"&gt;$1&lt;/a&gt; &lt;a href=\"http://www.openstreetmap.org/browse/node/$2\"&gt;$2&lt;/a&gt; &lt;a href=\"http://www.openstreetmap.org/browse/way/$3\"&gt;$3&lt;/a&gt;)" if($errortypes{$error} eq "N2W");
              }

            print "\n";
           }
        }
     }

   print "\n".
         "&lt;/BODY&gt;\n".
         "\n".
         "&lt;/HTML&gt;\n";

}
</pre></body></html>