<html>
<head>
<style>
P
{
margin:0px;
padding:0px
}
body
{
FONT-SIZE: 10pt;
FONT-FAMILY:Tahoma
}
</style>
</head>
<body><BLOCKQUOTE style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #008080 2px solid; MARGIN-RIGHT: 0px"><BR>
<META content="Microsoft SafeHTML" name=Generator>
<STYLE>
.ExternalClass P
{padding:0px;}
.ExternalClass
{font-size:10pt;font-family:Tahoma;}
</STYLE>
<BR>Hello,<BR>My name is Johnny Lee. I have developed a *ahem* perl script which scans C/C++ source files for typos. <BR>&nbsp;<BR>I ran the typo.pl script on the released Python 2.5 source code. <BR><BR>The scan took about two minutes and produced ~340 typos.<BR><BR>After spending about 13 minutes weeding out the obvious false positives, 149 typos remain.<BR>&nbsp;<BR>One of the pros/cons of the script is that it doesn't need to be intergrated into the build process to work.<BR>It just searches for files with typical C/C++ source code file extensions and scans them.<BR>The downside is if the source file is not included in the build process, then the script is scanning an irrelevant file.<BR>Unless you aid the script via some parameters, it will scan all the code, even stuff inside #ifdef's<BR>that wouldn't normally be compiled.<BR>&nbsp;<BR>You can access the list of typos from &lt;<A href="http://www.geocities.com/typopl/typoscan.htm" target=_blank>http://www.geocities.com/typopl/typoscan.htm</A>&gt;<BR>The Perl 1999 paper can be read at &lt;<A href="http://www.geocities.com/typopl/index.htm" target=_blank>http://www.geocities.com/typopl/index.htm</A>&gt;<BR>&nbsp;<BR>I've mapped the Python memory-related calls PyMem_Alloc, <FONT>PyMem_<FONT>Realloc</FONT></FONT>, etc. to the same behaviour as the C std library malloc, realloc, etc. since<BR>Include\pymem.h seem to map them to those calls. If that assumption is not valid, then you can ignore typos that involve those PyMem_XXX calls.<BR>&nbsp;<BR>&nbsp;<BR>The Python 2.5&nbsp;typos can be classified into 7 types.<BR>&nbsp;<BR>1) if (X = 0)<BR>Assignment within an if statement. Typically a false positive, but sometimes it catches something valid.<BR>In Python's case, the one typo is:<BR>&nbsp;if (status = ERROR_MORE_DATA)<BR>but the previous code statement returns an error code into the status variable.<BR>&nbsp;<BR>2) realloc overwrite src if NULL, i.e. p = realloc(p, new_size);<BR>If realloc() fails, it will return NULL. If you assign the return value to the same variable you passed into realloc,<BR>then you've overwritten the variable and possibly leaked the memory that the variable pointed to.<BR>&nbsp;<BR>3) if (CreateFileMapping == IHV)<BR>On Win32, the CreateFileMapping() API will return NULL on failure, not INVALID_HANDLE_VALUE.<BR>The Python code does not check for NULL though.<BR>&nbsp;<BR>4) if ((X!=0) || (X!=1))<BR>The problem with code of this type is that it doesn't work. In the Python case, we have in a large if statement:<BR>&nbsp;quotetabs &amp;&amp; ((data[in]!='\t')||(data[in]!=' '))<BR>Now if data[in] == '\t', then it will fail the first data[in] but it will pass the second data[in] comparison.<BR>Typically you want "&amp;&amp;" not "||".<BR><BR>5) using API result w/no check<BR>There are several APIs that should be checked for success before using the returned ptrs/cookies, i.e.<BR>malloc, realloc, and fopen among others.<BR>&nbsp;<BR>6) XX;;<BR>Just being anal here. Two semicolons in a row. Second one is extraneous.<BR>&nbsp;<BR>7) extraneous test for non-NULL ptr<BR>Several memory calls that free memory accept NULL ptrs. <BR>So testing for NULL before calling them is redundant and wastes code space.<BR>Now some codepaths may be time-critical, but probably not all, and smaller code usually helps.<BR><BR>If you have any questions, comments, feel free to email. I hope this scan is useful.<BR>&nbsp;<BR>Thanks for your time,<BR>J<BR><BR></BLOCKQUOTE><br /><hr />Use Messenger to talk to your IM friends, even those on Yahoo! <a href='http://ideas.live.com/programpage.aspx?versionId=7adb59de-a857-45ba-81cc-685ee3e858fe' target='_new'>Talk now!</a></body>
</html>