5,139,275 members and growing! (12,216 online)
Email Password   helpLost your password?
Web Development » Applications & Tools » Tools with source code     Intermediate License: The Code Project Open License (CPOL)

LintProject - Improving the usability of PC-Lint with Visual C++ solutions and projects

By Anna-Jayne Metcalfe, -+- Beth Mackenzie -+-

Utility to run PC-Lint on Visual C++ solutions and projects, generating XML and HTML reports of the results.
XML, VC7.1, C++, HTMLWindows, NT4, Win2K, WinXP, MFC, VS.NET2002, VS.NET2003, VS6, VS, Dev

Posted: 10 Oct 2004
Updated: 7 Mar 2005
Views: 75,390
Announcements



Search    
Advanced Search
Sitemap
25 votes for this Article.
Popularity: 6.23 Rating: 4.45 out of 5
2 votes, 8.0%
1
2 votes, 8.0%
2
1 vote, 4.0%
3
1 vote, 4.0%
4
19 votes, 76.0%
5

LintProject in action. Note the HTML report being updated

Introduction

LintProject is a command line tool intended to make the process of using the PC-Lint code analysis tool produced by Gimpel software with Visual C++ projects a little easier and more productive.

PC-Lint analyses C++ code to identify potential problems. By comparison with a C++ compiler such as that provided with Visual C++, it is highly customizable and very thorough, but (understandably) significantly slower. The output it produces is file based and directed to the console by default, for example:

 --- Module: CJFlatHeaderCtrl.cpp
}
CJFlatHeaderCtrl.cpp(160): error 1401: 
       (Warning -- member 'CCJFlatHeaderCtrl::m_bSortAsc'
(line 146, file ..\Include\CJFlatHeaderCtrl.h) not initialized by constructor)

}
CJFlatHeaderCtrl.cpp(166): error 1740: 
      (Info -- pointer member'CCJFlatHeaderCtrl::m_pParentWnd'
(line 150, file ..\Include\CJFlatHeaderCtrl.h) 
      not directly freed or zero'ed by destructor

-- Effective C++ #6)


--- Global Wrap-up
error 900: (Note -- Successful completion, 2 messages produced)

Although PC-Lint does a great job of analyzing C++ source and header files for potential problems, it is a generic cross-platform tool and as such its integration with development environments is limited. For example, when used with Visual C++, PC-Lint can be used to scan the current file for warnings and direct the results to the Output window, or to scan a list of files defined in a text file.

While this level of integration is perfectly adequate under some scenarios (for example, when developing new classes), it is less than ideal if you want to perform a complete analysis of an entire project or solution. Furthermore, since PC-Lint does not provide any means of generating useful reports on the results, it can be difficult to spot potential problems amongst the mass of results.

If you are working with a large project, these limitations can make using PC-Lint to analyze your code time consuming and difficult, which can potentially be a real disincentive to using this very useful tool on a regular basis. As a result, the quality of your code could well suffer.

LintProject was written to address two of these issues. Unlike PC-Lint, LintProject can read both Visual C++ project and solution files. It can be run against either a complete solution or an individual project:

  • When run against a project, it reads the Visual C++ project file (.dsp or .vcproj) and instructs PC-Lint which files to analyze. For each file analyzed, the PC-Lint output is captured and recorded in a text file for later analysis.
  • When run against a complete solution, LintProject reads the Visual C++ solution file (.sln or .dsw) and recursively analyses the projects it contains.

XML and HTML Reports

Whilst the availability of text files containing the results of the analysis is an essential result of the process, without a means of summarizing their contents and indexing them, the process of interpreting the results is likely to be slow and laborious.

LintProject provides a convenient solution to this problem by writing XML and HTML reports which link to the result files and indicate how many warnings were found within each implementation file, project and solution:

Example HTML output for a solution. Each project Example HTML output for a project. Each implementation file

Example HTML output

A key design aim of LintProject was to be capable of indicating its process whilst it runs. This is especially important when you consider that a PC-Lint analysis of a large project can take some considerable time on some systems. To achieve this aim, the output reports produced by LintProject are automatically regenerated as the analysis progresses. Even better, any supported browser windows* displaying the corresponding result files will automatically refresh as each file is analyzed. This gives immediate feedback on the progress of the analysis, and is proving to be a very useful feature.

* At present, this feature supports only Internet Explorer and derived browsers such as Crazy Browser, Avant browser etc. Hopefully, we will be able to add similar functionality for Mozilla, Firefox and Opera at some time in the future.

Installation

Installation of LintProject is straightforward. The simplest method is simply to place the executable (LintProject.exe) into the same folder as the PC-Lint executable (lint-nt.exe). If you prefer to locate LintProject.exe elsewhere, the /f switch can be used to tell it where to find the PC-Lint executable.

Using LintProject

LintProject is invoked by a simple command line, for example:

  • LintProject <SolutionName.sln> <ResultsFolder> [options]

    or

  • LintProject <ProjectName.vcproj> <ResultsFolder> [options]

There are four additional options:

  • /f<FolderName>

    Specifies the location of the LintProject executable. This is only required if LintProject is installed in a different folder from the PC-Lint executable.

  • /l"<parameters>"

    Passes the following parameters to the PC-Lint executable (lint-nt.exe). For example, /l" -background" will instruct PC-Lint to perform analysis at a low priority.

  • /s

    Specifies that the HTML output should be automatically opened in a browser window when analysis starts.

  • /?

    Display help information.

LintProject runs the PC-Lint executable (lint-nt.exe) on each source file individually, instructing it to redirect its output to a text file which is linked to from the corresponding HTML report. For each file, a command line such as the following is used:

<lint-folder>\lint-nt.exe -i"<lint-folder>" -b -u std.lnt
env-vc6.lnt -i"Debug" <source file> >Lint\<source file>.txt

std.lnt and env-vc6.lnt are standard options files produced by the PC-Lint installation - the latter being specific to Visual C++ 6.0 projects. Although the PC-Lint installation will install only one such file into the PC-Lint installation folder by default, copies of the others are available in the lnt subfolder.

LintProject will use env-vc6.lnt for Visual C++ 5.0 and 6.0 projects (<projectname>.dsp) and env-vc7.lnt for Visual C++ .NET projects (<projectname>.vcproj), so it is a good idea to place the options files you expect to use in the PC-Lint installation folder itself.

Source Code

LintProject is a fairly straightforward command line application built using the static library version of the MFC library. Note that MFC was used more for convenience at the time than anything else - the classes used to parse Visual C++ Solution (.sln or .dsw) and Project (.vcproj or .dsp) files were taken directly from ResOrg, and originally written under MFC. The dependency on MFC may well be removed at a later date.

Parser and utility classes aside, the LintProject essentially consists of three classes - CFileLintAnalyser, CProjectLintAnalyser and CSolutionLintAnalyser - which together control the entire process of Linting the specified project or solution. These classes invoke PC-Lint, index its output, and generate output reports in both XML and HTML formats (the latter by transforming the XML using XSLT stylesheets).

One issue which became apparent early on was that the time taken to analyze a complete project using PC-Lint can be very significant as a consequence of its depth of coverage. To allow the user to see the progress of the analysis, LintProject regenerates its output reports as the analysis progresses. An added dimension is added by its ability to refresh any browser window on the host PC displaying its reports as the analysis progresses (it's actually quite mesmerizing watching the warning count steadily climb...).

Implementing the browser refresh is one of those techniques which falls into the category of "easy once you know how". It is achieved by enumerating all of the WebBrowser controls open on the local machine using the SHDocVw::IShellWindows interface (see MSDN KB article 176792 - "How To Connect to a Running Instance of Internet Explorer").

For each control retrieved, the URL it is displaying is compared with the canonicalized pathname of the report which has just been updated. If they match, the control is refreshed, causing the updated version of the report to be displayed:

/// Refresh all WebBrowser controls displaying the file with the given pathname

///

/// Note that this technique currently works

/// for Internet Explorer and derived browsers only

bool RefreshAllOpenBrowserWindows(const CString& sFullPathName)
{
    if (sFullPathName.IsEmpty() )
    {
        return false;
    }

    // Convert the pathname to a uniform URL ready

    // for comparison with the URL in each control

    DWORD dwLen = _MAX_PATH;
    CString sCompareURL;

    if (!::InternetCanonicalizeUrl(sFullPathName, 
                                   sCompareURL.GetBufferSetLength(_MAX_PATH), 
                                   &dwLen,
                                   ICU_BROWSER_MODE) )
    {
        return false;
    }
    sCompareURL.Replace( _T("//"), _T("///") );
    sCompareURL.Replace( _T('\\'), _T('/') );
    sCompareURL.MakeLower();

    SHDocVw::IShellWindowsPtr shellws = NULL;

    bool bSuccess = true;

    try
    {
        // Connect to an instance of the shell

        HRESULT hr = shellws.CreateInstance(__uuidof(SHDocVw::ShellWindows));
        if (FAILED(hr) )
        {
            throw hr;
        }

        // Enumerate through current open windows (Internet Explorer and Explorer)

        long lCount = shellws->GetCount();

        for (int i = 0; i < (int)lCount; i++)
        {
            // Get a current open shell window

            _variant_t vtIndex( (long)i);
            IDispatchPtr idisp = shellws->Item(vtIndex);
            if (idisp == NULL)
            {
                continue;
            }

            // Retrieve an interface to the WebBrowser control

            SHDocVw::IWebBrowser2Ptr pWebBrowser = NULL;
            hr = idisp->QueryInterface(IID_IWebBrowser2, (LPVOID *)&pWebBrowser);

            if (pWebBrowser != NULL)
            {
                // Which URL is it displaying?

                _bstr_t bsURL = pWebBrowser->GetLocationURL();

                CString sURL((LPCTSTR)bsURL);
                sURL.MakeLower();

                // Compare the browser URL to the url to be refreshed

                if (sURL == sCompareURL)
                {
                    // This WebBrowser control is displaying the file

                    // we're interested in, so refresh it

                    hr = pWebBrowser->Refresh();
                    if (SUCCEEDED(hr))
                    {
                        TRACE("browser refreshed correctly\n");
                    }
                }
            }
        }
    }
    catch(...)
    {
        // There's been a problem during the enumeration

        bSuccess = false;
    }

    // Clean-up

    shellws.Release();

    return bSuccess;
}

Unfortunately, this technique works only for Internet Explorer and derived browsers. Similar techniques could of course be used with any other browser which offers a COM interface and a method of enumerating open windows at a system level. If anyone knows of comparable interfaces which will work for Mozilla, Firefox and Opera, we'd be very interested to hear about them and will incorporate them into the code.

Finally, despite appearances to the contrary, LintProject is single threaded. Whilst it could have been written to spawn multiple analysis threads, the extra complexity this would cause just didn't seem worthwhile given its original target use of running with an overnight build.

FAQ

Can I use LintProject on its own?

No. To use LintProject, you must have a licensed copy of PC-Lint. Please contact Gimpel Software for ordering information for PC-Lint.

Which platforms does LintProject support?

LintProject should run on any Windows 2000 or later. This restriction is solely the result of the use of the Win32 function SHCreateDirectoryEx(); if you need a version of LintProject which runs on Windows 9x, please contact us and we will be happy to prepare a version without this restriction.

It has not yet been tested on the forthcoming Longhorn release of Windows.

Which versions of Visual C++ is LintProject compatible with?

LintProject is compatible with Visual C++ versions 5.0, 6.0, .NET 2002 and .NET 2003. Limited testing has also been successfully carried out with Visual C++ .NET 2005.

Compilation of the LintProject source requires Visual C++ .NET 2003.

What configuration does LintProject require?

None. Simply place the executable into the same folder as the PC-Lint executable (lint-nt.exe) and it should work quite happily.

If you prefer to locate LintProject.exe elsewhere, the /f switch can be used to tell it where to find the PC-Lint executable.

Can I pass my own parameters to the PC-Lint executable?

Yes. You can use the /l switch to pass parameters directly to lint-nt.exe.

I have Windows XP Service Pack 2 installed, and some of the links in the reports don't work

This is a direct result of the "Local Machine Zone Lockdown" policy introduced in Windows XP SP2, which prevents active content (including JavaScript code, which is included in the HTML reports to provide table sorting facilities) from running when HTML pages are accessed locally.

The following articles discuss the lockdown and its implications:

According to the articles we've read on this, it should be possible to circumvent this by adding "The mark of the web" (in Microsoft terminology) to the generated HTML. Unfortunately, so far this has proved unreliable or has had unwanted side effects. We will continue to look for a way to circumvent this restriction, but for now it can be worked around quite simply by either clicking on the Information Bar when the warning appears and selecting the "Allow Blocked Content" option, or checking the "Allow active content to run in files on My Computer" option in the "Advanced" page of Internet Options:

Windows XP SP2 security options

Note that this issue only affects Internet Explorer. Other browsers should be unaffected.

Which additional system DLLs does LintProject require, and what versions?

LintProject requires MSXML3 to generate HTML reports. Although it should be installed by default on Windows XP systems, it can be manually installed if necessary by installing the XML SDK (supplied with the Platform SDK).

Aside from MSXML3, LintProject should not require any additional system DLLs to be installed. Please let us know if you have difficulties using it on your system.

Version History

7th March 2004

LintProject version 1.2.4 released to CodeProject. The following improvements have been made:

  • CSolutionLintAnalyser::Analyse() and CProjectLintAnalyser::Analyse() now use SHCreateDirectoryEx() instead of mkdir() to create folders for analysis results so that recursive folders are automatically created. Note: this function requires Windows 2000 or later.
  • Fix to UNC path checking suggested on the LintProject CP forum.
  • Improved handling of relative pathnames. Analysis and source files no longer need reside on the same logical drive.
  • Added support for passing parameters directly to lint-nt.exe via a new command line option (/l"<params>").
  • If a warning count of 255 is returned from lint-nt.exe, CFileLintAnalyser::Analyse() will now parse the results file to try to retrieve the true warning count.
  • Re-implemented the FileExists() helper function.
  • Added solution to source code control.
  • Modifications to allow operation on systems where PC-Lint is installed in a pathname containing spaces (e.g., C:\Program Files\Lint).

October, 2004

LintProject version 1.2.2 released to CodeProject.

Finally...

The original version of LintProject was written by Anna during her employment at Sonardyne International Limited. We would like to express our gratitude to them (and in particular, Bruce Baker and Richard Baldock) for agreeing to release ownership of the source to us so that we could maintain and further develop it.

LintProject is freeware. You may use it without restriction, provided all copyright notices in the code and stylesheets remain intact. We hope it proves to be as useful to you as it has to us, and we welcome your suggestions for future enhancements and improvements.

For the latest information on LintProject, please visit the Riverblade website.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Authors

Anna-Jayne Metcalfe


I haven't always written software for a living. When I graduated from Surrey University in 1989, it was with an Electronic Engineering degree, but unfortunately that never really gave me the opportunity to do anything particularly interesting (with the possible exception of designing Darth Vader's Codpiece * for the UK Army in 1990 - but that's another story...).
    * Also known as the Standard Army Bootswitch
Since the opportunity arose to lead a software team developing C++ software for Avionic Test Systems in 1996, I've not looked back. More recently I've been involved in the development of subsea acoustic navigation systems (with Sonardyne International Ltd), and I'm now working as a freelance software consultant for Riverblade Limited.

One of my personal interests is add-in development. The Resource ID Organiser Add-In for Visual C++ was my first attempt at an add-in, and I'm currently working on Visual Lint, an add-in which closely integrates the PC-Lint code analysis tool with Visual Studio .NET.

I love lots of things, but particularly music, anything historical (especially if it gives me the opportunity to have a bit of sword practice!), reading, chatting and being with friends. I despise ignorant, intolerant and obstructive people - and it shows...I can be a bolshy cow if you wind me up the wrong way...:laugh

I'm currently based 15 minutes walk from the beach in Bournemouth on the south coast of England. Since I moved here I've grown to love the place - even if it is full of grockles in Summer!
Occupation: Founder
Company: Riverblade Limited
Location: United Kingdom United Kingdom

-+- Beth Mackenzie -+-


Co-developing Riverblade Ltd Visual Lint as well working as development consultant providing world applications in the Defensive and non-defensive industries.

I have worked in the ICT industry for many years. I like to find imaginative solutions to problem solving. I have a flexible and varied skillset and varied industry/business experience.

My primarily skillset consists of Windows C++ (> 6 years) and C# (> 1 year), incorporating Frameworks WTL, MFC, ATL, and COM. I also enjoy working with databases - Microsoft Access, SQL Server (2000+), Oracle (>= 10g).


Occupation: Software Developer
Company: Riverblade Ltd
Location: United Kingdom United Kingdom

Other popular Applications & Tools articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 76 (Total in Forum: 76) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralMay be interesting... Installation of PC-LintmemberKarpov Andrey8:55 7 Dec '07  
GeneralFix for sRelativePath workspace pathsmemberNoXQS22:18 3 Jul '07  
GeneralFix for more than 255 errorsmemberNoXQS17:24 3 Jul '07  
GeneralFix for error 89: Argument or option too long ('String')memberNoXQS16:57 3 Jul '07  
QuestionBugfixmemberGulus4:29 30 Oct '06  
GeneralRefreshAllOpenBrowserWindows problemmemberPeter Miller7:10 23 Mar '06  
QuestionBug or missing feature?..memberrbid23:00 14 Feb '06  
AnswerRe: Bug or missing feature?..memberAnna-Jayne Metcalfe12:51 19 Feb '06  
GeneralMFC71.DLL ProblemmemberGerry Murphy6:44 20 Jan '06  
GeneralRe: MFC71.DLL ProblemmemberAnna-Jayne Metcalfe8:22 20 Jan '06  
GeneralRe: MFC71.DLL ProblemmemberGerry Murphy8:46 20 Jan '06  
GeneralRe: MFC71.DLL ProblemmemberAnna-Jayne Metcalfe9:15 20 Jan '06  
GeneralRe: MFC71.DLL ProblemmemberGerry Murphy9:28 20 Jan '06  
GeneralRe: MFC71.DLL ProblemmemberAnna-Jayne Metcalfe9:36 20 Jan '06  
GeneralOrder of parameterssitebuilderUwe Keim19:28 24 May '05  
GeneralRe: Order of parametersmemberAnna-Jayne Metcalfe21:00 24 May '05  
GeneralRe: Order of parameterssitebuilderUwe Keim21:32 24 May '05  
GeneralRe: Order of parametersmemberAnna-Jayne Metcalfe23:38 24 May '05  
GeneralRe: Order of parameterssitebuilderUwe Keim23:56 24 May '05  
Generalhellomembervijayan.S20:20 25 Mar '07