Compare commits

...

11 Commits

Author SHA1 Message Date
Quentin Guidée
4af76cc3ae [omega] 1.20.1 2020-07-21 22:32:19 +02:00
Quentin
93c431be04 Merge pull request #387 from M4xi1m3/omega-hotfix
[mpy] Fix crash on append on new file, new os module
2020-07-21 22:30:32 +02:00
M4x1m3
63acf7b0ee [app/code] Changed color of mandelbrot script 2020-07-21 22:27:04 +02:00
M4x1m3
14a3ea51c4 [mpy/os] listdir 2020-07-21 22:27:04 +02:00
M4x1m3
18ccc0c771 [mpy/os] rename 2020-07-21 22:27:04 +02:00
M4x1m3
f65881420c [mpy/file] Fixed concurency issues 2020-07-21 22:27:04 +02:00
M4x1m3
8eeae5f161 [mpy/os] Added remove 2020-07-21 22:27:04 +02:00
M4x1m3
2dce8a1343 [mpy/os] uname 2020-07-21 22:27:00 +02:00
M4x1m3
b9a6298ffa [mpy] Added os module 2020-07-21 18:00:12 +02:00
M4x1m3
2040a2cd5b [mpy/files] Fixed crash with new files in append mode 2020-07-21 16:57:57 +02:00
Quentin Guidée
73037e3faf [github] Fix README.md 2020-07-21 09:32:14 +02:00
15 changed files with 239 additions and 10 deletions

View File

@@ -19,7 +19,7 @@ Omega is a fork of Numworks' Epsilon, the OS that runs on their calculator, whic
- ~~32 KB Python heap instead of 16 KB~~ Now available on Epsilon `>=13.2.0`!
- And more...
The main new features are listed [here](https://github.com/Omega-Numworks/Omega/wiki/Main-features), and the complete changelog can be found [here](https://github.com/Omega-Numworks/Omega/wiki/Complete-changelog).
The main new features are listed [here](https://github.com/Omega-Numworks/Omega/wiki/Main-features), and the complete changelog can be found [here](https://github.com/Omega-Numworks/Omega/wiki/Changelog).
## Installation

View File

@@ -36,7 +36,7 @@ def mandelbrot(N_iteration):
z = z*z+c
# Choose the color of the dot from the Mandelbrot sequence
rgb = int(255*i/N_iteration)
col = kandinsky.color(int(rgb),int(rgb*0.75),int(rgb*0.25))
col = kandinsky.color(int(rgb*0.82),int(rgb*0.13),int(rgb*0.18))
# Draw a pixel colored in 'col' at position (x,y)
kandinsky.set_pixel(x,y,col))");

View File

@@ -53,7 +53,7 @@ bool AboutController::handleEvent(Ion::Events::Event event) {
if (childLabel == I18n::Message::OmegaVersion) {
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)m_selectableTableView.selectedCell();
if (strcmp(myCell->accessoryText(), Ion::omegaVersion()) == 0) {
myCell->setAccessoryText("Dev"); //Change for public/dev
myCell->setAccessoryText("Public"); //Change for public/dev
return true;
}
myCell->setAccessoryText(Ion::omegaVersion());

View File

@@ -5,7 +5,7 @@ DEBUG ?= 0
HOME_DISPLAY_EXTERNALS ?= 1
EPSILON_VERSION ?= 14.4.1
OMEGA_VERSION ?= 1.20.0
OMEGA_VERSION ?= 1.20.1
# USERNAME ?= N/A
EPSILON_APPS ?= calculation rpn graph code statistics probability solver atom sequence regression settings external
EPSILON_I18N ?= en fr nl pt it de es hu

View File

@@ -122,6 +122,10 @@ public:
// Useful
static bool FullNameCompliant(const char * name);
// User by Python OS module
int numberOfRecords();
Record recordAtIndex(int index);
private:
constexpr static uint32_t Magic = 0xEE0BDDBA;

View File

@@ -208,6 +208,37 @@ int Storage::numberOfRecordsWithExtension(const char * extension) {
return count;
}
int Storage::numberOfRecords() {
int count = 0;
for (char * p : *this) {
const char * name = fullNameOfRecordStarting(p);
count++;
}
return count;
}
Storage::Record Storage::recordAtIndex(int index) {
int currentIndex = -1;
const char * name = nullptr;
char * recordAddress = nullptr;
for (char * p : *this) {
const char * currentName = fullNameOfRecordStarting(p);
currentIndex++;
if (currentIndex == index) {
recordAddress = p;
name = currentName;
break;
}
}
if (name == nullptr) {
return Record();
}
Record r = Record(name);
m_lastRecordRetrieved = r;
m_lastRecordRetrievedPointer = recordAddress;
return Record(name);
}
Storage::Record Storage::recordWithExtensionAtIndex(const char * extension, int index) {
int currentIndex = -1;
const char * name = nullptr;

View File

@@ -1,6 +1,7 @@
SFLAGS += -Ipython/src
SFLAGS += -Ipython/port
SFLAGS += -I$(BUILD_DIR)/python/port
SFLAGS += -DEPSILON_VERSION="$(EPSILON_VERSION)" -DOMEGA_VERSION="$(OMEGA_VERSION)"
# How to maintain this Makefile
# - Copy PY_CORE_O_BASENAME from py.mk into py_src
@@ -148,6 +149,8 @@ port_src += $(addprefix python/port/,\
mod/matplotlib/pyplot/plot_view.cpp \
mod/time/modtime.c \
mod/time/modtime_table.c \
mod/os/modos.cpp \
mod/os/modos_table.c \
mod/turtle/modturtle.cpp \
mod/turtle/modturtle_table.c \
mod/turtle/turtle.cpp \

View File

@@ -526,3 +526,14 @@ Q(SEEK_SET)
Q(SEEK_CUR)
Q(SEEK_END)
// os QSTRs
Q(os)
Q(uname)
Q(sysname)
Q(nodename)
Q(release)
Q(version)
Q(machine)
Q(rename)
Q(listdir)

View File

@@ -464,15 +464,22 @@ STATIC mp_obj_t file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
break;
case APPEND:
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
file->position = 0;
if (file->record == Ion::Storage::Record()) {
status = Ion::Storage::sharedStorage()->createRecordWithFullName(file_name, "", 0);
if (status == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable) {
status = Ion::Storage::sharedStorage()->createRecordWithFullName(file_name, "", 0);
switch (status) {
case Ion::Storage::Record::ErrorStatus::NameTaken:
// setValue messes with empty buffer, so we delete record and re-create it.
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
file->record.destroy();
break;
case Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable:
mp_raise_OSError(28);
}
break;
default:
break;
}
file->position = file->record.value().size;
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
break;
}
@@ -520,6 +527,17 @@ STATIC mp_obj_t file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
void check_closed(file_obj_t* file) {
if (file->closed)
mp_raise_ValueError("I/O operation on closed file");
// This is VERY imports, as it eliminates concurrency
// issues (eg. removing the file and then writing to it,
// having file move in the store, etc.)
size_t l;
const char* file_name = mp_obj_str_get_data(file->name, &l);
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
if (file->record == Ion::Storage::Record()) {
mp_raise_OSError(2);
}
}

View File

@@ -0,0 +1,115 @@
extern "C" {
#include "modos.h"
#include <string.h>
#include <py/obj.h>
#include <py/runtime.h>
#include <py/objstr.h>
#include <py/objtuple.h>
}
#include <ion/storage.h>
#ifndef OMEGA_VERSION
#error This file expects OMEGA_VERSION to be defined
#endif
#ifndef EPSILON_VERSION
#error This file expects EPSILON_VERSION to be defined
#endif
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_sysname_obj, "NumWorks");
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_nodename_obj, "");
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_release_obj, "O" MP_STRINGIFY(OMEGA_VERSION) "E-" MP_STRINGIFY(EPSILON_VERSION));
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_version_obj, MICROPY_VERSION_STRING);
#if defined(DEVICE_N0110)
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_machine_obj, "NumWorks N0110");
#elif defined(DEVICE_N0100)
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_machine_obj, "NumWorks N0100");
#else
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_machine_obj, "NumWorks Simulator");
#endif
STATIC const mp_rom_map_elem_t modos_uname_info_table[] = {
{ MP_ROM_QSTR(MP_QSTR_sysname), &modos_uname_info_sysname_obj },
{ MP_ROM_QSTR(MP_QSTR_nodename), &modos_uname_info_nodename_obj },
{ MP_ROM_QSTR(MP_QSTR_release), &modos_uname_info_release_obj },
{ MP_ROM_QSTR(MP_QSTR_version), &modos_uname_info_version_obj },
{ MP_ROM_QSTR(MP_QSTR_machine), &modos_uname_info_machine_obj },
};
STATIC MP_DEFINE_CONST_DICT(modos_uname_info_obj, modos_uname_info_table);
mp_obj_t modos_uname(void) {
return (mp_obj_t)&modos_uname_info_obj;
}
mp_obj_t modos_remove(mp_obj_t o_file_name) {
size_t len;
const char* file_name;
file_name = mp_obj_str_get_data(o_file_name, &len);
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(file_name);
if (record == Ion::Storage::Record()) {
mp_raise_OSError(2);
}
record.destroy();
return mp_const_none;
}
mp_obj_t modos_rename(mp_obj_t o_old_name, mp_obj_t o_new_name) {
size_t len;
const char* old_name;
const char* new_name;
old_name = mp_obj_str_get_data(o_old_name, &len);
new_name = mp_obj_str_get_data(o_new_name, &len);
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(old_name);
if (record == Ion::Storage::Record()) {
mp_raise_OSError(2);
}
Ion::Storage::Record::ErrorStatus status = record.setName(new_name);
switch (status) {
case Ion::Storage::Record::ErrorStatus::NameTaken:
mp_raise_OSError(17);
break;
case Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable:
mp_raise_OSError(28);
break;
case Ion::Storage::Record::ErrorStatus::NonCompliantName:
mp_raise_OSError(22);
break;
case Ion::Storage::Record::ErrorStatus::RecordDoesNotExist:
mp_raise_OSError(2);
break;
default:
break;
}
return mp_const_none;
}
mp_obj_t modos_listdir(void) {
mp_obj_t list = mp_obj_new_list(0, NULL);
for(size_t i = 0; i < (size_t)Ion::Storage::sharedStorage()->numberOfRecords(); i++) {
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordAtIndex(i);
size_t file_name_length = strlen(record.fullName());
mp_obj_t file_name = mp_obj_new_str(record.fullName(), file_name_length);
mp_obj_list_append(list, file_name);
}
return list;
}

View File

@@ -0,0 +1,6 @@
#include <py/obj.h>
mp_obj_t modos_uname();
mp_obj_t modos_remove(mp_obj_t o_file_name);
mp_obj_t modos_rename(mp_obj_t o_old_name, mp_obj_t o_new_name);
mp_obj_t modos_listdir();

View File

@@ -0,0 +1,21 @@
#include "modos.h"
MP_DEFINE_CONST_FUN_OBJ_0(modos_uname_obj, modos_uname);
MP_DEFINE_CONST_FUN_OBJ_1(modos_remove_obj, modos_remove);
MP_DEFINE_CONST_FUN_OBJ_2(modos_rename_obj, modos_rename);
MP_DEFINE_CONST_FUN_OBJ_0(modos_listdir_obj, modos_listdir);
STATIC const mp_rom_map_elem_t modos_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) },
{ MP_ROM_QSTR(MP_QSTR_uname), &modos_uname_obj},
{ MP_ROM_QSTR(MP_QSTR_remove), &modos_remove_obj},
{ MP_ROM_QSTR(MP_QSTR_rename), &modos_rename_obj},
{ MP_ROM_QSTR(MP_QSTR_listdir), &modos_listdir_obj},
};
STATIC MP_DEFINE_CONST_DICT(modos_module_globals, modos_module_globals_table);
const mp_obj_module_t modos_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&modos_module_globals,
};

View File

@@ -0,0 +1,18 @@
extern "C" {
#include <py/smallint.h>
#include <py/objint.h>
#include <py/objstr.h>
#include <py/objtype.h>
#include <py/runtime.h>
#include <py/stream.h>
#include <py/builtin.h>
#include <py/obj.h>
#include <py/misc.h>
#include "uname_result.h"
}
STATIC void uname_result_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
STATIC mp_obj_t uname_result_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
STATIC void uname_result_attr(mp_obj_t self_in, qstr attribute, mp_obj_t *destination);

View File

View File

@@ -131,6 +131,7 @@ extern const struct _mp_obj_module_t modkandinsky_module;
extern const struct _mp_obj_module_t modmatplotlib_module;
extern const struct _mp_obj_module_t modpyplot_module;
extern const struct _mp_obj_module_t modtime_module;
extern const struct _mp_obj_module_t modos_module;
extern const struct _mp_obj_module_t modturtle_module;
#define MICROPY_PORT_BUILTIN_MODULES \
@@ -139,5 +140,6 @@ extern const struct _mp_obj_module_t modturtle_module;
{ MP_ROM_QSTR(MP_QSTR_matplotlib), MP_ROM_PTR(&modmatplotlib_module) }, \
{ MP_ROM_QSTR(MP_QSTR_matplotlib_dot_pyplot), MP_ROM_PTR(&modpyplot_module) }, \
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&modtime_module) }, \
{ MP_ROM_QSTR(MP_QSTR_os), MP_ROM_PTR(&modos_module) }, \
{ MP_ROM_QSTR(MP_QSTR_turtle), MP_ROM_PTR(&modturtle_module) }, \