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"));