Skip to content

Instantly share code, notes, and snippets.

@fenrir-naru
Last active September 18, 2018 16:30
Show Gist options
  • Save fenrir-naru/706ffa714d65e8a7341198bb8dba9afb to your computer and use it in GitHub Desktop.
Save fenrir-naru/706ffa714d65e8a7341198bb8dba9afb to your computer and use it in GitHub Desktop.
int attribute_hidden
Rstd_ReadConsole(const char *prompt, unsigned char *buf, int len,
int addtohistory)
{
if(!R_Interactive) {
#if 0
size_t ll;
int err = 0;
if (!R_Slave) {
fputs(prompt, stdout);
fflush(stdout); /* make sure prompt is output */
}
if (fgets((char *)buf, len, ifp ? ifp: stdin) == NULL)
return 0;
ll = strlen((char *)buf);
/* remove CR in CRLF ending */
if (ll >= 2 && buf[ll - 1] == '\n' && buf[ll - 2] == '\r') {
buf[ll - 2] = '\n';
buf[--ll] = '\0';
}
/* translate if necessary */
if(strlen(R_StdinEnc) && strcmp(R_StdinEnc, "native.enc")) {
size_t res, inb = strlen((char *)buf), onb = len;
/* NB: this is somewhat dangerous. R's main loop and
scan will not call it with a larger value, but
contributed code might. */
char obuf[CONSOLE_BUFFER_SIZE+1];
const char *ib = (const char *)buf;
char *ob = obuf;
if(!cd) {
cd = Riconv_open("", R_StdinEnc);
if(cd == (void *)-1) error(_("encoding '%s' is not recognised"), R_StdinEnc);
}
res = Riconv(cd, &ib, &inb, &ob, &onb);
*ob = '\0';
err = res == (size_t)(-1);
/* errors lead to part of the input line being ignored */
if(err) printf(_("<ERROR: re-encoding failure from encoding '%s'>\n"),
R_StdinEnc);
strncpy((char *)buf, obuf, len);
}
/* according to system.txt, should be terminated in \n, so check this
at eof and error */
if ((err || feof(ifp ? ifp : stdin))
&& (ll == 0 || buf[ll - 1] != '\n') && ll < (size_t)len) {
buf[ll++] = '\n'; buf[ll] = '\0';
}
if (!R_Slave) {
fputs((char *)buf, stdout);
fflush(stdout);
}
return 1;
#endif
}
else {
#if 0 // defined(HAVE_LIBREADLINE)
R_ReadlineData rl_data;
if (UsingReadline) {
rl_data.readline_gotaline = 0;
rl_data.readline_buf = buf;
rl_data.readline_addtohistory = addtohistory;
rl_data.readline_len = len;
rl_data.readline_eof = 0;
rl_data.prev = rl_top;
rl_top = &rl_data;
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = "R";
pushReadline(prompt, readline_handler);
#ifdef HAVE_RL_COMPLETION_MATCHES
initialize_rlcompletion();
#endif
}
else
#endif /* HAVE_LIBREADLINE */
{
fputs(prompt, stdout);
fflush(stdout);
}
if(R_InputHandlers == NULL)
initStdinHandler();
for (;;) {
fd_set *what;
int wt = -1;
if (R_wait_usec > 0) wt = R_wait_usec;
if (Rg_wait_usec > 0 && (wt < 0 || wt > Rg_wait_usec))
wt = Rg_wait_usec;
what = R_checkActivityEx(wt, 0, handleInterrupt);
#ifdef NEED_INT_HANDLER
if (UsingReadline && caught_sigwinch) {
caught_sigwinch = FALSE;
// introduced in readline 4.0: only used for >= 6.3
#ifdef HAVE_RL_RESIZE_TERMINAL
rl_resize_terminal();
static int oldwidth;
int height, width;
rl_get_screen_size(&height,&width);
if (oldwidth >= 0 && oldwidth != width) {
static SEXP opsym = NULL;
if (! opsym)
opsym = install("setWidthOnResize");
Rboolean setOK = asLogical(GetOption1(opsym));
oldwidth = width;
if (setOK != NA_LOGICAL && setOK)
R_SetOptionWidth(width);
}
#endif
}
#endif
/* This is slightly clumsy. We have advertised the
* convention that R_wait_usec == 0 means "wait forever",
* but we also need to enable R_checkActivity to return
* immediately. */
R_runHandlers(R_InputHandlers, what);
if (what == NULL)
continue;
if (FD_ISSET(fileno(stdin), what)) {
/* We could make this a regular handler, but we need
* to pass additional arguments. */
#if 0 // defined(HAVE_LIBREADLINE)
if (UsingReadline) {
rl_callback_read_char();
if(rl_data.readline_eof || rl_data.readline_gotaline) {
rl_top = rl_data.prev;
return(rl_data.readline_eof ? 0 : 1);
}
}
else
#endif /* HAVE_LIBREADLINE */
{
if(fgets((char *)buf, len, stdin) == NULL)
return 0;
else
return 1;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment