xref: /original-bsd/bin/stty/cchar.c (revision 5e598c08)
1 /*-
2  * Copyright (c) 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)cchar.c	8.2 (Berkeley) 03/17/94";
10 #endif /* not lint */
11 
12 #include <sys/types.h>
13 
14 #include <err.h>
15 #include <limits.h>
16 #include <stddef.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include "stty.h"
21 #include "extern.h"
22 
23 /*
24  * Special control characters.
25  *
26  * Cchars1 are the standard names, cchars2 are the old aliases.
27  * The first are displayed, but both are recognized on the
28  * command line.
29  */
30 struct cchar cchars1[] = {
31 	{ "discard",	VDISCARD, 	CDISCARD },
32 	{ "dsusp", 	VDSUSP,		CDSUSP },
33 	{ "eof",	VEOF,		CEOF },
34 	{ "eol",	VEOL,		CEOL },
35 	{ "eol2",	VEOL2,		CEOL },
36 	{ "erase",	VERASE,		CERASE },
37 	{ "intr",	VINTR,		CINTR },
38 	{ "kill",	VKILL,		CKILL },
39 	{ "lnext",	VLNEXT,		CLNEXT },
40 	{ "quit",	VQUIT,		CQUIT },
41 	{ "reprint",	VREPRINT, 	CREPRINT },
42 	{ "start",	VSTART,		CSTART },
43 	{ "status",	VSTATUS, 	CSTATUS },
44 	{ "stop",	VSTOP,		CSTOP },
45 	{ "susp",	VSUSP,		CSUSP },
46 	{ "vmin",	VMIN,		CMIN },
47 	{ "vtime",	VTIME,		CTIME },
48 	{ "werase",	VWERASE,	CWERASE },
49 	{ NULL },
50 };
51 
52 struct cchar cchars2[] = {
53 	{ "brk",	VEOL,		CEOL },
54 	{ "flush",	VDISCARD, 	CDISCARD },
55 	{ "rprnt",	VREPRINT, 	CREPRINT },
56 	{ NULL },
57 };
58 
59 int
60 csearch(argvp, ip)
61 	char ***argvp;
62 	struct info *ip;
63 {
64 	register struct cchar *cp;
65 	struct cchar tmp;
66 	long val;
67 	char *arg, *ep, *name;
68 	static int c_cchar __P((const void *, const void *));
69 
70 	name = **argvp;
71 
72 	tmp.name = name;
73 	if (!(cp = (struct cchar *)bsearch(&tmp, cchars1,
74 	    sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar),
75 	    c_cchar)) && !(cp = (struct cchar *)bsearch(&tmp, cchars1,
76 	    sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar),
77 	    c_cchar)))
78 		return (0);
79 
80 	arg = *++*argvp;
81 	if (!arg) {
82 		warnx("option requires an argument -- %s", name);
83 		usage();
84 	}
85 
86 #define CHK(s)  (*arg == s[0] && !strcmp(arg, s))
87 	if (CHK("undef") || CHK("<undef>"))
88 		ip->t.c_cc[cp->sub] = _POSIX_VDISABLE;
89 	else if (cp->sub == VMIN || cp->sub == VTIME) {
90 		val = strtol(arg, &ep, 10);
91 		if (val == _POSIX_VDISABLE) {
92 			warnx("value of %ld would disable the option -- %s",
93 			    val, name);
94 			usage();
95 		}
96 		if (val > UCHAR_MAX) {
97 			warnx("maximum option value is %d -- %s",
98 			    UCHAR_MAX, name);
99 			usage();
100 		}
101 		if (*ep != '\0') {
102 			warnx("option requires a numeric argument -- %s", name);
103 			usage();
104 		}
105 		ip->t.c_cc[cp->sub] = val;
106 	} else if (arg[0] == '^')
107 		ip->t.c_cc[cp->sub] = (arg[1] == '?') ? 0177 :
108 		    (arg[1] == '-') ? _POSIX_VDISABLE : arg[1] & 037;
109 	else
110 		ip->t.c_cc[cp->sub] = arg[0];
111 	ip->set = 1;
112 	return (1);
113 }
114 
115 static int
116 c_cchar(a, b)
117         const void *a, *b;
118 {
119         return (strcmp(((struct cchar *)a)->name, ((struct cchar *)b)->name));
120 }
121