Scripting: added 'dirsel' command

fixes #287
This commit is contained in:
d0k3 2018-01-09 01:39:37 +01:00
parent 9bdd6a516f
commit 7befb8f1b5
8 changed files with 44 additions and 17 deletions

View File

@ -117,7 +117,7 @@ bool GetDirContentsWorker(DirStruct* contents, char* fpath, int fnsize, const ch
if (fvx_opendir(&pdir, fpath) != FR_OK) if (fvx_opendir(&pdir, fpath) != FR_OK)
return false; return false;
(fname++)[0] = '/'; if (*(fname-1) != '/') *(fname++) = '/';
while (fvx_readdir(&pdir, &fno) == FR_OK) { while (fvx_readdir(&pdir, &fno) == FR_OK) {
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0)) if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))

View File

@ -719,11 +719,16 @@ bool PathAttr(const char* path, u8 attr, u8 mask) {
return (f_chmod(path, attr, mask) == FR_OK); return (f_chmod(path, attr, mask) == FR_OK);
} }
bool FileSelector(char* result, const char* text, const char* path, const char* pattern, bool hide_ext, bool no_dirs) { bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags) {
DirStruct* contents = (DirStruct*) (void*) TEMP_BUFFER; DirStruct* contents = (DirStruct*) (void*) TEMP_BUFFER;
char path_local[256]; char path_local[256];
strncpy(path_local, path, 256); strncpy(path_local, path, 256);
bool no_dirs = flags & NO_DIRS;
bool no_files = flags & NO_FILES;
bool hide_ext = flags & HIDE_EXT;
bool select_dirs = flags & SELECT_DIRS;
// main loop // main loop
while (true) { while (true) {
u32 n_found = 0; u32 n_found = 0;
@ -737,7 +742,7 @@ bool FileSelector(char* result, const char* text, const char* path, const char*
for (; pos < contents->n_entries; pos++) { for (; pos < contents->n_entries; pos++) {
DirEntry* entry = &(contents->entry[pos]); DirEntry* entry = &(contents->entry[pos]);
if (((entry->type == T_DIR) && no_dirs) || if (((entry->type == T_DIR) && no_dirs) ||
((entry->type == T_FILE) && (fvx_match_name(entry->name, pattern) != FR_OK)) || ((entry->type == T_FILE) && (no_files || (fvx_match_name(entry->name, pattern) != FR_OK))) ||
(entry->type == T_DOTDOT) || (strncmp(entry->name, "._", 2) == 0)) (entry->type == T_DOTDOT) || (strncmp(entry->name, "._", 2) == 0))
continue; continue;
if (n_opt == _MAX_FS_OPT) { if (n_opt == _MAX_FS_OPT) {
@ -765,8 +770,12 @@ bool FileSelector(char* result, const char* text, const char* path, const char*
if (!user_select) return false; if (!user_select) return false;
DirEntry* res_local = res_entry[user_select-1]; DirEntry* res_local = res_entry[user_select-1];
if (res_local && (res_local->type == T_DIR)) { // selected dir if (res_local && (res_local->type == T_DIR)) { // selected dir
if (FileSelector(result, text, res_local->path, pattern, hide_ext, no_dirs)) if (select_dirs) {
strncpy(result, res_local->path, 256);
return true; return true;
} else if (FileSelector(result, text, res_local->path, pattern, flags)) {
return true;
}
break; break;
} else if (res_local && (res_local->type == T_FILE)) { // selected file } else if (res_local && (res_local->type == T_FILE)) { // selected file
strncpy(result, res_local->path, 256); strncpy(result, res_local->path, 256);

View File

@ -13,6 +13,13 @@
#define SKIP_ALL (1UL<<7) #define SKIP_ALL (1UL<<7)
#define OVERWRITE_ALL (1UL<<8) #define OVERWRITE_ALL (1UL<<8)
// file selector flags
#define NO_DIRS (1UL<<0)
#define NO_FILES (1UL<<1)
#define HIDE_EXT (1UL<<2)
#define SELECT_DIRS (1UL<<3)
/** Return total size of SD card **/ /** Return total size of SD card **/
uint64_t GetSDCardSize(); uint64_t GetSDCardSize();
@ -77,7 +84,7 @@ bool PathRename(const char* path, const char* newname);
bool PathAttr(const char* path, u8 attr, u8 mask); bool PathAttr(const char* path, u8 attr, u8 mask);
/** Select a file **/ /** Select a file **/
bool FileSelector(char* result, const char* text, const char* path, const char* pattern, bool hide_ext, bool no_dirs); bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags);
/** Create a screenshot of the current framebuffer **/ /** Create a screenshot of the current framebuffer **/
void CreateScreenshot(); void CreateScreenshot();

View File

@ -67,9 +67,9 @@ bool CheckSupportDir(const char* dname)
return GetSupportDir(path, dname); return GetSupportDir(path, dname);
} }
bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern, bool hide_ext, bool no_dirs) bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern)
{ {
char path[256]; char path[256];
if (!GetSupportDir(path, dname)) return false; if (!GetSupportDir(path, dname)) return false;
return FileSelector(result, text, path, pattern, hide_ext, no_dirs); return FileSelector(result, text, path, pattern, HIDE_EXT);
} }

View File

@ -10,4 +10,4 @@ bool CheckSupportFile(const char* fname);
size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len); size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len);
bool CheckSupportDir(const char* fpath); bool CheckSupportDir(const char* fpath);
bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern, bool hide_ext, bool no_dirs); bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern);

View File

@ -1853,9 +1853,9 @@ u32 GodMode(int entrypoint) {
godmode9 = true; godmode9 = true;
} else if (user_select == 2) { } else if (user_select == 2) {
bootloader = true; bootloader = true;
} else if ((user_select == 3) && (FileSelectorSupport(loadpath, "Bootloader payloads menu.\nSelect payload:", PAYLOADS_DIR, "*.firm", true, false))) { } else if ((user_select == 3) && (FileSelectorSupport(loadpath, "Bootloader payloads menu.\nSelect payload:", PAYLOADS_DIR, "*.firm"))) {
BootFirmHandler(loadpath, false, false); BootFirmHandler(loadpath, false, false);
} else if ((user_select == 4) && (FileSelectorSupport(loadpath, "Bootloader scripts menu.\nSelect script:", SCRIPTS_DIR, "*.gm9", true, false))) { } else if ((user_select == 4) && (FileSelectorSupport(loadpath, "Bootloader scripts menu.\nSelect script:", SCRIPTS_DIR, "*.gm9"))) {
ExecuteGM9Script(loadpath); ExecuteGM9Script(loadpath);
} else if (user_select == 5) { } else if (user_select == 5) {
exit_mode = GODMODE_EXIT_POWEROFF; exit_mode = GODMODE_EXIT_POWEROFF;
@ -2252,12 +2252,12 @@ u32 GodMode(int entrypoint) {
(user_select != poweroff) && (user_select != reboot)) { (user_select != poweroff) && (user_select != reboot)) {
char loadpath[256]; char loadpath[256];
if ((user_select == more) && (HomeMoreMenu(current_path) == 0)) break; // more... menu if ((user_select == more) && (HomeMoreMenu(current_path) == 0)) break; // more... menu
else if ((user_select == scripts) && (FileSelectorSupport(loadpath, "HOME scripts... menu.\nSelect script:", SCRIPTS_DIR, "*.gm9", true, false))) { else if ((user_select == scripts) && (FileSelectorSupport(loadpath, "HOME scripts... menu.\nSelect script:", SCRIPTS_DIR, "*.gm9"))) {
ExecuteGM9Script(loadpath); ExecuteGM9Script(loadpath);
GetDirContents(current_dir, current_path); GetDirContents(current_dir, current_path);
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
break; break;
} else if ((user_select == payloads) && (FileSelectorSupport(loadpath, "HOME payloads... menu.\nSelect payload:", PAYLOADS_DIR, "*.firm", true, false))) { } else if ((user_select == payloads) && (FileSelectorSupport(loadpath, "HOME payloads... menu.\nSelect payload:", PAYLOADS_DIR, "*.firm"))) {
BootFirmHandler(loadpath, false, false); BootFirmHandler(loadpath, false, false);
} }
} }
@ -2326,7 +2326,7 @@ u32 ScriptRunner(int entrypoint) {
ExecuteGM9Script(NULL); ExecuteGM9Script(NULL);
} else if (PathExist("V:/" VRAM0_SCRIPTS)) { } else if (PathExist("V:/" VRAM0_SCRIPTS)) {
char loadpath[256]; char loadpath[256];
if (FileSelector(loadpath, FLAVOR " scripts menu.\nSelect script:", "V:/" VRAM0_SCRIPTS, "*.gm9", true, false)) if (FileSelector(loadpath, FLAVOR " scripts menu.\nSelect script:", "V:/" VRAM0_SCRIPTS, "*.gm9", HIDE_EXT))
ExecuteGM9Script(loadpath); ExecuteGM9Script(loadpath);
} else ShowPrompt(false, "Compiled as script autorunner\nbut no script provided.\n \nDerp!"); } else ShowPrompt(false, "Compiled as script autorunner\nbut no script provided.\n \nDerp!");

View File

@ -70,6 +70,7 @@ typedef enum {
CMD_ID_ASK, CMD_ID_ASK,
CMD_ID_INPUT, CMD_ID_INPUT,
CMD_ID_FILESEL, CMD_ID_FILESEL,
CMD_ID_DIRSEL,
CMD_ID_SET, CMD_ID_SET,
CMD_ID_STRSPLIT, CMD_ID_STRSPLIT,
CMD_ID_STRREP, CMD_ID_STRREP,
@ -127,6 +128,7 @@ Gm9ScriptCmd cmd_list[] = {
{ CMD_ID_ASK , "ask" , 1, 0 }, { CMD_ID_ASK , "ask" , 1, 0 },
{ CMD_ID_INPUT , "input" , 2, 0 }, { CMD_ID_INPUT , "input" , 2, 0 },
{ CMD_ID_FILESEL , "filesel" , 3, _FLG('d') }, { CMD_ID_FILESEL , "filesel" , 3, _FLG('d') },
{ CMD_ID_DIRSEL , "dirsel" , 3, 0 },
{ CMD_ID_SET , "set" , 2, 0 }, { CMD_ID_SET , "set" , 2, 0 },
{ CMD_ID_STRSPLIT, "strsplit", 3, _FLG('b') | _FLG('f')}, { CMD_ID_STRSPLIT, "strsplit", 3, _FLG('b') | _FLG('f')},
{ CMD_ID_STRREP , "strrep" , 3, 0 }, { CMD_ID_STRREP , "strrep" , 3, 0 },
@ -815,7 +817,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail");
} }
} }
else if (id == CMD_ID_FILESEL) { else if ((id == CMD_ID_FILESEL) || (id == CMD_ID_DIRSEL)) {
char choice[_VAR_CNT_LEN] = { 0 }; char choice[_VAR_CNT_LEN] = { 0 };
char* var = get_var(argv[2], NULL); char* var = get_var(argv[2], NULL);
strncpy(choice, var, _VAR_CNT_LEN); strncpy(choice, var, _VAR_CNT_LEN);
@ -829,10 +831,14 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
} else if (!npattern) { } else if (!npattern) {
ret = false; ret = false;
if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid path"); if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid path");
} else { } else if (id == CMD_ID_FILESEL) {
u32 flags_ext = (flags & _FLG('d')) ? 0 : NO_DIRS;
*(npattern++) = '\0'; *(npattern++) = '\0';
ret = FileSelector(choice, argv[0], path, npattern, false, !(flags & _FLG('d'))); ret = FileSelector(choice, argv[0], path, npattern, flags_ext);
if (err_str) snprintf(err_str, _ERR_STR_LEN, "fileselect abort"); if (err_str) snprintf(err_str, _ERR_STR_LEN, "fileselect abort");
} else {
ret = FileSelector(choice, argv[0], path, npattern, NO_FILES | SELECT_DIRS);
if (err_str) snprintf(err_str, _ERR_STR_LEN, "dirselect abort");
} }
if (ret) { if (ret) {

View File

@ -107,7 +107,12 @@ echo $[TESTREP]
# The path is stored inside a variable, and the selection can be limited via wildcards # The path is stored inside a variable, and the selection can be limited via wildcards
# -d / --include_dirs allows to browse folders and select files inside # -d / --include_dirs allows to browse folders and select files inside
filesel "Please select a file" 0:/*.* SELFILE filesel "Please select a file" 0:/*.* SELFILE
echo "You selected $[SELFILE]\nWe'll do nothing with that :)."
# 'dirsel' COMMAND
# The 'dirsel' command works identically to the 'filesel' command, but allows selecting a dir
# Note that a final slash ('/') and no wildcard pattern is expected here.
dirsel "Now, select a dir" 0:/ SELDIR
echo "You selected $[SELFILE]\nand $[SELDIR]\nWe'll do nothing with either :)."
# 'allow' COMMAND # 'allow' COMMAND
# typically used at the beginning of a script, prompts to allow writes to the location given in the argument # typically used at the beginning of a script, prompts to allow writes to the location given in the argument