X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fprompter.c;h=7f71e028be4b43affaa581d1cccddfcb6cc0c0f4;hp=024f6049fb363601540164e4ef25a128655c6edf;hb=6e9577f324bef90765a5edc02044eb111ec48072;hpb=5f2b39344cca1086c975d47b730929d8f1904214 diff --git a/uip/prompter.c b/uip/prompter.c index 024f604..7f71e02 100644 --- a/uip/prompter.c +++ b/uip/prompter.c @@ -12,81 +12,59 @@ #include #include #include - -#include - -#define QUOTE '\\' - -#ifndef CKILL -# define CKILL '@' -#endif - -#ifndef CERASE -# define CERASE '#' -#endif +#include +#include +#include +#include +#include static struct swit switches[] = { -#define ERASESW 0 - { "erase chr", 0 }, -#define KILLSW 1 - { "kill chr", 0 }, -#define PREPSW 2 +#define PREPSW 0 { "prepend", 0 }, -#define NPREPSW 3 +#define NPREPSW 1 { "noprepend", 2 }, -#define RAPDSW 4 +#define RAPDSW 2 { "rapid", 0 }, -#define NRAPDSW 5 +#define NRAPDSW 3 { "norapid", 2 }, -#define BODYSW 6 - { "body", -4 }, -#define NBODYSW 7 - { "nobody", -6 }, -#define DOTSW 8 - { "doteof", 0 }, -#define NDOTSW 9 - { "nodoteof", 2 }, -#define VERSIONSW 10 +#define BODYSW 4 + { "body", 0 }, +#define NBODYSW 5 + { "nobody", 2 }, +#define VERSIONSW 6 { "Version", 0 }, -#define HELPSW 11 +#define HELPSW 7 { "help", 0 }, { NULL, 0 } }; +char *version=VERSION; -static struct termios tio; -#define ERASE tio.c_cc[VERASE] -#define KILL tio.c_cc[VKILL] -#define INTR tio.c_cc[VINTR] - -static int wtuser = 0; -static int sigint = 0; +volatile sig_atomic_t wtuser = 0; +volatile sig_atomic_t sigint = 0; static jmp_buf sigenv; /* ** prototypes */ int getln(char *, int); -static int chrcnv(char *); -static void chrdsp(char *, char); static void intrser(int); int 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]; + int qbody = 1, prepend = 1, rapid = 0; + int fdi, fdo, i; + char *cp, *drft = NULL; + enum state state; + struct field f = {{0}}; char buffer[BUFSIZ], tmpfil[BUFSIZ]; char **arguments, **argp; FILE *in, *out; char *tfile = NULL; -#ifdef LOCALE setlocale(LC_ALL, ""); -#endif invo_name = mhbasename(argv[0]); /* read user profile/context */ @@ -95,35 +73,25 @@ main(int argc, char **argv) arguments = getarguments(invo_name, argc, argv, 1); argp = arguments; - while ((cp = *argp++)) + while ((cp = *argp++)) { if (*cp == '-') { switch (smatch(++cp, switches)) { case AMBIGSW: ambigsw(cp, switches); - done(1); + exit(EX_USAGE); case UNKWNSW: - adios(NULL, "-%s unknown", cp); + adios(EX_USAGE, NULL, "-%s unknown", cp); case HELPSW: snprintf(buffer, sizeof(buffer), "%s [switches] file", invo_name); print_help(buffer, switches, 1); - done(1); + exit(argc == 2 ? EX_OK : EX_USAGE); + case VERSIONSW: print_version(invo_name); - done(1); - - case ERASESW: - if (!(erasep = *argp++) || *erasep == '-') - adios(NULL, "missing argument to %s", - argp[-2]); - continue; - case KILLSW: - if (!(killp = *argp++) || *killp == '-') - adios(NULL, "missing argument to %s", - argp[-2]); - continue; + exit(argc == 2 ? EX_OK : EX_USAGE); case PREPSW: prepend++; @@ -140,208 +108,167 @@ main(int argc, char **argv) continue; case BODYSW: - body++; + qbody++; continue; case NBODYSW: - body = 0; - continue; - - case DOTSW: - doteof++; - continue; - case NDOTSW: - doteof = 0; + qbody = 0; continue; } } else if (!drft) { drft = cp; } + } - if (!drft) - adios(NULL, "usage: %s [switches] file", invo_name); - if ((in = fopen(drft, "r")) == NULL) - adios(drft, "unable to open"); + if (!drft) { + adios(EX_USAGE, NULL, "usage: %s [switches] file", invo_name); + } + if ((in = fopen(drft, "r")) == NULL) { + adios(EX_IOERR, drft, "unable to open"); + } tfile = m_mktemp2(NULL, invo_name, NULL, &out); - if (tfile == NULL) - adios("prompter", "unable to create temporary file"); + if (tfile == NULL) { + adios(EX_CANTCREAT, "prompter", "unable to create temporary file"); + } chmod(tmpfil, 0600); strncpy(tmpfil, tfile, sizeof(tmpfil)); - /* - ** Are we changing the kill or erase character? - */ - if (killp || erasep) { - cc_t save_erase, save_kill; - - /* get the current terminal attributes */ - tcgetattr(0, &tio); - - /* save original kill, erase character for later */ - save_kill = KILL; - save_erase = ERASE; - - /* set new kill, erase character in terminal structure */ - KILL = killp ? chrcnv(killp) : save_kill; - ERASE = erasep ? chrcnv(erasep) : save_erase; - - /* set the new terminal attributes */ - tcsetattr(0, TCSADRAIN, &tio); - - /* print out new kill erase characters */ - chrdsp("erase", ERASE); - chrdsp(", kill", KILL); - chrdsp(", intr", INTR); - putchar('\n'); - fflush(stdout); - - /* - ** We set the kill and erase character back to original - ** setup in terminal structure so we can easily - ** restore it upon exit. - */ - KILL = save_kill; - ERASE = save_erase; - } - sigint = 0; SIGNAL2(SIGINT, intrser); /* ** Loop through the lines of the draft skeleton. */ - for (state = FLD;;) { - switch (state = m_getfld(state, name, field, sizeof(field), - in)) { - case FLD: - case FLDEOF: - case FLDPLUS: + for (state = FLD2;;) { + switch (state = m_getfld2(state, &f, in)) { + case LENERR2: + state = FLD2; + /* FALL */ + + case FLD2: /* ** Check if the value of field contains ** anything other than space or tab. */ - for (cp = field; *cp; cp++) - if (*cp != ' ' && *cp != '\t') + for (cp = f.value; *cp; cp++) { + if (*cp != ' ' && *cp != '\t') { break; + } + } /* If so, just add header line to draft */ - if (*cp++ != '\n' || *cp != 0) { - 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); - } + if (*cp++ != '\n' || *cp) { + printf("%s:%s", f.name, f.value); + fprintf(out, "%s:%s", f.name, f.value); } else { /* Else, get value of header field */ - printf("%s: ", name); + printf("%s: ", f.name); fflush(stdout); - i = getln(field, sizeof(field)); + i = getln(buffer, sizeof(buffer)); if (i == -1) { abort: - if (killp || erasep) { - tcsetattr(0, TCSADRAIN, &tio); - } unlink(tmpfil); - done(1); + exit(EX_DATAERR); } - if (i != 0 || (field[0] != '\n' && field[0] != 0)) { - fprintf(out, "%s:", name); + if (i || (buffer[0]!='\n' && buffer[0]!='\0')) { + fprintf(out, "%s:", f.name); do { - if (field[0] != ' ' && field[0] != '\t') + if (buffer[0] != ' ' && buffer[0] != '\t') { putc(' ', out); - fprintf(out, "%s", field); - } while (i == 1 && (i = getln(field, sizeof(field))) >= 0); - if (i == -1) + } + fprintf(out, "%s", buffer); + } while (i == 1 && (i = getln(buffer, sizeof(buffer))) >= 0); + if (i == -1) { goto 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; + case BODY2: + case FILEEOF2: fprintf(out, "--------\n"); - if (field[0] == 0 || !prepend) - printf("--------\n"); - if (field[0]) { - if (prepend && body) { - printf("\n--------Enter initial text\n\n"); + if (qbody) { + if (f.value == NULL) { + printf("--------\n"); + goto has_no_body; + } + + if (prepend) { + printf("--------Enter initial text\n"); fflush(stdout); for (;;) { getln(buffer, sizeof(buffer)); - if (doteof && buffer[0] == '.' && buffer[1] == '\n') - break; - if (buffer[0] == 0) + if (!*buffer) { break; + } fprintf(out, "%s", buffer); } + } else { + printf("--------\n"); } + } + if (state == BODY2) { do { - fprintf(out, "%s", field); - if (!rapid && !sigint) - printf("%s", field); - } while (state == BODY && (state = m_getfld(state, name, field, sizeof(field), in))); - if (prepend || !body) - break; - else - printf ("\n--------Enter additional text\n\n"); + fprintf(out, "%s", f.value); + if (!rapid && !sigint) { + printf("%s", f.value); + } + } while ((state = m_getfld2(state, &f, in)) + ==BODY2); + if (state != FILEEOF2) { + adios(EX_IOERR, "m_getfld2", "io error"); + } + } + + if (prepend || !qbody) { + break; } -no_body: + + printf("--------Enter additional text\n"); +has_no_body: fflush(stdout); for (;;) { - getln(field, sizeof(field)); - if (doteof && field[0] == '.' && field[1] == '\n') - break; - if (field[0] == 0) + getln(buffer, sizeof(buffer)); + if (!*buffer) { break; - fprintf(out, "%s", field); + } + fprintf(out, "%s", buffer); } break; + case FMTERR2: + advise(NULL, "skeleton is poorly formatted"); + continue; default: - adios(NULL, "skeleton is poorly formatted"); + adios(EX_IOERR, "m_getfld2", "io error"); } break; } - if (body) + if (qbody) { printf("--------\n"); + } fflush(stdout); fclose(in); fclose(out); SIGNAL(SIGINT, SIG_IGN); - if (killp || erasep) { - tcsetattr(0, TCSADRAIN, &tio); + if ((fdi = open(tmpfil, O_RDONLY)) == NOTOK) { + adios(EX_IOERR, tmpfil, "unable to re-open"); + } + if ((fdo = creat(drft, m_gmprot())) == NOTOK) { + adios(EX_IOERR, drft, "unable to write"); } - - if ((fdi = open(tmpfil, O_RDONLY)) == NOTOK) - adios(tmpfil, "unable to re-open"); - if ((fdo = creat(drft, m_gmprot())) == NOTOK) - adios(drft, "unable to write"); cpydata(fdi, fdo, tmpfil, drft); close(fdi); close(fdo); unlink(tmpfil); - context_save(); /* save the context file */ - done(0); - return 1; + context_save(); + return EX_OK; } @@ -349,23 +276,25 @@ int getln(char *buffer, int n) { int c; + sig_atomic_t psigint = sigint; char *cp; cp = buffer; - *cp = 0; + *cp = '\0'; switch (setjmp(sigenv)) { - case OK: + case 0: wtuser = 1; break; - case DONE: - wtuser = 0; - return 0; - default: wtuser = 0; - return NOTOK; + if (sigint == psigint) { + return 0; + } else { + sigint = psigint; + return NOTOK; + } } for (;;) { @@ -375,20 +304,20 @@ getln(char *buffer, int n) longjmp(sigenv, DONE); case '\n': - if (cp[-1] == QUOTE) { + if (cp[-1] == '\\') { cp[-1] = c; wtuser = 0; return 1; } *cp++ = c; - *cp = 0; + *cp = '\0'; wtuser = 0; return 0; default: if (cp < buffer + n) *cp++ = c; - *cp = 0; + *cp = '\0'; } } } @@ -397,25 +326,8 @@ getln(char *buffer, int n) static void intrser(int i) { - if (wtuser) - longjmp(sigenv, NOTOK); + if (wtuser) { + close(STDIN_FILENO); + } sigint++; } - - -static int -chrcnv(char *cp) -{ - return (*cp != QUOTE ? *cp : m_atoi(++cp)); -} - - -static void -chrdsp(char *s, char c) -{ - printf("%s ", s); - if (c < ' ' || c == 0177) - printf("^%c", c ^ 0100); - else - printf("%c", c); -}