--- hatari/src/debug/debugui.c 2019/04/09 08:56:50 1.1.1.9 +++ hatari/src/debug/debugui.c 2019/04/09 08:58:05 1.1.1.10 @@ -57,6 +57,9 @@ static char lastResult[10]; /* parse debugger commands from here on init */ static const char *parseFileName; +/* to which directory to change after (potentially recursed) scripts parsing finishes */ +static char *finalDir; + /** * Save/Restore snapshot of debugging session variables @@ -397,6 +400,14 @@ static int DebugUI_SetTracing(int argc, */ static int DebugUI_ChangeDir(int argc, char *argv[]) { + if (argc == 3 && strcmp("-f", argv[2]) == 0) + { + if (finalDir) + free(finalDir); + finalDir = strdup(argv[1]); + fprintf(stderr, "Will switch to '%s' dir after all scripts have finished.\n", argv[1]); + return DEBUGGER_CMDDONE; + } if (argc == 2) { if (chdir(argv[1]) == 0) @@ -807,6 +818,14 @@ static char *DebugUI_GetCommand(char *in return Str_Trim(readline("> ")); } +/** + * Get readlines idea of the terminal size + */ +static void DebugUI_GetScreenSize(int *rows, int *cols) +{ + rl_get_screen_size(rows, cols); +} + #else /* !HAVE_LIBREADLINE */ /** @@ -818,6 +837,21 @@ static void DebugUI_FreeCommand(char *in } /** + * Get number of lines/columns for terminal output + */ +static void DebugUI_GetScreenSize(int *rows, int *cols) +{ + const char *p; + + *rows = 24; + *cols = 80; + if ((p = getenv("LINES")) != NULL) + *rows = (int)strtol(p, NULL, 0); + if ((p = getenv("COLUMS")) != NULL) + *cols = (int)strtol(p, NULL, 0); +} + +/** * Read a command line from the keyboard and return a pointer to the string. * Only string returned by this function can be given for it as argument! * @return Pointer to the string which should be given back to this @@ -843,6 +877,29 @@ static char *DebugUI_GetCommand(char *in #endif /* !HAVE_LIBREADLINE */ +/** + * How many lines to "page" when user invokes calling command. + * + * If config value is >=0, use that. If it's negative, get number of lines + * from screensize. If even that's not defined, fall back to default value. + * + * @return Number of lines to output at the time. + */ +int DebugUI_GetPageLines(int config, int defvalue) +{ + int rows, cols; + + if (config >= 0) { + return config; + } + DebugUI_GetScreenSize(&rows, &cols); + /* leave 1 line for pager prompt */ + if (--rows > 0) { + return rows; + } + return defvalue; +} + static const dbgcommand_t uicommand[] = { @@ -851,8 +908,9 @@ static const dbgcommand_t uicommand[] = { DebugUI_ChangeDir, NULL, "cd", "", "change directory", - "\n" - "\tChange Hatari work directory.", + " [-f]\n" + "\tChange Hatari work directory. With '-f', directory is\n" + "\tchanged only after all script files have been parsed.", false }, { DebugUI_Evaluate, Vars_MatchCpuVariable, "evaluate", "e", @@ -912,7 +970,10 @@ static const dbgcommand_t uicommand[] = "parse", "p", "get debugger commands from file", "[filename]\n" - "\tRead debugger commands from given file and do them.", + "\tRead debugger commands from given file and do them.\n" + "\tCurrent directory is script directory during this.\n" + "\tTo specify directory to be used also for breakpoint\n" + "\tscripts execution, use '-f' option for 'cd' command.", false }, { DebugUI_Rename, NULL, "rename", "", @@ -1115,6 +1176,8 @@ void DebugUI(debug_reason_t reason) */ bool DebugUI_ParseFile(const char *path, bool reinit) { + int recurse; + static int recursing; char *olddir, *dir, *cmd, *input, *expanded, *slash; FILE *fp; @@ -1150,6 +1213,9 @@ bool DebugUI_ParseFile(const char *path, } free(dir); + recurse = recursing; + recursing = true; + input = NULL; for (;;) { @@ -1176,6 +1242,7 @@ bool DebugUI_ParseFile(const char *path, DebugUI_ParseCommand(cmd); free(expanded); } + recursing = false; free(input); fclose(fp); @@ -1189,10 +1256,27 @@ bool DebugUI_ParseFile(const char *path, free(olddir); } - if (reinit) + if (!recurse) { - DebugCpu_SetDebugging(); - DebugDsp_SetDebugging(); + /* current script (or something called by it) specified final dir */ + if (finalDir) + { + if (chdir(finalDir) != 0) + perror("ERROR"); + else + fprintf(stderr, "Delayed change to '%s' dir.\n", finalDir); + free(finalDir); + finalDir = NULL; + } + /* only top-level (non-recursed) call has valid re-init info, + * as that's the only one that can get directly called from + * breakpoints + */ + if (reinit) + { + DebugCpu_SetDebugging(); + DebugDsp_SetDebugging(); + } } return true; }