reactos/apps/utils/stats
diff -u -r1.6 -r1.7
--- stats.c 8 Apr 2004 12:47:49 -0000 1.6
+++ stats.c 13 Apr 2004 21:34:45 -0000 1.7
@@ -21,6 +21,7 @@
TCHAR Description[256];
DWORD FileCount;
DWORD LineCount;
+ DWORD EmptyLines;
} EXTENSION_INFO, *PEXTENSION_INFO;
typedef struct _FILE_INFO
@@ -30,26 +31,29 @@
PEXTENSION_INFO ExtInfo;
TCHAR FileName[MAX_PATH];
DWORD LineCount;
+ DWORD EmptyLines;
DWORD FunctionCount;
} FILE_INFO, *PFILE_INFO;
HANDLE FileHandle;
-DWORD TotalLineCount;
PEXTENSION_INFO ExtInfoList;
PFILE_INFO StatInfoList;
+BOOLEAN SkipEmptyLines;
+
+#define MAX_OPTIONS 1
+TCHAR *Options[MAX_OPTIONS];
VOID
-Initialize()
+Initialize(VOID)
{
- TotalLineCount = 0;
ExtInfoList = NULL;
StatInfoList = NULL;
}
VOID
-Cleanup()
+Cleanup(VOID)
{
PEXTENSION_INFO ExtInfo;
PEXTENSION_INFO NextExtInfo;
@@ -157,7 +161,7 @@
VOID
-CleanupAfterFile()
+CleanupAfterFile(VOID)
{
if(FileHandle != INVALID_HANDLE_VALUE)
CloseHandle (FileHandle);
@@ -190,10 +194,10 @@
}
-DWORD
-ReadLines()
+VOID
+ReadLines(PFILE_INFO StatInfo)
{
- DWORD ReadBytes, LineLen, Lines = 0;
+ DWORD ReadBytes, LineLen;
static char FileBuffer[1024];
char LastChar = '\0';
char *Current;
@@ -201,51 +205,52 @@
LineLen = 0;
while(ReadFile (FileHandle, FileBuffer, sizeof(FileBuffer), &ReadBytes, NULL) && ReadBytes >= sizeof(char))
{
- if(ReadBytes & 0x1)
- ReadBytes--;
-
for(Current = FileBuffer; ReadBytes > 0; ReadBytes -= sizeof(char), Current++)
{
if(*Current == '\n' && LastChar == '\r')
{
LastChar = '\0';
- if(LineLen > 0)
- Lines++;
+ if(!SkipEmptyLines || (LineLen > 0))
+ StatInfo->LineCount++;
+ if(LineLen == 0)
+ StatInfo->EmptyLines++;
LineLen = 0;
+ continue;
}
- LineLen++;
LastChar = *Current;
+ if(SkipEmptyLines && (*Current == ' ' || *Current == '\t'))
+ {
+ continue;
+ }
+ if(*Current != '\r')
+ LineLen++;
}
}
- Lines += (LineLen > 0);
- return Lines;
+ StatInfo->LineCount += (LineLen > 0);
+ StatInfo->EmptyLines += ((LastChar != '\0') && (LineLen == 0));
}
VOID
-DoStatisticsForFile(PFILE_INFO StatInfo)
-{
- StatInfo->LineCount = ReadLines();
-}
-
-
-VOID
-PrintStatistics()
+PrintStatistics(VOID)
{
PEXTENSION_INFO Info;
DWORD TotalFileCount;
DWORD TotalLineCount;
DWORD TotalAvgLF;
+ DWORD TotalEmptyLines;
TotalFileCount = 0;
TotalLineCount = 0;
+ TotalEmptyLines = 0;
Info = ExtInfoList;
for (Info = ExtInfoList; Info != NULL; Info = Info->Next)
{
TotalFileCount += Info->FileCount;
TotalLineCount += Info->LineCount;
+ TotalEmptyLines += Info->EmptyLines;
}
TotalAvgLF = (TotalFileCount ? TotalLineCount / TotalFileCount : 0);
@@ -264,18 +269,22 @@
}
_tprintf (_T("\n"));
- _tprintf (_T("File extension%c : %s\n"), ((Info->nExtensions > 1) ? _T('s') : _T(' ')), Info->ExpandedExtName);
- _tprintf (_T("File ext. description : %s\n"), Info->Description);
- _tprintf (_T("Number of files : %lu\n"), Info->FileCount);
- _tprintf (_T("Number of lines : %lu\n"), Info->LineCount);
- _tprintf (_T("Proportion of lines : %.2f %%\n"), (float)(TotalLineCount ? (((float)Info->LineCount * 100) / (float)TotalLineCount) : 0));
- _tprintf (_T("Average no. lines/file : %lu\n"), AvgLF);
+ _tprintf (_T("File extension%c : %s\n"), ((Info->nExtensions > 1) ? _T('s') : _T(' ')), Info->ExpandedExtName);
+ _tprintf (_T("File ext. description : %s\n"), Info->Description);
+ _tprintf (_T("Number of files : %lu\n"), Info->FileCount);
+ _tprintf (_T("Number of lines : %lu\n"), Info->LineCount);
+ if(SkipEmptyLines)
+ _tprintf (_T("Number of empty lines : %lu\n"), Info->EmptyLines);
+ _tprintf (_T("Proportion of lines : %.2f %%\n"), (float)(TotalLineCount ? (((float)Info->LineCount * 100) / (float)TotalLineCount) : 0));
+ _tprintf (_T("Average no. lines/file : %lu\n"), AvgLF);
}
_tprintf (_T("\n"));
- _tprintf (_T("Total number of files : %lu\n"), TotalFileCount);
- _tprintf (_T("Total number of lines : %lu\n"), TotalLineCount);
- _tprintf (_T("Average no. lines/file : %lu\n"), TotalAvgLF);
+ _tprintf (_T("Total number of files : %lu\n"), TotalFileCount);
+ _tprintf (_T("Total number of lines : %lu\n"), TotalLineCount);
+ if(SkipEmptyLines)
+ _tprintf (_T("Total number of empty lines : %lu\n"), TotalEmptyLines);
+ _tprintf (_T("Average no. lines/file : %lu\n"), TotalAvgLF);
}
@@ -324,10 +333,11 @@
return FALSE;
}
- DoStatisticsForFile (StatInfo);
+ ReadLines (StatInfo);
Info->FileCount++;
Info->LineCount += StatInfo->LineCount;
+ Info->EmptyLines += StatInfo->EmptyLines;
CleanupAfterFile();
}
@@ -413,19 +423,36 @@
PrintStatistics();
}
+BOOLEAN
+IsOptionSet(TCHAR *Option)
+{
+ int i;
+ for(i = 0; i < MAX_OPTIONS; i++)
+ {
+ if(!Options[i])
+ continue;
+
+ if(!_tcscmp(Options[i], Option))
+ return TRUE;
+ }
+ return FALSE;
+}
+
int
main (int argc, char * argv [])
{
+ int a;
#if UNICODE
TCHAR Path[MAX_PATH + 1];
#endif
_tprintf (_T("\nReactOS project statistics generator.\n\n"));
- if (argc < 2)
+ if (argc < 2 || argc > 2 + MAX_OPTIONS)
{
- _tprintf(_T("Usage: stats directory"));
+ _tprintf(_T("Usage: stats [-e] directory\n"));
+ _tprintf(_T(" -e: don't count empty lines"));
return 1;
}
@@ -433,12 +460,29 @@
AddExtension (_T("c\0\0"), _T("Ansi C Source files"));
AddExtension (_T("cpp\0cxx\0\0"), _T("C++ Source files"));
AddExtension (_T("h\0\0"), _T("Header files"));
+
+ for(a = 1; a < argc - 1; a++)
+ {
+#if UNICODE
+ int len = lstrlenA(argv[a]);
+ TCHAR *str = (TCHAR*)HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR));
+ if(MultiByteToWideChar(CP_ACP, 0, argv[a], -1, str, len + 1) > 0)
+ Options[a - 1] = str;
+ else
+ Options[a - 1] = NULL;
+#else
+ Options[a - 1] = argv[a];
+#endif
+ }
+
+ SkipEmptyLines = IsOptionSet(_T("-e"));
+
#if UNICODE
ZeroMemory(Path, sizeof(Path));
- if(MultiByteToWideChar(CP_ACP, 0, argv[1], -1, Path, MAX_PATH) > 0)
+ if(MultiByteToWideChar(CP_ACP, 0, argv[argc - 1], -1, Path, MAX_PATH) > 0)
Execute (Path);
#else
- Execute (argv[1]);
+ Execute (argv[argc - 1]);
#endif
Cleanup();