teptris 0.2.36-x86_64-linux → 0.2.38-x86_64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/ext/teptris_ext/engine/LICENSE.md +21 -0
  3. data/ext/teptris_ext/engine/src/include/teptris/plan.h +123 -0
  4. data/ext/teptris_ext/engine/src/include/teptris/teptris.h +208 -0
  5. data/ext/teptris_ext/engine/src/include/teptris/version.h +9 -0
  6. data/ext/teptris_ext/engine/src/teptris/api.c +362 -0
  7. data/ext/teptris_ext/engine/src/teptris/build.c +355 -0
  8. data/ext/teptris_ext/engine/src/teptris/common/chartype.c +70 -0
  9. data/ext/teptris_ext/engine/src/teptris/common/chartype.h +41 -0
  10. data/ext/teptris_ext/engine/src/teptris/common/ryu/common.h +114 -0
  11. data/ext/teptris_ext/engine/src/teptris/common/ryu/d2s.c +496 -0
  12. data/ext/teptris_ext/engine/src/teptris/common/ryu/d2s_full_table.h +367 -0
  13. data/ext/teptris_ext/engine/src/teptris/common/ryu/d2s_intrinsics.h +357 -0
  14. data/ext/teptris_ext/engine/src/teptris/common/ryu/digit_table.h +35 -0
  15. data/ext/teptris_ext/engine/src/teptris/common/ryu/ryu_d2s.h +39 -0
  16. data/ext/teptris_ext/engine/src/teptris/common/ryu/ryu_parse.h +45 -0
  17. data/ext/teptris_ext/engine/src/teptris/common/ryu/s2d.c +259 -0
  18. data/ext/teptris_ext/engine/src/teptris/common/simd.h +119 -0
  19. data/ext/teptris_ext/engine/src/teptris/dom/dom.c +192 -0
  20. data/ext/teptris_ext/engine/src/teptris/dom/dom.h +124 -0
  21. data/ext/teptris_ext/engine/src/teptris/emit/emitter.c +718 -0
  22. data/ext/teptris_ext/engine/src/teptris/emit/emitter.h +11 -0
  23. data/ext/teptris_ext/engine/src/teptris/memory/arena.c +104 -0
  24. data/ext/teptris_ext/engine/src/teptris/memory/arena.h +53 -0
  25. data/ext/teptris_ext/engine/src/teptris/parse/datetime.c +218 -0
  26. data/ext/teptris_ext/engine/src/teptris/parse/keys.c +121 -0
  27. data/ext/teptris_ext/engine/src/teptris/parse/parse.h +76 -0
  28. data/ext/teptris_ext/engine/src/teptris/parse/parser.c +931 -0
  29. data/ext/teptris_ext/engine/src/teptris/parse/scalars.c +940 -0
  30. data/ext/teptris_ext/engine/src/teptris/plan/plan.c +472 -0
  31. data/ext/teptris_ext/engine/src/teptris/version.c +6 -0
  32. data/ext/teptris_ext/extconf.rb +61 -0
  33. data/ext/teptris_ext/materialize.c +608 -0
  34. data/lib/teptris/version.rb +1 -1
  35. metadata +35 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afb8e42fa0385bd45f96b312b7f1ebcba3335fe99a51ac9f0db8b920b29bced8
4
- data.tar.gz: b48758047d5ee7f6c3e142f8b821ee0acdde70653a32212fd40ccc6ea79a0857
3
+ metadata.gz: ab9f038bc4784b948475584f5b56d6c815d1f37e1b122708a48395872d9e3635
4
+ data.tar.gz: aa29ac1fa9c7b2715d23ef44db846024a3e123aa4384a2dfed185d29f57cde32
5
5
  SHA512:
6
- metadata.gz: bc37dfcf7eefc085ab46aec1c1c4052a89bb0ce54453dcf301451f8ae74311d534e6f59f95efffb63f3554c00ba62994b806b324224a43d052c46315a5b83320
7
- data.tar.gz: 8170acc497f6cab20278ba09a71eab2ec0bc9e4cd253f2aa6b93604cc2ea020c12a9e41c99914d3a59f767a542e17f830da035858f1d162aa7ba59dfb751c65c
6
+ metadata.gz: 82cf78d9770fcd0e41aec5a1a1e0eca3178942e535376dc0fae4594e95156e820024f3316f01766199dbc575f41bf547106fc5145a8778e023ab07cb120c2583
7
+ data.tar.gz: fc1518bb6b12ad9ca32903db8ca5352d447f2dc4dee55fd600a4f2e23d6f389b7284e5128e1880b590dcbd0e952b35d09b50660eaed10cd48d74e032f78a3009
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 teptris contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,123 @@
1
+ #ifndef TEPTRIS_PLAN_H
2
+ #define TEPTRIS_PLAN_H
3
+
4
+ #include <stdint.h>
5
+
6
+ #include "teptris/teptris.h"
7
+
8
+ #ifdef __cplusplus
9
+ extern "C" {
10
+ #endif
11
+
12
+ #define TEPTRIS_PLAN_ABI_VERSION 1
13
+
14
+ typedef struct teptris_plan teptris_plan;
15
+ typedef struct teptris_plan_result teptris_plan_result;
16
+
17
+ typedef enum {
18
+ TEPTRIS_PLAN_SCALAR = 1,
19
+ TEPTRIS_PLAN_COLLECTION = 2,
20
+ TEPTRIS_PLAN_NESTED = 3,
21
+ TEPTRIS_PLAN_RAW = 4,
22
+ } teptris_plan_row_kind;
23
+
24
+ /* Result node kinds (walk output). */
25
+ enum {
26
+ TEPTRIS_PLAN_MISSING = 0,
27
+ TEPTRIS_PLAN_SCALAR_RESULT = 1,
28
+ TEPTRIS_PLAN_ARRAY = 2,
29
+ TEPTRIS_PLAN_TABLE = 3,
30
+ TEPTRIS_PLAN_RAW_RESULT = 4,
31
+ };
32
+
33
+ typedef struct teptris_plan_row {
34
+ const char *name; /* table key */
35
+ uint8_t kind; /* teptris_plan_row_kind */
36
+ uint32_t sub; /* sub-plan index (NESTED only) */
37
+ } teptris_plan_row;
38
+
39
+ /* Flattened plan tree: plan p owns rows [first_row[p], first_row[p+1]).
40
+ * The builder deep-copies; caller memory is transient. */
41
+ typedef struct teptris_plan_spec {
42
+ uint32_t abi_version;
43
+ uint32_t plan_count;
44
+ const teptris_plan_row *plans;
45
+ const uint32_t *plan_first_row; /* plan_count + 1 entries */
46
+ } teptris_plan_spec;
47
+
48
+ TEPTRIS_API teptris_plan *teptris_plan_build(const teptris_plan_spec *spec,
49
+ teptris_status *status);
50
+ TEPTRIS_API void teptris_plan_free(teptris_plan *plan);
51
+
52
+ /* Walk a TABLE node against the plan's root. Results are addressed by
53
+ * ROW INDEX (the plan's row order); keys absent from the document (or
54
+ * type-mismatched rows) read as MISSING. */
55
+ TEPTRIS_API teptris_plan_result *teptris_plan_walk(const teptris_plan *plan,
56
+ const teptris_node *node,
57
+ teptris_status *status);
58
+ TEPTRIS_API void teptris_plan_result_free(teptris_plan_result *result);
59
+
60
+ TEPTRIS_API uint8_t teptris_plan_result_kind_at(const teptris_plan_result *r,
61
+ uint32_t row);
62
+ TEPTRIS_API uint8_t teptris_plan_result_value_kind_at(
63
+ const teptris_plan_result *r, uint32_t row);
64
+ TEPTRIS_API teptris_status teptris_plan_result_string_at(
65
+ const teptris_plan_result *r, uint32_t row, teptris_view *out);
66
+ TEPTRIS_API teptris_status teptris_plan_result_integer_at(
67
+ const teptris_plan_result *r, uint32_t row, int64_t *out);
68
+ TEPTRIS_API teptris_status teptris_plan_result_float_at(
69
+ const teptris_plan_result *r, uint32_t row, double *out);
70
+ TEPTRIS_API teptris_status teptris_plan_result_boolean_at(
71
+ const teptris_plan_result *r, uint32_t row, bool *out);
72
+ TEPTRIS_API teptris_status teptris_plan_result_datetime_at(
73
+ const teptris_plan_result *r, uint32_t row, teptris_datetime *out);
74
+ TEPTRIS_API uint32_t teptris_plan_result_array_len_at(
75
+ const teptris_plan_result *r, uint32_t row);
76
+ TEPTRIS_API uint8_t teptris_plan_result_array_value_kind_at(
77
+ const teptris_plan_result *r, uint32_t row, uint32_t i);
78
+ TEPTRIS_API uint8_t teptris_plan_result_array_kind_at(
79
+ const teptris_plan_result *r, uint32_t row, uint32_t i);
80
+ TEPTRIS_API teptris_status teptris_plan_result_array_string_at(
81
+ const teptris_plan_result *r, uint32_t row, uint32_t i, teptris_view *out);
82
+ TEPTRIS_API teptris_status teptris_plan_result_array_integer_at(
83
+ const teptris_plan_result *r, uint32_t row, uint32_t i, int64_t *out);
84
+ /* RAW rows: the untouched document subtree (read with the normal
85
+ * teptris_node_* API). */
86
+ /* Borrowed sub-result over a TABLE-kind row (NESTED): its plan rows
87
+ * stay addressable with the same accessors. */
88
+ TEPTRIS_API teptris_plan_result *teptris_plan_result_row_view(
89
+ const teptris_plan_result *r, uint32_t row);
90
+ TEPTRIS_API teptris_status teptris_plan_result_array_float_at(
91
+ const teptris_plan_result *r, uint32_t row, uint32_t i, double *out);
92
+ TEPTRIS_API teptris_status teptris_plan_result_array_boolean_at(
93
+ const teptris_plan_result *r, uint32_t row, uint32_t i, bool *out);
94
+ TEPTRIS_API teptris_status teptris_plan_result_array_datetime_at(
95
+ const teptris_plan_result *r, uint32_t row, uint32_t i,
96
+ teptris_datetime *out);
97
+ /* Plan row metadata (assembly drivers): kind/sub/name by plan+row. */
98
+ TEPTRIS_API uint8_t teptris_plan_row_kind_at(const teptris_plan *p,
99
+ uint32_t plan_idx, uint32_t row);
100
+ TEPTRIS_API uint32_t teptris_plan_row_sub_at(const teptris_plan *p,
101
+ uint32_t plan_idx, uint32_t row);
102
+ TEPTRIS_API const char *teptris_plan_row_name_at(const teptris_plan *p,
103
+ uint32_t plan_idx, uint32_t row);
104
+ /* Borrowed sub-result over an ARRAY element (e.g. a table from an
105
+ * array-of-tables): its plan rows are addressable with the same
106
+ * accessors. Shares the parent result's lifetime; release the wrapper
107
+ * with teptris_plan_result_view_free (the tree itself is not freed). */
108
+ TEPTRIS_API teptris_plan_result *teptris_plan_result_array_entry_at(
109
+ const teptris_plan_result *r, uint32_t row, uint32_t i);
110
+ TEPTRIS_API void teptris_plan_result_view_free(teptris_plan_result *view);
111
+
112
+ TEPTRIS_API const teptris_node *teptris_plan_result_raw_at(
113
+ const teptris_plan_result *r, uint32_t row);
114
+
115
+ TEPTRIS_API uint32_t teptris_plan_row_count(const teptris_plan *plan,
116
+ uint32_t plan_idx);
117
+ TEPTRIS_API uint32_t teptris_plan_abi_version(void);
118
+
119
+ #ifdef __cplusplus
120
+ }
121
+ #endif
122
+
123
+ #endif /* TEPTRIS_PLAN_H */
@@ -0,0 +1,208 @@
1
+ #ifndef TEPTRIS_TEPTRIS_H
2
+ #define TEPTRIS_TEPTRIS_H
3
+
4
+ #include <stdbool.h>
5
+ #include <stddef.h>
6
+ #include <stdint.h>
7
+
8
+ #include "teptris/version.h"
9
+
10
+ /* Export annotation: the shared library builds with TEPTRIS_BUILDING_DLL
11
+ * (dllexport); consumers may define TEPTRIS_USE_DLL for dllimport, and
12
+ * static builds link plainly. Non-Windows platforms export by default. */
13
+ #if defined(_WIN32)
14
+ # if defined(TEPTRIS_BUILDING_DLL)
15
+ # define TEPTRIS_API __declspec(dllexport)
16
+ # elif defined(TEPTRIS_USE_DLL)
17
+ # define TEPTRIS_API __declspec(dllimport)
18
+ # else
19
+ # define TEPTRIS_API
20
+ # endif
21
+ #else
22
+ # define TEPTRIS_API __attribute__((visibility("default")))
23
+ #endif
24
+
25
+ #ifdef __cplusplus
26
+ extern "C" {
27
+ #endif
28
+
29
+ /* Opaque handles. Every node handed out by the read API is owned by its
30
+ * document and valid until teptris_document_free. */
31
+ typedef struct teptris_document teptris_document;
32
+ typedef struct teptris_node teptris_node;
33
+
34
+ typedef enum teptris_status {
35
+ TEPTRIS_OK = 0,
36
+ TEPTRIS_ERR_ALLOC,
37
+ TEPTRIS_ERR_SYNTAX,
38
+ TEPTRIS_ERR_SEMANTIC,
39
+ TEPTRIS_ERR_ENCODING,
40
+ TEPTRIS_ERR_DEPTH,
41
+ TEPTRIS_ERR_ARG,
42
+ TEPTRIS_ERR_STATE
43
+ } teptris_status;
44
+
45
+ typedef enum teptris_kind {
46
+ TEPTRIS_STRING = 0,
47
+ TEPTRIS_INTEGER,
48
+ TEPTRIS_FLOAT,
49
+ TEPTRIS_BOOLEAN,
50
+ TEPTRIS_DATETIME_OFFSET,
51
+ TEPTRIS_DATETIME_LOCAL,
52
+ TEPTRIS_DATE_LOCAL,
53
+ TEPTRIS_TIME_LOCAL,
54
+ TEPTRIS_ARRAY,
55
+ TEPTRIS_TABLE
56
+ } teptris_kind;
57
+
58
+ /* Views are (ptr, len); string values are additionally NUL-terminated.
59
+ * Table keys are views into the parse input and may not be. */
60
+ typedef struct teptris_view {
61
+ const char *ptr;
62
+ size_t len;
63
+ } teptris_view;
64
+
65
+ typedef struct teptris_datetime {
66
+ int32_t year; /* valid for DATE/DATETIME kinds */
67
+ uint8_t month, day; /* 1-based */
68
+ uint8_t hour, minute, second; /* second may be 60 (leap second) */
69
+ uint32_t nanosecond;
70
+ int32_t offset_seconds; /* valid for DATETIME_OFFSET only */
71
+ } teptris_datetime;
72
+
73
+ typedef struct teptris_error {
74
+ teptris_status status;
75
+ size_t line; /* 1-based */
76
+ size_t column; /* 1-based */
77
+ const char *message; /* NUL-terminated, document-owned */
78
+ } teptris_error;
79
+
80
+ typedef struct teptris_options {
81
+ uint32_t max_depth; /* 0 = default (512) */
82
+ uint32_t _reserved[3];
83
+ } teptris_options;
84
+
85
+ /* Parse a TOML 1.0 document. On failure the status is returned AND *out
86
+ * is set (non-NULL) so the error can be read; free it either way.
87
+ * Table-key views point into `data`: the caller must keep the input
88
+ * buffer alive for the lifetime of the document.
89
+ * Memory: *out must be freed with teptris_document_free. */
90
+ TEPTRIS_API teptris_status teptris_parse(const char *data, size_t len,
91
+ const teptris_options *opts,
92
+ teptris_document **out);
93
+
94
+ /* Memory: frees every allocation reachable from the document. */
95
+ TEPTRIS_API void teptris_document_free(teptris_document *doc);
96
+
97
+ TEPTRIS_API const teptris_error * teptris_document_error(const teptris_document *doc);
98
+ TEPTRIS_API const teptris_node * teptris_document_root(const teptris_document *doc);
99
+
100
+ TEPTRIS_API teptris_kind teptris_node_kind(const teptris_node *node);
101
+
102
+ /* Type-checked scalar accessors: return TEPTRIS_ERR_ARG on kind mismatch
103
+ * (or TEPTRIS_ERR_STATE with a NULL node). */
104
+ TEPTRIS_API teptris_status teptris_node_string(const teptris_node *node, teptris_view *out);
105
+ TEPTRIS_API teptris_status teptris_node_integer(const teptris_node *node, int64_t *out);
106
+ TEPTRIS_API teptris_status teptris_node_float(const teptris_node *node, double *out);
107
+ TEPTRIS_API teptris_status teptris_node_boolean(const teptris_node *node, bool *out);
108
+ TEPTRIS_API teptris_status teptris_node_datetime(const teptris_node *node,
109
+ teptris_datetime *out);
110
+
111
+ TEPTRIS_API size_t teptris_node_array_length(const teptris_node *node);
112
+ TEPTRIS_API const teptris_node * teptris_node_array_at(const teptris_node *node, size_t index);
113
+
114
+ /* Iteration is in insertion order. */
115
+ TEPTRIS_API size_t teptris_node_table_length(const teptris_node *node);
116
+ TEPTRIS_API const teptris_node * teptris_node_table_at(const teptris_node *node, size_t index,
117
+ teptris_view *key_out);
118
+ TEPTRIS_API const teptris_node * teptris_node_table_get(const teptris_node *node,
119
+ const char *key, size_t key_len);
120
+
121
+ /* Emit canonical TOML (deterministic; parse(emit(d)) == d).
122
+ * Memory: *buf is malloc'd; caller frees with free(). */
123
+ TEPTRIS_API teptris_status teptris_document_emit(const teptris_document *doc,
124
+ char **buf, size_t *len);
125
+
126
+ /* Emit the toml-test wire shape: scalars as {"type":..,"value":..},
127
+ * tables as objects, arrays as lists, insertion order.
128
+ * Memory: *buf is malloc'd; caller frees with free(). */
129
+ TEPTRIS_API teptris_status teptris_document_emit_json(const teptris_document *doc,
130
+ char **buf, size_t *len);
131
+
132
+ /* Bulk drain for FFI/ctypes bindings: the whole tree in ONE crossing as
133
+ * a self-describing flat buffer (explicit little-endian):
134
+ * table 0x01 u32 n *(u32 klen key node)
135
+ * array 0x02 u32 n *(node)
136
+ * string 0x03 u32 len bytes
137
+ * int 0x04 i64
138
+ * float 0x05 f64
139
+ * bool 0x06 / 0x07
140
+ * dt 0x08..0x0B (offset/local-dt/date/time) i64 y u8 mo d h mi s u32 ns i64 off (25 B)
141
+ * Memory: *buf is malloc'd; free with teptris_flatten_free. */
142
+ TEPTRIS_API teptris_status teptris_document_flatten(const teptris_document *doc,
143
+ uint8_t **buf, size_t *len);
144
+ TEPTRIS_API void teptris_flatten_free(void *buf);
145
+
146
+ TEPTRIS_API const char * teptris_status_string(teptris_status status);
147
+ TEPTRIS_API const char * teptris_version_string(void);
148
+
149
+ /* ------------------------------------------------------------- builder --
150
+ * Construct a document from materialized values (the dump side of
151
+ * parse): every emission flows through teptris_document_emit, so the
152
+ * emitter stays the single source of formatting truth.
153
+ *
154
+ * Stack discipline: open_* pushes a container, teptris_builder_close
155
+ * pops it; scalars attach to the current container. A NULL key means
156
+ * "element of the current array"; a keyed call requires a table
157
+ * current. Array nature is derived: the first table element makes the
158
+ * array an array-of-tables ([[..]] sections); scalars make it inline;
159
+ * mixing them is TEPTRIS_ERR_ARG. Tables reachable only as array
160
+ * elements or from inline tables render inline ({..}); tables under a
161
+ * section render as [..] sections.
162
+ *
163
+ * Keys and strings are copied into the document (no parse input is
164
+ * kept alive). Duplicate keys are TEPTRIS_ERR_ARG.
165
+ * Memory: the builder owns its document until teptris_builder_finish
166
+ * transfers it; otherwise teptris_builder_free destroys it. */
167
+ typedef struct teptris_builder teptris_builder;
168
+
169
+ TEPTRIS_API teptris_builder *teptris_builder_new(void);
170
+ TEPTRIS_API void teptris_builder_free(teptris_builder *b);
171
+
172
+ TEPTRIS_API teptris_status teptris_builder_put_string(teptris_builder *b,
173
+ const char *key, size_t key_len,
174
+ const char *val, size_t val_len);
175
+ TEPTRIS_API teptris_status teptris_builder_put_integer(teptris_builder *b,
176
+ const char *key, size_t key_len,
177
+ int64_t v);
178
+ TEPTRIS_API teptris_status teptris_builder_put_float(teptris_builder *b,
179
+ const char *key, size_t key_len,
180
+ double v);
181
+ TEPTRIS_API teptris_status teptris_builder_put_boolean(teptris_builder *b,
182
+ const char *key, size_t key_len,
183
+ bool v);
184
+ /* kind is one of TEPTRIS_DATETIME_OFFSET, TEPTRIS_DATETIME_LOCAL,
185
+ * TEPTRIS_DATE_LOCAL, TEPTRIS_TIME_LOCAL; fields must be zero where
186
+ * the kind does not use them (offset only for OFFSET). */
187
+ TEPTRIS_API teptris_status teptris_builder_put_datetime(teptris_builder *b,
188
+ const char *key, size_t key_len,
189
+ teptris_kind kind,
190
+ const teptris_datetime *dt);
191
+
192
+ TEPTRIS_API teptris_status teptris_builder_open_table(teptris_builder *b,
193
+ const char *key, size_t key_len);
194
+ TEPTRIS_API teptris_status teptris_builder_open_array(teptris_builder *b,
195
+ const char *key, size_t key_len);
196
+ /* like open_array but pinned inline ([..]) — for callers whose
197
+ * lookahead knows the array is not a homogeneous table array */
198
+ TEPTRIS_API teptris_status teptris_builder_open_inline_array(teptris_builder *b,
199
+ const char *key, size_t key_len);
200
+ TEPTRIS_API teptris_status teptris_builder_close(teptris_builder *b);
201
+ TEPTRIS_API teptris_status teptris_builder_finish(teptris_builder *b,
202
+ teptris_document **out);
203
+
204
+ #ifdef __cplusplus
205
+ }
206
+ #endif
207
+
208
+ #endif /* TEPTRIS_TEPTRIS_H */
@@ -0,0 +1,9 @@
1
+ #ifndef TEPTRIS_VERSION_H
2
+ #define TEPTRIS_VERSION_H
3
+
4
+ #define TEPTRIS_VERSION_MAJOR 0
5
+ #define TEPTRIS_VERSION_MINOR 1
6
+ #define TEPTRIS_VERSION_PATCH 24
7
+ #define TEPTRIS_VERSION_STRING "0.1.24"
8
+
9
+ #endif /* TEPTRIS_VERSION_H */