📄 fileex.cpp
字号:
// FileEx.cpp: implementation of the CFileEx class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FileEx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFileEx::CFileEx()
{
}
CFileEx::~CFileEx()
{
}
BOOL CFileEx::IsEof()
{
BOOL bRet = FALSE;
DWORD dwOldPos = GetPosition();
SeekToEnd();
DWORD dwEnd = GetPosition();
bRet = (dwOldPos == dwEnd);
SeekToBegin();
DWORD dwBegin = GetPosition();
Seek(dwOldPos - dwBegin, CFile::begin);
return bRet;
}
//从当前位置读内容到行结尾
CString CFileEx::ReadALine()
{
char ch;
CString strRet = "";
strRet.Empty();
//如果不到文件尾并且没有碰到换行符
while(Read(&ch, 1) >= 1 && ch != '\n')
{
strRet.Insert(strRet.GetLength(), ch);
}
return strRet;
}
long CFileEx::GetFileLines()
{
long m_nFileLines = 0;
//保存文件指针的当前位置
DWORD dwOldPos = GetPosition();
//文件开始和结束位置
SeekToEnd();
DWORD dwEndPos = GetPosition();
//从文件头部开始统计
SeekToBegin();
DWORD dwBeginPos = GetPosition();
//
while(GetPosition() != dwEndPos)
{
ReadALine();
++m_nFileLines;
}
//恢复原指针位置
Seek(dwOldPos - dwBeginPos, CFile::begin);
return m_nFileLines;
}
//得到当前无注释的源文件路径
CString CFileEx::GetNoNotesFilePath(CString strFilename)
{
CString m_strRet = "";
char lpAppname[MAX_PATH];
memset(lpAppname, 0x0, sizeof(lpAppname));
::GetModuleFileName(::AfxGetInstanceHandle(), lpAppname, MAX_PATH);
m_strRet.Format("%s", lpAppname);
m_strRet = m_strRet.Left( m_strRet.ReverseFind('\\') + 1 );
m_strRet += strFilename.Right(strFilename.GetLength() - strFilename.ReverseFind('\\') - 1);
return m_strRet;
}
/*******************CParseVCFile文件解析类******************/
CParseVCFile::CParseVCFile()
{
m_slstSource.RemoveAll();
m_slstHead.RemoveAll();
}
CParseVCFile::~CParseVCFile()
{
if(!m_slstSource.IsEmpty())
m_slstSource.RemoveAll();
if(!m_slstHead.IsEmpty())
m_slstHead.RemoveAll();
}
//解析.CPP|.H|.RC文件
void CParseVCFile::InitFileList()
{
BOOL bFlag = FALSE;
char lpszFindStart[] = "SOURCE=.\\",
lpszCppFileExt[] = ".CPP", //不区分大小写比较
lpszHeadFileExt[] = ".H";
int nIndex = this->GetFilePath().ReverseFind('\\');
CString strCppBasePath = this->GetFilePath().Left(nIndex + 1); //CPP基路径
SeekToBegin();
while(!IsEof())
{
CString strLine = this->ReadALine();
//如果找到一个CPP文件路径
if(strLine.Find(lpszFindStart) == 0)
{
CString strCppFilename = strLine.Right(strLine.GetLength() - strlen(lpszFindStart));
CString strCppPath = strCppBasePath + strCppFilename;
strCppFilename.MakeUpper();
int nIndex = strCppFilename.ReverseFind('.');
if(strCppFilename.Find(lpszCppFileExt) == nIndex)
m_slstSource.AddTail(strCppPath);
else if(strCppFilename.Find(lpszHeadFileExt) == nIndex)
m_slstHead.AddTail(strCppPath);
}
}
}
//移除.H/.CPP文件中的所有注释内容
BOOL CParseVCFile::RemoveVCFileNoteInfo(char strVCFilename[MAX_PATH])
{
m_strNoNotesFilename = GetNoNotesFilePath(strVCFilename);
FILE* file; FILE* lpfile;
//写无注释内容到lpfile文件
lpfile = fopen(m_strNoNotesFilename.GetBuffer(0), "w");
if(lpfile == NULL) return FALSE; //打开写文件失败
//由于效率问题所以采用C语言文件操作
file = fopen(strVCFilename, "r"); //以只读方式打开文件
if(file == NULL)
{
fclose(lpfile); //关闭写文件
::DeleteFile((LPCTSTR)m_strNoNotesFilename);
return FALSE; //打开读文件失败
}
char bufLine[MAX_LINE_SIZE]; //存放行内容
memset(bufLine, 0x0, sizeof(bufLine));
while(!feof(file)) //循环遍历文件内容
{
char buf[3]; //用于判断是否为注释符号
memset(buf, 0x0, sizeof(buf));
//读2个连续的字节[即:同一行的两个字节]
//如果到行尾则有多少读多少(可能读不够两个字节)
int i = 0;
while(!feof(file) && i < 2)
{
char ch = 0;
fread(&ch, sizeof(char), 1, file);
buf[i++] = ch;
if(ch == '\n') break;
}
//如果其中有字符串标志符则一直读到该字符串的结尾[字符串的优先级最高]
/************************以下部分对字符串进行了过滤************************/
char* p = strchr(buf, GLOBAL_VCSTR_SPECCHAR);
if(p != NULL)
{
if(p != buf)
bufLine[strlen(bufLine)] = buf[0];
/********************先保存Buf缓存内容*******************/
if( strlen(bufLine) + strlen(buf) < MAX_LINE_SIZE ) //如果缓存未满
{
char ch = 0;
for(int nIndex = 0; (unsigned)nIndex < strlen(buf); ++nIndex)
{
if((ch = buf[nIndex]) != '\n')
;//bufLine[strlen(bufLine)] = ch; //则连到行内容字符串中
else
{
fprintf(lpfile, "%s\n", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
break; //至此一行内容解析完毕[不包含注释部分]
}
}
}
char ch = 0;
if(p == buf) //如果双引号是在开头字符[即第一个字符]
{
if(*(p + 1) == GLOBAL_PASSTR_SPECCHAR) //如果Buf的内容刚好构成一对双引号,则无须遍历文件寻找其配对的双引号
continue;
}
/*********************读该字符串到结尾********************/
char chprev = 0; //保存前一个字符[考虑字符串中有转义字符]
while(!feof(file))
{
fread(&ch, sizeof(char), 1, file);
//bufLine[strlen(bufLine)] = ch;
if(chprev != '\\' && ch == GLOBAL_VCSTR_SPECCHAR) break; //配对成功则结束该字符串
chprev = ch;
}
fprintf(lpfile, "%s", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
continue;
}
/*****************************如果读到'//'注释符号时***************************/
if(strchr(buf, '/')) //!!!注意'//'和'/*'的相似之处!!!
{
if(strcmp(buf, "//") == 0) //!!!如果单行注释符号一次性读入Buf!!!
{
char ch = 0;
while(!feof(file)) //读到行结尾
{
fread(&ch, sizeof(char), 1, file);
if(ch == '\n')
{
//至此一行内容解析完毕
fprintf(lpfile, "%s\n", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
break;
}
}
}
else //!!![注意当'//'分两次才读完时的情况]!!!
{
char ch = 0;
if(!feof(file))
{
fread(&ch, sizeof(char), 1, file);
if(ch == '/' && !feof(file))
{
bufLine[strlen(bufLine)] = buf[0];
while(!feof(file)) //读到行结尾
{
fread(&ch, sizeof(char), 1, file);
if(ch == '\n')
{
//至此一行内容解析完毕
fprintf(lpfile, "%s\n", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
break;
}
}
}
//如果ch字符为'*'则和前面一个ch字符构成多行注释标志
else if(strcmp(buf, "/*") == 0 || (buf[1] == '/' && ch == '*'))
{
//解析多个多行注释嵌套时的情况
char stack[3], chprev = 0;
memset(stack, 0x0, sizeof(stack));
while(!feof(file))
{
fread(&ch, sizeof(char), 1, file);
if(ch == '/')
{
//先判断前一个字符
if(chprev == '*')
{
if(strcmp(stack, "/*") == 0)
memset(stack, 0x0, sizeof(stack));
else
break;
}
else
{
//再判断下一个字符
fread(&ch, sizeof(char), 1, file);
if(ch == '*')
{
stack[0] = '/';
stack[1] = '*';
}
}
}
chprev = ch;
}
}
else
{
/********************先保存Buf缓存内容*******************/
if( strlen(bufLine) + strlen(buf) < MAX_LINE_SIZE ) //如果缓存未满
{
char ch = 0;
for(int nIndex = 0; (unsigned)nIndex < strlen(buf); ++nIndex)
{
if((ch = buf[nIndex]) != '\n')
bufLine[strlen(bufLine)] = ch; //则连到行内容字符串中
else
{
fprintf(lpfile, "%s\n", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
//[如果ch为下一行字符则应提前保存到缓存]
bufLine[strlen(bufLine)] = ch;
break; //至此一行内容解析完毕[不包含注释部分]
}
}
}
bufLine[strlen(bufLine)] = ch;
if(ch == '\n')
{
fprintf(lpfile, "%s", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
//至此一行内容解析完毕
}
}
}
}
}
else //普通字符
{
if( strlen(bufLine) + strlen(buf) < MAX_LINE_SIZE ) //如果缓存未满
{
char ch = 0;
for(int nIndex = 0; (unsigned)nIndex < strlen(buf); ++nIndex)
{
if((ch = buf[nIndex]) != '\n')
bufLine[strlen(bufLine)] = ch; //则连到行内容字符串中
else
{
fprintf(lpfile, "%s\n", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
break; //至此一行内容解析完毕[不包含注释部分]
}
}
}
else
{
fprintf(lpfile, "%s\n", bufLine);
memset(bufLine, 0x0, sizeof(bufLine));
strcat(bufLine, buf);
break; //至此一行内容解析完毕[不包含注释部分]
}
}
}
fclose(file);
fclose(lpfile);
return TRUE;
}
//解析文件内部类结构,并修改m_cilClassNames列表内容
BOOL CParseVCFile::ParseVCClass(char strVCFilename[MAX_PATH])
{
if(RemoveVCFileNoteInfo(strVCFilename))
{
//开始解析没有注释的源文件内容
CFileEx file;
if( file.Open((LPCTSTR)m_strNoNotesFilename, CFile::modeRead) )
{
//查找类标志符class
while(!file.IsEof())
{
CString strLine = "", strOldLine = "";
strLine = file.ReadALine();
strLine.Replace('\n', ' '); //非常必要
strLine.TrimLeft(); strLine.TrimRight();
if(strLine != "")
{
strOldLine = strLine;
int i = strLine.Find("class");
if(i != -1)
{
TCHAR chp = 0;
if(i == 0) //如果在开头位置
chp = ' ';
else
chp = strLine.GetAt(i-1);
TCHAR chn = 0;
i = i+strlen("class");
if( i >= strLine.GetLength() )
chn = ' ';
else
chn = strLine.GetAt(i);
//如果符合了类定义标志符所在位置关系
if( chp == ' ' && chn == ' ' )
{
LPCLASSANDFILEREL lpitem;
lpitem = (LPCLASSANDFILEREL)malloc(sizeof(CLASSANDFILEREL));
memset(lpitem, 0x0, sizeof(lpitem));
lpitem->nFuncCounts = 0;
lstrcpy(lpitem->strFileName, strVCFilename);
//标志该类是否有类实体
BOOL bHaveClassBody = TRUE;
/**************************分解类名**************************/
CString strClassDefine = strOldLine; //类名定义行
int nIndex = strLine.Find('{');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -