1. Serge Zaitsev
  2. codehound

Source

codehound / codehound.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
#include <limits.h>

#include "index.h"

uint32_t *trigrams_create(const char *s) {
	uint32_t *trigrams = malloc(sizeof(uint32_t *) * (strlen(s) - 1));
	memset(trigrams, 0, sizeof(uint32_t *) * (strlen(s) - 1));
	uint32_t t = 0;
	int i;
	for (i = 0; *s; s++, i++) {
		t = (t << 8) & 0xffffff;
		t = t | (*s);
		if (i > 1) {
			trigrams[i-2] = t;
		}
	}
	return trigrams;
}

void trigrams_destroy(uint32_t *t) {
	free(t);
}

typedef void (*scan_cb)(const char *, void *);

void scan_file_cb(const char *path, void *arg) {
	struct index_writer *writer = (struct index_writer *) arg;
	index_writer_add(writer, path);
}

int scandirs(const char *root, scan_cb cb, void *arg) {
	DIR *dir;
	struct dirent *entry;


	if ((dir = opendir(root)) == NULL) {
		return -errno;
	}

	while ((entry = readdir(dir)) != NULL) {
		struct stat st;
		char path[256];
		snprintf(path, sizeof(path)-1, "%s/%s", root, entry->d_name);
		if (stat(path, &st) < 0) {
			return -errno;
		}
		if (S_ISREG(st.st_mode)) {
			printf("indexing %s\n", entry->d_name);
			cb(path, arg);
		} else if (S_ISDIR(st.st_mode) && strcmp(entry->d_name, ".") != 0 
				&& strcmp(entry->d_name, "..") != 0) {
			scandirs(path, cb, arg);
		}
	}
	closedir(dir);
	return 0;
}

void search_cb(const char *file, void *arg) {
	char *word = arg;
	char cmd[256];
	sprintf(cmd, "grep --color=auto -H '%s' %s", word, file);
	system(cmd);
	printf("%s\n", file);
}

int main(int argc, char *argv[]) {
	if (argc < 2) {
		return 0;
	}
	//struct index index;
	if (strcmp(argv[1], "index") == 0) {
		struct index_writer *writer = index_writer_create("index.cache");
		/*if (root[strlen(root)-1] == '/') {
			root[strlen(root)-1] = '\0';
		}*/
		scandirs(argv[2], scan_file_cb, writer);
		printf("writign index file...\n");
		index_writer_write(writer);
		index_writer_destroy(writer);
	} else if (strcmp(argv[1], "find") == 0) {
		struct index *index = index_open("index.cache");
		uint32_t *trigrams = trigrams_create(argv[2]);
		index_search(index, trigrams, search_cb, argv[2]);
		trigrams_destroy(trigrams);
		index_destroy(index);
	}
	return 0;
}