mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-19 07:21:20 +03:00
import KernelEx-4.0-RC1
This commit is contained in:
699
util/prep/prep.cpp
Normal file
699
util/prep/prep.cpp
Normal file
@ -0,0 +1,699 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma warning(disable:4786)
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
using namespace std;
|
||||
#include "prep.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vector<export_entry_named> all_exports_named;
|
||||
vector<export_entry_ordinal> all_exports_ordinal;
|
||||
stringstream all_declarations;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int count(const string& s, char c, size_t pos, size_t epos)
|
||||
{
|
||||
int num = 0;
|
||||
if (epos == string::npos)
|
||||
epos = s.length();
|
||||
if (pos < 0 || pos >= epos)
|
||||
return 0;
|
||||
for (int i = pos ; i < epos ; i++)
|
||||
if (s[i] == c)
|
||||
num++;
|
||||
return num;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FileFinder::FileFinder()
|
||||
{
|
||||
}
|
||||
|
||||
FileFinder::FileFinder(const string& fn)
|
||||
{
|
||||
search_for(fn);
|
||||
}
|
||||
|
||||
FileFinder::~FileFinder()
|
||||
{
|
||||
}
|
||||
|
||||
void FileFinder::search_for(const string& fn)
|
||||
{
|
||||
WIN32_FIND_DATA find_data;
|
||||
files.clear();
|
||||
pos = 0;
|
||||
HANDLE h = FindFirstFile(fn.c_str(), &find_data);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
do
|
||||
files.push_back(find_data.cFileName);
|
||||
while (FindNextFile(h, &find_data));
|
||||
CloseHandle(h);
|
||||
stable_sort(files.begin(), files.end());
|
||||
}
|
||||
|
||||
string FileFinder::get_next_file()
|
||||
{
|
||||
if (files.empty() || pos >= files.size())
|
||||
return "";
|
||||
return files[pos++];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FileDeclParser::FileDeclParser(const char* file_name) throw(exception)
|
||||
{
|
||||
this->file_name = file_name;
|
||||
ifstream f(file_name);
|
||||
if (!f)
|
||||
throw Exception("Failed to open file");
|
||||
|
||||
stringstream buf;
|
||||
buf << f.rdbuf();
|
||||
|
||||
buffer = buf.str();
|
||||
}
|
||||
|
||||
void FileDeclParser::parse() throw(exception)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = buffer.find("MAKE_EXPORT", pos)) != string::npos)
|
||||
{
|
||||
size_t lfpos = buffer.find('\n', pos);
|
||||
if (lfpos == string::npos)
|
||||
break;
|
||||
|
||||
parse_make_export(buffer.substr(pos, lfpos - pos));
|
||||
pos += sizeof("MAKE_EXPORT");
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
while ((pos = buffer.find("FORWARD_TO_UNICOWS(", pos)) != string::npos)
|
||||
{
|
||||
size_t lfpos = buffer.find('\n', pos);
|
||||
if (lfpos == string::npos)
|
||||
break;
|
||||
|
||||
if (!is_containing_line_commented(pos))
|
||||
parse_forward_to_unicows(buffer.substr(pos, lfpos - pos));
|
||||
pos = lfpos + 1;
|
||||
}
|
||||
|
||||
int total_exports = exports_named.size() + exports_ordinal.size();
|
||||
if (total_exports == 0)
|
||||
{
|
||||
cout << "File doesn't contain exports" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
prefilter();
|
||||
|
||||
int dcount = 0;
|
||||
size_t lpos = 0; //last pos
|
||||
int nest_level = 0; // nest level
|
||||
|
||||
while ((pos = buffer.find('(', lpos)) != string::npos)
|
||||
{
|
||||
nest_level += count(buffer, '{', lpos, pos)
|
||||
- count(buffer, '}', lpos, pos);
|
||||
|
||||
lpos = pos + 1;
|
||||
|
||||
if (nest_level == 0)
|
||||
{
|
||||
if (is_containing_line_commented(pos))
|
||||
continue;
|
||||
|
||||
//at this level we have position of function opening brace '('
|
||||
//the hard part is finding beginning of function declaration
|
||||
|
||||
size_t beg = buffer.find_last_of(";}", pos);
|
||||
if (beg == string::npos)
|
||||
beg = 0;
|
||||
|
||||
while (is_containing_line_commented(beg) && beg != string::npos)
|
||||
beg = buffer.find_last_of(";}", beg - 1);
|
||||
|
||||
if (beg == string::npos)
|
||||
beg = 0;
|
||||
|
||||
if (beg)
|
||||
beg++;
|
||||
|
||||
size_t end = buffer.find(')', pos);
|
||||
if (end == string::npos)
|
||||
continue;
|
||||
|
||||
while (is_containing_line_commented(end) && end != string::npos)
|
||||
end = buffer.find(')', end + 1);
|
||||
|
||||
if (end == string::npos)
|
||||
continue;
|
||||
|
||||
end++;
|
||||
|
||||
string decl = buffer.substr(beg, end - beg) + ';';
|
||||
filter_declaration(decl);
|
||||
|
||||
int cnt = find_matching_export(decl);
|
||||
|
||||
if (!cnt)
|
||||
continue;
|
||||
|
||||
all_declarations << decl << endl;
|
||||
dcount += cnt;
|
||||
|
||||
//cout << decl << endl;
|
||||
|
||||
lpos = end + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vector<export_entry_named>::iterator i1 = exports_named.begin();
|
||||
vector<export_entry_ordinal>::iterator i2 = exports_ordinal.begin();
|
||||
|
||||
while (i1 != exports_named.end())
|
||||
all_exports_named.push_back(*i1++);
|
||||
while (i2 != exports_ordinal.end())
|
||||
all_exports_ordinal.push_back(*i2++);
|
||||
|
||||
if (dcount < total_exports)
|
||||
cout << "!Unresolved exports: " << total_exports - dcount << endl;
|
||||
}
|
||||
|
||||
size_t FileDeclParser::find_line_start(size_t pos)
|
||||
{
|
||||
size_t line_start = buffer.rfind('\n', pos);
|
||||
if (line_start == string::npos)
|
||||
line_start = 0;
|
||||
else
|
||||
line_start++;
|
||||
return line_start;
|
||||
}
|
||||
|
||||
bool FileDeclParser::is_containing_line_commented(size_t pos)
|
||||
{
|
||||
size_t line_start = find_line_start(pos);
|
||||
string p = buffer.substr(line_start, pos - line_start);
|
||||
size_t pp;
|
||||
if ((pp = p.find("//")) != string::npos || (pp = p.find('#')) != string::npos)
|
||||
{
|
||||
for (int i = 0 ; i < pp ; i++)
|
||||
// if there is something before '//' then the line isn't commented
|
||||
if (p[i] != ' ' && p[i] != '\t')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileDeclParser::parse_make_export(const string& line) throw(exception)
|
||||
{
|
||||
size_t pos = line.find("MAKE_EXPORT");
|
||||
if (pos == string::npos)
|
||||
throw Exception("MAKE_EXPORT tag not found");
|
||||
pos += sizeof("MAKE_EXPORT");
|
||||
pos = line.find_first_not_of(" \t", pos);
|
||||
if (pos == string::npos)
|
||||
throw Exception("Invalid MAKE_EXPORT tag");
|
||||
size_t pos2 = line.find('=', pos);
|
||||
if (pos2 == string::npos)
|
||||
throw Exception("Invalid MAKE_EXPORT tag");
|
||||
string source_name = line.substr(pos, pos2 - pos);
|
||||
pos = pos2 + 1;
|
||||
pos2 = line.find_first_of(" \t", pos);
|
||||
if (line.compare(pos, sizeof("ordinal") - 1, "ordinal"))
|
||||
{
|
||||
export_entry_named ee;
|
||||
ee.source_name = source_name;
|
||||
ee.export_name = line.substr(pos, pos2 - pos);
|
||||
exports_named.push_back(ee);
|
||||
}
|
||||
else
|
||||
{
|
||||
export_entry_ordinal ee;
|
||||
ee.source_name = source_name;
|
||||
ee.ordinal = strtol(line.substr(pos + sizeof("ordinal") - 1).c_str(), NULL, 0);
|
||||
exports_ordinal.push_back(ee);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDeclParser::parse_forward_to_unicows(const string& line) throw(exception)
|
||||
{
|
||||
size_t pos = line.find("FORWARD_TO_UNICOWS(");
|
||||
if (pos == string::npos)
|
||||
throw Exception("FORWARD_TO_UNICOWS(");
|
||||
pos += sizeof("FORWARD_TO_UNICOWS(") - 1;
|
||||
size_t pos2 = line.find(')', pos);
|
||||
if (pos2 == string::npos)
|
||||
throw Exception("Invalid FORWARD_TO_UNICOWS tag");
|
||||
string name = line.substr(pos, pos2 - pos);
|
||||
export_entry_named ee;
|
||||
ee.source_name = name + "_fwd";
|
||||
ee.export_name = name;
|
||||
all_exports_named.push_back(ee);
|
||||
all_declarations << "FWDPROC " + name + "_fwd;" << endl;
|
||||
}
|
||||
|
||||
int FileDeclParser::find_matching_export(const string& s)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
//try named exports first
|
||||
vector<export_entry_named>::iterator itn = exports_named.begin();
|
||||
while (itn != exports_named.end())
|
||||
{
|
||||
if (s.find(itn->source_name) != string::npos)
|
||||
count++;
|
||||
itn++;
|
||||
}
|
||||
//then try ordinal exports
|
||||
vector<export_entry_ordinal>::iterator ito = exports_ordinal.begin();
|
||||
while (ito != exports_ordinal.end())
|
||||
{
|
||||
if (s.find(ito->source_name) != string::npos)
|
||||
count++;
|
||||
ito++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void FileDeclParser::prefilter() throw(exception)
|
||||
{
|
||||
//erase C-style comments
|
||||
size_t pos;
|
||||
while ((pos = buffer.find("/*")) != string::npos)
|
||||
{
|
||||
size_t pos2 = buffer.find("*/", pos + 1);
|
||||
if (pos2 == string::npos)
|
||||
throw Exception("No matching C-style comment closing");
|
||||
buffer.erase(pos, pos2 - pos + sizeof("*/") - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDeclParser::filter_declaration(string& s)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
//erase precompiler directives
|
||||
size_t pos;
|
||||
while ((pos = s.find('#')) != string::npos)
|
||||
{
|
||||
size_t p2 = s.find('\n', pos + 1);
|
||||
if (p2 != string::npos)
|
||||
p2 -= pos;
|
||||
s.erase(pos, p2);
|
||||
}
|
||||
|
||||
//erase C++ style comments
|
||||
while ((pos = s.find("//")) != string::npos)
|
||||
{
|
||||
size_t p2 = s.find('\n', pos + 1);
|
||||
if (p2 != string::npos)
|
||||
p2 -= pos;
|
||||
s.erase(pos, p2);
|
||||
}
|
||||
|
||||
//erase "__declspec(naked)"
|
||||
while ((pos = s.find("__declspec(naked)")) != string::npos)
|
||||
s.erase(pos, sizeof("__declspec(naked)"));
|
||||
|
||||
//replace tabs and newlines with spaces
|
||||
for (i = 0 ; i < s.length() ; i++)
|
||||
if (s[i] == '\t' || s[i] == '\n')
|
||||
s[i] = ' ';
|
||||
|
||||
//erase leading spaces
|
||||
while (s[0] == ' ')
|
||||
s.erase(0, 1);
|
||||
|
||||
|
||||
//erase spaces after bracket
|
||||
pos = s.find('(');
|
||||
while (s[pos + 1] == ' ')
|
||||
s.erase(pos + 1, 1);
|
||||
|
||||
//erase spaces before bracket
|
||||
pos = s.rfind(')');
|
||||
while (s[pos - 1] == ' ')
|
||||
{
|
||||
s.erase(pos - 1, 1);
|
||||
pos--;
|
||||
}
|
||||
|
||||
//erase multiple spaces
|
||||
i = 0;
|
||||
while (i < s.length())
|
||||
{
|
||||
if (s[i] == ' ')
|
||||
while (i + 1 < s.length() && s[i + 1] == ' ')
|
||||
s.erase(i + 1, 1);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StubsParser::StubsParser(const char* file_name) throw(exception) : FileDeclParser(file_name)
|
||||
{
|
||||
}
|
||||
|
||||
void StubsParser::parse() throw(exception)
|
||||
{
|
||||
prefilter();
|
||||
|
||||
size_t pos = 0;
|
||||
size_t lpos = 0;
|
||||
|
||||
while ((pos = buffer.find("UNIMPL_FUNC", lpos)) != string::npos)
|
||||
{
|
||||
size_t beg = buffer.find('(', pos);
|
||||
if (beg == string::npos)
|
||||
continue;
|
||||
beg++;
|
||||
|
||||
while (isspace(buffer[beg]))
|
||||
beg++;
|
||||
|
||||
size_t end = buffer.find(',', beg + 1);
|
||||
if (end == string::npos)
|
||||
continue;
|
||||
end--;
|
||||
|
||||
while (isspace(buffer[end]))
|
||||
end--;
|
||||
|
||||
string name = buffer.substr(beg, end - beg + 1);
|
||||
string decl = "STUB " + name + "_stub" + ';';
|
||||
all_declarations << decl << endl;
|
||||
export_entry_named ee;
|
||||
ee.export_name = name;
|
||||
ee.source_name = name + "_stub";
|
||||
all_exports_named.push_back(ee);
|
||||
|
||||
lpos = end + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void write_named_exports(ostream& o)
|
||||
{
|
||||
vector<export_entry_named>::iterator it = all_exports_named.begin();
|
||||
while (it != all_exports_named.end())
|
||||
{
|
||||
o << "\tDECL_API(\"" << it->export_name << "\", "
|
||||
<< it->source_name << ")," << endl;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
void write_ordinal_exports(ostream& o)
|
||||
{
|
||||
vector<export_entry_ordinal>::iterator it = all_exports_ordinal.begin();
|
||||
while (it != all_exports_ordinal.end())
|
||||
{
|
||||
o << "\tDECL_API(" << it->ordinal << ", "
|
||||
<< it->source_name << ")," << endl;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
void dump_all()
|
||||
{
|
||||
cout << "*** function declarations:" << endl;
|
||||
cout << all_declarations.rdbuf();
|
||||
cout << "*** named exports:" << endl;
|
||||
write_named_exports(cout);
|
||||
cout << "*** ordinal exports:" << endl;
|
||||
write_ordinal_exports(cout);
|
||||
}
|
||||
|
||||
void replace_if_changed(const string& out, const string& in)
|
||||
{
|
||||
fstream f;
|
||||
stringstream buf;
|
||||
string in1;
|
||||
string in2;
|
||||
|
||||
f.open(out.c_str(), fstream::in);
|
||||
if (!f)
|
||||
throw Exception("Failed to open file");
|
||||
buf << f.rdbuf();
|
||||
in1 = buf.str();
|
||||
f.close();
|
||||
|
||||
f.open(in.c_str(), fstream::in);
|
||||
if (!f)
|
||||
throw Exception("Failed to open file");
|
||||
buf.clear();
|
||||
buf.str("");
|
||||
buf << f.rdbuf();
|
||||
in2 = buf.str();
|
||||
f.close();
|
||||
|
||||
if (in1.compare(in2))
|
||||
{
|
||||
f.open(out.c_str(), ios::out | ios::trunc);
|
||||
if (!f)
|
||||
throw Exception("Failed to open file");
|
||||
f << in2;
|
||||
f.close();
|
||||
}
|
||||
|
||||
remove(in.c_str());
|
||||
}
|
||||
|
||||
void work()
|
||||
{
|
||||
ifstream dirlist("dirlist");
|
||||
if (!dirlist)
|
||||
throw Exception("Couldn't open dirlist");
|
||||
|
||||
while (!dirlist.eof())
|
||||
{
|
||||
fstream out_file;
|
||||
stringstream buf;
|
||||
string path;
|
||||
string file;
|
||||
FileFinder ff;
|
||||
string line;
|
||||
|
||||
all_exports_named.clear();
|
||||
all_exports_ordinal.clear();
|
||||
all_declarations.clear();
|
||||
all_declarations.str("");
|
||||
|
||||
getline(dirlist, path);
|
||||
|
||||
//skip empty lines
|
||||
if (path.empty())
|
||||
continue;
|
||||
|
||||
path += '\\';
|
||||
|
||||
cout << "Processing directory: '" << path << '\'' << endl;
|
||||
|
||||
ff.search_for(path + "*.c");
|
||||
|
||||
//read declarations
|
||||
while (!(file = ff.get_next_file()).empty())
|
||||
{
|
||||
FileDeclParser* parser;
|
||||
|
||||
//if (file.find("_apilist.") != string::npos)
|
||||
// continue;
|
||||
|
||||
file = path + file;
|
||||
|
||||
cout << "Parsing file: '" << file << '\'' << endl;
|
||||
|
||||
if (file.find("_stubs.") != string::npos)
|
||||
parser = new StubsParser(file.c_str());
|
||||
else
|
||||
parser = new FileDeclParser(file.c_str());
|
||||
|
||||
parser->parse();
|
||||
delete parser;
|
||||
}
|
||||
|
||||
stable_sort(all_exports_named.begin(), all_exports_named.end());
|
||||
stable_sort(all_exports_ordinal.begin(), all_exports_ordinal.end());
|
||||
|
||||
//write output defs
|
||||
ff.search_for(path + "_*_apilist.c");
|
||||
file = ff.get_next_file();
|
||||
if (file.empty())
|
||||
throw Exception("Couldn't find output def file");
|
||||
|
||||
file = path + file;
|
||||
|
||||
cout << "Definitions output: '" << file << '\'' << endl;
|
||||
|
||||
out_file.open(file.c_str(), fstream::in);
|
||||
if (!out_file.is_open())
|
||||
throw Exception("Failed to open output def file for read");
|
||||
|
||||
buf << out_file.rdbuf();
|
||||
|
||||
out_file.close();
|
||||
|
||||
out_file.open((file + ".tmp").c_str(), ios::out | ios::trunc);
|
||||
if (!out_file.is_open())
|
||||
throw Exception("Failed to open output def file for write");
|
||||
|
||||
while (true)
|
||||
{
|
||||
getline(buf, line);
|
||||
if (0 == line.compare("/*** AUTOGENERATED APILIST NAMED EXPORTS BEGIN ***/"))
|
||||
{
|
||||
out_file << line << endl;
|
||||
while (true)
|
||||
{
|
||||
getline(buf,line);
|
||||
if (0 == line.compare("/*** AUTOGENERATED APILIST NAMED EXPORTS END ***/"))
|
||||
break;
|
||||
}
|
||||
|
||||
write_named_exports(out_file);
|
||||
}
|
||||
else if (0 == line.compare("/*** AUTOGENERATED APILIST ORDINAL EXPORTS BEGIN ***/"))
|
||||
{
|
||||
out_file << line << endl;
|
||||
while (true)
|
||||
{
|
||||
getline(buf,line);
|
||||
if (0 == line.compare("/*** AUTOGENERATED APILIST ORDINAL EXPORTS END ***/"))
|
||||
break;
|
||||
}
|
||||
|
||||
write_ordinal_exports(out_file);
|
||||
}
|
||||
out_file << line;
|
||||
|
||||
if (!buf.eof())
|
||||
out_file << endl;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
out_file.close();
|
||||
replace_if_changed(file, file + ".tmp");
|
||||
|
||||
//write output decls
|
||||
ff.search_for(path + "_*_apilist.h");
|
||||
|
||||
file = ff.get_next_file();
|
||||
if (file.empty())
|
||||
throw Exception("Couldn't find output decl file");
|
||||
|
||||
file = path + file;
|
||||
|
||||
cout << "Declarations output: '" << file << '\'' << endl;
|
||||
|
||||
out_file.open(file.c_str(), fstream::in);
|
||||
if (!out_file.is_open())
|
||||
throw Exception("Failed to open output decl file for read");
|
||||
|
||||
buf.clear();
|
||||
buf.str("");
|
||||
buf << out_file.rdbuf();
|
||||
|
||||
out_file.close();
|
||||
|
||||
out_file.open((file + ".tmp").c_str(), ios::out | ios::trunc);
|
||||
if (!out_file.is_open())
|
||||
throw Exception("Failed to open output decl file for write");
|
||||
|
||||
while (true)
|
||||
{
|
||||
getline(buf, line);
|
||||
if (0 == line.compare("/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/"))
|
||||
{
|
||||
out_file << line << endl;
|
||||
while (true)
|
||||
{
|
||||
getline(buf,line);
|
||||
if (0 == line.compare("/*** AUTOGENERATED APILIST DECLARATIONS END ***/"))
|
||||
break;
|
||||
}
|
||||
|
||||
all_declarations.peek();
|
||||
if (all_declarations.good())
|
||||
out_file << all_declarations.rdbuf();
|
||||
}
|
||||
out_file << line;
|
||||
|
||||
if (!buf.eof())
|
||||
out_file << endl;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
out_file.close();
|
||||
replace_if_changed(file, file + ".tmp");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc > 2)
|
||||
{
|
||||
cout << "Invalid parameters!" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc == 2)
|
||||
if (!SetCurrentDirectory(argv[1]))
|
||||
{
|
||||
cout << "Failed to change directory" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
work();
|
||||
}
|
||||
catch (const exception& e)
|
||||
{
|
||||
cout << "Exception: " << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
120
util/prep/prep.dsp
Normal file
120
util/prep/prep.dsp
Normal file
@ -0,0 +1,120 @@
|
||||
# Microsoft Developer Studio Project File - Name="prep" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=prep - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "prep.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "prep.mak" CFG="prep - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "prep - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "prep - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "prep - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GF /c
|
||||
# ADD BASE RSC /l 0x415 /d "NDEBUG"
|
||||
# ADD RSC /l 0x415 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /OPT:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
# Begin Custom Build
|
||||
OutDir=.\Release
|
||||
WkspDir=.
|
||||
TargetName=prep
|
||||
InputPath=.\Release\prep.exe
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"nope" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(OutDir)\$(TargetName) $(WkspDir)\apilibs\kexbases
|
||||
$(OutDir)\$(TargetName) $(WkspDir)\apilibs\kexbasen
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "prep - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /GF /c
|
||||
# ADD BASE RSC /l 0x415 /d "_DEBUG"
|
||||
# ADD RSC /l 0x415 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /OPT:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
# Begin Custom Build
|
||||
OutDir=.\Debug
|
||||
WkspDir=.
|
||||
TargetName=prep
|
||||
InputPath=.\Debug\prep.exe
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"nope" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(OutDir)\$(TargetName) $(WkspDir)\apilibs\kexbases
|
||||
$(OutDir)\$(TargetName) $(WkspDir)\apilibs\kexbasen
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "prep - Win32 Release"
|
||||
# Name "prep - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prep.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prep.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
117
util/prep/prep.h
Normal file
117
util/prep/prep.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PREP_H
|
||||
#define __PREP_H
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int count(const string& s, char c, size_t pos = 0, size_t epos = string::npos);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Exception : public exception
|
||||
{
|
||||
private:
|
||||
string reason;
|
||||
|
||||
public:
|
||||
Exception(const char* what) : reason(what) {}
|
||||
~Exception() throw() {}
|
||||
const char* what() const throw() { return reason.c_str(); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FileFinder
|
||||
{
|
||||
public:
|
||||
FileFinder();
|
||||
FileFinder(const string& fn);
|
||||
~FileFinder();
|
||||
void search_for(const string& fn);
|
||||
string get_next_file();
|
||||
|
||||
private:
|
||||
int pos;
|
||||
vector<string> files;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct export_entry_named
|
||||
{
|
||||
string source_name;
|
||||
string export_name;
|
||||
|
||||
bool operator<(const export_entry_named& e) const
|
||||
{
|
||||
return this->export_name.compare(e.export_name) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct export_entry_ordinal
|
||||
{
|
||||
string source_name;
|
||||
unsigned short ordinal;
|
||||
|
||||
export_entry_ordinal() : ordinal(0) {}
|
||||
bool operator<(const export_entry_ordinal& e) const
|
||||
{
|
||||
return this->ordinal < e.ordinal;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FileDeclParser
|
||||
{
|
||||
public:
|
||||
FileDeclParser(const char* file_name) throw(exception);
|
||||
virtual void parse() throw(exception);
|
||||
|
||||
protected:
|
||||
string buffer;
|
||||
string file_name;
|
||||
vector<export_entry_named> exports_named;
|
||||
vector<export_entry_ordinal> exports_ordinal;
|
||||
|
||||
size_t find_line_start(size_t pos);
|
||||
bool is_containing_line_commented(size_t pos);
|
||||
void prefilter() throw(exception);
|
||||
void parse_make_export(const string& line) throw(exception);
|
||||
void parse_forward_to_unicows(const string& line) throw(exception);
|
||||
int find_matching_export(const string& s);
|
||||
void filter_declaration(string& s);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class StubsParser : public FileDeclParser
|
||||
{
|
||||
public:
|
||||
StubsParser(const char* file_name) throw(exception);
|
||||
void parse() throw(exception);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
5
util/prep/test/_te_apilist.c
Normal file
5
util/prep/test/_te_apilist.c
Normal file
@ -0,0 +1,5 @@
|
||||
junk1
|
||||
/*** APILIST NAMED EXPORTS BEGIN HERE ***/
|
||||
DECL_API("junkjard", junk),
|
||||
/*** APILIST NAMED EXPORTS END HERE ***/
|
||||
junk5
|
1
util/prep/test/dirlist
Normal file
1
util/prep/test/dirlist
Normal file
@ -0,0 +1 @@
|
||||
.
|
4
util/prep/test/junk.c
Normal file
4
util/prep/test/junk.c
Normal file
@ -0,0 +1,4 @@
|
||||
// MAKE_EXPORT junk=junkjard
|
||||
int junk(void** sf, float fd)
|
||||
{
|
||||
}
|
38
util/prep/test/test.c
Normal file
38
util/prep/test/test.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// MAKE_EXPORT fun=funny
|
||||
void fun()
|
||||
{
|
||||
int foobar;
|
||||
foobar++;
|
||||
}
|
||||
|
||||
typedef int sad;
|
||||
|
||||
/* MAKE_EXPORT barbar=jarjar
|
||||
*/
|
||||
//difficutly gets higher
|
||||
/* _cdecl barbar(bool b)
|
||||
{
|
||||
}
|
||||
*/
|
||||
#ifdef WINDOWS
|
||||
__declspec(dllexport)
|
||||
//total fuckup
|
||||
#else
|
||||
__cdecl
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
long long barbar(int a, //test
|
||||
bool b, /* dfas */ char /* sad */ c,
|
||||
//dumb stuff
|
||||
|
||||
float f,
|
||||
double d)
|
||||
{
|
||||
} int main() {
|
||||
fun();
|
||||
return (int) barbar(0, true, 'a', 2.3f, 0.34);
|
||||
}
|
Reference in New Issue
Block a user