2004-03-15 21:51:14 +00:00
|
|
|
#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();
|
2004-03-16 12:47:09 +00:00
|
|
|
} else line += c;
|
2004-03-15 21:51:14 +00:00
|
|
|
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()
|
|
|
|
{
|
2004-03-16 12:47:09 +00:00
|
|
|
string storeDir = "/nix/store/";
|
|
|
|
int sz = storeDir.size();
|
2004-03-15 21:51:14 +00:00
|
|
|
string tag = inHeader ? "head" : "line";
|
|
|
|
cout << "<" << tag << ">";
|
2004-03-16 12:47:09 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < line.size(); i++) {
|
|
|
|
|
|
|
|
if (line[i] == '<') cout << "<";
|
|
|
|
else if (line[i] == '&') cout << "&";
|
|
|
|
else if (i + sz + 33 < line.size() &&
|
|
|
|
string(line, i, sz) == storeDir &&
|
|
|
|
line[i + sz + 32] == '-')
|
|
|
|
{
|
|
|
|
int j = i + sz + 32;
|
|
|
|
/* skip name */
|
|
|
|
while (!strchr("/\n\r\t ()[]:;?<>", line[j])) j++;
|
|
|
|
int k = j;
|
|
|
|
while (!strchr("\n\r\t ()[]:;?<>", line[k])) k++;
|
|
|
|
// !!! escaping
|
|
|
|
cout << "<storeref>"
|
|
|
|
<< "<storedir>"
|
|
|
|
<< string(line, i, sz)
|
|
|
|
<< "</storedir>"
|
|
|
|
<< "<hash>"
|
|
|
|
<< string(line, i + sz, 32)
|
|
|
|
<< "</hash>"
|
|
|
|
<< "<name>"
|
|
|
|
<< string(line, i + sz + 32, j - (i + sz + 32))
|
|
|
|
<< "</name>"
|
|
|
|
<< "<path>"
|
|
|
|
<< string(line, j, k - j)
|
|
|
|
<< "</path>"
|
|
|
|
<< "</storeref>";
|
|
|
|
i = k - 1;
|
|
|
|
} else cout << line[i];
|
|
|
|
}
|
|
|
|
|
2004-03-15 21:51:14 +00:00
|
|
|
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;
|
|
|
|
}
|