You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <console.h>
  22. #include <gpxe/keys.h>
  23. #include <gpxe/editstring.h>
  24. #include <readline/readline.h>
  25. /** @file
  26. *
  27. * Minimal readline
  28. *
  29. */
  30. #define READLINE_MAX 256
  31. static void sync_console ( struct edit_string *string ) __nonnull;
  32. /**
  33. * Synchronise console with edited string
  34. *
  35. * @v string Editable string
  36. */
  37. static void sync_console ( struct edit_string *string ) {
  38. unsigned int mod_start = string->mod_start;
  39. unsigned int mod_end = string->mod_end;
  40. unsigned int cursor = string->last_cursor;
  41. size_t len = strlen ( string->buf );
  42. /* Expand region back to old cursor position if applicable */
  43. if ( mod_start > string->last_cursor )
  44. mod_start = string->last_cursor;
  45. /* Expand region forward to new cursor position if applicable */
  46. if ( mod_end < string->cursor )
  47. mod_end = string->cursor;
  48. /* Backspace to start of region */
  49. while ( cursor > mod_start ) {
  50. putchar ( '\b' );
  51. cursor--;
  52. }
  53. /* Print modified region */
  54. while ( cursor < mod_end ) {
  55. putchar ( ( cursor >= len ) ? ' ' : string->buf[cursor] );
  56. cursor++;
  57. }
  58. /* Backspace to new cursor position */
  59. while ( cursor > string->cursor ) {
  60. putchar ( '\b' );
  61. cursor--;
  62. }
  63. }
  64. /**
  65. * Read line from console
  66. *
  67. * @v prompt Prompt string
  68. * @ret line Line read from console (excluding terminating newline)
  69. *
  70. * The returned line is allocated with malloc(); the caller must
  71. * eventually call free() to release the storage.
  72. */
  73. char * readline ( const char *prompt ) {
  74. char buf[READLINE_MAX];
  75. struct edit_string string;
  76. int key;
  77. char *line;
  78. if ( prompt )
  79. printf ( "%s", prompt );
  80. memset ( &string, 0, sizeof ( string ) );
  81. string.buf = buf;
  82. string.len = sizeof ( buf );
  83. buf[0] = '\0';
  84. while ( 1 ) {
  85. key = edit_string ( &string, getkey() );
  86. sync_console ( &string );
  87. switch ( key ) {
  88. case CR:
  89. case LF:
  90. putchar ( '\n' );
  91. line = strdup ( buf );
  92. if ( ! line )
  93. printf ( "Out of memory\n" );
  94. return line;
  95. case CTRL_C:
  96. putchar ( '\n' );
  97. return NULL;
  98. default:
  99. /* Do nothing */
  100. break;
  101. }
  102. }
  103. }