#ifndef __NASAL_IMPORT_H__ #define __NASAL_IMPORT_H__ #ifdef _MSC_VER #define F_OK 0 #endif class nasal_import { private: bool show_path; bool lib_loaded; nasal_err& nerr; std::vector files; std::vector envpath; bool imptchk(const nasal_ast&); bool exist(const string&); void linker(nasal_ast&,nasal_ast&&); string path(const nasal_ast&); string findf(const string&); nasal_ast fimpt(nasal_ast&); nasal_ast libimpt(); nasal_ast load(nasal_ast&,u16); public: nasal_import(nasal_err&); void link(nasal_parse&,const string&,bool); const std::vector& filelist() const {return files;} }; nasal_import::nasal_import(nasal_err& e):lib_loaded(false),nerr(e){ #ifdef _WIN32 char sep=';'; #else char sep=':'; #endif string PATH=getenv("PATH"); usize last=0,pos=PATH.find(sep,0); while(pos!=string::npos) { string dirpath=PATH.substr(last,pos-last); if(dirpath.length()) envpath.push_back(dirpath); last=pos+1; pos=PATH.find(sep,last); } if(last!=PATH.length()) envpath.push_back(PATH.substr(last)); } string nasal_import::path(const nasal_ast& node) { if(node[1].type()==ast_callf) return node[1][0].str(); string fpath="."; for(usize i=1;i filepath={fname}; for(auto&p:envpath) { #ifdef _WIN32 filepath.push_back(p+"\\"+fname); #else filepath.push_back(p+"/"+fname); #endif } for(auto& i:filepath) if(access(i.c_str(),F_OK)!=-1) return i; if(fname=="lib.nas") #ifdef _WIN32 return findf("stl\\lib.nas"); #else return findf("stl/lib.nas"); #endif if(!show_path) { nerr.err("link","cannot find file <"+fname+">"); return ""; } string paths=""; for(auto& i:filepath) paths+=" "+i+"\n"; nerr.err("link","cannot find file <"+fname+"> in these paths:\n"+paths); return ""; } bool nasal_import::imptchk(const nasal_ast& node) { // only these two kinds of node can be recognized as 'import': /* call |_id:import |_callh:stl |_callh:file */ if(node.type()==ast_call && node[0].str()=="import" && node.size()>=2 && node[1].type()==ast_callh) { for(usize i=1;i