diff options
author | unknown <magnus@neptunus.(none)> | 2004-04-14 10:53:21 +0200 |
---|---|---|
committer | unknown <magnus@neptunus.(none)> | 2004-04-14 10:53:21 +0200 |
commit | 6386c55cee50bad6a9979d1fab28e03bb8612ca7 (patch) | |
tree | 3fbbacf704304b69228474b9f03549ccd585a017 /ndb/src/common/editline | |
parent | 0ba6cb48d84f1ff951d09871a96be6cdef3f2c3c (diff) | |
download | mariadb-git-6386c55cee50bad6a9979d1fab28e03bb8612ca7.tar.gz |
Initial revision of NDB Cluster files
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
Diffstat (limited to 'ndb/src/common/editline')
-rw-r--r-- | ndb/src/common/editline/MANIFEST | 15 | ||||
-rw-r--r-- | ndb/src/common/editline/Makefile | 18 | ||||
-rw-r--r-- | ndb/src/common/editline/README | 53 | ||||
-rw-r--r-- | ndb/src/common/editline/complete.c | 211 | ||||
-rw-r--r-- | ndb/src/common/editline/editline.3 | 178 | ||||
-rw-r--r-- | ndb/src/common/editline/editline.c | 1514 | ||||
-rw-r--r-- | ndb/src/common/editline/editline_internal.h | 47 | ||||
-rw-r--r-- | ndb/src/common/editline/editline_win32.c | 33 | ||||
-rw-r--r-- | ndb/src/common/editline/sysunix.c | 143 | ||||
-rw-r--r-- | ndb/src/common/editline/test/Makefile | 10 | ||||
-rw-r--r-- | ndb/src/common/editline/test/testit.c | 59 | ||||
-rw-r--r-- | ndb/src/common/editline/unix.h | 26 |
12 files changed, 2307 insertions, 0 deletions
diff --git a/ndb/src/common/editline/MANIFEST b/ndb/src/common/editline/MANIFEST new file mode 100644 index 00000000000..dc8b4b36f88 --- /dev/null +++ b/ndb/src/common/editline/MANIFEST @@ -0,0 +1,15 @@ +File Name Description +-------------------------------------------------------- +README Release notes and copyright +MANIFEST This shipping list +Make.os9 OS-9 makefile +Makefile Unix makefile +complete.c Filename completion routines +editline.3 Manual page for editline library +editline.c Line-editing routines +editline_internal.h Internal library header file +os9.h OS-9-specific declarations +sysos9.c OS-9-specific routines +sysunix.c Unix-specific routines +testit.c Test driver +unix.h Unix-specific declarations diff --git a/ndb/src/common/editline/Makefile b/ndb/src/common/editline/Makefile new file mode 100644 index 00000000000..800df8f0f31 --- /dev/null +++ b/ndb/src/common/editline/Makefile @@ -0,0 +1,18 @@ +include .defs.mk + +TYPE := + +ARCHIVE_TARGET := editline + +CFLAGS += -DANSI_ARROWS -DHAVE_TCGETATTR -DSYS_UNIX + +ifeq ($(NDB_OS), WIN32) +SOURCES = editline_win32.c +else +SOURCES = complete.c editline.c sysunix.c +endif + +DIRS := test + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/src/common/editline/README b/ndb/src/common/editline/README new file mode 100644 index 00000000000..537c7bd8611 --- /dev/null +++ b/ndb/src/common/editline/README @@ -0,0 +1,53 @@ +-- +NOTE: This version has been modified by Ericsson/Alzato. Please +see the cvs changelog for more details. +-- + +$Revision: 1.2 $ + +This is a line-editing library. It can be linked into almost any +program to provide command-line editing and recall. + +It is call-compatible with the FSF readline library, but it is a +fraction of the size (and offers fewer features). It does not use +standard I/O. It is distributed under a "C News-like" copyright. + +Configuration is done in the Makefile. Type "make testit" to get +a small slow shell for testing. + +This contains some changes since the posting to comp.sources.misc: + - Bugfix for completion on absolute pathnames. + - Better handling of M-n versus showing raw 8bit chars. + - Better signal handling. + - Now supports termios/termio/sgttyb ioctl's. + - Add M-m command to toggle how 8bit data is displayed. +The following changes, made since the last public release, come from +J.G. Vons <vons@cesar.crbca1.sinet.slb.com>: + - History-searching no longer redraws the line wrong + - Added ESC-ESC as synonym for ESC-? + - SIGQUIT (normally ^\) now sends a signal, not indicating EOF. + - Fixed some typo's and unclear wording in the manpage. + - Fixed completion when all entries shared a common prefix. + - Fixed some meta-char line-redrawing bugs. + +Enjoy, + Rich $alz + <rsalz@osf.org> + + Copyright 1992,1993 Simmule Turner and Rich Salz. All rights reserved. + + This software is not subject to any license of the American Telephone + and Telegraph Company or of the Regents of the University of California. + + Permission is granted to anyone to use this software for any purpose on + any computer system, and to alter it and redistribute it freely, subject + to the following restrictions: + 1. The authors are not responsible for the consequences of use of this + software, no matter how awful, even if they arise from flaws in it. + 2. The origin of this software must not be misrepresented, either by + explicit claim or by omission. Since few users ever read sources, + credits must appear in the documentation. + 3. Altered versions must be plainly marked as such, and must not be + misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation. + 4. This notice may not be removed or altered. diff --git a/ndb/src/common/editline/complete.c b/ndb/src/common/editline/complete.c new file mode 100644 index 00000000000..d1f8b1d3ff4 --- /dev/null +++ b/ndb/src/common/editline/complete.c @@ -0,0 +1,211 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* -*- c-basic-offset: 4; -*- +** $Revision: 1.8 $ +** +** History and file completion functions for editline library. +*/ +#include "editline_internal.h" + + +/* +** strcmp-like sorting predicate for qsort. +*/ +static int +compare(const void *p1, const void *p2) +{ + const char **v1; + const char **v2; + + v1 = (const char **)p1; + v2 = (const char **)p2; + return strcmp(*v1, *v2); +} + +/* +** Fill in *avp with an array of names that match file, up to its length. +** Ignore . and .. . +*/ +static int +FindMatches(char *dir, char *file, char ***avp) +{ + char **av; + char **new; + char *p; + DIR *dp; + struct dirent *ep; + size_t ac; + size_t len; + + if ((dp = opendir(dir)) == NULL) + return 0; + + av = NULL; + ac = 0; + len = strlen(file); + while ((ep = readdir(dp)) != NULL) { + p = ep->d_name; + if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0'))) + continue; + if (len && strncmp(p, file, len) != 0) + continue; + + if ((ac % MEM_INC) == 0) { + if ((new = malloc(sizeof(char*) * (ac + MEM_INC))) == NULL) + break; + if (ac) { + memcpy(new, av, ac * sizeof (char **)); + free(av); + } + *avp = av = new; + } + + if ((av[ac] = strdup(p)) == NULL) { + if (ac == 0) + free(av); + break; + } + ac++; + } + + /* Clean up and return. */ + (void)closedir(dp); + if (ac) + qsort(av, ac, sizeof (char **), compare); + return ac; +} + +/* +** Split a pathname into allocated directory and trailing filename parts. +*/ +static int +SplitPath(char *path, char **dirpart, char ** filepart) +{ + static char DOT[] = "."; + char *dpart; + char *fpart; + + if ((fpart = strrchr(path, '/')) == NULL) { + if ((dpart = strdup(DOT)) == NULL) + return -1; + if ((fpart = strdup(path)) == NULL) { + free(dpart); + return -1; + } + } + else { + if ((dpart = strdup(path)) == NULL) + return -1; + dpart[fpart - path + 1] = '\0'; + if ((fpart = strdup(++fpart)) == NULL) { + free(dpart); + return -1; + } + } + *dirpart = dpart; + *filepart = fpart; + return 0; +} + +/* +** Attempt to complete the pathname, returning an allocated copy. +** Fill in *unique if we completed it, or set it to 0 if ambiguous. +*/ +char * +rl_complete(char *pathname,int *unique) +{ + char **av; + char *dir; + char *file; + char *new; + char *p; + size_t ac; + size_t end; + size_t i; + size_t j; + size_t len; + size_t new_len; + size_t p_len; + + if (SplitPath(pathname, &dir, &file) < 0) + return NULL; + if ((ac = FindMatches(dir, file, &av)) == 0) { + free(dir); + free(file); + return NULL; + } + + p = NULL; + len = strlen(file); + if (ac == 1) { + /* Exactly one match -- finish it off. */ + *unique = 1; + j = strlen(av[0]) - len + 2; + p_len = sizeof(char) * (j + 1); + if ((p = malloc(p_len)) != NULL) { + memcpy(p, av[0] + len, j); + new_len = sizeof(char) * (strlen(dir) + strlen(av[0]) + 2); + new = malloc(new_len); + if(new != NULL) { + snprintf(new, new_len, "%s/%s", dir, av[0]); + rl_add_slash(new, p, p_len); + free(new); + } + } + } + else { + /* Find largest matching substring. */ + for (*unique = 0, i = len, end = strlen(av[0]); i < end; i++) + for (j = 1; j < ac; j++) + if (av[0][i] != av[j][i]) + goto breakout; +breakout: + if (i > len) { + j = i - len + 1; + if ((p = malloc(sizeof(char) * j)) != NULL) { + memcpy(p, av[0] + len, j); + p[j - 1] = '\0'; + } + } + } + + /* Clean up and return. */ + free(dir); + free(file); + for (i = 0; i < ac; i++) + free(av[i]); + free(av); + return p; +} + +/* +** Return all possible completions. +*/ +int +rl_list_possib(char *pathname, char ***avp) +{ + char *dir; + char *file; + int ac; + + if (SplitPath(pathname, &dir, &file) < 0) + return 0; + ac = FindMatches(dir, file, avp); + free(dir); + free(file); + return ac; +} diff --git a/ndb/src/common/editline/editline.3 b/ndb/src/common/editline/editline.3 new file mode 100644 index 00000000000..159cc7f87bb --- /dev/null +++ b/ndb/src/common/editline/editline.3 @@ -0,0 +1,178 @@ +.\" $Revision: 1.1 $ +.TH EDITLINE 3 +.SH NAME +editline \- command-line editing library with history +.SH SYNOPSIS +.nf +.B "char *" +.B "readline(prompt)" +.B " char *prompt;" + +.B "void" +.B "add_history(line)" +.B " char *line;" +.fi +.SH DESCRIPTION +.I Editline +is a library that provides an line-editing interface with text recall. +It is intended to be compatible with the +.I readline +library provided by the Free Software Foundation, but much smaller. +The bulk of this manual page describes the user interface. +.PP +The +.I readline +routine returns a line of text with the trailing newline removed. +The data is returned in a buffer allocated with +.IR malloc (3), +so the space should be released with +.IR free (3) +when the calling program is done with it. +Before accepting input from the user, the specified +.I prompt +is displayed on the terminal. +.PP +The +.I add_history +routine makes a copy of the specified +.I line +and adds it to the internal history list. +.SS "User Interface" +A program that uses this library provides a simple emacs-like editing +interface to its users. +A line may be edited before it is sent to the calling program by typing either +control characters or escape sequences. +A control character, shown as a caret followed by a letter, is typed by +holding down the ``control'' key while the letter is typed. +For example, ``^A'' is a control-A. +An escape sequence is entered by typing the ``escape'' key followed by one or +more characters. +The escape key is abbreviated as ``ESC''. +Note that unlike control keys, case matters in escape sequences; ``ESC\ F'' +is not the same as ``ESC\ f''. +.PP +An editing command may be typed anywhere on the line, not just at the +beginning. +In addition, a return may also be typed anywhere on the line, not just at +the end. +.PP +Most editing commands may be given a repeat count, +.IR n , +where +.I n +is a number. +To enter a repeat count, type the escape key, the number, and then +the command to execute. +For example, ``ESC\ 4\ ^f'' moves forward four characters. +If a command may be given a repeat count then the text ``[n]'' is given at the +end of its description. +.PP +The following control characters are accepted: +.RS +.nf +.ta \w'ESC DEL 'u +^A Move to the beginning of the line +^B Move left (backwards) [n] +^D Delete character [n] +^E Move to end of line +^F Move right (forwards) [n] +^G Ring the bell +^H Delete character before cursor (backspace key) [n] +^I Complete filename (tab key); see below +^J Done with line (return key) +^K Kill to end of line (or column [n]) +^L Redisplay line +^M Done with line (alternate return key) +^N Get next line from history [n] +^P Get previous line from history [n] +^R Search backward (forward if [n]) through history for text; +\& prefixing the string with a caret (^) forces it to +\& match only at the beginning of a history line +^T Transpose characters +^V Insert next character, even if it is an edit command +^W Wipe to the mark +^X^X Exchange current location and mark +^Y Yank back last killed text +^[ Start an escape sequence (escape key) +^]c Move forward to next character ``c'' +^? Delete character before cursor (delete key) [n] +.fi +.RE +.PP +The following escape sequences are provided. +.RS +.nf +.ta \w'ESC DEL 'u +ESC\ ^H Delete previous word (backspace key) [n] +ESC\ DEL Delete previous word (delete key) [n] +ESC\ ESC Show possible completions; see below +ESC\ SP Set the mark (space key); see ^X^X and ^Y above +ESC\ . Get the last (or [n]'th) word from previous line +ESC\ ? Show possible completions; see below +ESC\ < Move to start of history +ESC\ > Move to end of history +ESC\ b Move backward a word [n] +ESC\ d Delete word under cursor [n] +ESC\ f Move forward a word [n] +ESC\ l Make word lowercase [n] +ESC\ m Toggle if 8bit chars display as themselves or with +\& an ``M\-'' prefix +ESC\ u Make word uppercase [n] +ESC\ y Yank back last killed text +ESC\ w Make area up to mark yankable +ESC\ nn Set repeat count to the number nn +ESC\ C Read from environment variable ``_C_'', where C is +\& an uppercase letter +.fi +.RE +.PP +The +.I editline +library has a small macro facility. +If you type the escape key followed by an uppercase letter, +.IR C , +then the contents of the environment variable +.I _C_ +are read in as if you had typed them at the keyboard. +For example, if the variable +.I _L_ +contains the following: +.RS +^A^Kecho '^V^[[H^V^[[2J'^M +.RE +Then typing ``ESC L'' will move to the beginning of the line, kill the +entire line, enter the echo command needed to clear the terminal (if your +terminal is like a VT-100), and send the line back to the shell. +.PP +The +.I editline +library also does filename completion. +Suppose the root directory has the following files in it: +.RS +.nf +.ta \w'core 'u +bin vmunix +core vmunix.old +.fi +.RE +If you type ``rm\ /v'' and then the tab key. +.I Editline +will then finish off as much of the name as possible by adding ``munix''. +Because the name is not unique, it will then beep. +If you type the escape key followed by either a question mark or another +escape, it will display the two choices. +If you then type a period and a tab, the library will finish off the filename +for you: +.RS +.nf +.RI "rm /v[TAB]" munix ".[TAB]" old +.fi +.RE +The tab key is shown by ``[TAB]'' and the automatically-entered text +is shown in italics. +.SH "BUGS AND LIMITATIONS" +Cannot handle lines more than 80 columns. +.SH AUTHORS +Simmule R. Turner <uunet.uu.net!capitol!sysgo!simmy> +and Rich $alz <rsalz@osf.org>. +Original manual page by DaviD W. Sanderson <dws@ssec.wisc.edu>. diff --git a/ndb/src/common/editline/editline.c b/ndb/src/common/editline/editline.c new file mode 100644 index 00000000000..0529d18b952 --- /dev/null +++ b/ndb/src/common/editline/editline.c @@ -0,0 +1,1514 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* -*- c-basic-offset: 4; -*- +** $Revision: 1.6 $ +** +** Main editing routines for editline library. +*/ +#include "editline_internal.h" +#include <signal.h> +#include <ctype.h> +#include <unistd.h> + +/* +** Manifest constants. +*/ +#define SCREEN_WIDTH 80 +#define SCREEN_ROWS 24 +#define NO_ARG (-1) +#define DEL 127 +#define TAB '\t' +#define CTL(x) ((x) & 0x1F) +#define ISCTL(x) ((x) && (x) < ' ') +#define UNCTL(x) ((x) + 64) +#define META(x) ((x) | 0x80) +#define ISMETA(x) ((x) & 0x80) +#define UNMETA(x) ((x) & 0x7F) +#define MAPSIZE 32 +#define METAMAPSIZE 16 +#if !defined(HIST_SIZE) +#define HIST_SIZE 20 +#endif /* !defined(HIST_SIZE) */ + +/* +** Command status codes. +*/ +typedef enum _STATUS { + CSdone, CSeof, CSmove, CSdispatch, CSstay, CSsignal +} STATUS; + +/* +** The type of case-changing to perform. +*/ +typedef enum _CASE { + TOupper, TOlower +} CASE; + +/* +** Key to command mapping. +*/ +typedef struct _KEYMAP { + char Key; + char Active; + STATUS (*Function)(); +} KEYMAP; + +/* +** Command history structure. +*/ +typedef struct _HISTORY { + int Size; + int Pos; + char *Lines[HIST_SIZE]; +} HISTORY; + +/* +** Globals. +*/ +int rl_eof; +int rl_erase; +int rl_intr; +int rl_kill; +int rl_quit; +#if defined(DO_SIGTSTP) +int rl_susp; +#endif /* defined(DO_SIGTSTP) */ + +static char NIL[] = ""; +static const char *Input = NIL; +static char *Line; +static const char *Prompt; +static char *Yanked; +static char *Screen; +static char NEWLINE[]= CRLF; +static HISTORY H; +static int Repeat; +static int End; +static int Mark; +static int OldPoint; +static int Point; +static int PushBack; +static int Pushed; +static int Signal; +static KEYMAP Map[MAPSIZE]; +static KEYMAP MetaMap[METAMAPSIZE]; +static size_t Length; +static size_t ScreenCount; +static size_t ScreenSize; +static char *backspace; +static int TTYwidth; +static int TTYrows; + +/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */ +int rl_meta_chars = 1; + +/* +** Declarations. +*/ +static char *editinput(); + +#if defined(USE_TERMCAP) +extern char *getenv(); +extern char *tgetstr(); +extern int tgetent(); +extern int tgetnum(); +#endif /* defined(USE_TERMCAP) */ + +/* +** TTY input/output functions. +*/ + +static void +TTYflush() +{ + if (ScreenCount) { + (void)write(1, Screen, ScreenCount); + ScreenCount = 0; + } +} + +static void +TTYput(const char c) +{ + Screen[ScreenCount] = c; + if (++ScreenCount >= ScreenSize - 1) { + ScreenSize += SCREEN_INC; + Screen = realloc(Screen, sizeof(char) * ScreenSize); + /* XXX what to do if realloc failes? */ + } +} + +static void +TTYputs(const char *p) +{ + while (*p) + TTYput(*p++); +} + +static void +TTYshow(char c) +{ + if (c == DEL) { + TTYput('^'); + TTYput('?'); + } + else if (c == TAB) { + /* XXX */ + } + else if (ISCTL(c)) { + TTYput('^'); + TTYput(UNCTL(c)); + } + else if (rl_meta_chars && ISMETA(c)) { + TTYput('M'); + TTYput('-'); + TTYput(UNMETA(c)); + } + else + TTYput(c); +} + +static void +TTYstring(char *p) +{ + while (*p) + TTYshow(*p++); +} + +static int +TTYget() +{ + char c; + + TTYflush(); + if (Pushed) { + Pushed = 0; + return PushBack; + } + if (*Input) + return *Input++; + return read(0, &c, (size_t)1) == 1 ? c : EOF; +} + +#define TTYback() (backspace ? TTYputs((const char *)backspace) : TTYput('\b')) + +static void +TTYbackn(int n) +{ + while (--n >= 0) + TTYback(); +} + +static void +TTYinfo() +{ + static int init; +#if defined(USE_TERMCAP) + char *term; + char buff[2048]; + char *bp; + char *p; +#endif /* defined(USE_TERMCAP) */ +#if defined(TIOCGWINSZ) + struct winsize W; +#endif /* defined(TIOCGWINSZ) */ + + if (init) { +#if defined(TIOCGWINSZ) + /* Perhaps we got resized. */ + if (ioctl(0, TIOCGWINSZ, &W) >= 0 + && W.ws_col > 0 && W.ws_row > 0) { + TTYwidth = (int)W.ws_col; + TTYrows = (int)W.ws_row; + } +#endif /* defined(TIOCGWINSZ) */ + return; + } + init++; + + TTYwidth = TTYrows = 0; +#if defined(USE_TERMCAP) + bp = &buff[0]; + if ((term = getenv("TERM")) == NULL) + term = "dumb"; + if (tgetent(buff, term) < 0) { + TTYwidth = SCREEN_WIDTH; + TTYrows = SCREEN_ROWS; + return; + } + p = tgetstr("le", &bp); + backspace = p ? strdup(p) : NULL; + TTYwidth = tgetnum("co"); + TTYrows = tgetnum("li"); +#endif /* defined(USE_TERMCAP) */ + +#if defined(TIOCGWINSZ) + if (ioctl(0, TIOCGWINSZ, &W) >= 0) { + TTYwidth = (int)W.ws_col; + TTYrows = (int)W.ws_row; + } +#endif /* defined(TIOCGWINSZ) */ + + if (TTYwidth <= 0 || TTYrows <= 0) { + TTYwidth = SCREEN_WIDTH; + TTYrows = SCREEN_ROWS; + } +} + + +/* +** Print an array of words in columns. +*/ +static void +columns(int ac, char **av) +{ + char *p; + int i; + int j; + int k; + int len; + int skip; + int longest; + int cols; + + /* Find longest name, determine column count from that. */ + for (longest = 0, i = 0; i < ac; i++) + if ((j = strlen((char *)av[i])) > longest) + longest = j; + cols = TTYwidth / (longest + 3); + + TTYputs((const char *)NEWLINE); + for (skip = ac / cols + 1, i = 0; i < skip; i++) { + for (j = i; j < ac; j += skip) { + for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++) + TTYput(*p); + if (j + skip < ac) + while (++len < longest + 3) + TTYput(' '); + } + TTYputs((const char *)NEWLINE); + } +} + +static void +reposition() +{ + int i; + char *p; + + TTYput('\r'); + TTYputs((const char *)Prompt); + for (i = Point, p = Line; --i >= 0; p++) + TTYshow(*p); +} + +static void +left(STATUS Change) +{ + char c; + + TTYback(); + if (Point) { + c = Line[Point - 1]; + if (c == TAB) { + /* XXX */ + } + else if (ISCTL(c)) + TTYback(); + else if (rl_meta_chars && ISMETA(c)) { + TTYback(); + TTYback(); + } + } + if (Change == CSmove) + Point--; +} + +static void +right(STATUS Change) +{ + TTYshow(Line[Point]); + if (Change == CSmove) + Point++; +} + +static STATUS +ring_bell() +{ + TTYput('\07'); + TTYflush(); + return CSstay; +} + +static STATUS +do_macro(int c) +{ + char name[4]; + + name[0] = '_'; + name[1] = c; + name[2] = '_'; + name[3] = '\0'; + + if ((Input = (char *)getenv((char *)name)) == NULL) { + Input = NIL; + return ring_bell(); + } + return CSstay; +} + +static STATUS +do_forward(STATUS move) +{ + int i; + char *p; + + i = 0; + do { + p = &Line[Point]; + for ( ; Point < End && (*p == ' ' || !isalnum((int)*p)); Point++, p++) + if (move == CSmove) + right(CSstay); + + for (; Point < End && isalnum((int)*p); Point++, p++) + if (move == CSmove) + right(CSstay); + + if (Point == End) + break; + } while (++i < Repeat); + + return CSstay; +} + +static STATUS +do_case(CASE type) +{ + int i; + int end; + int count; + char *p; + + (void)do_forward(CSstay); + if (OldPoint != Point) { + if ((count = Point - OldPoint) < 0) + count = -count; + Point = OldPoint; + if ((end = Point + count) > End) + end = End; + for (i = Point, p = &Line[i]; i < end; i++, p++) { + if (type == TOupper) { + if (islower((int)*p)) + *p = toupper((int)*p); + } + else if (isupper((int)*p)) + *p = tolower((int)*p); + right(CSmove); + } + } + return CSstay; +} + +static STATUS +case_down_word() +{ + return do_case(TOlower); +} + +static STATUS +case_up_word() +{ + return do_case(TOupper); +} + +static void +ceol() +{ + int extras; + int i; + char *p; + + for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) { + TTYput(' '); + if (*p == TAB) { + /* XXX */ + } + else if (ISCTL(*p)) { + TTYput(' '); + extras++; + } + else if (rl_meta_chars && ISMETA(*p)) { + TTYput(' '); + TTYput(' '); + extras += 2; + } + } + + for (i += extras; i > Point; i--) + TTYback(); +} + +static void +clear_line() +{ + Point = -strlen(Prompt); + TTYput('\r'); + ceol(); + Point = 0; + End = 0; + Line[0] = '\0'; +} + +static STATUS +insert_string(char *p) +{ + size_t len; + int i; + char *new; + char *q; + + len = strlen((char *)p); + if (End + len >= Length) { + if ((new = malloc(sizeof(char) * (Length + len + MEM_INC))) == NULL) + return CSstay; + if (Length) { + memcpy(new, Line, Length); + free(Line); + } + Line = new; + Length += len + MEM_INC; + } + + for (q = &Line[Point], i = End - Point; --i >= 0; ) + q[len + i] = q[i]; + memcpy(&Line[Point], p, len); + End += len; + Line[End] = '\0'; + TTYstring(&Line[Point]); + Point += len; + + return Point == End ? CSstay : CSmove; +} + +static STATUS +redisplay() +{ + TTYputs((const char *)NEWLINE); + TTYputs((const char *)Prompt); + TTYstring(Line); + return CSmove; +} + +static STATUS +redisplay_no_nl() +{ + TTYput('\r'); + TTYputs((const char *)Prompt); + TTYstring(Line); + return CSmove; +} + +static STATUS +toggle_meta_mode() +{ + rl_meta_chars = !rl_meta_chars; + return redisplay(); +} + + +static char * +next_hist() +{ + return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos]; +} + +static char * +prev_hist() +{ + return H.Pos == 0 ? NULL : H.Lines[--H.Pos]; +} + +static STATUS +do_insert_hist(char *p) +{ + if (p == NULL) + return ring_bell(); + Point = 0; + reposition(); + ceol(); + End = 0; + return insert_string(p); +} + +static STATUS +do_hist(char *(*move)()) +{ + char *p; + int i; + + i = 0; + do { + if ((p = (*move)()) == NULL) + return ring_bell(); + } while (++i < Repeat); + return do_insert_hist(p); +} + +static STATUS +h_next() +{ + return do_hist(next_hist); +} + +static STATUS +h_prev() +{ + return do_hist(prev_hist); +} + +static STATUS +h_first() +{ + return do_insert_hist(H.Lines[H.Pos = 0]); +} + +static STATUS +h_last() +{ + return do_insert_hist(H.Lines[H.Pos = H.Size - 1]); +} + +/* +** Return zero if pat appears as a substring in text. +*/ +static int +substrcmp(char *text, char *pat,int len) +{ + char c; + + if ((c = *pat) == '\0') + return *text == '\0'; + for ( ; *text; text++) + if (*text == c && strncmp(text, pat, len) == 0) + return 0; + return 1; +} + +static char * +search_hist(char *search,char *(*move)()) +{ + static char *old_search; + int len; + int pos; + int (*match)(); + char *pat; + + /* Save or get remembered search pattern. */ + if (search && *search) { + if (old_search) + free(old_search); + old_search = strdup(search); + } + else { + if (old_search == NULL || *old_search == '\0') + return NULL; + search = old_search; + } + + /* Set up pattern-finder. */ + if (*search == '^') { + match = strncmp; + pat = (char *)(search + 1); + } + else { + match = substrcmp; + pat = (char *)search; + } + len = strlen(pat); + + for (pos = H.Pos; (*move)() != NULL; ) + if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0) + return H.Lines[H.Pos]; + H.Pos = pos; + return NULL; +} + +static STATUS +h_search() +{ + static int Searching; + const char *old_prompt; + char *(*move)(); + char *p; + + if (Searching) + return ring_bell(); + Searching = 1; + + clear_line(); + old_prompt = Prompt; + Prompt = "Search: "; + TTYputs((const char *)Prompt); + move = Repeat == NO_ARG ? prev_hist : next_hist; + p = editinput(); + Searching = 0; + if (p == NULL && Signal > 0) { + Signal = 0; + clear_line(); + Prompt = old_prompt; + return redisplay_no_nl(); + } + p = search_hist(p, move); + clear_line(); + Prompt = old_prompt; + if (p == NULL) { + (void)ring_bell(); + return redisplay_no_nl(); + } + return do_insert_hist(p); +} + +static STATUS +fd_char() +{ + int i; + + i = 0; + do { + if (Point >= End) + break; + right(CSmove); + } while (++i < Repeat); + return CSstay; +} + +static void +save_yank(int begin, int i) +{ + if (Yanked) { + free(Yanked); + Yanked = NULL; + } + + if (i < 1) + return; + + if ((Yanked = malloc(sizeof(char) * (i + 1))) != NULL) { + memcpy(Yanked, &Line[begin], i); + Yanked[i] = '\0'; + } +} + +static STATUS +delete_string(int count) +{ + int i; + char *p; + + if (count <= 0 || End == Point) + return ring_bell(); + + if (count == 1 && Point == End - 1) { + /* Optimize common case of delete at end of line. */ + End--; + p = &Line[Point]; + i = 1; + TTYput(' '); + if (*p == TAB) { + /* XXX */ + } + else if (ISCTL(*p)) { + i = 2; + TTYput(' '); + } + else if (rl_meta_chars && ISMETA(*p)) { + i = 3; + TTYput(' '); + TTYput(' '); + } + TTYbackn(i); + *p = '\0'; + return CSmove; + } + if (Point + count > End && (count = End - Point) <= 0) + return CSstay; + + if (count > 1) + save_yank(Point, count); + + ceol(); + for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++) + p[0] = p[count]; + End -= count; + TTYstring(&Line[Point]); + return CSmove; +} + +static STATUS +bk_char() +{ + int i; + + i = 0; + do { + if (Point == 0) + break; + left(CSmove); + } while (++i < Repeat); + + return CSstay; +} + +static STATUS +bk_del_char() +{ + int i; + + i = 0; + do { + if (Point == 0) + break; + left(CSmove); + } while (++i < Repeat); + + return delete_string(i); +} + +static STATUS +kill_line() +{ + int i; + + if (Repeat != NO_ARG) { + if (Repeat < Point) { + i = Point; + Point = Repeat; + reposition(); + (void)delete_string(i - Point); + } + else if (Repeat > Point) { + right(CSmove); + (void)delete_string(Repeat - Point - 1); + } + return CSmove; + } + + save_yank(Point, End - Point); + ceol(); + Line[Point] = '\0'; + End = Point; + return CSstay; +} + +static STATUS +insert_char(int c) +{ + STATUS s; + char buff[2]; + char *p; + char *q; + int i; + + if (Repeat == NO_ARG || Repeat < 2) { + buff[0] = c; + buff[1] = '\0'; + return insert_string(buff); + } + + if ((p = malloc(sizeof(char) * (Repeat + 1))) == NULL) + return CSstay; + for (i = Repeat, q = p; --i >= 0; ) + *q++ = c; + *q = '\0'; + Repeat = 0; + s = insert_string(p); + free(p); + return s; +} + +static STATUS +meta() +{ + int c; + KEYMAP *kp; + + if ((c = TTYget()) == EOF) + return CSeof; +#if defined(ANSI_ARROWS) + /* Also include VT-100 arrows. */ + if (c == '[' || c == 'O') + switch ((int)(c = TTYget())) { + default: return ring_bell(); + case EOF: return CSeof; + case 'A': return h_prev(); + case 'B': return h_next(); + case 'C': return fd_char(); + case 'D': return bk_char(); + } +#endif /* defined(ANSI_ARROWS) */ + + if (isdigit(c)) { + for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); ) + Repeat = Repeat * 10 + c - '0'; + Pushed = 1; + PushBack = c; + return CSstay; + } + + if (isupper(c)) + return do_macro(c); + for (OldPoint = Point, kp = MetaMap; kp < &MetaMap[METAMAPSIZE]; kp++) + if (kp->Key == c && kp->Active) + return (*kp->Function)(); + + return ring_bell(); +} + +static STATUS +emacs(int c) +{ + STATUS s; + KEYMAP *kp; + +#if 0 + /* This test makes it impossible to enter eight-bit characters when + * meta-char mode is enabled. */ + if (rl_meta_chars && ISMETA(c)) { + Pushed = 1; + PushBack = UNMETA(c); + return meta(); + } +#endif /* 0 */ + for (kp = Map; kp < &Map[MAPSIZE]; kp++) + if (kp->Key == c && kp->Active) + break; + s = kp < &Map[MAPSIZE] ? (*kp->Function)() : insert_char((int)c); + if (!Pushed) + /* No pushback means no repeat count; hacky, but true. */ + Repeat = NO_ARG; + return s; +} + +static STATUS +TTYspecial(int c) +{ + if (rl_meta_chars && ISMETA(c)) + return CSdispatch; + + if (c == rl_erase || c == DEL) + return bk_del_char(); + if (c == rl_kill) { + if (Point != 0) { + Point = 0; + reposition(); + } + Repeat = NO_ARG; + return kill_line(); + } + if (c == rl_eof && Point == 0 && End == 0) + return CSeof; + if (c == rl_intr) { + Signal = SIGINT; + return CSsignal; + } + if (c == rl_quit) { + Signal = SIGQUIT; + return CSsignal; + } +#if defined(DO_SIGTSTP) + if (c == rl_susp) { + Signal = SIGTSTP; + return CSsignal; + } +#endif /* defined(DO_SIGTSTP) */ + + return CSdispatch; +} + +static char * +editinput() +{ + int c; + + Repeat = NO_ARG; + OldPoint = Point = Mark = End = 0; + Line[0] = '\0'; + + Signal = -1; + while ((c = TTYget()) != EOF) + switch (TTYspecial(c)) { + case CSdone: + return Line; + case CSeof: + return NULL; + case CSsignal: + return (char *)""; + case CSmove: + reposition(); + break; + case CSdispatch: + switch (emacs(c)) { + case CSdone: + return Line; + case CSeof: + return NULL; + case CSsignal: + return (char *)""; + case CSmove: + reposition(); + break; + case CSdispatch: + case CSstay: + break; + } + break; + case CSstay: + break; + } + return NULL; +} + +static void +hist_add(char *p) +{ + int i; + + if ((p = strdup(p)) == NULL) + return; + if (H.Size < HIST_SIZE) + H.Lines[H.Size++] = p; + else { + free(H.Lines[0]); + for (i = 0; i < HIST_SIZE - 1; i++) + H.Lines[i] = H.Lines[i + 1]; + H.Lines[i] = p; + } + H.Pos = H.Size - 1; +} + +static char * +read_redirected() +{ + int size; + char *p; + char *line; + char *end; + + for (size = MEM_INC, p = line = malloc(sizeof(char) * size), end = p + size; ; p++) { + if (p == end) { + size += MEM_INC; + p = line = realloc(line, size); + end = p + size; + } + if (read(0, p, 1) <= 0) { + /* Ignore "incomplete" lines at EOF, just like we do for a tty. */ + free(line); + return NULL; + } + if (*p == '\n') + break; + } + *p = '\0'; + return line; +} + +/* +** For compatibility with FSF readline. +*/ +/* ARGSUSED0 */ +void +rl_reset_terminal(char *p) +{ + (void)p; /* Suppress warning */ +} + +void +rl_initialize() +{ +} + +int +rl_insert(int count, int c) +{ + if (count > 0) { + Repeat = count; + (void)insert_char(c); + (void)redisplay_no_nl(); + } + return 0; +} + +int (*rl_event_hook)(); + +int +rl_key_action(int c, char flag) +{ + KEYMAP *kp; + int size; + + (void)flag; /* Suppress warning */ + + if (ISMETA(c)) { + kp = MetaMap; + size = METAMAPSIZE; + } + else { + kp = Map; + size = MAPSIZE; + } + for ( ; --size >= 0; kp++) + if (kp->Key == c) { + kp->Active = c ? 1 : 0; + return 1; + } + return -1; +} + +char * +readline(const char *prompt) +{ + char *line; + int s; + + if (!isatty(0)) { + TTYflush(); + return read_redirected(); + } + + if (Line == NULL) { + Length = MEM_INC; + if ((Line = malloc(sizeof(char) * Length)) == NULL) + return NULL; + } + + TTYinfo(); + rl_ttyset(0); + hist_add(NIL); + ScreenSize = SCREEN_INC; + Screen = malloc(sizeof(char) * ScreenSize); + Prompt = prompt ? prompt : (char *)NIL; + TTYputs((const char *)Prompt); + if ((line = editinput()) != NULL) { + line = strdup(line); + TTYputs((const char *)NEWLINE); + TTYflush(); + } + rl_ttyset(1); + free(Screen); + free(H.Lines[--H.Size]); + if (Signal > 0) { + s = Signal; + Signal = 0; + (void)kill(getpid(), s); + } + return (char *)line; +} + +void +add_history(char *p) +{ + if (p == NULL || *p == '\0') + return; + +#if defined(UNIQUE_HISTORY) + if (H.Size && strcmp(p, H.Lines[H.Size - 1]) == 0) + return; +#endif /* defined(UNIQUE_HISTORY) */ + hist_add((char *)p); +} + + +static STATUS +beg_line() +{ + if (Point) { + Point = 0; + return CSmove; + } + return CSstay; +} + +static STATUS +del_char() +{ + return delete_string(Repeat == NO_ARG ? 1 : Repeat); +} + +static STATUS +end_line() +{ + if (Point != End) { + Point = End; + return CSmove; + } + return CSstay; +} + +/* +** Return allocated copy of word under cursor, moving cursor after the +** word. +*/ +static char * +find_word() +{ + static char SEPS[] = "\"#;&|^$=`'{}()<>\n\t "; + char *p; + char *new; + size_t len; + + /* Move forward to end of word. */ + p = &Line[Point]; + for ( ; Point < End && strchr(SEPS, (char)*p) == NULL; Point++, p++) + right(CSstay); + + /* Back up to beginning of word. */ + for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--) + continue; + len = Point - (p - Line) + 1; + if ((new = malloc(sizeof(char) * len)) == NULL) + return NULL; + memcpy(new, p, len); + new[len - 1] = '\0'; + return new; +} + +static STATUS +c_complete() +{ + char *p; + char *word; + int unique; + + word = find_word(); + p = (char *)rl_complete((char *)word, &unique); + if (word) + free(word); + if (p && *p) { + (void)insert_string(p); + if (!unique) + (void)ring_bell(); + free(p); + return redisplay_no_nl(); + } + return ring_bell(); +} + +static STATUS +c_possible() +{ + char **av; + char *word; + int ac; + + word = find_word(); + ac = rl_list_possib((char *)word, (char ***)&av); + if (word) + free(word); + if (ac) { + columns(ac, av); + while (--ac >= 0) + free(av[ac]); + free(av); + return redisplay_no_nl(); + } + return ring_bell(); +} + +static STATUS +accept_line() +{ + Line[End] = '\0'; + return CSdone; +} + +static STATUS +transpose() +{ + char c; + + if (Point) { + if (Point == End) + left(CSmove); + c = Line[Point - 1]; + left(CSstay); + Line[Point - 1] = Line[Point]; + TTYshow(Line[Point - 1]); + Line[Point++] = c; + TTYshow(c); + } + return CSstay; +} + +static STATUS +quote() +{ + int c; + + return (c = TTYget()) == EOF ? CSeof : insert_char((int)c); +} + +static STATUS +wipe() +{ + int i; + + if (Mark > End) + return ring_bell(); + + if (Point > Mark) { + i = Point; + Point = Mark; + Mark = i; + reposition(); + } + + return delete_string(Mark - Point); +} + +static STATUS +mk_set() +{ + Mark = Point; + return CSstay; +} + +static STATUS +exchange() +{ + int c; + + if ((c = TTYget()) != CTL('X')) + return c == EOF ? CSeof : ring_bell(); + + if ((c = Mark) <= End) { + Mark = Point; + Point = c; + return CSmove; + } + return CSstay; +} + +static STATUS +yank() +{ + if (Yanked && *Yanked) + return insert_string(Yanked); + return CSstay; +} + +static STATUS +copy_region() +{ + if (Mark > End) + return ring_bell(); + + if (Point > Mark) + save_yank(Mark, Point - Mark); + else + save_yank(Point, Mark - Point); + + return CSstay; +} + +static STATUS +move_to_char() +{ + int c; + int i; + char *p; + + if ((c = TTYget()) == EOF) + return CSeof; + for (i = Point + 1, p = &Line[i]; i < End; i++, p++) + if (*p == c) { + Point = i; + return CSmove; + } + return CSstay; +} + +static STATUS +fd_word() +{ + return do_forward(CSmove); +} + +static STATUS +fd_kill_word() +{ + int i; + + (void)do_forward(CSstay); + if (OldPoint != Point) { + i = Point - OldPoint; + Point = OldPoint; + return delete_string(i); + } + return CSstay; +} + +static STATUS +bk_word() +{ + int i; + char *p; + + i = 0; + do { + for (p = &Line[Point]; p > Line && !isalnum((int)p[-1]); p--) + left(CSmove); + + for (; p > Line && p[-1] != ' ' && isalnum((int)p[-1]); p--) + left(CSmove); + + if (Point == 0) + break; + } while (++i < Repeat); + + return CSstay; +} + +static STATUS +bk_kill_word() +{ + (void)bk_word(); + if (OldPoint != Point) + return delete_string(OldPoint - Point); + return CSstay; +} + +static int +argify(char *line, char ***avp) +{ + char *c; + char **p; + char **new; + int ac; + int i; + + i = MEM_INC; + if ((*avp = p = malloc(sizeof(char*) * i))== NULL) + return 0; + + for (c = line; isspace((int)*c); c++) + continue; + if (*c == '\n' || *c == '\0') + return 0; + + for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) { + if (isspace((int)*c)) { + *c++ = '\0'; + if (*c && *c != '\n') { + if (ac + 1 == i) { + new = malloc(sizeof(char*) * (i + MEM_INC)); + if (new == NULL) { + p[ac] = NULL; + return ac; + } + memcpy(new, p, i * sizeof (char **)); + i += MEM_INC; + free(p); + *avp = p = new; + } + p[ac++] = c; + } + } + else + c++; + } + *c = '\0'; + p[ac] = NULL; + return ac; +} + +static STATUS +last_argument() +{ + char **av; + char *p; + STATUS s; + int ac; + + if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL) + return ring_bell(); + + if ((p = strdup(p)) == NULL) + return CSstay; + ac = argify(p, &av); + + if (Repeat != NO_ARG) + s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell(); + else + s = ac ? insert_string(av[ac - 1]) : CSstay; + + if (ac) + free(av); + free(p); + return s; +} + +static KEYMAP Map[MAPSIZE] = { + { CTL('@'), 1, ring_bell }, + { CTL('A'), 1, beg_line }, + { CTL('B'), 1, bk_char }, + { CTL('D'), 1, del_char }, + { CTL('E'), 1, end_line }, + { CTL('F'), 1, fd_char }, + { CTL('G'), 1, ring_bell }, + { CTL('H'), 1, bk_del_char }, + { CTL('I'), 1, c_complete }, + { CTL('J'), 1, accept_line }, + { CTL('K'), 1, kill_line }, + { CTL('L'), 1, redisplay }, + { CTL('M'), 1, accept_line }, + { CTL('N'), 1, h_next }, + { CTL('O'), 1, ring_bell }, + { CTL('P'), 1, h_prev }, + { CTL('Q'), 1, ring_bell }, + { CTL('R'), 1, h_search }, + { CTL('S'), 1, ring_bell }, + { CTL('T'), 1, transpose }, + { CTL('U'), 1, ring_bell }, + { CTL('V'), 1, quote }, + { CTL('W'), 1, wipe }, + { CTL('X'), 1, exchange }, + { CTL('Y'), 1, yank }, + { CTL('Z'), 1, ring_bell }, + { CTL('['), 1, meta }, + { CTL(']'), 1, move_to_char }, + { CTL('^'), 1, ring_bell }, + { CTL('_'), 1, ring_bell }, +}; + +static KEYMAP MetaMap[16]= { + { CTL('H'), 1, bk_kill_word }, + { CTL('['), 1, c_possible }, + { DEL, 1, bk_kill_word }, + { ' ', 1, mk_set }, + { '.', 1, last_argument }, + { '<', 1, h_first }, + { '>', 1, h_last }, + { '?', 1, c_possible }, + { 'b', 1, bk_word }, + { 'd', 1, fd_kill_word }, + { 'f', 1, fd_word }, + { 'l', 1, case_down_word }, + { 'm', 1, toggle_meta_mode}, + { 'u', 1, case_up_word }, + { 'y', 1, yank }, + { 'w', 1, copy_region }, +}; diff --git a/ndb/src/common/editline/editline_internal.h b/ndb/src/common/editline/editline_internal.h new file mode 100644 index 00000000000..93c13e55edc --- /dev/null +++ b/ndb/src/common/editline/editline_internal.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* $Revision: 1.2 $ +** +** Internal header file for editline library. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined(SYS_UNIX) +#include "unix.h" +#endif /* defined(SYS_UNIX) */ + +#define MEM_INC 64 +#define SCREEN_INC 256 + +/* +** Variables and routines internal to this package. +*/ +extern int rl_eof; +extern int rl_erase; +extern int rl_intr; +extern int rl_kill; +extern int rl_quit; +#if defined(DO_SIGTSTP) +extern int rl_susp; +#endif /* defined(DO_SIGTSTP) */ +extern char *rl_complete(); +extern int rl_list_possib(); +extern void rl_ttyset(); +extern void rl_add_slash(); + diff --git a/ndb/src/common/editline/editline_win32.c b/ndb/src/common/editline/editline_win32.c new file mode 100644 index 00000000000..feef0108523 --- /dev/null +++ b/ndb/src/common/editline/editline_win32.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#include <stdio.h> +#include <malloc.h> + + +char* readline(const char* prompt) +{ + char* szBuf; + printf(prompt); + szBuf = (char*)malloc(256); + return gets(szBuf); +} + +void add_history(char* pch) +{ +} + diff --git a/ndb/src/common/editline/sysunix.c b/ndb/src/common/editline/sysunix.c new file mode 100644 index 00000000000..000bca78dfc --- /dev/null +++ b/ndb/src/common/editline/sysunix.c @@ -0,0 +1,143 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* $Revision: 1.4 $ +** +** Unix system-dependant routines for editline library. +*/ +#include "editline_internal.h" + +#if defined(HAVE_TCGETATTR) +#include <termios.h> + +void +rl_ttyset(int Reset) +{ + static struct termios old; + struct termios new; + + if (Reset == 0) { + if (tcgetattr(0, &old) < 0) perror("tcgetattr"); + rl_erase = old.c_cc[VERASE]; + rl_kill = old.c_cc[VKILL]; + rl_eof = old.c_cc[VEOF]; + rl_intr = old.c_cc[VINTR]; + rl_quit = old.c_cc[VQUIT]; +#if defined(DO_SIGTSTP) + rl_susp = old.c_cc[VSUSP]; +#endif /* defined(DO_SIGTSTP) */ + + new = old; + new.c_lflag &= ~(ECHO | ICANON | ISIG); + new.c_iflag &= ~(ISTRIP | INPCK); + new.c_cc[VMIN] = 1; + new.c_cc[VTIME] = 0; + if (tcsetattr(0, TCSADRAIN, &new) < 0) perror("tcsetattr"); + } + else + (void)tcsetattr(0, TCSADRAIN, &old); +} + +#else +#if defined(HAVE_TERMIO) +#include <termio.h> + +void +rl_ttyset(int Reset) +{ + static struct termio old; + struct termio new; + + if (Reset == 0) { + (void)ioctl(0, TCGETA, &old); + rl_erase = old.c_cc[VERASE]; + rl_kill = old.c_cc[VKILL]; + rl_eof = old.c_cc[VEOF]; + rl_intr = old.c_cc[VINTR]; + rl_quit = old.c_cc[VQUIT]; +#if defined(DO_SIGTSTP) + rl_susp = old.c_cc[VSUSP]; +#endif /* defined(DO_SIGTSTP) */ + + new = old; + new.c_lflag &= ~(ECHO | ICANON | ISIG); + new.c_iflag &= ~(ISTRIP | INPCK); + new.c_cc[VMIN] = 1; + new.c_cc[VTIME] = 0; + (void)ioctl(0, TCSETAW, &new); + } + else + (void)ioctl(0, TCSETAW, &old); +} + +#else +#include <sgtty.h> + +void +rl_ttyset(int Reset) +{ + static struct sgttyb old_sgttyb; + static struct tchars old_tchars; + struct sgttyb new_sgttyb; + struct tchars new_tchars; +#if defined(DO_SIGTSTP) + struct ltchars old_ltchars; +#endif /* defined(DO_SIGTSTP) */ + + if (Reset == 0) { + (void)ioctl(0, TIOCGETP, &old_sgttyb); + rl_erase = old_sgttyb.sg_erase; + rl_kill = old_sgttyb.sg_kill; + + (void)ioctl(0, TIOCGETC, &old_tchars); + rl_eof = old_tchars.t_eofc; + rl_intr = old_tchars.t_intrc; + rl_quit = old_tchars.t_quitc; + +#if defined(DO_SIGTSTP) + (void)ioctl(0, TIOCGLTC, &old_ltchars); + rl_susp = old_ltchars.t_suspc; +#endif /* defined(DO_SIGTSTP) */ + + new_sgttyb = old_sgttyb; + new_sgttyb.sg_flags &= ~ECHO; + new_sgttyb.sg_flags |= RAW; +#if defined(PASS8) + new_sgttyb.sg_flags |= PASS8; +#endif /* defined(PASS8) */ + (void)ioctl(0, TIOCSETP, &new_sgttyb); + + new_tchars = old_tchars; + new_tchars.t_intrc = -1; + new_tchars.t_quitc = -1; + (void)ioctl(0, TIOCSETC, &new_tchars); + } + else { + (void)ioctl(0, TIOCSETP, &old_sgttyb); + (void)ioctl(0, TIOCSETC, &old_tchars); + } +} +#endif /* defined(HAVE_TERMIO) */ +#endif /* defined(HAVE_TCGETATTR) */ + +void +rl_add_slash(char *path, char *p, size_t p_len) +{ + struct stat Sb; + + if (stat(path, &Sb) >= 0) + (void)strlcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ", p_len); +} diff --git a/ndb/src/common/editline/test/Makefile b/ndb/src/common/editline/test/Makefile new file mode 100644 index 00000000000..20229d0aa62 --- /dev/null +++ b/ndb/src/common/editline/test/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE := util + +BIN_TARGET := editline_test +BIN_TARGET_ARCHIVES := editline + +SOURCES = testit.c + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/editline/test/testit.c b/ndb/src/common/editline/test/testit.c new file mode 100644 index 00000000000..9a7dfb7bbdf --- /dev/null +++ b/ndb/src/common/editline/test/testit.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* -*- c-basic-offset: 4; -*- +** $Revision: 1.5 $ +** +** A "micro-shell" to test editline library. +** If given any arguments, commands aren't executed. +*/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <NdbString.h> +#include <editline/editline.h> + +int +main(int argc, char **argv) +{ + char *prompt; + char *p; + int doit; + + (void)argv; /* Suppress warning */ + + doit = argc == 1; + if ((prompt = getenv("TESTPROMPT")) == NULL) + prompt = "testit> "; + + while ((p = readline(prompt)) != NULL) { + (void)printf("\t\t\t|%s|\n", p); + if (doit) { + if (strncmp(p, "cd ", 3) == 0) { + if (chdir(&p[3]) < 0) + perror(&p[3]); + } else { + if (system(p) != 0) + perror(p); + } + } + add_history(p); + free(p); + } + + return 0; +} diff --git a/ndb/src/common/editline/unix.h b/ndb/src/common/editline/unix.h new file mode 100644 index 00000000000..582c4888856 --- /dev/null +++ b/ndb/src/common/editline/unix.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* $Revision: 1.3 $ +** +** Editline system header file for Unix. +*/ + +#define CRLF "\r\n" + +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> |