BSD 4_4_Lite1 release
[unix-history] / usr / src / bin / stty / cchar.c
index 6ba0c0e..79cb90a 100644 (file)
@@ -1,17 +1,50 @@
 /*-
 /*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1991, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cchar.c    5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)cchar.c    8.5 (Berkeley) 4/2/94";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
+
+#include <err.h>
+#include <limits.h>
 #include <stddef.h>
 #include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "stty.h"
 #include "stty.h"
+#include "extern.h"
 
 /*
  * Special control characters.
 
 /*
  * Special control characters.
@@ -21,30 +54,92 @@ static char sccsid[] = "@(#)cchar.c 5.2 (Berkeley) %G%";
  * command line.
  */
 struct cchar cchars1[] = {
  * command line.
  */
 struct cchar cchars1[] = {
-       "discard",      VDISCARD,       CDISCARD,
-       "dsusp",        VDSUSP,         CDSUSP,
-       "eof",          VEOF,           CEOF,
-       "eol",          VEOL,           CEOL,
-       "eol2",         VEOL2,          CEOL,
-       "erase",        VERASE,         CERASE,
-       "intr",         VINTR,          CINTR,
-       "kill",         VKILL,          CKILL,
-       "lnext",        VLNEXT,         CLNEXT,
-       "quit",         VQUIT,          CQUIT,
-       "reprint",      VREPRINT,       CREPRINT,
-       "start",        VSTART,         CSTART,
-       "status",       VSTATUS,        CSTATUS,
-       "stop",         VSTOP,          CSTOP,
-       "susp",         VSUSP,          CSUSP,
-       "werase",       VWERASE,        CWERASE,
-       NULL
+       { "discard",    VDISCARD,       CDISCARD },
+       { "dsusp",      VDSUSP,         CDSUSP },
+       { "eof",        VEOF,           CEOF },
+       { "eol",        VEOL,           CEOL },
+       { "eol2",       VEOL2,          CEOL },
+       { "erase",      VERASE,         CERASE },
+       { "intr",       VINTR,          CINTR },
+       { "kill",       VKILL,          CKILL },
+       { "lnext",      VLNEXT,         CLNEXT },
+       { "min",        VMIN,           CMIN },
+       { "quit",       VQUIT,          CQUIT },
+       { "reprint",    VREPRINT,       CREPRINT },
+       { "start",      VSTART,         CSTART },
+       { "status",     VSTATUS,        CSTATUS },
+       { "stop",       VSTOP,          CSTOP },
+       { "susp",       VSUSP,          CSUSP },
+       { "time",       VTIME,          CTIME },
+       { "werase",     VWERASE,        CWERASE },
+       { NULL },
 };
 
 struct cchar cchars2[] = {
 };
 
 struct cchar cchars2[] = {
-       "brk",          VEOL,           CEOL,
-       "flush",        VDISCARD,       CDISCARD,
-       "rprnt",        VREPRINT,       CREPRINT,
-       "xoff",         VSTOP,          CSTOP,
-       "xon",          VSTART,         CSTART,
-       NULL
+       { "brk",        VEOL,           CEOL },
+       { "flush",      VDISCARD,       CDISCARD },
+       { "rprnt",      VREPRINT,       CREPRINT },
+       { NULL },
 };
 };
+
+static int
+c_cchar(a, b)
+        const void *a, *b;
+{
+
+        return (strcmp(((struct cchar *)a)->name, ((struct cchar *)b)->name));
+}
+
+int
+csearch(argvp, ip)
+       char ***argvp;
+       struct info *ip;
+{
+       struct cchar *cp, tmp;
+       long val;
+       char *arg, *ep, *name;
+               
+       name = **argvp;
+
+       tmp.name = name;
+       if (!(cp = (struct cchar *)bsearch(&tmp, cchars1,
+           sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar),
+           c_cchar)) && !(cp = (struct cchar *)bsearch(&tmp, cchars1,
+           sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar),
+           c_cchar)))
+               return (0);
+
+       arg = *++*argvp;
+       if (!arg) {
+               warnx("option requires an argument -- %s", name);
+               usage();
+       }
+
+#define CHK(s)  (*arg == s[0] && !strcmp(arg, s))
+       if (CHK("undef") || CHK("<undef>"))
+               ip->t.c_cc[cp->sub] = _POSIX_VDISABLE;
+       else if (cp->sub == VMIN || cp->sub == VTIME) {
+               val = strtol(arg, &ep, 10);
+               if (val == _POSIX_VDISABLE) {
+                       warnx("value of %ld would disable the option -- %s",
+                           val, name);
+                       usage();
+               }
+               if (val > UCHAR_MAX) {
+                       warnx("maximum option value is %d -- %s",
+                           UCHAR_MAX, name);
+                       usage();
+               }
+               if (*ep != '\0') {
+                       warnx("option requires a numeric argument -- %s", name);
+                       usage();
+               }
+               ip->t.c_cc[cp->sub] = val;
+       } else if (arg[0] == '^')
+               ip->t.c_cc[cp->sub] = (arg[1] == '?') ? 0177 :
+                   (arg[1] == '-') ? _POSIX_VDISABLE : arg[1] & 037;
+       else
+               ip->t.c_cc[cp->sub] = arg[0];
+       ip->set = 1;
+       return (1);
+}