176 lines
4.3 KiB
C++
Executable File
176 lines
4.3 KiB
C++
Executable File
#include "bpp.hpp"
|
|
|
|
bool BPP::process_macro(Macro ¯o, const lstring &arg) {
|
|
lstring linedata;
|
|
linedata.split("\n", macro.data);
|
|
|
|
for(unsigned i = 0; i < linedata.size(); i++) {
|
|
string line = linedata[i];
|
|
|
|
for(unsigned j = 0; j < macro.args; j++) {
|
|
line.replace(macro.arg[j], arg[j]);
|
|
}
|
|
|
|
for(unsigned j = 0; j < global.size(); j++) {
|
|
line.replace(global[j].name, global[j].data);
|
|
}
|
|
|
|
output.print(string() << line << "\n");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BPP::process(const char *inputfn) {
|
|
string filedata;
|
|
if(filedata.readfile(inputfn) == false) {
|
|
fprintf(stdout, "error: failed to open input file '%s'\n", inputfn);
|
|
return false;
|
|
}
|
|
|
|
filedata.replace("\r", "");
|
|
lstring linedata;
|
|
linedata.split("\n", filedata);
|
|
|
|
for(unsigned i = 0; i < linedata.size();) {
|
|
string line = linedata[i];
|
|
trim(line);
|
|
line.replace("\t", " ");
|
|
|
|
if(strbegin(line, "@") == false) {
|
|
output.print(string() << linedata[i] << "\n");
|
|
i++;
|
|
} else if(strbegin(line, "@include ")) {
|
|
ltrim(line, "@include ");
|
|
trim(line, "\"");
|
|
if(process(line) == false) return false;
|
|
i++;
|
|
} else if(strbegin(line, "@global ")) {
|
|
ltrim(line, "@global ");
|
|
while(qstrpos(line, " ") >= 0) line.replace(" ", " ");
|
|
|
|
lstring part;
|
|
part.qsplit(" ", line);
|
|
if(part.size() != 2) {
|
|
fprintf(stdout, "error: malformed global\n");
|
|
return false;
|
|
}
|
|
|
|
unsigned n = global.size();
|
|
global[n].name = string() << "{" << part[0] << "}";
|
|
global[n].data = trim(part[1], "\"");
|
|
i++;
|
|
} else if(strbegin(line, "@macro ")) {
|
|
ltrim(line, "@macro ");
|
|
|
|
int pos = strpos(line, "(");
|
|
if(pos < 0 || !strend(line, ")")) {
|
|
fprintf(stdout, "error: malformed macro\n");
|
|
return false;
|
|
}
|
|
|
|
string name = substr(line, 0, pos);
|
|
line = substr(line, pos);
|
|
ltrim(line, "(");
|
|
rtrim(line, ")");
|
|
line.qreplace(" ", "");
|
|
|
|
unsigned n = macro.size();
|
|
macro[n].name = name;
|
|
|
|
if(line == "") {
|
|
macro[n].args = 0;
|
|
} else {
|
|
lstring arg;
|
|
arg.split(",", line);
|
|
if(arg.size() >= 8) {
|
|
fprintf(stdout, "error: too many macro arguments\n");
|
|
return false;
|
|
}
|
|
|
|
macro[n].args = arg.size();
|
|
for(unsigned j = 0; j < arg.size(); j++) {
|
|
macro[n].arg[j] = string() << "{" << arg[j] << "}";
|
|
}
|
|
}
|
|
|
|
i++;
|
|
|
|
while(i < linedata.size()) {
|
|
string line = linedata[i];
|
|
trim(line);
|
|
if(line == "@endmacro") break;
|
|
macro[n].data << linedata[i++] << "\n";
|
|
}
|
|
|
|
i++;
|
|
} else {
|
|
ltrim(line, "@");
|
|
int pos = strpos(line, "(");
|
|
if(pos < 0 || !strend(line, ")")) {
|
|
fprintf(stdout, "error: malformed macro invocation\n");
|
|
return false;
|
|
}
|
|
|
|
string name = substr(line, 0, pos);
|
|
line = substr(line, pos);
|
|
ltrim(line, "(");
|
|
rtrim(line, ")");
|
|
line.qreplace(" ", "");
|
|
|
|
lstring arg;
|
|
if(line != "") arg.qsplit(",", line);
|
|
for(unsigned j = 0; j < arg.size(); j++) {
|
|
trim(arg[j], "\"");
|
|
}
|
|
|
|
bool success = false;
|
|
for(unsigned j = 0; j < macro.size(); j++) {
|
|
if(name == macro[j].name && arg.size() == macro[j].args) {
|
|
success = process_macro(macro[j], arg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(success == false) {
|
|
fprintf(stdout, "error: unable to process macro '%s'\n", (const char*)name);
|
|
return false;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BPP::process(const char *outputfn, const char *inputfn) {
|
|
if(file::exists(inputfn) == false) {
|
|
fprintf(stdout, "error: failed to open input file\n");
|
|
return false;
|
|
}
|
|
|
|
if(output.open(outputfn, file::mode_write) == false) {
|
|
fprintf(stdout, "error: failed to open output file\n");
|
|
return false;
|
|
}
|
|
|
|
bool result = process(inputfn);
|
|
output.close();
|
|
return result;
|
|
}
|
|
|
|
int main(int argc, const char **argv) {
|
|
if(argc != 3) {
|
|
fprintf(stdout, "bpp v0.01\n");
|
|
fprintf(stdout, "author: byuu\n");
|
|
fprintf(stdout, "usage: bpp output input\n");
|
|
return 0;
|
|
}
|
|
|
|
BPP bpp;
|
|
bool success = bpp.process(argv[1], argv[2]);
|
|
if(success == false) fprintf(stdout, "error: pre-processing failed\n");
|
|
return 0;
|
|
}
|