This is Unofficial EPICS BASE Doxygen Site
epicsReadline.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Saskatchewan
3 * Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne
4 * National Laboratory.
5 * EPICS BASE is distributed subject to a Software License Agreement found
6 * in file LICENSE that is included with this distribution.
7 \*************************************************************************/
8 /* Author: Eric Norum */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 
14 #include "envDefs.h"
15 #include "epicsReadline.h"
16 
17 /* Basic command-line input, no editing or history: */
18 #define EPICS_COMMANDLINE_LIBRARY_EPICS 0
19 
20 /* OS-specific command-line editing and/or history: */
21 #define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1
22 #define EPICS_COMMANDLINE_LIBRARY_LEDLIB 1
23 #define EPICS_COMMANDLINE_LIBRARY_OTHER 1
24 
25 /* GNU readline, or Apple's libedit wrapper: */
26 #define EPICS_COMMANDLINE_LIBRARY_READLINE 2
27 #define EPICS_COMMANDLINE_LIBRARY_READLINE_CURSES 2
28 #define EPICS_COMMANDLINE_LIBRARY_READLINE_NCURSES 2
29 
30 #ifndef EPICS_COMMANDLINE_LIBRARY
31 # define EPICS_COMMANDLINE_LIBRARY EPICS_COMMANDLINE_LIBRARY_EPICS
32 #endif
33 
34 struct osdContext;
36  FILE *in;
37  char *line;
38  struct osdContext *osd;
39 };
40 
41 static void osdReadlineBegin(struct readlineContext *);
42 static char * osdReadline(const char *prompt, struct readlineContext *);
43 static void osdReadlineEnd(struct readlineContext *);
44 
45 #if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS
46 
47 static void osdReadlineBegin(struct readlineContext *rc) {}
48 static char * osdReadline(const char *prompt, struct readlineContext *rc)
49 {
50  return NULL;
51 }
52 static void osdReadlineEnd(struct readlineContext *rc) {}
53 
54 #elif EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE
55 # include "gnuReadline.c"
56 #else
57 # include "osdReadline.c"
58 #endif
59 
60 /*
61  * Create a command-line context
62  */
63 void * epicsStdCall
65 {
66  struct readlineContext *rc = calloc(1, sizeof(*rc));
67 
68  if (rc) {
69  rc->in = in;
70  rc->line = NULL;
72  osdReadlineBegin(rc);
73  }
74  return rc;
75 }
76 
77 /*
78  * Read a line of input
79  */
80 char * epicsStdCall
81 epicsReadline (const char *prompt, void *context)
82 {
83  struct readlineContext *rc = context;
84  FILE *in;
85  char *line;
86  int c; /* char is unsigned on some archs, EOF is -ve */
87  int linelen = 0;
88  int linesize = 50;
89 
90  if (rc->osd)
91  return osdReadline(prompt, rc);
92 
93  free(rc->line);
94  rc->line = NULL;
95  if ((in = rc->in) == NULL) {
96  in = stdin;
97  if (prompt) {
98  fputs(prompt, stdout);
99  fflush(stdout);
100  }
101  }
102  line = (char *)malloc(linesize);
103  if (line == NULL) {
104  printf("Out of memory!\n");
105  return NULL;
106  }
107  while ((c = getc(in)) != '\n') {
108  if (c == EOF) {
109  if (ferror(in)) {
110  if ((errno == EINTR) || (errno == EPIPE)) {
111  clearerr(in);
112  continue;
113  }
114  }
115  free (line);
116  return NULL;
117  }
118  if ((linelen + 1) >= linesize) {
119  char *cp;
120 
121  linesize += 50;
122  cp = (char *)realloc(line, linesize);
123  if (cp == NULL) {
124  printf("Out of memory!\n");
125  free(line);
126  return NULL;
127  }
128  line = cp;
129  }
130  line[linelen++] = c;
131  }
132  line[linelen] = '\0';
133  rc->line = line;
134  return line;
135 }
136 
137 /*
138  * Destroy a command-line context
139  */
140 void epicsStdCall
141 epicsReadlineEnd (void *context)
142 {
143  if (context) {
144  struct readlineContext *rc = context;
145 
146  if (rc->osd)
147  osdReadlineEnd(rc);
148  else
149  free(rc->line);
150  free(rc);
151  }
152 }
153 
int linesize
Definition: reader.c:26
LIBCOM_API const char *epicsStdCall envGetConfigParamPtr(const ENV_PARAM *pParam)
Get a configuration parameter&#39;s value or default string.
Definition: envSubr.c:81
Routines to get and set EPICS environment parameters.
void *epicsStdCall epicsReadlineBegin(FILE *in)
Create a command-line context.
Definition: epicsReadline.c:64
#define printf
Definition: epicsStdio.h:41
char *epicsStdCall epicsReadline(const char *prompt, void *context)
Read a line of input.
Definition: epicsReadline.c:81
#define NULL
Definition: catime.c:38
Command-line editing functions.
#define stdout
Definition: epicsStdio.h:30
void epicsStdCall epicsReadlineEnd(void *context)
Destroy a command-line context.
#define stdin
Definition: epicsStdio.h:28
struct osdContext * osd
Definition: epicsReadline.c:38
LIBCOM_API const ENV_PARAM IOCSH_HISTEDIT_DISABLE