107 lines
2.5 KiB
C++
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;
|
|
}
|