Jelajahi Sumber

allow py command to display stdout

Oliver Fabel 1 tahun lalu
induk
melakukan
d1381bd0ee
5 mengubah file dengan 36 tambahan dan 4 penghapusan
  1. 5 0
      CHANGELOG.md
  2. 2 2
      lib/micropython-port/mp_flipper_halport.c
  3. 6 1
      upython.c
  4. 2 1
      upython.h
  5. 21 0
      upython_cli.c

+ 5 - 0
CHANGELOG.md

@@ -16,8 +16,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
   * Log levels according to the Flipper Zero API: trace, debug, info, warn, error.
   * Log levels according to the Flipper Zero API: trace, debug, info, warn, error.
   * Only the root logger is supported, so no `getLogger` function.
   * Only the root logger is supported, so no `getLogger` function.
   * Logs directly to the log output, so no output in the REPL.
   * Logs directly to the log output, so no output in the REPL.
+* Send output from `print` to `stdout` if script is started by `py` command from the CLI.
 * UART support for the `flipperzero` module.
 * UART support for the `flipperzero` module.
 
 
+### Changed
+
+* The `py` command waits until the script terminates.
+
 ### Fixed
 ### Fixed
 
 
 * [#3](https://github.com/ofabel/mp-flipper/issues/3): Proper `CR` and `LF` handling in the REPL:
 * [#3](https://github.com/ofabel/mp-flipper/issues/3): Proper `CR` and `LF` handling in the REPL:

+ 2 - 2
lib/micropython-port/mp_flipper_halport.c

@@ -9,11 +9,11 @@
 #include "mp_flipper_file_helper.h"
 #include "mp_flipper_file_helper.h"
 
 
 inline void mp_flipper_stdout_tx_str(const char* str) {
 inline void mp_flipper_stdout_tx_str(const char* str) {
-    printf("%s", str);
+    furi_thread_stdout_write(str, strlen(str));
 }
 }
 
 
 inline void mp_flipper_stdout_tx_strn_cooked(const char* str, size_t len) {
 inline void mp_flipper_stdout_tx_strn_cooked(const char* str, size_t len) {
-    printf("%.*s", len, str);
+    furi_thread_stdout_write(str, len);
 }
 }
 
 
 inline mp_flipper_import_stat_t mp_flipper_import_stat(const char* path) {
 inline mp_flipper_import_stat_t mp_flipper_import_stat(const char* path) {

+ 6 - 1
upython.c

@@ -6,8 +6,9 @@
 
 
 #include "upython.h"
 #include "upython.h"
 
 
-Action action = ActionNone;
+volatile Action action = ActionNone;
 FuriString* file_path = NULL;
 FuriString* file_path = NULL;
+volatile FuriThreadStdoutWriteCallback stdout_callback = NULL;
 
 
 void upython_reset_file_path() {
 void upython_reset_file_path() {
     furi_string_set(file_path, APP_ASSETS_PATH("upython"));
     furi_string_set(file_path, APP_ASSETS_PATH("upython"));
@@ -35,12 +36,16 @@ int32_t upython(void* args) {
         case ActionRepl:
         case ActionRepl:
             break;
             break;
         case ActionExec:
         case ActionExec:
+            furi_thread_set_stdout_callback(stdout_callback);
+
             upython_file_execute(file_path);
             upython_file_execute(file_path);
 
 
             upython_reset_file_path();
             upython_reset_file_path();
 
 
             action = ActionNone;
             action = ActionNone;
 
 
+            furi_thread_set_stdout_callback(stdout_callback = NULL);
+
             break;
             break;
         case ActionExit:
         case ActionExit:
             action = upython_confirm_exit_action() ? ActionTerm : ActionNone;
             action = upython_confirm_exit_action() ? ActionTerm : ActionNone;

+ 2 - 1
upython.h

@@ -15,8 +15,9 @@ typedef enum {
     ActionTerm
     ActionTerm
 } Action;
 } Action;
 
 
-extern Action action;
 extern FuriString* file_path;
 extern FuriString* file_path;
+extern volatile Action action;
+extern volatile FuriThreadStdoutWriteCallback stdout_callback;
 
 
 void upython_reset_file_path();
 void upython_reset_file_path();
 
 

+ 21 - 0
upython_cli.c

@@ -1,7 +1,14 @@
+#include <furi.h>
 #include <storage/storage.h>
 #include <storage/storage.h>
 
 
 #include "upython.h"
 #include "upython.h"
 
 
+static FuriStreamBuffer* stdout_buffer = NULL;
+
+static void write_to_stdout_buffer(const char* data, size_t size) {
+    furi_stream_buffer_send(stdout_buffer, data, size, 0);
+}
+
 void upython_cli(Cli* cli, FuriString* args, void* ctx) {
 void upython_cli(Cli* cli, FuriString* args, void* ctx) {
     UNUSED(ctx);
     UNUSED(ctx);
 
 
@@ -20,7 +27,21 @@ void upython_cli(Cli* cli, FuriString* args, void* ctx) {
     } else {
     } else {
         furi_string_set(file_path, args);
         furi_string_set(file_path, args);
 
 
+        stdout_buffer = furi_stream_buffer_alloc(128, 1);
+
+        stdout_callback = write_to_stdout_buffer;
+
         action = ActionExec;
         action = ActionExec;
+
+        char data = '\0';
+
+        while(action == ActionExec || !furi_stream_buffer_is_empty(stdout_buffer)) {
+            if(furi_stream_buffer_receive(stdout_buffer, &data, 1, 0) > 0) {
+                printf("%c", data);
+            }
+        }
+
+        furi_stream_buffer_free(stdout_buffer);
     }
     }
 }
 }