*
* $Header$
* $Locker$
- *
+ *
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* Permission to use, copy, modify, and distribute this software and
* express or implied warranty.
*/
+#include "config.h"
#include "ss_internal.h"
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/param.h>
-#ifdef BSD
-#include <sgtty.h>
-#endif
-
-#ifndef lint
-static char const rcs_id[] =
- "$Header$";
-#endif
typedef void sigret_t;
static jmp_buf listen_jmpb;
static sigret_t (*sig_cont)(int);
-static sigret_t print_prompt(int sig)
+static sigret_t print_prompt(int sig __SS_ATTR((unused)))
{
-#ifdef BSD
- /* put input into a reasonable mode */
- struct sgttyb ttyb;
- if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) {
- if (ttyb.sg_flags & (CBREAK|RAW)) {
- ttyb.sg_flags &= ~(CBREAK|RAW);
- (void) ioctl(0, TIOCSETP, &ttyb);
- }
+ if (current_info->redisplay)
+ (*current_info->redisplay)();
+ else {
+ (void) fputs(current_info->prompt, stdout);
+ (void) fflush(stdout);
}
-#endif
- (void) fputs(current_info->prompt, stdout);
- (void) fflush(stdout);
}
-static sigret_t listen_int_handler(int sig)
+static sigret_t listen_int_handler(int sig __SS_ATTR((unused)))
{
putc('\n', stdout);
signal(SIGINT, listen_int_handler);
ss_data *info;
sigret_t (*sig_int)(int), (*old_sig_cont)(int);
char input[BUFSIZ];
-#ifdef POSIX_SIGNALS
sigset_t omask, igmask;
-#else
- int mask;
-#endif
int code;
jmp_buf old_jmpb;
ss_data *old_info = current_info;
-
+ char *line;
+
current_info = info = ss_info(sci_idx);
sig_cont = (sigret_t (*)(int)) 0;
info->abort = 0;
-#ifdef POSIX_SIGNALS
sigemptyset(&igmask);
sigaddset(&igmask, SIGINT);
sigprocmask(SIG_BLOCK, &igmask, &omask);
-#else
- mask = sigblock(sigmask(SIGINT));
-#endif
memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
sig_int = signal(SIGINT, listen_int_handler);
setjmp(listen_jmpb);
-#ifdef POSIX_SIGNALS
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
-#else
- (void) sigsetmask(mask);
-#endif
+
while(!info->abort) {
- print_prompt(0);
old_sig_cont = sig_cont;
sig_cont = signal(SIGCONT, print_prompt);
if (sig_cont == print_prompt)
sig_cont = old_sig_cont;
- if (fgets(input, BUFSIZ, stdin) != input) {
- code = SS_ET_EOF;
- (void) signal(SIGCONT, sig_cont);
- goto egress;
+ if (info->readline) {
+ line = (*info->readline)(current_info->prompt);
+ } else {
+ print_prompt(0);
+ if (fgets(input, BUFSIZ, stdin) == input)
+ line = input;
+ else
+ line = NULL;
+
+ input[BUFSIZ-1] = 0;
}
- input[BUFSIZ-1] = 0;
-
- cp = strchr(input, '\n');
+ if (line == NULL) {
+ code = SS_ET_EOF;
+ (void) signal(SIGCONT, sig_cont);
+ goto egress;
+ }
+
+ cp = strchr(line, '\n');
if (cp) {
*cp = '\0';
- if (cp == input)
+ if (cp == line)
continue;
}
(void) signal(SIGCONT, sig_cont);
+ if (info->add_history)
+ (*info->add_history)(line);
- code = ss_execute_line (sci_idx, input);
+ code = ss_execute_line (sci_idx, line);
if (code == SS_ET_COMMAND_NOT_FOUND) {
- register char *c = input;
+ register char *c = line;
while (*c == ' ' || *c == '\t')
c++;
cp = strchr (c, ' ');
"Unknown request \"%s\". Type \"?\" for a request list.",
c);
}
+ if (info->readline)
+ free(line);
}
code = 0;
egress:
{
ss_info(sci_idx)->abort = 1;
ss_info(sci_idx)->exit_status = code;
-
+
}
-void ss_quit(int argc, const char * const *argv, int sci_idx, pointer infop)
+void ss_quit(int argc __SS_ATTR((unused)),
+ ss_argv_t argv __SS_ATTR((unused)),
+ int sci_idx, pointer infop __SS_ATTR((unused)))
{
ss_abort_subsystem(sci_idx, 0);
}
+
+#ifdef HAVE_DLOPEN
+#define get_request(tbl,idx) ((tbl) -> requests + (idx))
+
+static char *cmd_generator(const char *text, int state)
+{
+ static int len;
+ static ss_request_table **rqtbl;
+ static int curr_rqt;
+ static char const * const * name;
+ ss_request_entry *request;
+ char *ret;
+
+ if (state == 0) {
+ len = strlen(text);
+ rqtbl = current_info->rqt_tables;
+ if (!rqtbl || !*rqtbl)
+ return 0;
+ curr_rqt = 0;
+ name = 0;
+ }
+
+ while (1) {
+ if (!name || !*name) {
+ request = get_request(*rqtbl, curr_rqt++);
+ name = request->command_names;
+ if (!name) {
+ rqtbl++;
+ if (*rqtbl) {
+ curr_rqt = 0;
+ continue;
+ } else
+ break;
+ }
+ }
+ if (strncmp(*name, text, len) == 0) {
+ ret = malloc(strlen(*name)+1);
+ if (ret)
+ strcpy(ret, *name);
+ name++;
+ return ret;
+ }
+ name++;
+ }
+
+ return 0;
+}
+
+char **ss_rl_completion(const char *text, int start,
+ int end __SS_ATTR((unused)))
+{
+ if ((start == 0) && current_info->rl_completion_matches)
+ return (*current_info->rl_completion_matches)
+ (text, cmd_generator);
+ return 0;
+}
+#endif
+