1 //*******************************************************************************
4 // You may use this source code, compile or redistribute it as part of your application
5 // for free. You cannot redistribute it as a part of a software development
6 // library without the agreement of the author. If the sources are
7 // distributed along with the application, you should leave the original
8 // copyright notes in the source code without any changes.
9 // This code can be used WITHOUT ANY WARRANTIES at your own risk.
11 // For the latest updates to this code, check this site:
12 // http://www.masmex.com
15 // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
16 //*******************************************************************************
19 #include "TextParse.h"
21 CTextParse::CTextParse()
24 m_pStartLine = m_szBuffer;
26 m_pSavePos = m_szBuffer;
29 CTextParse::CTextParse(LPCTSTR pszLine)
35 CTextParse::~CTextParse()
39 CTextParse::CTextParse(const CTextParse &tp)
42 m_pStartLine = tp.m_pStartLine;
43 m_pSavePos = tp.m_pSavePos;
44 m_szCopyBuf[0] = '\0';
46 _tcscpy(m_szCopyBuf,tp.m_szCopyBuf);
47 _tcscpy(m_szBuffer,tp.m_szBuffer);
50 const CTextParse& CTextParse::operator=(LPCTSTR lpsz)
53 m_szCopyBuf[0] = '\0';
58 const CTextParse& CTextParse::operator=(const CTextParse &tp)
63 m_pStartLine = tp.m_pStartLine;
64 m_pSavePos = tp.m_pSavePos;
65 _tcscpy(m_szCopyBuf,tp.m_szCopyBuf);
66 _tcscpy(m_szBuffer,tp.m_szBuffer);
70 BOOL CTextParse::CharExistFromCurPos(int c,BOOL bForward)
80 while (p > m_pStartLine && *p != c)
81 p = _tcsdec(m_pLine,p);
86 BOOL CTextParse::ValidCppCharExist(int c,BOOL bForward)
89 while (*p && *p != c && *p != '/')
94 BOOL CTextParse::CharExist(LPCTSTR str)
96 LPCTSTR p = m_pStartLine;
97 while (*p && !IsToken(str,p))
102 BOOL CTextParse::FindString(LPCTSTR str)
104 LPCTSTR p = _tcsstr(m_pLine,str);
107 return p ? TRUE : FALSE;
110 BOOL CTextParse::FindChar(int c)
112 LPCTSTR p = _tcschr(m_pLine,c);
115 return p ? TRUE : FALSE;
118 BOOL CTextParse::MoveUntilChar(int c,BOOL bForward)
122 while(*m_pLine && *m_pLine != c)
123 m_pLine = _tcsinc(m_pLine);
124 return *m_pLine != '\0';
128 while(m_pLine > m_pStartLine && *m_pLine != c)
129 m_pLine = _tcsdec(m_pStartLine,m_pLine);
130 return *m_pLine == c;
134 BOOL CTextParse::MoveUntilChar(LPCTSTR strTok,BOOL bForward)
138 while(*m_pLine && !IsToken(strTok,m_pLine))
139 m_pLine = _tcsinc(m_pLine);
140 return *m_pLine != '\0';
144 while(m_pLine > m_pStartLine && !IsToken(strTok,m_pLine))
145 m_pLine = _tcsdec(m_pStartLine,m_pLine);
146 return IsToken(strTok,m_pLine);
150 BOOL CTextParse::MoveUntilString(LPCTSTR str,BOOL bForward)
154 while(*m_pLine && !IsString(str))
155 m_pLine = _tcsinc(m_pLine);
156 return *m_pLine != '\0';
160 while(m_pLine > m_pStartLine && !IsString(str))
161 m_pLine = _tcsdec(m_pStartLine,m_pLine);
162 return IsString(str);
166 BOOL CTextParse::MoveWhileChar(int c,BOOL bForward)
170 while(*m_pLine && *m_pLine == c)
171 m_pLine = _tcsinc(m_pLine);
172 return *m_pLine != '\0';
176 while(m_pLine > m_pStartLine && *m_pLine == c)
177 m_pLine = _tcsdec(m_pStartLine,m_pLine);
178 return *m_pLine == c;
182 BOOL CTextParse::MoveWhileChar(LPCTSTR strTok,BOOL bForward)
186 while(*m_pLine && IsToken(strTok,m_pLine))
187 m_pLine = _tcsinc(m_pLine);
188 return *m_pLine != '\0';
192 while(m_pLine > m_pStartLine && IsToken(strTok,m_pLine))
193 m_pLine = _tcsdec(m_pStartLine,m_pLine);
194 return IsToken(strTok,m_pLine);
198 LPCTSTR CTextParse::CopyWhileChar(int c)
200 for(int i=0;i < MAX_BUF && *m_pLine != '\0' && *m_pLine == c;i++)
202 m_szCopyBuf[i] = *m_pLine;
203 m_pLine = _tcsinc(m_pLine);
205 m_szCopyBuf[i] = '\0';
209 LPCTSTR CTextParse::CopyUntilString(LPCTSTR pszText)
211 int nLen = _tcslen(pszText);
212 for(int i=0;i < MAX_BUF && *m_pLine != '\0' && _tcsncmp(m_pLine,pszText,nLen) != 0;i++)
214 m_szCopyBuf[i] = *m_pLine;
215 m_pLine = _tcsinc(m_pLine);
217 m_szCopyBuf[i] = '\0';
221 LPCTSTR CTextParse::CopyUntilChar(int c)
223 for(int i=0;i < MAX_BUF && *m_pLine != '\0' && *m_pLine != c;i++)
225 m_szCopyBuf[i] = *m_pLine;
226 m_pLine = _tcsinc(m_pLine);
228 m_szCopyBuf[i] = '\0';
232 LPCTSTR CTextParse::CopyWhileChar(LPCTSTR strTok)
234 for(int i=0;i < MAX_BUF && *m_pLine != '\0' && IsToken(strTok,m_pLine);i++)
236 m_szCopyBuf[i] = *m_pLine;
237 m_pLine = _tcsinc(m_pLine);
239 m_szCopyBuf[i] = '\0';
243 LPCTSTR CTextParse::CopyUntilChar(LPCTSTR strTok)
245 for(int i=0;i < MAX_BUF && *m_pLine != '\0' && !IsToken(strTok,m_pLine);i++)
247 m_szCopyBuf[i] = *m_pLine;
248 m_pLine = _tcsinc(m_pLine);
250 m_szCopyBuf[i] = '\0';
254 LPCTSTR CTextParse::CopyFuncUntilChar(LPCTSTR strTok)
256 for(int i=0;i < MAX_BUF && !IsEnd() && !IsToken(strTok,m_pLine);i++)
258 /* if (*m_pLine == '=') {
260 if (m_szCopyBuf[i-1] == ' ') {
264 if (CharAtCurrent('/'))
267 MoveUntilChar(_T("/"));
268 if (m_szCopyBuf[i-1] == ' ')
274 m_szCopyBuf[i] = *m_pLine;
277 m_szCopyBuf[i] = '\0';
281 BOOL CTextParse::IsToken(LPCTSTR strTok,LPCTSTR p)
287 strTok = _tcsinc(strTok);
289 return *strTok != '\0';
292 LPCTSTR CTextParse::ExtractConstructor()
296 _tcscat(m_szCopyBuf,_T(")"));
300 LPCTSTR CTextParse::ExtractDeclareMacro()
302 return CopyUntilChar('(');
305 LPCTSTR CTextParse::ExtractFuncName()
309 if (_tcsncmp(m_pLine,_T("const"),5) == 0 || _tcsncmp(m_pLine,_T("afx_msg"),7) == 0 || _tcsncmp(m_pLine,_T("virtual"),7) == 0)
311 CopyUntilWhiteSpace();
312 MoveWhileWhiteSpace();
314 MoveUntilChar(_T("("));
315 MoveUntilWhiteSpace(FALSE);
316 if (*m_pLine == CPP_SPACE) // regular function
317 MoveWhileWhiteSpace();
319 { // else constructor or destructor
320 // allow for virtual destructors
321 if (_tcsncmp(m_pLine,_T("virtual"),7) == 0)
323 CopyUntilWhiteSpace();
324 MoveWhileWhiteSpace();
328 // returning pointer or reference
329 if (*m_pLine == '*' || *m_pLine == '&')
330 m_pLine = _tcsinc(m_pLine);
331 return CopyUntilChar('(');
334 LPCTSTR CTextParse::ExtractClassName()
336 MoveWhileWhiteSpace();
337 if (_tcsncmp(m_pLine,_T("class"),5) != 0)
343 // check if derived class
344 if (!CharExistFromCurPos(':'))
346 if (!CharExistFromCurPos('{'))
349 MoveWhileWhiteSpace(FALSE);
350 MoveUntilWhiteSpace(FALSE);
351 MoveWhileWhiteSpace();
356 MoveUntilWhiteSpace(FALSE);
357 MoveWhileWhiteSpace(FALSE);
358 MoveUntilWhiteSpace(FALSE);
359 MoveWhileWhiteSpace();
365 // go back and skip colon
366 MoveUntilWhiteSpace(FALSE);
367 MoveWhileWhiteSpace(FALSE);
368 if (CharAtCurrent('>'))
370 MoveUntilChar('<',FALSE);
371 MoveUntilWhiteSpace(FALSE);
372 MoveWhileWhiteSpace(FALSE);
374 MoveUntilWhiteSpace(FALSE);
375 MoveWhileWhiteSpace();
377 return CopyUntilChar(_T(" \t<"));
380 LPCTSTR CTextParse::ExtractBaseClassName()
383 MoveWhileWhiteSpace();
384 if (_tcsncmp(m_pLine,_T("class"),5) != 0)
390 // check if derived class
391 if (CharExistFromCurPos(':'))
396 MoveWhileWhiteSpace();
397 MoveUntilWhiteSpace();
398 MoveWhileWhiteSpace();
405 return CopyUntilChar(_T(" \t<"));
408 BOOL CTextParse::IsCommentBlock(LPCTSTR strStart,LPCTSTR strEnd)
410 LPCTSTR p = _tcsstr(m_pLine,strStart);
413 if (p == m_pStartLine && *(p+sizeof(TCHAR)*2) == '+')
415 if (p == m_pStartLine || (p != m_pStartLine && *(p-sizeof(TCHAR)) != '/') )
417 if (_tcsstr(m_pLine,strEnd) == NULL)
424 LPCTSTR CTextParse::CopyWholeWord()
427 for(int i=0;i < MAX_BUF && *m_pLine != '\0';i++)
433 else if (*m_pLine == ' ' && bQuote == false)
437 m_szCopyBuf[i] = *m_pLine;
438 m_pLine = _tcsinc(m_pLine);
441 m_szCopyBuf[i] = '\0';
445 LPCTSTR CTextParse::CopyUntilEnd()
447 for(int i=0;i < MAX_BUF && *m_pLine != '\0';i++)
449 m_szCopyBuf[i] = *m_pLine;
450 m_pLine = _tcsinc(m_pLine);
452 m_szCopyBuf[i] = '\0';
456 bool CTextParse::FindWholeWord(LPCTSTR pszText)
458 bool bQuote = _tcsstr(pszText,_T("\"")) != NULL;
459 if (*pszText == '+' || *pszText == '-')
460 pszText = _tcsinc(pszText);
461 int nLen = _tcslen(pszText);
463 for(int i=0;i < MAX_BUF && *m_pLine != '\0';i++)
470 nRet = _tcsncmp(m_pLine,pszText,nLen);
480 nRet = _tcsncmp(m_pLine,pszText,GetWordLen());
489 int CTextParse::GetWordLen()
492 for (int i=0;*p && !IsToken(CPP_WHITE_SPACE,p);i++)
499 bool CTextParse::SkipHTMLCommand(bool bSkipCRLF)
501 if (CharAtCurrent('&'))
504 if (CharAtCurrent(';'))
511 while (*p == '\r' || *p == '\n')
516 while (*p != '>' && *p != '\0')
524 void CTextParse::SkipHTMLCommands(bool bSkipCRLF)
526 while (SkipHTMLCommand(bSkipCRLF))
530 BOOL CTextParse::IsValidCPP(LPCTSTR pszText)
533 if (FindString(pszText))
535 // check if a comment
537 if (!MoveUntilString(_T("//"),FALSE))
540 if (!MoveUntilString(_T("/*"),FALSE))
548 BOOL CTextParse::IsPrivate()
550 return IsValidCPP(_T("private"));
553 BOOL CTextParse::IsPublic()
555 return IsValidCPP(_T("public"));
558 BOOL CTextParse::IsProtected()
560 return IsValidCPP(_T("protected"));
563 BOOL CTextParse::IsVirtualFunc()
565 return IsValidCPP(_T("virtual"));
568 BOOL CTextParse::IsStartBrace()
570 return IsValidCPP(_T("{"));
573 BOOL CTextParse::IsEndBrace()
575 return IsValidCPP(_T("}"));
578 BOOL CTextParse::IsAccessSpecifier()
580 return IsValidCPP(_T(":"));
583 BOOL CTextParse::IsConstructor(LPCTSTR pszClassName)
585 CString sTest(pszClassName);
592 return IsValidCPP(sTest);
595 BOOL CTextParse::IsMsgMap()
597 return FindString(_T("{{AFX_MSG"));
600 BOOL CTextParse::IsDeclareMacro()
603 if (IsValidCPP(_T("DECLARE_")))
605 if (!FindString(_T("()")))
612 BOOL CTextParse::IsStartCommentBlock()
614 if (!FindString(_T("//")))
615 return FindString(_T("/*"));
619 BOOL CTextParse::IsEndCommentBlock()
621 return FindString(_T("*/"));
624 BOOL CTextParse::IsClass()
627 if (FindString(_T("template")))
631 if (!StringAtCurrent(_T("class ")))
636 // any line comments before 'class '
637 MoveUntilString(_T("class "));
638 if (MoveUntilString(_T("//"),FALSE))
643 if (FindChar(_T(';')))
647 if (FindChar(_T('#')))
655 BOOL CTextParse::ExtractArgs(CString &sRet,CStringArray &asArgs)
659 if (!CharAtCurrent('(') && FindChar('('))
663 if (StringAtCurrent(_T("const")))
665 MoveUntilWhiteSpace();
668 sRet = CopyUntilWhiteSpace();
669 if (MoveUntilChar('('))
678 while (!CharAtCurrent(')') && !IsEnd())
681 if (StringAtCurrent(_T("const")))
683 MoveUntilWhiteSpace();
686 MoveUntilWhiteSpace();
688 if (StringAtCurrent(_T("void")))
690 if (CharAtCurrent('*') || CharAtCurrent('&'))
692 asArgs.Add(CopyUntilChar(_T(",)\t ")));
693 if (CharAtCurrent(','))
701 LPCTSTR CTextParse::ExtractHTMLText(bool bRemoveCRLF)
703 return ExtractHTMLText(_T("<"),bRemoveCRLF);
706 LPCTSTR CTextParse::ExtractHTMLText(LPCTSTR pszUntil,bool bRemoveCRLF)
708 int nLen=_tcslen(pszUntil);
711 while(i < MAX_BUF && *m_pLine != '\0' && _tcsncmp(m_pLine,pszUntil,nLen) != 0)
713 if (*m_pLine == '<' || *m_pLine == '&')
715 while (SkipHTMLCommand(false))
717 if (_tcsncmp(m_pLine,pszUntil,nLen) == 0)
726 if (bRemoveCRLF && (*m_pLine == '\n' || *m_pLine == '\r'))
728 m_pLine = _tcsinc(m_pLine);
732 m_szCopyBuf[i++] = *m_pLine;
733 m_pLine = _tcsinc(m_pLine);
736 m_szCopyBuf[i] = '\0';
740 LPCTSTR CTextParse::ExtractHTMLLink()
742 m_szCopyBuf[0] = '\0';
743 if (!FindString(_T("href=")))
751 LPCTSTR pRet = CopyUntilChar('"');