queries c.h c.scm cpp.h cpp.scm cuda.h cuda.scm glsl.h glsl.scm go.h go.scm javascript.h javascript.scm kotlin.h kotlin.scm lua.h lua.scm odin.h odin.scm php.h php.scm python.h python.scm rust.h rust.scm tcl.h tcl.scm zig.h zig.scm
tests
depth_test
sub level1.c
level0.c
test.c test.cpp test.cu test.cuh test.glsl test.go test.js test.kt test.lua test.odin test.php test.py test.rs test.tcl test.zig
vendor
tree-sitter
lib
include
tree_sitter api.h parser.h
src
unicode ICU_SHA LICENSE README.md ptypes.h umachine.h urename.h utf.h utf16.h utf8.h
alloc.c alloc.h array.h atomic.h clock.h error_costs.h get_changed_ranges.c get_changed_ranges.h host.h language.c language.h length.h lexer.c lexer.h lib.c node.c parser.c point.h query.c reduce_action.h reusable_node.h stack.c stack.h subtree.c subtree.h tree.c tree.h tree_cursor.c tree_cursor.h unicode.h
LICENSE Makefile
tree-sitter-c
src
tree_sitter parser.h
grammar.json node-types.json parser.c
LICENSE Makefile
tree-sitter-cpp
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-cuda
src
tree_sitter alloc.h array.h parser.h runtime.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-glsl
src
tree_sitter alloc.h array.h parser.h runtime.h
grammar.json node-types.json parser.c
LICENSE Makefile
tree-sitter-go
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c
LICENSE Makefile
tree-sitter-javascript
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-kotlin
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-lua
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE.md Makefile
tree-sitter-odin
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-php
src
common common.mak define-grammar.js scanner.h
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-python
src
tree_sitter parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-rust
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-tcl
src
tree_sitter parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-template Makefile
tree-sitter-zig
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c
LICENSE Makefile
.clang-format .gitattributes .gitignore LICENSE Makefile README.md abicheck.c compile_flags.txt file.c file.h list.c list.h main.c tests.sh tpool.c tpool.h
vendor/tree-sitter/lib/src/array.h raw
  1#ifndef TREE_SITTER_ARRAY_H_
  2#define TREE_SITTER_ARRAY_H_
  3
  4#ifdef __cplusplus
  5extern "C" {
  6#endif
  7
  8#include <string.h>
  9#include <stdlib.h>
 10#include <stdint.h>
 11#include <assert.h>
 12#include <stdbool.h>
 13#include "./alloc.h"
 14
 15#define Array(T)       \
 16  struct {             \
 17    T *contents;       \
 18    uint32_t size;     \
 19    uint32_t capacity; \
 20  }
 21
 22#define array_init(self) \
 23  ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
 24
 25#define array_new() \
 26  { NULL, 0, 0 }
 27
 28#define array_get(self, _index) \
 29  (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index])
 30
 31#define array_front(self) array_get(self, 0)
 32
 33#define array_back(self) array_get(self, (self)->size - 1)
 34
 35#define array_clear(self) ((self)->size = 0)
 36
 37#define array_reserve(self, new_capacity) \
 38  array__reserve((VoidArray *)(self), array__elem_size(self), new_capacity)
 39
 40// Free any memory allocated for this array.
 41#define array_delete(self) array__delete((VoidArray *)(self))
 42
 43#define array_push(self, element)                            \
 44  (array__grow((VoidArray *)(self), 1, array__elem_size(self)), \
 45   (self)->contents[(self)->size++] = (element))
 46
 47// Increase the array's size by a given number of elements, reallocating
 48// if necessary. New elements are zero-initialized.
 49#define array_grow_by(self, count) \
 50  (array__grow((VoidArray *)(self), count, array__elem_size(self)), \
 51   memset((self)->contents + (self)->size, 0, (count) * array__elem_size(self)), \
 52   (self)->size += (count))
 53
 54#define array_push_all(self, other)                                       \
 55  array_extend((self), (other)->size, (other)->contents)
 56
 57// Append `count` elements to the end of the array, reading their values from the
 58// `contents` pointer.
 59#define array_extend(self, count, contents)                    \
 60  array__splice(                                               \
 61    (VoidArray *)(self), array__elem_size(self), (self)->size, \
 62    0, count,  contents                                        \
 63  )
 64
 65// Remove `old_count` elements from the array starting at the given `index`. At
 66// the same index, insert `new_count` new elements, reading their values from the
 67// `new_contents` pointer.
 68#define array_splice(self, _index, old_count, new_count, new_contents)  \
 69  array__splice(                                                       \
 70    (VoidArray *)(self), array__elem_size(self), _index,                \
 71    old_count, new_count, new_contents                                 \
 72  )
 73
 74// Insert one `element` into the array at the given `index`.
 75#define array_insert(self, _index, element) \
 76  array__splice((VoidArray *)(self), array__elem_size(self), _index, 0, 1, &(element))
 77
 78// Remove one `element` from the array at the given `index`.
 79#define array_erase(self, _index) \
 80  array__erase((VoidArray *)(self), array__elem_size(self), _index)
 81
 82#define array_pop(self) ((self)->contents[--(self)->size])
 83
 84#define array_assign(self, other) \
 85  array__assign((VoidArray *)(self), (const VoidArray *)(other), array__elem_size(self))
 86
 87#define array_swap(self, other) \
 88  array__swap((VoidArray *)(self), (VoidArray *)(other))
 89
 90// Search a sorted array for a given `needle` value, using the given `compare`
 91// callback to determine the order.
 92//
 93// If an existing element is found to be equal to `needle`, then the `index`
 94// out-parameter is set to the existing value's index, and the `exists`
 95// out-parameter is set to true. Otherwise, `index` is set to an index where
 96// `needle` should be inserted in order to preserve the sorting, and `exists`
 97// is set to false.
 98#define array_search_sorted_with(self, compare, needle, _index, _exists) \
 99  array__search_sorted(self, 0, compare, , needle, _index, _exists)
100
101// Search a sorted array for a given `needle` value, using integer comparisons
102// of a given struct field (specified with a leading dot) to determine the order.
103//
104// See also `array_search_sorted_with`.
105#define array_search_sorted_by(self, field, needle, _index, _exists) \
106  array__search_sorted(self, 0, compare_int, field, needle, _index, _exists)
107
108// Insert a given `value` into a sorted array, using the given `compare`
109// callback to determine the order.
110#define array_insert_sorted_with(self, compare, value) \
111  do { \
112    unsigned _index, _exists; \
113    array_search_sorted_with(self, compare, &(value), &_index, &_exists); \
114    if (!_exists) array_insert(self, _index, value); \
115  } while (0)
116
117// Insert a given `value` into a sorted array, using integer comparisons of
118// a given struct field (specified with a leading dot) to determine the order.
119//
120// See also `array_search_sorted_by`.
121#define array_insert_sorted_by(self, field, value) \
122  do { \
123    unsigned _index, _exists; \
124    array_search_sorted_by(self, field, (value) field, &_index, &_exists); \
125    if (!_exists) array_insert(self, _index, value); \
126  } while (0)
127
128// Private
129
130typedef Array(void) VoidArray;
131
132#define array__elem_size(self) sizeof(*(self)->contents)
133
134static inline void array__delete(VoidArray *self) {
135  if (self->contents) {
136    ts_free(self->contents);
137    self->contents = NULL;
138    self->size = 0;
139    self->capacity = 0;
140  }
141}
142
143static inline void array__erase(VoidArray *self, size_t element_size,
144                                uint32_t index) {
145  assert(index < self->size);
146  char *contents = (char *)self->contents;
147  memmove(contents + index * element_size, contents + (index + 1) * element_size,
148          (self->size - index - 1) * element_size);
149  self->size--;
150}
151
152static inline void array__reserve(VoidArray *self, size_t element_size, uint32_t new_capacity) {
153  if (new_capacity > self->capacity) {
154    if (self->contents) {
155      self->contents = ts_realloc(self->contents, new_capacity * element_size);
156    } else {
157      self->contents = ts_malloc(new_capacity * element_size);
158    }
159    self->capacity = new_capacity;
160  }
161}
162
163static inline void array__assign(VoidArray *self, const VoidArray *other, size_t element_size) {
164  array__reserve(self, element_size, other->size);
165  self->size = other->size;
166  memcpy(self->contents, other->contents, self->size * element_size);
167}
168
169static inline void array__swap(VoidArray *self, VoidArray *other) {
170  VoidArray swap = *other;
171  *other = *self;
172  *self = swap;
173}
174
175static inline void array__grow(VoidArray *self, uint32_t count, size_t element_size) {
176  uint32_t new_size = self->size + count;
177  if (new_size > self->capacity) {
178    uint32_t new_capacity = self->capacity * 2;
179    if (new_capacity < 8) new_capacity = 8;
180    if (new_capacity < new_size) new_capacity = new_size;
181    array__reserve(self, element_size, new_capacity);
182  }
183}
184
185static inline void array__splice(VoidArray *self, size_t element_size,
186                                 uint32_t index, uint32_t old_count,
187                                 uint32_t new_count, const void *elements) {
188  uint32_t new_size = self->size + new_count - old_count;
189  uint32_t old_end = index + old_count;
190  uint32_t new_end = index + new_count;
191  assert(old_end <= self->size);
192
193  array__reserve(self, element_size, new_size);
194
195  char *contents = (char *)self->contents;
196  if (self->size > old_end) {
197    memmove(
198      contents + new_end * element_size,
199      contents + old_end * element_size,
200      (self->size - old_end) * element_size
201    );
202  }
203  if (new_count > 0) {
204    if (elements) {
205      memcpy(
206        (contents + index * element_size),
207        elements,
208        new_count * element_size
209      );
210    } else {
211      memset(
212        (contents + index * element_size),
213        0,
214        new_count * element_size
215      );
216    }
217  }
218  self->size += new_count - old_count;
219}
220
221// A binary search routine, based on Rust's `std::slice::binary_search_by`.
222#define array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \
223  do { \
224    *(_index) = start; \
225    *(_exists) = false; \
226    uint32_t size = (self)->size - *(_index); \
227    if (size == 0) break; \
228    int comparison; \
229    while (size > 1) { \
230      uint32_t half_size = size / 2; \
231      uint32_t mid_index = *(_index) + half_size; \
232      comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \
233      if (comparison <= 0) *(_index) = mid_index; \
234      size -= half_size; \
235    } \
236    comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
237    if (comparison == 0) *(_exists) = true; \
238    else if (comparison < 0) *(_index) += 1; \
239  } while (0)
240
241// Helper macro for the `_sorted_by` routines below. This takes the left (existing)
242// parameter by reference in order to work with the generic sorting function above.
243#define compare_int(a, b) ((int)*(a) - (int)(b))
244
245#ifdef __cplusplus
246}
247#endif
248
249#endif  // TREE_SITTER_ARRAY_H_