jtlc/main/jtlc.cc
josh 7b8436acb4 added Compiler class to pass to Node::process() instead of a FILE *
git-svn-id: svn://anubis/jtlc/trunk@22 f5bc74b8-7b62-4e90-9214-7121d538519f
2010-01-14 20:27:01 +00:00

107 lines
2.5 KiB
C++

#include <stdio.h> /* tmpfile() */
#include <stdlib.h> /* exit() */
#include <unistd.h> /* unlink() */
#include <sys/types.h>
#include <sys/wait.h> /* waitpid() */
#include <vector>
#include "util/refptr.h"
#include "parser/parser.h"
#include "nodes/Node.h"
using namespace std;
int usage();
string compile(const char * filename);
void ccompile(const char * c_file, const char * obj_file);
void link(vector<string> & obj_files, const char * out_file);
int usage()
{
fprintf(stderr, "Usage: jtlc [options] <source files>\n");
exit(42);
}
int main(int argc, char * argv[])
{
vector<const char *> source_files;
for (int i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
{
source_files.push_back(argv[i]);
}
}
if (source_files.size() < 1)
{
usage();
}
vector<string> obj_files;
for (int i = 0, num = source_files.size(); i < num; i++)
{
obj_files.push_back(compile(source_files[i]));
}
link(obj_files, "a.out");
return 0;
}
string compile(const char * filename)
{
string out_filename = string(filename) + ".c";
string obj_filename = string(filename) + ".o";
FILE * out = fopen(out_filename.c_str(), "w");
refptr<Node> tree = parse(filename);
refptr<Compiler> compiler = new Compiler(out);
tree->process(compiler);
fclose(out);
ccompile(out_filename.c_str(), obj_filename.c_str());
// unlink(out_filename.c_str());
return obj_filename;
}
void ccompile(const char * c_file, const char * obj_file)
{
int id = fork();
const char * const args[] = {"cc", "-c", "-o", obj_file, c_file, NULL};
if (id == 0)
{
execvp("cc", (char * const *) args);
}
else if (id > 0)
{
waitpid(id, NULL, 0);
}
}
void link(vector<string> & obj_files, const char * out_file)
{
vector<const char *> args;
args.push_back("-o");
args.push_back(out_file);
for (int i = 0, sz = obj_files.size(); i < sz; i++)
{
args.push_back(obj_files[i].c_str());
}
int sz = args.size();
const char ** args_static = new const char * [sz + 2];
args_static[0] = "cc";
for (int i = 0; i < sz; i++)
{
args_static[i + 1] = args[i];
}
args_static[sz + 1] = NULL;
int id = fork();
if (id == 0)
{
execvp("cc", (char * const *) args_static);
}
else if (id > 0)
{
waitpid(id, NULL, 0);
}
delete[] args_static;
}