From 437bca524595d1007f37988e862db8bfeff329b0 Mon Sep 17 00:00:00 2001 From: marha Date: Wed, 29 Jul 2009 09:17:47 +0000 Subject: Added mhmake GNU make compatible (with extensions) make utility. --- tools/mhmake/src/fileinfo.cpp | 339 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 tools/mhmake/src/fileinfo.cpp (limited to 'tools/mhmake/src/fileinfo.cpp') diff --git a/tools/mhmake/src/fileinfo.cpp b/tools/mhmake/src/fileinfo.cpp new file mode 100644 index 000000000..65b7d52a2 --- /dev/null +++ b/tools/mhmake/src/fileinfo.cpp @@ -0,0 +1,339 @@ +/* This file is part of mhmake. + * + * Copyright (C) 2001-2009 Marc Haesen + * + * Mhmake 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 3 of the License, or + * (at your option) any later version. + * + * Mhmake 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 Mhmake. If not, see . +*/ + +/* $Rev$ */ + +#include "stdafx.h" + +#include "fileinfo.h" +#include "rule.h" +#include "util.h" +#include "mhmakeparser.h" + +const string NullString; +refptr NullFileInfo; + +#ifdef WIN32 +ZEROTIME g_ZeroTime; +#endif + +/////////////////////////////////////////////////////////////////////////////// +refptr fileinfo::GetDir() const +{ + return GetAbsFileInfo(m_AbsFileName.substr(0,m_AbsFileName.find_last_of(OSPATHSEP))); +} + +/////////////////////////////////////////////////////////////////////////////// +string fileinfo::GetName() const +{ + return m_AbsFileName.substr(m_AbsFileName.find_last_of(OSPATHSEP)+1); +} + +/////////////////////////////////////////////////////////////////////////////// +mh_time_t fileinfo::realGetDate() +{ +#ifdef WIN32 + WIN32_FIND_DATA FindData; + HANDLE hFind=FindFirstFile(m_AbsFileName.c_str(),&FindData); + if (hFind==INVALID_HANDLE_VALUE) + { + m_Date.SetNotExist(); + } + else + { + FindClose(hFind); + if (FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + { // For directories we just take an old time since the lastwritetime is changed each time something + // is added to the directory + m_Date.SetDir(); + } + else + { + m_Date=g_ZeroTime.ConvertTime(&FindData.ftLastWriteTime); + } + } +#else + struct stat Buf; + if (-1==stat(m_AbsFileName.c_str(),&Buf)) + m_Date.SetNotExist(); + else if (S_ISDIR(Buf.st_mode)) + m_Date.SetDir(); + else + m_Date=Buf.st_mtime; +#endif + return m_Date; +} + +/////////////////////////////////////////////////////////////////////////////// +bool fileinfo::IsDir() const +{ +#ifdef WIN32 + WIN32_FIND_DATA FindData; + HANDLE hFind=FindFirstFile(m_AbsFileName.c_str(),&FindData); + if (hFind==INVALID_HANDLE_VALUE) + { + return false; + } + else + { + FindClose(hFind); + if (FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + { + return true; + } + else + { + return false; + } + } +#else + struct stat Buf; + if (-1==stat(m_AbsFileName.c_str(),&Buf)) + return false; // File does not exist, so consider this as not a directory + else + return 0!=S_ISDIR (Buf.st_mode); + return true; +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +void fileinfo::SetDateToNow() +{ +#ifdef WIN32 + FILETIME FileTime; + GetSystemTimeAsFileTime(&FileTime); + m_Date=g_ZeroTime.ConvertTime(&FileTime); +#else + m_Date=time(NULL); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +string fileinfo::GetPrerequisits() const +{ + // Build a string with all prerequisits, but make sure that every dependency + // is only in there once (we do this be building a set in parallel + vector< refptr >::const_iterator DepIt=m_Deps.begin(); + set< refptr > Deps; + bool first=true; + string Ret=g_EmptyString; + while (DepIt!=m_Deps.end()) + { + set< refptr >::iterator pFound=Deps.find(*DepIt); + if (pFound==Deps.end()) + { + if (first) + { + first=false; + } + else + { + Ret+=g_SpaceString; + } + Ret+=(*DepIt)->GetFullFileName(); + } + Deps.insert(*DepIt); + DepIt++; + } + return Ret; +} + +/////////////////////////////////////////////////////////////////////////////// +void fileinfo::AddDeps(vector< refptr > &Deps) +{ + vector< refptr >::iterator It=Deps.begin(); + vector< refptr >::iterator ItEnd=Deps.end(); + while (It!=ItEnd) + { + AddDep(*It++); + } +} + +/////////////////////////////////////////////////////////////////////////////// +bool fileinfo::IsAutoDepExtention(void) const +{ + const char *pName=GetFullFileName().c_str(); + const char *pExt=strrchr(pName,'.'); + if (!pExt) + return false; + pExt++; + if (m_pRule) + { + string ObjExt=m_pRule->GetMakefile()->ExpandVar(OBJEXTVAR); + return ((0==strcmp(pExt,ObjExt.c_str()+1)) || (0==strcmp(pExt,"h"))); + } + else + return ((0==strcmp(pExt,"obj")) || (0==strcmp(pExt,"doj")) || (0==strcmp(pExt,"o")) || (0==strcmp(pExt,"h"))); +} + +#ifdef _DEBUG +/////////////////////////////////////////////////////////////////////////////// +void fileinfo::DumpErrorMessageDuplicateRule(const refptr&pRule) +{ + cerr << m_AbsFileName << ": rule is defined multiple times\n"; + cerr << "First ("<GetMakefile()->GetMakeDir()->GetFullFileName()<<") :\n"; + + vector::const_iterator It=m_pRule->GetCommands().begin(); + while (It!=m_pRule->GetCommands().end()) + { + cerr << " " << m_pRule->GetMakefile()->ExpandExpression(*It) << endl; + It++; + } + cerr << "Second ("<GetMakefile()->GetMakeDir()->GetFullFileName()<<") :\n"; + It=pRule->GetCommands().begin(); + while (It!=pRule->GetCommands().end()) + { + cerr << " " << pRule->GetMakefile()->ExpandExpression(*It) << endl; + It++; + } +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +static inline string &GetFullLowerPathName(string &Name) +{ + const char *pPtr=Name.c_str(); + const char *pBeg=pPtr; + const char *pLastSlash=NULL; + char *pWr=(char*)pBeg; + char Char=*pPtr++; + + while (Char) + { + if (Char=='\\' || Char=='/') + { + char Char2=pPtr[0]; + if (Char2=='.') + { + if (pPtr[1]=='.') + { + pPtr+=2; + while ((pPtr[0]=='\\' || pPtr[0]=='/') && pPtr[1]=='.' && pPtr[2]=='.') + { + pLastSlash--; + while (*pLastSlash!='\\' && *pLastSlash!='/') pLastSlash--; + if (pLastSlash &GetFileInfo(const string &NameIn,const refptr &RelDir) +{ + string Name=NameIn; + bool DoesExist=true; + //Only concatenate if szName is not already a full name +#ifdef WIN32 + if (!Name.empty() && Name[1]!=':') +#endif + { + if (Name[0]!=OSPATHSEP) + { + Name=RelDir->GetFullFileName()+OSPATHSEPSTR+Name; + if (!RelDir->Exists()) /* if the directory does not exist, the file will not exist either */ + DoesExist=false; + } + #ifdef WIN32 + else + { + /* The filename is absolute but does not contain a driver letter. So add it (only on windows) */ + Name=RelDir->GetFullFileName().substr(0,2)+Name; + } + #endif + } + const refptr &Ret=GetAbsFileInfo(GetFullLowerPathName(Name)); + #ifdef _DEBUG + if (Ret->GetFullFileName().find(' ')!=string::npos) + { + cerr << "Spaces are not allowed in filenames: "<< Ret->GetFullFileName() << endl; + exit(1); + } + #endif + if (!DoesExist) + Ret->SetNotExist(); + return Ret; +} + +#ifdef _DEBUG +/////////////////////////////////////////////////////////////////////////////// +void PrintFileInfos() +{ + set,less_refptrfileinfo>::iterator pIt=g_FileInfos.begin(); + while (pIt!=g_FileInfos.end()) + { + cout<<(*pIt)->GetFullFileName()<<" :"; + if ((*pIt)->IsPhony()) + cout<<" (phony)"; + vector< refptr > &Deps=(*pIt)->GetDeps(); + vector< refptr >::iterator pDepIt=Deps.begin(); + while (pDepIt!=Deps.end()) + { + cout<GetFullFileName(); + pDepIt++; + } + cout< pRule=(*pIt)->GetRule(); + if (pRule) + { + cout<GetMakefile()->GetMakeDir()->GetFullFileName()<PrintCommands(); + } + pIt++; + } + +} +#endif + -- cgit v1.2.3