History

kdb: Use format-strings rather than '\0' injection in kdb_read()

Currently when kdb_read() needs to reposition the cursor it uses copy and paste code that works by injecting an '\0' at the cursor position before delivering a carriage-return and reprinting the line (which stops at the '\0'). Tidy up the code by hoisting the copy and paste code into an appropriately named function. Additionally let's replace the '\0' injection with a proper field width parameter so that the string will be abridged during formatting instead.

Daniel Thompson committed 2 years ago

Commit 09b35981 parent e9730741 file · +34 −21Browse files

Showing the changes to kernel/debug (1 of 1 file). Show all

Unified · Split

kernel/debug/kdb/kdb_io.c+34−21
@@ -184,6 +184,33 @@ char kdb_getchar(void) · 183 unmodified lines
184184 unreachable();
185185 }
186186
187+/**
188+ * kdb_position_cursor() - Place cursor in the correct horizontal position
189+ * @prompt: Nil-terminated string containing the prompt string
190+ * @buffer: Nil-terminated string containing the entire command line
191+ * @cp: Cursor position, pointer the character in buffer where the cursor
192+ * should be positioned.
193+ *
194+ * The cursor is positioned by sending a carriage-return and then printing
195+ * the content of the line until we reach the correct cursor position.
196+ *
197+ * There is some additional fine detail here.
198+ *
199+ * Firstly, even though kdb_printf() will correctly format zero-width fields
200+ * we want the second call to kdb_printf() to be conditional. That keeps things
201+ * a little cleaner when LOGGING=1.
202+ *
203+ * Secondly, we can't combine everything into one call to kdb_printf() since
204+ * that renders into a fixed length buffer and the combined print could result
205+ * in unwanted truncation.
206+ */
207+static void kdb_position_cursor(char *prompt, char *buffer, char *cp)
208+{
209+ kdb_printf("\r%s", kdb_prompt_str);
210+ if (cp > buffer)
211+ kdb_printf("%.*s", (int)(cp - buffer), buffer);
212+}
213+
187214 /*
188215 * kdb_read
189216 *
@@ -212,7 +239,6 @@ static char *kdb_read(char *buffer, size_t bufsize) · 22 unmodified lines
212239 * and null byte */
213240 char *lastchar;
214241 char *p_tmp;
215− char tmp;
216242 static char tmpbuffer[CMD_BUFLEN];
217243 int len = strlen(buffer);
218244 int len_tmp;
@@ -249,12 +275,8 @@ poll_again: · 30 unmodified lines
249275 }
250276 *(--lastchar) = '\0';
251277 --cp;
252− kdb_printf("\b%s \r", cp);
253− tmp = *cp;
254− *cp = '\0';
255− kdb_printf(kdb_prompt_str);
256− kdb_printf("%s", buffer);
257− *cp = tmp;
278+ kdb_printf("\b%s ", cp);
279+ kdb_position_cursor(kdb_prompt_str, buffer, cp);
258280 }
259281 break;
260282 case 10: /* linefeed */
@@ -272,19 +294,14 @@ poll_again: · 11 unmodified lines
272294 memcpy(tmpbuffer, cp+1, lastchar - cp - 1);
273295 memcpy(cp, tmpbuffer, lastchar - cp - 1);
274296 *(--lastchar) = '\0';
275− kdb_printf("%s \r", cp);
276− tmp = *cp;
277− *cp = '\0';
278− kdb_printf(kdb_prompt_str);
279− kdb_printf("%s", buffer);
280− *cp = tmp;
297+ kdb_printf("%s ", cp);
298+ kdb_position_cursor(kdb_prompt_str, buffer, cp);
281299 }
282300 break;
283301 case 1: /* Home */
284302 if (cp > buffer) {
285− kdb_printf("\r");
286− kdb_printf(kdb_prompt_str);
287303 cp = buffer;
304+ kdb_position_cursor(kdb_prompt_str, buffer, cp);
288305 }
289306 break;
290307 case 5: /* End */
@@ -390,13 +407,9 @@ poll_again: · 99 unmodified lines
390407 memcpy(cp+1, tmpbuffer, lastchar - cp);
391408 *++lastchar = '\0';
392409 *cp = key;
393− kdb_printf("%s\r", cp);
410+ kdb_printf("%s", cp);
394411 ++cp;
395− tmp = *cp;
396− *cp = '\0';
397− kdb_printf(kdb_prompt_str);
398− kdb_printf("%s", buffer);
399− *cp = tmp;
412+ kdb_position_cursor(kdb_prompt_str, buffer, cp);
400413 } else {
401414 *++lastchar = '\0';
402415 *cp++ = key;