X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/017a82124bf2ea39ced5aa4c8f969c18b3c2fb90..63621a81d16ab743de6b57d47578a9a2c670ad22:/uip/prompter.c diff --git a/uip/prompter.c b/uip/prompter.c index 79e0eb79..224734e0 100644 --- a/uip/prompter.c +++ b/uip/prompter.c @@ -1,86 +1,44 @@ - -/* - * prompter.c -- simple prompting editor front-end +/* prompter.c -- simple prompting editor front-end * - * $Id$ + * This code is Copyright (c) 2002, by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. */ #include #include #include -#include -#include +#include +#include "sbr/m_mktemp.h" #include -#ifdef HAVE_TERMIOS_H -# include -#else -# ifdef HAVE_TERMIO_H -# include -# else -# include -# endif -#endif +#include #define QUOTE '\\' -#ifndef CKILL -# define CKILL '@' -#endif - -#ifndef CERASE -# define CERASE '#' -#endif - -static struct swit switches[] = { -#define ERASESW 0 - { "erase chr", 0 }, -#define KILLSW 1 - { "kill chr", 0 }, -#define PREPSW 2 - { "prepend", 0 }, -#define NPREPSW 3 - { "noprepend", 0 }, -#define RAPDSW 4 - { "rapid", 0 }, -#define NRAPDSW 5 - { "norapid", 0 }, -#define BODYSW 6 - { "body", -4 }, -#define NBODYSW 7 - { "nobody", -6 }, -#define DOTSW 8 - { "doteof", 0 }, -#define NDOTSW 9 - { "nodoteof", 0 }, -#define VERSIONSW 10 - { "version", 0 }, -#define HELPSW 11 - { "help", 0 }, - { NULL, 0 } -}; - -extern int errno; - -#ifdef HAVE_TERMIOS_H +#define PROMPTER_SWITCHES \ + X("erase chr", 0, ERASESW) \ + X("kill chr", 0, KILLSW) \ + X("prepend", 0, PREPSW) \ + X("noprepend", 0, NPREPSW) \ + X("rapid", 0, RAPDSW) \ + X("norapid", 0, NRAPDSW) \ + X("body", -4, BODYSW) \ + X("nobody", -6, NBODYSW) \ + X("doteof", 0, DOTSW) \ + X("nodoteof", 0, NDOTSW) \ + X("version", 0, VERSIONSW) \ + X("help", 0, HELPSW) \ + +#define X(sw, minchars, id) id, +DEFINE_SWITCH_ENUM(PROMPTER); +#undef X + +#define X(sw, minchars, id) { sw, minchars, id }, +DEFINE_SWITCH_ARRAY(PROMPTER, switches); +#undef X + static struct termios tio; -# define ERASE tio.c_cc[VERASE] -# define KILL tio.c_cc[VKILL] -# define INTR tio.c_cc[VINTR] -#else -# ifdef HAVE_TERMIO_H -static struct termio tio; -# define ERASE tio.c_cc[VERASE] -# define KILL tio.c_cc[VKILL] -# define INTR tio.c_cc[VINTR] -# else -static struct sgttyb tio; -static struct tchars tc; -# define ERASE tio.sg_erase -# define KILL tio.sg_kill -# define INTR tc.t_intrc -# endif -#endif static int wtuser = 0; static int sigint = 0; @@ -89,10 +47,10 @@ static jmp_buf sigenv; /* * prototypes */ -int getln (char *, int); +static int getln (char *, int); static int chrcnv (char *); static void chrdsp (char *, char); -static RETSIGTYPE intrser (int); +static void intrser (int); int @@ -101,18 +59,14 @@ main (int argc, char **argv) int body = 1, prepend = 1, rapid = 0; int doteof = 0, fdi, fdo, i, state; char *cp, *drft = NULL, *erasep = NULL; - char *killp = NULL, name[NAMESZ], field[BUFSIZ]; - char buffer[BUFSIZ], tmpfil[BUFSIZ]; + char *killp = NULL, name[NAMESZ], field[NMH_BUFSIZ]; + char buffer[BUFSIZ]; char **arguments, **argp; FILE *in, *out; + char *tmpfil; + m_getfld_state_t gstate; -#ifdef LOCALE - setlocale(LC_ALL, ""); -#endif - invo_name = r1bindex (argv[0], '/'); - - /* read user profile/context */ - context_read(); + if (nmh_init(argv[0], 2)) { return 1; } arguments = getarguments (invo_name, argc, argv, 1); argp = arguments; @@ -130,10 +84,10 @@ main (int argc, char **argv) snprintf (buffer, sizeof(buffer), "%s [switches] file", invo_name); print_help (buffer, switches, 1); - done (1); + done (0); case VERSIONSW: print_version(invo_name); - done (1); + done (0); case ERASESW: if (!(erasep = *argp++) || *erasep == '-') @@ -182,56 +136,34 @@ main (int argc, char **argv) if ((in = fopen (drft, "r")) == NULL) adios (drft, "unable to open"); - strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil)); - if ((out = fopen (tmpfil, "w")) == NULL) - adios (tmpfil, "unable to create"); - chmod (tmpfil, 0600); + if ((tmpfil = m_mktemp2(NULL, invo_name, NULL, &out)) == NULL) { + adios(NULL, "unable to create temporary file in %s", get_temp_dir()); + } /* * Are we changing the kill or erase character? */ if (killp || erasep) { -#ifdef HAVE_TERMIOS_H cc_t save_erase, save_kill; -#else - int save_erase, save_kill; -#endif /* get the current terminal attributes */ -#ifdef HAVE_TERMIOS_H tcgetattr(0, &tio); -#else -# ifdef HAVE_TERMIO_H - ioctl(0, TCGETA, &tio); -# else - ioctl (0, TIOCGETP, (char *) &tio); - ioctl (0, TIOCGETC, (char *) &tc); -# endif -#endif /* save original kill, erase character for later */ - save_kill = KILL; - save_erase = ERASE; + save_kill = tio.c_cc[VKILL]; + save_erase = tio.c_cc[VERASE]; /* set new kill, erase character in terminal structure */ - KILL = killp ? chrcnv (killp) : save_kill; - ERASE = erasep ? chrcnv (erasep) : save_erase; + tio.c_cc[VKILL] = killp ? chrcnv (killp) : save_kill; + tio.c_cc[VERASE] = erasep ? chrcnv (erasep) : save_erase; /* set the new terminal attributes */ -#ifdef HAVE_TERMIOS_H tcsetattr(0, TCSADRAIN, &tio); -#else -# ifdef HAVE_TERMIO_H - ioctl(0, TCSETAW, &tio); -# else - ioctl (0, TIOCSETN, (char *) &tio); -# endif -#endif /* print out new kill erase characters */ - chrdsp ("erase", ERASE); - chrdsp (", kill", KILL); - chrdsp (", intr", INTR); + chrdsp ("erase", tio.c_cc[VERASE]); + chrdsp (", kill", tio.c_cc[VKILL]); + chrdsp (", intr", tio.c_cc[VINTR]); putchar ('\n'); fflush (stdout); @@ -240,8 +172,8 @@ main (int argc, char **argv) * setup in terminal structure so we can easily * restore it upon exit. */ - KILL = save_kill; - ERASE = save_erase; + tio.c_cc[VKILL] = save_kill; + tio.c_cc[VERASE] = save_erase; } sigint = 0; @@ -250,10 +182,11 @@ main (int argc, char **argv) /* * Loop through the lines of the draft skeleton. */ - for (state = FLD;;) { - switch (state = m_getfld (state, name, field, sizeof(field), in)) { + gstate = m_getfld_state_init(in); + for (;;) { + int fieldsz = sizeof field; + switch (state = m_getfld2(&gstate, name, field, &fieldsz)) { case FLD: - case FLDEOF: case FLDPLUS: /* * Check if the value of field contains anything @@ -268,10 +201,10 @@ main (int argc, char **argv) printf ("%s:%s", name, field); fprintf (out, "%s:%s", name, field); while (state == FLDPLUS) { - state = - m_getfld (state, name, field, sizeof(field), in); - printf ("%s", field); - fprintf (out, "%s", field); + fieldsz = sizeof field; + state = m_getfld2(&gstate, name, field, &fieldsz); + fputs(field, stdout); + fputs(field, out); } } else { /* Else, get value of header field */ @@ -281,17 +214,9 @@ main (int argc, char **argv) if (i == -1) { abort: if (killp || erasep) { -#ifdef HAVE_TERMIOS_H tcsetattr(0, TCSADRAIN, &tio); -#else -# ifdef HAVE_TERMIO - ioctl (0, TCSETA, &tio); -# else - ioctl (0, TIOCSETN, (char *) &tio); -# endif -#endif } - unlink (tmpfil); + (void) m_unlink (tmpfil); done (1); } if (i != 0 || (field[0] != '\n' && field[0] != 0)) { @@ -299,7 +224,7 @@ abort: do { if (field[0] != ' ' && field[0] != '\t') putc (' ', out); - fprintf (out, "%s", field); + fputs(field, out); } while (i == 1 && (i = getln (field, sizeof(field))) >= 0); if (i == -1) @@ -307,26 +232,18 @@ abort: } } - if (state == FLDEOF) { /* moby hack */ - fprintf (out, "--------\n"); - printf ("--------\n"); - if (!body) - break; - goto no_body; - } continue; case BODY: - case BODYEOF: case FILEEOF: if (!body) break; fprintf (out, "--------\n"); if (field[0] == 0 || !prepend) - printf ("--------\n"); + puts("--------"); if (field[0]) { if (prepend && body) { - printf ("\n--------Enter initial text\n\n"); + puts("\n--------Enter initial text\n"); fflush (stdout); for (;;) { getln (buffer, sizeof(buffer)); @@ -334,22 +251,22 @@ abort: break; if (buffer[0] == 0) break; - fprintf (out, "%s", buffer); + fputs(buffer, out); } } do { - fprintf (out, "%s", field); + fputs(field, out); if (!rapid && !sigint) - printf ("%s", field); + fputs(field, stdout); } while (state == BODY && - (state = m_getfld (state, name, field, sizeof(field), in))); + (fieldsz = sizeof field, + state = m_getfld2(&gstate, name, field, &fieldsz))); if (prepend || !body) break; - else - printf ("\n--------Enter additional text\n\n"); + puts("\n--------Enter additional text\n"); } -no_body: + fflush (stdout); for (;;) { getln (field, sizeof(field)); @@ -357,7 +274,7 @@ no_body: break; if (field[0] == 0) break; - fprintf (out, "%s", field); + fputs(field, out); } break; @@ -366,9 +283,10 @@ no_body: } break; } + m_getfld_state_destroy (&gstate); if (body) - printf ("--------\n"); + puts("--------"); fflush (stdout); fclose (in); @@ -376,15 +294,7 @@ no_body: SIGNAL (SIGINT, SIG_IGN); if (killp || erasep) { -#ifdef HAVE_TERMIOS_H tcsetattr(0, TCSADRAIN, &tio); -#else -# ifdef HAVE_TERMIO_H - ioctl (0, TCSETAW, &tio); -# else - ioctl (0, TIOCSETN, (char *) &tio); -# endif -#endif } if ((fdi = open (tmpfil, O_RDONLY)) == NOTOK) @@ -394,21 +304,22 @@ no_body: cpydata (fdi, fdo, tmpfil, drft); close (fdi); close (fdo); - unlink (tmpfil); + (void) m_unlink (tmpfil); context_save (); /* save the context file */ - return done (0); + done (0); + return 1; } -int +static int getln (char *buffer, int n) { int c; char *cp; + static int quoting = 0; - cp = buffer; - *cp = 0; + *buffer = 0; switch (setjmp (sigenv)) { case OK: @@ -424,15 +335,20 @@ getln (char *buffer, int n) return NOTOK; } + cp = buffer; + *cp = 0; + for (;;) { switch (c = getchar ()) { case EOF: + quoting = 0; clearerr (stdin); longjmp (sigenv, DONE); case '\n': - if (cp[-1] == QUOTE) { - cp[-1] = c; + if (quoting) { + *(cp - 1) = c; + quoting = 0; wtuser = 0; return 1; } @@ -442,6 +358,11 @@ getln (char *buffer, int n) return 0; default: + if (c == QUOTE) { + quoting = 1; + } else { + quoting = 0; + } if (cp < buffer + n) *cp++ = c; *cp = 0; @@ -450,12 +371,10 @@ getln (char *buffer, int n) } -static RETSIGTYPE +static void intrser (int i) { -#ifndef RELIABLE_SIGNALS - SIGNAL (SIGINT, intrser); -#endif + NMH_UNUSED (i); if (wtuser) longjmp (sigenv, NOTOK);