asoma.dev · the C reference for libose
libose
the C library every o.se host is built on
Loading...
Searching...
No Matches
ose.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019-23 John MacCallum Permission is hereby granted,
3 free of charge, to any person obtaining a copy of this software
4 and associated documentation files (the "Software"), to deal in
5 the Software without restriction, including without limitation the
6 rights to use, copy, modify, merge, publish, distribute,
7 sublicense, and/or sell copies of the Software, and to permit
8 persons to whom the Software is furnished to do so, subject to the
9 following conditions:
10
11 The above copyright notice and this permission notice shall be
12 included in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 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
21 DEALINGS IN THE SOFTWARE.
22*/
23
58#ifndef OSE_H
59#define OSE_H
60
61#ifdef __cplusplus
62extern "C" {
63#endif
64
65#include <limits.h>
66#if !defined(SWIG) && CHAR_BIT != 8
67#error "Unsupported hardware (CHAR_BIT != 8)"
68#endif
69
70#include <inttypes.h>
71
72/* avr-libc has no 64-bit printf formats and none of strtof(), strtoll() or
73 strtoull(). Its printf prints a 64-bit integer as "?" whatever the
74 format, so the formats only have to compile; strtod() is float there, and
75 the integers are read at 32 bits, which is what the part has. */
76#if defined(__AVR__)
77#include <stdlib.h>
78#ifndef PRId64
79#define PRId64 "ld"
80#endif
81#ifndef PRIu64
82#define PRIu64 "lu"
83#endif
84#define strtof(s, e) ((float)strtod((s), (e)))
85#define strtoll(s, e, b) ((long long)strtol((s), (e), (b)))
86#define strtoull(s, e, b) ((unsigned long long)strtoul((s), (e), (b)))
87#endif
88
89/* Would be nice to use this, but the compiler for the */
90/* ESP8266 doesn't support it :( */
91/* #if __has_include("sys/ose_endian.h") */
92/* #include "sys/ose_endian.h" */
93/* #endif */
94#ifdef HAVE_OSE_ENDIAN_H
95#include "sys/ose_endian.h"
96#endif
97
98#ifdef OSE_IN_DOXYGEN
103#define OSE_CONF_DEBUG
104
112#define OSE_CONF_MEMPROFILE
/* conf_debug */
114#endif
115
116#ifdef OSE_IN_DOXYGEN
129#define OSE_CONF_WRAP_BUNDLE_PTR
/* conf_debug */
131#endif
132
133#ifdef OSE_CONF_WRAP_BUNDLE_PTR
134#define OSE_WRAP_BUNDLE_PTR
135#endif
136
137#ifdef OSE_CONF_MEMPROFILE
138#define OSE_MEMPROFILE
139#endif
140
154#ifdef OSE_CONF_HOT
155#define OSE_HOT OSE_CONF_HOT
156#else
157#define OSE_HOT
158#endif
159
170#ifdef ESP_PLATFORM
171#include <stddef.h>
172void *ose_memmove(void *dst, const void *src, size_t n);
173#else
174#define ose_memmove memmove
175#endif
176
192#ifdef OSE_CONF_VALIDATE_VM_STEP
193#define OSE_VALIDATE_VM_STEP
194#endif
195
197#ifdef OSE_CONF_DEBUG
198#ifdef NDEBUG
199#undef NDEBUG
200#endif
201#ifndef OSE_DEBUG
202#define OSE_DEBUG
203#endif
204#ifndef OSE_WRAP_BUNDLE_PTR
205#define OSE_WRAP_BUNDLE_PTR
206#endif
207#ifndef OSE_MEMPROFILE
208#define OSE_MEMPROFILE
209#endif
210#else
211#ifndef NDEBUG
212#define NDEBUG
213#endif
214#endif
/* DOXYGEN_SKIP */
216
222#if defined (__unix__) \
223 || ( defined (__APPLE__) \
224 && defined (__MACH__) ) \
225 || defined (__EMSCRIPTEN__)
226#include <arpa/inet.h>
227#elif defined (_WIN32) || defined (_WIN64)
228#include <Windows.h>
229#include <Winsock.h>
230#else
231
232#ifndef htonl
233#define OSE_NEED_HTONL
234int32_t htonl(int32_t x);
235#define OSE_BYTE_SWAP32(x) \
236 ((((x) & 0xff000000) >> 24) | \
237 (((x) & 0x00ff0000) >> 8) | \
238 (((x) & 0x0000ff00) << 8) | \
239 (((x) & 0x000000ff) << 24))
240#endif
241
242#ifndef ntohl
243#define OSE_NEED_NTOHL
244int32_t ntohl(int32_t x);
245#define OSE_BYTE_SWAP64(x) \
246 ((((x) & 0xff00000000000000LL) >> 56) | \
247 (((x) & 0x00ff000000000000LL) >> 40) | \
248 (((x) & 0x0000ff0000000000LL) >> 24) | \
249 (((x) & 0x000000ff00000000LL) >> 8) | \
250 (((x) & 0x00000000ff000000LL) << 8) | \
251 (((x) & 0x0000000000ff0000LL) << 24) | \
252 (((x) & 0x000000000000ff00LL) << 40) | \
253 (((x) & 0x00000000000000ffLL) << 56))
254#endif
255#endif
256
257
258#define ose_htonl(x) htonl(x)
259#define ose_ntohl(x) ntohl(x)
260#ifndef htonll
261#define ose_htonll(x) \
262 ((1==ose_htonl(1)) \
263 ? (x) \
264 : ((uint64_t)ose_htonl((x) \
265 & 0xFFFFFFFF) << 32) \
266 | ose_htonl((x) >> 32))
267#else
268#define ose_htonll(x) htonll(x)
269#endif
270
271#ifndef ntohll
272#define ose_ntohll(x) \
273 ((1==ose_ntohl(1)) \
274 ? (x) \
275 : ((uint64_t)ose_ntohl((x) \
276 & 0xFFFFFFFF) << 32) \
277 | ose_ntohl((x) >> 32))
278#else
279#define ose_ntohll(x) ntohll(x)
280#endif
281
282#define OSE_INT32_TO_BUF_SWAP(buf, i) \
283 { \
284 (buf)[0] = ((i) & 0xFF000000) >> 24; \
285 (buf)[1] = ((i) & 0x00FF0000) >> 16; \
286 (buf)[2] = ((i) & 0x0000FF00) >> 8; \
287 (buf)[3] = ((i) & 0x000000FF); \
288 }
289#define OSE_INT32_TO_BUF(buf, i) memcpy((buf), &(i), 4);
290
291#define OSE_INT64_TO_BUF_SWAP(buf, i) \
292 { \
293 (buf)[0] = ((i) & 0xFF00000000000000) >> 56; \
294 (buf)[1] = ((i) & 0x00FF000000000000) >> 48; \
295 (buf)[2] = ((i) & 0x0000FF0000000000) >> 40; \
296 (buf)[3] = ((i) & 0x000000FF00000000) >> 32; \
297 (buf)[4] = ((i) & 0x00000000FF000000) >> 24; \
298 (buf)[5] = ((i) & 0x0000000000FF0000) >> 16; \
299 (buf)[6] = ((i) & 0x000000000000FF00) >> 8; \
300 (buf)[7] = ((i) & 0x00000000000000FF); \
301 }
302#define OSE_INT64_TO_BUF(buf, i) memcpy((buf), &(i), 8);
303
304#define OSE_BUF_TO_INT32_SWAP(buf, i) \
305 { \
306 i = (((uint64_t)b[0]) & 0xFF) << 24 \
307 | (((uint64_t)b[1]) & 0xFF) << 16 \
308 | (((uint64_t)b[2]) & 0xFF) << 8 \
309 | (((uint64_t)b[3]) & 0xFF); \
310 }
311#define OSE_BUF_TO_INT32(buf, i) memcpy(&(i), (buf), 4);
312
313#define OSE_BUF_TO_INT64_SWAP(buf, i) \
314 { \
315 i = (((uint64_t)b[0]) & 0xFF) << 56 \
316 | (((uint64_t)b[1]) & 0xFF) << 48 \
317 | (((uint64_t)b[2]) & 0xFF) << 40 \
318 | (((uint64_t)b[3]) & 0xFF) << 32 \
319 | (((uint64_t)b[4]) & 0xFF) << 24 \
320 | (((uint64_t)b[5]) & 0xFF) << 16 \
321 | (((uint64_t)b[6]) & 0xFF) << 8 \
322 | (((uint64_t)b[7]) & 0xFF); \
323 }
324#define OSE_BUF_TO_INT64(buf, i) memcpy(&(i), (buf), 8);
325
326#if defined(OSE_ENDIAN)
327#if OSE_ENDIAN == OSE_LITTLE_ENDIAN
328#define OSE_BYTE_SWAP32_INT_TO_BUF(buf, i)\
329 OSE_INT32_TO_BUF_SWAP(buf, i)
330#define OSE_BYTE_SWAP64_INT_TO_BUF(buf, i)\
331 OSE_INT64_TO_BUF_SWAP(buf, i)
332
333#define OSE_BYTE_SWAP32_BUF_TO_INT(buf, i)\
334 OSE_BUF_TO_INT32_SWAP(buf, i)
335#define OSE_BYTE_SWAP64_BUF_TO_INT(buf, i)\
336 OSE_BUF_TO_INT64_SWAP(buf, i)
337
338#else /* OSE_BIG_ENDIAN */
339
340#define OSE_BYTE_SWAP32_INT_TO_BUF(buf, i)\
341 OSE_INT32_TO_BUF(buf, i)
342#define OSE_BYTE_SWAP64_INT_TO_BUF(buf, i)\
343 OSE_INT64_TO_BUF(buf, i)
344
345#define OSE_BYTE_SWAP32_BUF_TO_INT(buf, i)\
346 OSE_BUF_TO_INT32(buf, i)
347#define OSE_BYTE_SWAP64_BUF_TO_INT(buf, i)\
348 OSE_BUF_TO_INT64(buf, i)
349
350#endif
351
352#else /* defined(OSE_ENDIAN) */
353
354#define OSE_BYTE_SWAP32_INT_TO_BUF(buf, i) \
355 if(ose_ntohl(1) == 1) \
356 { \
357 OSE_INT32_TO_BUF(buf, i); \
358 } \
359 else \
360 { \
361 OSE_INT32_TO_BUF_SWAP(buf, i); \
362 }
363#define OSE_BYTE_SWAP64_INT_TO_BUF(buf, i) \
364 if(ose_ntohl(1) == 1) \
365 { \
366 OSE_INT64_TO_BUF(buf, i); \
367 } \
368 else \
369 { \
370 OSE_INT64_TO_BUF_SWAP(buf, i); \
371 }
372
373#define OSE_BYTE_SWAP32_BUF_TO_INT(buf, i) \
374 if(ose_ntohl(1) == 1) \
375 { \
376 OSE_BUF_TO_INT32(buf, i); \
377 } \
378 else \
379 { \
380 OSE_BUF_TO_INT32_SWAP(buf, i); \
381 }
382#define OSE_BYTE_SWAP64_BUF_TO_INT(buf, i) \
383 if(ose_ntohl(1) == 1) \
384 { \
385 OSE_BUF_TO_INT64(buf, i); \
386 } \
387 else \
388 { \
389 OSE_BUF_TO_INT64_SWAP(buf, i); \
390 }
391
392#endif
/* DOXYGEN_SKIP */
394
398#ifdef OSE_WRAP_BUNDLE_PTR
399typedef struct ose_bundle
400{
401 char *b;
402} ose_bundle;
403#define ose_constbundle ose_bundle
404ose_bundle ose_makeBundle(const char * const p);
405#define ose_makeConstBundle ose_makeBundle
406#define ose_getBundlePtr(bundle) (bundle).b
407#else
411typedef char* ose_bundle;
415#define ose_makeBundle(charptr) charptr
420#define ose_makeConstBundle(charptr) charptr
424#define ose_getBundlePtr(bundle) (bundle)
428#define ose_constbundle const char *
429#endif
430
435typedef void (*ose_fn)(ose_bundle);
436
440#define OSE_INTPTR2 (sizeof(intptr_t) * 2)
441
446{
447 uint32_t sec;
448 uint32_t fsec;
449};
450
451/* C23 made bool, true and false keywords, and the compilers for the Teensy
452 (gcc 15) and the RP2040 (gcc 16) build C as C23 by default. */
453#if !defined(__cplusplus) && !defined(SWIG) \
454 && !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
455#ifndef __bool_true_false_are_defined
456typedef enum
457{
458 false = 0,
459 true
460} bool;
461#endif
462#endif
463
/* Types */
465
470#define OSETT_ID_ ','
471static const char OSETT_ID = OSETT_ID_;
472#define OSETTSTR_ID_ ","
473static const char * const OSETTSTR_ID = OSETTSTR_ID_;
474
475#define OSETT_INT32_ 'i'
476static const char OSETT_INT32 = OSETT_INT32_;
477#define OSETTSTR_INT32_ "i"
478static const char * const OSETTSTR_INT32 = OSETTSTR_INT32_;
479
480#define OSETT_FLOAT_ 'f'
481static const char OSETT_FLOAT = OSETT_FLOAT_;
482#define OSETTSTR_FLOAT_ "f"
483static const char * const OSETTSTR_FLOAT = OSETTSTR_FLOAT_;
484
485#define OSETT_STRING_ 's'
486static const char OSETT_STRING = OSETT_STRING_;
487#define OSETTSTR_STRING_ "s"
488static const char * const OSETTSTR_STRING = OSETTSTR_STRING_;
489
490#define OSETT_BLOB_ 'b'
491static const char OSETT_BLOB = OSETT_BLOB_;
492#define OSETTSTR_BLOB_ "b"
493static const char * const OSETTSTR_BLOB = OSETTSTR_BLOB_;
/* OSC 1.0 Types */
495
496#ifdef OSE_IN_DOXYGEN
501#define OSE_CONF_PROVIDE_TYPE_SYMBOL
502#define OSE_CONF_PROVIDE_TYPE_DOUBLE
503#define OSE_CONF_PROVIDE_TYPE_INT8
504#define OSE_CONF_PROVIDE_TYPE_UINT8
505#define OSE_CONF_PROVIDE_TYPE_INT16
506#define OSE_CONF_PROVIDE_TYPE_UINT16
507#define OSE_CONF_PROVIDE_TYPE_UINT32
508#define OSE_CONF_PROVIDE_TYPE_INT64
509#define OSE_CONF_PROVIDE_TYPE_UINT64
510#define OSE_CONF_PROVIDE_TYPE_TIMETAG
511#define OSE_CONF_PROVIDE_TYPE_TRUE
512#define OSE_CONF_PROVIDE_TYPE_FALSE
513#define OSE_CONF_PROVIDE_TYPE_NIL
514#define OSE_CONF_PROVIDE_TYPE_INFINITUM
/* conf_types */
516#endif /* OSE_IN_DOXYGEN */
517
522#ifdef OSE_CONF_PROVIDE_TYPE_SYMBOL
523#define OSE_PROVIDE_TYPE_SYMBOL
524#define OSETT_SYMBOL_ 'S'
525static const char OSETT_SYMBOL = OSETT_SYMBOL_;
526#define OSETTSTR_SYMBOL_ "S"
527static const char * const OSETTSTR_SYMBOL = OSETTSTR_SYMBOL_;
528#endif
529#ifdef OSE_CONF_PROVIDE_TYPE_DOUBLE
530#define OSE_PROVIDE_TYPE_DOUBLE
531#define OSETT_DOUBLE_ 'd'
532static const char OSETT_DOUBLE = OSETT_DOUBLE_;
533#define OSETTSTR_DOUBLE_ "d"
534static const char * const OSETTSTR_DOUBLE = OSETTSTR_DOUBLE_;
535#endif
536#ifdef OSE_CONF_PROVIDE_TYPE_INT8
537#define OSE_PROVIDE_TYPE_INT8
538#define OSETT_INT8_ 'c'
539static const char OSETT_INT8 = OSETT_INT8_;
540#define OSETTSTR_INT8_ "c"
541static const char * const OSETTSTR_INT8 = OSETTSTR_INT8_;
542#endif
543#ifdef OSE_CONF_PROVIDE_TYPE_UINT8
544#define OSE_PROVIDE_TYPE_UINT8
545#define OSETT_UINT8_ 'C'
546static const char OSETT_UINT8 = OSETT_UINT8_;
547#define OSETTSTR_UINT8_ "C"
548static const char * const OSETTSTR_UINT8 = OSETTSTR_UINT8_;
549#endif
550#ifdef OSE_CONF_PROVIDE_TYPE_INT16
551#define OSE_PROVIDE_TYPE_INT16
552#define OSETT_INT16_ 'u'
553static const char OSETT_INT16 = OSETT_INT16_;
554#define OSETTSTR_INT16_ "u"
555static const char * const OSETTSTR_INT16 = OSETTSTR_INT16_;
556#endif
557#ifdef OSE_CONF_PROVIDE_TYPE_UINT16
558#define OSE_PROVIDE_TYPE_UINT16
559#define OSETT_UINT16_ 'U'
560static const char OSETT_UINT16 = OSETT_UINT16_;
561#define OSETTSTR_UINT16_ "U"
562static const char * const OSETTSTR_UINT16 = OSETTSTR_UINT16_;
563#endif
564#ifdef OSE_CONF_PROVIDE_TYPE_UINT32
565#define OSE_PROVIDE_TYPE_UINT32
566#define OSETT_UINT32_ 'k'
567static const char OSETT_UINT32 = OSETT_UINT32_;
568#define OSETTSTR_UINT32_ "k"
569static const char * const OSETTSTR_UINT32 = OSETTSTR_UINT32_;
570#endif
571#ifdef OSE_CONF_PROVIDE_TYPE_INT64
572#define OSE_PROVIDE_TYPE_INT64
573#define OSETT_INT64_ 'h'
574static const char OSETT_INT64 = OSETT_INT64_;
575#define OSETTSTR_INT64_ "h"
576static const char * const OSETTSTR_INT64 = OSETTSTR_INT64_;
577#endif
578#ifdef OSE_CONF_PROVIDE_TYPE_UINT64
579#define OSE_PROVIDE_TYPE_UINT64
580#define OSETT_UINT64_ 'H'
581static const char OSETT_UINT64 = OSETT_UINT64_;
582#define OSETTSTR_UINT64_ "H"
583static const char * const OSETTSTR_UINT64 = OSETTSTR_UINT64_;
584#endif
585#ifdef OSE_CONF_PROVIDE_TYPE_TIMETAG
586#define OSE_PROVIDE_TYPE_TIMETAG
587#define OSETT_TIMETAG_ 't'
588static const char OSETT_TIMETAG = OSETT_TIMETAG_;
589#define OSETTSTR_TIMETAG_ "t"
590static const char * const OSETTSTR_TIMETAG = OSETTSTR_TIMETAG_;
591#endif
592#ifdef OSE_CONF_PROVIDE_TYPE_TRUE
593#define OSE_PROVIDE_TYPE_TRUE
594#define OSETT_TRUE_ 'T'
595static const char OSETT_TRUE = OSETT_TRUE_;
596#define OSETTSTR_TRUE_ "T"
597static const char * const OSETTSTR_TRUE = OSETTSTR_TRUE_;
598static const char * const ose_str_true = "/,/T";
599static const int32_t ose_strlen_true = 4;
600static const int32_t ose_pstrlen_true = 8;
601#endif
602#ifdef OSE_CONF_PROVIDE_TYPE_FALSE
603#define OSE_PROVIDE_TYPE_FALSE
604#define OSETT_FALSE_ 'F'
605static const char OSETT_FALSE = OSETT_FALSE_;
606#define OSETTSTR_FALSE_ "F"
607static const char * const OSETTSTR_FALSE = OSETTSTR_FALSE_;
608static const char * const ose_str_false = "/,/F";
609static const int32_t ose_strlen_false = 4;
610static const int32_t ose_pstrlen_false = 8;
611#endif
612#ifdef OSE_CONF_PROVIDE_TYPE_NIL
613#define OSE_PROVIDE_TYPE_NIL
614#define OSETT_NIL_ 'N'
615static const char OSETT_NIL = OSETT_NIL_;
616#define OSETTSTR_NIL_ "N"
617static const char * const OSETTSTR_NIL = OSETTSTR_NIL_;
618static const char * const ose_str_nil = "/,/N";
619static const int32_t ose_strlen_nil = 4;
620static const int32_t ose_pstrlen_nil = 8;
621#endif
622#ifdef OSE_CONF_PROVIDE_TYPE_INFINITUM
623#define OSE_PROVIDE_TYPE_INFINITUM
624#define OSETT_INFINITUM_ 'I'
625static const char OSETT_INFINITUM = OSETT_INFINITUM_;
626#define OSETTSTR_INFINITUM_ "I"
627static const char * const OSETTSTR_INFINITUM = OSETTSTR_INFINITUM_;
628static const char * const ose_str_infinitum = "/,/I";
629static const int32_t ose_strlen_infinitum = 4;
630static const int32_t ose_pstrlen_infinitum = 8;
631#endif
/* Extended Types */
633
634/* non-osc data types
635 these are never written into a bundle
636 (unless they are defined above) */
637#ifndef OSE_PROVIDE_TYPE_TRUE
638#define OSETT_TRUE_ 'T'
639static const char OSETT_TRUE = OSETT_TRUE_;
640#define OSETTSTR_TRUE_ "T"
641static const char * const OSETTSTR_TRUE = OSETTSTR_TRUE_;
642#endif
643
644#ifndef OSE_PROVIDE_TYPE_TRUE
645#define OSETT_FALSE_ 'F'
646static const char OSETT_FALSE = OSETT_FALSE_;
647#define OSETTSTR_FALSE_ "F"
648static const char * const OSETTSTR_FALSE = OSETTSTR_FALSE_;
649#endif
650
682#define OSETT_ALIGNEDPTR_ 'p'
683static const char OSETT_ALIGNEDPTR = OSETT_ALIGNEDPTR_;
684#define OSETTSTR_ALIGNEDPTR_ "p"
685static const char * const OSETTSTR_ALIGNEDPTR = OSETTSTR_ALIGNEDPTR_;
686
707#define OSETT_WILDPTR_ 'P'
708static const char OSETT_WILDPTR = OSETT_WILDPTR_;
709#define OSETTSTR_WILDPTR_ "P"
710static const char * const OSETTSTR_WILDPTR = OSETTSTR_WILDPTR_;
/* Extension type */
712
749#define OSETT_OPCODE_ '!'
750static const char OSETT_OPCODE = OSETT_OPCODE_;
751#define OSETTSTR_OPCODE_ "!"
752static const char * const OSETTSTR_OPCODE = OSETTSTR_OPCODE_;
753
754#define OSETT_NOTYPETAG_ 0
755static const char OSETT_NOTYPETAG = OSETT_NOTYPETAG_;
756#define OSETTSTR_NOTYPETAG_ "0"
757static const char * const OSETTSTR_NOTYPETAG = OSETTSTR_NOTYPETAG_;
758
759#define OSETT_BUNDLE_ '|'
760static const char OSETT_BUNDLE = OSETT_BUNDLE_;
761#define OSETTSTR_BUNDLE_ "|"
762static const char * const OSETTSTR_BUNDLE = OSETTSTR_BUNDLE_;
763
764#define OSETT_MESSAGE_ '-'
765static const char OSETT_MESSAGE = OSETT_MESSAGE_;
766#define OSETTSTR_MESSAGE_ "-"
767static const char * const OSETTSTR_MESSAGE = OSETTSTR_MESSAGE_;
768
/* Internal types */
770
775#define OSE_BUNDLE_ID_ "#bundle\0"
776/* THE WIDTHS THE LAYOUT IS MADE OF, in one place.
777 *
778 * Every walk through a bundle reads a size word, steps past it, and pads
779 * to an alignment. Those three numbers were written as literals in about a
780 * thousand places; they are these three constants now, at the values OSC
781 * fixes, so that the layout is stated once and a build that wanted a
782 * narrower one (ose-design PROPOSAL-NARROW-OSC.md) would change it here.
783 * An int32 or a float is still four bytes wherever one is read or
784 * written: that is the item's width, not the layout's, and it stays
785 * literal. */
786#define OSE_SIZEWORD_LEN_ 4 /* an element's, a blob's or a pointer item's length word */
787#define OSE_ALIGN_ 4 /* addresses, typetags, strings and blobs pad to this */
788static const int32_t OSE_SIZEWORD_LEN = OSE_SIZEWORD_LEN_;
789static const int32_t OSE_ALIGN = OSE_ALIGN_;
790#define OSE_BUNDLE_ID_LEN_ 8
791#define OSE_TIMETAG_NULL_ "\0\0\0\0\0\0\0\0"
792#define OSE_TIMETAG_LEN_ 8
793static const char * const OSE_BUNDLE_ID = OSE_BUNDLE_ID_;
794static const int32_t OSE_BUNDLE_ID_LEN = OSE_BUNDLE_ID_LEN_;
795static const char * const OSE_TIMETAG_NULL = OSE_TIMETAG_NULL_;
796static const int32_t OSE_TIMETAG_LEN = OSE_TIMETAG_LEN_;
797static const char * const OSE_BUNDLE_HEADER =
798 OSE_BUNDLE_ID_ OSE_TIMETAG_NULL_;
799/* The macro is what sizes an array: in C a static const int32_t is not a
800 constant expression, and gcc refuses one at file scope where clang lets it
801 pass. */
802#define OSE_BUNDLE_HEADER_LEN_ (OSE_BUNDLE_ID_LEN_ + OSE_TIMETAG_LEN_)
803static const int32_t OSE_BUNDLE_HEADER_LEN = OSE_BUNDLE_HEADER_LEN_;
804
805#define OSE_EMPTY_TYPETAG_STRING_ ",\0\0\0"
806static const char * const OSE_EMPTY_TYPETAG_STRING =
807 OSE_EMPTY_TYPETAG_STRING_;
808static const int32_t OSE_EMPTY_TYPETAG_STRING_LEN = 1;
809static const int32_t OSE_EMPTY_TYPETAG_STRING_SIZE = 4;
810
811/* undocumented for now -- consider dropping support for changing this */
812#ifdef OSE_CONF_ADDRESS_ANONVAL
813#define OSE_USER_ADDRESS_ANONVAL
814#include <stdint.h>
815static const char * const OSE_ADDRESS_ANONVAL =
816 OSE_CONF_ADDRESS_ANONVAL;
817static const int32_t OSE_ADDRESS_ANONVAL_LEN =
818 OSE_CONF_ADDRESS_ANONVAL_LEN;
819#define OSE_ADDRESS_ANONVAL_SIZE_ (OSE_CONF_ADDRESS_ANONVAL_SIZE)
820static const int32_t OSE_ADDRESS_ANONVAL_SIZE =
821 OSE_ADDRESS_ANONVAL_SIZE_;
822static const char * const OSE_ADDRESS_ANONVAL_EMPTY_TYPETAG_STRING =
823 OSE_CONF_ADDRESS_ANONVAL OSE_EMPTY_TYPETAG_STRING_;
824
825#else /* OSE_CONF_ADDRESS_ANONVAL */
826
827#define OSE_ADDRESS_ANONVAL_ "\0\0\0\0"
828static const char * const OSE_ADDRESS_ANONVAL = OSE_ADDRESS_ANONVAL_;
829static const int32_t OSE_ADDRESS_ANONVAL_LEN = 0;
830#define OSE_ADDRESS_ANONVAL_SIZE_ 4
831static const int32_t OSE_ADDRESS_ANONVAL_SIZE = OSE_ADDRESS_ANONVAL_SIZE_;
832static const char * const OSE_ADDRESS_ANONVAL_EMPTY_TYPETAG_STRING =
833 OSE_ADDRESS_ANONVAL_ OSE_EMPTY_TYPETAG_STRING_;
834#endif /* OSE_CONF_ADDRESS_ANONVAL */
835
836static const int32_t OSE_ADDRESS_MIN_LEN = 0;
837static const int32_t OSE_ADDRESS_MIN_PLEN = 4;
/* Constants */
839
845typedef int32_t (*ose_getPayloadItemLengthFn)(ose_constbundle, char,
846 int32_t, int32_t);
847typedef int32_t (*ose_getPayloadItemSizeFn)(ose_constbundle, char,
848 int32_t, int32_t);
849typedef int32_t (*ose_pprintPayloadItemFn)(ose_bundle, char,
850 int32_t, int32_t);
851typedef int32_t (*ose_fromStringFn)(ose_bundle, char,
852 int32_t, int32_t);
853
854#define OSE_TYPE_ADDR_PREFIX "/"
855
856#define OSE_TYPE_ADDR_PPRINTPAYLOADITEM_SUFFIX "/PPPI"
857#define OSE_PPRINTPAYLOADITEM_ADDR_ \
858 OSE_TYPE_ADDR_PREFIX "%c" OSE_TYPE_ADDR_PPRINTPAYLOADITEM_SUFFIX
859static const char * const OSE_PPRINTPAYLOADITEM_ADDR =
860 OSE_PPRINTPAYLOADITEM_ADDR_;
861static const int32_t OSE_PPRINTPAYLOADITEM_ADDR_LEN =
862 sizeof(OSE_PPRINTPAYLOADITEM_ADDR_);
863#ifndef OSE_PPRINTPAYLOADITEM_HOOK
864#define OSE_PPRINTPAYLOADITEM_HOOK ose_pprintPayloadItem_hook
865#else
866extern int32_t OSE_PPRINTPAYLOADITEM_HOOK (ose_bundle bundle,
867 char typetag,
868 int32_t msg_offset,
869 int32_t item_offset);
870#endif
871
872#define OSE_TYPE_ADDR_GETPAYLOADITEMLENGTH_SUFFIX "/GPIL"
873#define OSE_GETPAYLOADITEMLENGTH_ADDR_ \
874 OSE_TYPE_ADDR_PREFIX "%c" OSE_TYPE_ADDR_GETPAYLOADITEMLENGTH_SUFFIX
875static const char * const OSE_GETPAYLOADITEMLENGTH_ADDR =
876 OSE_GETPAYLOADITEMLENGTH_ADDR_;
877static const int32_t OSE_GETPAYLOADITEMLENGTH_ADDR_LEN =
878 sizeof(OSE_GETPAYLOADITEMLENGTH_ADDR_);
879#ifndef OSE_GETPAYLOADITEMLENGTH_HOOK
880#define OSE_GETPAYLOADITEMLENGTH_HOOK ose_getPayloadItemLength_hook
881#else
882extern int32_t OSE_GETPAYLOADITEMLENGTH_HOOK (ose_constbundle bundle,
883 char typetag,
884 int32_t msg_offset,
885 int32_t item_offset);
886#endif
887
888#define OSE_TYPE_ADDR_GETPAYLOADITEMSIZE_SUFFIX "/GPIS"
889#define OSE_GETPAYLOADITEMSIZE_ADDR_ \
890 OSE_TYPE_ADDR_PREFIX "%c" OSE_TYPE_ADDR_GETPAYLOADITEMSIZE_SUFFIX
891static const char * const OSE_GETPAYLOADITEMSIZE_ADDR =
892 OSE_GETPAYLOADITEMSIZE_ADDR_;
893static const int32_t OSE_GETPAYLOADITEMSIZE_ADDR_LEN =
894 sizeof(OSE_GETPAYLOADITEMSIZE_ADDR_);
895#ifndef OSE_GETPAYLOADITEMSIZE_HOOK
896#define OSE_GETPAYLOADITEMSIZE_HOOK ose_getPayloadItemSize_hook
897#else
898extern int32_t OSE_GETPAYLOADITEMSIZE_HOOK (ose_constbundle bundle,
899 char typetag,
900 int32_t msg_offset,
901 int32_t item_offset);
902#endif
903
904#define OSE_TYPE_ADDR_FROMSTRING_SUFFIX "/FRST"
905#define OSE_FROMSTRING_ADDR_ \
906 OSE_TYPE_ADDR_PREFIX "%c" OSE_TYPE_ADDR_FROMSTRING_SUFFIX
907static const char * const OSE_FROMSTRING_ADDR =
908 OSE_FROMSTRING_ADDR_;
909static const int32_t OSE_FROMSTRING_ADDR_LEN =
910 sizeof(OSE_FROMSTRING_ADDR_);
911#ifndef OSE_FROMSTRING_HOOK
912#define OSE_FROMSTRING_HOOK ose_fromString_hook
913#else
914extern int32_t OSE_FROMSTRING_HOOK (ose_bundle bundle,
915 char typetag,
916 const char * const str);
917#endif
918
919#ifndef OSE_REGISTERTYPE_HOOK
920#define OSE_REGISTERTYPE_HOOK ose_registerType_hook
921#else
922extern void
923OSE_REGISTERTYPE_HOOK (ose_bundle bundle,
924 char typetag,
925 const char * const getPayloadItemLength_addr,
926 ose_getPayloadItemLengthFn getPayloadItemLength,
927 const char * const getPayloadItemSize_addr,
928 ose_getPayloadItemSizeFn getPayloadItemSize,
929 const char * const pprintPayloadItem_addr,
930 ose_pprintPayloadItemFn pprintPayloadItem,
931 const char * const evalType_addr,
932 void (*evalType)(ose_bundle),
933 const char * const fromString_addr,
934 void (*fromString)(ose_bundle));
935#endif
936
/* Type Extensibility Hooks */
938
943const char *ose_version_string(void);
944const char *ose_debug_string(void);
945const char *ose_date_compiled_string(void);
/* Version */
947
948/* The VM's hook functions, as this build named them (OSEVM_ASSIGN and the
949 rest, which a host may override), for a module compiled apart from the
950 host -- the stdlib -- to bind. Every field is a function's name fixed at
951 build time, so the table is const: defined once in ose_vm.c, never
952 written. */
954{
955 void (*ASSIGN)(ose_bundle);
956 void (*LOOKUP)(ose_bundle);
957 void (*FUNCALL)(ose_bundle);
958 void (*QUOTE)(ose_bundle);
959 void (*COPYREGISTERTOELEM)(ose_bundle);
960 void (*APPENDELEMTOREGISTER)(ose_bundle);
961 void (*REPLACEREGISTERWITHELEM)(ose_bundle);
962 void (*MOVEELEMTOREGISTER)(ose_bundle);
963 void (*TOTYPE)(ose_bundle);
964 void (*TOINT32)(ose_bundle);
965 void (*TOFLOAT)(ose_bundle);
966 void (*TOSTRING)(ose_bundle);
967 void (*TOBLOB)(ose_bundle);
968#ifdef OSE_PROVIDE_TYPE_SYMBOL
969 void (*TOSYMBOL)(ose_bundle);
970#endif
971#ifdef OSE_PROVIDE_TYPE_DOUBLE
972 void (*TODOUBLE)(ose_bundle);
973#endif
974#ifdef OSE_PROVIDE_TYPE_INT8
975 void (*TOINT8)(ose_bundle);
976#endif
977#ifdef OSE_PROVIDE_TYPE_UINT8
978 void (*TOUINT8)(ose_bundle);
979#endif
980#ifdef OSE_PROVIDE_TYPE_INT16
981 void (*TOINT16)(ose_bundle);
982#endif
983#ifdef OSE_PROVIDE_TYPE_UINT16
984 void (*TOUINT16)(ose_bundle);
985#endif
986#ifdef OSE_PROVIDE_TYPE_UINT32
987 void (*TOUINT32)(ose_bundle);
988#endif
989#ifdef OSE_PROVIDE_TYPE_INT64
990 void (*TOINT64)(ose_bundle);
991#endif
992#ifdef OSE_PROVIDE_TYPE_UINT64
993 void (*TOUINT64)(ose_bundle);
994#endif
995#ifdef OSE_PROVIDE_TYPE_TIMETAG
996 void (*TOTIMETAG)(ose_bundle);
997#endif
998#ifdef OSE_PROVIDE_TYPE_TRUE
999 void (*TOTRUE)(ose_bundle);
1000#endif
1001#ifdef OSE_PROVIDE_TYPE_FALSE
1002 void (*TOFALSE)(ose_bundle);
1003#endif
1004#ifdef OSE_PROVIDE_TYPE_NIL
1005 void (*TONIL)(ose_bundle);
1006#endif
1007#ifdef OSE_PROVIDE_TYPE_INFINITUM
1008 void (*TOINFINITUM)(ose_bundle);
1009#endif
1010 void (*APPENDBYTE)(ose_bundle);
1011 void (*RESPONDTOSTRING)(ose_bundle);
1012 void (*PREINPUT)(ose_bundle);
1013 void (*POSTINPUT)(ose_bundle);
1014 void (*POPINPUTTOCONTROL)(ose_bundle);
1015 void (*POSTCONTROL)(ose_bundle);
1016 void (*EVALTYPE)(ose_bundle);
1017};
1018extern const struct osevm_hooks osevm_hooks;
1019
1020#ifdef __cplusplus
1021}
1022#endif
1023
1024#endif
#define OSETT_OPCODE_
An instruction, by number: an int32 index into the host's instruction table.
Definition ose.h:749
#define ose_memmove
Move bytes that may overlap: memmove, or on the ESP32 a faster way.
Definition ose.h:174
#define OSETT_WILDPTR_
A pointer by name: the name a 'p' was bound under, as text.
Definition ose.h:707
void(* ose_fn)(ose_bundle)
Function pointer for the basic OSE function that operates on a bundle.
Definition ose.h:435
Definition ose.h:400
Convenience struct for OSC/NTP timetags.
Definition ose.h:446
uint32_t sec
Definition ose.h:447
uint32_t fsec
Definition ose.h:448
Definition ose.h:954