Changes between Version 1 and Version 2 of splint

Show
Ignore:
Timestamp:
07/28/10 02:18:52 (11 years ago)
Author:
Util
Comment:

Add formatting to Splint Wiki page

Legend:

Unmodified
Added
Removed
Modified
  • splint

    v1 v2  
    1 Splint 
     1= Splint = 
     2 
    23I'm not really sure how to organize this page; I'm hoping that myself and others can expand it, and eventually, converge on something that actually works. I actually started writing this months ago as docs/splint.pod, which is why it looks an awful lot like POD. Please feel free to expand, correct, and reorganize as you see fit. 
    34 
    4 OVERVIEW 
     5= OVERVIEW = 
     6 
    57I'm writing this to document my experiences (and failures) with getting this to work, in the hopes that it's useful to others who are also working on this. 
    68 
     
    1113Unfortunately, splint's parser is just as strict as its warning generator is. Also unfortunately, a parse error causes splint to exit right then and there, preventing it from giving you a nifty summary at the end. And the "parse error" message tells you very little of value in finding and fixing the problem. 
    1214 
    13 SYNOPSIS 
     15= SYNOPSIS = 
     16{{{ 
    1417perl Configure.pl --cgoto=0 
    1518make splint 
     19}}} 
    1620 
    17 STRATEGY 
     21= STRATEGY = 
    1822Splint has internal libraries defining common system headers. There's an "ansi" library, there's a "posix" library (extending the ANSI one), and a "unix" library (extending the POSIX one). If a file includes stdio.h, it checks its library to see if it contains a version of stdio.h, and if it does, it uses the library version instead of the one provided by your system C library headers. 
    1923 
     
    2226I think this is a fundamental difference in philosophy, which we need to overcome. Splint wants things to be as generic as possible, but parrot is trying to be as specific as possible. I don't know what the best strategy to reconcile this is, but there are 2 obvious possibilities: 
    2327 
    24 Convince splint to use the system headers as much as possible. 
    25 Convince splint to use the system headers as little as possible. 
     28    1. Convince splint to use the system headers as much as possible. 
     29    2. Convince splint to use the system headers as little as possible. 
     30 
    2631Option 1 allows parrot to use whatever platform-specific things it has detected, but required (at least, for me) a lot of work convincing splint to parse my system headers properly. This involves disabling splint's header-libraries as much as possible, and then just trying to run it, seeing what breaks, finding a fix or workaround, and repeating until it passes. The below "Parse error in a system header file" section describes some specific issues I found there, and how I worked around them. 
    2732 
     
    3035My personal feeling at the moment is that Option 2 is the way to go. I'm hoping that if we can get the has_header.h and feature.h contents right, all of the problems I've been having with Option 1 will just vanish. 
    3136 
    32 PROBLEMS I'VE RUN INTO 
     37= PROBLEMS I'VE RUN INTO = 
    3338There are several types of problems which have often cropped up, for me. The end result is usually an uninformative parse error. 
    3439 
     
    3641Common sources for this problem: 
    3742 
    38 conflict between splint's "header library" and a system header 
     43== conflict between splint's "header library" and a system header == 
    3944 
    4045This occurs when a system header is not covered by splint's internal library, but relies on another header that was defined by a splint library, and defined in an incompatible fashion. In my case, "+posixstrictlib" caused splint to use an internal version of netinet/in.h, but not an arpa/inet.h. Unfortunately, my arpa/inet.h relied on netinet/in.h to define an "in_addr_t" typedef, which splint's library version didn't. The solution is to disable +posixstrictlib, or (in my arpa/inet.h case) upgrade to +unixstrictlib. 
    4146 
    42 build-specific defines required 
     47== build-specific defines required == 
    4348 
    4449This occurs when a system header expects the compiler to define some build-specific stuff. In #parrot, particle mentioned a problem where his winnt.h was relying on MSVC to define something specifying which target the source was being built for. The solution is to figure out what needs to be defined, and define it on the splint command-line, with a -D option. 
    4550 
    46 __attribute syntax 
     51== `__attribute syntax` == 
    4752 
    48 This occurs when a system header uses "__attribute" instead of "__attribute__". Note the trailing underscores, in the latter. Apparently, 
    49 splint recognises the latter, but not the former. Unfortunately, my system has glibc headers, and glibc's pthread.h uses __attribute all over the place. The solution for this is to define __attribute to __attribute__ on the splint command line, by adding an option like "-D__attribute=__attribute__". 
     53This occurs when a system header uses "`__attribute`" instead of "`__attribute__`". Note the trailing underscores, in the latter. Apparently, 
     54splint recognizes the latter, but not the former. Unfortunately, my system has glibc headers, and glibc's pthread.h uses `__attribute` all over the place. The solution for this is to define `__attribute` to `__attribute__` on the splint command line, by adding an option like "`-D__attribute=__attribute__`". 
    5055 
    51 C library dependence on compiler headers 
     56== C library dependence on compiler headers == 
    5257 
    5358Glibc was written with gcc in mind. The headers in /usr/include sometimes depend on compiler-specific stuff, either language parser extensions, or things defined by gcc headers in /usr/lib/gcc-lib/*. From this perspective, splint is essentially just a different compiler (though it doesn't generate any binaries, so we can't just do a "perl Configure.pl --cc=splint" directly). 
    5459 
    55 Recursive #define in a header file 
     60== Recursive #define in a header file == 
    5661 
    5762My /usr/include/bits/confname.h includes both enums and defines for the same tokens. It looks like this: 
    58  
     63{{{ 
    5964enum 
    6065{ 
     
    6368_PC_MAX_CANON, 
    6469#define _PC_MAX_CANON _PC_MAX_CANON 
    65  
     70}}} 
    6671etc, etc. I'm guessing they want to use an enum for compile-time typechecking, but retain compatibility with code that uses #ifdef to determine its presence, or something. Anyway, splint barfs on this with an "internal error": 
    67  
     72{{{ 
    6873/usr/include/bits/confname.h:31:27: *** Internal Bug at cscannerHelp.c:2422: Unexpanded macro not function or constant: int _PC_MAX_CANON [errno: 25] 
    6974     *** Please report bug to splint-bug@splint.org *** 
     
    7176/usr/include/bits/confname.h:32:1: Parse Error: Non-function declaration: _PC_MAX_CANON : int. (For help on parse errors, see splint -help parseerrors.) 
    7277*** Cannot continue. 
    73  
    74 The nice thing about this error, of course, is that it waits until after all sourcefile processing to emit this error. Which means you think everything's running great, and yet you're denied your nifty summary at the end. 
     78}}} 
     79The nice thing about this error, of course, is that it waits until after all sourcefile processing to emit this error. Which means you think everything is running great, and yet you're denied your nifty summary at the end. 
    7580 
    7681For now, I've wrapped my system include with #ifndef S_SPLINT_S. But its another argument in favor of keeping splint as far away from system headers as possible... 
    7782 
    78 Parse error in a Parrot source (or header) file 
     83== Parse error in a Parrot source (or header) file == 
    7984This section handles problems on a case by case basis. 
    8085 
     
    8388These files are an implementation of the "CGoto" runloop. The CGoto runloop implements an array of pointers to goto target symbols, and uses nonstandard (gcc-specific) syntax which splint cannot parse. The solution is to re-run Configure.pl with the "--cgoto=0" option. 
    8489 
    85 AVAILABLE TOOLS AND REFERENCES 
     90= AVAILABLE TOOLS AND REFERENCES = 
    8691Splint has a reference manual, available at http://www.splint.org/manual/manual.html. 
    8792 
     
    9095Splint also has a "+keep" option, which causes it to tell you where to find its temporary (preprocessed) files, and to not automatically remove them. This flag is very useful to see the preprocessed output that splint actually parses, and thus, see what caused a parse error. 
    9196 
    92 UPDATED CODE 
     97= UPDATED CODE =  
    9398I've had splint crash on me, and I think it's because negative shifts cause a crash, rather than generating a splint error. This bug has been fixed in the CVS version of the code. The CVS version builds just fine.