1 /* 2 * Copyright (C) 2026 Jo-Philipp Wich <jo@mein.io> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ANY IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * 16 * --- 17 * 18 * Interactive line editing, history and command-name completion for udbg's 19 * "dbg > " prompt, ported from the pre-protocol interactive debugger's 20 * hand-rolled terminal line editor (formerly lib/debug.c's termline_t/ 21 * term_getc()/term_getline()/term_line_tabcomplete()) - no external 22 * readline/editline dependency, matching the original's choice not to take 23 * on one either. 24 * 25 * The one architectural change the port needed: the original owned a 26 * dedicated, blocking input loop (it was a synchronous, in-process 27 * debugger), whereas udbg is driven by a single select() loop that also has 28 * to watch the server socket for async EVENTs - so every function here is 29 * non-blocking and consumes only bytes already available, meant to be 30 * called each time select()/poll() reports STDIN_FILENO readable. 31 */ 32 33 #ifndef _DEBUG_LINEEDIT_H 34 #define _DEBUG_LINEEDIT_H 35 36 #include <stddef.h> 37 #include <stdbool.h> 38 39 /* One command-name completion candidate set for Tab, e.g. a CLI's own 40 * verb/alias table - `names` is a NUL-separated list of aliases (primary 41 * name first), itself NUL-terminated, the same shape already used for 42 * udbg's own help table. Only ever matched against the line's first 43 * (unterminated-by-space) word - this module has no notion of per-argument 44 * completion (function names, file paths, ...). */ 45 typedef struct { 46 const char *names; 47 } lineedit_completion_t; 48 49 /* Try to put STDIN_FILENO into raw, non-blocking mode for interactive 50 * editing. No-op if stdin isn't a terminal (piped/scripted input, the 51 * common case when testing) - callers must check lineedit_active() and 52 * fall back to plain fgets()-based reads in that case, since nothing below 53 * does anything useful without raw mode. Registers an atexit() handler to 54 * restore the original terminal settings; safe to call more than once. */ 55 void lineedit_init(void); 56 57 /* True if lineedit_init() actually engaged raw mode. */ 58 bool lineedit_active(void); 59 60 /* Temporarily restore the original (cooked, blocking) terminal mode - for a 61 * one-off plain fgets()-based prompt elsewhere (e.g. a yes/no confirmation) 62 * that needs normal line buffering and echo. Pair with lineedit_resume(). */ 63 void lineedit_suspend(void); 64 65 /* Re-engage raw mode after lineedit_suspend(), if it was active before. */ 66 void lineedit_resume(void); 67 68 /* Install the Tab completion candidate table. Optional - skip the call to 69 * disable completion entirely. `completions` must outlive any subsequent 70 * lineedit_feed() call. */ 71 void lineedit_set_completions(const lineedit_completion_t *completions, size_t n); 72 73 /* Print `prompt` and start a fresh, empty line - call this whenever the 74 * caller (re)enters a state where it wants to accept a new command, i.e. 75 * the one place that used to just printf() the prompt directly. */ 76 void lineedit_begin(const char *prompt); 77 78 /* Consume whatever is currently available on STDIN_FILENO. Never blocks. 79 * Returns true exactly once a line has been submitted (Enter), copied 80 * NUL-terminated into `out` (truncated to fit `outsz`); *eof is set to true 81 * if the terminal hung up (read() saw EOF) rather than a line being ready. 82 * Redraws the prompt/line itself as needed - callers only need to react to 83 * a completed line or *eof, not to intermediate keystrokes. */ 84 bool lineedit_feed(char *out, size_t outsz, bool *eof); 85 86 #endif 87
This page was automatically generated by LXR 0.3.1. • OpenWrt