This is Unofficial EPICS BASE Doxygen Site
gnuReadline.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Saskatchewan
3 * Copyright (c) 2014 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 Date: 12DEC2001 */
9 
10 /*
11  * This file is included by epicsReadline.c which has already included the
12  * headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h
13  */
14 
15 #include <readline/readline.h>
16 #include <readline/history.h>
17 
18 #include "epicsExit.h"
19 
20 static struct osdContext {
21  char dummy; /* Required for older compilers */
22 } present;
23 
24 static enum {rlNone, rlIdle, rlBusy} rlState = rlNone;
25 
26 static void rlExit(void *dummy) {
27  if (rlState == rlBusy)
28  rl_cleanup_after_signal();
29 }
30 
31 
32 /*
33  * Create a command-line context
34  */
35 static void
36 osdReadlineBegin(struct readlineContext *context)
37 {
38  if (rlState == rlNone) {
39  epicsAtExit(rlExit, NULL);
40  rlState = rlIdle;
41  }
42 
43  context->osd = &present;
44  if (context->in == NULL) {
45  long i = 50;
46 
48  if (i < 0)
49  i = 0;
50  stifle_history(i);
51  rl_bind_key('\t', rl_insert);
52  }
53 }
54 
55 /*
56  * Read a line of input
57  */
58 static char *
59 osdReadline (const char *prompt, struct readlineContext *context)
60 {
61  char *line;
62 
63  free(context->line);
64  context->line = NULL;
65  if (context->in == NULL) {
66  rlState = rlBusy;
67  line = readline (prompt);
68  rlState = rlIdle;
69  }
70  else {
71  int c; /* char is unsigned on some archs; EOF is -ve */
72  int linelen = 0;
73  int linesize = 50;
74 
75  line = malloc(linesize);
76  if (line == NULL) {
77  printf("Out of memory!\n");
78  return NULL;
79  }
80  if (prompt) {
81  fputs(prompt, stdout);
82  fflush(stdout);
83  }
84  while ((c = getc(context->in)) != '\n') {
85  if (c == EOF) {
86  free(line);
87  line = NULL;
88  break;
89  }
90  if ((linelen + 1) >= linesize) {
91  char *cp;
92 
93  linesize += 50;
94  cp = (char *)realloc(line, linesize);
95  if (cp == NULL) {
96  printf ("Out of memory!\n");
97  free(line);
98  line = NULL;
99  break;
100  }
101  line = cp;
102  }
103  line[linelen++] = c;
104  }
105  if (line)
106  line[linelen] = '\0';
107  }
108  context->line = line;
109  if (line && *line)
110  add_history(line);
111  return line;
112 }
113 
114 /*
115  * Destroy a command-line context
116  */
117 static void
118 osdReadlineEnd (struct readlineContext *context)
119 {
120  if (context->osd) {
121  free(context->line);
122  }
123 }
124 
int linesize
Definition: reader.c:26
int i
Definition: scan.c:967
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
LIBCOM_API const ENV_PARAM IOCSH_HISTSIZE
char * line
Definition: reader.c:25
Extended replacement for the Posix exit and atexit routines.
#define stdout
Definition: epicsStdio.h:30
epics::pvData::PVStructurePtr dummy
Definition: pvAccess.cpp:72
LIBCOM_API long epicsStdCall envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong)
Get value of a long configuration parameter.
Definition: envSubr.c:303
struct osdContext * osd
Definition: epicsReadline.c:38
#define epicsAtExit(F, A)
Convenience macro to register a function and context value to be run when the process exits...
Definition: epicsExit.h:70