1 /*
2 * Copyright (c) 2021 Calvin Rose
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22 
23 #ifndef JANET_UTIL_H_defined
24 #define JANET_UTIL_H_defined
25 
26 #ifndef JANET_AMALG
27 #include "features.h"
28 #include <janet.h>
29 #include "state.h"
30 #endif
31 
32 #include <stdio.h>
33 #include <errno.h>
34 
35 #if !defined(JANET_REDUCED_OS) || !defined(JANET_SINGLE_THREADED)
36 #include <time.h>
37 #define JANET_GETTIME
38 #endif
39 
40 /* Handle runtime errors */
41 #ifndef JANET_EXIT
42 #include <stdio.h>
43 #define JANET_EXIT(m) do { \
44     fprintf(stderr, "C runtime error at line %d in file %s: %s\n",\
45         __LINE__,\
46         __FILE__,\
47         (m));\
48     exit(1);\
49 } while (0)
50 #endif
51 
52 #define JANET_MARSHAL_DECREF 0x40000
53 
54 #define janet_assert(c, m) do { \
55     if (!(c)) JANET_EXIT((m)); \
56 } while (0)
57 
58 /* Utils */
59 uint32_t janet_hash_mix(uint32_t input, uint32_t more);
60 #define janet_maphash(cap, hash) ((uint32_t)(hash) & (cap - 1))
61 int janet_valid_utf8(const uint8_t *str, int32_t len);
62 int janet_is_symbol_char(uint8_t c);
63 extern const char janet_base64[65];
64 int32_t janet_array_calchash(const Janet *array, int32_t len);
65 int32_t janet_kv_calchash(const JanetKV *kvs, int32_t len);
66 int32_t janet_string_calchash(const uint8_t *str, int32_t len);
67 int32_t janet_tablen(int32_t n);
68 void safe_memcpy(void *dest, const void *src, size_t len);
69 void janet_buffer_push_types(JanetBuffer *buffer, int types);
70 const JanetKV *janet_dict_find(const JanetKV *buckets, int32_t cap, Janet key);
71 void janet_memempty(JanetKV *mem, int32_t count);
72 void *janet_memalloc_empty(int32_t count);
73 JanetTable *janet_get_core_table(const char *name);
74 void janet_def_addflags(JanetFuncDef *def);
75 const void *janet_strbinsearch(
76     const void *tab,
77     size_t tabcount,
78     size_t itemsize,
79     const uint8_t *key);
80 void janet_buffer_format(
81     JanetBuffer *b,
82     const char *strfrmt,
83     int32_t argstart,
84     int32_t argc,
85     Janet *argv);
86 Janet janet_next_impl(Janet ds, Janet key, int is_interpreter);
87 
88 /* Registry functions */
89 void janet_registry_put(
90     JanetCFunction key,
91     const char *name,
92     const char *name_prefix,
93     const char *source_file,
94     int32_t source_line);
95 JanetCFunRegistry *janet_registry_get(JanetCFunction key);
96 
97 /* Inside the janet core, defining globals is different
98  * at bootstrap time and normal runtime */
99 #ifdef JANET_BOOTSTRAP
100 #define JANET_CORE_REG JANET_REG
101 #define JANET_CORE_FN JANET_FN
102 #define JANET_CORE_DEF JANET_DEF
103 #define janet_core_def_sm janet_def_sm
104 #define janet_core_cfuns_ext janet_cfuns_ext
105 #else
106 #define JANET_CORE_REG JANET_REG_S
107 #define JANET_CORE_FN JANET_FN_S
108 #define JANET_CORE_DEF(ENV, NAME, X, DOC) janet_core_def_sm(ENV, NAME, X, DOC, NULL, 0)
109 void janet_core_def_sm(JanetTable *env, const char *name, Janet x, const void *p, const void *sf, int32_t sl);
110 void janet_core_cfuns_ext(JanetTable *env, const char *regprefix, const JanetRegExt *cfuns);
111 #endif
112 
113 /* Clock gettime */
114 #ifdef JANET_GETTIME
115 int janet_gettime(struct timespec *spec);
116 #endif
117 
118 /* strdup */
119 #ifdef JANET_WINDOWS
120 #define strdup(x) _strdup(x)
121 #endif
122 
123 #define RETRY_EINTR(RC, CALL) do { (RC) = CALL; } while((RC) < 0 && errno == EINTR)
124 
125 /* Initialize builtin libraries */
126 void janet_lib_io(JanetTable *env);
127 void janet_lib_math(JanetTable *env);
128 void janet_lib_array(JanetTable *env);
129 void janet_lib_tuple(JanetTable *env);
130 void janet_lib_buffer(JanetTable *env);
131 void janet_lib_table(JanetTable *env);
132 void janet_lib_struct(JanetTable *env);
133 void janet_lib_fiber(JanetTable *env);
134 void janet_lib_os(JanetTable *env);
135 void janet_lib_string(JanetTable *env);
136 void janet_lib_marsh(JanetTable *env);
137 void janet_lib_parse(JanetTable *env);
138 #ifdef JANET_ASSEMBLER
139 void janet_lib_asm(JanetTable *env);
140 #endif
141 void janet_lib_compile(JanetTable *env);
142 void janet_lib_debug(JanetTable *env);
143 #ifdef JANET_PEG
144 void janet_lib_peg(JanetTable *env);
145 #endif
146 #ifdef JANET_TYPED_ARRAY
147 void janet_lib_typed_array(JanetTable *env);
148 #endif
149 #ifdef JANET_INT_TYPES
150 void janet_lib_inttypes(JanetTable *env);
151 #endif
152 #ifdef JANET_NET
153 void janet_lib_net(JanetTable *env);
154 extern const JanetAbstractType janet_address_type;
155 #endif
156 #ifdef JANET_EV
157 void janet_lib_ev(JanetTable *env);
158 void janet_ev_mark(void);
159 int janet_make_pipe(JanetHandle handles[2], int mode);
160 #endif
161 
162 #endif
163