Completed. Properly generates the desired outputs now.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8622 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2004-08-22 10:30:45 +00:00
parent 478bbd8507
commit a8ca1ab348
+91 -38
View File
@@ -14,15 +14,20 @@
// usage // usage
const char *kUsage = const char *kUsage =
"Usage: gensyscalls <header> <dispatcher template> <calls> <dispatcher>\n" "Usage: gensyscalls <header> <calls> <dispatcher>\n"
"\n"
"Given the (preprocessed) header file that defines the syscall prototypes the\n"
"command generates a piece of assembly source file that defines the actual\n"
"syscalls and a piece of C source (cases of a switch statement) for the \n"
"kernel syscall dispatcher. Either file is to be included from a respective\n"
"skeleton source file.\n"
"\n" "\n"
" <header> - Input: The preprocessed header file with the\n" " <header> - Input: The preprocessed header file with the\n"
" syscall prototypes.\n" " syscall prototypes.\n"
" <dispatcher template> - Input: A template used to generate the syscall\n"
" dispatcher source file.\n"
" <calls> - Output: The assembly source file implementing the\n" " <calls> - Output: The assembly source file implementing the\n"
" actual syscalls." " actual syscalls."
" <dispatcher> - Output: The syscall dispatcher source file.\n"; " <dispatcher> - Output: The C source file to be included by the\n"
" syscall dispatcher source file.\n";
// print_usage // print_usage
static static
@@ -80,12 +85,28 @@ public:
return fReturnType; return fReturnType;
} }
private: protected:
string fName; string fName;
vector<Type> fParameters; vector<Type> fParameters;
Type fReturnType; Type fReturnType;
}; };
// Syscall
class Syscall : public Function {
public:
string GetKernelName() const
{
int baseIndex = 0;
if (fName.find("_kern_") == 0)
baseIndex = strlen("_kern_");
else if (fName.find("sys_") == 0)
baseIndex = strlen("sys_");
string kernelName("_user_");
kernelName.append(string(fName, baseIndex));
return kernelName;
}
};
// Exception // Exception
struct Exception : exception { struct Exception : exception {
Exception() Exception()
@@ -168,7 +189,6 @@ public:
fHasCurrent = true; fHasCurrent = true;
if (skippedTokens) if (skippedTokens)
skippedTokens->push(fTokens.front()); skippedTokens->push(fTokens.front());
printf("next token: `%s'\n", fTokens.front().c_str());
return fTokens.front(); return fTokens.front();
} }
@@ -290,38 +310,26 @@ public:
print_usage(false); print_usage(false);
return 0; return 0;
} }
if (argc != 5) { if (argc != 4) {
print_usage(true); print_usage(true);
return 1; return 1;
} }
// fDispatcherTemplateFile = argv[2]; _ParseSyscalls(argv[1]);
// fCallsFile = argv[3]; _WriteSyscallsFile(argv[2]);
// fDispatcherFile = argv[4]; _WriteDispatcherFile(argv[3]);
// open the files
fHeaderFile.open(argv[1], ifstream::in);
if (!fHeaderFile.is_open())
throw new IOException(string("Failed to open `") + argv[1] + "'.");
// parse the syscalls
vector<Function> syscalls;
_ParseSyscalls(syscalls);
for (int i = 0; i < (int)syscalls.size(); i++) {
const Function &syscall = syscalls[i];
printf("syscall: `%s'\n", syscall.GetName().c_str());
for (int k = 0; k < (int)syscall.CountParameters(); k++)
printf(" arg: `%s'\n", syscall.ParameterAt(k).type.c_str());
printf(" return type: `%s'\n",
syscall.GetReturnType().type.c_str());
}
printf("Found %lu syscalls.\n", syscalls.size());
return 0; return 0;
} }
private: private:
void _ParseSyscalls(vector<Function> &syscalls) void _ParseSyscalls(const char *filename)
{ {
Tokenizer tokenizer(fHeaderFile); // open the input file
ifstream file(filename, ifstream::in);
if (!file.is_open())
throw new IOException(string("Failed to open `") + filename + "'.");
// parse the syscalls
Tokenizer tokenizer(file);
// find "#pragma syscalls begin" // find "#pragma syscalls begin"
while (true) { while (true) {
while (tokenizer.GetNextToken() != "#"); while (tokenizer.GetNextToken() != "#");
@@ -335,17 +343,65 @@ private:
} }
// parse the functions // parse the functions
while (!tokenizer.CheckNextToken("#")) { while (!tokenizer.CheckNextToken("#")) {
Function syscall; Syscall syscall;
_ParseSyscall(tokenizer, syscall); _ParseSyscall(tokenizer, syscall);
syscalls.push_back(syscall); fSyscalls.push_back(syscall);
} }
// expect "pragma syscalls end" // expect "pragma syscalls end"
tokenizer.ExpectNextToken("pragma"); tokenizer.ExpectNextToken("pragma");
tokenizer.ExpectNextToken("syscalls"); tokenizer.ExpectNextToken("syscalls");
tokenizer.ExpectNextToken("end"); tokenizer.ExpectNextToken("end");
// for (int i = 0; i < (int)fSyscalls.size(); i++) {
// const Syscall &syscall = fSyscalls[i];
// printf("syscall: `%s'\n", syscall.GetName().c_str());
// for (int k = 0; k < (int)syscall.CountParameters(); k++)
// printf(" arg: `%s'\n", syscall.ParameterAt(k).type.c_str());
// printf(" return type: `%s'\n",
// syscall.GetReturnType().type.c_str());
// }
// printf("Found %lu syscalls.\n", fSyscalls.size());
} }
void _ParseSyscall(Tokenizer &tokenizer, Function &syscall) void _WriteSyscallsFile(const char *filename)
{
// open the syscalls output file
ofstream file(filename, ofstream::out | ofstream::trunc);
if (!file.is_open())
throw new IOException(string("Failed to open `") + filename + "'.");
// output the syscalls definitions
for (int i = 0; i < (int)fSyscalls.size(); i++) {
const Syscall &syscall = fSyscalls[i];
file << "SYSCALL" << syscall.CountParameters() << "("
<< syscall.GetName() << ", " << i << ")" << endl;
}
}
void _WriteDispatcherFile(const char *filename)
{
// open the dispatcher output file
ofstream file(filename, ofstream::out | ofstream::trunc);
if (!file.is_open())
throw new IOException(string("Failed to open `") + filename + "'.");
// output the case statements
for (int i = 0; i < (int)fSyscalls.size(); i++) {
const Syscall &syscall = fSyscalls[i];
file << "case " << i << ":" << endl;
file << "\t";
if (syscall.GetReturnType().type != "void")
file << "*call_ret = ";
file << syscall.GetKernelName() << "(";
if (syscall.CountParameters() > 0) {
file << "(" << syscall.ParameterAt(0).type << ")arg0";
for (int k = 1; k < (int)syscall.CountParameters(); k++)
file << ", (" << syscall.ParameterAt(k).type << ")arg" << k;
}
file << ");" << endl;
file << "\tbreak;" << endl;
}
}
void _ParseSyscall(Tokenizer &tokenizer, Syscall &syscall)
{ {
// get return type and function name // get return type and function name
vector<string> returnType; vector<string> returnType;
@@ -378,7 +434,7 @@ private:
tokenizer.ExpectNextToken(";"); tokenizer.ExpectNextToken(";");
} }
void _ParseParameter(Tokenizer &tokenizer, Function &syscall) void _ParseParameter(Tokenizer &tokenizer, Syscall &syscall)
{ {
vector<string> type; vector<string> type;
while (tokenizer.GetNextToken() != ")" while (tokenizer.GetNextToken() != ")"
@@ -410,7 +466,7 @@ private:
syscall.AddParameter(typeString); syscall.AddParameter(typeString);
} }
void _ParseFunctionPointerParameter(Tokenizer &tokenizer, Function &syscall, void _ParseFunctionPointerParameter(Tokenizer &tokenizer, Syscall &syscall,
vector<string> &type) vector<string> &type)
{ {
// When this method is entered, the return type and the opening // When this method is entered, the return type and the opening
@@ -445,10 +501,7 @@ private:
} }
private: private:
ifstream fHeaderFile; vector<Syscall> fSyscalls;
const char *fDispatcherTemplateFile;
const char *fCallsFile;
const char *fDispatcherFile;
}; };