Skip to content

Commit

Permalink
Add support for multiple paths for searching compiler files.
Browse files Browse the repository at this point in the history
This also adds support for the `FASTBASIC_HOME` environment variable,
fixes #67.
  • Loading branch information
dmsc committed Dec 30, 2024
1 parent 6366fcc commit f276025
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 19 deletions.
20 changes: 16 additions & 4 deletions compiler/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,12 @@ The compilation is a three step process:

- The compiler calls the `CA65` assembler to produce an object file.

- The compiler calls the `LD65` linker to join the object file with the runtime library, generating the `XEX`, `ROM` or `BIN` depending on the target.
- The compiler calls the `LD65` linker to join the object file with the runtime
library, generating the `XEX`, `ROM` or `BIN` depending on the target.

- To search the target, syntax, libraries and other tools, the compiler
searches in the installation path and in the path in the `FASTBASIC_HOME`
environment variable.


Advanced Usage
Expand Down Expand Up @@ -187,11 +192,18 @@ an `:` or an `=` to separate the option from the argument.
target will produce a 16kB cartridge binary instead of the 32kB default.

- **-target-path**:*path*
Sets the path where the target definition files are searched. The default is
to search in the same folder as the compiler executable.
Sets the list of paths where the target definition files are searched, as a
list of folder names separated by `:`.

The default is to search in the same folder as the compiler executable, and
in the path in the `FASTBASIC_HOME` environment variable.

- **-syntax-path**:*path*
Sets the path where the syntax grammar files are searched.
Sets the list of paths where the syntax grammar files are searched, as a list
of folder names separated by `:`.

The default path is the same as the target path with `syntax` folder at the
end.

- **-keep**
Do not remove the intermediate files on compilation.
Expand Down
26 changes: 22 additions & 4 deletions src/compiler/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,32 @@ static std::string to_lower(std::string in)
return ret;
}

// Parse path list into a vector of strings
static std::vector<std::string> parse_path_list(const std::string &str)
{
std::vector<std::string> ret;
size_t pos = 0;
while(1)
{
auto nxt = str.find(':', pos);
if(nxt == str.npos)
{
ret.emplace_back(str.substr(pos));
return ret;
}
ret.emplace_back(str.substr(pos, nxt - pos));
pos = nxt + 1;
}
}

int main(int argc, char **argv)
{
// OS specific initializations
os::init(argv[0]);

// Default folders for target and syntax files
auto syntax_folder = os::compiler_path("syntax");
auto target_folder = os::compiler_path("");
auto syntax_folder = os::get_search_path("syntax");
auto target_folder = os::get_search_path("");
std::vector<std::string> args(argv + 1, argv + argc);
std::string out_name;
std::string exe_name;
Expand Down Expand Up @@ -217,11 +235,11 @@ int main(int argc, char **argv)
}
else if(arg.rfind("-syntax-path:", 0) == 0 || arg.rfind("-syntax-path=", 0) == 0)
{
syntax_folder = arg.substr(13);
syntax_folder = parse_path_list(arg.substr(13));
}
else if(arg.rfind("-target-path:", 0) == 0 || arg.rfind("-target-path=", 0) == 0)
{
target_folder = arg.substr(13);
target_folder = parse_path_list(arg.substr(13));
}
else if(arg[0] == '-')
return show_error("invalid option '" + arg + "', try -h for help");
Expand Down
45 changes: 41 additions & 4 deletions src/compiler/os.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// os.cc: Host OS functions
#include "os.h"
#include <memory>
#include <sys/stat.h>

#ifdef _WIN32
#include <windows.h>
Expand All @@ -33,7 +34,7 @@ static const char *path_sep = "\\/";
static const char *path_sep = "/";
#endif

static std::string compiler_search_path;
static std::vector<std::string> compiler_search_path;

bool os::path_absolute(const std::string &path)
{
Expand Down Expand Up @@ -110,13 +111,49 @@ void os::init(const std::string &prog)
#else
// No init needed.
#endif
// Store out program name
compiler_search_path = dir_name(prog);
// Initialize the compiler search path:
// The FASTBASIC_HOME environment variable:
const char *env = getenv("FASTBASIC_HOME");
if(env)
compiler_search_path.emplace_back(env);
// The directory of the invoked program
compiler_search_path.emplace_back(dir_name(prog));
// And on Linux systems, the instalation path
#ifndef _WIN32
compiler_search_path.emplace_back("/usr/local/share/fastbasic");
compiler_search_path.emplace_back("/usr/share/fastbasic");
#endif
}

std::string os::search_path(const std::vector<std::string> &paths,
const std::string &filename)
{
// Check each possible path:
for(auto &path : paths)
{
struct stat st;
auto f = full_path(path, filename);
auto e = stat(f.c_str(), &st);
if(0 == e)
return f;
}
// Not found, return only file name
return filename;
}

std::string os::compiler_path(const std::string &filename)
{
return full_path(compiler_search_path, filename);
return search_path(compiler_search_path, filename);
}

std::vector<std::string> os::get_search_path(const std::string &filename)
{
if(filename.empty())
return compiler_search_path;
std::vector<std::string> ret;
for(auto &path : compiler_search_path)
ret.emplace_back(full_path(path, filename));
return ret;
}

int os::prog_exec(std::string exe, std::vector<std::string> &args)
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@

namespace os
{
// Returns the current compiler search path for the given base
std::vector<std::string> get_search_path(const std::string &filename);
// Locates a file or folder in the compiler data and
// returns the path
std::string compiler_path(const std::string &filename);
// Appends a file name to a path
std::string full_path(const std::string &path, const std::string &filename);
// Search a file in a list of paths
std::string search_path(const std::vector<std::string> &paths,
const std::string &filename);
// Returns the file name from a full path
std::string file_name(const std::string &path);
// Returns the directory name from a full path
Expand Down
13 changes: 7 additions & 6 deletions src/compiler/target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
class target_file
{
public:
std::string target_folder;
std::vector<std::string> target_path;
std::vector<std::string> slist;
std::vector<std::string> ca65_args;
std::string lib_name;
std::string cfg_name;
std::string bin_ext;
target_file(std::string target_folder) : target_folder(target_folder) {}
target_file(std::vector<std::string> target_path) : target_path(target_path) {}
void read_file(std::string fname);
};

Expand All @@ -61,7 +61,7 @@ void target_file::read_file(std::string fname)
fname = os::add_extension(fname, ".tgt");

if(!os::path_absolute(fname))
fname = os::full_path(target_folder, fname);
fname = os::search_path(target_path, fname);

std::ifstream f;
f.open(fname);
Expand Down Expand Up @@ -127,10 +127,11 @@ void target_file::read_file(std::string fname)

target::target() {}

void target::load(std::string target_folder, std::string syntax_folder, std::string fname)
void target::load(std::vector<std::string> target_path,
std::vector<std::string> syntax_path, std::string fname)
{
// Read target file
target_file f(target_folder);
target_file f(target_path);
f.read_file(fname);
lib_name = f.lib_name;
cfg_name = f.cfg_name;
Expand All @@ -143,7 +144,7 @@ void target::load(std::string target_folder, std::string syntax_folder, std::str
for(auto &name : f.slist)
{
std::ifstream ifile;
ifile.open(os::full_path(syntax_folder, name));
ifile.open(os::search_path(syntax_path, name));
if(!ifile.is_open())
throw std::runtime_error("can't open syntax file: '" + name + "'");
auto data = pre.read_input(ifile);
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class target

public:
target();
void load(std::string target_folder, std::string syntax_folder, std::string fname);
void load(std::vector<std::string> target_folder,
std::vector<std::string> syntax_folder, std::string fname);
const syntax::sm_list &sl() const { return s; }
std::string lib() const { return lib_name; }
std::string cfg() const { return cfg_name; }
Expand Down

0 comments on commit f276025

Please sign in to comment.