add namespace fs

This commit is contained in:
ValKmjolnir 2023-12-03 21:14:14 +08:00
parent 2c03d59b6f
commit 3b1659e7ee
8 changed files with 80 additions and 24 deletions

View File

@ -1,9 +1,5 @@
#include "io_lib.h"
#ifdef _MSC_VER
#define F_OK 0 // fuck msc
#endif
#include <sys/stat.h>
namespace nasal {
@ -47,7 +43,7 @@ var builtin_exists(context* ctx, gc* ngc) {
if (!filename.is_str()) {
return zero;
}
return access(filename.str().c_str(), F_OK)!=-1? one:zero;
return fs::exists(filename.str())? one:zero;
}
var builtin_open(context* ctx, gc* ngc) {

View File

@ -29,6 +29,7 @@ const u32 VM_DEBUG = 1<<6;
const u32 VM_SYMINFO = 1<<7;
const u32 VM_PROFILE = 1<<8;
const u32 VM_PROF_ALL = 1<<9;
const u32 VM_REF_FILE = 1<<10;
std::ostream& help(std::ostream& out) {
out
@ -53,6 +54,7 @@ std::ostream& help(std::ostream& out) {
<< " -e, --exec | execute directly.\n"
<< " -t, --time | show execute time.\n"
<< " -d, --detail | get detail info.\n"
<< " -f, --ref-file | get referenced files.\n"
<< " -dbg, --debug | debug mode.\n"
<< " --prof | show profiling result, available in debug mode.\n"
<< " --prof-all | show profiling result of all files,"
@ -131,6 +133,14 @@ void execute(
// linker gets parser's ast and load import files to this ast
ld.link(parse, file, cmd&VM_DETAIL).chkerr();
if (cmd&VM_REF_FILE) {
if (ld.get_file_list().size()) {
std::cout << "referenced file(s):\n";
}
for(const auto& file: ld.get_file_list()) {
std::cout << " " << file << "\n";
}
}
// optimizer does simple optimization on ast
auto opt = std::unique_ptr<nasal::optimizer>(new nasal::optimizer);
@ -211,7 +221,9 @@ i32 main(i32 argc, const char* argv[]) {
{"--debug", VM_DEBUG},
{"-dbg", VM_DEBUG},
{"--prof", VM_PROFILE},
{"--prof-all", VM_PROF_ALL}
{"--prof-all", VM_PROF_ALL},
{"-f", VM_REF_FILE},
{"--ref-file", VM_REF_FILE}
};
u32 cmd = 0;
std::string filename = "";

View File

@ -41,7 +41,6 @@ const u32 STACK_DEPTH = 4096;
f64 hex2f(const char*);
f64 oct2f(const char*);
// we have the same reason not using atof here
// just as andy's interpreter does.
// it is not platform independent, and may have strange output.
@ -55,4 +54,27 @@ i32 utf8_hdchk(const char);
std::string chrhex(const char);
std::string rawstr(const std::string&, const usize maxlen = 0);
namespace fs {
class path {
private:
std::string file_system_path;
public:
path(const path&) = default;
path(const std::string& file_path): file_system_path(file_path) {}
path& operator/(const path&);
const char* c_str() const {
return file_system_path.c_str();
}
std::string str() const {
return file_system_path;
}
};
bool exists(const path&);
bool is_regular(const path&);
}
}

View File

@ -4,14 +4,10 @@
#include <memory>
#include <unordered_set>
#ifdef _MSC_VER
#define F_OK 0 // fuck msc
#endif
namespace nasal {
linker::linker(): show_path_flag(false), library_loaded(false), this_file("") {
const auto seperator= is_windows()? ';':':';
const auto seperator = is_windows()? ';':':';
const auto PATH = std::string(getenv("PATH"));
usize last = 0, position = PATH.find(seperator, 0);
while(position!=std::string::npos) {
@ -48,17 +44,17 @@ std::string linker::get_path(expr* node) {
std::string linker::find_real_file_path(
const std::string& filename, const span& location) {
// first add file name itself into the file path
std::vector<std::string> path_list = {filename};
std::vector<fs::path> path_list = {filename};
// generate search path from environ path
for(const auto& p : envpath) {
path_list.push_back(p + (is_windows()? "\\":"/") + filename);
path_list.push_back(fs::path(p)/filename);
}
// search file
for(const auto& path : path_list) {
if (access(path.c_str(), F_OK)!=-1) {
return path;
if (fs::exists(path)) {
return path.str();
}
}
@ -78,7 +74,7 @@ std::string linker::find_real_file_path(
}
auto path_list_info = std::string("");
for(const auto& path : path_list) {
path_list_info += " -> " + path + "\n";
path_list_info += " -> " + path.str() + "\n";
}
err.err("link",
"in <" + location.file + ">: " +

View File

@ -29,7 +29,7 @@ private:
error err;
std::vector<std::string> imported_files;
std::vector<std::string> module_load_stack;
std::vector<std::string> envpath;
std::vector<fs::path> envpath;
private:
bool import_check(expr*);

View File

@ -76,11 +76,7 @@ void lexer::open(const std::string& file) {
}
// check file exsits and it is a regular file
#ifdef _MSC_VER
#define S_ISREG(m) (((m)&0xF000)==0x8000)
#endif
struct stat buffer;
if (stat(file.c_str(), &buffer)==0 && !S_ISREG(buffer.st_mode)) {
if (!fs::is_regular(file)) {
err.err("lexer", "<"+file+"> is not a regular file");
err.chkerr();
}

View File

@ -10,7 +10,6 @@
#include <sstream>
#include <vector>
#include <unordered_map>
#include <sys/stat.h>
#include "nasal.h"
#include "nasal_err.h"

View File

@ -1,5 +1,12 @@
#include "nasal.h"
#ifndef _MSC_VER
#include <unistd.h>
#else
#include <io.h>
#endif
#include <sys/stat.h>
namespace nasal {
bool is_windows() {
@ -234,4 +241,32 @@ std::string rawstr(const std::string& str, const usize maxlen) {
return ret;
}
namespace fs {
path& path::operator/(const path& another) {
this->file_system_path += is_windows()? "\\":"/";
this->file_system_path += another.file_system_path;
return *this;
}
bool exists(const path& file_path) {
#ifdef _MSC_VER
#define F_OK 0 // fuck msc
#endif
return access(file_path.c_str(), F_OK)==0;
}
bool is_regular(const path& file_path) {
#ifdef _MSC_VER
#define S_ISREG(m) (((m)&0xF000)==0x8000)
#endif
struct stat buffer;
if (stat(file_path.c_str(), &buffer)!=0) {
return false;
}
return S_ISREG(buffer.st_mode);
}
}
}