int main(int argc, char *argv[]) { EditLine *el = NULL; int num; const char *buf; Tokenizer *tok; #if 0 int lastevent = 0; #endif int ncontinuation; History *hist; HistEvent ev; (void) setlocale(LC_CTYPE, ""); (void) signal(SIGINT, sig); (void) signal(SIGQUIT, sig); (void) signal(SIGHUP, sig); (void) signal(SIGTERM, sig); hist = history_init(); /* Init the builtin history */ /* Remember 100 events */ history(hist, &ev, H_SETSIZE, 100); tok = tok_init(NULL); /* Initialize the tokenizer */ /* Initialize editline */ el = el_init(*argv, stdin, stdout, stderr); el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ el_set(el, EL_PROMPT_ESC, prompt, '\1');/* Set the prompt function */ /* Tell editline to use this history interface */ el_set(el, EL_HIST, history, hist); /* Add a user-defined function */ el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); /* Bind tab to it */ el_set(el, EL_BIND, "^I", "ed-complete", NULL); /* * Bind j, k in vi command mode to previous and next line, instead * of previous and next history. */ el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); /* * Source the user's defaults file. */ el_source(el, NULL); while ((buf = el_gets(el, &num)) != NULL && num != 0) { int ac, cc, co; #ifdef DEBUG int i; #endif const char **av; const LineInfo *li; li = el_line(el); #ifdef DEBUG (void) fprintf(stderr, "==> got %d %s", num, buf); (void) fprintf(stderr, " > li `%.*s_%.*s'\n", (li->cursor - li->buffer), li->buffer, (li->lastchar - 1 - li->cursor), (li->cursor >= li->lastchar) ? "" : li->cursor); #endif if (gotsig) { (void) fprintf(stderr, "Got signal %d.\n", (int)gotsig); gotsig = 0; el_reset(el); } if (!continuation && num == 1) continue; ac = cc = co = 0; ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co); if (ncontinuation < 0) { (void) fprintf(stderr, "Internal error\n"); continuation = 0; continue; } #ifdef DEBUG (void) fprintf(stderr, " > nc %d ac %d cc %d co %d\n", ncontinuation, ac, cc, co); #endif #if 0 if (continuation) { /* * Append to the right event in case the user * moved around in history. */ if (history(hist, &ev, H_SET, lastevent) == -1) err(1, "%d: %s", lastevent, ev.str); history(hist, &ev, H_ADD , buf); } else { history(hist, &ev, H_ENTER, buf); lastevent = ev.num; } #else /* Simpler */ history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); #endif continuation = ncontinuation; ncontinuation = 0; if (continuation) continue; #ifdef DEBUG for (i = 0; i < ac; i++) { (void) fprintf(stderr, " > arg# %2d ", i); if (i != cc) (void) fprintf(stderr, "`%s'\n", av[i]); else (void) fprintf(stderr, "`%.*s_%s'\n", co, av[i], av[i] + co); } #endif if (strcmp(av[0], "history") == 0) { int rv; switch (ac) { case 1: for (rv = history(hist, &ev, H_LAST); rv != -1; rv = history(hist, &ev, H_PREV)) (void) fprintf(stdout, "%4d %s", ev.num, ev.str); break; case 2: if (strcmp(av[1], "clear") == 0) history(hist, &ev, H_CLEAR); else goto badhist; break; case 3: if (strcmp(av[1], "load") == 0) history(hist, &ev, H_LOAD, av[2]); else if (strcmp(av[1], "save") == 0) history(hist, &ev, H_SAVE, av[2]); break; badhist: default: (void) fprintf(stderr, "Bad history arguments\n"); break; } } else if (el_parse(el, ac, av) == -1) { switch (fork()) { case 0: execvp(av[0], __DECONST(char **, av)); perror(av[0]); _exit(1); /*NOTREACHED*/ break; case -1: perror("fork"); break; default: if (wait(&num) == -1) perror("wait"); (void) fprintf(stderr, "Exit %x\n", num); break; } } tok_reset(tok); } el_end(el); tok_end(tok); history_end(hist); return (0); }
int el_parse_from_buffer (stralloc *sa, buffer *b) { return el_parse(sa, &next, b) ; }
int cmdloop(void) { char *line; const char *elline; int cmd_argc, rval = 0, known; #define scratch known char **cmd_argv; struct cmdtable *cmdp; History *hist; EditLine *elptr; HistEvent he; curinode = check_ginode(ROOTINO); curinum = ROOTINO; printactive(0); hist = history_init(); history(hist, &he, H_SETSIZE, 100); /* 100 elt history buffer */ elptr = el_init("fsdb", stdin, stdout, stderr); el_set(elptr, EL_EDITOR, "emacs"); el_set(elptr, EL_PROMPT, prompt); el_set(elptr, EL_HIST, history, hist); el_source(elptr, NULL); while ((elline = el_gets(elptr, &scratch)) != NULL && scratch != 0) { if (check_debug) printf("command `%s'\n", elline); history(hist, &he, H_ENTER, elline); line = strdup(elline); cmd_argv = crack(line, &cmd_argc); /* * el_parse returns -1 to signal that it's not been handled * internally. */ if (el_parse(elptr, cmd_argc, (const char **)cmd_argv) != -1) continue; if (cmd_argc) { known = 0; for (cmdp = cmds; cmdp->cmd; cmdp++) { if (!strcmp(cmdp->cmd, cmd_argv[0])) { if ((cmdp->flags & FL_WR) == FL_WR && nflag) warnx("`%s' requires write access", cmd_argv[0]), rval = 1; else if (cmd_argc >= cmdp->minargc && cmd_argc <= cmdp->maxargc) rval = (*cmdp->handler)(cmd_argc, cmd_argv); else if (cmd_argc >= cmdp->minargc && (cmdp->flags & FL_ST) == FL_ST) { strcpy(line, elline); cmd_argv = recrack(line, &cmd_argc, cmdp->maxargc); rval = (*cmdp->handler)(cmd_argc, cmd_argv); } else rval = argcount(cmdp, cmd_argc, cmd_argv); known = 1; break; } } if (!known) warnx("unknown command `%s'", cmd_argv[0]), rval = 1; } else rval = 0; free(line); if (rval < 0) /* user typed "quit" */ return 0; if (rval) warnx("rval was %d", rval); } el_end(elptr); history_end(hist); return rval; }
int cmdloop(void *arg) { struct clitenv *env = arg; EditLine *el = env->el; History *hist = env->hist; const char *elline; int cnt; char **argv; int maxargs = 16; /* XXX */ int stop; stop = 0; if ((argv = calloc(sizeof(char *), maxargs)) == NULL) err(1, "malloc"); while (!stop && (elline = el_gets(el, &cnt)) != NULL) { char *line, *orgline; struct c**t *cmdp; char **ap; int argc, res; HistEvent ev; memset(argv, 0, sizeof(char *) * maxargs); history(hist, &ev, H_ENTER, elline); orgline = line = strdup(elline); if (line == NULL) err(1, "strdup"); argc = 0; for (ap = argv; (*ap = strsep(&line, " \t\n")) != NULL;) { if (**ap != '\0') { ++ap; if (++argc == maxargs) break; } } if (argc == maxargs) { fprintf(stderr, "Too many arguments\n"); goto cmdout; } if (!argc) goto cmdout; /* * Editline commands. */ if (el_parse(el, argc, (const char **)argv) != -1) goto cmdout; if ((res = name_to_cmd(argv[0], env->cmds, env->ncmds, &cmdp)) == 1) { if (argc - 1 > cmdp->maxargc) fprintf(stderr, "Too many arguments\n"); else if (argc - 1 < cmdp->minargc) fprintf(stderr, "Too few arguments\n"); else stop = (*cmdp->handler)(argc, argv, cmdp->arg ? cmdp->arg : env); } else { fprintf(stderr, "%s command: %s\n", res == 0 ? "unknown" : "ambiguous", argv[0]); } cmdout: free(orgline); } free(argv); return stop; }
/* * Command parser. */ static void cmdscanner(void) { register struct cmd *c; static EditLine *el; static History *hist; HistEvent he; size_t len; int num; const char *bp; num = 0; bp = NULL; el = NULL; hist = NULL; for (;;) { if (fromatty) { if (!el) { el = el_init("lpc", stdin, stdout, stderr); hist = history_init(); history(hist, &he, H_SETSIZE, 100); el_set(el, EL_HIST, history, hist); el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_PROMPT, lpc_prompt); el_set(el, EL_SIGNAL, 1); el_source(el, NULL); /* * EditLine init may call 'cgetset()' to set a * capability-db meant for termcap (eg: to set * terminal type 'xterm'). Reset that now, or * that same db-information will be used for * printcap (giving us an "xterm" printer, with * all kinds of invalid capabilities...). */ cgetset(NULL); } if ((bp = el_gets(el, &num)) == NULL || num == 0) quit(0, NULL); len = (num > MAX_CMDLINE - 1) ? MAX_CMDLINE - 1 : num; memcpy(cmdline, bp, len); cmdline[len] = 0; history(hist, &he, H_ENTER, bp); } else { if (fgets(cmdline, MAX_CMDLINE, stdin) == NULL) quit(0, NULL); if (cmdline[0] == 0 || cmdline[0] == '\n') break; } makeargv(); if (margc == 0) continue; if (el != NULL && el_parse(el, margc, margv) != -1) continue; c = getcmd(margv[0]); if (c == (struct cmd *)-1) { printf("?Ambiguous command\n"); continue; } if (c == NULL) { printf("?Invalid command\n"); continue; } if ((c->c_opts & LPC_PRIVCMD) && getuid() && ingroup(LPR_OPER) == 0) { printf("?Privileged command\n"); continue; } /* * Two different commands might have the same generic rtn * (eg: "clean" and "tclean"), and just use different * handler routines for distinct command-setup. The handler * routine might also be set on a generic routine for * initial parameter processing. */ if (c->c_generic != NULL) generic(c->c_generic, c->c_opts, c->c_handler, margc, margv); else (*c->c_handler)(margc, margv); } }
int main(int argc, char *argv[]) { int num; const char *buf; Tokenizer *tok; #if 0 int lastevent = 0; #endif int ncontinuation; History *hist; HistEvent ev; (void) signal(SIGINT, sig); (void) signal(SIGQUIT, sig); (void) signal(SIGHUP, sig); (void) signal(SIGTERM, sig); hist = history_init(); /* Init the builtin history */ /* Remember 100 events */ history(hist, &ev, H_SETSIZE, 100); tok = tok_init(NULL); /* Initialize the tokenizer */ /* Initialize editline */ el = el_init(*argv, stdin, stdout, stderr); el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ el_set(el, EL_PROMPT, prompt); /* Set the prompt function */ /* Tell editline to use this history interface */ el_set(el, EL_HIST, history, hist); /* Add a user-defined function */ el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); /* Bind tab to it */ el_set(el, EL_BIND, "^I", "ed-complete", NULL); /* * Bind j, k in vi command mode to previous and next line, instead * of previous and next history. */ el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); /* * Source the user's defaults file. */ el_source(el, NULL); while ((buf = el_gets(el, &num)) != NULL && num != 0) { int ac; const char **av; #ifdef DEBUG (void) fprintf(stderr, "got %d %s", num, buf); #endif if (!continuation && num == 1) continue; ncontinuation = tok_line(tok, buf, &ac, &av) > 0; #if 0 if (continuation) { /* * Append to the right event in case the user * moved around in history. */ if (history(hist, &ev, H_SET, lastevent) == -1) err(1, "%d: %s\n", lastevent, ev.str); history(hist, &ev, H_ADD , buf); } else { history(hist, &ev, H_ENTER, buf); lastevent = ev.num; } #else /* Simpler */ history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); #endif continuation = ncontinuation; ncontinuation = 0; if (strcmp(av[0], "history") == 0) { int rv; switch (ac) { case 1: for (rv = history(hist, &ev, H_LAST); rv != -1; rv = history(hist, &ev, H_PREV)) (void) fprintf(stdout, "%4d %s", ev.num, ev.str); break; case 2: if (strcmp(av[1], "clear") == 0) history(hist, &ev, H_CLEAR); else goto badhist; break; case 3: if (strcmp(av[1], "load") == 0) history(hist, &ev, H_LOAD, av[2]); else if (strcmp(av[1], "save") == 0) history(hist, &ev, H_SAVE, av[2]); break; badhist: default: (void) fprintf(stderr, "Bad history arguments\n"); break; } } else if (el_parse(el, ac, av) == -1) { switch (fork()) { case 0: execvp(av[0], (char *const *)av); perror(av[0]); _exit(1); /*NOTREACHED*/ break; case -1: perror("fork"); break; default: if (wait(&num) == -1) perror("wait"); (void) fprintf(stderr, "Exit %x\n", num); break; } } tok_reset(tok); } el_end(el); tok_end(tok); history_end(hist); return (0); }
static int cmdloop(void) { char *line = NULL; const char *elline; int cmd_argc, rval = 0, known; #define scratch known char **cmd_argv; struct cmdtable *cmdp; History *hist; EditLine *elptr; HistEvent hev; curinode = ginode(ROOTINO); curinum = ROOTINO; printactive(); hist = history_init(); history(hist, &hev, H_SETSIZE, 100); /* 100 elt history buffer */ elptr = el_init(__progname, stdin, stdout, stderr); el_set(elptr, EL_EDITOR, "emacs"); el_set(elptr, EL_PROMPT, prompt); el_set(elptr, EL_HIST, history, hist); el_source(elptr, NULL); while ((elline = el_gets(elptr, &scratch)) != NULL && scratch != 0) { if (debug) printf("command `%s'\n", line); history(hist, &hev, H_ENTER, elline); line = strdup(elline); if (line == NULL) errx(1, "out of memory"); cmd_argv = crack(line, &cmd_argc); if (cmd_argc) { /* * el_parse returns -1 to signal that it's not been handled * internally. */ if (el_parse(elptr, cmd_argc, (const char **)cmd_argv) != -1) continue; known = 0; for (cmdp = cmds; cmdp->cmd; cmdp++) { if (!strcmp(cmdp->cmd, cmd_argv[0])) { if (cmd_argc >= cmdp->minargc && cmd_argc <= cmdp->maxargc) rval = (*cmdp->handler)(cmd_argc, cmd_argv); else rval = argcount(cmdp, cmd_argc, cmd_argv); known = 1; break; } } if (!known) { warnx("unknown command `%s'", cmd_argv[0]); rval = 1; } } else rval = 0; free(line); if (rval < 0) return rval; if (rval) warnx("rval was %d", rval); } el_end(elptr); history_end(hist); return rval; }
/* * Command parser. */ void cmdscanner(int top) { struct cmd *c; int num; HistEvent hev; if (!top && !editing) (void)putc('\n', ttyout); for (;;) { if (!editing) { if (fromatty) { fputs(prompt(), ttyout); (void)fflush(ttyout); } if (fgets(line, sizeof(line), stdin) == NULL) quit(0, 0); num = strlen(line); if (num == 0) break; if (line[--num] == '\n') { if (num == 0) break; line[num] = '\0'; } else if (num == sizeof(line) - 2) { fputs("sorry, input line too long.\n", ttyout); while ((num = getchar()) != '\n' && num != EOF) /* void */; break; } /* else it was a line without a newline */ } else { const char *buf; cursor_pos = NULL; if ((buf = el_gets(el, &num)) == NULL || num == 0) quit(0, 0); if (buf[--num] == '\n') { if (num == 0) break; } if (num >= sizeof(line)) { fputs("sorry, input line too long.\n", ttyout); break; } memcpy(line, buf, (size_t)num); line[num] = '\0'; history(hist, &hev, H_ENTER, buf); } makeargv(); if (margc == 0) continue; c = getcmd(margv[0]); if (c == (struct cmd *)-1) { fputs("?Ambiguous command.\n", ttyout); continue; } if (c == 0) { /* * Give editline(3) a shot at unknown commands. * XXX - bogus commands with a colon in * them will not elicit an error. */ if (editing && el_parse(el, margc, (const char **)margv) != 0) fputs("?Invalid command.\n", ttyout); continue; } if (c->c_conn && !connected) { fputs("Not connected.\n", ttyout); continue; } confirmrest = 0; (*c->c_handler)(margc, margv); if (bell && c->c_bell) (void)putc('\007', ttyout); if (c->c_handler != help) break; } (void)signal(SIGINT, (sig_t)intr); (void)signal(SIGPIPE, (sig_t)lostpeer); }
/* * Command parser. */ void cmdscanner(void) { struct cmd *c; char *p; #ifndef NO_EDITCOMPLETE int ch; #endif size_t num; for (;;) { #ifndef NO_EDITCOMPLETE if (!editing) { #endif /* !NO_EDITCOMPLETE */ if (fromatty) { fputs(prompt(), ttyout); p = rprompt(); if (*p) fprintf(ttyout, "%s ", p); } (void)fflush(ttyout); num = getline(stdin, line, sizeof(line), NULL); switch (num) { case -1: /* EOF */ case -2: /* error */ if (fromatty) putc('\n', ttyout); quit(0, NULL); /* NOTREACHED */ case -3: /* too long; try again */ fputs("Sorry, input line is too long.\n", ttyout); continue; case 0: /* empty; try again */ continue; default: /* all ok */ break; } #ifndef NO_EDITCOMPLETE } else { const char *buf; HistEvent ev; cursor_pos = NULL; buf = el_gets(el, &ch); num = ch; if (buf == NULL || num == 0) { if (fromatty) putc('\n', ttyout); quit(0, NULL); } if (num >= sizeof(line)) { fputs("Sorry, input line is too long.\n", ttyout); break; } memcpy(line, buf, num); if (line[--num] == '\n') { line[num] = '\0'; if (num == 0) break; } history(hist, &ev, H_ENTER, buf); } #endif /* !NO_EDITCOMPLETE */ makeargv(); if (margc == 0) continue; c = getcmd(margv[0]); if (c == (struct cmd *)-1) { fputs("?Ambiguous command.\n", ttyout); continue; } if (c == NULL) { #if !defined(NO_EDITCOMPLETE) /* * attempt to el_parse() unknown commands. * any command containing a ':' would be parsed * as "[prog:]cmd ...", and will result in a * false positive if prog != "ftp", so treat * such commands as invalid. */ if (strchr(margv[0], ':') != NULL || el_parse(el, margc, (const char **)margv) != 0) #endif /* !NO_EDITCOMPLETE */ fputs("?Invalid command.\n", ttyout); continue; } if (c->c_conn && !connected) { fputs("Not connected.\n", ttyout); continue; } confirmrest = 0; margv[0] = c->c_name; (*c->c_handler)(margc, margv); if (bell && c->c_bell) (void)putc('\007', ttyout); if (c->c_handler != help) break; } (void)xsignal(SIGINT, intr); (void)xsignal(SIGPIPE, lostpeer); }
int el_parse_from_string (stralloc *sa, char const *s) { return el_parse(sa, &next, &s) ; }