Main Page Data Structures File List Data Fields Globals Related Pages

# readline.cpp

Go to the documentation of this file.

    00001 /*  readline.cpp
    00002     A simple version of the GNU readline function.
    00003
    00004     31.09.2001: tk, history functions were quickly hacked in.
    00005                 They're ugly, but work fine. There's no function
    00006                 to free the history buffers, but the c-runtime
    00007                 should free them on program exit.
    00008     30.09.2001: tk, initial implementation.
    00009
    00010     Copyright (c)2000 by Thomas Kindler, thomas.kindler@gmx.de
    00011
    00012     This program is free software; you can redistribute it and/or
    00013     modify it under the terms of the GNU General Public License as
    00014     published by the Free Software Foundation; either version 2 of
    00015     the License, or (at your option) any later version. Read the
    00016     full License at http://www.gnu.org/copyleft for more details.
    00017 */
    00018
    00019 // include files -----
    00020 //
    00021 #include <stdio.h>
    00022 #include <stdlib.h>
    00023 #include <conio.h>
    00024 #include <assert.h>
    00025 #include <string.h>
    00026 #include <malloc.h>
    00027 #include "readline.h"
    00028
    00029 #define HISTORY_SIZE   8
    00030
    00031 static char *history[HISTORY_SIZE];
    00032 static int   numlines = 0;
    00033
    00034
    00042 static void addline(char *s)
    00043 {
    00044   if (numlines == HISTORY_SIZE) {
    00045     if (history[0])
    00046       free(history[0]);
    00047     for (int i=0; i<numlines-1; i++)
    00048       history[i] = history[i+1];
    00049     numlines--;
    00050   }
    00051
    00052   history[numlines++] = strdup(s);
    00053 }
    00054
    00055
    00063 static char* getline(int line)
    00064 {
    00065   if (line>=0 || line<numlines)
    00066     return history[line];
    00067   else
    00068     return NULL;
    00069 }
    00070
    00071
    00085 char *readline(char *s, int n)
    00086 {
    00087   int  c, cursor=0, len=0, line=numlines-1;
    00088   bool reprint = true;
    00089
    00090   *s = '\0';
    00091   printf("\033[s");
    00092   while ((c=getch()) != '\r') {
    00093     // process user input
    00094     //
    00095     switch (c) {
    00096       case 0x1b:  // ansi escape code?
    00097         if (getch() == '[')
    00098           switch(getch()) {
    00099             case 'A':  // cursor up
    00100               strncpy(s, getline(line), n-1);
    00101               if (line>0)
    00102                 line--;
    00103               cursor = len = strlen(s);
    00104               reprint = true;
    00105               break;
    00106             case 'B':  // cursor down
    00107               if (line<numlines-1)
    00108                 line++;
    00109               strncpy(s, getline(line), n-1);
    00110               cursor = len = strlen(s);
    00111               reprint = true;
    00112               break;
    00113             case 'C':  // cursor right
    00114               if (cursor<len) {
    00115                 cursor++;
    00116                 printf("\033[C");
    00117               }
    00118               break;
    00119             case 'D':  // cursor left
    00120               if (cursor>0) {
    00121                 cursor--;
    00122                 printf("\033[D");
    00123               }
    00124               break;
    00125           }
    00126         break;
    00127
    00128       case 0x08:  // backspace
    00129         if (cursor>0) {
    00130           len--;
    00131           cursor--;
    00132           for (int i=cursor; i<len; i++)
    00133             s[i] = s[i+1];
    00134           reprint = true;
    00135         }
    00136         break;
    00137
    00138       case 0x7f:  // delete
    00139         if (cursor < len) {
    00140           len--;
    00141           for (int i=cursor; i<len; i++)
    00142             s[i] = s[i+1];
    00143           reprint = true;
    00144         }
    00145         break;
    00146
    00147       default:  // insert char
    00148         if (len<n-1) {
    00149           for (int i=len; i>=cursor; i--)
    00150             s[i+1] = s[i];
    00151           s[cursor]=c;
    00152           len++;
    00153           cursor++;
    00154           reprint = true;
    00155         } else printf("\a");
    00156         break;
    00157     }
    00158     assert(len >= 0);  assert(len < n);
    00159     assert(cursor >= 0);  assert(cursor <= len);
    00160     s[len] = '\0';
    00161
    00162     // print new string
    00163     //
    00164     if (reprint) {
    00165       printf("\033[u\033[s");
    00166       printf("%s \b", s);
    00167       if (len-cursor > 0)
    00168         printf("\033[%dD", len-cursor);
    00169       reprint = false;
    00170     }
    00171   };
    00172   if (len>0)
    00173     addline(s);
    00174
    00175   return s;
    00176 }
    00177