Files
openide/native/fsNotifier/linux/util.c
Roman Shevchenko 7163a25b10 [vfs] updating in Linux/WSL fsnotifier
Dropping `syslog(3)` use; forwarding errors and warnings to the IDE via `stderr`

GitOrigin-RevId: c981356950a0ac3cdcd60990a714f8e7e7220496
2021-04-16 13:21:12 +03:00

190 lines
3.4 KiB
C

// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#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 = calloc(1, sizeof(array));
if (a == NULL) {
return NULL;
}
a->data = calloc(initial_capacity, sizeof(void*));
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 = calloc(1, sizeof(table));
if (t == NULL) {
return NULL;
}
t->data = calloc(capacity, sizeof(void*));
if (t->data == NULL) {
free(t);
return NULL;
}
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] == '/');
}