ReactOS  0.4.14-dev-554-g2f8d847
stats.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS project statistics
4  * FILE: stats.c
5  * PURPOSE: Main program file
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * REVISIONS:
8  * CSH 01/01-2002 Created
9  */
10 #include <windows.h>
11 #include <tchar.h>
12 #include <stdio.h>
13 
14 typedef struct _EXTENSION_INFO
15 {
26 
27 typedef struct _FILE_INFO
28 {
29  struct _FILE_INFO * Next;
37 
42 
43 #define MAX_OPTIONS 2
45 
46 
47 VOID
49 {
50  ExtInfoList = NULL;
52 }
53 
54 
55 VOID
57 {
59  PEXTENSION_INFO NextExtInfo;
60 
62  while (ExtInfo != NULL)
63  {
64  NextExtInfo = ExtInfo->Next;
66  ExtInfo = NextExtInfo;
67  }
68 }
69 
70 
74 {
77  TCHAR *t;
78  DWORD ln;
79 
81  if (!ExtInfo)
82  return NULL;
83 
84  for(t = ExtName; *t != _T('\0'); t += _tcslen(t) + 1);
85  ln = (DWORD_PTR)t - (DWORD_PTR)ExtName;
86 
87  ZeroMemory (ExtInfo, sizeof (EXTENSION_INFO));
88  memcpy (ExtInfo->ExtName, ExtName, ln);
90 
91  for(t = ExtInfo->ExtName; *t != _T('\0'); t += _tcslen(t) + 1)
92  {
93  if(ExtInfo->nExtensions++ != 0)
97  }
98 
99  if (ExtInfoList)
100  {
101  Info = ExtInfoList;
102  while (Info->Next != NULL)
103  {
104  Info = Info->Next;
105  }
106  Info->Next = ExtInfo;
107  }
108  else
109  {
111  }
112 
113  return ExtInfo;
114 }
115 
116 
120 {
121  PFILE_INFO StatInfo;
123 
124  StatInfo = (PFILE_INFO) HeapAlloc (GetProcessHeap(), 0, sizeof (FILE_INFO));
125  if (!StatInfo)
126  return NULL;
127  ZeroMemory (StatInfo, sizeof (FILE_INFO));
128  _tcscpy (StatInfo->FileName, FileName);
129  StatInfo->ExtInfo = ExtInfo;
130 
131  if (ExtInfo->StatInfoList)
132  {
134  while (Info->StatInfoListNext != NULL)
135  {
136  Info = Info->StatInfoListNext;
137  }
138  Info->StatInfoListNext = StatInfo;
139  }
140  else
141  {
142  ExtInfo->StatInfoList = StatInfo;
143  }
144 
145  if (StatInfoList)
146  {
147  Info = StatInfoList;
148  while (Info->Next != NULL)
149  {
150  Info = Info->Next;
151  }
152  Info->Next = StatInfo;
153  }
154  else
155  {
156  StatInfoList = StatInfo;
157  }
158 
159  return StatInfo;
160 }
161 
162 
163 VOID
165 {
168 }
169 
170 
171 BOOL
173 {
174  LONG FileSize;
175 
176  FileHandle = CreateFile (FileName, // Create this file
177  GENERIC_READ, // Open for reading
178  0, // No sharing
179  NULL, // No security
180  OPEN_EXISTING, // Open the file
181  FILE_ATTRIBUTE_NORMAL, // Normal file
182  NULL); // No attribute template
184  return FALSE;
185 
187  if (FileSize <= 0)
188  {
190  return FALSE;
191  }
192 
193  return TRUE;
194 }
195 
196 
197 VOID
199 {
200  DWORD ReadBytes, LineLen;
201  static char FileBuffer[1024];
202  char LastChar = '\0';
203  char *Current;
204 
205  LineLen = 0;
206  while(ReadFile (FileHandle, FileBuffer, sizeof(FileBuffer), &ReadBytes, NULL) && ReadBytes >= sizeof(char))
207  {
208  for(Current = FileBuffer; ReadBytes > 0; ReadBytes -= sizeof(char), Current++)
209  {
210  if(*Current == '\n' && LastChar == '\r')
211  {
212  LastChar = '\0';
213  if(!SkipEmptyLines || (LineLen > 0))
214  StatInfo->LineCount++;
215  if(LineLen == 0)
216  StatInfo->EmptyLines++;
217  LineLen = 0;
218  continue;
219  }
220  LastChar = *Current;
221  if(SkipEmptyLines && (*Current == ' ' || *Current == '\t'))
222  {
223  continue;
224  }
225  if(*Current != '\r')
226  LineLen++;
227  }
228  }
229 
230  StatInfo->LineCount += (LineLen > 0);
231  StatInfo->EmptyLines += ((LastChar != '\0') && (LineLen == 0));
232 }
233 
234 
235 VOID
237 {
239  DWORD TotalFileCount;
240  DWORD TotalLineCount;
241  DWORD TotalAvgLF;
242  DWORD TotalEmptyLines;
243 
244  TotalFileCount = 0;
245  TotalLineCount = 0;
246  TotalEmptyLines = 0;
247  Info = ExtInfoList;
248 
249  for (Info = ExtInfoList; Info != NULL; Info = Info->Next)
250  {
251  TotalFileCount += Info->FileCount;
252  TotalLineCount += Info->LineCount;
253  TotalEmptyLines += Info->EmptyLines;
254  }
255 
256  TotalAvgLF = (TotalFileCount ? TotalLineCount / TotalFileCount : 0);
257 
258  for (Info = ExtInfoList; Info != NULL; Info = Info->Next)
259  {
260  DWORD AvgLF;
261 
262  if (Info->FileCount != 0)
263  {
264  AvgLF = (Info->FileCount ? Info->LineCount / Info->FileCount : 0);
265  }
266  else
267  {
268  AvgLF = 0;
269  }
270 
271  _tprintf (_T("\n"));
272  _tprintf (_T("File extension%c : %s\n"), ((Info->nExtensions > 1) ? _T('s') : _T(' ')), Info->ExpandedExtName);
273  _tprintf (_T("File ext. description : %s\n"), Info->Description);
274  _tprintf (_T("Number of files : %lu\n"), Info->FileCount);
275  _tprintf (_T("Number of lines : %lu\n"), Info->LineCount);
276  if(SkipEmptyLines)
277  _tprintf (_T("Number of empty lines : %lu\n"), Info->EmptyLines);
278  _tprintf (_T("Proportion of lines : %.2f %%\n"), (float)(TotalLineCount ? (((float)Info->LineCount * 100) / (float)TotalLineCount) : 0));
279  _tprintf (_T("Average no. lines/file : %lu\n"), AvgLF);
280  }
281 
282  _tprintf (_T("\n"));
283  _tprintf (_T("Total number of files : %lu\n"), TotalFileCount);
284  _tprintf (_T("Total number of lines : %lu\n"), TotalLineCount);
285  if(SkipEmptyLines)
286  _tprintf (_T("Total number of empty lines : %lu\n"), TotalEmptyLines);
287  _tprintf (_T("Average no. lines/file : %lu\n"), TotalAvgLF);
288 }
289 
290 
291 BOOL
293 {
296  TCHAR SearchPath[256];
297  TCHAR FileName[256];
298  TCHAR *Ext;
299  HANDLE SearchHandle;
300  BOOL More;
301 
302  Info = ExtInfoList;
303  while (Info != NULL)
304  {
305  Ext = Info->ExtName;
306  do
307  {
308  ZeroMemory (&FindFile, sizeof (FindFile));
310  _tcscat (SearchPath, _T("\\*."));
312  _tcscpy (FindFile.cFileName, SearchPath);
313  SearchHandle = FindFirstFile (SearchPath, &FindFile);
314  if (SearchHandle != INVALID_HANDLE_VALUE)
315  {
316  More = TRUE;
317  while (More)
318  {
319  if (!(FindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
320  {
321  _tcscpy (FileName, Path);
322  _tcscat (FileName, _T("\\"));
323  _tcscat (FileName, FindFile.cFileName);
324 
325  if (LoadFile (FileName))
326  {
327  PFILE_INFO StatInfo;
328 
329  StatInfo = AddFile (FindFile.cFileName, Info);
330  if (!StatInfo)
331  {
332  _tprintf (_T("Not enough free memory.\n"));
333  return FALSE;
334  }
335 
336  ReadLines (StatInfo);
337 
338  Info->FileCount++;
339  Info->LineCount += StatInfo->LineCount;
340  Info->EmptyLines += StatInfo->EmptyLines;
341 
343  }
344  }
345  More = FindNextFile (SearchHandle, &FindFile);
346  }
347  FindClose (SearchHandle);
348  }
349  Ext += _tcslen(Ext) + 1;
350  } while(*Ext != _T('\0'));
351  Info = Info->Next;
352  }
353  return TRUE;
354 }
355 
356 
357 BOOL
359 {
362  HANDLE SearchHandle;
363  BOOL More;
364 
365  if(!BeSilent)
366  {
367  _tprintf (_T("Processing %s ...\n"), Path);
368  }
369 
371  _tcscat (SearchPath, _T("\\*.*"));
372 
373  SearchHandle = FindFirstFileEx (SearchPath,
375  &FindFile,
377  NULL,
378  0);
379  if (SearchHandle != INVALID_HANDLE_VALUE)
380  {
381  More = TRUE;
382  while (More)
383  {
384  if ((FindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
385  && (_tcscmp (FindFile.cFileName, _T(".")) != 0)
386  && (_tcscmp (FindFile.cFileName, _T("..")) != 0)
387  && (_tcscmp (FindFile.cFileName, _T("CVS")) != 0)
388  && (_tcscmp (FindFile.cFileName, _T(".svn")) != 0))
389  {
391  _tcscat (SearchPath, _T("\\"));
392  _tcscat (SearchPath, FindFile.cFileName);
394  return FALSE;
395  if (!ProcessFiles (SearchPath))
396  return FALSE;
397  }
398  More = FindNextFile (SearchHandle, &FindFile);
399  }
400  FindClose (SearchHandle);
401  }
402  return TRUE;
403 }
404 
405 
406 VOID
408 {
409  if (!ExtInfoList)
410  {
411  _tprintf (_T("No extensions specified.\n"));
412  return;
413  }
414 
415  if (!ProcessDirectories (Path))
416  {
417  _tprintf (_T("Failed to process directories.\n"));
418  return;
419  }
420 
421  if (!ProcessFiles (Path))
422  {
423  _tprintf (_T("Failed to process files.\n"));
424  return;
425  }
426 
427  PrintStatistics();
428 }
429 
430 BOOLEAN
432 {
433  int i;
434  for(i = 0; i < MAX_OPTIONS; i++)
435  {
436  if(!Options[i])
437  continue;
438 
439  if(!_tcscmp(Options[i], Option))
440  return TRUE;
441  }
442  return FALSE;
443 }
444 
445 
446 int _tmain(int argc, _TCHAR * argv[])
447 {
448  int a;
449 
450  _tprintf (_T("ReactOS Project Statistics\n"));
451  _tprintf (_T("==========================\n\n"));
452 
453  if (argc < 2 || argc > 2 + MAX_OPTIONS)
454  {
455  _tprintf(_T("Usage: stats [-e] [-s] directory\n"));
456  _tprintf(_T(" -e: don't count empty lines\n"));
457  _tprintf(_T(" -s: be silent, don't print directories while processing\n"));
458  return 1;
459  }
460 
461  Initialize();
462  AddExtension (_T("c\0\0"), _T("Ansi C Source files"));
463  AddExtension (_T("cpp\0cxx\0\0"), _T("C++ Source files"));
464  AddExtension (_T("h\0\0"), _T("Header files"));
465 
466  for(a = 1; a < argc - 1; a++)
467  {
468  Options[a - 1] = argv[a];
469  }
470 
471  SkipEmptyLines = IsOptionSet(_T("-e"));
472  BeSilent = IsOptionSet(_T("-s"));
473 
474  Execute (argv[argc - 1]);
475  Cleanup();
476 
477  return 0;
478 }
static int argc
Definition: ServiceArgs.c:12
#define _tprintf
Definition: tchar.h:506
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
TCHAR * Options[MAX_OPTIONS]
Definition: stats.c:44
DWORD LineCount
Definition: stats.c:23
#define DWORD_PTR
Definition: treelist.c:76
DWORD FileCount
Definition: stats.c:22
VOID Cleanup(VOID)
Definition: stats.c:56
VOID Execute(LPTSTR Path)
Definition: stats.c:407
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
struct _FILE_INFO * StatInfoListNext
Definition: stats.c:30
struct _FILE_INFO FILE_INFO
GLdouble GLdouble t
Definition: gl.h:2047
PEXTENSION_INFO ExtInfoList
Definition: stats.c:39
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
PEXTENSION_INFO AddExtension(LPTSTR ExtName, LPTSTR Description)
Definition: stats.c:72
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
#define ZeroMemory
Definition: winbase.h:1642
#define MAX_OPTIONS
Definition: stats.c:43
static const WCHAR Description[]
Definition: oid.c:1266
BOOLEAN SkipEmptyLines
Definition: stats.c:41
PFILE_INFO AddFile(LPTSTR FileName, PEXTENSION_INFO ExtInfo)
Definition: stats.c:118
#define argv
Definition: mplay32.c:18
CHAR * LPTSTR
Definition: xmlstorage.h:192
struct TraceInfo Info
#define SearchPath
Definition: winbase.h:3734
HANDLE FileHandle
Definition: stats.c:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define a
Definition: ke_i.h:78
BOOL LoadFile(LPTSTR FileName)
Definition: stats.c:172
struct _EXTENSION_INFO * Next
Definition: stats.c:16
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
BOOL ProcessDirectories(LPTSTR Path)
Definition: stats.c:358
#define FindFirstFile
Definition: winbase.h:3616
BOOLEAN BeSilent
Definition: stats.c:41
#define OPEN_EXISTING
Definition: compat.h:434
char _TCHAR
Definition: tchar.h:1392
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:67
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define GetProcessHeap()
Definition: compat.h:403
struct _FILE_INFO * PFILE_INFO
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD EmptyLines
Definition: stats.c:34
#define FindNextFile
Definition: winbase.h:3622
DWORD FunctionCount
Definition: stats.c:35
#define MAX_PATH
Definition: compat.h:26
BOOL ProcessFiles(LPTSTR Path)
Definition: stats.c:292
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
static struct proto Ext[]
Definition: mkg3states.c:87
struct _EXTENSION_INFO EXTENSION_INFO
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define GENERIC_READ
Definition: compat.h:124
DWORD EmptyLines
Definition: stats.c:24
VOID CleanupAfterFile(VOID)
Definition: stats.c:164
uint32_t DWORD_PTR
Definition: typedefs.h:63
TCHAR FileName[MAX_PATH]
Definition: stats.c:32
PFILE_INFO StatInfoList
Definition: stats.c:40
VOID PrintStatistics(VOID)
Definition: stats.c:236
TCHAR ExpandedExtName[128]
Definition: stats.c:19
BOOLEAN IsOptionSet(TCHAR *Option)
Definition: stats.c:431
TCHAR ExtName[16]
Definition: stats.c:18
PRTL_UNICODE_STRING_BUFFER Path
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:904
TCHAR Description[256]
Definition: stats.c:21
struct _EXTENSION_INFO * PEXTENSION_INFO
VOID ReadLines(PFILE_INFO StatInfo)
Definition: stats.c:198
PEXTENSION_INFO ExtInfo
Definition: stats.c:31
VOID Initialize(VOID)
Definition: stats.c:48
_TCHAR * _tcscat(_TCHAR *s, const _TCHAR *append)
Definition: tcscat.h:8
#define FindFirstFileEx
Definition: winbase.h:3617
struct _FILE_INFO * StatInfoList
Definition: stats.c:17
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
DWORD nExtensions
Definition: stats.c:20
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define HeapFree(x, y, z)
Definition: compat.h:402
struct _FILE_INFO * Next
Definition: stats.c:29
DWORD LineCount
Definition: stats.c:33
Definition: find.c:28
int _tmain(int argc, _TCHAR *argv[])
Definition: stats.c:446
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502