2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS project statistics
5 * PURPOSE: Main program file
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/01-2002 Created
14 typedef struct _EXTENSION_INFO
16 struct _EXTENSION_INFO
* Next
;
17 struct _FILE_INFO
* StatInfoList
;
19 TCHAR Description
[256];
22 } EXTENSION_INFO
, *PEXTENSION_INFO
;
24 typedef struct _FILE_INFO
26 struct _FILE_INFO
* Next
;
27 struct _FILE_INFO
* StatInfoListNext
;
28 PEXTENSION_INFO ExtInfo
;
32 } FILE_INFO
, *PFILE_INFO
;
43 PEXTENSION_INFO ExtInfoList
;
44 PFILE_INFO StatInfoList
;
64 PEXTENSION_INFO ExtInfo
;
65 PEXTENSION_INFO NextExtInfo
;
67 ExtInfo
= ExtInfoList
;
68 while (ExtInfo
!= NULL
)
70 NextExtInfo
= ExtInfo
->Next
;
71 HeapFree (GetProcessHeap(), 0, ExtInfo
);
72 ExtInfo
= NextExtInfo
;
78 AddExtension(LPTSTR ExtName
,
81 PEXTENSION_INFO ExtInfo
;
84 ExtInfo
= (PEXTENSION_INFO
) HeapAlloc (GetProcessHeap(), 0, sizeof (EXTENSION_INFO
));
87 ZeroMemory (ExtInfo
, sizeof (EXTENSION_INFO
));
88 _tcscpy (ExtInfo
->ExtName
, ExtName
);
89 _tcscpy (ExtInfo
->Description
, Description
);
94 while (Info
->Next
!= NULL
)
102 ExtInfoList
= ExtInfo
;
110 AddFile(LPTSTR FileName
,
111 PEXTENSION_INFO ExtInfo
)
116 StatInfo
= (PFILE_INFO
) HeapAlloc (GetProcessHeap(), 0, sizeof (FILE_INFO
));
119 ZeroMemory (StatInfo
, sizeof (FILE_INFO
));
120 _tcscpy (StatInfo
->FileName
, FileName
);
121 StatInfo
->ExtInfo
= ExtInfo
;
123 if (ExtInfo
->StatInfoList
)
125 Info
= ExtInfo
->StatInfoList
;
126 while (Info
->StatInfoListNext
!= NULL
)
128 Info
= Info
->StatInfoListNext
;
130 Info
->StatInfoListNext
= StatInfo
;
134 ExtInfo
->StatInfoList
= StatInfo
;
140 while (Info
->Next
!= NULL
)
144 Info
->Next
= StatInfo
;
148 StatInfoList
= StatInfo
;
160 HeapFree (GetProcessHeap(), 0, FileBuffer
);
167 LoadFile(LPTSTR FileName
)
173 FileHandle
= CreateFile (FileName
, // Create this file
174 GENERIC_READ
, // Open for reading
177 OPEN_EXISTING
, // Open the file
178 FILE_ATTRIBUTE_NORMAL
, // Normal file
179 NULL
); // No attribute template
180 if (FileHandle
== INVALID_HANDLE_VALUE
)
183 FileSize
= GetFileSize (FileHandle
, NULL
);
186 CloseHandle (FileHandle
);
190 FileBufferSize
= (DWORD
) FileSize
;
192 FileBuffer
= (PCHAR
) HeapAlloc (GetProcessHeap(), 0, FileBufferSize
);
195 CloseHandle (FileHandle
);
199 if (!ReadFile (FileHandle
, FileBuffer
, FileBufferSize
, &BytesRead
, NULL
))
201 CloseHandle(FileHandle
);
202 HeapFree (GetProcessHeap(), 0, FileBuffer
);
207 CloseHandle (FileHandle
);
220 * FUNCTION: Reads the next line into the line buffer
222 * TRUE if there is a new line, FALSE if not
228 if (CurrentOffset
>= FileBufferSize
)
232 while ((((j
= CurrentOffset
+ i
) < FileBufferSize
) && (i
< sizeof (Line
)) &&
233 ((ch
= FileBuffer
[j
]) != 0x0D && (ch
= FileBuffer
[j
]) != 0x0A)))
242 if ((FileBuffer
[CurrentOffset
+ i
] == 0x0D) && (FileBuffer
[CurrentOffset
+ i
+ 1] == 0x0A))
245 CurrentOffset
+= i
+ 1;
256 DoStatisticsForFile(PFILE_INFO StatInfo
)
261 StatInfo
->LineCount
= CurrentLine
;
268 PEXTENSION_INFO Info
;
269 DWORD TotalFileCount
;
270 DWORD TotalLineCount
;
281 if (Info
->FileCount
!= 0)
283 AvgLF
= Info
->LineCount
/ Info
->FileCount
;
291 _tprintf (_T("File extension : %s\n"), Info
->ExtName
);
292 _tprintf (_T("File ext. description : %s\n"), Info
->Description
);
293 _tprintf (_T("Number of files : %d\n"), Info
->FileCount
);
294 _tprintf (_T("Number of lines : %d\n"), Info
->LineCount
);
295 _tprintf (_T("Average no. lines/file : %d\n"), AvgLF
);
297 TotalFileCount
+= Info
->FileCount
;
298 TotalLineCount
+= Info
->LineCount
;
303 TotalAvgLF
= TotalLineCount
/ TotalFileCount
;
306 _tprintf (_T("Total number of files : %d\n"), TotalFileCount
);
307 _tprintf (_T("Total number of lines : %d\n"), TotalLineCount
);
308 _tprintf (_T("Average no. lines/file : %d\n"), TotalAvgLF
);
313 ProcessFiles(LPTSTR Path
)
315 WIN32_FIND_DATA FindFile
;
316 PEXTENSION_INFO Info
;
317 TCHAR SearchPath
[256];
325 ZeroMemory (&FindFile
, sizeof (FindFile
));
326 _tcscpy (SearchPath
, Path
);
327 _tcscat (SearchPath
, _T("\\*."));
328 _tcscat (SearchPath
, Info
->ExtName
);
329 _tcscpy (FindFile
.cFileName
, SearchPath
);
330 SearchHandle
= FindFirstFile (SearchPath
, &FindFile
);
331 if (SearchHandle
!= INVALID_HANDLE_VALUE
)
336 if (!(FindFile
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
338 _tcscpy (FileName
, Path
);
339 _tcscat (FileName
, _T("\\"));
340 _tcscat (FileName
, FindFile
.cFileName
);
342 if (LoadFile (FileName
))
346 StatInfo
= AddFile (FindFile
.cFileName
, Info
);
349 _tprintf (_T("Not enough free memory.\n"));
353 DoStatisticsForFile (StatInfo
);
356 Info
->LineCount
+= StatInfo
->LineCount
;
361 More
= FindNextFile (SearchHandle
, &FindFile
);
363 FindClose (SearchHandle
);
372 ProcessDirectories(LPTSTR Path
)
374 WIN32_FIND_DATA FindFile
;
375 TCHAR SearchPath
[MAX_PATH
];
379 _tprintf (_T("Processing directory %s\n"), Path
);
381 _tcscpy (SearchPath
, Path
);
382 _tcscat (SearchPath
, _T("\\*.*"));
384 SearchHandle
= FindFirstFileEx (SearchPath
,
387 FindExSearchLimitToDirectories
,
390 if (SearchHandle
!= INVALID_HANDLE_VALUE
)
395 if ((FindFile
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
396 && (_tcscmp (FindFile
.cFileName
, _T(".")) != 0)
397 && (_tcscmp (FindFile
.cFileName
, _T("..")) != 0)
398 && (_tcscmp (FindFile
.cFileName
, _T("CVS")) != 0))
400 _tcscpy (SearchPath
, Path
);
401 _tcscat (SearchPath
, _T("\\"));
402 _tcscat (SearchPath
, FindFile
.cFileName
);
403 if (!ProcessDirectories (SearchPath
))
405 if (!ProcessFiles (SearchPath
))
408 More
= FindNextFile (SearchHandle
, &FindFile
);
410 FindClose (SearchHandle
);
421 _tprintf (_T("No extensions specified.\n"));
425 if (!ProcessDirectories (Path
))
427 _tprintf (_T("Failed to process directories.\n"));
431 if (!ProcessFiles (Path
))
433 _tprintf (_T("Failed to process files.\n"));
442 main (int argc
, char * argv
[])
444 _tprintf (_T("\nReactOS project statistics generator.\n\n"));
448 _tprintf(_T("Usage: stats directory"));
453 AddExtension (_T("c"), _T("Source files"));
454 AddExtension (_T("h"), _T("Header files"));