Numworks Epsilon  1.4.1
Graphing Calculator Operating System
misc.h
Go to the documentation of this file.
1 /*
2  * This file is part of the MicroPython project, http://micropython.org/
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2013, 2014 Damien P. George
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26 #ifndef MICROPY_INCLUDED_PY_MISC_H
27 #define MICROPY_INCLUDED_PY_MISC_H
28 
29 // a mini library of useful types and functions
30 
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <stddef.h>
36 
37 typedef unsigned char byte;
38 typedef unsigned int uint;
39 
42 #ifndef MIN
43 #define MIN(x, y) ((x) < (y) ? (x) : (y))
44 #endif
45 #ifndef MAX
46 #define MAX(x, y) ((x) > (y) ? (x) : (y))
47 #endif
48 
49 // Classical double-indirection stringification of preprocessor macro's value
50 #define _MP_STRINGIFY(x) #x
51 #define MP_STRINGIFY(x) _MP_STRINGIFY(x)
52 
55 // TODO make a lazy m_renew that can increase by a smaller amount than requested (but by at least 1 more element)
56 
57 #define m_new(type, num) ((type*)(m_malloc(sizeof(type) * (num))))
58 #define m_new_maybe(type, num) ((type*)(m_malloc_maybe(sizeof(type) * (num))))
59 #define m_new0(type, num) ((type*)(m_malloc0(sizeof(type) * (num))))
60 #define m_new_obj(type) (m_new(type, 1))
61 #define m_new_obj_maybe(type) (m_new_maybe(type, 1))
62 #define m_new_obj_var(obj_type, var_type, var_num) ((obj_type*)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num)))
63 #define m_new_obj_var_maybe(obj_type, var_type, var_num) ((obj_type*)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num)))
64 #if MICROPY_ENABLE_FINALISER
65 #define m_new_obj_with_finaliser(type) ((type*)(m_malloc_with_finaliser(sizeof(type))))
66 #else
67 #define m_new_obj_with_finaliser(type) m_new_obj(type)
68 #endif
69 #if MICROPY_MALLOC_USES_ALLOCATED_SIZE
70 #define m_renew(type, ptr, old_num, new_num) ((type*)(m_realloc((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num))))
71 #define m_renew_maybe(type, ptr, old_num, new_num, allow_move) ((type*)(m_realloc_maybe((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num), (allow_move))))
72 #define m_del(type, ptr, num) m_free(ptr, sizeof(type) * (num))
73 #define m_del_var(obj_type, var_type, var_num, ptr) (m_free(ptr, sizeof(obj_type) + sizeof(var_type) * (var_num)))
74 #else
75 #define m_renew(type, ptr, old_num, new_num) ((type*)(m_realloc((ptr), sizeof(type) * (new_num))))
76 #define m_renew_maybe(type, ptr, old_num, new_num, allow_move) ((type*)(m_realloc_maybe((ptr), sizeof(type) * (new_num), (allow_move))))
77 #define m_del(type, ptr, num) ((void)(num), m_free(ptr))
78 #define m_del_var(obj_type, var_type, var_num, ptr) ((void)(var_num), m_free(ptr))
79 #endif
80 #define m_del_obj(type, ptr) (m_del(type, ptr, 1))
81 
82 void *m_malloc(size_t num_bytes);
83 void *m_malloc_maybe(size_t num_bytes);
84 void *m_malloc_with_finaliser(size_t num_bytes);
85 void *m_malloc0(size_t num_bytes);
86 #if MICROPY_MALLOC_USES_ALLOCATED_SIZE
87 void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes);
88 void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes, bool allow_move);
89 void m_free(void *ptr, size_t num_bytes);
90 #else
91 void *m_realloc(void *ptr, size_t new_num_bytes);
92 void *m_realloc_maybe(void *ptr, size_t new_num_bytes, bool allow_move);
93 void m_free(void *ptr);
94 #endif
95 NORETURN void m_malloc_fail(size_t num_bytes);
96 
97 #if MICROPY_MEM_STATS
98 size_t m_get_total_bytes_allocated(void);
99 size_t m_get_current_bytes_allocated(void);
100 size_t m_get_peak_bytes_allocated(void);
101 #endif
102 
105 // get the number of elements in a fixed-size array
106 #define MP_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
107 
108 // align ptr to the nearest multiple of "alignment"
109 #define MP_ALIGN(ptr, alignment) (void*)(((uintptr_t)(ptr) + ((alignment) - 1)) & ~((alignment) - 1))
110 
113 #if MICROPY_PY_BUILTINS_STR_UNICODE
114 // with unicode enabled we need a type which can fit chars up to 0x10ffff
115 typedef uint32_t unichar;
116 #else
117 // without unicode enabled we can only need to fit chars up to 0xff
118 // (on 16-bit archs uint is 16-bits and more efficient than uint32_t)
119 typedef uint unichar;
120 #endif
121 
122 unichar utf8_get_char(const byte *s);
123 const byte *utf8_next_char(const byte *s);
124 
136 mp_uint_t unichar_charlen(const char *str, mp_uint_t len);
137 #define UTF8_IS_NONASCII(ch) ((ch) & 0x80)
138 #define UTF8_IS_CONT(ch) (((ch) & 0xC0) == 0x80)
139 
142 typedef struct _vstr_t {
143  size_t alloc;
144  size_t len;
145  char *buf;
146  bool fixed_buf : 1;
147 } vstr_t;
148 
149 // convenience macro to declare a vstr with a fixed size buffer on the stack
150 #define VSTR_FIXED(vstr, alloc) vstr_t vstr; char vstr##_buf[(alloc)]; vstr_init_fixed_buf(&vstr, (alloc), vstr##_buf);
151 
152 void vstr_init(vstr_t *vstr, size_t alloc);
153 void vstr_init_len(vstr_t *vstr, size_t len);
154 void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf);
155 struct _mp_print_t;
156 void vstr_init_print(vstr_t *vstr, size_t alloc, struct _mp_print_t *print);
157 void vstr_clear(vstr_t *vstr);
158 vstr_t *vstr_new(size_t alloc);
159 void vstr_free(vstr_t *vstr);
160 static inline void vstr_reset(vstr_t *vstr) { vstr->len = 0; }
161 static inline char *vstr_str(vstr_t *vstr) { return vstr->buf; }
162 static inline size_t vstr_len(vstr_t *vstr) { return vstr->len; }
163 void vstr_hint_size(vstr_t *vstr, size_t size);
164 char *vstr_extend(vstr_t *vstr, size_t size);
165 char *vstr_add_len(vstr_t *vstr, size_t len);
166 char *vstr_null_terminated_str(vstr_t *vstr);
167 void vstr_add_byte(vstr_t *vstr, byte v);
168 void vstr_add_char(vstr_t *vstr, unichar chr);
169 void vstr_add_str(vstr_t *vstr, const char *str);
170 void vstr_add_strn(vstr_t *vstr, const char *str, size_t len);
171 void vstr_ins_byte(vstr_t *vstr, size_t byte_pos, byte b);
172 void vstr_ins_char(vstr_t *vstr, size_t char_pos, unichar chr);
173 void vstr_cut_head_bytes(vstr_t *vstr, size_t bytes_to_cut);
174 void vstr_cut_tail_bytes(vstr_t *vstr, size_t bytes_to_cut);
175 void vstr_cut_out_bytes(vstr_t *vstr, size_t byte_pos, size_t bytes_to_cut);
176 void vstr_printf(vstr_t *vstr, const char *fmt, ...);
177 
180 #define CHECKBUF(buf, max_size) char buf[max_size + 1]; size_t buf##_len = max_size; char *buf##_p = buf;
181 #define CHECKBUF_RESET(buf, max_size) buf##_len = max_size; buf##_p = buf;
182 #define CHECKBUF_APPEND(buf, src, src_len) \
183  { size_t l = MIN(src_len, buf##_len); \
184  memcpy(buf##_p, src, l); \
185  buf##_len -= l; \
186  buf##_p += l; }
187 #define CHECKBUF_APPEND_0(buf) { *buf##_p = 0; }
188 #define CHECKBUF_LEN(buf) (buf##_p - buf)
189 
190 #ifdef va_start
191 void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap);
192 #endif
193 
194 // Debugging helpers
195 int DEBUG_printf(const char *fmt, ...);
196 
198 
199 // This is useful for unicode handling. Some CPU archs has
200 // special instructions for efficient implementation of this
201 // function (e.g. CLZ on ARM).
202 // NOTE: this function is unused at the moment
203 #ifndef count_lead_ones
204 static inline mp_uint_t count_lead_ones(byte val) {
205  mp_uint_t c = 0;
206  for (byte mask = 0x80; val & mask; mask >>= 1) {
207  c++;
208  }
209  return c;
210 }
211 #endif
212 
215 #if MICROPY_PY_BUILTINS_FLOAT
216 #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
217 #define MP_FLOAT_EXP_BITS (11)
218 #define MP_FLOAT_FRAC_BITS (52)
219 #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
220 #define MP_FLOAT_EXP_BITS (8)
221 #define MP_FLOAT_FRAC_BITS (23)
222 #endif
223 #define MP_FLOAT_EXP_BIAS ((1 << (MP_FLOAT_EXP_BITS - 1)) - 1)
224 #endif // MICROPY_PY_BUILTINS_FLOAT
225 
226 #endif // MICROPY_INCLUDED_PY_MISC_H
void * m_realloc(void *ptr, size_t new_num_bytes)
Definition: malloc.c:130
void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf)
Definition: vstr.c:57
uintptr_t mp_uint_t
Definition: mpconfigport.h:74
Definition: misc.h:142
char * vstr_extend(vstr_t *vstr, size_t size)
Definition: vstr.c:93
int DEBUG_printf(const char *fmt,...)
void vstr_add_strn(vstr_t *vstr, const char *str, size_t len)
Definition: vstr.c:179
bool unichar_isalpha(unichar c)
Definition: unicode.c:132
void vstr_add_char(vstr_t *vstr, unichar chr)
Definition: vstr.c:146
void vstr_init_len(vstr_t *vstr, size_t len)
Definition: vstr.c:52
void * m_malloc_maybe(size_t num_bytes)
Definition: malloc.c:88
char * buf
Definition: misc.h:145
void vstr_init(vstr_t *vstr, size_t alloc)
Definition: vstr.c:40
vstr_t * vstr_new(size_t alloc)
Definition: vstr.c:77
bool unichar_isxdigit(unichar c)
Definition: unicode.c:146
unichar unichar_tolower(unichar c)
Definition: unicode.c:162
void m_free(void *ptr)
Definition: malloc.c:178
void vstr_add_byte(vstr_t *vstr, byte v)
Definition: vstr.c:141
const byte * utf8_next_char(const byte *s)
Definition: unicode.c:89
size_t len
Definition: misc.h:144
void vstr_hint_size(vstr_t *vstr, size_t size)
Definition: vstr.c:120
void vstr_add_str(vstr_t *vstr, const char *str)
Definition: vstr.c:175
bool unichar_isdigit(unichar c)
Definition: unicode.c:142
char * vstr_add_len(vstr_t *vstr, size_t len)
Definition: vstr.c:124
void vstr_ins_char(vstr_t *vstr, size_t char_pos, unichar chr)
Definition: vstr.c:206
c(generic_all_nodes)
void * m_realloc_maybe(void *ptr, size_t new_num_bytes, bool allow_move)
Definition: malloc.c:154
bool unichar_isspace(unichar c)
Definition: unicode.c:128
void * m_malloc_with_finaliser(size_t num_bytes)
unsigned int uint32_t
Definition: stdint.h:6
mp_uint_t unichar_xdigit_value(unichar c)
Definition: unicode.c:176
bool unichar_islower(unichar c)
Definition: unicode.c:158
bool unichar_isident(unichar c)
Definition: unicode.c:150
#define NORETURN
Definition: mpconfig.h:1268
mp_uint_t mp_verbose_flag
void * m_malloc0(size_t num_bytes)
Definition: malloc.c:115
unsigned char byte
Definition: misc.h:37
unichar utf8_get_char(const byte *s)
Definition: unicode.c:71
NORETURN void m_malloc_fail(size_t num_bytes)
Definition: runtime.c:1437
void vstr_cut_out_bytes(vstr_t *vstr, size_t byte_pos, size_t bytes_to_cut)
Definition: vstr.c:224
char * vstr_null_terminated_str(vstr_t *vstr)
Definition: vstr.c:132
bool unichar_isprint(unichar c)
struct _vstr_t vstr_t
void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap)
Definition: vstr.c:242
__builtin_va_list va_list
Definition: stdarg.h:4
unichar unichar_toupper(unichar c)
Definition: unicode.c:169
void vstr_free(vstr_t *vstr)
Definition: vstr.c:83
bool fixed_buf
Definition: misc.h:146
void vstr_cut_head_bytes(vstr_t *vstr, size_t bytes_to_cut)
Definition: vstr.c:212
mp_uint_t unichar_charlen(const char *str, mp_uint_t len)
Definition: unicode.c:113
uint unichar
Definition: misc.h:119
void vstr_init_print(vstr_t *vstr, size_t alloc, struct _mp_print_t *print)
Definition: vstr.c:64
void vstr_clear(vstr_t *vstr)
Definition: vstr.c:70
void * m_malloc(size_t num_bytes)
Definition: malloc.c:74
size_t alloc
Definition: misc.h:143
bool unichar_isupper(unichar c)
Definition: unicode.c:154
void vstr_cut_tail_bytes(vstr_t *vstr, size_t bytes_to_cut)
Definition: vstr.c:216
void vstr_ins_byte(vstr_t *vstr, size_t byte_pos, byte b)
Definition: vstr.c:201
void vstr_printf(vstr_t *vstr, const char *fmt,...)
Definition: vstr.c:235
unsigned int uint
Definition: misc.h:38