2018-05-21 21:42:19 -05:00
|
|
|
// 21 may 2018
|
|
|
|
#include <vector>
|
|
|
|
#include <stdio.h>
|
2018-05-26 19:09:16 -05:00
|
|
|
#include <string.h>
|
2018-05-26 15:56:53 -05:00
|
|
|
#include "lib.hpp"
|
2018-05-21 21:42:19 -05:00
|
|
|
|
2018-05-26 19:09:16 -05:00
|
|
|
struct item {
|
|
|
|
Slice *name;
|
|
|
|
Slice *callingConvention;
|
|
|
|
Slice **params;
|
|
|
|
size_t nParams;
|
|
|
|
Slice *returns;
|
|
|
|
bool keepReturn;
|
|
|
|
Slice *cond[2];
|
|
|
|
};
|
|
|
|
|
2018-05-22 20:19:54 -05:00
|
|
|
bool generate(const char *line, size_t n, FILE *fout)
|
|
|
|
{
|
|
|
|
std::vector<char> genout;
|
2018-05-26 16:42:11 -05:00
|
|
|
std::vector<Slice *> *tokens;
|
2018-05-26 19:09:16 -05:00
|
|
|
size_t i, j;
|
|
|
|
struct item item;
|
2018-05-22 20:19:54 -05:00
|
|
|
size_t nw;
|
|
|
|
|
2018-05-26 16:42:11 -05:00
|
|
|
tokens = TokenizeWhitespace(line, n);
|
2018-05-26 19:09:16 -05:00
|
|
|
|
|
|
|
memset(&item, 0, sizeof (struct item));
|
|
|
|
i = 0;
|
|
|
|
item.returns = tokens->at(i);
|
|
|
|
if (item.returns->Data()[0] == '*') {
|
|
|
|
item.returns = new Slice(item.returns->Data() + 1, item.returns->Len() - 1);
|
|
|
|
item.keepReturn = true;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
if (tokens->size() % 2 == 1) {
|
|
|
|
item.callingConvention = tokens->at(i);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
item.name = tokens->at(i);
|
|
|
|
i++;
|
|
|
|
item.cond[0] = tokens->at(tokens->size() - 2);
|
|
|
|
item.cond[1] = tokens->at(tokens->size() - 1);
|
|
|
|
item.nParams = (tokens->size() - 2) - i;
|
|
|
|
item.params = new Slice *[item.nParams];
|
|
|
|
for (j = 0; j < item.nParams; j++) {
|
|
|
|
item.params[j] = tokens->at(i);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
AppendString(&genout, "HRESULT ");
|
|
|
|
if (item.callingConvention != NULL) {
|
|
|
|
AppendSlice(&genout, item.callingConvention);
|
2018-05-26 16:42:11 -05:00
|
|
|
genout.push_back(' ');
|
|
|
|
}
|
2018-05-26 19:09:16 -05:00
|
|
|
AppendSlice(&genout, item.name);
|
|
|
|
genout.push_back('(');
|
|
|
|
for (i = 0; i < item.nParams; i += 2) {
|
|
|
|
AppendSlice(&genout, item.params[i]);
|
|
|
|
genout.push_back(' ');
|
|
|
|
AppendSlice(&genout, item.params[i + 1]);
|
|
|
|
genout.push_back(',');
|
|
|
|
genout.push_back(' ');
|
|
|
|
}
|
|
|
|
if (item.keepReturn) {
|
|
|
|
AppendSlice(&genout, item.returns);
|
|
|
|
AppendString(&genout, " *ret");
|
|
|
|
} else if (item.nParams != 0) {
|
|
|
|
// remove the trailing comma and space
|
|
|
|
genout.pop_back();
|
|
|
|
genout.pop_back();
|
|
|
|
} else
|
|
|
|
AppendString(&genout, "void");
|
|
|
|
genout.push_back(')');
|
|
|
|
genout.push_back('\n');
|
|
|
|
|
|
|
|
delete[] item.params;
|
|
|
|
if (item.keepReturn)
|
|
|
|
delete item.returns;
|
2018-05-26 16:42:11 -05:00
|
|
|
FreeTokenized(tokens);
|
2018-05-22 20:19:54 -05:00
|
|
|
|
|
|
|
genout.push_back('\n');
|
|
|
|
nw = fwrite(genout.data(), sizeof (char), genout.size(), fout);
|
|
|
|
return nw == genout.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool process(const char *line, size_t n, FILE *fout)
|
|
|
|
{
|
|
|
|
size_t nw;
|
|
|
|
|
|
|
|
if (n > 0 && line[0] == '@')
|
|
|
|
return generate(line + 1, n - 1, fout);
|
|
|
|
nw = fwrite(line, sizeof (char), n, fout);
|
|
|
|
if (nw != n)
|
|
|
|
return false;
|
|
|
|
return fwrite("\n", sizeof (char), 1, fout) == 1;
|
|
|
|
}
|
|
|
|
|
2018-05-21 21:42:19 -05:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2018-05-26 15:56:53 -05:00
|
|
|
ReadCloser *fin = NULL;
|
2018-05-24 15:11:58 -05:00
|
|
|
FILE *fout = NULL;
|
2018-05-22 20:19:54 -05:00
|
|
|
Scanner *s = NULL;
|
2018-05-21 21:42:19 -05:00
|
|
|
int ret = 1;
|
2018-05-26 15:56:53 -05:00
|
|
|
Error *err = NULL;
|
2018-05-21 21:42:19 -05:00
|
|
|
|
|
|
|
if (argc != 3) {
|
|
|
|
fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-05-26 15:56:53 -05:00
|
|
|
err = OpenRead(argv[1], &fin);
|
|
|
|
if (err != NULL) {
|
|
|
|
fprintf(stderr, "error opening %s: %s\n", argv[1], err->String());
|
2018-05-21 21:42:19 -05:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
fout = fopen(argv[2], "wb");
|
|
|
|
if (fout == NULL) {
|
|
|
|
fprintf(stderr, "error creating %s\n", argv[2]);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2018-05-22 20:19:54 -05:00
|
|
|
s = new Scanner(fin);
|
|
|
|
while (s->Scan()) {
|
|
|
|
const char *line;
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
line = s->Bytes();
|
|
|
|
n = s->Len();
|
|
|
|
if (!process(line, n, fout)) {
|
2018-05-21 21:42:19 -05:00
|
|
|
fprintf(stderr, "error writing to %s\n", argv[2]);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
2018-05-26 15:56:53 -05:00
|
|
|
if (s->Err() != 0) {
|
|
|
|
fprintf(stderr, "error reading from %s: %s\n", argv[1], s->Err()->String());
|
2018-05-21 21:42:19 -05:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
done:
|
2018-05-22 20:19:54 -05:00
|
|
|
if (s != NULL)
|
|
|
|
delete s;
|
2018-05-21 21:42:19 -05:00
|
|
|
if (fout != NULL)
|
|
|
|
fclose(fout);
|
2018-05-26 15:56:53 -05:00
|
|
|
if (fin != NULL)
|
|
|
|
delete fin;
|
|
|
|
if (err != NULL)
|
|
|
|
delete err;
|
2018-05-21 21:42:19 -05:00
|
|
|
return ret;
|
|
|
|
}
|