Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
8eeca90b
Commit
8eeca90b
authored
Nov 08, 2004
by
tomas@poseidon.ndb.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-4.1
into poseidon.ndb.mysql.com:/home/tomas/mysql-4.1
parents
b7776f83
9f999953
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
273 additions
and
2663 deletions
+273
-2663
configure.in
configure.in
+0
-1
ndb/src/common/Makefile.am
ndb/src/common/Makefile.am
+1
-1
ndb/src/common/Makefile_old
ndb/src/common/Makefile_old
+0
-15
ndb/src/common/editline/MANIFEST
ndb/src/common/editline/MANIFEST
+0
-15
ndb/src/common/editline/Makefile.am
ndb/src/common/editline/Makefile.am
+0
-10
ndb/src/common/editline/Makefile_old
ndb/src/common/editline/Makefile_old
+0
-18
ndb/src/common/editline/README
ndb/src/common/editline/README
+0
-53
ndb/src/common/editline/complete.c
ndb/src/common/editline/complete.c
+0
-195
ndb/src/common/editline/editline.3
ndb/src/common/editline/editline.3
+0
-178
ndb/src/common/editline/editline.c
ndb/src/common/editline/editline.c
+0
-1498
ndb/src/common/editline/editline_internal.h
ndb/src/common/editline/editline_internal.h
+0
-30
ndb/src/common/editline/sysunix.c
ndb/src/common/editline/sysunix.c
+0
-132
ndb/src/common/editline/test/Makefile
ndb/src/common/editline/test/Makefile
+0
-10
ndb/src/common/editline/test/testit.c
ndb/src/common/editline/test/testit.c
+0
-55
ndb/src/common/editline/unix.h
ndb/src/common/editline/unix.h
+0
-9
ndb/src/mgmclient/CommandInterpreter.cpp
ndb/src/mgmclient/CommandInterpreter.cpp
+227
-175
ndb/src/mgmclient/CommandInterpreter.hpp
ndb/src/mgmclient/CommandInterpreter.hpp
+0
-197
ndb/src/mgmclient/Makefile.am
ndb/src/mgmclient/Makefile.am
+7
-6
ndb/src/mgmclient/Makefile_old
ndb/src/mgmclient/Makefile_old
+0
-25
ndb/src/mgmclient/main.cpp
ndb/src/mgmclient/main.cpp
+4
-4
ndb/src/mgmclient/ndb_mgmclient.hpp
ndb/src/mgmclient/ndb_mgmclient.hpp
+15
-14
ndb/src/mgmsrv/CommandInterpreter.hpp
ndb/src/mgmsrv/CommandInterpreter.hpp
+14
-14
ndb/src/mgmsrv/Makefile.am
ndb/src/mgmsrv/Makefile.am
+0
-1
ndb/test/include/CpcClient.hpp
ndb/test/include/CpcClient.hpp
+0
-0
ndb/test/run-test/Makefile.am
ndb/test/run-test/Makefile.am
+2
-3
ndb/test/src/CpcClient.cpp
ndb/test/src/CpcClient.cpp
+0
-0
ndb/test/src/Makefile.am
ndb/test/src/Makefile.am
+2
-1
ndb/test/tools/Makefile.am
ndb/test/tools/Makefile.am
+1
-3
No files found.
configure.in
View file @
8eeca90b
...
...
@@ -3093,7 +3093,6 @@ AC_CONFIG_FILES(ndb/Makefile ndb/include/Makefile dnl
ndb/src/common/logger/Makefile dnl
ndb/src/common/transporter/Makefile dnl
ndb/src/common/mgmcommon/Makefile dnl
ndb/src/common/editline/Makefile dnl
ndb/src/kernel/Makefile dnl
ndb/src/kernel/error/Makefile dnl
ndb/src/kernel/blocks/Makefile dnl
...
...
ndb/src/common/Makefile.am
View file @
8eeca90b
SUBDIRS
=
portlib debugger util logger transporter mgmcommon
editline
SUBDIRS
=
portlib debugger util logger transporter mgmcommon
noinst_LTLIBRARIES
=
libcommon.la
...
...
ndb/src/common/Makefile_old
deleted
100644 → 0
View file @
b7776f83
include .defs.mk
LIB_DIRS := \
portlib \
debugger \
util \
logger
ifneq ($(USE_EDITLINE), N)
LIB_DIRS += editline
endif
DIRS := transporter mgmcommon
include $(NDB_TOP)/Epilogue.mk
ndb/src/common/editline/MANIFEST
deleted
100644 → 0
View file @
b7776f83
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
ndb/src/common/editline/Makefile.am
deleted
100644 → 0
View file @
b7776f83
noinst_LIBRARIES
=
libeditline.a
libeditline_a_SOURCES
=
complete.c editline.c sysunix.c
INCLUDES
=
-I
$(top_srcdir)
/include
-I
$(top_srcdir)
/ndb/include
DEFS
=
-DANSI_ARROWS
-DHAVE_TCGETATTR
-DSYS_UNIX
# Don't update the files from bitkeeper
%
::
SCCS/s.%
ndb/src/common/editline/Makefile_old
deleted
100644 → 0
View file @
b7776f83
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
ndb/src/common/editline/README
deleted
100644 → 0
View file @
b7776f83
--
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.
ndb/src/common/editline/complete.c
deleted
100644 → 0
View file @
b7776f83
/* -*- 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
;
}
ndb/src/common/editline/editline.3
deleted
100644 → 0
View file @
b7776f83
.\" $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>.
ndb/src/common/editline/editline.c
deleted
100644 → 0
View file @
b7776f83
/* -*- c-basic-offset: 4; -*-
** $Revision: 1.6 $
**
** Main editing routines for editline library.
*/
#include <ndb_global.h>
#include "editline_internal.h"
#include <signal.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
},
};
ndb/src/common/editline/editline_internal.h
deleted
100644 → 0
View file @
b7776f83
/* $Revision: 1.2 $
**
** Internal header file for editline library.
*/
#include <ndb_global.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
();
ndb/src/common/editline/sysunix.c
deleted
100644 → 0
View file @
b7776f83
/* $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
)
{
size_t
len
=
strlen
(
p
);
if
(
len
+
1
<
p_len
)
{
p
[
len
]
=
S_ISDIR
(
Sb
.
st_mode
)
?
'/'
:
' '
;
p
[
len
+
1
]
=
0
;
}
}
}
ndb/src/common/editline/test/Makefile
deleted
100644 → 0
View file @
b7776f83
include
.defs.mk
TYPE
:=
util
BIN_TARGET
:=
editline_test
BIN_TARGET_ARCHIVES
:=
editline
SOURCES
=
testit.c
include
$(NDB_TOP)/Epilogue.mk
ndb/src/common/editline/test/testit.c
deleted
100644 → 0
View file @
b7776f83
/* 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 <ndb_global.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
;
}
ndb/src/common/editline/unix.h
deleted
100644 → 0
View file @
b7776f83
/* $Revision: 1.3 $
**
** Editline system header file for Unix.
*/
#define CRLF "\r\n"
#include <ndb_global.h>
#include <dirent.h>
ndb/src/mgmclient/CommandInterpreter.cpp
View file @
8eeca90b
...
...
@@ -17,7 +17,195 @@
#include <ndb_global.h>
#include <my_sys.h>
#include "CommandInterpreter.hpp"
// copied from mysql.cc to get readline
extern
"C"
{
#if defined( __WIN__) || defined(OS2)
#include <conio.h>
#elif !defined(__NETWARE__)
#include <readline/readline.h>
extern
"C"
int
add_history
(
const
char
*
command
);
/* From readline directory */
#define HAVE_READLINE
#endif
}
//#define HAVE_GLOBAL_REPLICATION
#include <Vector.hpp>
#ifdef HAVE_GLOBAL_REPLICATION
#include "../rep/repapi/repapi.h"
#endif
#include <mgmapi.h>
class
MgmtSrvr
;
/**
* @class CommandInterpreter
* @brief Reads command line in management client
*
* This class has one public method which reads a command line
* from a stream. It then interpret that commmand line and calls a suitable
* method in the MgmtSrvr class which executes the command.
*
* For command syntax, see the HELP command.
*/
class
CommandInterpreter
{
public:
/**
* Constructor
* @param mgmtSrvr: Management server to use when executing commands
*/
CommandInterpreter
(
const
char
*
);
~
CommandInterpreter
();
/**
* Reads one line from the stream, parse the line to find
* a command and then calls a suitable method which executes
* the command.
*
* @return true until quit/bye/exit has been typed
*/
int
readAndExecute
(
int
_try_reconnect
=-
1
);
int
execute
(
const
char
*
_line
,
int
_try_reconnect
=-
1
);
private:
void
printError
();
/**
* Analyse the command line, after the first token.
*
* @param processId: DB process id to send command to or -1 if
* command will be sent to all DB processes.
* @param allAfterFirstToken: What the client gave after the
* first token on the command line
*/
void
analyseAfterFirstToken
(
int
processId
,
char
*
allAfterFirstTokenCstr
);
/**
* Parse the block specification part of the LOG* commands,
* things after LOG*: [BLOCK = {ALL|<blockName>+}]
*
* @param allAfterLog: What the client gave after the second token
* (LOG*) on the command line
* @param blocks, OUT: ALL or name of all the blocks
* @return: true if correct syntax, otherwise false
*/
bool
parseBlockSpecification
(
const
char
*
allAfterLog
,
Vector
<
const
char
*>&
blocks
);
/**
* A bunch of execute functions: Executes one of the commands
*
* @param processId: DB process id to send command to
* @param parameters: What the client gave after the command name
* on the command line.
* For example if complete input from user is: "1 LOGLEVEL 22" then the
* parameters argument is the string with everything after LOGLEVEL, in
* this case "22". Each function is responsible to check the parameters
* argument.
*/
void
executeHelp
(
char
*
parameters
);
void
executeShow
(
char
*
parameters
);
void
executeShutdown
(
char
*
parameters
);
void
executeRun
(
char
*
parameters
);
void
executeInfo
(
char
*
parameters
);
void
executeClusterLog
(
char
*
parameters
);
public:
void
executeStop
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeEnterSingleUser
(
char
*
parameters
);
void
executeExitSingleUser
(
char
*
parameters
);
void
executeStart
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeRestart
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogLevel
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeError
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeTrace
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLog
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogIn
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogOut
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogOff
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeTestOn
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeTestOff
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeSet
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeGetStat
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeStatus
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeEventReporting
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeDumpState
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeStartBackup
(
char
*
parameters
);
void
executeAbortBackup
(
char
*
parameters
);
void
executeRep
(
char
*
parameters
);
void
executeCpc
(
char
*
parameters
);
public:
bool
connect
();
bool
disconnect
();
/**
* A execute function definition
*/
public:
typedef
void
(
CommandInterpreter
::*
ExecuteFunction
)(
int
processId
,
const
char
*
param
,
bool
all
);
struct
CommandFunctionPair
{
const
char
*
command
;
ExecuteFunction
executeFunction
;
};
private:
/**
*
*/
void
executeForAll
(
const
char
*
cmd
,
ExecuteFunction
fun
,
const
char
*
param
);
NdbMgmHandle
m_mgmsrv
;
bool
connected
;
const
char
*
host
;
int
try_reconnect
;
#ifdef HAVE_GLOBAL_REPLICATION
NdbRepHandle
m_repserver
;
const
char
*
rep_host
;
bool
rep_connected
;
#endif
};
/*
* Facade object for CommandInterpreter
*/
#include "ndb_mgmclient.hpp"
Ndb_mgmclient
::
Ndb_mgmclient
(
const
char
*
host
)
{
m_cmd
=
new
CommandInterpreter
(
host
);
}
Ndb_mgmclient
::~
Ndb_mgmclient
()
{
delete
m_cmd
;
}
int
Ndb_mgmclient
::
read_and_execute
(
int
_try_reconnect
)
{
return
m_cmd
->
readAndExecute
(
_try_reconnect
);
}
int
Ndb_mgmclient
::
execute
(
const
char
*
_line
,
int
_try_reconnect
)
{
return
m_cmd
->
execute
(
_line
,
_try_reconnect
);
}
int
Ndb_mgmclient
::
disconnect
()
{
return
m_cmd
->
disconnect
();
}
/*
* The CommandInterpreter
*/
#include <mgmapi.h>
#include <mgmapi_debug.h>
...
...
@@ -33,7 +221,10 @@
#endif // HAVE_GLOBAL_REPLICATION
#include "MgmtErrorReporter.hpp"
#include "CpcClient.hpp"
#include <Parser.hpp>
#include <SocketServer.hpp>
#include <util/InputStream.hpp>
#include <util/OutputStream.hpp>
/*****************************************************************************
...
...
@@ -201,7 +392,7 @@ CommandInterpreter::~CommandInterpreter()
host
=
NULL
;
}
bool
static
bool
emptyString
(
const
char
*
s
)
{
if
(
s
==
NULL
)
{
...
...
@@ -265,17 +456,47 @@ CommandInterpreter::disconnect()
int
CommandInterpreter
::
readAndExecute
(
int
_try_reconnect
)
{
static
char
*
line_read
=
(
char
*
)
NULL
;
/* If the buffer has already been allocated, return the memory
to the free pool. */
if
(
line_read
)
{
free
(
line_read
);
line_read
=
(
char
*
)
NULL
;
}
#ifdef HAVE_READLINE
/* Get a line from the user. */
line_read
=
readline
(
"ndb_mgm> "
);
/* If the line has any text in it, save it on the history. */
if
(
line_read
&&
*
line_read
)
add_history
(
line_read
);
#else
static
char
linebuffer
[
254
];
fputs
(
"ndb_mgm> "
,
stdout
);
linebuffer
[
sizeof
(
linebuffer
)
-
1
]
=
0
;
line_read
=
fgets
(
linebuffer
,
sizeof
(
linebuffer
)
-
1
,
stdin
);
if
(
line_read
==
linebuffer
)
{
char
*
q
=
linebuffer
;
while
(
*
q
>
31
)
q
++
;
*
q
=
0
;
line_read
=
strdup
(
linebuffer
);
}
#endif
return
execute
(
line_read
,
_try_reconnect
);
}
int
CommandInterpreter
::
execute
(
const
char
*
_line
,
int
_try_reconnect
)
{
if
(
_try_reconnect
>=
0
)
try_reconnect
=
_try_reconnect
;
char
*
_line
=
readline_gets
();
char
*
line
;
if
(
_line
==
NULL
)
{
// ndbout << endl;
return
false
;
}
line
=
my_strdup
(
_line
,
MYF
(
MY_WME
));
My_auto_ptr
<
char
>
ptr
(
line
);
...
...
@@ -349,10 +570,6 @@ CommandInterpreter::readAndExecute(int _try_reconnect)
strcmp
(
firstToken
,
"BYE"
)
==
0
)
&&
allAfterFirstToken
==
NULL
){
return
false
;
#if 0
} else if(strcmp(firstToken, "CPC") == 0) {
executeCpc(allAfterFirstToken);
#endif
}
else
{
/**
* First token should be a digit, node ID
...
...
@@ -1903,169 +2120,4 @@ CommandInterpreter::executeRep(char* parameters)
}
#endif // HAVE_GLOBAL_REPLICATION
/*****************************************************************************
* CPC
*****************************************************************************/
#if 0
#if 0
//#ifdef NDB_SOLARIS // XXX fix me
static char* strsep(char** x, const char* y) { return 0; }
#endif
// Note this code has not been verified
#if 0
static char * my_strsep(char **stringp, const char *delim)
{
char *tmp= *stringp;
if (tmp == 0)
return 0;
*stringp = strtok(tmp, delim);
return tmp;
}
#endif
void
CommandInterpreter::executeCpc(char *parameters)
{
char *host_str = NULL, *port_str = NULL, *end;
long port = 1234; /* XXX */
while((host_str = my_strsep(¶meters, " \t:")) != NULL &&
host_str[0] == '\0');
if(parameters && parameters[0] != '\0') {
while((port_str = my_strsep(¶meters, " \t:")) != NULL &&
port_str[0] == '\0');
errno = 0;
port = strtol(port_str, &end, 0);
if(end[0] != '\0')
goto error;
if((port == LONG_MAX || port == LONG_MIN) &&
errno == ERANGE)
goto error;
}
{
SimpleCpcClient cpc(host_str, port);
bool done = false;
if(cpc.connect() < 0) {
ndbout_c("Cannot connect to %s:%d.", cpc.getHost(), cpc.getPort());
switch(errno) {
case ENOENT:
ndbout << ": " << "No such host" << endl;
break;
default:
ndbout << ": " << strerror(errno) << endl;
break;
}
return;
}
while(!done) {
char *line = readline("CPC> ");
if(line != NULL) {
add_history(line);
char *cmd = strtok(line, " ");
char *arg = strtok(NULL, "");
if(arg != NULL) {
while(arg[0] == ' ')
arg++;
if(strlen(arg) == 0)
arg = NULL;
}
if(cmd != NULL) {
if(strcmp(cmd, "exit") == 0)
done = true;
else if(strcmp(cmd, "list") == 0)
cpc.cmd_list(arg);
else if(strcmp(cmd, "start") == 0)
cpc.cmd_start(arg);
else if(strcmp(cmd, "stop") == 0)
cpc.cmd_stop(arg);
else if(strcmp(cmd, "help") == 0)
cpc.cmd_help(arg);
}
} else {
done = true;
ndbout << endl;
}
}
}
return;
error:
ndbout << "Error: expected a tcp port number, got '" << port_str << "'."
<< endl;
return;
}
#endif
#if 0
static
void
CmdBackupCallback(const MgmtSrvr::BackupEvent & event){
char str[255];
ndbout << endl;
bool ok = false;
switch(event.Event){
case MgmtSrvr::BackupEvent::BackupStarted:
ok = true;
BaseString::snprintf(str, sizeof(str),
"Backup %d started", event.Started.BackupId);
break;
case MgmtSrvr::BackupEvent::BackupFailedToStart:
ok = true;
BaseString::snprintf(str, sizeof(str),
"Backup failed to start (Error %d)",
event.FailedToStart.ErrorCode);
break;
case MgmtSrvr::BackupEvent::BackupCompleted:
ok = true;
BaseString::snprintf(str, sizeof(str),
"Backup %d completed",
event.Completed.BackupId);
ndbout << str << endl;
BaseString::snprintf(str, sizeof(str),
" StartGCP: %d StopGCP: %d",
event.Completed.startGCP, event.Completed.stopGCP);
ndbout << str << endl;
BaseString::snprintf(str, sizeof(str),
" #Records: %d #LogRecords: %d",
event.Completed.NoOfRecords, event.Completed.NoOfLogRecords);
ndbout << str << endl;
BaseString::snprintf(str, sizeof(str),
" Data: %d bytes Log: %d bytes",
event.Completed.NoOfBytes, event.Completed.NoOfLogBytes);
break;
case MgmtSrvr::BackupEvent::BackupAborted:
ok = true;
BaseString::snprintf(str, sizeof(str),
"Backup %d has been aborted reason %d",
event.Aborted.BackupId,
event.Aborted.Reason);
break;
}
if(!ok){
BaseString::snprintf(str, sizeof(str),
"Unknown backup event: %d",
event.Event);
}
ndbout << str << endl;
}
#endif
template
class
Vector
<
char
const
*
>;
ndb/src/mgmclient/CommandInterpreter.hpp
deleted
100644 → 0
View file @
b7776f83
/* 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 */
#ifndef CommandInterpreter_H
#define CommandInterpreter_H
//#define HAVE_GLOBAL_REPLICATION
//*****************************************************************************
// Author: Peter Lind
//*****************************************************************************
#include <ndb_global.h>
#include <Vector.hpp>
#include <editline/editline.h>
#ifdef HAVE_GLOBAL_REPLICATION
#include "../rep/repapi/repapi.h"
#endif
#include <mgmapi.h>
class
MgmtSrvr
;
/**
* @class CommandInterpreter
* @brief Reads command line in management client
*
* This class has one public method which reads a command line
* from a stream. It then interpret that commmand line and calls a suitable
* method in the MgmtSrvr class which executes the command.
*
* For command syntax, see the HELP command.
*/
class
CommandInterpreter
{
public:
/**
* Constructor
* @param mgmtSrvr: Management server to use when executing commands
*/
CommandInterpreter
(
const
char
*
);
~
CommandInterpreter
();
/**
* Reads one line from the stream, parse the line to find
* a command and then calls a suitable method which executes
* the command.
*
* @return true until quit/bye/exit has been typed
*/
int
readAndExecute
(
int
_try_reconnect
=-
1
);
private:
/**
* Read a string, and return a pointer to it.
*
* @return NULL on EOF.
*/
char
*
readline_gets
()
{
static
char
*
line_read
=
(
char
*
)
NULL
;
/* If the buffer has already been allocated, return the memory
to the free pool. */
if
(
line_read
)
{
free
(
line_read
);
line_read
=
(
char
*
)
NULL
;
}
/* Get a line from the user. */
line_read
=
readline
(
"NDB> "
);
/* If the line has any text in it, save it on the history. */
if
(
line_read
&&
*
line_read
)
add_history
(
line_read
);
return
(
line_read
);
}
void
printError
();
/**
* Analyse the command line, after the first token.
*
* @param processId: DB process id to send command to or -1 if
* command will be sent to all DB processes.
* @param allAfterFirstToken: What the client gave after the
* first token on the command line
*/
void
analyseAfterFirstToken
(
int
processId
,
char
*
allAfterFirstTokenCstr
);
/**
* Parse the block specification part of the LOG* commands,
* things after LOG*: [BLOCK = {ALL|<blockName>+}]
*
* @param allAfterLog: What the client gave after the second token
* (LOG*) on the command line
* @param blocks, OUT: ALL or name of all the blocks
* @return: true if correct syntax, otherwise false
*/
bool
parseBlockSpecification
(
const
char
*
allAfterLog
,
Vector
<
const
char
*>&
blocks
);
/**
* A bunch of execute functions: Executes one of the commands
*
* @param processId: DB process id to send command to
* @param parameters: What the client gave after the command name
* on the command line.
* For example if complete input from user is: "1 LOGLEVEL 22" then the
* parameters argument is the string with everything after LOGLEVEL, in
* this case "22". Each function is responsible to check the parameters
* argument.
*/
void
executeHelp
(
char
*
parameters
);
void
executeShow
(
char
*
parameters
);
void
executeShutdown
(
char
*
parameters
);
void
executeRun
(
char
*
parameters
);
void
executeInfo
(
char
*
parameters
);
void
executeClusterLog
(
char
*
parameters
);
public:
void
executeStop
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeEnterSingleUser
(
char
*
parameters
);
void
executeExitSingleUser
(
char
*
parameters
);
void
executeStart
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeRestart
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogLevel
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeError
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeTrace
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLog
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogIn
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogOut
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeLogOff
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeTestOn
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeTestOff
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeSet
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeGetStat
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeStatus
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeEventReporting
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeDumpState
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeStartBackup
(
char
*
parameters
);
void
executeAbortBackup
(
char
*
parameters
);
void
executeRep
(
char
*
parameters
);
void
executeCpc
(
char
*
parameters
);
public:
bool
connect
();
bool
disconnect
();
/**
* A execute function definition
*/
public:
typedef
void
(
CommandInterpreter
::*
ExecuteFunction
)(
int
processId
,
const
char
*
param
,
bool
all
);
struct
CommandFunctionPair
{
const
char
*
command
;
ExecuteFunction
executeFunction
;
};
private:
/**
*
*/
void
executeForAll
(
const
char
*
cmd
,
ExecuteFunction
fun
,
const
char
*
param
);
NdbMgmHandle
m_mgmsrv
;
bool
connected
;
const
char
*
host
;
int
try_reconnect
;
#ifdef HAVE_GLOBAL_REPLICATION
NdbRepHandle
m_repserver
;
const
char
*
rep_host
;
bool
rep_connected
;
#endif
};
#endif // CommandInterpreter_H
ndb/src/mgmclient/Makefile.am
View file @
8eeca90b
ndbtools_PROGRAMS
=
ndb_mgm
noinst_LTLIBRARIES
=
libndbmgmclient.la
ndb_mgm_SOURCES
=
\
main.cpp
\
CommandInterpreter.cpp
\
CpcClient.cpp
libndbmgmclient_la_SOURCES
=
CommandInterpreter.cpp
ndb_mgm_SOURCES
=
main.cpp
include
$(top_srcdir)/ndb/config/common.mk.am
include
$(top_srcdir)/ndb/config/type_ndbapi.mk.am
INCLUDES
+=
-I
$(top_srcdir)
/ndb/include/mgmapi
-I
$(top_srcdir)
/ndb/src/common/mgmcommon
LDADD_LOC
=
$(top_builddir)
/ndb/src/libndbclient.la
\
$(top_builddir)
/ndb/src/common/editline/libeditline.a
\
LDADD_LOC
=
$(top_builddir)
/ndb/src/mgmclient/libndbmgmclient.la
\
@readline_link@
\
$(top_builddir)
/ndb/src/libndbclient.la
\
$(top_builddir)
/dbug/libdbug.a
\
$(top_builddir)
/mysys/libmysys.a
\
$(top_builddir)
/strings/libmystrings.a
\
...
...
ndb/src/mgmclient/Makefile_old
deleted
100644 → 0
View file @
b7776f83
include .defs.mk
TYPE := ndbapi
BIN_TARGET := mgmtclient
BIN_TARGET_LIBS :=
BIN_TARGET_ARCHIVES := trace logger mgmapi general mgmsrvcommon portlib repapi
BIN_TARGET_ARCHIVES += editline
DIRS = test_cpcd
# Source files of non-templated classes (.cpp files)
SOURCES = \
main.cpp \
CommandInterpreter.cpp \
CpcClient.cpp
CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \
-I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon)
include $(NDB_TOP)/Epilogue.mk
_bins_mkconfig : $(NDB_TOP)/bin/$(BIN_TARGET)
ndb/src/mgmclient/main.cpp
View file @
8eeca90b
...
...
@@ -23,12 +23,12 @@
#include <ndb_version.h>
#include <LocalConfig.hpp>
#include "
CommandInterpreter
.hpp"
#include "
ndb_mgmclient
.hpp"
const
char
*
progname
=
"ndb_mgm"
;
static
CommandInterpreter
*
com
;
static
Ndb_mgmclient
*
com
;
extern
"C"
void
...
...
@@ -127,8 +127,8 @@ int main(int argc, char** argv){
signal
(
SIGPIPE
,
handler
);
com
=
new
CommandInterpreter
(
buf
);
while
(
com
->
read
AndE
xecute
(
_try_reconnect
));
com
=
new
Ndb_mgmclient
(
buf
);
while
(
com
->
read
_and_e
xecute
(
_try_reconnect
));
delete
com
;
return
0
;
...
...
ndb/src/
common/editline/editline_win32.c
→
ndb/src/
mgmclient/ndb_mgmclient.hpp
View file @
8eeca90b
...
...
@@ -14,19 +14,20 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef Ndb_mgmclient_h
#define Ndb_mgmclient_h
#include <ndb_global.h>
char
*
readline
(
const
char
*
prompt
)
class
CommandInterpreter
;
class
Ndb_mgmclient
{
char
*
szBuf
;
printf
(
prompt
);
szBuf
=
(
char
*
)
malloc
(
256
);
return
gets
(
szBuf
);
}
void
add_history
(
char
*
pch
)
{
}
public:
Ndb_mgmclient
(
const
char
*
);
~
Ndb_mgmclient
();
int
read_and_execute
(
int
_try_reconnect
=-
1
);
int
execute
(
const
char
*
_line
,
int
_try_reconnect
=-
1
);
int
disconnect
();
private:
CommandInterpreter
*
m_cmd
;
};
#endif // Ndb_mgmclient_h
ndb/src/mgmsrv/CommandInterpreter.hpp
View file @
8eeca90b
...
...
@@ -23,7 +23,6 @@
#include <ndb_global.h>
#include <Vector.hpp>
#include <editline/editline.h>
#include <BaseString.hpp>
class
MgmtSrvr
;
...
...
@@ -63,26 +62,27 @@ private:
*/
char
*
readline_gets
()
{
static
char
linebuffer
[
254
];
static
char
*
line_read
=
(
char
*
)
NULL
;
// Disable the default file-name completion action of TAB
// rl_bind_key ('\t', rl_insert);
/* If the buffer has already been allocated, return the memory
to the free pool. */
if
(
line_read
)
{
free
(
line_read
);
line_read
=
(
char
*
)
NULL
;
}
{
free
(
line_read
);
line_read
=
(
char
*
)
NULL
;
}
/* Get a line from the user. */
line_read
=
readline
(
"NDB> "
);
/* If the line has any text in it, save it on the history. */
if
(
line_read
&&
*
line_read
)
add_history
(
line_read
);
fputs
(
"ndb_mgmd> "
,
stdout
);
linebuffer
[
sizeof
(
linebuffer
)
-
1
]
=
0
;
line_read
=
fgets
(
linebuffer
,
sizeof
(
linebuffer
)
-
1
,
stdin
);
if
(
line_read
==
linebuffer
)
{
char
*
q
=
linebuffer
;
while
(
*
q
>
31
)
q
++
;
*
q
=
0
;
line_read
=
strdup
(
linebuffer
);
}
return
(
line_read
);
}
...
...
ndb/src/mgmsrv/Makefile.am
View file @
8eeca90b
...
...
@@ -24,7 +24,6 @@ INCLUDES_LOC = -I$(top_srcdir)/ndb/src/ndbapi \
-I
$(top_srcdir)
/ndb/src/common/mgmcommon
LDADD_LOC
=
$(top_builddir)
/ndb/src/libndbclient.la
\
$(top_builddir)
/ndb/src/common/editline/libeditline.a
\
$(top_builddir)
/dbug/libdbug.a
\
$(top_builddir)
/mysys/libmysys.a
\
$(top_builddir)
/strings/libmystrings.a @NDB_SCI_LIBS@
...
...
ndb/
src/mgmclient
/CpcClient.hpp
→
ndb/
test/include
/CpcClient.hpp
View file @
8eeca90b
File moved
ndb/test/run-test/Makefile.am
View file @
8eeca90b
...
...
@@ -11,9 +11,8 @@ test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \
atrt-clear-result.sh make-config.sh make-index.sh make-html-reports.sh
atrt_SOURCES
=
main.cpp
INCLUDES_LOC
=
-I
$(top_srcdir)
/ndb/test/include
-I
$(top_srcdir)
/ndb/src/mgmclient
LDADD_LOC
=
$(top_builddir)
/ndb/src/mgmclient/CpcClient.o
\
$(top_builddir)
/ndb/test/src/libNDBT.a
\
INCLUDES_LOC
=
-I
$(top_srcdir)
/ndb/test/include
LDADD_LOC
=
$(top_builddir)
/ndb/test/src/libNDBT.a
\
$(top_builddir)
/ndb/src/libndbclient.la
\
$(top_builddir)
/dbug/libdbug.a
\
$(top_builddir)
/mysys/libmysys.a
\
...
...
ndb/
src/mgmclient
/CpcClient.cpp
→
ndb/
test/src
/CpcClient.cpp
View file @
8eeca90b
File moved
ndb/test/src/Makefile.am
View file @
8eeca90b
...
...
@@ -9,7 +9,8 @@ libNDBT_a_SOURCES = \
HugoAsynchTransactions.cpp UtilTransactions.cpp
\
NdbRestarter.cpp NdbRestarts.cpp NDBT_Output.cpp
\
NdbBackup.cpp NdbConfig.cpp NdbGrep.cpp NDBT_Table.cpp
\
NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c
NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c
\
CpcClient.cpp
INCLUDES_LOC
=
-I
$(top_srcdir)
/ndb/src/common/mgmcommon
-I
$(top_srcdir)
/ndb/include/mgmcommon
-I
$(top_srcdir)
/ndb/include/kernel
-I
$(top_srcdir)
/ndb/src/mgmapi
...
...
ndb/test/tools/Makefile.am
View file @
8eeca90b
...
...
@@ -20,12 +20,10 @@ copy_tab_SOURCES = copy_tab.cpp
create_index_SOURCES
=
create_index.cpp
ndb_cpcc_SOURCES
=
cpcc.cpp
INCLUDES_LOC
=
-I
$(top_srcdir)
/ndb/src/mgmclient
include
$(top_srcdir)/ndb/config/common.mk.am
include
$(top_srcdir)/ndb/config/type_ndbapitest.mk.am
ndb_cpcc_LDADD
=
$(LDADD)
$(top_builddir)
/ndb/src/mgmclient/CpcClient.o
ndb_cpcc_LDADD
=
$(LDADD)
# Don't update the files from bitkeeper
%
::
SCCS/s.%
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment