]>
diplodocus.org Git - nmh/blob - uip/prompter.c
6f97a8806a2a01a6fa2860285d02457add14375d
3 * prompter.c -- simple prompting editor front-end
7 * This code is Copyright (c) 2002, by the authors of nmh. See the
8 * COPYRIGHT file in the root directory of the nmh distribution for
9 * complete copyright information.
14 #include <h/signals.h>
39 static struct swit switches
[] = {
69 static struct termios tio
;
70 # define ERASE tio.c_cc[VERASE]
71 # define KILL tio.c_cc[VKILL]
72 # define INTR tio.c_cc[VINTR]
75 static struct termio tio
;
76 # define ERASE tio.c_cc[VERASE]
77 # define KILL tio.c_cc[VKILL]
78 # define INTR tio.c_cc[VINTR]
80 static struct sgttyb tio
;
81 static struct tchars tc
;
82 # define ERASE tio.sg_erase
83 # define KILL tio.sg_kill
84 # define INTR tc.t_intrc
88 static int wtuser
= 0;
89 static int sigint
= 0;
90 static jmp_buf sigenv
;
95 int getln (char *, int);
96 static int chrcnv (char *);
97 static void chrdsp (char *, char);
98 static RETSIGTYPE
intrser (int);
102 main (int argc
, char **argv
)
104 int body
= 1, prepend
= 1, rapid
= 0;
105 int doteof
= 0, fdi
, fdo
, i
, state
;
106 char *cp
, *drft
= NULL
, *erasep
= NULL
;
107 char *killp
= NULL
, name
[NAMESZ
], field
[BUFSIZ
];
108 char buffer
[BUFSIZ
], tmpfil
[BUFSIZ
];
109 char **arguments
, **argp
;
114 setlocale(LC_ALL
, "");
116 invo_name
= r1bindex (argv
[0], '/');
118 /* read user profile/context */
121 arguments
= getarguments (invo_name
, argc
, argv
, 1);
124 while ((cp
= *argp
++))
126 switch (smatch (++cp
, switches
)) {
128 ambigsw (cp
, switches
);
131 adios (NULL
, "-%s unknown", cp
);
134 snprintf (buffer
, sizeof(buffer
), "%s [switches] file",
136 print_help (buffer
, switches
, 1);
139 print_version(invo_name
);
143 if (!(erasep
= *argp
++) || *erasep
== '-')
144 adios (NULL
, "missing argument to %s", argp
[-2]);
147 if (!(killp
= *argp
++) || *killp
== '-')
148 adios (NULL
, "missing argument to %s", argp
[-2]);
185 adios (NULL
, "usage: %s [switches] file", invo_name
);
186 if ((in
= fopen (drft
, "r")) == NULL
)
187 adios (drft
, "unable to open");
189 tfile
= m_mktemp2(NULL
, invo_name
, NULL
, &out
);
190 if (tfile
== NULL
) adios("prompter", "unable to create temporary file");
191 chmod (tmpfil
, 0600);
192 strncpy (tmpfil
, tfile
, sizeof(tmpfil
));
195 * Are we changing the kill or erase character?
197 if (killp
|| erasep
) {
198 #ifdef HAVE_TERMIOS_H
199 cc_t save_erase
, save_kill
;
201 int save_erase
, save_kill
;
204 /* get the current terminal attributes */
205 #ifdef HAVE_TERMIOS_H
208 # ifdef HAVE_TERMIO_H
209 ioctl(0, TCGETA
, &tio
);
211 ioctl (0, TIOCGETP
, (char *) &tio
);
212 ioctl (0, TIOCGETC
, (char *) &tc
);
216 /* save original kill, erase character for later */
220 /* set new kill, erase character in terminal structure */
221 KILL
= killp
? chrcnv (killp
) : save_kill
;
222 ERASE
= erasep
? chrcnv (erasep
) : save_erase
;
224 /* set the new terminal attributes */
225 #ifdef HAVE_TERMIOS_H
226 tcsetattr(0, TCSADRAIN
, &tio
);
228 # ifdef HAVE_TERMIO_H
229 ioctl(0, TCSETAW
, &tio
);
231 ioctl (0, TIOCSETN
, (char *) &tio
);
235 /* print out new kill erase characters */
236 chrdsp ("erase", ERASE
);
237 chrdsp (", kill", KILL
);
238 chrdsp (", intr", INTR
);
243 * We set the kill and erase character back to original
244 * setup in terminal structure so we can easily
245 * restore it upon exit.
252 SIGNAL2 (SIGINT
, intrser
);
255 * Loop through the lines of the draft skeleton.
257 for (state
= FLD
;;) {
258 switch (state
= m_getfld (state
, name
, field
, sizeof(field
), in
)) {
263 * Check if the value of field contains anything
264 * other than space or tab.
266 for (cp
= field
; *cp
; cp
++)
267 if (*cp
!= ' ' && *cp
!= '\t')
270 /* If so, just add header line to draft */
271 if (*cp
++ != '\n' || *cp
!= 0) {
272 printf ("%s:%s", name
, field
);
273 fprintf (out
, "%s:%s", name
, field
);
274 while (state
== FLDPLUS
) {
276 m_getfld (state
, name
, field
, sizeof(field
), in
);
277 printf ("%s", field
);
278 fprintf (out
, "%s", field
);
281 /* Else, get value of header field */
282 printf ("%s: ", name
);
284 i
= getln (field
, sizeof(field
));
287 if (killp
|| erasep
) {
288 #ifdef HAVE_TERMIOS_H
289 tcsetattr(0, TCSADRAIN
, &tio
);
292 ioctl (0, TCSETA
, &tio
);
294 ioctl (0, TIOCSETN
, (char *) &tio
);
301 if (i
!= 0 || (field
[0] != '\n' && field
[0] != 0)) {
302 fprintf (out
, "%s:", name
);
304 if (field
[0] != ' ' && field
[0] != '\t')
306 fprintf (out
, "%s", field
);
308 && (i
= getln (field
, sizeof(field
))) >= 0);
314 if (state
== FLDEOF
) { /* moby hack */
315 fprintf (out
, "--------\n");
316 printf ("--------\n");
328 fprintf (out
, "--------\n");
329 if (field
[0] == 0 || !prepend
)
330 printf ("--------\n");
332 if (prepend
&& body
) {
333 printf ("\n--------Enter initial text\n\n");
336 getln (buffer
, sizeof(buffer
));
337 if (doteof
&& buffer
[0] == '.' && buffer
[1] == '\n')
341 fprintf (out
, "%s", buffer
);
346 fprintf (out
, "%s", field
);
347 if (!rapid
&& !sigint
)
348 printf ("%s", field
);
349 } while (state
== BODY
&&
350 (state
= m_getfld (state
, name
, field
, sizeof(field
), in
)));
351 if (prepend
|| !body
)
354 printf ("\n--------Enter additional text\n\n");
359 getln (field
, sizeof(field
));
360 if (doteof
&& field
[0] == '.' && field
[1] == '\n')
364 fprintf (out
, "%s", field
);
369 adios (NULL
, "skeleton is poorly formatted");
375 printf ("--------\n");
380 SIGNAL (SIGINT
, SIG_IGN
);
382 if (killp
|| erasep
) {
383 #ifdef HAVE_TERMIOS_H
384 tcsetattr(0, TCSADRAIN
, &tio
);
386 # ifdef HAVE_TERMIO_H
387 ioctl (0, TCSETAW
, &tio
);
389 ioctl (0, TIOCSETN
, (char *) &tio
);
394 if ((fdi
= open (tmpfil
, O_RDONLY
)) == NOTOK
)
395 adios (tmpfil
, "unable to re-open");
396 if ((fdo
= creat (drft
, m_gmprot ())) == NOTOK
)
397 adios (drft
, "unable to write");
398 cpydata (fdi
, fdo
, tmpfil
, drft
);
403 context_save (); /* save the context file */
410 getln (char *buffer
, int n
)
418 switch (setjmp (sigenv
)) {
433 switch (c
= getchar ()) {
436 longjmp (sigenv
, DONE
);
439 if (cp
[-1] == QUOTE
) {
461 #ifndef RELIABLE_SIGNALS
462 SIGNAL (SIGINT
, intrser
);
466 longjmp (sigenv
, NOTOK
);
474 return (*cp
!= QUOTE
? *cp
: m_atoi (++cp
));
479 chrdsp (char *s
, char c
)
482 if (c
< ' ' || c
== 0177)
483 printf ("^%c", c
^ 0100);