about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/log2xml/Makefile.am9
-rw-r--r--src/log2xml/log2html.xsl61
-rw-r--r--src/log2xml/log2xml.cc102
-rw-r--r--src/log2xml/logfile.css66
6 files changed, 240 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 093812e7acc0..f07dd6dd7b82 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,6 +118,7 @@ AC_CONFIG_FILES([Makefile
    src/libexpr/Makefile
    src/nix-instantiate/Makefile
    src/nix-env/Makefile
+   src/log2xml/Makefile
    scripts/Makefile
    corepkgs/Makefile
    corepkgs/fetchurl/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 0f1273426e32..29bd535f6ee0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,2 +1,2 @@
 SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
- libexpr nix-instantiate nix-env
+ libexpr nix-instantiate nix-env log2xml
diff --git a/src/log2xml/Makefile.am b/src/log2xml/Makefile.am
new file mode 100644
index 000000000000..b439f5e10d77
--- /dev/null
+++ b/src/log2xml/Makefile.am
@@ -0,0 +1,9 @@
+bin_PROGRAMS = log2xml
+
+log2xml_SOURCES = log2xml.cc
+
+%.xml: %.log log2xml
+	./log2xml < $< > $@
+
+%.html: %.xml log2html.xsl
+	xsltproc log2html.xsl $< > $@
\ No newline at end of file
diff --git a/src/log2xml/log2html.xsl b/src/log2xml/log2html.xsl
new file mode 100644
index 000000000000..96691a6aefd7
--- /dev/null
+++ b/src/log2xml/log2html.xsl
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  
+  <xsl:template match="logfile">
+    <html>
+      <head>
+        <link rel="stylesheet" href="logfile.css" type="text/css" />
+        <title>Log File</title>
+      </head>
+      <body>
+        <xsl:apply-templates/>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="nest">
+    <div class='nesting'>
+      <div class='head'>
+        <code>
+          <xsl:value-of select="head"/>
+        </code>
+      </div>
+      <blockquote class='body'>
+        <xsl:for-each select='line|nest'>
+          <xsl:if test="position() != last()">
+            <table class='x'>
+              <tr class='x'>
+                <td class='dummy'>
+                  <div class='dummy' />
+                </td>
+                <td>
+                  <xsl:apply-templates select='.'/>
+                </td>
+              </tr>
+            </table>
+          </xsl:if>
+          <xsl:if test="position() = last()">
+            <table class='y'>
+              <tr class='y'>
+                <td class='dummy'>
+                  <div class='dummy' />
+                </td>
+                <td>
+                  <xsl:apply-templates select='.'/>
+                </td>
+              </tr>
+            </table>
+          </xsl:if>
+        </xsl:for-each>
+      </blockquote>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="line">
+    <code class='line'>
+      <xsl:value-of select="."/>
+    </code>
+  </xsl:template>
+  
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/src/log2xml/log2xml.cc b/src/log2xml/log2xml.cc
new file mode 100644
index 000000000000..711fc82b89cf
--- /dev/null
+++ b/src/log2xml/log2xml.cc
@@ -0,0 +1,102 @@
+#include <iostream>
+#include <cstdio>
+#include <string>
+
+using namespace std;
+
+
+struct Decoder
+{
+    enum { stTop, stEscape, stCSI } state;
+    string line;
+    bool inHeader;
+    int level;
+
+    Decoder()
+    {
+        state = stTop;
+        line = "";
+        inHeader = false;
+        level = 0;
+    }
+
+    void pushChar(char c);
+
+    void finishLine();
+};
+
+
+void Decoder::pushChar(char c)
+{
+    switch (state) {
+        
+        case stTop:
+            if (c == '\e') {
+                state = stEscape;
+            } else if (c == '\n') {
+                finishLine();
+            } else if (c == '<')
+                line += "&lt;";
+            else if (c == '&')
+                line += "&amp;";
+            else
+                line += c;
+            break;
+
+        case stEscape:
+            if (c == '[')
+                state = stCSI;
+            else
+                state = stTop; /* !!! wrong */
+            break;
+
+        case stCSI:
+            if (c >= 0x40 && c != 0x7e) {
+                state = stTop;
+                switch (c) {
+                    case 'p':
+                        if (line.size()) finishLine();
+                        level++;
+                        inHeader = true;
+                        cout << "<nest>" << endl;
+                        break;
+                    case 'q':
+                        if (line.size()) finishLine();
+                        if (level > 0) {
+                            level--;
+                            cout << "</nest>" << endl;
+                        } else
+                            cerr << "not enough nesting levels" << endl;
+                        break;
+                }
+            }
+            break;
+            
+    }
+}
+
+
+void Decoder::finishLine()
+{
+    string tag = inHeader ? "head" : "line";
+    cout << "<" << tag << ">";
+    cout << line;
+    cout << "</" << tag << ">" << endl;
+    line = "";
+    inHeader = false;
+}
+
+
+int main(int argc, char * * argv)
+{
+    Decoder dec;
+    int c;
+
+    cout << "<logfile>" << endl;
+    
+    while ((c = getchar()) != EOF) {
+        dec.pushChar(c);
+    }
+
+    cout << "</logfile>" << endl;
+}
diff --git a/src/log2xml/logfile.css b/src/log2xml/logfile.css
new file mode 100644
index 000000000000..e240eb381520
--- /dev/null
+++ b/src/log2xml/logfile.css
@@ -0,0 +1,66 @@
+body
+{
+    font-family: sans-serif;
+    background: white;
+}
+
+
+blockquote.body
+{
+    padding: 6px 0px;
+    margin: 0px 1px;
+}
+
+
+table.x, tr.x
+{
+    border-collapse: separate;
+    border-spacing: 0pt;
+    margin: 0em 0em 0em 0em;
+    padding: 0em 0em 0em 0em;
+}
+
+
+tr.x > td.dummy
+{
+    vertical-align: top;
+    margin: 0em 0em 0em 0em;
+    padding: 0.5em 0em 0em 0em;
+    border-left: 3px solid #6185a0;
+}
+
+
+tr.x > td.dummy > div.dummy
+{
+    width: 1.5em;
+    height: 3px;
+    margin: 0em 0em 0em 0em;
+    border-top: 3px solid #6185a0;
+}
+
+
+table.y, tr.y
+{
+    border-collapse: separate;
+    border-spacing: 0pt;
+    margin: 0em 0em 0em 0em;
+    padding: 0em 0em 0em 0em;
+}
+
+
+tr.y > td.dummy
+{
+    vertical-align: top;
+    margin: 0em 0em 0em 0em;
+    padding: 0em 0em 0em 0em;
+}
+
+
+tr.y > td.dummy > div.dummy
+{
+    width: 1.5em;
+    height: 6px;
+    margin: 0em 0em 0em 0em;
+    border-left: 3px solid #6185a0;
+    border-bottom: 3px solid #6185a0;
+}