#ifndef COMMON_H #define COMMON_H #include #include #include #include #include #include "Logger.h" using namespace Upp; int CharFilterCid(int c); int ReadLNG(CParser& p); String MakeLNG(int lang); bool OldLang(); String PrintTime(int msecs); inline String GetPrintTime(dword time0) { return PrintTime(msecs() - time0); } bool SaveChangedFile(const char *path, String data, bool delete_empty = false); bool IsDoc(String s); void CopyFile(const String& dst, const String& src, bool brc = false); void CopyFolder(const char *_dst, const char *_src, Index& used, bool all, bool brc = false); class Workspace; struct Ide; namespace Upp { class Ctrl; class Image; } String CacheDir(); String CacheFile(const char *name); void ReduceCache(); void ReduceCache(int mb_limit); void ReduceCacheFolder(const char *path, int64 max_total); class Hdepend { // to be replaced by PPInfo struct Info { Time time; Vector depend; Vector bydefine; Index macroinclude; // includes by macro, like #include LAYOUTFILE Vector define; bool flag; bool macroflag; // prevent infinite recursion in GetMacroIndex bool timedirty; bool guarded; // has guards or BLITZ_APPROVED bool blitzprohibit; // has BLITZ_PROHIBIT bool CanBlitz() { return guarded && !blitzprohibit; } void Serialize(Stream& s); Info() { time = Null; flag = false; timedirty = true; guarded = false; } }; ArrayMap map; Vector incdir; // include directories VectorMap > depends; // externally forced dependecies bool console = true; void Include(const char *trm, Info& info, const String& filedir, bool bydefine); void ScanFile(const String& path, int map_index); int File(const String& path); Time FileTime(int i); void ClearFlag(); void ClearMacroFlag(); void GetMacroIndex(Index& dest, int ix); public: void SetDirs(Vector&& id); void SetDirs(const String& includes); void TimeDirty(); void ClearDependencies() { depends.Clear(); } void AddDependency(const String& file, const String& depends); Time FileTime(const String& path); bool BlitzApproved(const String& path); static String FindIncludeFile(const char *s, const String& filedir, const Vector& incdirs); String FindIncludeFile(const char *s, const String& filedir) { return FindIncludeFile(s, filedir, incdir); } const Vector& GetDefines(const String& path); Vector GetDependencies(const String& path, bool bydefine_too = true); const Vector& GetAllFiles() { return map.GetKeys(); } void NoConsole() { console = false; } void Serialize(Stream& s); }; class PPInfo { enum { AUTO, APPROVED, PROHIBITED }; struct PPFile : Moveable { int scan_serial = 0; Vector> flags; // "#if... flagXXXX" VectorMap defines; // #define ... Index includes[2]; // 1 - speculative includes Index define_includes[2]; // #define LAYOUTFILE bool guarded; // has include guards int blitz; // AUTO, APPROVED, PROHIBITED Time time = Null; // file time bool dirty = true; // need to be rechecked void Dirty() { dirty = true; time = Null; } void Parse(Stream& in); void Serialize(Stream& s); }; ArrayMap files; Vector includes; // include dirs VectorMap inc_cache; // cache for FindIncludeFile VectorMap> dir_cache; // cache for GetFileTime, FileExists static std::atomic scan_serial; PPFile& File(const String& path); public: static void RescanAll() { scan_serial++; } Event WhenBlitzBlock; Time GetFileTime(const String& path); bool FileExists(const String& path) { return !IsNull(GetFileTime(path)); } void SetIncludes(const String& includes); String FindIncludeFile(const char *s, const String& filedir, const Vector& incdirs); String FindIncludeFile(const char *s, const String& filedir); bool BlitzApproved(const String& path); Time GatherDependencies(const String& path, VectorMap& result, ArrayMap>& define_includes, Vector>& flags, bool speculative = true); void GatherDependencies(const String& path, VectorMap& result, ArrayMap>& define_includes, bool speculative = true); Time GetTime(const String& path); const VectorMap& GetFileDefines(const String& path) { return File(NormalizePath(path)).defines; } const Vector>& GetFileFlags(const String& path) { return File(NormalizePath(path)).flags; } void Dirty(); }; class IdeContext { public: virtual bool IsVerbose() const = 0; virtual void PutConsole(const char *s) = 0; virtual void PutVerbose(const char *s) = 0; virtual void PutLinking() = 0; virtual void PutLinkingEnd(bool ok) = 0; virtual const Workspace& IdeWorkspace() const = 0; virtual bool IdeIsBuilding() const = 0; virtual String IdeGetOneFile() const = 0; virtual int IdeConsoleExecute(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false, bool noconvert = false) = 0; virtual int IdeConsoleExecuteWithInput(const char *cmdline, Stream *out, const char *envptr, bool quiet, bool noconvert = false) = 0; virtual int IdeConsoleExecute(One pick_ process, const char *cmdline, Stream *out = NULL, bool quiet = false) = 0; virtual int IdeConsoleAllocSlot() = 0; virtual bool IdeConsoleRun(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1) = 0; virtual bool IdeConsoleRun(One pick_ process, const char *cmdline, Stream *out = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1) = 0; virtual void IdeConsoleFlush() = 0; virtual void IdeConsoleBeginGroup(String group) = 0; virtual void IdeConsoleEndGroup() = 0; virtual bool IdeConsoleWait() = 0; virtual bool IdeConsoleWait(int slot) = 0; virtual void IdeConsoleOnFinish(Event<> cb) = 0; virtual void IdeProcessEvents() = 0; virtual bool IdeIsDebug() const = 0; virtual void IdeEndDebug() = 0; virtual void IdeSetBottom(Ctrl& ctrl) = 0; virtual void IdeActivateBottom() = 0; virtual void IdeRemoveBottom(Ctrl& ctrl) = 0; virtual void IdeSetRight(Ctrl& ctrl) = 0; virtual void IdeRemoveRight(Ctrl& ctrl) = 0; virtual String IdeGetFileName() const = 0; virtual int IdeGetFileLine() = 0; virtual String IdeGetLine(int i) const = 0; virtual void IdeSetDebugPos(const String& fn, int line, const Image& img, int i) = 0; virtual void IdeHidePtr() = 0; virtual bool IdeDebugLock() = 0; virtual bool IdeDebugUnLock() = 0; virtual bool IdeIsDebugLock() const = 0; virtual void IdeSetBar() = 0; virtual void IdeOpenTopicFile(const String& file) = 0; virtual void IdeFlushFile() = 0; virtual String IdeGetFileName() = 0; virtual String IdeGetNestFolder() = 0; virtual String IdeGetIncludePath() = 0; virtual String GetDefaultMethod(); virtual VectorMap GetMethodVars(const String& method); virtual String GetMethodName(const String& method); virtual bool IsPersistentFindReplace() = 0; virtual int IdeGetHydraThreads() = 0; virtual String IdeGetCurrentBuildMethod() = 0; virtual String IdeGetCurrentMainPackage() = 0; virtual void IdePutErrorLine(const String&) = 0; virtual ~IdeContext() {} }; IdeContext *TheIdeContext(); void SetTheIde(IdeContext *context); bool IsVerbose(); void PutConsole(const char *s); void PutVerbose(const char *s); void PutLinking(); void PutLinkingEnd(bool ok); const Workspace& GetIdeWorkspace(); bool IdeIsBuilding(); String IdeGetOneFile(); int IdeConsoleExecute(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false, bool noconvert = false); int IdeConsoleExecuteWithInput(const char *cmdline, Stream *out, const char *envptr, bool quiet, bool noconvert = false); int IdeConsoleExecute(One process, const char *cmdline, Stream *out = NULL, bool quiet = false); int IdeConsoleAllocSlot(); bool IdeConsoleRun(const char *cmdline, Stream *out = NULL, const char *envptr = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1); bool IdeConsoleRun(One pick_ process, const char *cmdline, Stream *out = NULL, bool quiet = false, int slot = 0, String key = Null, int blitz_count = 1); void IdeConsoleFlush(); void IdeConsoleBeginGroup(String group); void IdeConsoleEndGroup(); bool IdeConsoleWait(); bool IdeConsoleWait(int slot); void IdeConsoleOnFinish(Event<> cb); void IdeProcessEvents(); String GetSourcePackage(const String& path); String GetDefaultMethod(); VectorMap GetMethodVars(const String& method); String GetMethodPath(const String& method); bool IdeIsDebug(); void IdeEndDebug(); void IdeSetBottom(Ctrl& ctrl); void IdeActivateBottom(); void IdeRemoveBottom(Ctrl& ctrl); void IdeSetRight(Ctrl& ctrl); void IdeRemoveRight(Ctrl& ctrl); String IdeGetFileName(); int IdeGetFileLine(); String IdeGetLine(int i); void IdeSetDebugPos(const String& fn, int line, const Image& img, int i); void IdeHidePtr(); bool IdeDebugLock(); bool IdeDebugUnLock(); bool IdeIsDebugLock(); void IdeSetBar(); int IdeGetHydraThreads(); String IdeGetCurrentBuildMethod(); String IdeGetCurrentMainPackage(); void IdePutErrorLine(const String& s); #include "Host.h" struct IdeMacro { IdeMacro(); int hotkey; String menu; String submenu; EscValue code; }; ArrayMap& UscGlobal(); Array& UscMacros(); void UscSetCleanModules(void (*CleanModules)()); void SetIdeModuleUsc(bool (*IdeModuleUsc)(CParser& p,String&)); void UscSetReadMacro(void (*ReadMacro)(CParser& p)); void CleanUsc(); void ParseUscFile(const char *filename); Point ReadNums(CParser& p); Point ReadPoint(CParser& p); Vector SplitDirs(const char *s); class Nest { VectorMap var; VectorMap package_cache; String PackagePath0(const String& name); public: bool Save(const char *path); bool Load(const char *path); String Get(const String& id); void Set(const String& id, const String& val); void InvalidatePackageCache(); String PackagePath(const String& name); }; Nest& MainNest(); String DefaultHubFilePath(); void SetHubDir(const String& path); String GetHubDir(); bool InUppHub(const String& p); String VarFilePath(); String VarFilePath(String name); bool SaveVarFile(const char *filename, const VectorMap& var); bool LoadVarFile(const char *name, VectorMap& var); bool SaveVars(const char *name); bool LoadVars(const char *name); String GetVar(const String& var); String GetVarsName(); String VarFilePath(); Vector GetUppDirsRaw(); Vector GetUppDirs(); bool IsHubDir(const String& path); String GetUppDir(); void SetVar(const String& var, const String& val, bool save = true); void SetMainNest(const String& n); String GetAssemblyId(); String GetCurrentBuildMethod(); String GetCurrentMainPackage(); String GetAnyFileName(const char *path); String GetAnyFileTitle(const char *path); String CatAnyPath(String path, const char *more); void InvalidatePackageCache(); String PackagePath(const String& name); String SourcePath(const String& package, const String& name); inline String PackageDirectory(const String& name) { return GetFileDirectory(PackagePath(name)); } bool IsNestReadOnly(const String& path); String GetPackagePathNest(const String& path); String GetLocalDir(); String LocalPath(const String& filename); bool IsFullDirectory(const String& d); bool IsFolder(const String& path); bool IsCSourceFile(const char *path); bool IsCHeaderFile(const char *path); String FollowCygwinSymlink(const String& filename); void SplitPathMap(const char *path_map, Vector& local, Vector& remote); String JoinPathMap(const Vector& local, const Vector& remote); void SplitHostName(const char *hostname, String& host, int& port); Vector SplitFlags0(const char *flags); Vector SplitFlags(const char *flags, bool main = false); Vector SplitFlags(const char *flags, bool main, const Vector& accepts); bool MatchWhen(const String& when, const Vector& flag); String ReadWhen(CParser& p); String AsStringWhen(const String& when); struct OptItem { String when; String text; String ToString() const { return when + ": " + text ; } }; struct CustomStep { String when; String ext; String command; String output; void Load(CParser& p); String AsString() const; String GetExt() const; bool MatchExt(const char *fn) const; }; Vector Combine(const Vector& conf, const char *flags); String Gather(const Array& set, const Vector& conf, bool nospace = false); Vector GatherV(const Array& set, const Vector& conf); bool HasFlag(const Vector& conf, const char *flag); enum { FLAG_MISMATCH = -2, FLAG_UNDEFINED = -1, }; int GetType(const Vector& conf, const char *flags); int GetType(const Vector& conf, const char *flags, int def); bool GetFlag(const Vector& conf, const char *flag); String RemoveType(Vector& conf, const char *flags); enum IdeCharsets { CHARSET_UTF8_BOM = 250, // same as TextCtrl::CHARSET_UTF8_BOM; CtrlLib not included here CHARSET_UTF16_LE, CHARSET_UTF16_BE, CHARSET_UTF16_LE_BOM, CHARSET_UTF16_BE_BOM }; String ReadValue(CParser& p); class Package { void Reset(); void Option(bool& option, const char *name); public: struct File : public String { Array option; Array depends; bool readonly; bool separator; int tabsize; byte charset; int font; String highlight; bool pch, nopch, noblitz; int spellcheck_comments; void operator=(const String& s) { String::operator=(s); readonly = separator = false; } void Init() { readonly = separator = false; tabsize = Null; charset = 0; font = 0; pch = nopch = noblitz = false; spellcheck_comments = Null; } File() { Init(); } File(const String& s) : String(s) { Init(); } }; struct Config { String name; String param; }; byte charset; int tabsize; bool noblitz; bool nowarnings; String description; Vector accepts; Array flag; Array uses; Array target; Array library; Array static_library; Array link; Array option; Array include; Array pkg_config; Array file; Array config; Array custom; Time time; bool bold, italic; Color ink; int spellcheck_comments; bool cr = false; int GetCount() const { return file.GetCount(); } File& operator[](int i) { return file[i]; } const File& operator[](int i) const { return file[i]; } bool Load(const char *path); bool Save(const char *file) const; static void SetPackageResolver(bool (*Resolve)(const String& error, const String& path, int line)); Package(); }; String IdeCharsetName(byte charset); class Workspace { void AddUses(Package& p, const Vector *flag); void AddLoad(const String& name); void Scan(const char *prjname, const Vector *flag); public: ArrayMap package; Vector use_order; void Clear() { package.Clear(); } String operator[](int i) const { return package.GetKey(i); } Package& GetPackage(int i) { return package[i]; } const Package& GetPackage(int i) const { return package[i]; } int GetCount() const { return package.GetCount(); } void Scan(const char *prjname) { Scan(prjname, nullptr); } void Scan(const char *prjname, const Vector& flag) { Scan(prjname, &flag); } Vector GetAllAccepts(int pk) const; void Dump(); }; struct Ide; String FindInDirs(const Vector& dir, const String& file); String FindCommand(const Vector& exedir, const String& cmdline); struct MakeFile { String outdir; String outfile; String output; String config; String install; String rules; String linkdep; String linkfiles; String linkfileend; }; String GetMakePath(String fn, bool win32); String AdjustMakePath(const char *fn); String Join(const String& a, const String& b, const char *sep = " "); String GetExeExt(); String NormalizeExePath(String exePath); String NormalizePathSeparator(String path); struct Builder { Host *host; Index config; String method; String compiler; String outdir; Vector include; Vector libpath; String target; String cpp_options; String c_options; String debug_options; String release_options; String common_link; String debug_link; String release_link; String version; String script; String mainpackage; bool doall; bool main_conf; bool allow_pch; FileTime start_time; Index pkg_config; // names of packages for pkg-config Vector CINC; Vector Macro; VectorMap tmpfilei; // for naming automatic response files static VectorMap cmdx_cache; // caching e.g. pkg-config String CmdX(const char *s); virtual bool BuildPackage(const String& package, Vector& linkfile, Vector& immfile, String& linkoptions, const Vector& all_uses, const Vector& all_libraries, int optimize) { return false; } virtual bool Link(const Vector& linkfile, const String& linkoptions, bool createmap) { return false; } virtual bool Preprocess(const String& package, const String& file, const String& result, bool asmout) { return false; } virtual void CleanPackage(const String& package, const String& outdir) {} virtual void AfterClean() {} virtual void AddFlags(Index& cfg) {} virtual void AddMakeFile(MakeFile& mfinfo, String package, const Vector& all_uses, const Vector& all_libraries, const Index& common_config, bool exporting) {} virtual void AddCCJ(MakeFile& mfinfo, String package, const Index& common_config, bool exporting, bool last_ws) {} virtual String GetTargetExt() const = 0; virtual void SaveBuildInfo(const String& package) {} Builder() { doall = false; main_conf = false; } virtual ~Builder() {} void ChDir(const String& path); String GetPathQ(const String& path) const; Vector GetFileInfo(const Vector& path) const; Host::FileInfo GetFileInfo(const String& path) const; Time GetFileTime(const String& path) const; int Execute(const char *cmdline); int Execute(const char *cl, Stream& out); bool HasFlag(const char *f) const { return config.Find(f) >= 0; } }; VectorMap& BuilderMap(); void RegisterBuilder(const char *name, Builder *(*create)()); void HdependSetDirs(Vector pick_ id); void HdependTimeDirty(); void HdependClearDependencies(); void HdependAddDependency(const String& file, const String& depends); Time HdependFileTime(const String& path); Vector HdependGetDependencies(const String& file, bool bydefine_too = true); bool HdependBlitzApproved(const String& path); const Vector& HdependGetDefines(const String& path); const Vector& HdependGetAllFiles(); bool IsHeaderExt(const String& ext); class BinObjInfo { public: BinObjInfo(); void Parse(CParser& binscript, String base_dir); struct Block { Block() : index(-1), length(0), scriptline(-1), encoding(ENC_PLAIN), flags(0), offset(-1), len_meta_offset(-1) {} String ident; int index; String file; int length; int scriptline; int encoding; enum { ENC_PLAIN, ENC_ZIP, ENC_BZ2, ENC_LZ4, ENC_LZMA, ENC_ZSTD, }; int flags; enum { FLG_ARRAY = 0x01, FLG_MASK = 0x02, }; int offset; int off_meta_offset; int len_meta_offset; void Compress(String& data); }; VectorMap< String, ArrayMap > blocks; }; void RegisterPCHFile(const String& pch_file); void DeletePCHFiles(); String GetLineEndings(const String& data, const String& default_eol = "\r\n"); enum { NOT_REPO_DIR = 0, SVN_DIR, GIT_DIR }; int GetRepoKind(const String& p); int GetRepo(String& path); #endif