Implement fixed buffer vstrs; use them for import path.
This commit is contained in:
parent
64131f3215
commit
354d15a964
@ -149,7 +149,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
|
|||||||
const char *mod_str = (const char*)mp_obj_str_get_data(args[0], &mod_len);
|
const char *mod_str = (const char*)mp_obj_str_get_data(args[0], &mod_len);
|
||||||
|
|
||||||
uint last = 0;
|
uint last = 0;
|
||||||
vstr_t *path = vstr_new();
|
VSTR_FIXED(path, MICROPY_PATH_MAX)
|
||||||
module_obj = MP_OBJ_NULL;
|
module_obj = MP_OBJ_NULL;
|
||||||
uint i;
|
uint i;
|
||||||
for (i = 1; i <= mod_len; i++) {
|
for (i = 1; i <= mod_len; i++) {
|
||||||
@ -159,14 +159,14 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
|
|||||||
|
|
||||||
// find the file corresponding to the module name
|
// find the file corresponding to the module name
|
||||||
mp_import_stat_t stat;
|
mp_import_stat_t stat;
|
||||||
if (vstr_len(path) == 0) {
|
if (vstr_len(&path) == 0) {
|
||||||
// first module in the dotted-name; search for a directory or file
|
// first module in the dotted-name; search for a directory or file
|
||||||
stat = find_file(mod_str, i, path);
|
stat = find_file(mod_str, i, &path);
|
||||||
} else {
|
} else {
|
||||||
// latter module in the dotted-name; append to path
|
// latter module in the dotted-name; append to path
|
||||||
vstr_add_char(path, PATH_SEP_CHAR);
|
vstr_add_char(&path, PATH_SEP_CHAR);
|
||||||
vstr_add_strn(path, mod_str + last, i - last);
|
vstr_add_strn(&path, mod_str + last, i - last);
|
||||||
stat = stat_dir_or_file(path);
|
stat = stat_dir_or_file(&path);
|
||||||
}
|
}
|
||||||
last = i + 1;
|
last = i + 1;
|
||||||
|
|
||||||
@ -182,14 +182,14 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
|
|||||||
module_obj = mp_obj_new_module(mod_name);
|
module_obj = mp_obj_new_module(mod_name);
|
||||||
|
|
||||||
if (stat == MP_IMPORT_STAT_DIR) {
|
if (stat == MP_IMPORT_STAT_DIR) {
|
||||||
vstr_add_char(path, PATH_SEP_CHAR);
|
vstr_add_char(&path, PATH_SEP_CHAR);
|
||||||
vstr_add_str(path, "__init__.py");
|
vstr_add_str(&path, "__init__.py");
|
||||||
if (mp_import_stat(vstr_str(path)) == MP_IMPORT_STAT_FILE) {
|
if (mp_import_stat(vstr_str(&path)) == MP_IMPORT_STAT_FILE) {
|
||||||
do_load(module_obj, path);
|
do_load(module_obj, &path);
|
||||||
}
|
}
|
||||||
vstr_cut_tail(path, 12); // cut off /__init__.py
|
vstr_cut_tail(&path, 12); // cut off /__init__.py
|
||||||
} else { // MP_IMPORT_STAT_FILE
|
} else { // MP_IMPORT_STAT_FILE
|
||||||
do_load(module_obj, path);
|
do_load(module_obj, &path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,8 +202,6 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vstr_free(path);
|
|
||||||
|
|
||||||
return module_obj;
|
return module_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
py/misc.h
11
py/misc.h
@ -68,10 +68,17 @@ typedef struct _vstr_t {
|
|||||||
int alloc;
|
int alloc;
|
||||||
int len;
|
int len;
|
||||||
char *buf;
|
char *buf;
|
||||||
bool had_error;
|
struct {
|
||||||
|
bool had_error : 1;
|
||||||
|
bool fixed_buf : 1;
|
||||||
|
};
|
||||||
} vstr_t;
|
} vstr_t;
|
||||||
|
|
||||||
|
// convenience macro to declare a vstr with a fixed size buffer on the stack
|
||||||
|
#define VSTR_FIXED(vstr, alloc) vstr_t vstr; char vstr##_buf[(alloc)]; vstr_init_fixed_buf(&vstr, (alloc), vstr##_buf);
|
||||||
|
|
||||||
void vstr_init(vstr_t *vstr, int alloc);
|
void vstr_init(vstr_t *vstr, int alloc);
|
||||||
|
void vstr_init_fixed_buf(vstr_t *vstr, int alloc, char *buf);
|
||||||
void vstr_clear(vstr_t *vstr);
|
void vstr_clear(vstr_t *vstr);
|
||||||
vstr_t *vstr_new(void);
|
vstr_t *vstr_new(void);
|
||||||
vstr_t *vstr_new_size(int alloc);
|
vstr_t *vstr_new_size(int alloc);
|
||||||
@ -81,7 +88,7 @@ bool vstr_had_error(vstr_t *vstr);
|
|||||||
char *vstr_str(vstr_t *vstr);
|
char *vstr_str(vstr_t *vstr);
|
||||||
int vstr_len(vstr_t *vstr);
|
int vstr_len(vstr_t *vstr);
|
||||||
void vstr_hint_size(vstr_t *vstr, int size);
|
void vstr_hint_size(vstr_t *vstr, int size);
|
||||||
char *vstr_extend(vstr_t *vstr, int size);
|
char *vstr_extend(vstr_t *vstr, int size);
|
||||||
bool vstr_set_size(vstr_t *vstr, int size);
|
bool vstr_set_size(vstr_t *vstr, int size);
|
||||||
bool vstr_shrink(vstr_t *vstr);
|
bool vstr_shrink(vstr_t *vstr);
|
||||||
char *vstr_add_len(vstr_t *vstr, int len);
|
char *vstr_add_len(vstr_t *vstr, int len);
|
||||||
|
@ -101,6 +101,12 @@ typedef long long mp_longint_impl_t;
|
|||||||
#define MICROPY_CPYTHON_COMPAT (1)
|
#define MICROPY_CPYTHON_COMPAT (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Maximum length of a path in the filesystem
|
||||||
|
// So we can allocate a buffer on the stack for path manipulation in import
|
||||||
|
#ifndef MICROPY_PATH_MAX
|
||||||
|
#define MICROPY_PATH_MAX (512)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Miscellaneous settings */
|
/* Miscellaneous settings */
|
||||||
|
|
||||||
|
40
py/vstr.c
40
py/vstr.c
@ -1,6 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
// returned value is always at least 1 greater than argument
|
// returned value is always at least 1 greater than argument
|
||||||
@ -16,10 +17,23 @@ void vstr_init(vstr_t *vstr, int alloc) {
|
|||||||
}
|
}
|
||||||
vstr->buf[0] = 0;
|
vstr->buf[0] = 0;
|
||||||
vstr->had_error = false;
|
vstr->had_error = false;
|
||||||
|
vstr->fixed_buf = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vstr_init_fixed_buf(vstr_t *vstr, int alloc, char *buf) {
|
||||||
|
assert(alloc > 0); // need at least room for the null byte
|
||||||
|
vstr->alloc = alloc;
|
||||||
|
vstr->len = 0;
|
||||||
|
vstr->buf = buf;
|
||||||
|
vstr->buf[0] = 0;
|
||||||
|
vstr->had_error = false;
|
||||||
|
vstr->fixed_buf = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vstr_clear(vstr_t *vstr) {
|
void vstr_clear(vstr_t *vstr) {
|
||||||
m_del(char, vstr->buf, vstr->alloc);
|
if (!vstr->fixed_buf) {
|
||||||
|
m_del(char, vstr->buf, vstr->alloc);
|
||||||
|
}
|
||||||
vstr->buf = NULL;
|
vstr->buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +57,9 @@ vstr_t *vstr_new_size(int alloc) {
|
|||||||
|
|
||||||
void vstr_free(vstr_t *vstr) {
|
void vstr_free(vstr_t *vstr) {
|
||||||
if (vstr != NULL) {
|
if (vstr != NULL) {
|
||||||
m_del(char, vstr->buf, vstr->alloc);
|
if (!vstr->fixed_buf) {
|
||||||
|
m_del(char, vstr->buf, vstr->alloc);
|
||||||
|
}
|
||||||
m_del_obj(vstr_t, vstr);
|
m_del_obj(vstr_t, vstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +89,10 @@ int vstr_len(vstr_t *vstr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extend vstr strictly to by requested size, return pointer to newly added chunk
|
// Extend vstr strictly to by requested size, return pointer to newly added chunk
|
||||||
char *vstr_extend(vstr_t *vstr, int size) {
|
char *vstr_extend(vstr_t *vstr, int size) {
|
||||||
|
if (vstr->fixed_buf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, vstr->alloc + size);
|
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, vstr->alloc + size);
|
||||||
if (new_buf == NULL) {
|
if (new_buf == NULL) {
|
||||||
vstr->had_error = true;
|
vstr->had_error = true;
|
||||||
@ -87,6 +106,9 @@ char *vstr_extend(vstr_t *vstr, int size) {
|
|||||||
|
|
||||||
// Shrink vstr to be given size
|
// Shrink vstr to be given size
|
||||||
bool vstr_set_size(vstr_t *vstr, int size) {
|
bool vstr_set_size(vstr_t *vstr, int size) {
|
||||||
|
if (vstr->fixed_buf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, size);
|
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, size);
|
||||||
if (new_buf == NULL) {
|
if (new_buf == NULL) {
|
||||||
vstr->had_error = true;
|
vstr->had_error = true;
|
||||||
@ -102,8 +124,11 @@ bool vstr_shrink(vstr_t *vstr) {
|
|||||||
return vstr_set_size(vstr, vstr->len);
|
return vstr_set_size(vstr, vstr->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vstr_ensure_extra(vstr_t *vstr, int size) {
|
static bool vstr_ensure_extra(vstr_t *vstr, int size) {
|
||||||
if (vstr->len + size + 1 > vstr->alloc) {
|
if (vstr->len + size + 1 > vstr->alloc) {
|
||||||
|
if (vstr->fixed_buf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
int new_alloc = ROUND_ALLOC((vstr->len + size + 1) * 2);
|
int new_alloc = ROUND_ALLOC((vstr->len + size + 1) * 2);
|
||||||
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, new_alloc);
|
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, new_alloc);
|
||||||
if (new_buf == NULL) {
|
if (new_buf == NULL) {
|
||||||
@ -156,8 +181,15 @@ void vstr_add_str(vstr_t *vstr, const char *str) {
|
|||||||
|
|
||||||
void vstr_add_strn(vstr_t *vstr, const char *str, int len) {
|
void vstr_add_strn(vstr_t *vstr, const char *str, int len) {
|
||||||
if (vstr->had_error || !vstr_ensure_extra(vstr, len)) {
|
if (vstr->had_error || !vstr_ensure_extra(vstr, len)) {
|
||||||
|
// if buf is fixed, we got here because there isn't enough room left
|
||||||
|
// so just try to copy as much as we can, with room for null byte
|
||||||
|
if (vstr->fixed_buf && vstr->len + 1 < vstr->alloc) {
|
||||||
|
len = vstr->alloc - vstr->len - 1;
|
||||||
|
goto copy;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
copy:
|
||||||
memmove(vstr->buf + vstr->len, str, len);
|
memmove(vstr->buf + vstr->len, str, len);
|
||||||
vstr->len += len;
|
vstr->len += len;
|
||||||
vstr->buf[vstr->len] = 0;
|
vstr->buf[vstr->len] = 0;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define MICROPY_ENABLE_GC (1)
|
#define MICROPY_ENABLE_GC (1)
|
||||||
#define MICROPY_ENABLE_REPL_HELPERS (1)
|
#define MICROPY_ENABLE_REPL_HELPERS (1)
|
||||||
#define MICROPY_ENABLE_FLOAT (1)
|
#define MICROPY_ENABLE_FLOAT (1)
|
||||||
|
#define MICROPY_PATH_MAX (128)
|
||||||
|
|
||||||
// type definitions for the specific machine
|
// type definitions for the specific machine
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||||
#define MICROPY_ENABLE_FLOAT (1)
|
#define MICROPY_ENABLE_FLOAT (1)
|
||||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
|
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
|
||||||
|
#define MICROPY_PATH_MAX (PATH_MAX)
|
||||||
|
|
||||||
// type definitions for the specific machine
|
// type definitions for the specific machine
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user