1252884aeSStefan Eßer /* 2252884aeSStefan Eßer * ***************************************************************************** 3252884aeSStefan Eßer * 43aa99676SStefan Eßer * SPDX-License-Identifier: BSD-2-Clause 5252884aeSStefan Eßer * 6*a970610aSStefan Eßer * Copyright (c) 2018-2024 Gavin D. Howard and contributors. 7252884aeSStefan Eßer * 8252884aeSStefan Eßer * Redistribution and use in source and binary forms, with or without 9252884aeSStefan Eßer * modification, are permitted provided that the following conditions are met: 10252884aeSStefan Eßer * 11252884aeSStefan Eßer * * Redistributions of source code must retain the above copyright notice, this 12252884aeSStefan Eßer * list of conditions and the following disclaimer. 13252884aeSStefan Eßer * 14252884aeSStefan Eßer * * Redistributions in binary form must reproduce the above copyright notice, 15252884aeSStefan Eßer * this list of conditions and the following disclaimer in the documentation 16252884aeSStefan Eßer * and/or other materials provided with the distribution. 17252884aeSStefan Eßer * 18252884aeSStefan Eßer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19252884aeSStefan Eßer * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20252884aeSStefan Eßer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21252884aeSStefan Eßer * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22252884aeSStefan Eßer * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23252884aeSStefan Eßer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24252884aeSStefan Eßer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25252884aeSStefan Eßer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26252884aeSStefan Eßer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27252884aeSStefan Eßer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28252884aeSStefan Eßer * POSSIBILITY OF SUCH DAMAGE. 29252884aeSStefan Eßer * 30252884aeSStefan Eßer * ***************************************************************************** 31252884aeSStefan Eßer * 32252884aeSStefan Eßer * Definitions for bc vectors (resizable arrays). 33252884aeSStefan Eßer * 34252884aeSStefan Eßer */ 35252884aeSStefan Eßer 36252884aeSStefan Eßer #ifndef BC_VECTOR_H 37252884aeSStefan Eßer #define BC_VECTOR_H 38252884aeSStefan Eßer 39252884aeSStefan Eßer #include <stdbool.h> 40252884aeSStefan Eßer #include <stddef.h> 41252884aeSStefan Eßer #include <stdint.h> 42252884aeSStefan Eßer 43252884aeSStefan Eßer #include <status.h> 44252884aeSStefan Eßer 4544d4804dSStefan Eßer /// An invalid index for a map to mark when an item does not exist. 46252884aeSStefan Eßer #define BC_VEC_INVALID_IDX (SIZE_MAX) 4744d4804dSStefan Eßer 4844d4804dSStefan Eßer /// The starting capacity for vectors. This is based on the minimum allocation 4944d4804dSStefan Eßer /// for 64-bit systems. 50252884aeSStefan Eßer #define BC_VEC_START_CAP (UINTMAX_C(1) << 5) 51252884aeSStefan Eßer 5244d4804dSStefan Eßer /// An alias. 53252884aeSStefan Eßer typedef unsigned char uchar; 54252884aeSStefan Eßer 5544d4804dSStefan Eßer /** 5644d4804dSStefan Eßer * A destructor. Frees the object that @a ptr points to. This is used by vectors 5744d4804dSStefan Eßer * to free the memory they own. 5844d4804dSStefan Eßer * @param ptr Pointer to the data to free. 5944d4804dSStefan Eßer */ 6044d4804dSStefan Eßer typedef void (*BcVecFree)(void* ptr); 61252884aeSStefan Eßer 6244d4804dSStefan Eßer #if BC_LONG_BIT >= 64 6344d4804dSStefan Eßer 6444d4804dSStefan Eßer /// An integer to shrink the size of a vector by using these instead of size_t. 6544d4804dSStefan Eßer typedef uint32_t BcSize; 6644d4804dSStefan Eßer 6744d4804dSStefan Eßer #else // BC_LONG_BIT >= 64 6844d4804dSStefan Eßer 6944d4804dSStefan Eßer /// An integer to shrink the size of a vector by using these instead of size_t. 7044d4804dSStefan Eßer typedef uint16_t BcSize; 7144d4804dSStefan Eßer 7244d4804dSStefan Eßer #endif // BC_LONG_BIT >= 64 7344d4804dSStefan Eßer 7444d4804dSStefan Eßer /// An enum of all of the destructors. We use an enum to save space. 7578bc019dSStefan Eßer typedef enum BcDtorType 7678bc019dSStefan Eßer { 7744d4804dSStefan Eßer /// No destructor needed. 7844d4804dSStefan Eßer BC_DTOR_NONE, 7944d4804dSStefan Eßer 8044d4804dSStefan Eßer /// Vector destructor. 8144d4804dSStefan Eßer BC_DTOR_VEC, 8244d4804dSStefan Eßer 8344d4804dSStefan Eßer /// BcNum destructor. 8444d4804dSStefan Eßer BC_DTOR_NUM, 8544d4804dSStefan Eßer 8644d4804dSStefan Eßer #if !BC_ENABLE_LIBRARY 8744d4804dSStefan Eßer 88103d7cdfSStefan Eßer #if BC_DEBUG 8944d4804dSStefan Eßer 9044d4804dSStefan Eßer /// BcFunc destructor. 9144d4804dSStefan Eßer BC_DTOR_FUNC, 9244d4804dSStefan Eßer 93103d7cdfSStefan Eßer #endif // BC_DEBUG 9444d4804dSStefan Eßer 9544d4804dSStefan Eßer /// BcSlab destructor. 9644d4804dSStefan Eßer BC_DTOR_SLAB, 9744d4804dSStefan Eßer 9844d4804dSStefan Eßer /// BcConst destructor. 9944d4804dSStefan Eßer BC_DTOR_CONST, 10044d4804dSStefan Eßer 10144d4804dSStefan Eßer /// BcResult destructor. 10244d4804dSStefan Eßer BC_DTOR_RESULT, 10344d4804dSStefan Eßer 10444d4804dSStefan Eßer #if BC_ENABLE_HISTORY 10544d4804dSStefan Eßer 10644d4804dSStefan Eßer /// String destructor for history, which is *special*. 10744d4804dSStefan Eßer BC_DTOR_HISTORY_STRING, 10844d4804dSStefan Eßer 10944d4804dSStefan Eßer #endif // BC_ENABLE_HISTORY 11044d4804dSStefan Eßer #else // !BC_ENABLE_LIBRARY 11144d4804dSStefan Eßer 11244d4804dSStefan Eßer /// Destructor for bcl numbers. 11344d4804dSStefan Eßer BC_DTOR_BCL_NUM, 11444d4804dSStefan Eßer 11544d4804dSStefan Eßer #endif // !BC_ENABLE_LIBRARY 11644d4804dSStefan Eßer 11744d4804dSStefan Eßer } BcDtorType; 11844d4804dSStefan Eßer 11944d4804dSStefan Eßer /// The actual vector struct. 12078bc019dSStefan Eßer typedef struct BcVec 12178bc019dSStefan Eßer { 12244d4804dSStefan Eßer /// The vector array itself. This uses a char* because it is compatible with 12344d4804dSStefan Eßer /// pointers of all other types, and I can do pointer arithmetic on it. 12444d4804dSStefan Eßer char* restrict v; 12544d4804dSStefan Eßer 12644d4804dSStefan Eßer /// The length of the vector, which is how many items actually exist. 127252884aeSStefan Eßer size_t len; 12844d4804dSStefan Eßer 12944d4804dSStefan Eßer /// The capacity of the vector, which is how many items can fit in the 13044d4804dSStefan Eßer /// current allocation. 131252884aeSStefan Eßer size_t cap; 13244d4804dSStefan Eßer 13344d4804dSStefan Eßer /// The size of the items in the vector, as returned by sizeof(). 13444d4804dSStefan Eßer BcSize size; 13544d4804dSStefan Eßer 13644d4804dSStefan Eßer /// The destructor as a BcDtorType enum. 13744d4804dSStefan Eßer BcSize dtor; 13844d4804dSStefan Eßer 139252884aeSStefan Eßer } BcVec; 140252884aeSStefan Eßer 14144d4804dSStefan Eßer /** 14244d4804dSStefan Eßer * Initializes a vector. 14344d4804dSStefan Eßer * @param v The vector to initialize. 14444d4804dSStefan Eßer * @param esize The size of the elements, as returned by sizeof(). 14544d4804dSStefan Eßer * @param dtor The destructor of the elements, as a BcDtorType enum. 14644d4804dSStefan Eßer */ 14778bc019dSStefan Eßer void 14878bc019dSStefan Eßer bc_vec_init(BcVec* restrict v, size_t esize, BcDtorType dtor); 14944d4804dSStefan Eßer 15044d4804dSStefan Eßer /** 15144d4804dSStefan Eßer * Expands the vector to have a capacity of @a req items, if it doesn't have 15244d4804dSStefan Eßer * enough already. 15344d4804dSStefan Eßer * @param v The vector to expand. 15444d4804dSStefan Eßer * @param req The requested capacity. 15544d4804dSStefan Eßer */ 15678bc019dSStefan Eßer void 15778bc019dSStefan Eßer bc_vec_expand(BcVec* restrict v, size_t req); 15844d4804dSStefan Eßer 15944d4804dSStefan Eßer /** 16044d4804dSStefan Eßer * Grow a vector by at least @a n elements. 16144d4804dSStefan Eßer * @param v The vector to grow. 16244d4804dSStefan Eßer * @param n The number of elements to grow the vector by. 16344d4804dSStefan Eßer */ 16478bc019dSStefan Eßer void 16578bc019dSStefan Eßer bc_vec_grow(BcVec* restrict v, size_t n); 166252884aeSStefan Eßer 16744d4804dSStefan Eßer /** 16844d4804dSStefan Eßer * Pops @a n items off the back of the vector. The vector must have at least 16944d4804dSStefan Eßer * @a n elements. 17044d4804dSStefan Eßer * @param v The vector to pop off of. 17144d4804dSStefan Eßer * @param n The number of elements to pop off. 17244d4804dSStefan Eßer */ 17378bc019dSStefan Eßer void 17478bc019dSStefan Eßer bc_vec_npop(BcVec* restrict v, size_t n); 17544d4804dSStefan Eßer 17644d4804dSStefan Eßer /** 17744d4804dSStefan Eßer * Pops @a n items, starting at index @a idx, off the vector. The vector must 17844d4804dSStefan Eßer * have at least @a n elements after the @a idx index. Any remaining elements at 17944d4804dSStefan Eßer * the end are moved up to fill the hole. 18044d4804dSStefan Eßer * @param v The vector to pop off of. 18144d4804dSStefan Eßer * @param n The number of elements to pop off. 18244d4804dSStefan Eßer * @param idx The index to start popping at. 18344d4804dSStefan Eßer */ 18478bc019dSStefan Eßer void 18578bc019dSStefan Eßer bc_vec_npopAt(BcVec* restrict v, size_t n, size_t idx); 186252884aeSStefan Eßer 18744d4804dSStefan Eßer /** 18844d4804dSStefan Eßer * Pushes one item on the back of the vector. It does a memcpy(), but it assumes 18944d4804dSStefan Eßer * that the vector takes ownership of the data. 19044d4804dSStefan Eßer * @param v The vector to push onto. 19144d4804dSStefan Eßer * @param data A pointer to the data to push. 19244d4804dSStefan Eßer */ 19378bc019dSStefan Eßer void 19478bc019dSStefan Eßer bc_vec_push(BcVec* restrict v, const void* data); 19544d4804dSStefan Eßer 19644d4804dSStefan Eßer /** 19744d4804dSStefan Eßer * Pushes @a n items on the back of the vector. It does a memcpy(), but it 19844d4804dSStefan Eßer * assumes that the vector takes ownership of the data. 19944d4804dSStefan Eßer * @param v The vector to push onto. 20044d4804dSStefan Eßer * @param data A pointer to the elements of data to push. 20144d4804dSStefan Eßer */ 20278bc019dSStefan Eßer void 20378bc019dSStefan Eßer bc_vec_npush(BcVec* restrict v, size_t n, const void* data); 20444d4804dSStefan Eßer 20544d4804dSStefan Eßer /** 20644d4804dSStefan Eßer * Push an empty element and return a pointer to it. This is done as an 20744d4804dSStefan Eßer * optimization where initializing an item needs a pointer anyway. It removes an 20844d4804dSStefan Eßer * extra memcpy(). 20944d4804dSStefan Eßer * @param v The vector to push onto. 21044d4804dSStefan Eßer * @return A pointer to the newly-pushed element. 21144d4804dSStefan Eßer */ 21278bc019dSStefan Eßer void* 21378bc019dSStefan Eßer bc_vec_pushEmpty(BcVec* restrict v); 21444d4804dSStefan Eßer 21544d4804dSStefan Eßer /** 21644d4804dSStefan Eßer * Pushes a byte onto a bytecode vector. This is a convenience function for the 21744d4804dSStefan Eßer * parsers pushing instructions. The vector must be a bytecode vector. 21844d4804dSStefan Eßer * @param v The vector to push onto. 21944d4804dSStefan Eßer * @param data The byte to push. 22044d4804dSStefan Eßer */ 22178bc019dSStefan Eßer void 22278bc019dSStefan Eßer bc_vec_pushByte(BcVec* restrict v, uchar data); 22344d4804dSStefan Eßer 22444d4804dSStefan Eßer /** 22544d4804dSStefan Eßer * Pushes and index onto a bytecode vector. The vector must be a bytecode 22644d4804dSStefan Eßer * vector. For more info about why and how this is done, see the development 22744d4804dSStefan Eßer * manual (manuals/development#bytecode-indices). 22844d4804dSStefan Eßer * @param v The vector to push onto. 22944d4804dSStefan Eßer * @param idx The index to push. 23044d4804dSStefan Eßer */ 23178bc019dSStefan Eßer void 23278bc019dSStefan Eßer bc_vec_pushIndex(BcVec* restrict v, size_t idx); 23344d4804dSStefan Eßer 23444d4804dSStefan Eßer /** 23544d4804dSStefan Eßer * Push an item onto the vector at a certain index. The index must be valid 23644d4804dSStefan Eßer * (either exists or is equal to the length of the vector). The elements at that 23744d4804dSStefan Eßer * index and after are moved back one element and kept in the same order. This 23844d4804dSStefan Eßer * is how the map vectors are kept sorted. 23944d4804dSStefan Eßer * @param v The vector to push onto. 24044d4804dSStefan Eßer * @param data A pointer to the data to push. 24144d4804dSStefan Eßer * @param idx The index to push at. 24244d4804dSStefan Eßer */ 24378bc019dSStefan Eßer void 24478bc019dSStefan Eßer bc_vec_pushAt(BcVec* restrict v, const void* data, size_t idx); 24544d4804dSStefan Eßer 24644d4804dSStefan Eßer /** 24744d4804dSStefan Eßer * Empties the vector and sets it to the string. The vector must be a valid 24844d4804dSStefan Eßer * vector and must have chars as its elements. 24944d4804dSStefan Eßer * @param v The vector to set to the string. 25044d4804dSStefan Eßer * @param len The length of the string. This can be less than the actual length 25144d4804dSStefan Eßer * of the string, but must never be more. 25244d4804dSStefan Eßer * @param str The string to push. 25344d4804dSStefan Eßer */ 25478bc019dSStefan Eßer void 25578bc019dSStefan Eßer bc_vec_string(BcVec* restrict v, size_t len, const char* restrict str); 25644d4804dSStefan Eßer 25744d4804dSStefan Eßer /** 25844d4804dSStefan Eßer * Appends the string to the end of the vector, which must be holding a string 25944d4804dSStefan Eßer * (nul byte-terminated) already. 26044d4804dSStefan Eßer * @param v The vector to append to. 26144d4804dSStefan Eßer * @param str The string to append (by copying). 26244d4804dSStefan Eßer */ 26378bc019dSStefan Eßer void 26478bc019dSStefan Eßer bc_vec_concat(BcVec* restrict v, const char* restrict str); 26544d4804dSStefan Eßer 26644d4804dSStefan Eßer /** 26744d4804dSStefan Eßer * Empties a vector and pushes a nul-byte at the first index. The vector must be 26844d4804dSStefan Eßer * a char vector. 26944d4804dSStefan Eßer */ 27078bc019dSStefan Eßer void 27178bc019dSStefan Eßer bc_vec_empty(BcVec* restrict v); 272252884aeSStefan Eßer 273252884aeSStefan Eßer #if BC_ENABLE_HISTORY 27444d4804dSStefan Eßer 27544d4804dSStefan Eßer /** 27644d4804dSStefan Eßer * Replaces an item at a particular index. No elements are moved. The index must 27744d4804dSStefan Eßer * exist. 27844d4804dSStefan Eßer * @param v The vector to replace an item on. 27944d4804dSStefan Eßer * @param idx The index of the item to replace. 28044d4804dSStefan Eßer * @param data The data to replace the item with. 28144d4804dSStefan Eßer */ 28278bc019dSStefan Eßer void 28378bc019dSStefan Eßer bc_vec_replaceAt(BcVec* restrict v, size_t idx, const void* data); 28444d4804dSStefan Eßer 285252884aeSStefan Eßer #endif // BC_ENABLE_HISTORY 286252884aeSStefan Eßer 28744d4804dSStefan Eßer /** 28844d4804dSStefan Eßer * Returns a pointer to the item in the vector at the index. This is the key 28944d4804dSStefan Eßer * function for vectors. The index must exist. 29044d4804dSStefan Eßer * @param v The vector. 29144d4804dSStefan Eßer * @param idx The index to the item to get a pointer to. 29244d4804dSStefan Eßer * @return A pointer to the item at @a idx. 29344d4804dSStefan Eßer */ 29478bc019dSStefan Eßer void* 29578bc019dSStefan Eßer bc_vec_item(const BcVec* restrict v, size_t idx); 29644d4804dSStefan Eßer 29744d4804dSStefan Eßer /** 29844d4804dSStefan Eßer * Returns a pointer to the item in the vector at the index, reversed. This is 29944d4804dSStefan Eßer * another key function for vectors. The index must exist. 30044d4804dSStefan Eßer * @param v The vector. 30144d4804dSStefan Eßer * @param idx The index to the item to get a pointer to. 30244d4804dSStefan Eßer * @return A pointer to the item at len - @a idx - 1. 30344d4804dSStefan Eßer */ 30478bc019dSStefan Eßer void* 30578bc019dSStefan Eßer bc_vec_item_rev(const BcVec* restrict v, size_t idx); 306252884aeSStefan Eßer 30744d4804dSStefan Eßer /** 30844d4804dSStefan Eßer * Zeros a vector. The vector must not be allocated. 30944d4804dSStefan Eßer * @param v The vector to clear. 31044d4804dSStefan Eßer */ 31178bc019dSStefan Eßer void 31278bc019dSStefan Eßer bc_vec_clear(BcVec* restrict v); 313252884aeSStefan Eßer 31444d4804dSStefan Eßer /** 31544d4804dSStefan Eßer * Frees a vector and its elements. This is a destructor. 31644d4804dSStefan Eßer * @param vec A vector as a void pointer. 31744d4804dSStefan Eßer */ 31878bc019dSStefan Eßer void 31978bc019dSStefan Eßer bc_vec_free(void* vec); 320252884aeSStefan Eßer 32144d4804dSStefan Eßer /** 322d101cdd6SStefan Eßer * Attempts to insert an ID into a map and returns true if it succeeded, false 32344d4804dSStefan Eßer * if the item already exists. 32444d4804dSStefan Eßer * @param v The map vector to insert into. 32544d4804dSStefan Eßer * @param name The name of the item to insert. This name is assumed to be owned 32644d4804dSStefan Eßer * by another entity. 32744d4804dSStefan Eßer * @param idx The index of the partner array where the actual item is. 32844d4804dSStefan Eßer * @param i A pointer to an index that will be set to the index of the item 32944d4804dSStefan Eßer * in the map. 33044d4804dSStefan Eßer * @return True if the item was inserted, false if the item already exists. 33144d4804dSStefan Eßer */ 33278bc019dSStefan Eßer bool 33378bc019dSStefan Eßer bc_map_insert(BcVec* restrict v, const char* name, size_t idx, 33478bc019dSStefan Eßer size_t* restrict i); 33544d4804dSStefan Eßer 33644d4804dSStefan Eßer /** 33744d4804dSStefan Eßer * Returns the index of the item with @a name in the map, or BC_VEC_INVALID_IDX 33844d4804dSStefan Eßer * if it doesn't exist. 33944d4804dSStefan Eßer * @param v The map vector. 34044d4804dSStefan Eßer * @param name The name of the item to find. 34144d4804dSStefan Eßer * @return The index in the map of the item with @a name, or 34244d4804dSStefan Eßer * BC_VEC_INVALID_IDX if the item does not exist. 34344d4804dSStefan Eßer */ 34478bc019dSStefan Eßer size_t 34578bc019dSStefan Eßer bc_map_index(const BcVec* restrict v, const char* name); 346252884aeSStefan Eßer 34744d4804dSStefan Eßer #if DC_ENABLED 34844d4804dSStefan Eßer 34944d4804dSStefan Eßer /** 35044d4804dSStefan Eßer * Returns the name of the item at index @a idx in the map. 35144d4804dSStefan Eßer * @param v The map vector. 35244d4804dSStefan Eßer * @param idx The index. 35344d4804dSStefan Eßer * @return The name of the item at @a idx. 35444d4804dSStefan Eßer */ 35578bc019dSStefan Eßer const char* 35678bc019dSStefan Eßer bc_map_name(const BcVec* restrict v, size_t idx); 35744d4804dSStefan Eßer 35844d4804dSStefan Eßer #endif // DC_ENABLED 35944d4804dSStefan Eßer 36044d4804dSStefan Eßer /** 36144d4804dSStefan Eßer * Pops one item off of the vector. 36244d4804dSStefan Eßer * @param v The vector to pop one item off of. 36344d4804dSStefan Eßer */ 364252884aeSStefan Eßer #define bc_vec_pop(v) (bc_vec_npop((v), 1)) 36544d4804dSStefan Eßer 36644d4804dSStefan Eßer /** 36744d4804dSStefan Eßer * Pops all items off of the vector. 36844d4804dSStefan Eßer * @param v The vector to pop all items off of. 36944d4804dSStefan Eßer */ 37010328f8bSStefan Eßer #define bc_vec_popAll(v) (bc_vec_npop((v), (v)->len)) 37144d4804dSStefan Eßer 37244d4804dSStefan Eßer /** 37344d4804dSStefan Eßer * Return a pointer to the last item in the vector, or first if it's being 37444d4804dSStefan Eßer * treated as a stack. 37544d4804dSStefan Eßer * @param v The vector to get the top of stack of. 37644d4804dSStefan Eßer */ 377252884aeSStefan Eßer #define bc_vec_top(v) (bc_vec_item_rev((v), 0)) 378252884aeSStefan Eßer 37944d4804dSStefan Eßer /** 38044d4804dSStefan Eßer * Initializes a vector to serve as a map. 38144d4804dSStefan Eßer * @param v The vector to initialize. 38244d4804dSStefan Eßer */ 38344d4804dSStefan Eßer #define bc_map_init(v) (bc_vec_init((v), sizeof(BcId), BC_DTOR_NONE)) 38444d4804dSStefan Eßer 38544d4804dSStefan Eßer /// A reference to the array of destructors. 38644d4804dSStefan Eßer extern const BcVecFree bc_vec_dtors[]; 38744d4804dSStefan Eßer 38844d4804dSStefan Eßer #if !BC_ENABLE_LIBRARY 38944d4804dSStefan Eßer 39044d4804dSStefan Eßer /// The allocated size of slabs. 39144d4804dSStefan Eßer #define BC_SLAB_SIZE (4096) 39244d4804dSStefan Eßer 39344d4804dSStefan Eßer /// A slab for allocating strings. 39478bc019dSStefan Eßer typedef struct BcSlab 39578bc019dSStefan Eßer { 39644d4804dSStefan Eßer /// The actual allocation. 39744d4804dSStefan Eßer char* s; 39844d4804dSStefan Eßer 39944d4804dSStefan Eßer /// How many bytes of the slab are taken. 40044d4804dSStefan Eßer size_t len; 40144d4804dSStefan Eßer 40244d4804dSStefan Eßer } BcSlab; 40344d4804dSStefan Eßer 40444d4804dSStefan Eßer /** 40544d4804dSStefan Eßer * Frees a slab. This is a destructor. 40644d4804dSStefan Eßer * @param slab The slab as a void pointer. 40744d4804dSStefan Eßer */ 40878bc019dSStefan Eßer void 40978bc019dSStefan Eßer bc_slab_free(void* slab); 41044d4804dSStefan Eßer 41144d4804dSStefan Eßer /** 41244d4804dSStefan Eßer * Initializes a slab vector. 41344d4804dSStefan Eßer * @param v The vector to initialize. 41444d4804dSStefan Eßer */ 41578bc019dSStefan Eßer void 41678bc019dSStefan Eßer bc_slabvec_init(BcVec* restrict v); 41744d4804dSStefan Eßer 41844d4804dSStefan Eßer /** 41944d4804dSStefan Eßer * Duplicates the string using slabs in the slab vector. 42044d4804dSStefan Eßer * @param v The slab vector. 42144d4804dSStefan Eßer * @param str The string to duplicate. 42244d4804dSStefan Eßer * @return A pointer to the duplicated string, owned by the slab vector. 42344d4804dSStefan Eßer */ 42478bc019dSStefan Eßer char* 42578bc019dSStefan Eßer bc_slabvec_strdup(BcVec* restrict v, const char* str); 42644d4804dSStefan Eßer 42744d4804dSStefan Eßer /** 42844d4804dSStefan Eßer * Clears a slab vector. This deallocates all but the first slab and clears the 42944d4804dSStefan Eßer * first slab. 43044d4804dSStefan Eßer * @param v The slab vector to clear. 43144d4804dSStefan Eßer */ 43278bc019dSStefan Eßer void 43378bc019dSStefan Eßer bc_slabvec_clear(BcVec* restrict v); 43444d4804dSStefan Eßer 43544d4804dSStefan Eßer #if BC_DEBUG_CODE 43644d4804dSStefan Eßer 43744d4804dSStefan Eßer /** 43844d4804dSStefan Eßer * Prints all of the items in a slab vector, in order. 43944d4804dSStefan Eßer * @param v The vector whose items will be printed. 44044d4804dSStefan Eßer */ 44178bc019dSStefan Eßer void 44278bc019dSStefan Eßer bc_slabvec_print(BcVec* v, const char* func); 44344d4804dSStefan Eßer 44444d4804dSStefan Eßer #endif // BC_DEBUG_CODE 44544d4804dSStefan Eßer 44644d4804dSStefan Eßer /// A convenience macro for freeing a vector of slabs. 44744d4804dSStefan Eßer #define bc_slabvec_free bc_vec_free 44844d4804dSStefan Eßer 44944d4804dSStefan Eßer #ifndef _WIN32 45044d4804dSStefan Eßer 45144d4804dSStefan Eßer /** 45244d4804dSStefan Eßer * A macro to get rid of a warning on Windows. 45344d4804dSStefan Eßer * @param d The destination string. 45444d4804dSStefan Eßer * @param l The length of the destination string. This has to be big enough to 45544d4804dSStefan Eßer * contain @a s. 45644d4804dSStefan Eßer * @param s The source string. 45744d4804dSStefan Eßer */ 458662087dfSStefan Eßer #define bc_strcpy(d, l, s) strcpy(d, s) 45944d4804dSStefan Eßer 46044d4804dSStefan Eßer #else // _WIN32 46144d4804dSStefan Eßer 46244d4804dSStefan Eßer /** 46344d4804dSStefan Eßer * A macro to get rid of a warning on Windows. 46444d4804dSStefan Eßer * @param d The destination string. 46544d4804dSStefan Eßer * @param l The length of the destination string. This has to be big enough to 46644d4804dSStefan Eßer * contain @a s. 46744d4804dSStefan Eßer * @param s The source string. 46844d4804dSStefan Eßer */ 469662087dfSStefan Eßer #define bc_strcpy(d, l, s) strcpy_s(d, l, s) 47044d4804dSStefan Eßer 47144d4804dSStefan Eßer #endif // _WIN32 47244d4804dSStefan Eßer 47344d4804dSStefan Eßer #endif // !BC_ENABLE_LIBRARY 474252884aeSStefan Eßer 475252884aeSStefan Eßer #endif // BC_VECTOR_H 476