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
+18 -31
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;
}
-23
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_ */
-18
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_ */
-18
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_ */
+217 -37
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
+3 -4
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
}
-27
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_ */