about summary refs log tree commit diff
path: root/src/log2xml/log2xml.cc
blob: 711fc82b89cf983524648271ff181bccaf0a001c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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;
}