misc bugs, malloc & free
[unix-history] / usr / src / usr.bin / window / lcmd.c
CommitLineData
6a571c25 1#ifndef lint
4cbe417d 2static char *sccsid = "@(#)lcmd.c 3.6 83/08/25";
6a571c25
EW
3#endif
4
5#include "defs.h"
6
4cbe417d 7int l_buffer();
6a571c25
EW
8int l_window();
9int l_select();
10int l_escape();
11int l_label();
12int l_terse();
13int l_source();
14int l_write();
8aee01cc 15int l_close();
6a571c25
EW
16
17struct lcmd {
18 char *l_name; /* name of command */
19 int l_lmin; /* minimum length to check */
20 int l_lmax; /* maximum length to check */
21 int l_amin; /* minimum argument */
22 int l_amax; /* maximum argument */
23 int (*l_func)(); /* the function */
24};
25static struct lcmd lcmd[] = {
8aee01cc 26 "%", 1, 1, 0, 0, l_select,
4cbe417d 27 "buffer", 1, 0, 1, 1, l_buffer,
a4c3bba5 28 "close", 1, 0, 0, -1, l_close,
8aee01cc
EW
29 "escape", 1, 0, 1, 1, l_escape,
30 "label", 1, 0, 2, 2, l_label,
31 "source", 1, 0, 1, 1, l_source,
32 "terse", 1, 0, 0, 1, l_terse,
4cbe417d 33 "window", 1, 0, 4, 5, l_window,
8aee01cc 34 "write", 2, 0, 2, 2, l_write,
6a571c25
EW
35 0
36};
37
38dosource(filename)
39char *filename;
40{
41 register FILE *f;
42 char buf[BUFSIZ];
43
44 if ((f = fopen(filename, "r")) == 0)
45 return -1;
46 insource++;
47 beginerror(filename);
48 for (lineno = 1; fgets(buf, sizeof buf, f) != 0; lineno++)
49 dolongcmd(buf);
50 enderror();
51 insource = 0;
52 return 0;
53}
54
55dolongcmd(line)
56char *line;
57{
58 register struct lcmd *lp;
59 register len;
60
61 makeargv(line);
62 if (argc == 0)
63 return;
64 for (lp = lcmd; lp->l_name; lp++) {
65 len = strlen(*argv);
66 if (len < lp->l_lmin)
67 continue;
68 if (!strncmp(*argv, lp->l_name, lp->l_lmax ? lp->l_lmax : len))
69 break;
70 }
71 if (lp->l_name) {
72 if (lp->l_amin > argc - 1)
73 error("Too few arguments.");
8aee01cc 74 else if (lp->l_amax >= 0 && lp->l_amax < argc - 1)
6a571c25
EW
75 error("Too many arguments.");
76 else
77 (*lp->l_func)();
78 } else
79 error("%s: Unknown command.", *argv);
80}
81
82makeargv(p)
83register char *p;
84{
85 static char buf[BUFSIZ];
86 register char *q = buf, **pp = argv;
87 char quote = 0, escape = 0;
88 int i;
89
90 for (; *p == ' ' || *p == '\t'; p++)
91 ;
a4550a40 92 while (*p && *p != '\n' && (*p != '#' || escape || quote)
6a571c25
EW
93 && pp < &argv[sizeof argv/sizeof *argv - 1]) {
94 *pp++ = q;
95 while (*p && *p != '\n') {
96 if (escape) {
97 switch (*p) {
98 case 'n':
99 *q++ = '\n';
100 p++;
101 break;
102 case 'r':
103 *q++ = '\r';
104 p++;
105 break;
106 case '0': case '1': case '2': case '3':
107 case '4': case '5': case '6': case '7':
108 *q = 0;
109 for (i = 3; --i >= 0
110 && *p >= '0' && *p <= '9';)
111 *q = *q << 3 | *p++ - '0';
112 q++;
113 break;
114 default:
115 *q++ = *p++;
116 break;
117 }
118 escape = 0;
119 } else if (*p == '\\') {
120 escape = 1;
121 p++;
122 } else if (quote) {
123 if (*p == quote) {
124 quote = 0;
125 p++;
126 } else
127 *q++ = *p++;
128 } else {
129 if (*p == '"' || *p == '\'')
130 quote = *p++;
131 else if (*p == ' ' || *p == '\t')
132 break;
133 else
134 *q++ = *p++;
135 }
136 }
137 *q++ = 0;
138 for (; *p == ' ' || *p == '\t'; p++)
139 ;
140 }
141 *pp = 0;
142 argc = pp - argv;
143}