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" #include "io_lib.h"
#ifdef _MSC_VER
#define F_OK 0 // fuck msc
#endif
#include <sys/stat.h> #include <sys/stat.h>
namespace nasal { namespace nasal {
@ -47,7 +43,7 @@ var builtin_exists(context* ctx, gc* ngc) {
if (!filename.is_str()) { if (!filename.is_str()) {
return zero; 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) { 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_SYMINFO = 1<<7;
const u32 VM_PROFILE = 1<<8; const u32 VM_PROFILE = 1<<8;
const u32 VM_PROF_ALL = 1<<9; const u32 VM_PROF_ALL = 1<<9;
const u32 VM_REF_FILE = 1<<10;
std::ostream& help(std::ostream& out) { std::ostream& help(std::ostream& out) {
out out
@ -53,6 +54,7 @@ std::ostream& help(std::ostream& out) {
<< " -e, --exec | execute directly.\n" << " -e, --exec | execute directly.\n"
<< " -t, --time | show execute time.\n" << " -t, --time | show execute time.\n"
<< " -d, --detail | get detail info.\n" << " -d, --detail | get detail info.\n"
<< " -f, --ref-file | get referenced files.\n"
<< " -dbg, --debug | debug mode.\n" << " -dbg, --debug | debug mode.\n"
<< " --prof | show profiling result, available in debug mode.\n" << " --prof | show profiling result, available in debug mode.\n"
<< " --prof-all | show profiling result of all files," << " --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 // linker gets parser's ast and load import files to this ast
ld.link(parse, file, cmd&VM_DETAIL).chkerr(); 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 // optimizer does simple optimization on ast
auto opt = std::unique_ptr<nasal::optimizer>(new nasal::optimizer); auto opt = std::unique_ptr<nasal::optimizer>(new nasal::optimizer);
@ -211,7 +221,9 @@ i32 main(i32 argc, const char* argv[]) {
{"--debug", VM_DEBUG}, {"--debug", VM_DEBUG},
{"-dbg", VM_DEBUG}, {"-dbg", VM_DEBUG},
{"--prof", VM_PROFILE}, {"--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; u32 cmd = 0;
std::string filename = ""; std::string filename = "";

View File

@ -41,7 +41,6 @@ const u32 STACK_DEPTH = 4096;
f64 hex2f(const char*); f64 hex2f(const char*);
f64 oct2f(const char*); f64 oct2f(const char*);
// we have the same reason not using atof here // we have the same reason not using atof here
// just as andy's interpreter does. // just as andy's interpreter does.
// it is not platform independent, and may have strange output. // 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 chrhex(const char);
std::string rawstr(const std::string&, const usize maxlen = 0); 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,10 +4,6 @@
#include <memory> #include <memory>
#include <unordered_set> #include <unordered_set>
#ifdef _MSC_VER
#define F_OK 0 // fuck msc
#endif
namespace nasal { namespace nasal {
linker::linker(): show_path_flag(false), library_loaded(false), this_file("") { linker::linker(): show_path_flag(false), library_loaded(false), this_file("") {
@ -48,17 +44,17 @@ std::string linker::get_path(expr* node) {
std::string linker::find_real_file_path( std::string linker::find_real_file_path(
const std::string& filename, const span& location) { const std::string& filename, const span& location) {
// first add file name itself into the file path // 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 // generate search path from environ path
for(const auto& p : envpath) { for(const auto& p : envpath) {
path_list.push_back(p + (is_windows()? "\\":"/") + filename); path_list.push_back(fs::path(p)/filename);
} }
// search file // search file
for(const auto& path : path_list) { for(const auto& path : path_list) {
if (access(path.c_str(), F_OK)!=-1) { if (fs::exists(path)) {
return path; return path.str();
} }
} }
@ -78,7 +74,7 @@ std::string linker::find_real_file_path(
} }
auto path_list_info = std::string(""); auto path_list_info = std::string("");
for(const auto& path : path_list) { for(const auto& path : path_list) {
path_list_info += " -> " + path + "\n"; path_list_info += " -> " + path.str() + "\n";
} }
err.err("link", err.err("link",
"in <" + location.file + ">: " + "in <" + location.file + ">: " +

View File

@ -29,7 +29,7 @@ private:
error err; error err;
std::vector<std::string> imported_files; std::vector<std::string> imported_files;
std::vector<std::string> module_load_stack; std::vector<std::string> module_load_stack;
std::vector<std::string> envpath; std::vector<fs::path> envpath;
private: private:
bool import_check(expr*); 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 // check file exsits and it is a regular file
#ifdef _MSC_VER if (!fs::is_regular(file)) {
#define S_ISREG(m) (((m)&0xF000)==0x8000)
#endif
struct stat buffer;
if (stat(file.c_str(), &buffer)==0 && !S_ISREG(buffer.st_mode)) {
err.err("lexer", "<"+file+"> is not a regular file"); err.err("lexer", "<"+file+"> is not a regular file");
err.chkerr(); err.chkerr();
} }

View File

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

View File

@ -1,5 +1,12 @@
#include "nasal.h" #include "nasal.h"
#ifndef _MSC_VER
#include <unistd.h>
#else
#include <io.h>
#endif
#include <sys/stat.h>
namespace nasal { namespace nasal {
bool is_windows() { bool is_windows() {
@ -234,4 +241,32 @@ std::string rawstr(const std::string& str, const usize maxlen) {
return ret; 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);
}
}
} }