/* ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 1, or (at your option) ** any later version. ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef CVSLOG_H #define CVSLOG_H #ifdef WIN32 # ifdef _DEBUG # define qCvsDebug 1 # else # define qCvsDebug 0 # endif #endif /* WIN32 */ #include #include #include #if defined(_MSC_VER) && _MSC_VER < 0x514 // VC7 # include using namespace std; # define OSTREAM ::ostream #else # include # define OSTREAM std::ostream #endif // a C-string class CLogStr { public : inline CLogStr() : str(0L) {} inline CLogStr(const char *newstr) { str = 0L; *this = newstr; } inline CLogStr(const CLogStr & newstr) { str = 0L; *this = newstr; } virtual ~CLogStr() { flush(); } inline bool empty(void) const {return str == 0L || str[0] == '\0';} inline unsigned int length(void) const {return str == 0L ? 0 : strlen(str);} const char *operator=(const char *newstr); // set to a new C String (0L is OK) const CLogStr & operator=(const CLogStr & newstr); // set according to another CLogStr const CLogStr & set(const char *buf, unsigned int len); // set from a buffer bool operator<(const char *newstr) const; inline operator const char *() const {return str == 0L ? "" : str;} inline const char *c_str() const {return str == 0L ? "" : str;} // as a C string CLogStr & operator<<(const char *addToStr); CLogStr & operator<<(char addToStr); CLogStr & operator<<(int addToStr); // concatenate inline bool endsWith(char c) const {return !length() ? false : str[length()-1] == c;} const CLogStr & replace(char which, char bywhich); // replace a character protected : void flush(void); char *str; // the String }; // class to store a revision number class CRevNumber { public: CRevNumber() {} virtual ~CRevNumber() { reset(); } void reset(void); inline int size() const {return allDigits.size();} int cmp(const CRevNumber & arev) const; // return -1,0,1 "a la" qsort CRevNumber & operator+=(int adigit); CRevNumber & operator=(const CRevNumber & arev); bool operator==(const CRevNumber & arev) const; int operator[](int index) const; bool operator<(const CRevNumber & arev) const; bool ischildof(const CRevNumber & arev) const; // 1.4.2.2 is child of 1.4 bool issamebranch(const CRevNumber & arev) const; // 1.1.1.2 is same branch than 1.1.1.3 bool ispartof(const CRevNumber & arev) const; // 1.1.1.2 is part of 1.1.1 // 1.4.2.3 is part of 1.4.0.2 bool issubbranchof(const CRevNumber & arev) const; // 1.1.1 is subbranch of 1.1 // 1.4.0.2 is subbranch of 1.4 inline const std::vector & IntList(void) const { return allDigits; } inline std::vector & IntList(void) { return allDigits; } inline const CLogStr & Tag(void) const { return tagName; } inline CLogStr & Tag(void) { return tagName; } const char *c_str(void) const; protected: std::vector allDigits; CLogStr tagName; // or an author }; // a single revision for a file class CRevFile { public: CRevFile(); CRevFile(const CRevFile & afile); virtual ~CRevFile(); CRevFile & operator=(const CRevFile & afile); bool operator<(const CRevFile & afile) const; bool operator==(const CRevFile & afile) const; void print(OSTREAM & out) const; inline const CRevNumber & RevNum(void) const { return revNum; } inline CRevNumber & RevNum(void) { return revNum; } inline const struct tm & RevTime(void) const { return revTime; } inline struct tm & RevTime(void) { return revTime; } inline const CLogStr & Locker(void) const { return locker; } inline CLogStr & Locker(void) { return locker; } inline const std::vector & BranchesList(void) const { return branchesList; } inline std::vector & BranchesList(void) { return branchesList; } inline CRevNumber & LastBranche(void) { return branchesList[branchesList.size() - 1]; } inline const CLogStr & Author(void) const { return author; } inline CLogStr & Author(void) { return author; } inline const CLogStr & State(void) const { return state; } inline CLogStr & State(void) { return state; } inline int ChgPos(void) const { return chgPos; } inline int & ChgPos(void) { return chgPos; } inline int ChgNeg(void) const { return chgNeg; } inline int & ChgNeg(void) { return chgNeg; } inline const CLogStr & DescLog(void) const { return descLog; } inline CLogStr & DescLog(void) { return descLog; } protected: CRevNumber revNum; struct tm revTime; CLogStr locker; std::vector branchesList; CLogStr author; CLogStr state; int chgPos; int chgNeg; CLogStr descLog; }; // RCS infos for a file class CRcsFile { public: CRcsFile(); CRcsFile(const CRcsFile & afile); virtual ~CRcsFile(); CRcsFile & operator=(const CRcsFile & afile); bool operator<(const CRcsFile & afile) const; bool operator==(const CRcsFile & afile) const; void sort(void); void print(OSTREAM & out) const; inline const CLogStr & RcsFile(void) const { return rcsFile; } inline CLogStr & RcsFile(void) { return rcsFile; } inline const CLogStr & WorkingFile(void) const { return workingFile; } inline CLogStr & WorkingFile(void) { return workingFile; } inline const CRevNumber & HeadRev(void) const { return headRev; } inline CRevNumber & HeadRev(void) { return headRev; } inline const CRevNumber & BranchRev(void) const { return branchRev; } inline CRevNumber & BranchRev(void) { return branchRev; } inline const CLogStr & KeywordSubst(void) const { return keywordSubst; } inline CLogStr & KeywordSubst(void) { return keywordSubst; } inline int SelRevisions(void) const { return selRevisions; } inline int & SelRevisions(void) { return selRevisions; } inline int TotRevisions(void) const { return totRevisions; } inline int & TotRevisions(void) { return totRevisions; } inline const std::vector & AccessList(void) const { return accessList; } inline std::vector & AccessList(void) { return accessList; } inline CLogStr & LastAccess(void) { return accessList[accessList.size() - 1]; } inline const std::vector & SymbolicList(void) const { return symbolicList; } inline std::vector & SymbolicList(void) { return symbolicList; } inline CRevNumber & LastSymbName(void) { return symbolicList[symbolicList.size() - 1]; } inline const std::vector & LocksList(void) const { return locksList; } inline std::vector & LocksList(void) { return locksList; } inline CRevNumber & LastLock(void) { return locksList[locksList.size() - 1]; } inline bool LockStrict(void) const { return lockStrict; } inline bool & LockStrict(void) { return lockStrict; } inline const std::vector & AllRevs(void) const { return allRevs; } inline std::vector & AllRevs(void) { return allRevs; } inline CRevFile & LastRev(void) { return allRevs[allRevs.size() - 1]; } inline const CLogStr & DescLog(void) const { return descLog; } inline CLogStr & DescLog(void) { return descLog; } protected: CLogStr rcsFile; CLogStr workingFile; CRevNumber headRev; CRevNumber branchRev; CLogStr keywordSubst; std::vector accessList; std::vector symbolicList; std::vector locksList; int selRevisions; int totRevisions; bool lockStrict; std::vector allRevs; CLogStr descLog; }; // classes used to build a tree off the cvs log output typedef enum { kNodeHeader, kNodeBranch, kNodeRev, kNodeTag } kLogNode; class CLogNode; class CLogNodeData { public: CLogNodeData(CLogNode *node) { fNode = node; } virtual ~CLogNodeData() {} inline CLogNode *Node(void) { return fNode; } protected: CLogNode *fNode; }; class CLogNode { public: CLogNode(CLogNode * root = 0L); virtual ~CLogNode(); virtual kLogNode GetType(void) const = 0; inline const std::vector & Childs(void) const { return childs; } inline std::vector & Childs(void) { return childs; } inline const CLogNode * Root(void) const { return root; } inline CLogNode * & Root(void) { return root; } inline const CLogNode * Next(void) const { return next; } inline CLogNode * & Next(void) { return next; } inline void SetUserData(CLogNodeData *data) { user = data; } inline CLogNodeData *GetUserData(void) { return user; } protected: std::vector childs; CLogNode * root; CLogNode * next; CLogNodeData *user; }; class CLogNodeHeader : public CLogNode { public: CLogNodeHeader(const CRcsFile & h, CLogNode * r = 0L) : CLogNode(r), header(h) {} virtual kLogNode GetType(void) const { return kNodeHeader; } inline const CRcsFile & operator *() const { return header; } inline CRcsFile & operator *() { return header; } protected: CRcsFile header; }; class CLogNodeRev : public CLogNode { public: CLogNodeRev(const CRevFile & r, CLogNode * root = 0L) : CLogNode(root), rev(r) {} virtual kLogNode GetType(void) const { return kNodeRev; } inline const CRevFile & operator *() const { return rev; } inline CRevFile & operator *() { return rev; } protected: CRevFile rev; }; class CLogNodeTag : public CLogNode { public: CLogNodeTag(const CLogStr & t, CLogNode * r = 0L) : CLogNode(r), tag(t) {} virtual kLogNode GetType(void) const { return kNodeTag; } inline const CLogStr & operator*() const { return tag; } inline CLogStr & operator*() { return tag; } protected: CLogStr tag; }; class CLogNodeBranch : public CLogNode { public: CLogNodeBranch(const CLogStr & b, CLogNode * r = 0L) : CLogNode(r), branch(b) {} virtual kLogNode GetType(void) const { return kNodeBranch; } inline const CLogStr & operator*() const { return branch; } inline CLogStr & operator*() { return branch; } protected: CLogStr branch; }; std::vector & CvsLogParse(FILE * file); // parse a file and return the set of RCS files void CvsLogReset(void); // free the memory used CLogNode *CvsLogGraph(CRcsFile & rcsfile); // build a tree (i.e. graph) of the history #endif