blob: 179b3105a4229b80fcf707892ac79e27006b8b53 [file] [log] [blame]
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -08001/*
2 * Copyright 2000-2012 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "fsnotifier.h"
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23
24#define REALLOC_FACTOR 2
25
26struct __array {
27 void** data;
28 int size;
29 int capacity;
30};
31
32static bool array_realloc(array* a) {
33 if (a->size == a->capacity) {
34 int new_cap = a->capacity * REALLOC_FACTOR;
35 void* new_ptr = realloc(a->data, sizeof(void*) * new_cap);
36 if (new_ptr == NULL) {
37 return false;
38 }
39 a->capacity = new_cap;
40 a->data = new_ptr;
41 }
42 return true;
43}
44
45array* array_create(int initial_capacity) {
46 array* a = (array*) malloc(sizeof(array));
47 if (a == NULL) {
48 return NULL;
49 }
50
51 a->data = calloc(sizeof(void*), initial_capacity);
52 if (a->data == NULL) {
53 free(a);
54 return NULL;
55 }
56
57 a->capacity = initial_capacity;
58 a->size = 0;
59
60 return a;
61}
62
63inline int array_size(array* a) {
64 return (a != NULL ? a->size : 0);
65}
66
67void* array_push(array* a, void* element) {
68 if (a == NULL || !array_realloc(a)) {
69 return NULL;
70 }
71 a->data[a->size++] = element;
72 return element;
73}
74
75void* array_pop(array* a) {
76 if (a != NULL && a->size > 0) {
77 return a->data[--a->size];
78 }
79 else {
80 return NULL;
81 }
82}
83
84void array_put(array* a, int index, void* element) {
85 if (a != NULL && index >=0 && index < a->capacity) {
86 a->data[index] = element;
87 if (a->size <= index) {
88 a->size = index + 1;
89 }
90 }
91}
92
93void* array_get(array* a, int index) {
94 if (a != NULL && index >= 0 && index < a->size) {
95 return a->data[index];
96 }
97 else {
98 return NULL;
99 }
100}
101
102void array_delete(array* a) {
103 if (a != NULL) {
104 free(a->data);
105 free(a);
106 }
107}
108
109void array_delete_vs_data(array* a) {
110 if (a != NULL) {
111 for (int i=0; i<a->size; i++) {
112 if (a->data[i] != NULL) {
113 free(a->data[i]);
114 }
115 }
116 array_delete(a);
117 }
118}
119
120
121struct __table {
122 void** data;
123 int capacity;
124};
125
126table* table_create(int capacity) {
127 table* t = malloc(sizeof(table));
128 if (t == NULL) {
129 return NULL;
130 }
131
132 t->data = calloc(sizeof(void*), capacity);
133 if (t->data == NULL) {
134 free(t);
135 return NULL;
136 }
137 memset(t->data, 0, sizeof(void*) * capacity);
138
139 t->capacity = capacity;
140
141 return t;
142}
143
144static inline int wrap(int key, table* t) {
145 return (t != NULL ? key % t->capacity : -1);
146}
147
148// todo: resolve collisions (?)
149void* table_put(table* t, int key, void* value) {
150 int k = wrap(key, t);
151 if (k < 0 || (value != NULL && t->data[k] != NULL)) {
152 return NULL;
153 }
154 else {
155 return t->data[k] = value;
156 }
157}
158
159void* table_get(table* t, int key) {
160 int k = wrap(key, t);
161 if (k < 0) {
162 return NULL;
163 }
164 else {
165 return t->data[k];
166 }
167}
168
169void table_delete(table* t) {
170 if (t != NULL) {
171 free(t->data);
172 free(t);
173 }
174}
175
176
177#define INPUT_BUF_LEN 2048
178static char input_buf[INPUT_BUF_LEN];
179
180char* read_line(FILE* stream) {
181 char* retval = fgets(input_buf, INPUT_BUF_LEN, stream);
182 if (retval == NULL || feof(stream)) {
183 return NULL;
184 }
185 int pos = strlen(input_buf) - 1;
186 if (input_buf[pos] == '\n') {
187 input_buf[pos] = '\0';
188 }
189 return input_buf;
190}
191
192
193bool is_parent_path(const char* parent_path, const char* child_path) {
194 size_t parent_len = strlen(parent_path);
195 return strncmp(parent_path, child_path, parent_len) == 0 &&
196 (parent_len == strlen(child_path) || child_path[parent_len] == '/');
197}