码迷,mamicode.com
首页 > 其他好文 > 详细

VC 工程vcproj 代码目录生成工具

时间:2015-03-14 11:10:27      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

有时候我们想阅读开源的代码,在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;
}



VC 工程vcproj 代码目录生成工具

标签:

原文地址:http://my.oschina.net/u/659405/blog/386941

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!