-
Notifications
You must be signed in to change notification settings - Fork 1
/
scriptparser.cpp
133 lines (119 loc) · 3.25 KB
/
scriptparser.cpp
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "scriptparser.h"
#include "util.h"
#include <string.h>
#include <stdio.h> // include stdio before overriding stderr
#include <assert.h>
#include <errno.h>
#ifdef __has_include
#if !__has_include("SoEScriptDumper/list-rooms.cpp")
#error "SoEScriptDumper/list-rooms.cpp missing! Make sure git submodules are initialized correctly!"
#endif
#endif
// yes, this is ugly.
static FILE* outpipe = nullptr;
static FILE* errpipe = nullptr;
#ifdef stderr
#undef stderr
#endif
#define stderr errpipe
#define die(msg) do {\
fprintf(stderr, "%s", msg);\
free(buf);\
return 1;\
} while (false);
#define main _scriptparser
#define printf(...) fprintf(outpipe, __VA_ARGS__)
//#define HTML4
#define HTML5 // required for dark mode
#define NO_BOLD // does not play nice with synchronized textboxes
#define PRINT_HEX
#include "SoEScriptDumper/list-rooms.cpp"
#undef main
#undef printf
#undef stderr
ScriptParser::ScriptParser(const char* rom)
{
_romfile = rom;
}
std::string ScriptParser::parse(std::string* err, bool dark) const
{
assert(!outpipe);
assert(!errpipe);
// NOTE: css below seems to be the fastest
std::string res = (!dark) ? "<html>"
"<head><style>"
"body { white-space: pre; } "
#ifndef HTML4 // we use <font color> for HTML4 instead
".r { color:#f00; } "
".g { color:#0f0; } "
".u { color:#707; } "
".h,.t { color:#770; } "
#ifndef NO_BOLD
".t { font-weight:bold; } "
#endif
#endif
"</style></head><body>" : "<html>"
"<head><style>"
"body { white-space: pre; background:#070707; color:#eee; } "
#ifndef HTML4 // we use <font color> for HTML4 instead
".r { color:#f44; } "
".g { color:#4f4; } "
".u { color:#d4f; } "
".h,.t { color:#ee4; } "
#ifndef NO_BOLD
".t { font-weight:bold; } "
#endif
#endif
"</style></head><body>";
#ifdef WIN32
std::string outfn = tmpfn("out");
std::string errfn = tmpfn("err");
#endif
char app[] = "";
char* fn = strdup(_romfile.c_str());
char* args[] = {app,fn};
assert(fn);
#ifdef WIN32
outpipe = fopen(outfn.c_str(), "w+");
#else
outpipe = tmpfile();
#endif
if (!outpipe) {
if (err) *err = std::string("tmpfile: ") + strerror(errno);
goto done;
}
#ifdef WIN32
errpipe = fopen(errfn.c_str(), "w+");
#else
errpipe = tmpfile();
#endif
if (!errpipe) {
if (err) *err = std::string("tmpfile: ") + strerror(errno);
goto done;
}
_scriptparser(2, args);
rewind(outpipe);
while (!feof(outpipe)) {
char buf[4096];
size_t rd = fread(buf, 1, sizeof(buf), outpipe);
res += std::string(buf, rd);
}
rewind(errpipe);
while (err && !feof(errpipe)) {
char buf[4096];
size_t rd = fread(buf, 1, sizeof(buf), errpipe);
*err += std::string(buf, rd);
}
done:
if (outpipe) fclose(outpipe);
outpipe = nullptr;
if (errpipe) fclose(errpipe);
errpipe = nullptr;
free(fn);
res += " </body></html>";
#ifdef WIN32
if (! outfn.empty()) unlink(outfn.c_str());
if (! errfn.empty()) unlink(errfn.c_str());
#endif
return res;
}