about summary refs log tree commit diff stats
path: root/ignore.c
blob: c24769227f653393e42bae907f27f2a760e52e8e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#define _XOPEN_SOURCE 700

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ignore.h"

static int total_size;

struct ignores *init_ignores(char *path) {
	int i = 0;
	FILE *ignore = fopen(path, "r");

	if (ignore == NULL) {
		return NULL;
	}

	char *line = NULL;
	size_t llen = 0;
	total_size = IGNORE_SIZE;
	struct ignores *ignores =
		(struct ignores *)calloc(sizeof(struct ignores), 1);
	ignores->list = (char **)calloc(sizeof(char *), IGNORE_SIZE);
	ignores->size = 0;

	while (getline(&line, &llen, ignore) != -1) {
		/** isspace doesn't necessarily hold true for `\n` for anything
		 * other than the 'C' locale on some platforms, so we have to do
		 * an additional check for this
		 */

		if (strlen(line) == 1 && (isspace(line[0]) || line[0] == '\n')) {
			continue;
		}

		if (strlen(line) > 0) {
			char *l = (char *)calloc(sizeof(char), strlen(line));

			if (l == NULL) {
				fprintf(stderr, "calloc\n");
				exit(EXIT_FAILURE);
			}

			for (size_t j = 0, k = 0; j < strlen(line); j++) {
				char c = line[j];

				if (isspace(c) || c == '\n') {
					break;
				}

				l[k++] = c;
			}

			if (i + 1 > total_size) {
				ignores->list = (char **)realloc(
					ignores->list, sizeof(char *) * (total_size + IGNORE_SIZE));
				total_size += IGNORE_SIZE;
			}

			ignores->list[i++] = l;
		}
	}

	free(line);
	fclose(ignore);

	ignores->size = i;

	return ignores;
}

void free_ignores(struct ignores *ignores) {
	if (ignores != NULL) {
		if (ignores->size > 0) {
			for (int i = 0; i < ignores->size; i++) {
				free(ignores->list[i]);
			}
		}

		free(ignores->list);
		free(ignores);
	}
}