blob: 854a48c7da6f0dca3bd1b2b9d646f88da29dfb20 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "fsnotifier.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define REALLOC_FACTOR 2
struct __array {
void** data;
int size;
int capacity;
};
static bool array_realloc(array* a) {
if (a->size == a->capacity) {
int new_cap = a->capacity * REALLOC_FACTOR;
void* new_ptr = realloc(a->data, sizeof(void*) * new_cap);
if (new_ptr == NULL) {
return false;
}
a->capacity = new_cap;
a->data = new_ptr;
}
return true;
}
array* array_create(int initial_capacity) {
array* a = (array*) malloc(sizeof(array));
if (a == NULL) {
return NULL;
}
a->data = calloc(sizeof(void*), initial_capacity);
if (a->data == NULL) {
free(a);
return NULL;
}
a->capacity = initial_capacity;
a->size = 0;
return a;
}
inline int array_size(array* a) {
return (a != NULL ? a->size : 0);
}
void* array_push(array* a, void* element) {
if (a == NULL || !array_realloc(a)) {
return NULL;
}
a->data[a->size++] = element;
return element;
}
void* array_pop(array* a) {
if (a != NULL && a->size > 0) {
return a->data[--a->size];
}
else {
return NULL;
}
}
void array_put(array* a, int index, void* element) {
if (a != NULL && index >=0 && index < a->capacity) {
a->data[index] = element;
if (a->size <= index) {
a->size = index + 1;
}
}
}
void* array_get(array* a, int index) {
if (a != NULL && index >= 0 && index < a->size) {
return a->data[index];
}
else {
return NULL;
}
}
void array_delete(array* a) {
if (a != NULL) {
free(a->data);
free(a);
}
}
void array_delete_vs_data(array* a) {
if (a != NULL) {
array_delete_data(a);
array_delete(a);
}
}
void array_delete_data(array* a) {
if (a != NULL) {
for (int i=0; i<a->size; i++) {
if (a->data[i] != NULL) {
free(a->data[i]);
}
}
a->size = 0;
}
}
struct __table {
void** data;
int capacity;
};
table* table_create(int capacity) {
table* t = malloc(sizeof(table));
if (t == NULL) {
return NULL;
}
t->data = calloc(sizeof(void*), capacity);
if (t->data == NULL) {
free(t);
return NULL;
}
memset(t->data, 0, sizeof(void*) * capacity);
t->capacity = capacity;
return t;
}
static inline int wrap(int key, table* t) {
return (t != NULL ? key % t->capacity : -1);
}
// todo: resolve collisions (?)
void* table_put(table* t, int key, void* value) {
int k = wrap(key, t);
if (k < 0 || (value != NULL && t->data[k] != NULL)) {
return NULL;
}
else {
return t->data[k] = value;
}
}
void* table_get(table* t, int key) {
int k = wrap(key, t);
if (k < 0) {
return NULL;
}
else {
return t->data[k];
}
}
void table_delete(table* t) {
if (t != NULL) {
free(t->data);
free(t);
}
}
#define INPUT_BUF_LEN 2048
static char input_buf[INPUT_BUF_LEN];
char* read_line(FILE* stream) {
char* retval = fgets(input_buf, INPUT_BUF_LEN, stream);
if (retval == NULL || feof(stream)) {
return NULL;
}
int pos = strlen(input_buf) - 1;
if (input_buf[pos] == '\n') {
input_buf[pos] = '\0';
}
return input_buf;
}
bool is_parent_path(const char* parent_path, const char* child_path) {
size_t parent_len = strlen(parent_path);
return strncmp(parent_path, child_path, parent_len) == 0 &&
(parent_len == strlen(child_path) || child_path[parent_len] == '/');
}