Change command-line input to allow CONFIG_SITE selection of libtecla,

GNU readline, or built-in EPICS routines.
This commit is contained in:
W. Eric Norum
2002-11-20 20:17:36 +00:00
parent 1e14394d92
commit 1c7428c1cf
16 changed files with 274 additions and 179 deletions

View File

@@ -49,7 +49,7 @@ endif
# ppc604
# vxipc
#
CROSS_COMPILER_TARGET_ARCHS=vxWorks-68040 vxWorks-ppc604
CROSS_COMPILER_TARGET_ARCHS=
# If only a subset of the host architectures perform

View File

@@ -370,5 +370,12 @@ COMMON_INC += $(filter $(COMMON_DIR)/%, $(foreach file, $(INC), \
SOURCE_INC = $(wildcard $(file) $(SOURCE_INC_bbb) )
SOURCE_INC_bbb = $(foreach dir, $(ALL_SRC_DIRS), $(SOURCE_INC_aaa) )
SOURCE_INC_aaa = $(addsuffix /$(file), $(dir) )
# Command-line input support
OP_SYS_CFLAGS += -DEPICS_COMMANDLINE_LIBRARY=EPICS_COMMANDLINE_LIBRARY_$(COMMANDLINE_LIBRARY)
LDLIBS_READLINE = -lreadline -lncurses
LDLIBS_LIBTECLA = -ltecla_r -lncurses
OP_SYS_LDLIBS += $(LDLIBS_$(COMMANDLINE_LIBRARY))
endif

View File

@@ -124,3 +124,13 @@ CROSS_WARN=YES
# Installation directory
INSTALL_LOCATION=$(TOP)
# Command-line input support
#
# Currently Supporting:
# EPICS - Built-in EPICS routines (no command-line editing/history)
# READLINE - GNU readline library
# LIBTECLA - LIBTECLA library
#
#COMMANDLINE_LIBRARY=
COMMANDLINE_LIBRARY=READLINE

View File

@@ -35,7 +35,8 @@ CPP = $(RTEMS_BASE)/bin/$(CC_FOR_TARGET) -x c -E
AR = $(RTEMS_BASE)/bin/$(AR_FOR_TARGET)
LD = $(RTEMS_BASE)/bin/$(LD_FOR_TARGET) -r
RTEMS_LDFLAGS := $(STATIC_LDFLAGS) $(LDFLAGS)
LINK.cpp = $(CCC) -o $@ $(RTEMS_LDFLAGS) $(PROD_LD_OBJS) $(PROD_LD_RESS) $(LDLIBS)
LINK.cpp = $(CCC) -o $@ $(RTEMS_LDFLAGS) $(LDFLAGS) $(PROD_LD_OBJS) $(PROD_LD_RESS) $(LDLIBS)
RANLIB := $(RTEMS_BASE)/bin/$(RANLIB)
#-------------------------------------------------------
@@ -75,8 +76,8 @@ OS_CLASS = RTEMS
#--------------------------------------------------
# Operating system flags
OP_SYS_LDLIBS = -lrtemsCom -lrtemscpu -lreadline -lcurses -lm
OP_SYS_LDFLAGS = $(CPU_CFLAGS) -u Init \
OP_SYS_LDLIBS += -lrtemsCom -lrtemscpu -lm
OP_SYS_LDFLAGS += $(CPU_CFLAGS) -u Init \
$(PROJECT_RELEASE)/lib/no-dpmem.rel \
$(PROJECT_RELEASE)/lib/no-mp.rel \
$(PROJECT_RELEASE)/lib/no-part.rel \

View File

@@ -25,14 +25,11 @@ OP_SYS_CFLAGS += -fno-common
CPPSNCFLAGS += -no-cpp-precomp
#
# Need to get some fink-installed packages (readline, etc.).
# If you don't have readline on your system you must remove
# or comment out these lines and make the appropriate changes
# to src/libCom/osi/os/Darwin/osdReadline.h
# Need to get some fink-installed packages
#
OP_SYS_CPPFLAGS += -I$(FINK_DIR)/include
OP_SYS_LDFLAGS += -L$(FINK_DIR)/lib
OP_SYS_LDLIBS += -lreadline
OP_SYS_LDLIBS +=
#
# Stuff that will be needed when going to shared libraries

View File

@@ -21,8 +21,8 @@ POSIX_LDLIBS_NO =
# -D_BSD_SOURCE for gethostname() in unistd.h as needed by cacChannelIO.cpp.
OP_SYS_CPPFLAGS += -D_BSD_SOURCE
OP_SYS_CPPFLAGS += -Dlinux
OP_SYS_LDFLAGS =
OP_SYS_LDLIBS = -lreadline -lcurses -lrt
OP_SYS_LDFLAGS +=
OP_SYS_LDLIBS = -lrt
#ARCH_DEP_CPPFLAGS += -D_X86_

View File

@@ -23,8 +23,8 @@ POSIX_LDLIBS_NO =
# -D_BSD_SOURCE for gethostname() in unistd.h as needed by cacChannelIO.cpp.
OP_SYS_CPPFLAGS += -D_BSD_SOURCE
OP_SYS_CPPFLAGS += -Dlinux
OP_SYS_LDFLAGS =
OP_SYS_LDLIBS = -lreadline -lcurses -lrt
OP_SYS_LDFLAGS +=
OP_SYS_LDLIBS += -lrt
ARCH_DEP_CPPFLAGS += -D_X86_
ARCH_DEP_CFLAGS += -mcpu=pentium
@@ -36,4 +36,4 @@ ifdef CROSS
endif
#Allow R3.13 built extensions to load R3.14 shared libs
SYS_SHRLIB_LIBS += pthread readline curses rt
SYS_SHRLIB_LIBS += pthread rt

View File

@@ -86,11 +86,11 @@ export TOOL_FAMILY = GNU
#--------------------------------------------------
# Operating system flags
OP_SYS_CPPFLAGS = -DvxWorks
OP_SYS_CFLAGS = -fno-builtin
#OP_SYS_CFLAGS = -fno-builtin -fdollars-in-identifiers
OP_SYS_LDFLAGS =
OP_SYS_LDLIBS =
OP_SYS_CPPFLAGS += -DvxWorks
OP_SYS_CFLAGS += -fno-builtin
#OP_SYS_CFLAGS += -fno-builtin -fdollars-in-identifiers
OP_SYS_LDFLAGS +=
OP_SYS_LDLIBS +=
# Fix for vxWorks headers using macros defined in
# vxWorks.h but not including vxWorks.h

View File

@@ -23,8 +23,8 @@ POSIX_LDLIBS_NO =
# -D_BSD_SOURCE for gethostname() in unistd.h as needed by cacChannelIO.cpp.
OP_SYS_CPPFLAGS += -DCYGWIN32 -U_WIN32
OP_SYS_LDFLAGS =
####OP_SYS_LDLIBS = -lreadline -lcurses -lrt
OP_SYS_LDFLAGS +=
####OP_SYS_LDLIBS += -lrt
ARCH_DEP_CPPFLAGS += -D_X86_

View File

@@ -218,27 +218,14 @@ iocsh (const char *pathname)
int argBufCapacity = 0;
struct iocshCommand *found;
struct iocshFuncDef const *piocshFuncDef;
void *readlineContext;
/*
* See if command interpreter is interactive
*/
if ((pathname == NULL) || (strcmp (pathname, "<telnet>") == 0)) {
const char *historySize;
if ((prompt = getenv ("IOCSH_PS1")) == NULL)
prompt = "epics> ";
if (((historySize = getenv ("IOCSH_HISTSIZE")) == NULL)
&& ((historySize = getenv ("HISTSIZE")) == NULL))
historySize = "20";
if (pathname == NULL) {
epicsStifleHistory (atoi (historySize));
/*
* FIXME: Could enable tab-completion of commands here
*/
epicsBindKeys();
}
else {
fp = stdin;
}
}
else {
fp = fopen (pathname, "r");
@@ -253,24 +240,21 @@ iocsh (const char *pathname)
prompt = NULL;
}
/*
* Create a command-line input context
*/
if ((readlineContext = epicsReadlineBegin(fp)) == NULL) {
fprintf(stderr, "Can't allocate command-line object.\n");
if (fp)
fclose(fp);
return -1;
}
/*
* Read commands till EOF or exit
*/
for (;;) {
/*
* Get a line
*/
while ((line = epicsReadline(prompt, readlineContext)) != NULL) {
lineno++;
free (line);
line = epicsReadline (fp, prompt);
if (line == NULL)
break;
/*
* If using readline, add non-blank lines to history
*/
if ((fp == NULL) && *line)
epicsAddHistory (line);
/*
* Ignore comment lines
@@ -278,8 +262,11 @@ iocsh (const char *pathname)
if (*line == '#')
continue;
if ((prompt == NULL) && *line)
puts(line);
/*
* Echo commands read from scripts
*/
if ((prompt == NULL) && *line)
puts(line);
/*
* Break line into words
@@ -471,10 +458,10 @@ iocsh (const char *pathname)
}
if (fp && (fp != stdin))
fclose (fp);
free (line);
free (argv);
free (argBuf);
errlogFlush();
epicsReadlineEnd(readlineContext);
return 0;
}

View File

@@ -1,23 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* $Id$
*
* Author: Eric Norum
*/
#ifndef _OSD_READLINE_H_
#define _OSD_READLINE_H_
/*
* If you don't have the fink readline package installed, uncomment
* the `FAKE' line and comment out the `REAL' line.
*/
/* #define IOCSH_FAKE_READLINE */
#define IOCSH_REAL_READLINE
#endif /* _OSD_READLINE_H_ */

View File

@@ -1,18 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef _OSD_READLINE_H_
#define _OSD_READLINE_H_
/*
* Use readline library.
*/
#define IOCSH_REAL_READLINE
#endif /* _OSD_READLINE_H_ */

View File

@@ -1,18 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef _OSD_READLINE_H_
#define _OSD_READLINE_H_
/*
* Use readline library.
*/
#define IOCSH_REAL_READLINE
#endif /* _OSD_READLINE_H_ */

View File

@@ -12,49 +12,231 @@
#define epicsExportSharedSymbols
#include <epicsReadline.h>
#include <osdReadline.h>
#if (defined (IOCSH_REAL_READLINE) && defined (IOCSH_FAKE_READLINE))
# undef IOCSH_FAKE_READLINE
#define EPICS_COMMANDLINE_LIBRARY_EPICS 0
#define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1
#define EPICS_COMMANDLINE_LIBRARY_READLINE 2
#ifndef EPICS_COMMANDLINE_LIBRARY
#define EPICS_COMMANDLINE_LIBRARY EPICS_COMMANDLINE_LIBRARY_EPICS
#endif
#if (defined (IOCSH_REAL_READLINE) || defined (IOCSH_FAKE_READLINE))
#include <stdio.h>
#include <stdlib.h>
#if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_LIBTECLA
#include <libtecla.h>
#include <string.h>
#if (defined (IOCSH_REAL_READLINE))
# include <readline/readline.h>
# include <readline/history.h>
#endif
/*
* Create a command-line context
*/
void * epicsShareAPI
epicsReadlineBegin (FILE *in)
{
GetLine *gl;
const char *histSize = getenv("IOCSH_HISTSIZE");
int i;
if (histSize == NULL)
i = 50;
else if ((i = atoi(histSize)) < 0)
i = 0;
gl = new_GetLine(200, i * 40);
if ((gl != NULL) && (in != NULL))
gl_change_terminal(gl, in, stdout, NULL);
return gl;
}
/*
* Read a line of input
*/
char * epicsShareAPI
epicsReadline (FILE *fp, const char *prompt)
epicsReadline (const char *prompt, void *context)
{
char *line;
char *nl;
line = gl_get_line(context, prompt ? prompt : "", NULL, -1);
if ((line != NULL) && ((nl = strchr(line, '\n')) != NULL))
*nl = '\0';
return line;
}
/*
* Destroy a command-line context
*/
void epicsShareAPI
epicsReadlineEnd(void *context)
{
del_GetLine(context);
}
#elif EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
struct readlineContext {
FILE *in;
char *line;
};
/*
* Create a command-line context
*/
void * epicsShareAPI
epicsReadlineBegin(FILE *in)
{
struct readlineContext *readlineContext;
readlineContext = malloc(sizeof *readlineContext);
if (readlineContext != NULL) {
readlineContext->in = in;
readlineContext->line = NULL;
if (in == NULL) {
const char *histSize = getenv("IOCSH_HISTSIZE");
int i;
if (histSize == NULL)
i = 50;
else if ((i = atoi(histSize)) < 0)
i = 0;
stifle_history (i);
rl_bind_key ('\t', rl_insert);
}
}
return readlineContext;
}
/*
* Read a line of input
*/
char * epicsShareAPI
epicsReadline (const char *prompt, void *context)
{
struct readlineContext *readlineContext = context;
int c; /* char is unsigned on some archs, EOF is -ve */
char *line = NULL;
int linelen = 0;
int linesize = 50;
if (fp == NULL)
#ifdef IOCSH_REAL_READLINE
return readline (prompt);
#else
fp = stdin;
#endif
free (readlineContext->line);
readlineContext->line = NULL;
if (readlineContext->in == NULL) {
line = readline (prompt);
}
else {
line = (char *)malloc (linesize * sizeof *line);
if (line == NULL) {
printf ("Out of memory!\n");
return NULL;
}
if (prompt) {
fputs (prompt, stdout);
fflush (stdout);
}
while ((c = getc (readlineContext->in)) != '\n') {
if (c == EOF) {
free (line);
line = NULL;
break;
}
if ((linelen + 1) >= linesize) {
char *cp;
linesize += 50;
cp = (char *)realloc (line, linesize * sizeof *line);
if (cp == NULL) {
printf ("Out of memory!\n");
free (line);
line = NULL;
break;
}
line = cp;
}
line[linelen++] = c;
}
if (line)
line[linelen] = '\0';
}
readlineContext->line = line;
if (line && line[0] != '#')
add_history (line);
return line;
}
/*
* Destroy a command-line context
*/
void epicsShareAPI
epicsReadlineEnd (void *context)
{
struct readlineContext *readlineContext = context;
if (readlineContext) {
free(readlineContext->line);
free(readlineContext);
}
}
#elif EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS
struct readlineContext {
FILE *in;
char *line;
};
/*
* Create a command-line context
*/
void * epicsShareAPI
epicsReadlineBegin(FILE *in)
{
struct readlineContext *readlineContext;
readlineContext = malloc(sizeof *readlineContext);
if (readlineContext != NULL) {
readlineContext->in = in;
readlineContext->line = NULL;
}
return readlineContext;
}
/*
* Read a line of input
*/
char * epicsShareAPI
epicsReadline (const char *prompt, void *context)
{
struct readlineContext *readlineContext = context;
int c; /* char is unsigned on some archs, EOF is -ve */
char *line = NULL;
int linelen = 0;
int linesize = 50;
FILE *in;
free (readlineContext->line);
readlineContext->line = NULL;
if ((in = readlineContext->in) == NULL) {
in = stdin;
if (prompt != NULL) {
fputs (prompt, stdout);
fflush (stdout);
}
}
line = (char *)malloc (linesize * sizeof *line);
if (line == NULL) {
printf ("Out of memory!\n");
return NULL;
}
if (prompt) {
fputs (prompt, stdout);
fflush (stdout);
}
while ((c = getc (fp)) != '\n') {
while ((c = getc (in)) != '\n') {
if (c == EOF) {
free (line);
return NULL;
@@ -74,28 +256,26 @@ epicsReadline (FILE *fp, const char *prompt)
line[linelen++] = c;
}
line[linelen] = '\0';
readlineContext->line = line;
return line;
}
void epicsShareAPI epicsStifleHistory (int n)
/*
* Destroy a command-line context
*/
void epicsShareAPI
epicsReadlineEnd (void *context)
{
#if (defined (IOCSH_REAL_READLINE))
stifle_history (n);
#endif
struct readlineContext *readlineContext = context;
if (readlineContext) {
free(readlineContext->line);
free(readlineContext);
}
}
void epicsShareAPI epicsAddHistory (const char *line)
{
#if (defined (IOCSH_REAL_READLINE))
add_history (line);
#endif
}
#else
void epicsShareAPI epicsBindKeys (void)
{
#if (defined (IOCSH_REAL_READLINE))
rl_bind_key ('\t', rl_insert);
#endif
}
# error "Unsupported EPICS_COMMANDLINE_LIBRARY"
#endif /* defined (IOCSH_REAL_READLINE) || defined (IOCSH_FAKE_READLINE) */
#endif

View File

@@ -17,10 +17,9 @@ extern "C" {
#include <shareLib.h>
#include <stdio.h>
epicsShareFunc char * epicsShareAPI epicsReadline (FILE *fp, const char *prompt);
epicsShareFunc void epicsShareAPI epicsStifleHistory (int n);
epicsShareFunc void epicsShareAPI epicsAddHistory (const char *line);
epicsShareFunc void epicsShareAPI epicsBindKeys (void);
epicsShareFunc void * epicsShareAPI epicsReadlineBegin (FILE *in);
epicsShareFunc char * epicsShareAPI epicsReadline (const char *prompt, void *context);
epicsShareFunc void epicsShareAPI epicsReadlineEnd (void *context);
#ifdef __cplusplus
}

View File

@@ -1,27 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef _OSD_READLINE_H_
#define _OSD_READLINE_H_
/*
* Default version of osdReadline
* Don't use readline library, but do provide epicsReadline routines
*
* This wastes a few hundred bytes of memory if you're not using iocsh.
* If that many bytes is really important to you you can save it by
* going to the os-dependent directory and creating an osdReadline.h
* which defines neither of the following macros.
*
*/
/* #define IOCSH_REAL_READLINE */
#define IOCSH_FAKE_READLINE
#endif /* _OSD_READLINE_H_ */