]> diplodocus.org Git - nmh/blobdiff - uip/mhlsbr.c
whom.c: Don't store atoi(getenv("mhdist")) when value only tested.
[nmh] / uip / mhlsbr.c
index 5140b88eefb689a3d97e49614b38ef8ce18bafde..f51c562334dab2b2a7de77b017182472863d9df8 100644 (file)
 #include <h/fmt_scan.h>
 #include <h/tws.h>
 #include <h/utils.h>
-#include "../sbr/m_popen.h"
+#include "sbr/m_popen.h"
 #include <setjmp.h>
 #include <sys/types.h>
+#include "sbr/terminal.h"
 
 /*
  * MAJOR BUG:
@@ -315,7 +316,7 @@ static int ptos (char *, char **);
 static char *parse (void);
 static void process (char *, char *, int, int);
 static void mhlfile (FILE *, char *, int, int);
-static int mcomp_flags (char *);
+static int mcomp_flags (char *) PURE;
 static char *mcomp_add (unsigned long, char *, char *);
 static void mcomp_format (struct mcomp *, struct mcomp *);
 static struct mcomp *add_queue (struct mcomp **, struct mcomp **, char *, char *, int);
@@ -324,11 +325,12 @@ static void putcomp (struct mcomp *, struct mcomp *, int);
 static char *oneline (char *, unsigned long);
 static void putstr (char *, unsigned long);
 static void putch (char, unsigned long);
+static bool linefeed_typed(void);
 static void intrser (int);
 static void pipeser (int);
 static void quitser (int);
-static void mhladios (char *, char *, ...) CHECK_PRINTF(2, 3);
-static void mhldone (int);
+static void mhladios (char *, char *, ...) CHECK_PRINTF(2, 3) NORETURN;
+static void mhldone (int) NORETURN;
 static void filterbody (struct mcomp *, char *, int, int,
                         m_getfld_state_t);
 static void compile_formatfield(struct mcomp *);
@@ -360,20 +362,16 @@ mhl (int argc, char **argv)
                case AMBIGSW: 
                    ambigsw (cp, mhlswitches);
                    mhldone (1);
-                   /* FALLTHRU */
                case UNKWNSW: 
                    mhladios (NULL, "-%s unknown\n", cp);
-                   /* FALLTHRU */
 
                case HELPSW: 
                    snprintf (buf, sizeof(buf), "%s [switches] [files ...]", invo_name);
                    print_help (buf, mhlswitches, 1);
                    mhldone (0);
-                   /* FALLTHRU */
                case VERSIONSW:
                    print_version(invo_name);
                    mhldone (0);
-                   /* FALLTHRU */
 
                case BELLSW: 
                    bellflg = 1;
@@ -401,8 +399,7 @@ mhl (int argc, char **argv)
                case SLEEPSW:
                    if (!(cp = *argp++) || *cp == '-')
                        mhladios (NULL, "missing argument to %s", argp[-2]);
-                   else
-                       sleepsw = atoi (cp);/* ZERO ok! */
+                    sleepsw = atoi (cp);/* ZERO ok! */
                    continue;
 
                case PROGSW:
@@ -424,13 +421,13 @@ mhl (int argc, char **argv)
                case LENSW: 
                    if (!(cp = *argp++) || *cp == '-')
                        mhladios (NULL, "missing argument to %s", argp[-2]);
-                   else if ((length = atoi (cp)) < 1)
+                   if ((length = atoi (cp)) < 1)
                        mhladios (NULL, "bad argument %s %s", argp[-2], cp);
                    continue;
                case WIDTHSW: 
                    if (!(cp = *argp++) || *cp == '-')
                        mhladios (NULL, "missing argument to %s", argp[-2]);
-                   else if ((width = atoi (cp)) < 1)
+                   if ((width = atoi (cp)) < 1)
                        mhladios (NULL, "bad argument %s %s", argp[-2], cp);
                    continue;
 
@@ -441,13 +438,13 @@ mhl (int argc, char **argv)
                case ISSUESW:
                    if (!(cp = *argp++) || *cp == '-')
                        mhladios (NULL, "missing argument to %s", argp[-2]);
-                   else if ((issue = atoi (cp)) < 1)
+                   if ((issue = atoi (cp)) < 1)
                        mhladios (NULL, "bad argument %s %s", argp[-2], cp);
                    continue;
                case VOLUMSW:
                    if (!(cp = *argp++) || *cp == '-')
                        mhladios (NULL, "missing argument to %s", argp[-2]);
-                   else if ((volume = atoi (cp)) < 1)
+                   if ((volume = atoi (cp)) < 1)
                        mhladios (NULL, "bad argument %s %s", argp[-2], cp);
                    continue;
 
@@ -917,7 +914,7 @@ process (char *folder, char *fname, int ofilen, int ofilec)
                SIGNAL (SIGINT, SIG_IGN);
            if (mhl_action == NULL && fp != stdin && fp != NULL)
                fclose (fp);
-            mh_xfree(holder.c_text);
+            free(holder.c_text);
             holder.c_text = NULL;
            free_queue (&msghd, &msgtl);
            for (c1 = fmthd; c1; c1 = c1->c_next)
@@ -964,7 +961,6 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                break;
 
            case ISTTY: 
-               strncpy (buf, "\n", sizeof(buf));
                if (ofilec > 1) {
                    if (SOprintf ("Press <return> to list \"%s\"...", mname)) {
                        if (ofilen > 1)
@@ -972,12 +968,8 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                        printf ("Press <return> to list \"%s\"...", mname);
                    }
                    fflush (stdout);
-                   buf[0] = 0;
-                   if (read (fileno (stdout), buf, sizeof(buf)) < 0) {
-                       advise ("stdout", "read");
-                   }
                }
-               if (strchr(buf, '\n')) {
+                if (ofilec == 1 || linefeed_typed()) {
                    if ((global.c_flags & CLEARSCR))
                        nmh_clear_screen ();
                }
@@ -1115,7 +1107,7 @@ mcomp_flags (char *name)
 
     for (ap = pairs; ap->p_name; ap++)
        if (!strcasecmp (ap->p_name, name))
-           return (ap->p_flags);
+           return ap->p_flags;
 
     return 0;
 }
@@ -1216,8 +1208,8 @@ mcomp_format (struct mcomp *c1, struct mcomp *c2)
        }
        charstring_free (scanl);
 
-        mh_xfree(p->pq_text);
-        mh_xfree(p->pq_error);
+        free(p->pq_text);
+        free(p->pq_error);
        q = p->pq_next;
        free(p);
     }
@@ -1263,10 +1255,10 @@ free_queue (struct mcomp **head, struct mcomp **tail)
 
     for (c1 = *head; c1; c1 = c2) {
        c2 = c1->c_next;
-        mh_xfree(c1->c_name);
-        mh_xfree(c1->c_text);
-        mh_xfree(c1->c_ovtxt);
-        mh_xfree(c1->c_nfs);
+        free(c1->c_name);
+        free(c1->c_text);
+        free(c1->c_ovtxt);
+        free(c1->c_nfs);
        if (c1->c_fmt)
            fmt_free (c1->c_fmt, 0);
        free(c1);
@@ -1511,8 +1503,6 @@ putstr (char *string, unsigned long flags)
 static void
 putch (char ch, unsigned long flags)
 {
-    char buf[BUFSIZ];
-
     if (llim == 0)
        return;
 
@@ -1527,11 +1517,7 @@ putch (char ch, unsigned long flags)
            if (global.c_flags & BELL)
                putchar ('\007');
            fflush (stdout);
-           buf[0] = 0;
-           if (read (fileno (stdout), buf, sizeof(buf)) < 0) {
-               advise ("stdout", "read");
-           }
-           if (strchr(buf, '\n')) {
+            if (linefeed_typed()) {
                if (global.c_flags & CLEARSCR)
                    nmh_clear_screen ();
                row = 0;
@@ -1601,6 +1587,33 @@ putch (char ch, unsigned long flags)
     }
 }
 
+/* linefeed_typed() makes a single read(2) from stdin and returns true
+ * if a linefeed character is amongst the characters read.
+ * A read error is treated as if linefeed wasn't typed.
+ *
+ * Typing on a TTY can cause read() to return data without typing Enter
+ * by using the TTY's EOF character instead, normally ASCII EOT, Ctrl-D.
+ * The linefeed can also be escaped with the TTY's LNEXT character,
+ * normally ASCII SYN, Ctrl-V, by typing Ctrl-V Ctrl-J.
+ * It's not possible to distinguish between the user typing a buffer's
+ * worth of characters and then EOT, or more than the buffer can hold.
+ * Either way, the result depends on ASCII LF, either from typing Enter
+ * or an escaped Ctrl-J, being amongst the read characters.
+ */
+static bool linefeed_typed(void)
+{
+    char buf[128];
+    ssize_t n;
+
+    n = read(0, buf, sizeof buf);
+    if (n == -1) {
+        advise("stdin", "read");
+        return false; /* Treat as EOF. */
+    }
+
+    return memchr(buf, '\n', n);
+}
+
 
 static void
 intrser (int i)
@@ -1651,8 +1664,7 @@ mhldone (int status)
     exitstat = status;
     if (mhl_action)
        longjmp (mhlenv, DONE);
-    else
-       done (exitstat);
+    done (exitstat);
 }