From 2886122156f032fa2713fdf24499b6eded88f8f3 Mon Sep 17 00:00:00 2001 From: koldo Date: Sat, 18 Sep 2010 14:25:39 +0000 Subject: [PATCH] Functions4U: Added functions. Changes in include org. git-svn-id: svn://ultimatepp.org/upp/trunk@2706 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/Functions4U/Functions4U.cpp | 181 +++-- bazaar/Functions4U/Functions4U.h | 1047 +++++++++++++------------- bazaar/Functions4U/GatherTpp.cpp | 684 ++++++++--------- bazaar/Functions4U/GatherTpp.h | 82 +- bazaar/Functions4U/SvgColors.cpp | 326 ++++---- bazaar/Functions4U/bsdiffwrapper.h | 7 +- bazaar/Functions4U/plugin/bsdiff.cpp | 2 +- 7 files changed, 1214 insertions(+), 1115 deletions(-) diff --git a/bazaar/Functions4U/Functions4U.cpp b/bazaar/Functions4U/Functions4U.cpp index c6ce2df79..7468854c3 100644 --- a/bazaar/Functions4U/Functions4U.cpp +++ b/bazaar/Functions4U/Functions4U.cpp @@ -1190,76 +1190,167 @@ bool DirectoryCopy_Each(const char *dir, const char *newPlace, String relPath) return true; } -bool DirectoryCopyX(const char *dir, const char *newPlace) -{ +bool DirectoryCopyX(const char *dir, const char *newPlace) { return DirectoryCopy_Each(dir, newPlace, ""); } -void SearchFile_Each(String dir, String condFile, String text, Array &files, Array &errorList) -{ +#if defined(__MINGW32__) + #define _SH_DENYNO 0x40 +#endif + +int FileCompare(const char *path1, const char *path2) { + int fp1; +#ifdef PLATFORM_POSIX + fp1 = open(ToSystemCharset(path1), O_RDONLY, S_IWRITE|S_IREAD); +#else + fp1 = _wsopen(ToSystemCharsetW(path1), O_RDONLY|O_BINARY, _SH_DENYNO, _S_IREAD|_S_IWRITE); +#endif + if (fp1 == -1) + return -1; + int fp2; +#ifdef PLATFORM_POSIX + fp2 = open(ToSystemCharset(path2), O_RDONLY, S_IWRITE|S_IREAD); +#else + fp2 = _wsopen(ToSystemCharsetW(path2), O_RDONLY|O_BINARY, _SH_DENYNO, _S_IREAD|_S_IWRITE); +#endif + if (fp2 == -1) { + close(fp1); + return -1; + } + Buffer c1(8192), c2(8192); + int ret = 0; + while (true) { + int n1 = read(fp1, c1, 8192); + int n2 = read(fp2, c2, 8192); + if (n1 == -1 || n2 == -1) { + ret = -1; + break; + } + if (n1 != n2) + break; + if (memcmp(c1, c2, n1) != 0) + break; + if (n1 == 0) { + ret = 1; + break; + } + } +#ifdef PLATFORM_POSIX + if (-1 == close(fp1)) + ret = -1; + if (-1 == close(fp2)) + ret = -1; +#else + if (-1 == _close(fp1)) + ret = -1; + if (-1 == _close(fp2)) + ret = -1; +#endif + return ret; +} + +int FindStringInFile(const char *file, const String text) { +#ifdef PLATFORM_POSIX + FILE *fp = fopen(file, "rb"); +#else + FILE *fp = _wfopen(String(file).ToWString(), L"rb"); +#endif + if (fp != NULL) { + int i = 0, c; + while ((c = fgetc(fp)) != EOF) { + if (c == text[i]) { + ++i; + if (i == text.GetCount()) + return 1; + } else { + if (i != 0) + fseek(fp, -(i-1), SEEK_CUR); + i = 0; + } + } + fclose(fp); + } else + return -1; + return 0; +} + +bool MatchPathName(const char *name, const Array &cond, const Array &ext) { + for (int i = 0; i < cond.GetCount(); ++i) { + if(!PatternMatch(cond[i], name)) + return false; + } + for (int i = 0; i < ext.GetCount(); ++i) { + if(PatternMatch(ext[i], name)) + return false; + } + return true; +} + +void SearchFile_Each(String dir, const Array &condFiles, const Array &condFolders, + const Array &extFiles, const Array &extFolders, + const String text, Array &files, Array &errorList) { FindFile ff; - if (ff.Search(AppendFileName(dir, condFile))) { + if (ff.Search(AppendFileName(dir, "*"))) { do { if(ff.IsFile()) { - String p = AppendFileName(dir, ff.GetName()); - if (text.IsEmpty()) - files.Add(p); - else { -#ifdef PLATFORM_POSIX - FILE *fp = fopen(p, "rb"); -#else - FILE *fp = _wfopen(p.ToWString(), L"rb"); -#endif - if (fp != NULL) { - int i = 0, c; - while ((c = fgetc(fp)) != EOF) { - if (c == text[i]) { - ++i; - if (i == text.GetCount()) { - files.Add(p); - break; - } - } else { - if (i != 0) - fseek(fp, -(i-1), SEEK_CUR); - i = 0; - } + String name = AppendFileName(dir, ff.GetName()); + if (MatchPathName(ff.GetName(), condFiles, extFiles)) { + if (text.IsEmpty()) + files.Add(name); + else { + switch(FindStringInFile(name, text)) { + case 1: files.Add(name); + break; + case -1:errorList.Add(AppendFileName(dir, ff.GetName()) + String(": ") + + t_("Impossible to open file")); + break; } - fclose(fp); - } else - errorList.Add(AppendFileName(dir, ff.GetName()) + String(": ") + t_("Impossible to open file")); + } + } + } else if(ff.IsDirectory()) { + String folder = ff.GetName(); + if (folder != "." && folder != "..") { + String name = AppendFileName(dir, folder); + if (MatchPathName(name, condFolders, extFolders)) + SearchFile_Each(name, condFiles, condFolders, extFiles, extFolders, text, files, errorList); } } } while (ff.Next()); } - ff.Search(AppendFileName(dir, "*")); - do { - String name = ff.GetName(); - if(ff.IsDirectory() && name != "." && name != "..") { - String p = AppendFileName(dir, name); - SearchFile_Each(p, condFile, text, files, errorList); - } - } while (ff.Next()); +} + +Array SearchFile(String dir, const Array &condFiles, const Array &condFolders, + const Array &extFiles, const Array &extFolders, + const String &text, Array &errorList) { + Array files; + errorList.Clear(); + + SearchFile_Each(dir, condFiles, condFolders, extFiles, extFolders, text, files, errorList); + + + return files; } Array SearchFile(String dir, String condFile, String text, Array &errorList) { - Array ret; + Array condFiles, condFolders, extFiles, extFolders, files; errorList.Clear(); - SearchFile_Each(dir, condFile, text, ret, errorList); + condFiles.Add(condFile); + SearchFile_Each(dir, condFiles, condFolders, extFiles, extFolders, text, files, errorList); - return ret; + return files; } Array SearchFile(String dir, String condFile, String text) { Array errorList; - Array ret; + Array condFiles, condFolders, extFiles, extFolders, files; - SearchFile_Each(dir, condFile, text, ret, errorList); + condFiles.Add(condFile); + SearchFile_Each(dir, condFiles, condFolders, extFiles, extFolders, text, files, errorList); - return ret; + return files; } bool fileDataSortAscending; diff --git a/bazaar/Functions4U/Functions4U.h b/bazaar/Functions4U/Functions4U.h index a2b7ade0d..b4724613a 100644 --- a/bazaar/Functions4U/Functions4U.h +++ b/bazaar/Functions4U/Functions4U.h @@ -1,520 +1,527 @@ -#ifndef _Functions4U_Functions4U_h -#define _Functions4U_Functions4U_h - -#include -#ifdef flagGUI -#include -#include -#include "GatherTpp.h" -#endif -#include "SvgColors.h" - -enum EXT_FILE_FLAGS {USE_TRASH_BIN = 1, - BROWSE_LINKS = 2, - DELETE_READ_ONLY = 4, - ASK_BEFORE_DELETE = 8 -}; - -bool LaunchFile(const char *file); - -bool FileCat(const char *file, const char *appendFile); - -bool FileStrAppend(const char *file, const char *str); -bool AppendFile(const char *filename, const char *str); - -String AppendFileName(const String& path1, const char *path2, const char *path3); - -inline String Trim(const String& s) {return TrimLeft(TrimRight(s));}; - -///////// -bool DirectoryExistsX(const char *path, int flags = 0); -/////////////////////////////// -bool DirectoryDeleteX(const char *path, int flags = 0); -bool DirectoryDeleteDeepX(const char *path, int flags = 0); -bool DeleteFolderDeepX(const char *dir, int flags = 0); -bool DirectoryCopyX(const char *dir, const char *newPlace); -bool DeleteFolderDeepWildcards(const char *dir, int flags = 0); -/////////////////////////////// - -bool UpperFolder(String folderName); -String GetUpperFolder(String folderName); -String GetNextFolder(String folder, String lastFolder); -String GetRealName(String fileName); - -//bool GetSymLinkPath(const char *linkPath, String &filePath); -bool IsSymLink(const char *path); - -bool CreateFolderDeep(const char *dir); - -///////// -bool FileMoveX(const char *oldpath, const char *newpath, int flags = 0); -bool FileDeleteX(const char *path, int flags = 0); -///////// - - -//bool FileSetReadOnly(const char *fileName, bool readOnly); -bool FileSetReadOnly(const char *fileName, bool usr, bool grp = false, bool oth = false); -bool IsReadOnly(const char *fileName, bool &usr, bool &grp, bool &oth); - -String LoadFile_Safe(String fileName); - -int64 GetLength(String fileDirName); -int64 GetDirectoryLength(String directoryName); - -/////////////////////////////// -Array SearchFile(String dir, String condFile, String text, Array &errorList);//, int flags = 0); -Array SearchFile(String dir, String condFile, String text = "");//, int flags = 0); -/////////////////////////////// - -bool FileToTrashBin(const char *path); -int64 TrashBinGetCount(); -bool TrashBinClear(); - -//String GetDesktopFolder(); -//String GetProgramsFolder(); -//String GetAppDataFolder(); -//String GetMusicFolder(); -//String GetPicturesFolder(); -//String GetVideoFolder(); -String GetPersonalFolder(); -//String GetTemplatesFolder(); -//String GetDownloadFolder(); -String GetRootFolder(); -String GetTempFolder(); -String GetOsFolder(); -String GetSystemFolder(); - - -struct FileData : Moveable { - bool isFolder; - String fileName; - String relFilename; - int64 length; - struct Upp::Time t; - int64 id; - - String ToString() const { return Format("%s %0n", fileName, length); } - - FileData(bool isFolder, String fileName, String relFilename, int64 length, struct Upp::Time t, uint64 id) : isFolder(isFolder), fileName(fileName), relFilename(relFilename), length(length), t(t), id(id) {} - FileData() {} -}; - -struct FileDiff { - char action; // 'n': New, 'u': Update, 'd': Delete, 'p': Problem - bool isFolder; - String relPath; - String fileName; - uint64 idMaster, idSecondary; - struct Upp::Time tMaster, tSecondary; - uint64 lengthMaster, lengthSecondary; -}; - -class ErrorHandling -{ -public: - void SetLastError(String _lastError) {lastError = _lastError;}; - String GetLastError() {return lastError;}; - -private: - String lastError; -}; - -class FileDiffArray; - -class FileDataArray : public ErrorHandling -{ -public: - FileDataArray(bool use = false, int fileFlags = 0); - bool Init(String folder, FileDataArray &orig, FileDiffArray &diff); - void Clear(); - bool Search(String dir, String condFile, bool recurse = false, String text = ""); - FileData& operator[](long i) {return fileList[i];} - long GetFileCount() {return fileCount;}; - long GetFolderCount() {return folderCount;}; - long GetCount() {return fileCount + folderCount;}; - int64 GetSize() {return fileSize;}; - inline bool UseId() {return useId;}; - void SortByName(bool ascending = true); - void SortByDate(bool ascending = true); - void SortBySize(bool ascending = true); - Array &GetLastError() {return errorList;}; - int Find(String &relFileName, String &fileName, bool isFolder); - int Find(FileDataArray &data, int id); - String FullFileName(int i) {return AppendFileName(basePath, fileList[i].fileName);}; - bool SaveFile(const char *fileName); - bool AppendFile(const char *fileName); - bool LoadFile(const char *fileName); - -private: - void Search_Each(String dir, String condFile, bool recurse, String text); - int64 GetFileId(String fileName); - String GetRelativePath(String fullPath); - String GetFileText(); - - Array fileList; - Array errorList; - String basePath; - long fileCount, folderCount; - int64 fileSize; - bool useId; - int fileFlags; -}; - -class FileDiffArray : public ErrorHandling -{ -public: - FileDiffArray(); - void Clear(); - FileDiff& operator[](long i) {return diffList[i];} - bool Compare(FileDataArray &master, FileDataArray &secondary, String &folderFrom, Array &excepFolders, Array &excepFiles); - bool Apply(String toFolder, String fromFolder, int flags = 0); - long GetCount() {return diffList.GetCount();}; - bool SaveFile(const char *fileName); - bool LoadFile(const char *fileName); - String ToString(); - -private: - Array diffList; -}; - - -String Replace(String str, String find, String replace); -String Replace(String str, char find, char replace); - -int ReverseFind(const String& s, const String& toFind, int from = 0); - -String FormatLong(long a); - -const char *StrToTime(struct Upp::Time& d, const char *s); -::Time StrToTime(const char *s); -::Date StrToDate(const char *s); - -String BytesToString(uint64 bytes); - -String SecondsToString(double seconds, bool units = false); -String HMSToString(int hour, int min, double seconds, bool units = false); -double StringToSeconds(String str); // The opposite -void StringToHMS(String durat, int &hour, int &min, double &seconds); - -String FormatDoubleAdjust(double d, double range); - -String RemoveAccents(String str); -bool IsPunctuation(wchar c); - -inline double ToRad(double angle) {return angle*M_PI/180;} -inline double ToDeg(double angle) {return angle*180/M_PI;} - -inline bool Odd(int val) {return val%2;} -inline bool Even(int val) {return !Odd(val);} -inline int RoundEven(int val) {return Even(val) ? val : val+1;} -template -inline int Sign(T a) {return (a > 0) - (a < 0);} -template -inline T Average(T a, T b) {return T((a+b)/2);} -template -inline T Average(T a, T b, T c) {return T((a+b+c)/3);} -template -inline T Average(T a, T b, T c, T d){return T((a+b+c+d)/4);} -template -inline const T& min(const T& a, const T& b, const T& c) { - return a < b ? (a < c ? a : c) : ((b < c) ? b : c); } -template -inline const T& min(const T& a, const T& b, const T& c, const T& d) { - T ab = min(a, b); - T cd = min(c, d); - return ab < cd ? ab : cd; -} -template -inline const T& max(const T& a, const T& b, const T& c) { - return a > b ? (a > c ? a : c) : ((b > c) ? b : c); } -template -inline const T& max(const T& a, const T& b, const T& c, const T& d) { - T ab = max(a, b); - T cd = max(c, d); - return ab > cd ? ab : cd; -} - -int DayOfYear(Date d); - -// Fits object centered into frame maintaining the aspect -template -Rect_ FitInFrame(const Size_ &frame, const Size_ &object) -{ - double frameAspect = frame.cx/(double)frame.cy; - double objectAspect = object.cx/(double)object.cy; - - if (frameAspect > objectAspect) { - double x = (frame.cx - objectAspect*frame.cy)/2.; - return Rect_((T)x, 0, (T)(x + objectAspect*frame.cy), frame.cy); - } else { - double y = (frame.cy - frame.cx/objectAspect)/2.; - return Rect_(0, (T)y, frame.cx, (T)(y + frame.cx/objectAspect)); - } -} - -Color RandomColor(); - -// A String based class to parse into -class StringParse : public String { -public: - void GoInit() {pos = 0; lastSeparator='\0';}; - StringParse():String("") {GoInit();}; - StringParse(String s): String(s) {GoInit();}; - bool GoBefore(const String text) - { - if (pos >= GetLength()) { - pos = GetLength()-1; - return false; - } - int newpos = String::Find(text, pos); - if (newpos < 0) - return false; // If it does not find it, it does not move - pos = newpos; - return true; - }; - bool GoAfter(const String text) - { - if(!GoBefore(text)) - return false; - pos += strlen(text); - return true; - }; - bool GoAfter(const String text, const String text2) - { - if(!GoAfter(text)) - return false; - if(!GoAfter(text2)) - return false; - return true; - }; - bool GoAfter(const String text, const String text2, const String text3) - { - if(!GoAfter(text)) - return false; - if(!GoAfter(text2)) - return false; - if(!GoAfter(text3)) - return false; - return true; - }; - bool GoAfter_Init(const String text) {GoInit(); return GoAfter(text);}; - bool GoAfter_Init(const String text, const String text2) {GoInit(); return GoAfter(text, text2);}; - bool GoAfter_Init(const String text, const String text2, const String text3) {GoInit(); return GoAfter(text, text2, text3);}; - - void GoBeginLine() - { - for (; pos >= 0; --pos) { - if ((ToString()[pos-1] == '\r') || (ToString()[pos-1] == '\n')) - return; - } - } - bool IsBeginLine() - { - if (pos == 0) - return true; - if ((ToString()[pos-1] == '\r') || (ToString()[pos-1] == '\n')) - return true; - return false; - } - bool IsSpaceRN(int c) - { - if (IsSpace(c)) - return true; - if ((c == '\r') || (c == '\n')) - return true; - return false; - } - // Gets text between "" or just a word until an space - // It considers special characters with \ if between "" - // If not between "" it gets the word when it finds one of the separator characters - String GetText(String separators = "") - { - String ret = ""; - if (pos > GetCount()) - return ret; - int newpos = pos; - - while ((IsSpaceRN(ToString()[newpos]) && (ToString()[newpos] != '\"') && - (ToString()[newpos] != '\0'))) - newpos++; - if (ToString()[newpos] == '\0') { - pos = newpos; - return ""; - } - - if (ToString()[newpos] == '\"') { // Between "" - newpos++; - while (ToString()[newpos] != '\"' && ToString()[newpos] != '\0') { - if (ToString()[newpos] == '\\') { - newpos++; - if (ToString()[newpos] == '\0') - return ""; - } - ret.Cat(ToString()[newpos]); - newpos++; - } - lastSeparator = '"'; - } else if (separators == "") { // Simple word - while (!IsSpaceRN(ToString()[newpos]) && ToString()[newpos] != '\0') { - if (ToString()[newpos] == '\"') { - newpos--; // This " belongs to the next - break; - } - ret.Cat(ToString()[newpos]); - newpos++; - } - lastSeparator = ToString()[newpos]; - } else { // Simple word, special separator - while (ToString()[newpos] != '\0') {// Only consider included spaces (!IsSpaceRN(ToString()[newpos]) && ToString()[newpos] != '\0') { - if (ToString()[newpos] == '\"') { - newpos--; // This " belongs to the next - break; - } - if (separators.Find(ToString()[newpos]) >= 0) { - lastSeparator = ToString()[newpos]; - break; - } - ret.Cat(ToString()[newpos]); - newpos++; - } - lastSeparator = ToString()[newpos]; - } - pos = ++newpos; // After the separator: ", space or separator - return ret; - } - String GetLine() - { - return GetText("\r\n"); - } - double GetDouble(String separators = "") {return atof(GetText(separators));}; - int GetInt(String separators = "") {return atoi(GetText(separators));}; - long GetLong(String separators = "") {return atol(GetText(separators));}; - uint64 GetUInt64(String separators = "") -#if defined(PLATFORM_WIN32) - {return _atoi64(GetText(separators));}; -#endif -#ifdef PLATFORM_POSIX - {return atoll(GetText(separators));}; -#endif - - String Right() {return String::Mid(pos+1);} - int GetLastSeparator() {return lastSeparator;} - void MoveRel(int val) - { - pos += val; - if (pos < 0) - pos = 0; - else if (pos >= GetCount()) - pos = GetCount() - 1; - } - int GetPos() {return pos;}; - bool SetPos(int i) - { - if (i < 0 || i >= GetCount()) - return false; - else { - pos = i; - return true; - } - } - bool Eof() - { - return pos >= GetCount(); - } - unsigned Count(String s) - { - int from = 0; - unsigned count = 0; - - while ((from = ToString().Find(s, from)) >= 0) { - count++; - from++; - } - return count; - } -private: - int pos; - int lastSeparator; -}; - -#if defined(PLATFORM_WIN32) -Value GetVARIANT(VARIANT &result); -String WideToString(LPCWSTR wcs, int len = -1); -#endif - -#ifdef CTRLLIB_H - #include "Functions4U/Functions4U_Gui.h" -#endif - -/* -// A ProcessEvents than can be used in non gui programs -inline void DoEvents() { -#ifdef CTRLLIB_H - Ctrl::ProcessEvents(); -#endif -} -*/ - -String GetExtExecutable(String ext); - -Array GetDriveList(); - -String Getcwd(); -bool Chdir (const String &folder); - -//String Format(Time time, const char*fmt = "%2d:%2d"); - -class Dl { -public: - Dl(); - ~Dl(); - bool Load(const String &fileDll); - void *GetFunction(const String &functionName); - -private: -#if defined(PLATFORM_WIN32) - HINSTANCE hinstLib; -#else - void *hinstLib; -#endif -}; - -typedef Dl Dll; - -//bool RunFromMemory(const String &progBuffer, const String &name); - - -String BsGetLastError(); -bool BSPatch(String oldfile, String newfile, String patchfile); -bool BSDiff(String oldfile, String newfile, String patchfile); - -bool LoadFromXMLFileAES(Callback1 xmlize, const char *file, const char *key); -template -bool LoadFromXMLFileAES(T& data, const char *file, const char *key) -{ - ParamHelper__ p(data); - return LoadFromXMLFileAES(callback(&p, &ParamHelper__::Invoke), file, key); -} - -bool StoreAsXMLFileAES(Callback1 xmlize, const char *name, const char *file, const char *key); -template -bool StoreAsXMLFileAES(T& data, const char *name, const char *file, const char *key) -{ - ParamHelper__ p(data); - return StoreAsXMLFileAES(callback(&p, &ParamHelper__::Invoke), name, file, key); -} - -Image Rotate180(const Image& img); -Image GetRect(const Image& orig, const Rect &r); - -#ifdef flagAES - -#include -#include - -bool LoadFromXMLFileAES(Callback1 xmlize, const char *file, const char *key); -bool StoreAsXMLFileAES(Callback1 xmlize, const char *name, const char *file, const char *key); - -#endif - -#endif +#ifndef _Functions4U_Functions4U_h +#define _Functions4U_Functions4U_h + +#include +#ifdef flagGUI +#include +#include +#include "GatherTpp.h" +#endif +#include "SvgColors.h" + +enum EXT_FILE_FLAGS {USE_TRASH_BIN = 1, + BROWSE_LINKS = 2, + DELETE_READ_ONLY = 4, + ASK_BEFORE_DELETE = 8 +}; + +bool LaunchFile(const char *file); + +bool FileCat(const char *file, const char *appendFile); + +int FileCompare(const char *path1, const char *path2); + +int FindStringInFile(const char *file, const String text); + +bool FileStrAppend(const char *file, const char *str); +bool AppendFile(const char *filename, const char *str); + +String AppendFileName(const String& path1, const char *path2, const char *path3); + +inline String Trim(const String& s) {return TrimLeft(TrimRight(s));}; + +///////// +bool DirectoryExistsX(const char *path, int flags = 0); +/////////////////////////////// +bool DirectoryDeleteX(const char *path, int flags = 0); +bool DirectoryDeleteDeepX(const char *path, int flags = 0); +bool DeleteFolderDeepX(const char *dir, int flags = 0); +bool DirectoryCopyX(const char *dir, const char *newPlace); +bool DeleteFolderDeepWildcards(const char *dir, int flags = 0); +/////////////////////////////// + +bool UpperFolder(String folderName); +String GetUpperFolder(String folderName); +String GetNextFolder(String folder, String lastFolder); +String GetRealName(String fileName); + +//bool GetSymLinkPath(const char *linkPath, String &filePath); +bool IsSymLink(const char *path); + +bool CreateFolderDeep(const char *dir); + +///////// +bool FileMoveX(const char *oldpath, const char *newpath, int flags = 0); +bool FileDeleteX(const char *path, int flags = 0); +///////// + + +//bool FileSetReadOnly(const char *fileName, bool readOnly); +bool FileSetReadOnly(const char *fileName, bool usr, bool grp = false, bool oth = false); +bool IsReadOnly(const char *fileName, bool &usr, bool &grp, bool &oth); + +String LoadFile_Safe(String fileName); + +int64 GetLength(String fileDirName); +int64 GetDirectoryLength(String directoryName); + +/////////////////////////////// +Array SearchFile(String dir, const Array &condFiles, const Array &condFolders, + const Array &extFiles, const Array &extFolders, + const String &text, Array &errorList); +Array SearchFile(String dir, String condFile, String text, Array &errorList);//, int flags = 0); +Array SearchFile(String dir, String condFile, String text = "");//, int flags = 0); +/////////////////////////////// + +bool FileToTrashBin(const char *path); +int64 TrashBinGetCount(); +bool TrashBinClear(); + +//String GetDesktopFolder(); +//String GetProgramsFolder(); +//String GetAppDataFolder(); +//String GetMusicFolder(); +//String GetPicturesFolder(); +//String GetVideoFolder(); +String GetPersonalFolder(); +//String GetTemplatesFolder(); +//String GetDownloadFolder(); +String GetRootFolder(); +String GetTempFolder(); +String GetOsFolder(); +String GetSystemFolder(); + + +struct FileData : Moveable { + bool isFolder; + String fileName; + String relFilename; + int64 length; + struct Upp::Time t; + int64 id; + + String ToString() const { return Format("%s %0n", fileName, length); } + + FileData(bool isFolder, String fileName, String relFilename, int64 length, struct Upp::Time t, uint64 id) : isFolder(isFolder), fileName(fileName), relFilename(relFilename), length(length), t(t), id(id) {} + FileData() {} +}; + +struct FileDiff { + char action; // 'n': New, 'u': Update, 'd': Delete, 'p': Problem + bool isFolder; + String relPath; + String fileName; + uint64 idMaster, idSecondary; + struct Upp::Time tMaster, tSecondary; + uint64 lengthMaster, lengthSecondary; +}; + +class ErrorHandling +{ +public: + void SetLastError(String _lastError) {lastError = _lastError;}; + String GetLastError() {return lastError;}; + +private: + String lastError; +}; + +class FileDiffArray; + +class FileDataArray : public ErrorHandling +{ +public: + FileDataArray(bool use = false, int fileFlags = 0); + bool Init(String folder, FileDataArray &orig, FileDiffArray &diff); + void Clear(); + bool Search(String dir, String condFile, bool recurse = false, String text = ""); + FileData& operator[](long i) {return fileList[i];} + long GetFileCount() {return fileCount;}; + long GetFolderCount() {return folderCount;}; + long GetCount() {return fileCount + folderCount;}; + int64 GetSize() {return fileSize;}; + inline bool UseId() {return useId;}; + void SortByName(bool ascending = true); + void SortByDate(bool ascending = true); + void SortBySize(bool ascending = true); + Array &GetLastError() {return errorList;}; + int Find(String &relFileName, String &fileName, bool isFolder); + int Find(FileDataArray &data, int id); + String FullFileName(int i) {return AppendFileName(basePath, fileList[i].fileName);}; + bool SaveFile(const char *fileName); + bool AppendFile(const char *fileName); + bool LoadFile(const char *fileName); + +private: + void Search_Each(String dir, String condFile, bool recurse, String text); + int64 GetFileId(String fileName); + String GetRelativePath(String fullPath); + String GetFileText(); + + Array fileList; + Array errorList; + String basePath; + long fileCount, folderCount; + int64 fileSize; + bool useId; + int fileFlags; +}; + +class FileDiffArray : public ErrorHandling +{ +public: + FileDiffArray(); + void Clear(); + FileDiff& operator[](long i) {return diffList[i];} + bool Compare(FileDataArray &master, FileDataArray &secondary, String &folderFrom, Array &excepFolders, Array &excepFiles); + bool Apply(String toFolder, String fromFolder, int flags = 0); + long GetCount() {return diffList.GetCount();}; + bool SaveFile(const char *fileName); + bool LoadFile(const char *fileName); + String ToString(); + +private: + Array diffList; +}; + + +String Replace(String str, String find, String replace); +String Replace(String str, char find, char replace); + +int ReverseFind(const String& s, const String& toFind, int from = 0); + +String FormatLong(long a); + +const char *StrToTime(struct Upp::Time& d, const char *s); +::Time StrToTime(const char *s); +::Date StrToDate(const char *s); + +String BytesToString(uint64 bytes); + +String SecondsToString(double seconds, bool units = false); +String HMSToString(int hour, int min, double seconds, bool units = false); +double StringToSeconds(String str); // The opposite +void StringToHMS(String durat, int &hour, int &min, double &seconds); + +String FormatDoubleAdjust(double d, double range); + +String RemoveAccents(String str); +bool IsPunctuation(wchar c); + +inline double ToRad(double angle) {return angle*M_PI/180;} +inline double ToDeg(double angle) {return angle*180/M_PI;} + +inline bool Odd(int val) {return val%2;} +inline bool Even(int val) {return !Odd(val);} +inline int RoundEven(int val) {return Even(val) ? val : val+1;} +template +inline int Sign(T a) {return (a > 0) - (a < 0);} +template +inline T Average(T a, T b) {return T((a+b)/2);} +template +inline T Average(T a, T b, T c) {return T((a+b+c)/3);} +template +inline T Average(T a, T b, T c, T d){return T((a+b+c+d)/4);} +template +inline const T& min(const T& a, const T& b, const T& c) { + return a < b ? (a < c ? a : c) : ((b < c) ? b : c); } +template +inline const T& min(const T& a, const T& b, const T& c, const T& d) { + T ab = min(a, b); + T cd = min(c, d); + return ab < cd ? ab : cd; +} +template +inline const T& max(const T& a, const T& b, const T& c) { + return a > b ? (a > c ? a : c) : ((b > c) ? b : c); } +template +inline const T& max(const T& a, const T& b, const T& c, const T& d) { + T ab = max(a, b); + T cd = max(c, d); + return ab > cd ? ab : cd; +} + +int DayOfYear(Date d); + +// Fits object centered into frame maintaining the aspect +template +Rect_ FitInFrame(const Size_ &frame, const Size_ &object) +{ + double frameAspect = frame.cx/(double)frame.cy; + double objectAspect = object.cx/(double)object.cy; + + if (frameAspect > objectAspect) { + double x = (frame.cx - objectAspect*frame.cy)/2.; + return Rect_((T)x, 0, (T)(x + objectAspect*frame.cy), frame.cy); + } else { + double y = (frame.cy - frame.cx/objectAspect)/2.; + return Rect_(0, (T)y, frame.cx, (T)(y + frame.cx/objectAspect)); + } +} + +Color RandomColor(); + +// A String based class to parse into +class StringParse : public String { +public: + void GoInit() {pos = 0; lastSeparator='\0';}; + StringParse():String("") {GoInit();}; + StringParse(String s): String(s) {GoInit();}; + bool GoBefore(const String text) + { + if (pos >= GetLength()) { + pos = GetLength()-1; + return false; + } + int newpos = String::Find(text, pos); + if (newpos < 0) + return false; // If it does not find it, it does not move + pos = newpos; + return true; + }; + bool GoAfter(const String text) + { + if(!GoBefore(text)) + return false; + pos += strlen(text); + return true; + }; + bool GoAfter(const String text, const String text2) + { + if(!GoAfter(text)) + return false; + if(!GoAfter(text2)) + return false; + return true; + }; + bool GoAfter(const String text, const String text2, const String text3) + { + if(!GoAfter(text)) + return false; + if(!GoAfter(text2)) + return false; + if(!GoAfter(text3)) + return false; + return true; + }; + bool GoAfter_Init(const String text) {GoInit(); return GoAfter(text);}; + bool GoAfter_Init(const String text, const String text2) {GoInit(); return GoAfter(text, text2);}; + bool GoAfter_Init(const String text, const String text2, const String text3) {GoInit(); return GoAfter(text, text2, text3);}; + + void GoBeginLine() + { + for (; pos >= 0; --pos) { + if ((ToString()[pos-1] == '\r') || (ToString()[pos-1] == '\n')) + return; + } + } + bool IsBeginLine() + { + if (pos == 0) + return true; + if ((ToString()[pos-1] == '\r') || (ToString()[pos-1] == '\n')) + return true; + return false; + } + bool IsSpaceRN(int c) + { + if (IsSpace(c)) + return true; + if ((c == '\r') || (c == '\n')) + return true; + return false; + } + // Gets text between "" or just a word until an space + // It considers special characters with \ if between "" + // If not between "" it gets the word when it finds one of the separator characters + String GetText(String separators = "") + { + String ret = ""; + if (pos > GetCount()) + return ret; + int newpos = pos; + + while ((IsSpaceRN(ToString()[newpos]) && (ToString()[newpos] != '\"') && + (ToString()[newpos] != '\0'))) + newpos++; + if (ToString()[newpos] == '\0') { + pos = newpos; + return ""; + } + + if (ToString()[newpos] == '\"') { // Between "" + newpos++; + while (ToString()[newpos] != '\"' && ToString()[newpos] != '\0') { + if (ToString()[newpos] == '\\') { + newpos++; + if (ToString()[newpos] == '\0') + return ""; + } + ret.Cat(ToString()[newpos]); + newpos++; + } + lastSeparator = '"'; + } else if (separators == "") { // Simple word + while (!IsSpaceRN(ToString()[newpos]) && ToString()[newpos] != '\0') { + if (ToString()[newpos] == '\"') { + newpos--; // This " belongs to the next + break; + } + ret.Cat(ToString()[newpos]); + newpos++; + } + lastSeparator = ToString()[newpos]; + } else { // Simple word, special separator + while (ToString()[newpos] != '\0') {// Only consider included spaces (!IsSpaceRN(ToString()[newpos]) && ToString()[newpos] != '\0') { + if (ToString()[newpos] == '\"') { + newpos--; // This " belongs to the next + break; + } + if (separators.Find(ToString()[newpos]) >= 0) { + lastSeparator = ToString()[newpos]; + break; + } + ret.Cat(ToString()[newpos]); + newpos++; + } + lastSeparator = ToString()[newpos]; + } + pos = ++newpos; // After the separator: ", space or separator + return ret; + } + String GetLine() + { + return GetText("\r\n"); + } + double GetDouble(String separators = "") {return atof(GetText(separators));}; + int GetInt(String separators = "") {return atoi(GetText(separators));}; + long GetLong(String separators = "") {return atol(GetText(separators));}; + uint64 GetUInt64(String separators = "") +#if defined(PLATFORM_WIN32) + {return _atoi64(GetText(separators));}; +#endif +#ifdef PLATFORM_POSIX + {return atoll(GetText(separators));}; +#endif + + String Right() {return String::Mid(pos+1);} + int GetLastSeparator() {return lastSeparator;} + void MoveRel(int val) + { + pos += val; + if (pos < 0) + pos = 0; + else if (pos >= GetCount()) + pos = GetCount() - 1; + } + int GetPos() {return pos;}; + bool SetPos(int i) + { + if (i < 0 || i >= GetCount()) + return false; + else { + pos = i; + return true; + } + } + bool Eof() + { + return pos >= GetCount(); + } + unsigned Count(String s) + { + int from = 0; + unsigned count = 0; + + while ((from = ToString().Find(s, from)) >= 0) { + count++; + from++; + } + return count; + } +private: + int pos; + int lastSeparator; +}; + +#if defined(PLATFORM_WIN32) +Value GetVARIANT(VARIANT &result); +String WideToString(LPCWSTR wcs, int len = -1); +#endif + +#ifdef CTRLLIB_H + #include "Functions4U/Functions4U_Gui.h" +#endif + +/* +// A ProcessEvents than can be used in non gui programs +inline void DoEvents() { +#ifdef CTRLLIB_H + Ctrl::ProcessEvents(); +#endif +} +*/ + +String GetExtExecutable(String ext); + +Array GetDriveList(); + +String Getcwd(); +bool Chdir (const String &folder); + +//String Format(Time time, const char*fmt = "%2d:%2d"); + +class Dl { +public: + Dl(); + ~Dl(); + bool Load(const String &fileDll); + void *GetFunction(const String &functionName); + +private: +#if defined(PLATFORM_WIN32) + HINSTANCE hinstLib; +#else + void *hinstLib; +#endif +}; + +typedef Dl Dll; + +//bool RunFromMemory(const String &progBuffer, const String &name); + + +String BsGetLastError(); +bool BSPatch(String oldfile, String newfile, String patchfile); +bool BSDiff(String oldfile, String newfile, String patchfile); + +bool LoadFromXMLFileAES(Callback1 xmlize, const char *file, const char *key); +template +bool LoadFromXMLFileAES(T& data, const char *file, const char *key) +{ + ParamHelper__ p(data); + return LoadFromXMLFileAES(callback(&p, &ParamHelper__::Invoke), file, key); +} + +bool StoreAsXMLFileAES(Callback1 xmlize, const char *name, const char *file, const char *key); +template +bool StoreAsXMLFileAES(T& data, const char *name, const char *file, const char *key) +{ + ParamHelper__ p(data); + return StoreAsXMLFileAES(callback(&p, &ParamHelper__::Invoke), name, file, key); +} + +Image Rotate180(const Image& img); +Image GetRect(const Image& orig, const Rect &r); + +#ifdef flagAES + +#include +#include + +bool LoadFromXMLFileAES(Callback1 xmlize, const char *file, const char *key); +bool StoreAsXMLFileAES(Callback1 xmlize, const char *name, const char *file, const char *key); + +#endif + +#endif diff --git a/bazaar/Functions4U/GatherTpp.cpp b/bazaar/Functions4U/GatherTpp.cpp index cb3fced73..fb6bdd5b8 100644 --- a/bazaar/Functions4U/GatherTpp.cpp +++ b/bazaar/Functions4U/GatherTpp.cpp @@ -1,343 +1,343 @@ -#ifdef flagGUI -#include -#include - -using namespace Upp; - -#include "Functions4U/Functions4U.h" -#include "GatherTpp.h" - -struct ScanTopicIterator : RichText::Iterator { - VectorMap *reflink; - String link; - StaticCriticalSection reflink_lock; - - ScanTopicIterator(VectorMap *reflink) : reflink(reflink) {}; - virtual bool operator()(int pos, const RichPara& para) - { - if(!IsNull(para.format.label)) - reflink->Add(para.format.label, link); - return false; - } -}; - -void GatherTpp::GatherRefLinks(const char *upp) -{ - for(FindFile pff(AppendFileName(upp, "*.*")); pff; pff.Next()) { - if(pff.IsFolder()) { - String package = pff.GetName(); - String pdir = AppendFileName(upp, package); - TopicLink tl; - tl.package = package; - for(FindFile ff(AppendFileName(pdir, "*.tpp")); ff; ff.Next()) { - if(ff.IsFolder()) { - String group = GetFileTitle(ff.GetName() ); - tl.group = group; - String dir = AppendFileName(pdir, ff.GetName()); - for(FindFile ft(AppendFileName(dir, "*.tpp")); ft; ft.Next()) { - if(ft.IsFile()) { - String path = AppendFileName(dir, ft.GetName()); - tl.topic = GetFileTitle(ft.GetName()); - String link = TopicLinkString(tl); - ScanTopicIterator sti(&reflink); - sti.link = link; - ParseQTF(ReadTopic(LoadFile(path))).Iterate(sti); - } - } - } - } - } - } -} - -struct GatherLinkIterator : RichText::Iterator { - VectorMap *reflink; - Index link; - - GatherLinkIterator(VectorMap *reflink) : reflink(reflink) {}; - virtual bool operator()(int pos, const RichPara& para) - { - for(int i = 0; i < para.GetCount(); i++) { - String l = para[i].format.link; - if(!IsNull(l)) { - if(l[0] == ':') { - int q = reflink->Find(l); - int w = q; - if(q < 0) - q = reflink->Find(l + "::class"); - if(q < 0) - q = reflink->Find(l + "::struct"); - if(q < 0) - q = reflink->Find(l + "::union"); - if(q >= 0) - l = (*reflink)[q]; - } - link.FindAdd(Nvl(reflink->Get(l, Null), l)); - } - } - return false; - } -}; - -String GetIndexTopic(String file) -{ - String topic = GetFileTitle(file); - String folder = GetFileFolder(file); - String topicLocation = GetFileTitle(folder); - folder = GetUpperFolder(folder); - topicLocation = GetFileTitle(folder) + "/" + topicLocation; - - return "topic://" + topicLocation + "/" + topic; -} - -int CharFilterLbl(int c) -{ - return IsAlNum(c) ? c : '.'; -} - -void QtfAsPdf(PdfDraw &pdf, const char *qtf) -{ - RichText txt = ParseQTF(qtf); - Size page = Size(3968, 6074); - UPP::Print(pdf, txt, page); -} - -Htmls RoundFrame(Htmls data, String border, Color bg) -{ - return HtmlPackedTable().BgColor(bg).Width(-100) - .Attr("style", "border-style: solid; border-width: 1px; border-color: #" + border + ";") - / HtmlLine() / data; -} - -bool ContainsAt(const String &source, const String &pattern, int pos) -{ - return pos >= 0 - && pos + pattern.GetLength() <= source.GetLength() - && 0 == memcmp(source.Begin() + pos, pattern.Begin(), pattern.GetLength()); -} - -bool StartsWith(const String &source, const String &pattern) -{ - return ContainsAt(source, pattern, 0); -} - -bool EndsWith(const String &source, const String &pattern) -{ - return ContainsAt(source, pattern, source.GetLength() - pattern.GetLength()); -} - -String GatherTpp::QtfAsHtml(const char *qtf, Index& css, - const VectorMap& links, - const VectorMap& labels, - const String& outdir, const String& fn) -{ - return EncodeHtml(ParseQTF(qtf), css, links, labels, outdir, fn, Zoom(8, 40), escape, 40); -} - -String GetText(const char *s) -{ - return GetTopic(s).text; -} - -void GatherTpp::ExportPage(int i, String htmlFolder) -{ - Index css; - String path = links.GetKey(i); - - String text = GetText(path); - int h; - h = ParseQTF(tt[i].text).GetHeight(1000); - - String qtflangs; - String strlang; - - String page = tt[i]; - page = QtfAsHtml(page, css, links, labels, htmlFolder, links[i]); - - Color paper = SWhite; - Color bg = Color(210, 217, 210); - - Htmls html; - html << - HtmlPackedTable().Width(-100) / - HtmlLine().ColSpan(3) + - HtmlPackedTable().Width(-100) / ( - HtmlLine().ColSpan(3).BgColor(bg).Height(6) / "" + - HtmlRow() / ( - HtmlTCell().Width(-100).BgColor(bg) / ( - RoundFrame(page , "6E89AE;padding: 10px;", White) - ) - ) - ); - - String topicTitle = tt.GetKey(i); - String pageTitle = tt[i].title; - if(IsNull(pageTitle)) - pageTitle = title; -/* - if(StartsWith(topicTitle, "examples$")) - pageTitle = "Demos / " + pageTitle; - else if(StartsWith(topicTitle, "reference$")) - pageTitle = "Examples / " + pageTitle; -*/ - if(pageTitle != title) - pageTitle << " :: " << title; - - Htmls content = - "\n" + - HtmlHeader(pageTitle, AsCss(css) + - "a.l1 { text-decoration:none; font-size: 8pt; font-family: sans-serif; " - "font-weight: normal; }\n" - "a.l1:link { color:#000000; }\n" - "a.l1:visited { color:#000080; }\n" - "a.l1:hover { color:#9933CC; }\n" - "a.l1:active { color:#000000; }\n" - "a.l2 { text-decoration:none; font-size: 12pt; font-family: sans-serif; " - "font-variant: small-caps; }\n" - "a.l2:link { color:#0066FF; }\n" - "a.l2:visited { color:#FF6600; }\n" - "a.l2:hover { color:#BC0624; }\n" - "a.l2:active { color:#BC0024; }\n", - "" - "" - ) - .BgColor(bg) - .Alink(Red).Link(Black).Vlink(Blue) - / html; - SaveFile(AppendFileName(htmlFolder, links[i]), content); -} - -String GatherTpp::TopicFileName(const char *topic) -{ - TopicLink tl = ParseTopicLink(topic); - String file = AppendFileName(dir, AppendFileName(tl.group + ".tpp", tl.topic + ".tpp")); - if (FileExists(file)) - return file; - - for (int i = 0; i < rootFolders.GetCount(); ++i) { - if (rootFolders[i] != dir) { - file = AppendFileName(rootFolders[i], AppendFileName(tl.package , AppendFileName(tl.group + ".tpp", tl.topic + ".tpp"))); - if (FileExists(file)) - return file; - } - } - return ""; -} - -String TopicFileNameHtml(const char *topic) -{ - TopicLink tl = ParseTopicLink(topic); - return tl.group + "$" + tl.package+ "$" + tl.topic + ".html"; -} - -String GatherTpp::GatherTopics(const char *topic, String& title) -{ - int q = tt.Find(topic); - if(q < 0) { - Topic p = ReadTopic(LoadFile(TopicFileName(topic))); - title = p.title; - String t = p; - if(IsNull(t)) - return "index.html"; - tt.Add(topic) = p; - GatherLinkIterator ti(&(reflink)); - ParseQTF(t).Iterate(ti); - for(int i = 0; i < ti.link.GetCount(); i++) { - String dummy; - GatherTopics(ti.link[i], dummy); - } - } else - title = tt[q].title; - return TopicFileNameHtml(topic); -} - - -String GatherTpp::GatherTopics(const char *topic) -{ - String dummy; - return GatherTopics(topic, dummy); -} - -bool GatherTpp::Load(String indexFile, Gate2 progress) { - indexTopic = GetIndexTopic(indexFile); - for (int i = 0; i < rootFolders.GetCount(); ++i) { - if (progress(i+1, rootFolders.GetCount())) - return false; - dir = rootFolders[i]; - - if (!DirectoryExists(dir)) - return false; - - GatherRefLinks(dir); - - if (i == 0) - GatherTopics(indexTopic); - } - return true; -} - -bool GatherTpp::MakeHtml(const char *folder, Gate2 progress) { - DeleteFolderDeep(folder); - DirectoryCreate(folder); - - for(int i = 0; i < tt.GetCount(); i++) { - String topic = tt.GetKey(i); - links.Add(topic, topic == indexTopic ? "index.html" : - memcmp(topic, "topic://", 8) ? topic : TopicFileNameHtml(topic)); - } - for(int i = 0; i < reflink.GetCount(); i++) { - String l = reflink.GetKey(i); - String lbl = Filter(l, CharFilterLbl); - String f = links.Get(reflink[i], Null) + '#' + lbl; - links.Add(l, f); - static const char *x[] = { "::struct", "::class", "::union" }; - for(int ii = 0; ii < 3; ii++) { - String e = x[ii]; - if(EndsWith(l, e)) { - links.Add(l.Mid(0, l.GetLength() - e.GetLength()), f); - } - } - labels.Add(l, lbl); - } - - for(int i = 0; i < tt.GetCount(); i++) { - if (progress(i+1, tt.GetCount())) - return false; - ExportPage(i, folder); - } - return true; -} - -bool GatherTpp::MakePdf(const char *filename, Gate2 progress) { - PdfDraw pdf; - for(int i = 0; i < tt.GetCount(); i++) { - if (progress(i+1, tt.GetCount())) - return false; - bool dopdf = true; - for (int j = 0; j < i; ++j) { - if (tt[j].text == tt[i].text) { - dopdf = false; - break; - } - } - if (dopdf) - QtfAsPdf(pdf, tt[i]); - } - SaveFile(filename, pdf.Finish()); - return true; -} - -int GatherTpp::FindTopic(const String name) { - return tt.Find(name); -} - -Topic &GatherTpp::GetTopic(int id) { - return tt[id]; -} - -Topic &GatherTpp::AddTopic(const String name) { - return tt.Add(name); -} - +#ifdef flagGUI +#include +#include + +using namespace Upp; + +#include "Functions4U/Functions4U.h" +#include "GatherTpp.h" + +struct ScanTopicIterator : RichText::Iterator { + VectorMap *reflink; + String link; + StaticCriticalSection reflink_lock; + + ScanTopicIterator(VectorMap *reflink) : reflink(reflink) {}; + virtual bool operator()(int pos, const RichPara& para) + { + if(!IsNull(para.format.label)) + reflink->Add(para.format.label, link); + return false; + } +}; + +void GatherTpp::GatherRefLinks(const char *upp) +{ + for(FindFile pff(AppendFileName(upp, "*.*")); pff; pff.Next()) { + if(pff.IsFolder()) { + String package = pff.GetName(); + String pdir = AppendFileName(upp, package); + TopicLink tl; + tl.package = package; + for(FindFile ff(AppendFileName(pdir, "*.tpp")); ff; ff.Next()) { + if(ff.IsFolder()) { + String group = GetFileTitle(ff.GetName() ); + tl.group = group; + String dir = AppendFileName(pdir, ff.GetName()); + for(FindFile ft(AppendFileName(dir, "*.tpp")); ft; ft.Next()) { + if(ft.IsFile()) { + String path = AppendFileName(dir, ft.GetName()); + tl.topic = GetFileTitle(ft.GetName()); + String link = TopicLinkString(tl); + ScanTopicIterator sti(&reflink); + sti.link = link; + ParseQTF(ReadTopic(LoadFile(path))).Iterate(sti); + } + } + } + } + } + } +} + +struct GatherLinkIterator : RichText::Iterator { + VectorMap *reflink; + Index link; + + GatherLinkIterator(VectorMap *reflink) : reflink(reflink) {}; + virtual bool operator()(int pos, const RichPara& para) + { + for(int i = 0; i < para.GetCount(); i++) { + String l = para[i].format.link; + if(!IsNull(l)) { + if(l[0] == ':') { + int q = reflink->Find(l); + int w = q; + if(q < 0) + q = reflink->Find(l + "::class"); + if(q < 0) + q = reflink->Find(l + "::struct"); + if(q < 0) + q = reflink->Find(l + "::union"); + if(q >= 0) + l = (*reflink)[q]; + } + link.FindAdd(Nvl(reflink->Get(l, Null), l)); + } + } + return false; + } +}; + +String GetIndexTopic(String file) +{ + String topic = GetFileTitle(file); + String folder = GetFileFolder(file); + String topicLocation = GetFileTitle(folder); + folder = GetUpperFolder(folder); + topicLocation = GetFileTitle(folder) + "/" + topicLocation; + + return "topic://" + topicLocation + "/" + topic; +} + +int CharFilterLbl(int c) +{ + return IsAlNum(c) ? c : '.'; +} + +void QtfAsPdf(PdfDraw &pdf, const char *qtf) +{ + RichText txt = ParseQTF(qtf); + Size page = Size(3968, 6074); + UPP::Print(pdf, txt, page); +} + +Htmls RoundFrame(Htmls data, String border, Color bg) +{ + return HtmlPackedTable().BgColor(bg).Width(-100) + .Attr("style", "border-style: solid; border-width: 1px; border-color: #" + border + ";") + / HtmlLine() / data; +} + +bool ContainsAt(const String &source, const String &pattern, int pos) +{ + return pos >= 0 + && pos + pattern.GetLength() <= source.GetLength() + && 0 == memcmp(source.Begin() + pos, pattern.Begin(), pattern.GetLength()); +} + +bool StartsWith(const String &source, const String &pattern) +{ + return ContainsAt(source, pattern, 0); +} + +bool EndsWith(const String &source, const String &pattern) +{ + return ContainsAt(source, pattern, source.GetLength() - pattern.GetLength()); +} + +String GatherTpp::QtfAsHtml(const char *qtf, Index& css, + const VectorMap& links, + const VectorMap& labels, + const String& outdir, const String& fn) +{ + return EncodeHtml(ParseQTF(qtf), css, links, labels, outdir, fn, Zoom(8, 40), escape, 40); +} + +String GetText(const char *s) +{ + return GetTopic(s).text; +} + +void GatherTpp::ExportPage(int i, String htmlFolder, String keywords) +{ + Index css; + String path = links.GetKey(i); + + String text = GetText(path); + int h; + h = ParseQTF(tt[i].text).GetHeight(1000); + + String qtflangs; + String strlang; + + String page = tt[i]; + page = QtfAsHtml(page, css, links, labels, htmlFolder, links[i]); + + Color paper = SWhite; + Color bg = Color(210, 217, 210); + + Htmls html; + html << + HtmlPackedTable().Width(-100) / + HtmlLine().ColSpan(3) + + HtmlPackedTable().Width(-100) / ( + HtmlLine().ColSpan(3).BgColor(bg).Height(6) / "" + + HtmlRow() / ( + HtmlTCell().Width(-100).BgColor(bg) / ( + RoundFrame(page , "6E89AE;padding: 10px;", White) + ) + ) + ); + + String topicTitle = tt.GetKey(i); + String pageTitle = tt[i].title; + if(IsNull(pageTitle)) + pageTitle = title; +/* + if(StartsWith(topicTitle, "examples$")) + pageTitle = "Demos / " + pageTitle; + else if(StartsWith(topicTitle, "reference$")) + pageTitle = "Examples / " + pageTitle; +*/ + if(pageTitle != title) + pageTitle << " :: " << title; + + Htmls content = + "\n" + + HtmlHeader(pageTitle, AsCss(css) + + "a.l1 { text-decoration:none; font-size: 8pt; font-family: sans-serif; " + "font-weight: normal; }\n" + "a.l1:link { color:#000000; }\n" + "a.l1:visited { color:#000080; }\n" + "a.l1:hover { color:#9933CC; }\n" + "a.l1:active { color:#000000; }\n" + "a.l2 { text-decoration:none; font-size: 12pt; font-family: sans-serif; " + "font-variant: small-caps; }\n" + "a.l2:link { color:#0066FF; }\n" + "a.l2:visited { color:#FF6600; }\n" + "a.l2:hover { color:#BC0624; }\n" + "a.l2:active { color:#BC0024; }\n", + "" + "" + ) + .BgColor(bg) + .Alink(Red).Link(Black).Vlink(Blue) + / html; + SaveFile(AppendFileName(htmlFolder, links[i]), content); +} + +String GatherTpp::TopicFileName(const char *topic) +{ + TopicLink tl = ParseTopicLink(topic); + String file = AppendFileName(dir, AppendFileName(tl.group + ".tpp", tl.topic + ".tpp")); + if (FileExists(file)) + return file; + + for (int i = 0; i < rootFolders.GetCount(); ++i) { + if (rootFolders[i] != dir) { + file = AppendFileName(rootFolders[i], AppendFileName(tl.package , AppendFileName(tl.group + ".tpp", tl.topic + ".tpp"))); + if (FileExists(file)) + return file; + } + } + return ""; +} + +String TopicFileNameHtml(const char *topic) +{ + TopicLink tl = ParseTopicLink(topic); + return tl.group + "$" + tl.package+ "$" + tl.topic + ".html"; +} + +String GatherTpp::GatherTopics(const char *topic, String& title) +{ + int q = tt.Find(topic); + if(q < 0) { + Topic p = ReadTopic(LoadFile(TopicFileName(topic))); + title = p.title; + String t = p; + if(IsNull(t)) + return "index.html"; + tt.Add(topic) = p; + GatherLinkIterator ti(&(reflink)); + ParseQTF(t).Iterate(ti); + for(int i = 0; i < ti.link.GetCount(); i++) { + String dummy; + GatherTopics(ti.link[i], dummy); + } + } else + title = tt[q].title; + return TopicFileNameHtml(topic); +} + + +String GatherTpp::GatherTopics(const char *topic) +{ + String dummy; + return GatherTopics(topic, dummy); +} + +bool GatherTpp::Load(String indexFile, Gate2 progress) { + indexTopic = GetIndexTopic(indexFile); + for (int i = 0; i < rootFolders.GetCount(); ++i) { + if (progress(i+1, rootFolders.GetCount())) + return false; + dir = rootFolders[i]; + + if (!DirectoryExists(dir)) + return false; + + GatherRefLinks(dir); + + if (i == 0) + GatherTopics(indexTopic); + } + return true; +} + +bool GatherTpp::MakeHtml(const char *folder, Gate2 progress) { + DeleteFolderDeep(folder); + DirectoryCreate(folder); + + for(int i = 0; i < tt.GetCount(); i++) { + String topic = tt.GetKey(i); + links.Add(topic, topic == indexTopic ? "index.html" : + memcmp(topic, "topic://", 8) ? topic : TopicFileNameHtml(topic)); + } + for(int i = 0; i < reflink.GetCount(); i++) { + String l = reflink.GetKey(i); + String lbl = Filter(l, CharFilterLbl); + String f = links.Get(reflink[i], Null) + '#' + lbl; + links.Add(l, f); + static const char *x[] = { "::struct", "::class", "::union" }; + for(int ii = 0; ii < 3; ii++) { + String e = x[ii]; + if(EndsWith(l, e)) { + links.Add(l.Mid(0, l.GetLength() - e.GetLength()), f); + } + } + labels.Add(l, lbl); + } + + for(int i = 0; i < tt.GetCount(); i++) { + if (progress(i+1, tt.GetCount())) + return false; + ExportPage(i, folder); + } + return true; +} + +bool GatherTpp::MakePdf(const char *filename, Gate2 progress) { + PdfDraw pdf; + for(int i = 0; i < tt.GetCount(); i++) { + if (progress(i+1, tt.GetCount())) + return false; + bool dopdf = true; + for (int j = 0; j < i; ++j) { + if (tt[j].text == tt[i].text) { + dopdf = false; + break; + } + } + if (dopdf) + QtfAsPdf(pdf, tt[i]); + } + SaveFile(filename, pdf.Finish()); + return true; +} + +int GatherTpp::FindTopic(const String name) { + return tt.Find(name); +} + +Topic &GatherTpp::GetTopic(int id) { + return tt[id]; +} + +Topic &GatherTpp::AddTopic(const String name) { + return tt.Add(name); +} + #endif \ No newline at end of file diff --git a/bazaar/Functions4U/GatherTpp.h b/bazaar/Functions4U/GatherTpp.h index 7f016943a..53306ed4d 100644 --- a/bazaar/Functions4U/GatherTpp.h +++ b/bazaar/Functions4U/GatherTpp.h @@ -1,41 +1,41 @@ -#ifndef _GatherTpp_h_ -#define _GatherTpp_h_ - -class GatherTpp { -public: - //GatherTpp(); - void AddFolder(const char *folder) {rootFolders.Add(folder);}; - bool Load(String indexFile, Gate2 progress = false); - - int FindTopic(const String name); - Topic &GetTopic(int id); - Topic &AddTopic(const String name); - String GatherTopics(const char *topic, String& title); - - bool MakeHtml(const char *folder, Gate2 progress = false); - bool MakePdf(const char *filename, Gate2 progress = false); - - -private: - Array rootFolders; - String dir; - VectorMap escape; - VectorMap links; - VectorMap labels; - VectorMap reflink; - VectorMap tt; - - Htmls header; - String keywords; // - String title; // - String indexTopic; - - String TopicFileName(const char *topic); - String GatherTopics(const char *topic); - void GatherRefLinks(const char *upp); - void ExportPage(int i, String htmlFolder); - String QtfAsHtml(const char *qtf, Index& css, const VectorMap& links, - const VectorMap& labels, const String& outdir, const String& fn = Null); -}; - -#endif +#ifndef _GatherTpp_h_ +#define _GatherTpp_h_ + +class GatherTpp { +public: + //GatherTpp(); + void AddFolder(const char *folder) {rootFolders.Add(folder);}; + bool Load(String indexFile, Gate2 progress = false); + + int FindTopic(const String name); + Topic &GetTopic(int id); + Topic &AddTopic(const String name); + String GatherTopics(const char *topic, String& title); + + bool MakeHtml(const char *folder, Gate2 progress = false); + bool MakePdf(const char *filename, Gate2 progress = false); + + +private: + Array rootFolders; + String dir; + VectorMap escape; + VectorMap links; + VectorMap labels; + VectorMap reflink; + VectorMap tt; + + Htmls header; + String keywords; // + String title; // + String indexTopic; + + String TopicFileName(const char *topic); + String GatherTopics(const char *topic); + void GatherRefLinks(const char *upp); + void ExportPage(int i, String htmlFolder, String keywords = ""); + String QtfAsHtml(const char *qtf, Index& css, const VectorMap& links, + const VectorMap& labels, const String& outdir, const String& fn = Null); +}; + +#endif diff --git a/bazaar/Functions4U/SvgColors.cpp b/bazaar/Functions4U/SvgColors.cpp index 827ac75fe..ca60efd11 100644 --- a/bazaar/Functions4U/SvgColors.cpp +++ b/bazaar/Functions4U/SvgColors.cpp @@ -1,162 +1,164 @@ -#include - -#include "Functions4U.h" - -ColorDef svgColors[] = { - "aliceblue", Color(240,248,255), - "antiquewhite", Color(250,235,215), - "aqua", Color(0,255,255), - "aquamarine", Color(127,255,212), - "azure", Color(240,255,255), - "beige", Color(245,245,220), - "bisque", Color(255,228,196), - "black", Color(0,0,0), - "blanchedalmond", Color(255,235,205), - "blue", Color(0,0,255), - "blueviolet", Color(138,43,226), - "brown", Color(165,42,42), - "burlywood", Color(222,184,135), - "cadetblue", Color(95,158,160), - "chartreuse", Color(127,255,0), - "chocolate", Color(210,105,30), - "coral", Color(255,127,80), - "cornflowerblue", Color(100,149,237), - "cornsilk", Color(255,248,220), - "crimson", Color(220,20,60), - "cyan", Color(0,255,255), - "darkblue", Color(0,0,139), - "darkcyan", Color(0,139,139), - "darkgoldenrod", Color(184,134,11), - "darkgray", Color(169,169,169), - "darkgreen", Color(0,100,0), - "darkgrey", Color(169,169,169), - "darkkhaki", Color(189,183,107), - "darkmagenta", Color(139,0,139), - "darkolivegreen", Color(85,107,47), - "darkorange", Color(255,140,0), - "darkorchid", Color(153,50,204), - "darkred", Color(139,0,0), - "darksalmon", Color(233,150,122), - "darkseagreen", Color(143,188,143), - "darkslateblue", Color(72,61,139), - "darkslategray", Color(47,79,79), - "darkslategrey", Color(47,79,79), - "darkturquoise", Color(0,206,209), - "darkviolet", Color(148,0,211), - "deeppink", Color(255,20,147), - "deepskyblue", Color(0,191,255), - "dimgray", Color(105,105,105), - "dimgrey", Color(105,105,105), - "dodgerblue", Color(30,144,255), - "firebrick", Color(178,34,34), - "floralwhite", Color(255,250,240), - "forestgreen", Color(34,139,34), - "fuchsia", Color(255,0,255), - "gainsboro", Color(220,220,220), - "ghostwhite", Color(248,248,255), - "gold", Color(255,215,0), - "goldenrod", Color(218,165,32), - "gray", Color(128,128,128), - "green", Color(0,128,0), - "greenyellow", Color(173,255,47), - "grey", Color(128,128,128), - "honeydew", Color(240,255,240), - "hotpink", Color(255,105,180), - "indianred", Color(205,92,92), - "indigo", Color(75,0,130), - "ivory", Color(255,255,240), - "khaki", Color(240,230,140), - "lavender", Color(230,230,250), - "lavenderblush", Color(255,240,245), - "lawngreen", Color(124,252,0), - "lemonchiffon", Color(255,250,205), - "lightblue", Color(173,216,230), - "lightcoral", Color(240,128,128), - "lightcyan", Color(224,255,255), - "lightgoldenrodyellow", Color(250,250,210), - "lightgray", Color(211,211,211), - "lightgreen", Color(144,238,144), - "lightgrey", Color(211,211,211), - "lightpink", Color(255,182,193), - "lightsalmon", Color(255,160,122), - "lightseagreen", Color(32,178,170), - "lightskyblue", Color(135,206,250), - "lightslategray", Color(119,136,153), - "lightslategrey", Color(119,136,153), - "lightsteelblue", Color(176,196,222), - "lightyellow", Color(255,255,224), - "lime", Color(0,255,0), - "limegreen", Color(50,205,50), - "linen", Color(250,240,230), - "magenta", Color(255,0,255), - "maroon", Color(128,0,0), - "mediumaquamarine", Color(102,205,170), - "mediumblue", Color(0,0,205), - "mediumorchid", Color(186,85,211), - "mediumpurple", Color(147,112,219), - "mediumseagreen", Color(60,179,113), - "mediumslateblue", Color(123,104,238), - "mediumspringgreen", Color(0,250,154), - "mediumturquoise", Color(72,209,204), - "mediumvioletred", Color(199,21,133), - "midnightblue", Color(25,25,112), - "mintcream", Color(245,255,250), - "mistyrose", Color(255,228,225), - "moccasin", Color(255,228,181), - "navajowhite", Color(255,222,173), - "navy", Color(0,0,128), - "oldlace", Color(253,245,230), - "olive", Color(128,128,0), - "olivedrab", Color(107,142,35), - "orange", Color(255,165,0), - "orangered", Color(255,69,0), - "orchid", Color(218,112,214), - "palegoldenrod", Color(238,232,170), - "palegreen", Color(152,251,152), - "paleturquoise", Color(175,238,238), - "palevioletred", Color(219,112,147), - "papayawhip", Color(255,239,213), - "peachpuff", Color(255,218,185), - "peru", Color(205,133,63), - "pink", Color(255,192,203), - "plum", Color(221,160,221), - "powderblue", Color(176,224,230), - "purple", Color(128,0,128), - "red", Color(255,0,0), - "rosybrown", Color(188,143,143), - "royalblue", Color(65,105,225), - "saddlebrown", Color(139,69,19), - "salmon", Color(250,128,114), - "sandybrown", Color(244,164,96), - "seagreen", Color(46,139,87), - "seashell", Color(255,245,238), - "sienna", Color(160,82,45), - "silver", Color(192,192,192), - "skyblue", Color(135,206,235), - "slateblue", Color(106,90,205), - "slategray", Color(112,128,144), - "slategrey", Color(112,128,144), - "snow", Color(255,250,250), - "springgreen", Color(0,255,127), - "steelblue", Color(70,130,180), - "tan", Color(210,180,140), - "teal", Color(0,128,128), - "thistle", Color(216,191,216), - "tomato", Color(255,99,71), - "turquoise", Color(64,224,208), - "violet", Color(238,130,238), - "wheat", Color(245,222,179), - "white", Color(255,255,255), - "whitesmoke", Color(245,245,245), - "yellow", Color(255,255,0), - "yellowgreen", Color(154,205,50), - "" -}; - -Color GetSvgColor(const char *color) { - for (int i = 0; *svgColors[i].name; ++i) { - if (strcmp(svgColors[i].name, color) == 0) - return svgColors[i].color; - } - return Color(); -} +#include + +using namespace Upp; + +#include "Functions4U.h" + +ColorDef svgColors[] = { + "aliceblue", Color(240,248,255), + "antiquewhite", Color(250,235,215), + "aqua", Color(0,255,255), + "aquamarine", Color(127,255,212), + "azure", Color(240,255,255), + "beige", Color(245,245,220), + "bisque", Color(255,228,196), + "black", Color(0,0,0), + "blanchedalmond", Color(255,235,205), + "blue", Color(0,0,255), + "blueviolet", Color(138,43,226), + "brown", Color(165,42,42), + "burlywood", Color(222,184,135), + "cadetblue", Color(95,158,160), + "chartreuse", Color(127,255,0), + "chocolate", Color(210,105,30), + "coral", Color(255,127,80), + "cornflowerblue", Color(100,149,237), + "cornsilk", Color(255,248,220), + "crimson", Color(220,20,60), + "cyan", Color(0,255,255), + "darkblue", Color(0,0,139), + "darkcyan", Color(0,139,139), + "darkgoldenrod", Color(184,134,11), + "darkgray", Color(169,169,169), + "darkgreen", Color(0,100,0), + "darkgrey", Color(169,169,169), + "darkkhaki", Color(189,183,107), + "darkmagenta", Color(139,0,139), + "darkolivegreen", Color(85,107,47), + "darkorange", Color(255,140,0), + "darkorchid", Color(153,50,204), + "darkred", Color(139,0,0), + "darksalmon", Color(233,150,122), + "darkseagreen", Color(143,188,143), + "darkslateblue", Color(72,61,139), + "darkslategray", Color(47,79,79), + "darkslategrey", Color(47,79,79), + "darkturquoise", Color(0,206,209), + "darkviolet", Color(148,0,211), + "deeppink", Color(255,20,147), + "deepskyblue", Color(0,191,255), + "dimgray", Color(105,105,105), + "dimgrey", Color(105,105,105), + "dodgerblue", Color(30,144,255), + "firebrick", Color(178,34,34), + "floralwhite", Color(255,250,240), + "forestgreen", Color(34,139,34), + "fuchsia", Color(255,0,255), + "gainsboro", Color(220,220,220), + "ghostwhite", Color(248,248,255), + "gold", Color(255,215,0), + "goldenrod", Color(218,165,32), + "gray", Color(128,128,128), + "green", Color(0,128,0), + "greenyellow", Color(173,255,47), + "grey", Color(128,128,128), + "honeydew", Color(240,255,240), + "hotpink", Color(255,105,180), + "indianred", Color(205,92,92), + "indigo", Color(75,0,130), + "ivory", Color(255,255,240), + "khaki", Color(240,230,140), + "lavender", Color(230,230,250), + "lavenderblush", Color(255,240,245), + "lawngreen", Color(124,252,0), + "lemonchiffon", Color(255,250,205), + "lightblue", Color(173,216,230), + "lightcoral", Color(240,128,128), + "lightcyan", Color(224,255,255), + "lightgoldenrodyellow", Color(250,250,210), + "lightgray", Color(211,211,211), + "lightgreen", Color(144,238,144), + "lightgrey", Color(211,211,211), + "lightpink", Color(255,182,193), + "lightsalmon", Color(255,160,122), + "lightseagreen", Color(32,178,170), + "lightskyblue", Color(135,206,250), + "lightslategray", Color(119,136,153), + "lightslategrey", Color(119,136,153), + "lightsteelblue", Color(176,196,222), + "lightyellow", Color(255,255,224), + "lime", Color(0,255,0), + "limegreen", Color(50,205,50), + "linen", Color(250,240,230), + "magenta", Color(255,0,255), + "maroon", Color(128,0,0), + "mediumaquamarine", Color(102,205,170), + "mediumblue", Color(0,0,205), + "mediumorchid", Color(186,85,211), + "mediumpurple", Color(147,112,219), + "mediumseagreen", Color(60,179,113), + "mediumslateblue", Color(123,104,238), + "mediumspringgreen", Color(0,250,154), + "mediumturquoise", Color(72,209,204), + "mediumvioletred", Color(199,21,133), + "midnightblue", Color(25,25,112), + "mintcream", Color(245,255,250), + "mistyrose", Color(255,228,225), + "moccasin", Color(255,228,181), + "navajowhite", Color(255,222,173), + "navy", Color(0,0,128), + "oldlace", Color(253,245,230), + "olive", Color(128,128,0), + "olivedrab", Color(107,142,35), + "orange", Color(255,165,0), + "orangered", Color(255,69,0), + "orchid", Color(218,112,214), + "palegoldenrod", Color(238,232,170), + "palegreen", Color(152,251,152), + "paleturquoise", Color(175,238,238), + "palevioletred", Color(219,112,147), + "papayawhip", Color(255,239,213), + "peachpuff", Color(255,218,185), + "peru", Color(205,133,63), + "pink", Color(255,192,203), + "plum", Color(221,160,221), + "powderblue", Color(176,224,230), + "purple", Color(128,0,128), + "red", Color(255,0,0), + "rosybrown", Color(188,143,143), + "royalblue", Color(65,105,225), + "saddlebrown", Color(139,69,19), + "salmon", Color(250,128,114), + "sandybrown", Color(244,164,96), + "seagreen", Color(46,139,87), + "seashell", Color(255,245,238), + "sienna", Color(160,82,45), + "silver", Color(192,192,192), + "skyblue", Color(135,206,235), + "slateblue", Color(106,90,205), + "slategray", Color(112,128,144), + "slategrey", Color(112,128,144), + "snow", Color(255,250,250), + "springgreen", Color(0,255,127), + "steelblue", Color(70,130,180), + "tan", Color(210,180,140), + "teal", Color(0,128,128), + "thistle", Color(216,191,216), + "tomato", Color(255,99,71), + "turquoise", Color(64,224,208), + "violet", Color(238,130,238), + "wheat", Color(245,222,179), + "white", Color(255,255,255), + "whitesmoke", Color(245,245,245), + "yellow", Color(255,255,0), + "yellowgreen", Color(154,205,50), + "" +}; + +Color GetSvgColor(const char *color) { + for (int i = 0; *svgColors[i].name; ++i) { + if (strcmp(svgColors[i].name, color) == 0) + return svgColors[i].color; + } + return Color(); +} diff --git a/bazaar/Functions4U/bsdiffwrapper.h b/bazaar/Functions4U/bsdiffwrapper.h index 17c30af1b..82f4006a3 100644 --- a/bazaar/Functions4U/bsdiffwrapper.h +++ b/bazaar/Functions4U/bsdiffwrapper.h @@ -19,10 +19,9 @@ bool Err(String str); #define write _write #define close _close typedef unsigned char u_char; - - #if defined(__MINGW32__) - #define _SH_DENYNO 0x40 - #else + + #define _SH_DENYNO 0x40 + #if !defined(__MINGW32__) typedef long pid_t; typedef signed int ssize_t; #endif diff --git a/bazaar/Functions4U/plugin/bsdiff.cpp b/bazaar/Functions4U/plugin/bsdiff.cpp index 78a49d5e7..91a10ea25 100644 --- a/bazaar/Functions4U/plugin/bsdiff.cpp +++ b/bazaar/Functions4U/plugin/bsdiff.cpp @@ -189,7 +189,7 @@ static void offtout(off_t x,u_char *buf) if(x<0) y=-x; else y=x; - buf[0]=y%256;y-=buf[0]; + buf[0]=y%256;y-=buf[0]; y=y/256;buf[1]=y%256;y-=buf[1]; y=y/256;buf[2]=y%256;y-=buf[2]; y=y/256;buf[3]=y%256;y-=buf[3];