]> diplodocus.org Git - nmh/commitdiff
Convert all of the terminal functions over to terminfo(5) instead of
authorKen Hornstein <kenh@pobox.com>
Fri, 3 Jan 2014 04:59:57 +0000 (23:59 -0500)
committerKen Hornstein <kenh@pobox.com>
Fri, 3 Jan 2014 04:59:57 +0000 (23:59 -0500)
the older termcap.

Move the terminal-specific code from fmt_compile.c to terminal.c, so it
is all in one place.

h/prototypes.h
sbr/fmt_compile.c
sbr/terminal.c
uip/mhlsbr.c
uip/mshcmds.c
uip/scan.c

index d56ef30cee7c437af45318c874a2ccac335dd8f8..0c58310987ca37e5137a6e41b9758de4dcc22291 100644 (file)
@@ -113,6 +113,24 @@ char *get_charset(void);
 char *getcpy (const char *);
 char *get_default_editor(void);
 char *getfolder(int);
 char *getcpy (const char *);
 char *get_default_editor(void);
 char *getfolder(int);
+
+/*
+ * Get a string from the terminfo database for the current terminal.
+ *
+ * Retrieve the specified terminfo capability and return a string that
+ * can be output to the terminal.  The string returned has already been
+ * processed by tputs(), so it is safe to output directly.  The return
+ * value of this function is valid until the next call.
+ *
+ * Arguments:
+ *
+ * capability  - The name of a terminfo capability (see terminfo(5)).
+ *
+ * Returns a tputs-processed string, or NULL if terminal initialization failed
+ * or the capability wasn't found.
+ */
+char *get_term_stringcap(char *capability);
+
 /*
  * Lock open/close routines.
  *
 /*
  * Lock open/close routines.
  *
@@ -154,6 +172,11 @@ char *m_mktemp2(const char *, const char *, int *, FILE **);
 void m_unknown(m_getfld_state_t *, FILE *);
 int makedir (char *);
 char *message_id (time_t, int);
 void m_unknown(m_getfld_state_t *, FILE *);
 int makedir (char *);
 char *message_id (time_t, int);
+
+/*
+ * Clear the screen, using the appropriate entry from the terminfo database
+ */
+void nmh_clear_screen(void);
 char *nmh_getpass(const char *);
 char *norm_charmap(char *);
 char *new_fs (char *, char *, char *);
 char *nmh_getpass(const char *);
 char *norm_charmap(char *);
 char *new_fs (char *, char *, char *);
@@ -280,7 +303,6 @@ char *SystemName(void);
 int annotate (char *, char *, char *, int, int, int, int);
 void annolist(char *, char *, char *, int);
 void annopreserve(int);
 int annotate (char *, char *, char *, int, int, int, int);
 void annolist(char *, char *, char *, int);
 void annopreserve(int);
-void clear_screen(void);
 void m_pclose(void);
 int make_intermediates(char *);
 int mhl(int, char **);
 void m_pclose(void);
 int make_intermediates(char *);
 int mhl(int, char **);
index c4476f8d12468dbdee28bf50bbe6e884dc3095a7..7392c8c6738c167e6e5f3633904431d5b638a925 100644 (file)
@@ -49,9 +49,6 @@
 #include <h/mts.h>
 #include <h/utils.h>
 
 #include <h/mts.h>
 #include <h/utils.h>
 
-#include <curses.h>
-#include <term.h>
-
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
@@ -69,10 +66,6 @@ static struct comp *cm;                      /* most recent comp ref  */
 static struct ftable *ftbl;            /* most recent func ref  */
 static int ncomp;
 static int infunction;                 /* function nesting cnt  */
 static struct ftable *ftbl;            /* most recent func ref  */
 static int ncomp;
 static int infunction;                 /* function nesting cnt  */
-static int termstatus = 0;             /* 0=uninit,1=ok,-1=fail */
-static char *termcbuf = NULL;          /* Capability output str */
-static char *termcbufp = NULL;         /* Capability buf ptr    */
-static size_t termcbufsz = 0;          /* Size of termcbuf      */
 
 extern struct mailname fmt_mnull;
 
 
 extern struct mailname fmt_mnull;
 
@@ -91,7 +84,8 @@ extern struct mailname fmt_mnull;
 #define TF_LMBOX   11       /* special - get full local mailbox   */
 #define TF_BOLD    12      /* special - enter terminal bold mode */
 #define TF_UNDERLN 13       /* special - enter underline mode     */
 #define TF_LMBOX   11       /* special - get full local mailbox   */
 #define TF_BOLD    12      /* special - enter terminal bold mode */
 #define TF_UNDERLN 13       /* special - enter underline mode     */
-#define TF_RESET   14       /* special - reset terminal modes     */
+#define TF_STNDOUT 14       /* special - enter underline mode     */
+#define TF_RESET   15       /* special - reset terminal modes     */
 
 /* ftable->flags */
 /* NB that TFL_PUTS is also used to decide whether the test
 
 /* ftable->flags */
 /* NB that TFL_PUTS is also used to decide whether the test
@@ -227,6 +221,7 @@ static struct ftable functable[] = {
 
      { "bold",       TF_BOLD,  FT_LS_LIT,      0,              TFL_PUTS },
      { "underline",  TF_UNDERLN,FT_LS_LIT,     0,              TFL_PUTS },
 
      { "bold",       TF_BOLD,  FT_LS_LIT,      0,              TFL_PUTS },
      { "underline",  TF_UNDERLN,FT_LS_LIT,     0,              TFL_PUTS },
+     { "standout",   TF_STNDOUT,FT_LS_LIT,     0,              TFL_PUTS },
      { "resetterm",  TF_RESET, FT_LS_LIT,      0,              TFL_PUTS },
 
      { NULL,         0,                0,              0,              0 }
      { "resetterm",  TF_RESET, FT_LS_LIT,      0,              TFL_PUTS },
 
      { NULL,         0,                0,              0,              0 }
@@ -302,9 +297,6 @@ static char *do_loop(char *);
 static char *do_if(char *);
 static void free_component(struct comp *);
 static void free_comptable(void);
 static char *do_if(char *);
 static void free_component(struct comp *);
 static void free_comptable(void);
-static void initialize_terminfo(void);
-static void get_term_stringcap(struct ftable *, char *);
-static int termbytes(int);
 
 /*
  * Lookup a function name in the functable
 
 /*
  * Lookup a function name in the functable
@@ -649,15 +641,19 @@ do_func(char *sp)
        break;
 
     case TF_BOLD:
        break;
 
     case TF_BOLD:
-       get_term_stringcap(t, "bold");
+       LS(t->f_type, get_term_stringcap("bold"));
        break;
 
     case TF_UNDERLN:
        break;
 
     case TF_UNDERLN:
-       get_term_stringcap(t, "smul");
+       LS(t->f_type, get_term_stringcap("smul"));
+       break;
+
+    case TF_STNDOUT:
+       LS(t->f_type, get_term_stringcap("smso"));
        break;
 
     case TF_RESET:
        break;
 
     case TF_RESET:
-       get_term_stringcap(t, "sgr0");
+       LS(t->f_type, get_term_stringcap("sgr0"));
        break;
 
     case TF_NOW:
        break;
 
     case TF_NOW:
@@ -1063,102 +1059,3 @@ free_component(struct comp *cm)
        free(cm);
     }
 }
        free(cm);
     }
 }
-
-/*
- * These functions handles the case of outputting terminal strings depending
- * on the terminfo setting.
- */
-
-/*
- * We should only be called if we haven't yet called setupterm()
- */
-
-void
-initialize_terminfo(void)
-{
-    int errret, rc;
-
-    rc = setupterm(NULL, fileno(stdout), &errret);
-
-    if (rc != 0 || errret != 1)
-       termstatus = -1;
-    else
-       termstatus = 1;
-}
-
-/*
- * Place the results of the specified string entry into the str register.
- *
- * Arguments are:
- *
- * t   - Pointer to instruction table entry (used to create fmt instruction)
- * cap - Name of terminfo capability to insert (e.g., "bold", or "sgr0").
- *
- * This ended up being more complicated than I hoped.  You need to fetch the
- * entry via tigetstr(), but there MAY be a padding format embedded in what
- * gets returned by tigetstr(), so you have to run it through tputs().
- * And of course tputs() is designed to output to a terminal, so you have
- * capture every byte output by the tputs() callback to get the final
- * string to write to the format engine.
- *
- * If padding bytes are NULs that will be a problem for us, but some quick
- * experimentation suggests that padding bytes are mostly a non-issue anymore.
- * If they still crop up we'll have to figure out how to deal with them.
- */
-
-void
-get_term_stringcap(struct ftable *t, char *cap)
-{
-    char *parm;
-
-    /*
-     * Common to all functions; initialize the termcap if we need it.
-     * If it didn't initialize successfully, return silently
-     */
-
-    if (termstatus == 0)
-       initialize_terminfo();
-
-    termcbufp = termcbuf;
-
-    if (termstatus == -1)
-       goto out;
-
-    parm = tigetstr(cap);
-
-    if (parm == (char *) -1 || parm == NULL) {
-       goto out;
-    }
-
-    tputs(parm, 1, termbytes);
-
-out:
-    termcbufp = '\0';
-
-    LS(t->f_type, termcbuf);
-}
-
-/*
- * Store a sequence of characters in our local buffer
- */
-
-static int
-termbytes(int c)
-{
-    size_t offset;
-
-    /*
-     * Bump up the buffer size if we've reached the end (leave room for
-     * a trailing NUL)
-     */
-
-    if ((offset = termcbufp - termcbuf) - 1 >= termcbufsz) {
-        termcbufsz += 64;
-       termcbuf = mh_xrealloc(termcbuf, termcbufsz);
-       termcbufp = termcbuf + offset;
-    }
-
-    *termcbufp++ = c;
-
-    return 0;
-}
index 9ab81e0d0e4c61d730d994e6266f5be705f3329c..7226a88f38cfa3a75779dedc1521cecbff3b1a38 100644 (file)
@@ -8,8 +8,10 @@
  */
 
 #include <h/mh.h>
  */
 
 #include <h/mh.h>
+#include <h/utils.h>
 
 #include <termios.h>
 
 #include <termios.h>
+#include <sys/ioctl.h>
 
 /* It might be better to tie this to the termcap_curses_order in
    configure.ac.  It would be fine to check for ncurses/termcap.h
 
 /* It might be better to tie this to the termcap_curses_order in
    configure.ac.  It would be fine to check for ncurses/termcap.h
 #elif defined (HAVE_NCURSES_TERMCAP_H)
 # include <ncurses/termcap.h>
 #endif
 #elif defined (HAVE_NCURSES_TERMCAP_H)
 # include <ncurses/termcap.h>
 #endif
+#include <term.h>
 
 #ifdef WINSIZE_IN_PTEM
 # include <sys/stream.h>
 # include <sys/ptem.h>
 #endif
 
 
 #ifdef WINSIZE_IN_PTEM
 # include <sys/stream.h>
 # include <sys/ptem.h>
 #endif
 
-#if BUFSIZ<2048
-# define TXTSIZ        2048
-#else
-# define TXTSIZ BUFSIZ
-#endif
-
 static int initLI = 0;
 static int initCO = 0;
 
 static int initLI = 0;
 static int initCO = 0;
 
-static int LI = 40;      /* number of lines                       */
-static int CO = 80;      /* number of colums                      */
-static char *CL = NULL;  /* termcap string to clear screen        */
-static char *SE = NULL;  /* termcap string to end standout mode   */
-static char *SO = NULL;  /* termcap string to begin standout mode */
+static int LI = 40;             /* number of lines                        */
+static int CO = 80;             /* number of colums                       */
+static char *clear = NULL;      /* terminfo string to clear screen        */
+static char *standend = NULL;   /* terminfo string to end standout mode   */
+static char *standbegin = NULL; /* terminfo string to begin standout mode */
+static int termstatus = 0;     /* terminfo initialization status         */
+static char *termcbuf = NULL;  /* tputs() output buffer                  */
+static char *termcbufp = NULL; /* tputs() output buffer pointer          */
+static size_t termcbufsz = 0;  /* Size of termcbuf                       */
 
 
-static char termcap[TXTSIZ];
+static void initialize_terminfo(void);
+static int termbytes(int);
 
 
+/*
+ * Initialize the terminfo library.
+ */
 
 static void
 
 static void
-read_termcap(void)
+initialize_terminfo(void)
 {
 {
-    char *cp;
-    char *term;
+    int errret, rc;
 
 
-#ifndef TGETENT_ACCEPTS_NULL
-    char termbuf[TXTSIZ];
-#endif
+    if (termstatus)
+       return;
 
 
-    static int inited = 0;
+    rc = setupterm(NULL, fileno(stdout), &errret);
 
 
-    if (inited++)
-       return;
-
-    if (!(term = getenv ("TERM")))
-       return;
-
-/*
- * If possible, we let tgetent allocate its own termcap buffer
- */
-#ifdef TGETENT_ACCEPTS_NULL
-    if (tgetent (NULL, term) != TGETENT_SUCCESS)
+    if (rc != 0 || errret != 1) {
+       termstatus = -1;
        return;
        return;
-#else
-    if (tgetent (termbuf, term) != TGETENT_SUCCESS)
-       return;
-#endif
+    } else {
+       termstatus = 1;
+    }
 
 
-    if (!initCO && (CO = tgetnum ("co")) <= 0)
+    if (!initCO && (CO = tigetnum ("cols")) <= 0)
        CO = 80;
        CO = 80;
-    if (!initLI && (LI = tgetnum ("li")) <= 0)
+    if (!initLI && (LI = tigetnum ("lines")) <= 0)
        LI = 24;
 
        LI = 24;
 
-    cp = termcap;
-    CL = tgetstr ("cl", &cp);
-    if (tgetnum ("sg") <= 0) {
-       SE = tgetstr ("se", &cp);
-       SO = tgetstr ("so", &cp);
-    }
+    clear = tigetstr ("clear");
+    standbegin = tigetstr ("smso");
+    standend = tigetstr ("rmso");
 }
 
 
 }
 
 
@@ -99,7 +89,7 @@ sc_width (void)
        initCO++;
     } else
 #endif /* TIOCGWINSZ */
        initCO++;
     } else
 #endif /* TIOCGWINSZ */
-       read_termcap();
+       initialize_terminfo();
 
     return CO;
 }
 
     return CO;
 }
@@ -116,7 +106,7 @@ sc_length (void)
        initLI++;
     else
 #endif /* TIOCGWINSZ */
        initLI++;
     else
 #endif /* TIOCGWINSZ */
-       read_termcap();
+       initialize_terminfo();
 
     return LI;
 }
 
     return LI;
 }
@@ -130,12 +120,12 @@ outc (int c)
 
 
 void
 
 
 void
-clear_screen (void)
+nmh_clear_screen (void)
 {
 {
-    read_termcap ();
+    initialize_terminfo ();
 
 
-    if (CL)
-       tputs (CL, LI, outc);
+    if (clear)
+       tputs (clear, LI, outc);
     else {
        printf ("\f");
     }
     else {
        printf ("\f");
     }
@@ -152,18 +142,72 @@ SOprintf (char *fmt, ...)
 {
     va_list ap;
 
 {
     va_list ap;
 
-    read_termcap ();
-    if (!(SO && SE))
+    initialize_terminfo ();
+    if (!(standbegin && standend))
        return NOTOK;
 
        return NOTOK;
 
-    tputs (SO, 1, outc);
+    tputs (standbegin, 1, outc);
 
     va_start(ap, fmt);
     vprintf (fmt, ap);
     va_end(ap);
 
 
     va_start(ap, fmt);
     vprintf (fmt, ap);
     va_end(ap);
 
-    tputs (SE, 1, outc);
+    tputs (standend, 1, outc);
 
     return OK;
 }
 
 
     return OK;
 }
 
+/*
+ * Return the specified capability as a string that has already been
+ * processed with tputs().
+ */
+
+char *
+get_term_stringcap(char *capability)
+{
+    char *parm;
+
+    initialize_terminfo();
+
+    if (termstatus == -1)
+       return NULL;
+
+    termcbufp = termcbuf;
+
+    parm = tigetstr(capability);
+
+    if (parm == (char *) -1 || parm == NULL) {
+       return NULL;
+    }
+
+    tputs(parm, 1, termbytes);
+
+    termcbufp = '\0';
+
+    return termcbuf;
+}
+
+/*
+ * Store a sequence of characters in our local buffer
+ */
+
+static int
+termbytes(int c)
+{
+    size_t offset;
+
+    /*
+     * Bump up the buffer size if we've reached the end (leave room for
+     * a trailing NUL)
+     */
+
+    if ((offset = termcbufp - termcbuf) - 1 >= termcbufsz) {
+        termcbufsz += 64;
+       termcbuf = mh_xrealloc(termcbuf, termcbufsz);
+       termcbufp = termcbuf + offset;
+    }
+
+    *termcbufp++ = c;
+
+    return 0;
+}
index b6b7a627f9f8dc5a8a160d3f894ad166dd22b199..6a1c3db7878ef0e2121c1bc25c8c30fda167e073 100644 (file)
@@ -531,7 +531,7 @@ mhl (int argc, char **argv)
     }
     
     if (clearflg > 0 && ontty == NOTTY)
     }
     
     if (clearflg > 0 && ontty == NOTTY)
-       clear_screen ();
+       nmh_clear_screen ();
 
     if (ontty == PITTY)
        m_pclose ();
 
     if (ontty == PITTY)
        m_pclose ();
@@ -956,7 +956,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                if (ofilec > 1) {
                    if (ofilen > 1) {
                        if ((global.c_flags & CLEARSCR))
                if (ofilec > 1) {
                    if (ofilen > 1) {
                        if ((global.c_flags & CLEARSCR))
-                           clear_screen ();
+                           nmh_clear_screen ();
                        else
                            printf ("\n\n\n");
                    }
                        else
                            printf ("\n\n\n");
                    }
@@ -978,7 +978,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                }
                if (strchr(buf, '\n')) {
                    if ((global.c_flags & CLEARSCR))
                }
                if (strchr(buf, '\n')) {
                    if ((global.c_flags & CLEARSCR))
-                       clear_screen ();
+                       nmh_clear_screen ();
                }
                else
                    printf ("\n");
                }
                else
                    printf ("\n");
@@ -989,7 +989,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                    if (ofilen > 1) {
                        printf ("\n\n\n");
                        if (clearflg > 0)
                    if (ofilen > 1) {
                        printf ("\n\n\n");
                        if (clearflg > 0)
-                           clear_screen ();
+                           nmh_clear_screen ();
                    }
                    printf (">>> %s\n\n", mname);
                }
                    }
                    printf (">>> %s\n\n", mname);
                }
@@ -1485,7 +1485,7 @@ putch (char ch, long flags)
            read (fileno (stdout), buf, sizeof(buf));
            if (strchr(buf, '\n')) {
                if (global.c_flags & CLEARSCR)
            read (fileno (stdout), buf, sizeof(buf));
            if (strchr(buf, '\n')) {
                if (global.c_flags & CLEARSCR)
-                   clear_screen ();
+                   nmh_clear_screen ();
                row = 0;
            } else {
                putchar ('\n');
                row = 0;
            } else {
                putchar ('\n');
index f91f277afdabd7a615fa5f22d153325901427180..3a5f98fa4add71b9bb0f0370ad8a1cec7f4ac9f2 100644 (file)
@@ -2070,7 +2070,7 @@ scancmd (char **args)
        }
 
     if (clearsw)
        }
 
     if (clearsw)
-       clear_screen ();
+       nmh_clear_screen ();
 }
 
 
 }
 
 
index 6a134631f18facc7176dfbadfbc7e8c346f05bc5..1f487cdd9a77f1d97e441cc1784f06d07d9850e3 100644 (file)
@@ -37,12 +37,6 @@ DEFINE_SWITCH_ARRAY(SCAN, switches);
 #undef X
 
 
 #undef X
 
 
-/*
- * prototypes
- */
-void clear_screen(void);  /* from termsbr.c */
-
-
 int
 main (int argc, char **argv)
 {
 int
 main (int argc, char **argv)
 {
@@ -288,7 +282,7 @@ main (int argc, char **argv)
     ivector_free (seqnum);
     folder_free (mp);  /* free folder/message structure */
     if (clearflag)
     ivector_free (seqnum);
     folder_free (mp);  /* free folder/message structure */
     if (clearflag)
-       clear_screen ();
+       nmh_clear_screen ();
 
     done (0);
     return 1;
 
     done (0);
     return 1;