|
@@ -1,33 +1,52 @@
|
|
|
#include <dirent.h>
|
|
|
#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
|
|
|
-const char** filters = NULL;
|
|
|
-int filterAmount = 0;
|
|
|
-char path[PATH_MAX] = {'\0'};
|
|
|
-int pathLength = 0;
|
|
|
-int allLines = 0;
|
|
|
+static const char** filters = NULL;
|
|
|
+static int filterAmount = 0;
|
|
|
+static char path[PATH_MAX] = {'\0'};
|
|
|
+static int pathLength = 0;
|
|
|
|
|
|
-void appendToPath(const char* s) {
|
|
|
+typedef struct {
|
|
|
+ char path[PATH_MAX];
|
|
|
+ int lines;
|
|
|
+} LineFile;
|
|
|
+
|
|
|
+static LineFile* lineFiles = NULL;
|
|
|
+static size_t lineFileIndex = 0;
|
|
|
+static size_t lineFileCapacity = 0;
|
|
|
+
|
|
|
+static void addLineFile(int lines) {
|
|
|
+ while(lineFileIndex >= lineFileCapacity) {
|
|
|
+ lineFileCapacity += 16;
|
|
|
+ lineFiles = realloc(lineFiles, sizeof(LineFile) * lineFileCapacity);
|
|
|
+ }
|
|
|
+ LineFile* lf = lineFiles + lineFileIndex++;
|
|
|
+ memcpy(lf->path, path, sizeof(path));
|
|
|
+ lf->lines = lines;
|
|
|
+}
|
|
|
+
|
|
|
+static void appendToPath(const char* s) {
|
|
|
for(int i = 0; pathLength < (PATH_MAX - 1) && s[i] != '\0'; i++) {
|
|
|
path[pathLength++] = s[i];
|
|
|
}
|
|
|
path[pathLength] = '\0';
|
|
|
}
|
|
|
|
|
|
-int enterPath(const char* name) {
|
|
|
+static int enterPath(const char* name) {
|
|
|
int length = pathLength;
|
|
|
appendToPath("/");
|
|
|
appendToPath(name);
|
|
|
return length;
|
|
|
}
|
|
|
|
|
|
-void resetPath(int marker) {
|
|
|
+static void resetPath(int marker) {
|
|
|
path[marker] = '\0';
|
|
|
pathLength = marker;
|
|
|
}
|
|
|
|
|
|
-void countLines() {
|
|
|
+static void countLines(void) {
|
|
|
FILE* file = fopen(path, "r");
|
|
|
if(file == NULL) {
|
|
|
return;
|
|
@@ -42,15 +61,17 @@ void countLines() {
|
|
|
lines++;
|
|
|
}
|
|
|
}
|
|
|
- printf("%s = %d\n", path, lines);
|
|
|
- allLines += lines;
|
|
|
+ addLineFile(lines);
|
|
|
fclose(file);
|
|
|
}
|
|
|
|
|
|
-void handleFile(const char* name) {
|
|
|
- int end = strlen(name);
|
|
|
+static void handleFile(const char* name) {
|
|
|
+ size_t end = strlen(name);
|
|
|
for(int i = 0; i < filterAmount; i++) {
|
|
|
- int l = strlen(filters[i]);
|
|
|
+ if(*filters[i] == '-') {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ size_t l = strlen(filters[i]);
|
|
|
if(end >= l && !strcmp(filters[i], name + (end - l))) {
|
|
|
int marker = enterPath(name);
|
|
|
countLines();
|
|
@@ -60,7 +81,19 @@ void handleFile(const char* name) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void scanFolder() {
|
|
|
+static int isAllowedName(const char* name) {
|
|
|
+ for(int i = 0; i < filterAmount; i++) {
|
|
|
+ if(*filters[i] != '-') {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if(!strcmp(name, filters[i] + 1)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+static void scanFolder(void) {
|
|
|
DIR* dir = opendir(path);
|
|
|
if(dir == NULL) {
|
|
|
return;
|
|
@@ -72,9 +105,12 @@ void scanFolder() {
|
|
|
} else if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
|
|
|
continue;
|
|
|
} else if(entry->d_type == DT_DIR) {
|
|
|
- int marker = enterPath(entry->d_name);
|
|
|
- scanFolder();
|
|
|
- resetPath(marker);
|
|
|
+ const char* name = entry->d_name;
|
|
|
+ if(isAllowedName(name)) {
|
|
|
+ int marker = enterPath(name);
|
|
|
+ scanFolder();
|
|
|
+ resetPath(marker);
|
|
|
+ }
|
|
|
} else if(entry->d_type == DT_REG) {
|
|
|
handleFile(entry->d_name);
|
|
|
}
|
|
@@ -82,8 +118,18 @@ void scanFolder() {
|
|
|
closedir(dir);
|
|
|
}
|
|
|
|
|
|
+static int compareLineFiles(const void* a, const void* b) {
|
|
|
+ const LineFile* lnA = a;
|
|
|
+ const LineFile* lnB = b;
|
|
|
+ if(lnA->lines < lnB->lines) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ return lnA->lines == lnB->lines ? 0 : 1;
|
|
|
+}
|
|
|
+
|
|
|
int main(int argAmount, const char** args) {
|
|
|
if(argAmount < 3) {
|
|
|
+ puts("Use '-' before a name to exclude such paths");
|
|
|
if(argAmount > 0) {
|
|
|
printf("%s <path> <ending_1> [ending_2] ...\n", args[0]);
|
|
|
} else {
|
|
@@ -95,6 +141,17 @@ int main(int argAmount, const char** args) {
|
|
|
filterAmount = argAmount - 2;
|
|
|
appendToPath(args[1]);
|
|
|
scanFolder();
|
|
|
+
|
|
|
+ qsort(lineFiles, lineFileIndex, sizeof(LineFile), compareLineFiles);
|
|
|
+
|
|
|
+ int allLines = 0;
|
|
|
+ for(size_t i = 0; i < lineFileIndex; i++) {
|
|
|
+ LineFile* ln = lineFiles + i;
|
|
|
+ printf("%6d | %s\n", ln->lines, ln->path);
|
|
|
+ allLines += ln->lines;
|
|
|
+ }
|
|
|
printf("Lines: %d\n", allLines);
|
|
|
+
|
|
|
+ free(lineFiles);
|
|
|
return 0;
|
|
|
-}
|
|
|
+}
|