标签:
有时候我们想阅读开源的代码,在windows下vs是最好的IDE,但是开源代码不提供vs的工程文件,新建工程简单但是上百个文件的添加就比较傻逼了。下面提供一段代码爬目录修改vcproj 的xml描述文件,有需求可以参考下,丰富下功能:
#include <iostream> #include <list> #include <map> #include <io.h> #include <windows.h> #include <algorithm> #include <string> #include <cstring> #include <sys/stat.h> #include "tinyxml2.h" using namespace std; using namespace tinyxml2; //////////////////////////////////////////////////////////////////////// class fileNode { public: fileNode(){ fileList.clear(); dirList.clear(); } public: list<string> fileList; map<string, fileNode> dirList; }; //////////////////////////////////////////////////////////////////////// void getFileList(const string& sPath,fileNode& rNode); void getFile(const string& sPath,fileNode& rNode,_finddata_t& file) { string filename = file.name; if(filename == "." || filename == "..") { return ; } string sAddPath = sPath; sAddPath += filename; struct stat st; stat(sAddPath.c_str(), &st); if(st.st_mode & S_IFDIR == S_IFDIR) { sAddPath += "\\"; getFileList(sAddPath, rNode.dirList[filename]); } else { rNode.fileList.push_back(sAddPath); } } void getFileList(const string& sPath,fileNode& rNode) { struct _finddata_t file; long hFile; string sPathLast = sPath + "*"; // sPathLast = "c:\test\*.*" hFile = _findfirst(sPathLast.c_str(), &file); if(hFile == -1) { return; } else { getFile(sPath,rNode,file); } while(_findnext(hFile, &file) != -1) { getFile(sPath,rNode,file); } } void xmlEleFileList(XMLElement* elemXml, map<string, bool>& fileMap) { fileMap.clear(); if(elemXml == NULL) { return; } XMLElement* pNode = elemXml->FirstChildElement("File"); while(pNode != NULL) { const char* pName = pNode->Attribute("RelativePath"); if(pName != NULL) { fileMap[pName] = false; } pNode = pNode->NextSiblingElement("File"); } } void xmlEleAddFile(XMLElement* elemXml, const string& fileName) { if(elemXml == NULL) return; tinyxml2::XMLDocument* doc = elemXml->GetDocument(); XMLElement* pNode = doc->NewElement("File"); pNode->SetAttribute( "RelativePath", fileName.c_str()); elemXml->InsertEndChild(pNode); } void xmlEleRemoveFile(XMLElement* elemXml, map<string, bool>& fileMap) { if(elemXml == NULL) { return; } XMLElement* pNode = elemXml->FirstChildElement("File"); while(pNode != NULL) { string rName = pNode->Attribute("RelativePath"); if(rName.length() > 0 && fileMap.find(rName) != fileMap.end() && fileMap[rName] == false) { XMLElement* pOld = pNode; pNode = pOld->NextSiblingElement("File"); elemXml->DeleteChild(pOld); continue; } pNode = pNode->NextSiblingElement("File"); } } void saveFileList(fileNode& rNode, XMLElement* elemXml); void xmlEleCheckDir(XMLElement* elemXml,const string& dirName, fileNode& rNode) { if(elemXml == NULL) return; bool bfind = false; XMLElement* pNode = elemXml->FirstChildElement("Filter"); while(pNode != NULL) { string rName = pNode->Attribute("Name"); if(rName == dirName) { bfind = true; break; } pNode = pNode->NextSiblingElement("Filter"); } if(bfind == false) { pNode = NULL; } bool binsert = false; if(pNode == NULL) { tinyxml2::XMLDocument* doc = elemXml->GetDocument(); pNode = doc->NewElement("Filter"); pNode->SetAttribute( "Name", dirName.c_str()); binsert = true; } saveFileList(rNode, pNode); if(binsert == true) { elemXml->InsertEndChild(pNode); } } void xmlEleRemoveDir(XMLElement* elemXml, map<string, bool>& dirMap) { if(elemXml == NULL) { return; } XMLElement* pNode = elemXml->FirstChildElement("Filter"); while(pNode != NULL) { string rName = pNode->Attribute("Name"); if(rName.length() > 0 && dirMap.find(rName) == dirMap.end()) { XMLElement* pOld = pNode; pNode = pOld->NextSiblingElement("Filter"); elemXml->DeleteChild(pOld); continue; } pNode = pNode->NextSiblingElement("Filter"); } } void saveFileList(fileNode& rNode, XMLElement* elemXml) { if(elemXml == NULL) return; map<string, bool> fileMap; xmlEleFileList(elemXml, fileMap); for(list<string>::iterator iter = rNode.fileList.begin(); iter != rNode.fileList.end(); iter++) { string& filename = *iter; if(fileMap.find(filename) == fileMap.end()) { xmlEleAddFile(elemXml, filename); } fileMap[filename] = true; } xmlEleRemoveFile(elemXml, fileMap); fileMap.clear(); for(map<string, fileNode>::iterator iter = rNode.dirList.begin(); iter != rNode.dirList.end(); iter ++) { xmlEleCheckDir(elemXml, iter->first, iter->second); //fileMap[iter->first] = true; } //xmlEleRemoveDir(elemXml, fileMap); //fileMap.clear(); } //////////////////////////////////////////////////////////////////////// int main(int argc,char** argv) { if(argc > 2) { string xmlfile(argv[1]); string filedir(argv[2]); //获得列表 fileNode root; getFileList(filedir,root); tinyxml2::XMLDocument doc; if(doc.LoadFile(xmlfile.c_str()) != 0) { cout<<"读取文件:"<<xmlfile<<"失败!"<<endl; return -1; } XMLElement* elemProj = doc.FirstChildElement("VisualStudioProject"); if(elemProj == NULL) { cout<<"读取文件:"<<xmlfile<<"失败,VisualStudioProject节点不存在!"<<endl; return -2; } bool badd = false; XMLElement* elemFiles = elemProj->FirstChildElement("Files"); if(elemFiles == NULL) { elemFiles = doc.NewElement("Files"); badd = true; } saveFileList(root, elemFiles); if(badd == true) { elemProj->InsertEndChild(elemFiles); } doc.SaveFile(xmlfile.c_str()); } else { cout<<"usetage: addvsdir 工程文件 相对目录"<<endl; } return 0; }
标签:
原文地址:http://my.oschina.net/u/659405/blog/386941