summaryrefslogtreecommitdiff
path: root/src/utils.h
blob: 571a2170587a7c88c3ba44d085e1a8c3ad8c87cb (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#pragma once

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


#define DECLARE_VEC(T, Name)                                         \
    typedef struct {                                                 \
        T **blocks;                                                  \
        size_t count;                                                \
        size_t used;                                                 \
        size_t cap;                                                  \
        size_t block_size;                                           \
    } Name;                                                          \
                                                                     \
    static inline Name make_##Name(size_t block_size) {              \
        return (Name){                                               \
            .blocks = NULL,                                          \
            .count = 0,                                              \
            .used = 0,                                               \
            .cap = 0,                                                \
            .block_size = block_size,                                \
        };                                                           \
    }                                                                \
                                                                     \
    static inline T *push_to_##Name(Name *vec, T item) {             \
        size_t block_index = vec->count / vec->block_size;           \
        size_t item_index  = vec->count % vec->block_size;           \
                                                                     \
        if (block_index == vec->used) {                              \
            if (vec->used == vec->cap) {                             \
                size_t new_cap = vec->cap                            \
                    ? vec->cap * 2                                   \
                    : 8;                                             \
                                                                     \
                T **new_blocks = realloc(                            \
                    vec->blocks,                                     \
                    new_cap * sizeof(T *)                            \
                );                                                   \
                                                                     \
                if (!new_blocks) abort();                            \
                                                                     \
                vec->blocks = new_blocks;                            \
                vec->cap = new_cap;                                  \
            }                                                        \
                                                                     \
            vec->blocks[vec->used] =                                 \
                malloc(vec->block_size * sizeof(T));                 \
                                                                     \
            if (!vec->blocks[vec->used]) abort();                    \
                                                                     \
            vec->used++;                                             \
        }                                                            \
                                                                     \
        T *ptr = &vec->blocks[block_index][item_index];              \
        *ptr = item;                                                 \
                                                                     \
        vec->count++;                                                \
        return ptr;                                                  \
    }                                                                \
                                                                     \
    static inline T* get_from_##Name(Name *vec, size_t index) {      \
        if (index >= vec->count) return NULL;                        \
                                                                     \
        return &vec->blocks                                          \
            [index / vec->block_size]                                \
            [index % vec->block_size];                               \
    }                                                                \

DECLARE_VEC(int, IntVec)
DECLARE_VEC(char, String);
DECLARE_VEC(char*, StrVec)


void append_str_to_String(String* target, const char* src_str);
char* inner(String* str);



#define DECLARE_MAYBE(T, Name)                                      \
    typedef struct {                                                \
        bool some;                                                  \
        T value;                                                    \
    } Name;                                                     

DECLARE_MAYBE(char*, MaybeStr)


typedef struct {
    char* key;
    char* val;
} StrPair;
DECLARE_VEC(StrPair, KeyValMap)

void set_map_pair(KeyValMap* map, StrPair);
MaybeStr get_map_value(KeyValMap* map, char* key);
void unset_map_key(KeyValMap* map, char* key);


typedef struct {
    KeyValMap aliases;
    KeyValMap shell_vars;
} ShellState;

char* get_var(char* varname, ShellState* shstate);

bool is_identifier(char* str);