libCom: epicsReadline refactoring
This commit is contained in:
@@ -57,8 +57,11 @@ EPICS_TS_NTP_INET=
|
||||
# Prompt string
|
||||
# IOCSH_HISTSIZE
|
||||
# Number of lines of command history to keep.
|
||||
# IOCSH_HISTEDIT_DISABLE
|
||||
# Prevents use of readline or equivalent if defined.
|
||||
IOCSH_PS1="epics> "
|
||||
IOCSH_HISTSIZE=50
|
||||
IOCSH_HISTEDIT_DISABLE=
|
||||
|
||||
# Log Server:
|
||||
# EPICS_IOC_LOG_INET
|
||||
|
||||
@@ -20,6 +20,17 @@
|
||||
|
||||
-->
|
||||
|
||||
<h3>Refactoring of epicsReadline</h3>
|
||||
|
||||
<p>The epicsReadline code has been reorganized to allow the commandline history
|
||||
editor to be disabled at runtime. The EPICS_COMMANDLINE_LIBRARY build setting
|
||||
still selects the preferred editor, but the new <tt>IOCSH_HISTEDIT_DISABLE</tt>
|
||||
environment variable can be set at runtime to disable history editing and make
|
||||
the IOC or other program use the basic editor instead. This is useful when
|
||||
starting and controlling an IOC from another program through its stdin and
|
||||
stdout streams since history editors often insert invisible escape codes into
|
||||
the stdout stream, making it hard to parse.</p>
|
||||
|
||||
<h3>Callback subsystem API</h3>
|
||||
|
||||
<p>Added a new macro <tt>callbackGetPriority(prio, callback)</tt> to the
|
||||
|
||||
Vendored
+1
@@ -69,6 +69,7 @@ epicsShareExtern const ENV_PARAM EPICS_CMD_PROTO_PORT;
|
||||
epicsShareExtern const ENV_PARAM EPICS_AR_PORT;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_PS1;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_HISTSIZE;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_HISTEDIT_DISABLE;
|
||||
|
||||
epicsShareExtern const ENV_PARAM *env_param_list[];
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Revision-Id$ */
|
||||
/* Author: Eric Norum Date: 12DEC2001 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "envDefs.h"
|
||||
#include "epicsReadline.h"
|
||||
|
||||
#define EPICS_COMMANDLINE_LIBRARY_EPICS 0
|
||||
#define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1
|
||||
#define EPICS_COMMANDLINE_LIBRARY_READLINE 2
|
||||
#define EPICS_COMMANDLINE_LIBRARY_READLINE_CURSES 2
|
||||
#define EPICS_COMMANDLINE_LIBRARY_READLINE_NCURSES 2
|
||||
|
||||
#ifndef EPICS_COMMANDLINE_LIBRARY
|
||||
# define EPICS_COMMANDLINE_LIBRARY EPICS_COMMANDLINE_LIBRARY_EPICS
|
||||
#endif
|
||||
|
||||
struct osdContext;
|
||||
struct readlineContext {
|
||||
FILE *in;
|
||||
char *line;
|
||||
struct osdContext *osd;
|
||||
};
|
||||
|
||||
static void osdReadlineBegin(struct readlineContext *);
|
||||
static char * osdReadline(const char *prompt, struct readlineContext *);
|
||||
static void osdReadlineEnd(struct readlineContext *);
|
||||
|
||||
#if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS
|
||||
|
||||
static void osdReadlineBegin(struct readlineContext * c) {}
|
||||
static char * osdReadline(const char *prompt, struct readlineContext * c) { return NULL; }
|
||||
static void osdReadlineEnd(struct readlineContext * c) {}
|
||||
|
||||
#else
|
||||
|
||||
# if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE
|
||||
# include "gnuReadline.c"
|
||||
# else
|
||||
# include "osdReadline.c"
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a command-line context
|
||||
*/
|
||||
void * epicsShareAPI
|
||||
epicsReadlineBegin(FILE *in)
|
||||
{
|
||||
struct readlineContext *readlineContext = malloc(sizeof *readlineContext);
|
||||
|
||||
if (readlineContext) {
|
||||
readlineContext->in = in;
|
||||
readlineContext->line = NULL;
|
||||
if (!envGetConfigParamPtr(&IOCSH_HISTEDIT_DISABLE))
|
||||
osdReadlineBegin(readlineContext);
|
||||
}
|
||||
return readlineContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line of input
|
||||
*/
|
||||
char * epicsShareAPI
|
||||
epicsReadline (const char *prompt, void *context)
|
||||
{
|
||||
struct readlineContext *readlineContext = context;
|
||||
FILE *in;
|
||||
char *line;
|
||||
int c; /* char is unsigned on some archs, EOF is -ve */
|
||||
int linelen = 0;
|
||||
int linesize = 50;
|
||||
|
||||
if (readlineContext->osd)
|
||||
return osdReadline(prompt, readlineContext);
|
||||
|
||||
free(readlineContext->line);
|
||||
readlineContext->line = NULL;
|
||||
if ((in = readlineContext->in) == NULL) {
|
||||
in = stdin;
|
||||
if (prompt) {
|
||||
fputs(prompt, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
line = (char *)malloc(linesize);
|
||||
if (line == NULL) {
|
||||
printf("Out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
while ((c = getc(in)) != '\n') {
|
||||
if (c == EOF) {
|
||||
if (ferror(in)) {
|
||||
if ((errno == EINTR) || (errno == EPIPE)) {
|
||||
clearerr(in);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
free (line);
|
||||
return NULL;
|
||||
}
|
||||
if ((linelen + 1) >= linesize) {
|
||||
char *cp;
|
||||
|
||||
linesize += 50;
|
||||
cp = (char *)realloc(line, linesize);
|
||||
if (cp == NULL) {
|
||||
printf("Out of memory!\n");
|
||||
free(line);
|
||||
return NULL;
|
||||
}
|
||||
line = cp;
|
||||
}
|
||||
line[linelen++] = c;
|
||||
}
|
||||
line[linelen] = '\0';
|
||||
readlineContext->line = line;
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a command-line context
|
||||
*/
|
||||
void epicsShareAPI
|
||||
epicsReadlineEnd (void *context)
|
||||
{
|
||||
if (context) {
|
||||
struct readlineContext *readlineContext = context;
|
||||
|
||||
if (readlineContext->osd)
|
||||
osdReadlineEnd(readlineContext);
|
||||
else
|
||||
free(readlineContext->line);
|
||||
free(readlineContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2014 UChicago Argonne LLC, 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.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
#ifndef _EPICS_READLINE_H
|
||||
#define _EPICS_READLINE_H
|
||||
#ifndef INC_epicsReadline_H
|
||||
#define INC_epicsReadline_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -25,4 +24,4 @@ epicsShareFunc void epicsShareAPI epicsReadlineEnd (void *context);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _EPICS_READLINE_H */
|
||||
#endif /* INC_epicsReadline_H */
|
||||
@@ -0,0 +1,70 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Revision-Id$ */
|
||||
/* Author: Eric Norum Date: 12DEC2001 */
|
||||
|
||||
/*
|
||||
* This file is included by epicsReadline.c which has already included the
|
||||
* headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <libtecla.h>
|
||||
|
||||
struct osdContext {};
|
||||
|
||||
/*
|
||||
* Create a command-line context
|
||||
*/
|
||||
static void
|
||||
osdReadlineBegin (struct readlineContext *context)
|
||||
{
|
||||
GetLine *gl;
|
||||
long i = 50;
|
||||
|
||||
envGetLongConfigParam(&IOCSH_HISTSIZE, &i);
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
gl = new_GetLine(200, i * 40);
|
||||
if (gl) {
|
||||
context->osd = (struct osdContext *) gl;
|
||||
if (context->in)
|
||||
gl_change_terminal(gl, context->in, stdout, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line of input
|
||||
*/
|
||||
static char *
|
||||
osdReadline (const char *prompt, struct readlineContext *context)
|
||||
{
|
||||
GetLine *gl = (GetLine *) context->osd;
|
||||
char *line;
|
||||
|
||||
line = gl_get_line(gl, prompt ? prompt : "", NULL, -1);
|
||||
if (line) {
|
||||
char *nl = strchr(line, '\n');
|
||||
|
||||
if (nl)
|
||||
*nl = '\0';
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a command-line context
|
||||
*/
|
||||
static void
|
||||
osdReadlineEnd(struct readlineContext *context)
|
||||
{
|
||||
GetLine *gl = (GetLine *) context->osd;
|
||||
|
||||
del_GetLine(gl);
|
||||
}
|
||||
|
||||
@@ -1,376 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Revision-Id$ */
|
||||
/* Author: Eric Norum Date: 12DEC2001 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "envDefs.h"
|
||||
#include "epicsReadline.h"
|
||||
|
||||
#define EPICS_COMMANDLINE_LIBRARY_EPICS 0
|
||||
#define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1
|
||||
#define EPICS_COMMANDLINE_LIBRARY_READLINE 2
|
||||
#define EPICS_COMMANDLINE_LIBRARY_READLINE_CURSES 2
|
||||
#define EPICS_COMMANDLINE_LIBRARY_READLINE_NCURSES 2
|
||||
|
||||
#ifndef EPICS_COMMANDLINE_LIBRARY
|
||||
#define EPICS_COMMANDLINE_LIBRARY EPICS_COMMANDLINE_LIBRARY_EPICS
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_LIBTECLA
|
||||
#include <libtecla.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Create a command-line context
|
||||
*/
|
||||
void * epicsShareAPI
|
||||
epicsReadlineBegin (FILE *in)
|
||||
{
|
||||
GetLine *gl;
|
||||
long i = 50;
|
||||
|
||||
envGetLongConfigParam(&IOCSH_HISTSIZE, &i);
|
||||
if (i < 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 (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 <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) {
|
||||
long i = 50;
|
||||
|
||||
envGetLongConfigParam(&IOCSH_HISTSIZE, &i);
|
||||
if (i < 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;
|
||||
|
||||
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] != '\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
|
||||
|
||||
#if defined(vxWorks)
|
||||
|
||||
#include <string.h>
|
||||
#include <ledLib.h>
|
||||
#define LEDLIB_LINESIZE 1000
|
||||
|
||||
#ifndef _WRS_VXWORKS_MAJOR
|
||||
typedef int LED_ID;
|
||||
#endif
|
||||
|
||||
struct readlineContext {
|
||||
LED_ID ledId;
|
||||
char line[LEDLIB_LINESIZE];
|
||||
FILE *in;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a command-line context
|
||||
*/
|
||||
void * epicsShareAPI
|
||||
epicsReadlineBegin(FILE *in)
|
||||
{
|
||||
struct readlineContext *readlineContext;
|
||||
|
||||
readlineContext = malloc(sizeof *readlineContext);
|
||||
if (readlineContext != NULL) {
|
||||
readlineContext->ledId = (LED_ID) ERROR;
|
||||
readlineContext->in = in;
|
||||
if (in == NULL) {
|
||||
long i = 50;
|
||||
|
||||
envGetLongConfigParam(&IOCSH_HISTSIZE, &i);
|
||||
if (i < 1) i = 1;
|
||||
readlineContext->ledId = ledOpen(fileno(stdin), fileno(stdout), i);
|
||||
if (readlineContext->ledId == (LED_ID) ERROR) {
|
||||
readlineContext->in = stdin;
|
||||
printf("Warning -- Unabled to allocate space for command-line history.\n");
|
||||
printf("Warning -- Command-line editting disabled.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return readlineContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line of input
|
||||
*/
|
||||
char * epicsShareAPI
|
||||
epicsReadline (const char *prompt, void *context)
|
||||
{
|
||||
struct readlineContext *readlineContext = context;
|
||||
int i;
|
||||
|
||||
if (prompt) {
|
||||
fputs(prompt, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
if (readlineContext->ledId != (LED_ID) ERROR) {
|
||||
i = ledRead(readlineContext->ledId, readlineContext->line, LEDLIB_LINESIZE-1);
|
||||
if (i < 0)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
if (fgets(readlineContext->line, LEDLIB_LINESIZE, readlineContext->in) == NULL)
|
||||
return NULL;
|
||||
i = strlen(readlineContext->line);
|
||||
}
|
||||
if ((i >= 1) && (readlineContext->line[i-1] == '\n'))
|
||||
readlineContext->line[i-1] = '\0';
|
||||
else
|
||||
readlineContext->line[i] = '\0';
|
||||
return readlineContext->line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a command-line context
|
||||
*/
|
||||
void epicsShareAPI
|
||||
epicsReadlineEnd (void *context)
|
||||
{
|
||||
struct readlineContext *readlineContext = context;
|
||||
|
||||
if (readlineContext) {
|
||||
if (readlineContext->ledId != (LED_ID) ERROR)
|
||||
ledClose(readlineContext->ledId);
|
||||
free(readlineContext);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !vxWorks */
|
||||
|
||||
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;
|
||||
}
|
||||
while ((c = getc (in)) != '\n') {
|
||||
if (c == EOF) {
|
||||
if (ferror(in)) {
|
||||
if ((errno == EINTR) || (errno == EPIPE)) {
|
||||
clearerr(in);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
free (line);
|
||||
return NULL;
|
||||
}
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
line = cp;
|
||||
}
|
||||
line[linelen++] = c;
|
||||
}
|
||||
line[linelen] = '\0';
|
||||
readlineContext->line = line;
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a command-line context
|
||||
*/
|
||||
void epicsShareAPI
|
||||
epicsReadlineEnd (void *context)
|
||||
{
|
||||
struct readlineContext *readlineContext = context;
|
||||
|
||||
if (readlineContext) {
|
||||
free(readlineContext->line);
|
||||
free(readlineContext);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !vxWorks */
|
||||
|
||||
#else
|
||||
|
||||
# error "Unsupported EPICS_COMMANDLINE_LIBRARY"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,106 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Revision-Id$ */
|
||||
/* Author: Eric Norum Date: 12DEC2001 */
|
||||
|
||||
/*
|
||||
* This file is included by epicsReadline.c which has already included the
|
||||
* headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h
|
||||
*/
|
||||
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
struct osdContext {} present;
|
||||
|
||||
/*
|
||||
* Create a command-line context
|
||||
*/
|
||||
static void
|
||||
osdReadlineBegin(struct readlineContext *context)
|
||||
{
|
||||
context->osd = &present;
|
||||
if (context->in == NULL) {
|
||||
long i = 50;
|
||||
|
||||
envGetLongConfigParam(&IOCSH_HISTSIZE, &i);
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
stifle_history(i);
|
||||
rl_bind_key('\t', rl_insert);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line of input
|
||||
*/
|
||||
static char *
|
||||
osdReadline (const char *prompt, struct readlineContext *context)
|
||||
{
|
||||
char *line;
|
||||
|
||||
free(context->line);
|
||||
context->line = NULL;
|
||||
if (context->in == NULL) {
|
||||
line = readline(prompt);
|
||||
}
|
||||
else {
|
||||
int c; /* char is unsigned on some archs; EOF is -ve */
|
||||
int linelen = 0;
|
||||
int linesize = 50;
|
||||
|
||||
line = malloc(linesize);
|
||||
if (line == NULL) {
|
||||
printf("Out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
if (prompt) {
|
||||
fputs(prompt, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
while ((c = getc(context->in)) != '\n') {
|
||||
if (c == EOF) {
|
||||
free(line);
|
||||
line = NULL;
|
||||
break;
|
||||
}
|
||||
if ((linelen + 1) >= linesize) {
|
||||
char *cp;
|
||||
|
||||
linesize += 50;
|
||||
cp = (char *)realloc(line, linesize);
|
||||
if (cp == NULL) {
|
||||
printf ("Out of memory!\n");
|
||||
free(line);
|
||||
line = NULL;
|
||||
break;
|
||||
}
|
||||
line = cp;
|
||||
}
|
||||
line[linelen++] = c;
|
||||
}
|
||||
if (line)
|
||||
line[linelen] = '\0';
|
||||
}
|
||||
context->line = line;
|
||||
if (line && *line)
|
||||
add_history(line);
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a command-line context
|
||||
*/
|
||||
static void
|
||||
osdReadlineEnd (struct readlineContext *context)
|
||||
{
|
||||
if (context->osd) {
|
||||
free(context->line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Revision-Id$ */
|
||||
/* Author: Eric Norum Date: 12DEC2001 */
|
||||
|
||||
/*
|
||||
* This file is included by epicsReadline.c which has already included the
|
||||
* headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <ledLib.h>
|
||||
|
||||
/* FIXME: Remove line-lenth limitation */
|
||||
#define LEDLIB_LINESIZE 1000
|
||||
|
||||
#ifndef _WRS_VXWORKS_MAJOR
|
||||
typedef int LED_ID;
|
||||
#endif
|
||||
|
||||
struct osdContext {
|
||||
LED_ID ledId;
|
||||
char line[LEDLIB_LINESIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a command-line context
|
||||
*/
|
||||
static void
|
||||
osdReadlineBegin(struct readlineContext *context)
|
||||
{
|
||||
struct osdContext osd = malloc(sizeof *osd);
|
||||
|
||||
if (osd != NULL) {
|
||||
osd->ledId = (LED_ID) ERROR;
|
||||
if (context->in == NULL) {
|
||||
long i = 50;
|
||||
|
||||
envGetLongConfigParam(&IOCSH_HISTSIZE, &i);
|
||||
if (i < 1)
|
||||
i = 1;
|
||||
|
||||
osd->ledId = ledOpen(fileno(stdin), fileno(stdout), i);
|
||||
if (osd->ledId == (LED_ID) ERROR) {
|
||||
context->in = stdin;
|
||||
printf("Warning -- Unabled to allocate space for command-line history.\n");
|
||||
printf("Warning -- Command-line editting disabled.\n");
|
||||
}
|
||||
}
|
||||
context->osd = osd;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line of input
|
||||
*/
|
||||
static char *
|
||||
osdReadline (const char *prompt, struct readlineContext *context)
|
||||
{
|
||||
struct osdContext *osd = context->osd;
|
||||
int i;
|
||||
|
||||
if (prompt) {
|
||||
fputs(prompt, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
if (osd->ledId != (LED_ID) ERROR) {
|
||||
i = ledRead(osd->ledId, osd->line, LEDLIB_LINESIZE-1);
|
||||
if (i < 0)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
if (fgets(osd->line, LEDLIB_LINESIZE, context->in) == NULL)
|
||||
return NULL;
|
||||
i = strlen(osd->line);
|
||||
}
|
||||
if ((i >= 1) && (osd->line[i-1] == '\n'))
|
||||
osd->line[i-1] = '\0';
|
||||
else
|
||||
osd->line[i] = '\0';
|
||||
return osd->line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a command-line context
|
||||
*/
|
||||
static void
|
||||
osdReadlineEnd (struct readlineContext *context)
|
||||
{
|
||||
LED_ID ledId = context->osd->ledId;
|
||||
|
||||
if (ledId != (LED_ID) ERROR)
|
||||
ledClose(ledId);
|
||||
free(context->osd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user