Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
		
						commit
						f3904dc5a4
					
				| @ -241,13 +241,13 @@ distenv.PhonyTarget( | |||||||
| distenv.PhonyTarget( | distenv.PhonyTarget( | ||||||
|     "lint", |     "lint", | ||||||
|     "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}", |     "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}", | ||||||
|     LINT_SOURCES=firmware_env["LINT_SOURCES"], |     LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| distenv.PhonyTarget( | distenv.PhonyTarget( | ||||||
|     "format", |     "format", | ||||||
|     "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}", |     "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}", | ||||||
|     LINT_SOURCES=firmware_env["LINT_SOURCES"], |     LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| # PY_LINT_SOURCES contains recursively-built modules' SConscript files + application manifests | # PY_LINT_SOURCES contains recursively-built modules' SConscript files + application manifests | ||||||
|  | |||||||
| @ -133,7 +133,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { | |||||||
|         case ArchiveBrowserEventFileMenuRename: |         case ArchiveBrowserEventFileMenuRename: | ||||||
|             if(favorites) { |             if(favorites) { | ||||||
|                 browser->callback(ArchiveBrowserEventEnterFavMove, browser->context); |                 browser->callback(ArchiveBrowserEventEnterFavMove, browser->context); | ||||||
|             } else if((archive_is_known_app(selected->type)) && (selected->is_app == false)) { |             } else if(selected->is_app == false) { | ||||||
|                 archive_show_file_menu(browser, false); |                 archive_show_file_menu(browser, false); | ||||||
|                 scene_manager_set_scene_state( |                 scene_manager_set_scene_state( | ||||||
|                     archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH); |                     archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH); | ||||||
|  | |||||||
| @ -57,9 +57,11 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { | |||||||
|             ArchiveFile_t* file = archive_get_current_file(archive->browser); |             ArchiveFile_t* file = archive_get_current_file(archive->browser); | ||||||
| 
 | 
 | ||||||
|             FuriString* path_dst; |             FuriString* path_dst; | ||||||
|  | 
 | ||||||
|             path_dst = furi_string_alloc(); |             path_dst = furi_string_alloc(); | ||||||
|             path_extract_dirname(path_src, path_dst); |             path_extract_dirname(path_src, path_dst); | ||||||
|             furi_string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); |             furi_string_cat_printf( | ||||||
|  |                 path_dst, "/%s%s", archive->text_store, archive->file_extension); | ||||||
| 
 | 
 | ||||||
|             storage_common_rename(fs_api, path_src, furi_string_get_cstr(path_dst)); |             storage_common_rename(fs_api, path_src, furi_string_get_cstr(path_dst)); | ||||||
|             furi_record_close(RECORD_STORAGE); |             furi_record_close(RECORD_STORAGE); | ||||||
|  | |||||||
| @ -65,7 +65,6 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { | |||||||
|     if(!archive_is_known_app(selected->type)) { |     if(!archive_is_known_app(selected->type)) { | ||||||
|         furi_string_set(menu[0], "---"); |         furi_string_set(menu[0], "---"); | ||||||
|         furi_string_set(menu[1], "---"); |         furi_string_set(menu[1], "---"); | ||||||
|         furi_string_set(menu[2], "---"); |  | ||||||
|     } else { |     } else { | ||||||
|         if(model->tab_idx == ArchiveTabFavorites) { |         if(model->tab_idx == ArchiveTabFavorites) { | ||||||
|             furi_string_set(menu[2], "Move"); |             furi_string_set(menu[2], "Move"); | ||||||
|  | |||||||
| @ -237,12 +237,8 @@ static int32_t | |||||||
|     const char* line_tmp = furi_string_get_cstr(line); |     const char* line_tmp = furi_string_get_cstr(line); | ||||||
|     bool state = false; |     bool state = false; | ||||||
| 
 | 
 | ||||||
|     for(uint32_t i = 0; i < line_len; i++) { |     if(line_len == 0) { | ||||||
|         if((line_tmp[i] != ' ') && (line_tmp[i] != '\t') && (line_tmp[i] != '\n')) { |         return SCRIPT_STATE_NEXT_LINE; // Skip empty lines
 | ||||||
|             line_tmp = &line_tmp[i]; |  | ||||||
|             break; // Skip spaces and tabs
 |  | ||||||
|         } |  | ||||||
|         if(i == line_len - 1) return SCRIPT_STATE_NEXT_LINE; // Skip empty lines
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     FURI_LOG_D(WORKER_TAG, "line:%s", line_tmp); |     FURI_LOG_D(WORKER_TAG, "line:%s", line_tmp); | ||||||
| @ -450,10 +446,12 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil | |||||||
|                 bad_usb->st.line_cur++; |                 bad_usb->st.line_cur++; | ||||||
|                 bad_usb->buf_len = bad_usb->buf_len + bad_usb->buf_start - (i + 1); |                 bad_usb->buf_len = bad_usb->buf_len + bad_usb->buf_start - (i + 1); | ||||||
|                 bad_usb->buf_start = i + 1; |                 bad_usb->buf_start = i + 1; | ||||||
|  |                 furi_string_trim(bad_usb->line); | ||||||
|                 delay_val = ducky_parse_line( |                 delay_val = ducky_parse_line( | ||||||
|                     bad_usb, bad_usb->line, bad_usb->st.error, sizeof(bad_usb->st.error)); |                     bad_usb, bad_usb->line, bad_usb->st.error, sizeof(bad_usb->st.error)); | ||||||
| 
 |                 if(delay_val == SCRIPT_STATE_NEXT_LINE) { // Empty line
 | ||||||
|                 if(delay_val < 0) { |                     return 0; | ||||||
|  |                 } else if(delay_val < 0) { | ||||||
|                     bad_usb->st.error_line = bad_usb->st.line_cur; |                     bad_usb->st.error_line = bad_usb->st.line_cur; | ||||||
|                     FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur); |                     FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur); | ||||||
|                     return SCRIPT_STATE_ERROR; |                     return SCRIPT_STATE_ERROR; | ||||||
|  | |||||||
| @ -39,10 +39,5 @@ void ibutton_scene_delete_success_on_exit(void* context) { | |||||||
|     iButton* ibutton = context; |     iButton* ibutton = context; | ||||||
|     Popup* popup = ibutton->popup; |     Popup* popup = ibutton->popup; | ||||||
| 
 | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_reset(popup); | ||||||
|     popup_set_icon(popup, 0, 0, NULL); |  | ||||||
| 
 |  | ||||||
|     popup_disable_timeout(popup); |  | ||||||
|     popup_set_context(popup, NULL); |  | ||||||
|     popup_set_callback(popup, NULL); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -39,10 +39,5 @@ void ibutton_scene_save_success_on_exit(void* context) { | |||||||
|     iButton* ibutton = context; |     iButton* ibutton = context; | ||||||
|     Popup* popup = ibutton->popup; |     Popup* popup = ibutton->popup; | ||||||
| 
 | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_reset(popup); | ||||||
|     popup_set_icon(popup, 0, 0, NULL); |  | ||||||
| 
 |  | ||||||
|     popup_disable_timeout(popup); |  | ||||||
|     popup_set_context(popup, NULL); |  | ||||||
|     popup_set_callback(popup, NULL); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -43,10 +43,5 @@ void ibutton_scene_write_success_on_exit(void* context) { | |||||||
|     iButton* ibutton = context; |     iButton* ibutton = context; | ||||||
|     Popup* popup = ibutton->popup; |     Popup* popup = ibutton->popup; | ||||||
| 
 | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_reset(popup); | ||||||
|     popup_set_icon(popup, 0, 0, NULL); |  | ||||||
| 
 |  | ||||||
|     popup_disable_timeout(popup); |  | ||||||
|     popup_set_context(popup, NULL); |  | ||||||
|     popup_set_callback(popup, NULL); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -44,14 +44,7 @@ bool subghz_scene_delete_success_on_event(void* context, SceneManagerEvent event | |||||||
| 
 | 
 | ||||||
| void subghz_scene_delete_success_on_exit(void* context) { | void subghz_scene_delete_success_on_exit(void* context) { | ||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
| 
 |  | ||||||
|     // Clear view
 |  | ||||||
|     Popup* popup = subghz->popup; |     Popup* popup = subghz->popup; | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_reset(popup); | ||||||
|     popup_set_icon(popup, 0, 0, NULL); |  | ||||||
|     popup_set_callback(popup, NULL); |  | ||||||
|     popup_set_context(popup, NULL); |  | ||||||
|     popup_set_timeout(popup, 0); |  | ||||||
|     popup_disable_timeout(popup); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -44,14 +44,7 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) | |||||||
| 
 | 
 | ||||||
| void subghz_scene_save_success_on_exit(void* context) { | void subghz_scene_save_success_on_exit(void* context) { | ||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
| 
 |  | ||||||
|     // Clear view
 |  | ||||||
|     Popup* popup = subghz->popup; |     Popup* popup = subghz->popup; | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_reset(popup); | ||||||
|     popup_set_icon(popup, 0, 0, NULL); |  | ||||||
|     popup_set_callback(popup, NULL); |  | ||||||
|     popup_set_context(popup, NULL); |  | ||||||
|     popup_set_timeout(popup, 0); |  | ||||||
|     popup_disable_timeout(popup); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -36,16 +36,10 @@ bool subghz_scene_show_error_sub_on_event(void* context, SceneManagerEvent event | |||||||
| 
 | 
 | ||||||
| void subghz_scene_show_error_sub_on_exit(void* context) { | void subghz_scene_show_error_sub_on_exit(void* context) { | ||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
| 
 |  | ||||||
|     // Clear view
 |  | ||||||
|     Popup* popup = subghz->popup; |     Popup* popup = subghz->popup; | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_reset(popup); | ||||||
|     popup_set_icon(popup, 0, 0, NULL); | 
 | ||||||
|     popup_set_callback(popup, NULL); |  | ||||||
|     popup_set_context(popup, NULL); |  | ||||||
|     popup_set_timeout(popup, 0); |  | ||||||
|     popup_disable_timeout(popup); |  | ||||||
|     furi_string_reset(subghz->error_str); |     furi_string_reset(subghz->error_str); | ||||||
| 
 | 
 | ||||||
|     notification_message(subghz->notifications, &sequence_reset_rgb); |     notification_message(subghz->notifications, &sequence_reset_rgb); | ||||||
|  | |||||||
| @ -43,14 +43,7 @@ bool subghz_scene_show_only_rx_on_event(void* context, SceneManagerEvent event) | |||||||
| 
 | 
 | ||||||
| void subghz_scene_show_only_rx_on_exit(void* context) { | void subghz_scene_show_only_rx_on_exit(void* context) { | ||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
| 
 |  | ||||||
|     // Clear view
 |  | ||||||
|     Popup* popup = subghz->popup; |     Popup* popup = subghz->popup; | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_reset(popup); | ||||||
|     popup_set_icon(popup, 0, 0, NULL); |  | ||||||
|     popup_set_callback(popup, NULL); |  | ||||||
|     popup_set_context(popup, NULL); |  | ||||||
|     popup_set_timeout(popup, 0); |  | ||||||
|     popup_disable_timeout(popup); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ | |||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <notification/notification_messages.h> | #include <notification/notification_messages.h> | ||||||
| #include <loader/loader.h> | #include <loader/loader.h> | ||||||
|  | #include <lib/toolbox/args.h> | ||||||
| 
 | 
 | ||||||
| // Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'`
 | // Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'`
 | ||||||
| #define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d" | #define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d" | ||||||
| @ -192,6 +193,83 @@ void cli_command_log(Cli* cli, FuriString* args, void* context) { | |||||||
|     furi_stream_buffer_free(ring); |     furi_stream_buffer_free(ring); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void cli_command_sysctl_debug(Cli* cli, FuriString* args, void* context) { | ||||||
|  |     UNUSED(cli); | ||||||
|  |     UNUSED(context); | ||||||
|  |     if(!furi_string_cmp(args, "0")) { | ||||||
|  |         furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); | ||||||
|  |         loader_update_menu(); | ||||||
|  |         printf("Debug disabled."); | ||||||
|  |     } else if(!furi_string_cmp(args, "1")) { | ||||||
|  |         furi_hal_rtc_set_flag(FuriHalRtcFlagDebug); | ||||||
|  |         loader_update_menu(); | ||||||
|  |         printf("Debug enabled."); | ||||||
|  |     } else { | ||||||
|  |         cli_print_usage("sysctl debug", "<1|0>", furi_string_get_cstr(args)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void cli_command_sysctl_heap_track(Cli* cli, FuriString* args, void* context) { | ||||||
|  |     UNUSED(cli); | ||||||
|  |     UNUSED(context); | ||||||
|  |     if(!furi_string_cmp(args, "none")) { | ||||||
|  |         furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackModeNone); | ||||||
|  |         printf("Heap tracking disabled"); | ||||||
|  |     } else if(!furi_string_cmp(args, "main")) { | ||||||
|  |         furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackModeMain); | ||||||
|  |         printf("Heap tracking enabled for application main thread"); | ||||||
|  | #if FURI_DEBUG | ||||||
|  |     } else if(!furi_string_cmp(args, "tree")) { | ||||||
|  |         furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackModeTree); | ||||||
|  |         printf("Heap tracking enabled for application main and child threads"); | ||||||
|  |     } else if(!furi_string_cmp(args, "all")) { | ||||||
|  |         furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackModeAll); | ||||||
|  |         printf("Heap tracking enabled for all threads"); | ||||||
|  | #endif | ||||||
|  |     } else { | ||||||
|  |         cli_print_usage("sysctl heap_track", "<none|main|tree|all>", furi_string_get_cstr(args)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void cli_command_sysctl_print_usage() { | ||||||
|  |     printf("Usage:\r\n"); | ||||||
|  |     printf("sysctl <cmd> <args>\r\n"); | ||||||
|  |     printf("Cmd list:\r\n"); | ||||||
|  | 
 | ||||||
|  |     printf("\tdebug <0|1>\t - Enable or disable system debug\r\n"); | ||||||
|  | #if FURI_DEBUG | ||||||
|  |     printf("\theap_track <none|main|tree|all>\t - Set heap allocation tracking mode\r\n"); | ||||||
|  | #else | ||||||
|  |     printf("\theap_track <none|main>\t - Set heap allocation tracking mode\r\n"); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void cli_command_sysctl(Cli* cli, FuriString* args, void* context) { | ||||||
|  |     FuriString* cmd; | ||||||
|  |     cmd = furi_string_alloc(); | ||||||
|  | 
 | ||||||
|  |     do { | ||||||
|  |         if(!args_read_string_and_trim(args, cmd)) { | ||||||
|  |             cli_command_sysctl_print_usage(); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(furi_string_cmp_str(cmd, "debug") == 0) { | ||||||
|  |             cli_command_sysctl_debug(cli, args, context); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(furi_string_cmp_str(cmd, "heap_track") == 0) { | ||||||
|  |             cli_command_sysctl_heap_track(cli, args, context); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         cli_command_sysctl_print_usage(); | ||||||
|  |     } while(false); | ||||||
|  | 
 | ||||||
|  |     furi_string_free(cmd); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void cli_command_vibro(Cli* cli, FuriString* args, void* context) { | void cli_command_vibro(Cli* cli, FuriString* args, void* context) { | ||||||
|     UNUSED(cli); |     UNUSED(cli); | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
| @ -208,22 +286,6 @@ void cli_command_vibro(Cli* cli, FuriString* args, void* context) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cli_command_debug(Cli* cli, FuriString* args, void* context) { |  | ||||||
|     UNUSED(cli); |  | ||||||
|     UNUSED(context); |  | ||||||
|     if(!furi_string_cmp(args, "0")) { |  | ||||||
|         furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); |  | ||||||
|         loader_update_menu(); |  | ||||||
|         printf("Debug disabled."); |  | ||||||
|     } else if(!furi_string_cmp(args, "1")) { |  | ||||||
|         furi_hal_rtc_set_flag(FuriHalRtcFlagDebug); |  | ||||||
|         loader_update_menu(); |  | ||||||
|         printf("Debug enabled."); |  | ||||||
|     } else { |  | ||||||
|         cli_print_usage("debug", "<1|0>", furi_string_get_cstr(args)); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void cli_command_led(Cli* cli, FuriString* args, void* context) { | void cli_command_led(Cli* cli, FuriString* args, void* context) { | ||||||
|     UNUSED(cli); |     UNUSED(cli); | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
| @ -356,7 +418,7 @@ void cli_commands_init(Cli* cli) { | |||||||
| 
 | 
 | ||||||
|     cli_add_command(cli, "date", CliCommandFlagParallelSafe, cli_command_date, NULL); |     cli_add_command(cli, "date", CliCommandFlagParallelSafe, cli_command_date, NULL); | ||||||
|     cli_add_command(cli, "log", CliCommandFlagParallelSafe, cli_command_log, NULL); |     cli_add_command(cli, "log", CliCommandFlagParallelSafe, cli_command_log, NULL); | ||||||
|     cli_add_command(cli, "debug", CliCommandFlagDefault, cli_command_debug, NULL); |     cli_add_command(cli, "sysctl", CliCommandFlagDefault, cli_command_sysctl, NULL); | ||||||
|     cli_add_command(cli, "ps", CliCommandFlagParallelSafe, cli_command_ps, NULL); |     cli_add_command(cli, "ps", CliCommandFlagParallelSafe, cli_command_ps, NULL); | ||||||
|     cli_add_command(cli, "free", CliCommandFlagParallelSafe, cli_command_free, NULL); |     cli_add_command(cli, "free", CliCommandFlagParallelSafe, cli_command_free, NULL); | ||||||
|     cli_add_command(cli, "free_blocks", CliCommandFlagParallelSafe, cli_command_free_blocks, NULL); |     cli_add_command(cli, "free_blocks", CliCommandFlagParallelSafe, cli_command_free_blocks, NULL); | ||||||
|  | |||||||
| @ -45,6 +45,13 @@ static void desktop_switch_to_app(Desktop* desktop, const FlipperApplication* fl | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode(); | ||||||
|  |     if(mode > FuriHalRtcHeapTrackModeNone) { | ||||||
|  |         furi_thread_enable_heap_trace(desktop->scene_thread); | ||||||
|  |     } else { | ||||||
|  |         furi_thread_disable_heap_trace(desktop->scene_thread); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     furi_thread_set_name(desktop->scene_thread, flipper_app->name); |     furi_thread_set_name(desktop->scene_thread, flipper_app->name); | ||||||
|     furi_thread_set_stack_size(desktop->scene_thread, flipper_app->stack_size); |     furi_thread_set_stack_size(desktop->scene_thread, flipper_app->stack_size); | ||||||
|     furi_thread_set_callback(desktop->scene_thread, flipper_app->app); |     furi_thread_set_callback(desktop->scene_thread, flipper_app->app); | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| #include "input_i.h" | #include "input_i.h" | ||||||
| 
 | 
 | ||||||
|  | // #define INPUT_DEBUG
 | ||||||
|  | 
 | ||||||
| #define GPIO_Read(input_pin) (furi_hal_gpio_read(input_pin.pin->gpio) ^ (input_pin.pin->inverted)) | #define GPIO_Read(input_pin) (furi_hal_gpio_read(input_pin.pin->gpio) ^ (input_pin.pin->inverted)) | ||||||
| 
 | 
 | ||||||
| static Input* input = NULL; | static Input* input = NULL; | ||||||
| @ -72,6 +74,10 @@ int32_t input_srv(void* p) { | |||||||
|     input->event_pubsub = furi_pubsub_alloc(); |     input->event_pubsub = furi_pubsub_alloc(); | ||||||
|     furi_record_create(RECORD_INPUT_EVENTS, input->event_pubsub); |     furi_record_create(RECORD_INPUT_EVENTS, input->event_pubsub); | ||||||
| 
 | 
 | ||||||
|  | #if INPUT_DEBUG | ||||||
|  |     furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #ifdef SRV_CLI | #ifdef SRV_CLI | ||||||
|     input->cli = furi_record_open(RECORD_CLI); |     input->cli = furi_record_open(RECORD_CLI); | ||||||
|     if(input->cli) { |     if(input->cli) { | ||||||
| @ -95,10 +101,16 @@ int32_t input_srv(void* p) { | |||||||
|         bool is_changing = false; |         bool is_changing = false; | ||||||
|         for(size_t i = 0; i < input_pins_count; i++) { |         for(size_t i = 0; i < input_pins_count; i++) { | ||||||
|             bool state = GPIO_Read(input->pin_states[i]); |             bool state = GPIO_Read(input->pin_states[i]); | ||||||
|  |             if(state) { | ||||||
|  |                 if(input->pin_states[i].debounce < INPUT_DEBOUNCE_TICKS) | ||||||
|  |                     input->pin_states[i].debounce += 1; | ||||||
|  |             } else { | ||||||
|  |                 if(input->pin_states[i].debounce > 0) input->pin_states[i].debounce -= 1; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if(input->pin_states[i].debounce > 0 && |             if(input->pin_states[i].debounce > 0 && | ||||||
|                input->pin_states[i].debounce < INPUT_DEBOUNCE_TICKS) { |                input->pin_states[i].debounce < INPUT_DEBOUNCE_TICKS) { | ||||||
|                 is_changing = true; |                 is_changing = true; | ||||||
|                 input->pin_states[i].debounce += (state ? 1 : -1); |  | ||||||
|             } else if(input->pin_states[i].state != state) { |             } else if(input->pin_states[i].state != state) { | ||||||
|                 input->pin_states[i].state = state; |                 input->pin_states[i].state = state; | ||||||
| 
 | 
 | ||||||
| @ -129,8 +141,14 @@ int32_t input_srv(void* p) { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if(is_changing) { |         if(is_changing) { | ||||||
|  | #if INPUT_DEBUG | ||||||
|  |             furi_hal_gpio_write(&gpio_ext_pa4, 1); | ||||||
|  | #endif | ||||||
|             furi_delay_tick(1); |             furi_delay_tick(1); | ||||||
|         } else { |         } else { | ||||||
|  | #if INPUT_DEBUG | ||||||
|  |             furi_hal_gpio_write(&gpio_ext_pa4, 0); | ||||||
|  | #endif | ||||||
|             furi_thread_flags_wait(INPUT_THREAD_FLAG_ISR, FuriFlagWaitAny, FuriWaitForever); |             furi_thread_flags_wait(INPUT_THREAD_FLAG_ISR, FuriFlagWaitAny, FuriWaitForever); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -21,6 +21,13 @@ static bool | |||||||
| 
 | 
 | ||||||
|     FURI_LOG_I(TAG, "Starting: %s", loader_instance->application->name); |     FURI_LOG_I(TAG, "Starting: %s", loader_instance->application->name); | ||||||
| 
 | 
 | ||||||
|  |     FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode(); | ||||||
|  |     if(mode > FuriHalRtcHeapTrackModeNone) { | ||||||
|  |         furi_thread_enable_heap_trace(loader_instance->application_thread); | ||||||
|  |     } else { | ||||||
|  |         furi_thread_disable_heap_trace(loader_instance->application_thread); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     furi_thread_set_name(loader_instance->application_thread, loader_instance->application->name); |     furi_thread_set_name(loader_instance->application_thread, loader_instance->application->name); | ||||||
|     furi_thread_set_stack_size( |     furi_thread_set_stack_size( | ||||||
|         loader_instance->application_thread, loader_instance->application->stack_size); |         loader_instance->application_thread, loader_instance->application->stack_size); | ||||||
| @ -306,7 +313,7 @@ static Loader* loader_alloc() { | |||||||
|     Loader* instance = malloc(sizeof(Loader)); |     Loader* instance = malloc(sizeof(Loader)); | ||||||
| 
 | 
 | ||||||
|     instance->application_thread = furi_thread_alloc(); |     instance->application_thread = furi_thread_alloc(); | ||||||
|     furi_thread_enable_heap_trace(instance->application_thread); | 
 | ||||||
|     furi_thread_set_state_context(instance->application_thread, instance); |     furi_thread_set_state_context(instance->application_thread, instance); | ||||||
|     furi_thread_set_state_callback(instance->application_thread, loader_thread_state_callback); |     furi_thread_set_state_callback(instance->application_thread, loader_thread_state_callback); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -45,6 +45,31 @@ static void debug_changed(VariableItem* item) { | |||||||
|     loader_update_menu(); |     loader_update_menu(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const char* const heap_trace_mode_text[] = { | ||||||
|  |     "None", | ||||||
|  |     "Main", | ||||||
|  | #if FURI_DEBUG | ||||||
|  |     "Tree", | ||||||
|  |     "All", | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const uint32_t heap_trace_mode_value[] = { | ||||||
|  |     FuriHalRtcHeapTrackModeNone, | ||||||
|  |     FuriHalRtcHeapTrackModeMain, | ||||||
|  | #if FURI_DEBUG | ||||||
|  |     FuriHalRtcHeapTrackModeTree, | ||||||
|  |     FuriHalRtcHeapTrackModeAll, | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static void heap_trace_mode_changed(VariableItem* item) { | ||||||
|  |     // SystemSettings* app = variable_item_get_context(item);
 | ||||||
|  |     uint8_t index = variable_item_get_current_value_index(item); | ||||||
|  |     variable_item_set_current_value_text(item, heap_trace_mode_text[index]); | ||||||
|  |     furi_hal_rtc_set_heap_track_mode(heap_trace_mode_value[index]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static uint32_t system_settings_exit(void* context) { | static uint32_t system_settings_exit(void* context) { | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
|     return VIEW_NONE; |     return VIEW_NONE; | ||||||
| @ -79,6 +104,18 @@ SystemSettings* system_settings_alloc() { | |||||||
|     variable_item_set_current_value_index(item, value_index); |     variable_item_set_current_value_index(item, value_index); | ||||||
|     variable_item_set_current_value_text(item, debug_text[value_index]); |     variable_item_set_current_value_text(item, debug_text[value_index]); | ||||||
| 
 | 
 | ||||||
|  |     item = variable_item_list_add( | ||||||
|  |         app->var_item_list, | ||||||
|  |         "Heap Trace", | ||||||
|  |         COUNT_OF(heap_trace_mode_text), | ||||||
|  |         heap_trace_mode_changed, | ||||||
|  |         app); | ||||||
|  |     value_index = value_index_uint32( | ||||||
|  |         furi_hal_rtc_get_heap_track_mode(), heap_trace_mode_value, COUNT_OF(heap_trace_mode_text)); | ||||||
|  |     furi_hal_rtc_set_heap_track_mode(heap_trace_mode_value[value_index]); | ||||||
|  |     variable_item_set_current_value_index(item, value_index); | ||||||
|  |     variable_item_set_current_value_text(item, heap_trace_mode_text[value_index]); | ||||||
|  | 
 | ||||||
|     view_set_previous_callback( |     view_set_previous_callback( | ||||||
|         variable_item_list_get_view(app->var_item_list), system_settings_exit); |         variable_item_list_get_view(app->var_item_list), system_settings_exit); | ||||||
|     view_dispatcher_add_view( |     view_dispatcher_add_view( | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ env = ENV.Clone( | |||||||
|     FW_FLAVOR=fw_build_meta["flavor"], |     FW_FLAVOR=fw_build_meta["flavor"], | ||||||
|     LIB_DIST_DIR=fw_build_meta["build_dir"].Dir("lib"), |     LIB_DIST_DIR=fw_build_meta["build_dir"].Dir("lib"), | ||||||
|     LINT_SOURCES=[ |     LINT_SOURCES=[ | ||||||
|         "applications", |         Dir("applications"), | ||||||
|     ], |     ], | ||||||
|     LIBPATH=[ |     LIBPATH=[ | ||||||
|         "${LIB_DIST_DIR}", |         "${LIB_DIST_DIR}", | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| Import("env") | Import("env") | ||||||
| 
 | 
 | ||||||
| env.Append( | env.Append( | ||||||
|     LINT_SOURCES=["firmware"], |     LINT_SOURCES=[Dir(".")], | ||||||
|     SDK_HEADERS=[ |     SDK_HEADERS=[ | ||||||
|         *env.GlobRecursive("*.h", "targets/furi_hal_include", "*_i.h"), |         *env.GlobRecursive("*.h", "targets/furi_hal_include", "*_i.h"), | ||||||
|         *env.GlobRecursive("*.h", "targets/f${TARGET_HW}/furi_hal", "*_i.h"), |         *env.GlobRecursive("*.h", "targets/f${TARGET_HW}/furi_hal", "*_i.h"), | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| entry,status,name,type,params | entry,status,name,type,params | ||||||
| Version,+,7.4,, | Version,+,7.5,, | ||||||
| Header,+,applications/services/bt/bt_service/bt.h,, | Header,+,applications/services/bt/bt_service/bt.h,, | ||||||
| Header,+,applications/services/cli/cli.h,, | Header,+,applications/services/cli/cli.h,, | ||||||
| Header,+,applications/services/cli/cli_vcp.h,, | Header,+,applications/services/cli/cli_vcp.h,, | ||||||
| @ -1260,6 +1260,7 @@ Function,+,furi_hal_rtc_deinit_early,void, | |||||||
| Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode, | Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode, | ||||||
| Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime* | Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime* | ||||||
| Function,+,furi_hal_rtc_get_fault_data,uint32_t, | Function,+,furi_hal_rtc_get_fault_data,uint32_t, | ||||||
|  | Function,+,furi_hal_rtc_get_heap_track_mode,FuriHalRtcHeapTrackMode, | ||||||
| Function,+,furi_hal_rtc_get_log_level,uint8_t, | Function,+,furi_hal_rtc_get_log_level,uint8_t, | ||||||
| Function,+,furi_hal_rtc_get_pin_fails,uint32_t, | Function,+,furi_hal_rtc_get_pin_fails,uint32_t, | ||||||
| Function,+,furi_hal_rtc_get_register,uint32_t,FuriHalRtcRegister | Function,+,furi_hal_rtc_get_register,uint32_t,FuriHalRtcRegister | ||||||
| @ -1272,6 +1273,7 @@ Function,+,furi_hal_rtc_set_boot_mode,void,FuriHalRtcBootMode | |||||||
| Function,+,furi_hal_rtc_set_datetime,void,FuriHalRtcDateTime* | Function,+,furi_hal_rtc_set_datetime,void,FuriHalRtcDateTime* | ||||||
| Function,+,furi_hal_rtc_set_fault_data,void,uint32_t | Function,+,furi_hal_rtc_set_fault_data,void,uint32_t | ||||||
| Function,+,furi_hal_rtc_set_flag,void,FuriHalRtcFlag | Function,+,furi_hal_rtc_set_flag,void,FuriHalRtcFlag | ||||||
|  | Function,+,furi_hal_rtc_set_heap_track_mode,void,FuriHalRtcHeapTrackMode | ||||||
| Function,+,furi_hal_rtc_set_log_level,void,uint8_t | Function,+,furi_hal_rtc_set_log_level,void,uint8_t | ||||||
| Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t | Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t | ||||||
| Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t" | Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t" | ||||||
|  | |||||||
| 
 | 
| @ -10,7 +10,7 @@ extern "C" { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /* Input Related Constants */ | /* Input Related Constants */ | ||||||
| #define INPUT_DEBOUNCE_TICKS 30 | #define INPUT_DEBOUNCE_TICKS 4 | ||||||
| 
 | 
 | ||||||
| /* Input Keys */ | /* Input Keys */ | ||||||
| typedef enum { | typedef enum { | ||||||
|  | |||||||
| @ -30,7 +30,8 @@ typedef struct { | |||||||
|     uint8_t log_reserved : 4; |     uint8_t log_reserved : 4; | ||||||
|     uint8_t flags; |     uint8_t flags; | ||||||
|     uint8_t boot_mode : 4; |     uint8_t boot_mode : 4; | ||||||
|     uint16_t reserved : 12; |     uint8_t heap_track_mode : 2; | ||||||
|  |     uint16_t reserved : 10; | ||||||
| } DeveloperReg; | } DeveloperReg; | ||||||
| 
 | 
 | ||||||
| _Static_assert(sizeof(DeveloperReg) == 4, "DeveloperReg size mismatch"); | _Static_assert(sizeof(DeveloperReg) == 4, "DeveloperReg size mismatch"); | ||||||
| @ -224,6 +225,19 @@ FuriHalRtcBootMode furi_hal_rtc_get_boot_mode() { | |||||||
|     return (FuriHalRtcBootMode)data->boot_mode; |     return (FuriHalRtcBootMode)data->boot_mode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackMode mode) { | ||||||
|  |     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||||
|  |     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||||
|  |     data->heap_track_mode = mode; | ||||||
|  |     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FuriHalRtcHeapTrackMode furi_hal_rtc_get_heap_track_mode() { | ||||||
|  |     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||||
|  |     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||||
|  |     return (FuriHalRtcHeapTrackMode)data->heap_track_mode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) { | void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) { | ||||||
|     furi_assert(datetime); |     furi_assert(datetime); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -39,6 +39,13 @@ typedef enum { | |||||||
|     FuriHalRtcBootModePostUpdate, /**< Boot to Update, post update */ |     FuriHalRtcBootModePostUpdate, /**< Boot to Update, post update */ | ||||||
| } FuriHalRtcBootMode; | } FuriHalRtcBootMode; | ||||||
| 
 | 
 | ||||||
|  | typedef enum { | ||||||
|  |     FuriHalRtcHeapTrackModeNone = 0, /**< Disable allocation tracking */ | ||||||
|  |     FuriHalRtcHeapTrackModeMain, /**< Enable allocation tracking for main application thread */ | ||||||
|  |     FuriHalRtcHeapTrackModeTree, /**< Enable allocation tracking for main and children application threads */ | ||||||
|  |     FuriHalRtcHeapTrackModeAll, /**< Enable allocation tracking for all threads */ | ||||||
|  | } FuriHalRtcHeapTrackMode; | ||||||
|  | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     FuriHalRtcRegisterHeader, /**< RTC structure header */ |     FuriHalRtcRegisterHeader, /**< RTC structure header */ | ||||||
|     FuriHalRtcRegisterSystem, /**< Various system bits */ |     FuriHalRtcRegisterSystem, /**< Various system bits */ | ||||||
| @ -79,6 +86,10 @@ void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode); | |||||||
| 
 | 
 | ||||||
| FuriHalRtcBootMode furi_hal_rtc_get_boot_mode(); | FuriHalRtcBootMode furi_hal_rtc_get_boot_mode(); | ||||||
| 
 | 
 | ||||||
|  | void furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackMode mode); | ||||||
|  | 
 | ||||||
|  | FuriHalRtcHeapTrackMode furi_hal_rtc_get_heap_track_mode(); | ||||||
|  | 
 | ||||||
| void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime); | void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime); | ||||||
| 
 | 
 | ||||||
| void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime); | void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime); | ||||||
|  | |||||||
| @ -2,8 +2,7 @@ Import("env") | |||||||
| 
 | 
 | ||||||
| env.Append( | env.Append( | ||||||
|     LINT_SOURCES=[ |     LINT_SOURCES=[ | ||||||
|         "furi", |         Dir("."), | ||||||
|         "furi/core", |  | ||||||
|     ] |     ] | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -122,9 +122,14 @@ FuriThread* furi_thread_alloc() { | |||||||
|     thread->output.buffer = furi_string_alloc(); |     thread->output.buffer = furi_string_alloc(); | ||||||
|     thread->is_service = false; |     thread->is_service = false; | ||||||
| 
 | 
 | ||||||
|     if(furi_thread_get_current_id()) { |     FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode(); | ||||||
|  |     if(mode == FuriHalRtcHeapTrackModeAll) { | ||||||
|  |         thread->heap_trace_enabled = true; | ||||||
|  |     } else if(mode == FuriHalRtcHeapTrackModeTree && furi_thread_get_current_id()) { | ||||||
|         FuriThread* parent = pvTaskGetThreadLocalStoragePointer(NULL, 0); |         FuriThread* parent = pvTaskGetThreadLocalStoragePointer(NULL, 0); | ||||||
|         if(parent) thread->heap_trace_enabled = parent->heap_trace_enabled; |         if(parent) thread->heap_trace_enabled = parent->heap_trace_enabled; | ||||||
|  |     } else { | ||||||
|  |         thread->heap_trace_enabled = false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return thread; |     return thread; | ||||||
| @ -243,14 +248,12 @@ FuriThreadId furi_thread_get_id(FuriThread* thread) { | |||||||
| void furi_thread_enable_heap_trace(FuriThread* thread) { | void furi_thread_enable_heap_trace(FuriThread* thread) { | ||||||
|     furi_assert(thread); |     furi_assert(thread); | ||||||
|     furi_assert(thread->state == FuriThreadStateStopped); |     furi_assert(thread->state == FuriThreadStateStopped); | ||||||
|     furi_assert(thread->heap_trace_enabled == false); |  | ||||||
|     thread->heap_trace_enabled = true; |     thread->heap_trace_enabled = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_thread_disable_heap_trace(FuriThread* thread) { | void furi_thread_disable_heap_trace(FuriThread* thread) { | ||||||
|     furi_assert(thread); |     furi_assert(thread); | ||||||
|     furi_assert(thread->state == FuriThreadStateStopped); |     furi_assert(thread->state == FuriThreadStateStopped); | ||||||
|     furi_assert(thread->heap_trace_enabled == true); |  | ||||||
|     thread->heap_trace_enabled = false; |     thread->heap_trace_enabled = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,19 +2,19 @@ Import("env") | |||||||
| 
 | 
 | ||||||
| env.Append( | env.Append( | ||||||
|     LINT_SOURCES=[ |     LINT_SOURCES=[ | ||||||
|         "lib/app-scened-template", |         Dir("app-scened-template"), | ||||||
|         "lib/digital_signal", |         Dir("digital_signal"), | ||||||
|         "lib/drivers", |         Dir("drivers"), | ||||||
|         "lib/flipper_format", |         Dir("flipper_format"), | ||||||
|         "lib/infrared", |         Dir("infrared"), | ||||||
|         "lib/nfc", |         Dir("nfc"), | ||||||
|         "lib/one_wire", |         Dir("one_wire"), | ||||||
|         "lib/ST25RFAL002", |         Dir("ST25RFAL002"), | ||||||
|         "lib/subghz", |         Dir("subghz"), | ||||||
|         "lib/toolbox", |         Dir("toolbox"), | ||||||
|         "lib/u8g2", |         Dir("u8g2"), | ||||||
|         "lib/update_util", |         Dir("update_util"), | ||||||
|         "lib/print", |         Dir("print"), | ||||||
|     ], |     ], | ||||||
|     SDK_HEADERS=[ |     SDK_HEADERS=[ | ||||||
|         File("one_wire/one_wire_host_timing.h"), |         File("one_wire/one_wire_host_timing.h"), | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ Import("env") | |||||||
| 
 | 
 | ||||||
| env.Append( | env.Append( | ||||||
|     LINT_SOURCES=[ |     LINT_SOURCES=[ | ||||||
|         "lib/lfrfid", |         Dir("."), | ||||||
|     ], |     ], | ||||||
|     CPPPATH=[ |     CPPPATH=[ | ||||||
|         "#/lib/lfrfid", |         "#/lib/lfrfid", | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ env.Append( | |||||||
|         "#/lib/nfc", |         "#/lib/nfc", | ||||||
|     ], |     ], | ||||||
|     SDK_HEADERS=[ |     SDK_HEADERS=[ | ||||||
|         File("#/lib/nfc/nfc_device.h"), |         File("nfc_device.h"), | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ void path_extract_extension(FuriString* path, char* ext, size_t ext_len_max) { | |||||||
|     size_t dot = furi_string_search_rchar(path, '.'); |     size_t dot = furi_string_search_rchar(path, '.'); | ||||||
|     size_t filename_start = furi_string_search_rchar(path, '/'); |     size_t filename_start = furi_string_search_rchar(path, '/'); | ||||||
| 
 | 
 | ||||||
|     if((dot > 0) && (filename_start < dot)) { |     if((dot != FURI_STRING_FAILURE) && (filename_start < dot)) { | ||||||
|         strlcpy(ext, &(furi_string_get_cstr(path))[dot], ext_len_max); |         strlcpy(ext, &(furi_string_get_cstr(path))[dot], ext_len_max); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -35,11 +35,23 @@ class Main(App): | |||||||
|         ) |         ) | ||||||
|         self.parser_format.set_defaults(func=self.format) |         self.parser_format.set_defaults(func=self.format) | ||||||
| 
 | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def _filter_lint_directories(dirnames: list[str]): | ||||||
|  |         # Skipping 3rd-party code - usually resides in subfolder "lib" | ||||||
|  |         if "lib" in dirnames: | ||||||
|  |             dirnames.remove("lib") | ||||||
|  |         # Skipping hidden folders | ||||||
|  |         for dirname in dirnames.copy(): | ||||||
|  |             if dirname.startswith("."): | ||||||
|  |                 dirnames.remove(dirname) | ||||||
|  | 
 | ||||||
|     def _check_folders(self, folders: list): |     def _check_folders(self, folders: list): | ||||||
|         show_message = False |         show_message = False | ||||||
|         pattern = re.compile(SOURCE_CODE_DIR_PATTERN) |         pattern = re.compile(SOURCE_CODE_DIR_PATTERN) | ||||||
|         for folder in folders: |         for folder in folders: | ||||||
|             for dirpath, dirnames, filenames in os.walk(folder): |             for dirpath, dirnames, filenames in os.walk(folder): | ||||||
|  |                 self._filter_lint_directories(dirnames) | ||||||
|  | 
 | ||||||
|                 for dirname in dirnames: |                 for dirname in dirnames: | ||||||
|                     if not pattern.match(dirname): |                     if not pattern.match(dirname): | ||||||
|                         to_fix = os.path.join(dirpath, dirname) |                         to_fix = os.path.join(dirpath, dirname) | ||||||
| @ -54,9 +66,7 @@ class Main(App): | |||||||
|         output = [] |         output = [] | ||||||
|         for folder in folders: |         for folder in folders: | ||||||
|             for dirpath, dirnames, filenames in os.walk(folder): |             for dirpath, dirnames, filenames in os.walk(folder): | ||||||
|                 # Skipping 3rd-party code - usually resides in subfolder "lib" |                 self._filter_lint_directories(dirnames) | ||||||
|                 if "lib" in dirnames: |  | ||||||
|                     dirnames.remove("lib") |  | ||||||
| 
 | 
 | ||||||
|                 for filename in filenames: |                 for filename in filenames: | ||||||
|                     ext = os.path.splitext(filename.lower())[1] |                     ext = os.path.splitext(filename.lower())[1] | ||||||
|  | |||||||
| @ -1,37 +1,39 @@ | |||||||
| @echo off | @echo off | ||||||
| 
 | 
 | ||||||
| if not [%FBT_ROOT%] == [] ( | if not ["%FBT_ROOT%"] == [""] ( | ||||||
|     goto already_set |     goto already_set | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| set "FBT_ROOT=%~dp0\..\..\" | set "FBT_ROOT=%~dp0\..\..\" | ||||||
| pushd %FBT_ROOT% | pushd "%FBT_ROOT%" | ||||||
| set "FBT_ROOT=%cd%" | set "FBT_ROOT=%cd%" | ||||||
| popd | popd | ||||||
| 
 | 
 | ||||||
| if not [%FBT_NOENV%] == [] ( | if not ["%FBT_NOENV%"] == [""] ( | ||||||
|     exit /b 0 |     exit /b 0 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| set "FLIPPER_TOOLCHAIN_VERSION=19" | set "FLIPPER_TOOLCHAIN_VERSION=19" | ||||||
| 
 | 
 | ||||||
| if [%FBT_TOOLCHAIN_ROOT%] == [] ( | if ["%FBT_TOOLCHAIN_ROOT%"] == [""] ( | ||||||
|     set "FBT_TOOLCHAIN_ROOT=%FBT_ROOT%\toolchain\x86_64-windows" |     set "FBT_TOOLCHAIN_ROOT=%FBT_ROOT%\toolchain\x86_64-windows" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | set "FBT_TOOLCHAIN_VERSION_FILE=%FBT_TOOLCHAIN_ROOT%\VERSION" | ||||||
|  | 
 | ||||||
| if not exist "%FBT_TOOLCHAIN_ROOT%" ( | if not exist "%FBT_TOOLCHAIN_ROOT%" ( | ||||||
|     powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" "%FBT_TOOLCHAIN_ROOT%" |     powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" | ||||||
| ) |  | ||||||
| if not exist "%FBT_TOOLCHAIN_ROOT%\VERSION" ( |  | ||||||
|     powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" "%FBT_TOOLCHAIN_ROOT%" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| set /p REAL_TOOLCHAIN_VERSION=<"%FBT_TOOLCHAIN_ROOT%\VERSION" | if not exist "%FBT_TOOLCHAIN_VERSION_FILE%" ( | ||||||
|  |     powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | set /p REAL_TOOLCHAIN_VERSION=<"%FBT_TOOLCHAIN_VERSION_FILE%" | ||||||
| if not "%REAL_TOOLCHAIN_VERSION%" == "%FLIPPER_TOOLCHAIN_VERSION%" ( | if not "%REAL_TOOLCHAIN_VERSION%" == "%FLIPPER_TOOLCHAIN_VERSION%" ( | ||||||
|     powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" "%FBT_TOOLCHAIN_ROOT%" |     powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| set "HOME=%USERPROFILE%" | set "HOME=%USERPROFILE%" | ||||||
| set "PYTHONHOME=%FBT_TOOLCHAIN_ROOT%\python" | set "PYTHONHOME=%FBT_TOOLCHAIN_ROOT%\python" | ||||||
| set "PYTHONPATH=" | set "PYTHONPATH=" | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aleksandr Kutuzov
						Aleksandr Kutuzov