vsta

Check-in [d9ed814e76]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Convert to shell script man driver.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | master | trunk
Files: files | file ages | folders
SHA3-256:d9ed814e7613de0efde469e5786975ae0bd7254143d1b97088dbb9aee84df646
User & Date: vandys 2001-10-25 19:15:45
Context
2001-10-25
19:16
Install man.sh as man(1) command. check-in: 88976d4f8d user: vandys tags: master, trunk
19:15
Convert to shell script man driver. check-in: d9ed814e76 user: vandys tags: master, trunk
19:01
Useless whitespace fiddling. :-> check-in: bcd4979dec user: vandys tags: master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to vsta/src/bin/cmds/makefile.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
OUT=test args cat id ls swapd rm cp sleep mkdir pwd kill mv stat \
	dumpsect man fstab rmdir touch strings xargs echo du \
	tput basename uname fmt purge printf ps rcsdo changed \
	which true false whoami egrep fgrep awk cc [ view ascii

OBJS= args.o basename.o cat.o changed.o chmod.o cp.o du.o dumpsect.o \
	echo.o fmt.o fstab.o id.o kill.o ls.o man.o mkdir.o \
	mv.o printf.o ps.o purge.o pwd.o rcsdo.o rm.o rmdir.o \
	sleep.o stat.o strings.o swapd.o test.o touch.o tput.o \
	uname.o wc.o which.o xargs.o dump.o operators.o true.o \
	false.o whoami.o egrep.o fgrep.o awk.o cc.o [.o view.o \
	ascii.o

include ../../makefile.all
................................................................................

rmdir: rmdir.o
	$(LD) $(LDFLAGS) -o rmdir $(CRT0) rmdir.o -lc

fstab: fstab.o
	$(LD) $(LDFLAGS) -o fstab $(CRT0) fstab.o -lc

man: man.o
	$(LD) $(LDFLAGS) -o man $(CRT0) man.o -lc

stat: stat.o
	$(LD) $(LDFLAGS) -o stat $(CRT0) stat.o -lc

dump.o: ../testsh/dump.c
	$(CC) $(CFLAGS) -c ../testsh/dump.c

dumpsect: dumpsect.o dump.o

|




|







 







<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
33
34
35
36
37
38
39



40
41
42
43
44
45
46
OUT=test args cat id ls swapd rm cp sleep mkdir pwd kill mv stat \
	dumpsect fstab rmdir touch strings xargs echo du \
	tput basename uname fmt purge printf ps rcsdo changed \
	which true false whoami egrep fgrep awk cc [ view ascii

OBJS= args.o basename.o cat.o changed.o chmod.o cp.o du.o dumpsect.o \
	echo.o fmt.o fstab.o id.o kill.o ls.o mkdir.o \
	mv.o printf.o ps.o purge.o pwd.o rcsdo.o rm.o rmdir.o \
	sleep.o stat.o strings.o swapd.o test.o touch.o tput.o \
	uname.o wc.o which.o xargs.o dump.o operators.o true.o \
	false.o whoami.o egrep.o fgrep.o awk.o cc.o [.o view.o \
	ascii.o

include ../../makefile.all
................................................................................

rmdir: rmdir.o
	$(LD) $(LDFLAGS) -o rmdir $(CRT0) rmdir.o -lc

fstab: fstab.o
	$(LD) $(LDFLAGS) -o fstab $(CRT0) fstab.o -lc




stat: stat.o
	$(LD) $(LDFLAGS) -o stat $(CRT0) stat.o -lc

dump.o: ../testsh/dump.c
	$(CC) $(CFLAGS) -c ../testsh/dump.c

dumpsect: dumpsect.o dump.o

Deleted vsta/src/bin/cmds/man.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/*
 * man.c
 *	A simple interface to the VSTa documentation files
 */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <std.h>

/*
 * Where map of topics to man files is kept
 */
#define MANDIR "/vsta/doc/man"
#define MANDB MANDIR "/map"

/*
 * Number of matches we handle on ambiguity
 */
#define MAXMATCHES 20

/*
 * Number of sections
 */
#define NUMSECT 10

/*
 * Structure describing an entry in the manual mapfile
 */
struct mapent {
	int m_section;		/* Section number */
	char *m_name;		/* Full name */
	char *m_file;		/* File stored in */
	struct mapent *m_next;	/* Linked list under a section */
};

/*
 * Preserve order of entries found in DB
 */
struct maphd {
	struct mapent		/* Head/tail of list of entries */
		*m_hd, *m_tl;
} map[NUMSECT];

/*
 * load_mandb()
 *	Read in database so we can scan it quickly
 */
static void
load_mandb(void)
{
	FILE *fp;
	unsigned int section = 1;
	char buf[128], *p;
	struct mapent *m;

	/*
	 * Open manual database
	 */
	fp = fopen(MANDB, "r");
	if (fp == 0) {
		perror(MANDB);
		exit(1);
	}

	/*
	 * Read entries
	 */
	while (fgets(buf, sizeof(buf), fp)) {
		/*
		 * Ignore comments and blank lines
		 */
		if ((buf[0] == '\n') || (buf[0] == '#')) {
			continue;
		}

		/*
		 * Remove trailing \n
		 */
		buf[strlen(buf)-1] = '\0';

		/*
		 * Section header
		 */
		if (buf[0] == '/') {
			section = atoi(buf+1);
			if (section >= NUMSECT) {
				printf("Error: %s is corrupt\n", MANDB);
				exit(1);
			}
			continue;
		}

		/*
		 * File entry.  Break into name and file.
		 */
		p = strchr(buf, ':');
		if (p == 0) {
			printf("Error: %s is corrupt\n", MANDB);
			exit(1);
		}
		*p++ = '\0';
		while (isspace(*p)) {
			++p;
		}
		if (*p == '\0') {
			printf("Error: %s is corrupt\n", MANDB);
			exit(1);
		}

		/*
		 * Allocate an element and fill in
		 */
		m = malloc(sizeof(struct mapent));
		if (m == 0) {
			perror("man: init");
			exit(1);
		}
		m->m_name = strdup(buf);
		m->m_section = section;
		m->m_file = strdup(p);
		if ((m->m_name == 0) || (m->m_file == 0)) {
			perror("man: init");
			exit(1);
		}

		/*
		 * Add to list for appropriate section
		 */
		if (map[section].m_tl) {
			map[section].m_tl->m_next = m;
		}
		map[section].m_tl = m;
		if (map[section].m_hd == 0) {
			map[section].m_hd = m;
		}
	}
	fclose(fp);
}

/*
 * find_matches2()
 *	Do scan of single section
 *
 * Same kind of return value as find_matches()
 */
static int
find_matches2(struct maphd *mh, char *name, struct mapent **matches)
{
	struct mapent *m;
	int len, nmatch;

	/*
	 * Scan section
	 */
	len = strlen(name);
	nmatch = 0;
	for (m = mh->m_hd; m; m = m->m_next) {
		if (!strncmp(m->m_name, name, len)) {
			/*
			 * Special case for exact match
			 */
			if (!strcmp(m->m_name, name)) {
				matches[0] = m;
				return(1);
			}

			/*
			 * Check for too many matches
			 */
			if (nmatch >= MAXMATCHES) {
				return(MAXMATCHES+1);
			}

			/*
			 * Save match, increment count
			 */
			matches[nmatch++] = m;
		}
	}
	return(nmatch);
}

/*
 * find_matches()
 *	Scan in-core copy of database for matches
 *
 * Returns count of matches found, and fills matches[] with pointers
 * to those entries.  Returns MAXMATCHES+1 if too many are found.
 */
static int
find_matches(int sect, char *name, struct mapent **matches)
{
	int x, base;
	struct mapent *tmpmatch[MAXMATCHES];

	/*
	 * If specific section, just do it and return
	 */
	if (sect) {
		return(find_matches2(&map[sect], name, matches));
	}

	/*
	 * Otherwise accumulate scans of successive sections
	 */
	for (x = 0, base = 0; x < NUMSECT; ++x) {
		int nmatch;

		nmatch = find_matches2(&map[x], name, tmpmatch);
		if ((base + nmatch) > MAXMATCHES) {
			return(nmatch);
		}
		bcopy(tmpmatch, matches+base, nmatch * sizeof(char *));
		base += nmatch;
	}
	return(base);
}

/*
 * show_man()
 *	Display man page for given entry
 */
static void
show_man(struct mapent *m)
{
	char buf[128], *pager;
	static char tmpf[] = "/tmp/mantXXXXXX";

	mktemp(tmpf);
	sprintf(buf, "nroff -man %s/%d/%s > %s",
		MANDIR, m->m_section, m->m_file, tmpf);
	system(buf);
	pager = getenv("PAGER");
	if (pager == 0) {
		pager = "less";
	}
	sprintf(buf, "%s %s", pager, tmpf);
	system(buf);
	unlink(tmpf);
}

/*
 * show_matches()
 *	Display multiple matches nicely
 */
static void
show_matches(struct mapent **matches, int nmatch)
{
	int x, nent = 0, nline = 0, col = 0;
	char buf[128], buf2[128];

	/*
	 * Display comma-seperated list, wrapping at end of line
	 */
	buf[0] = '\0';
	for (x = 0; x < nmatch; ++x) {
		struct mapent *m = matches[x];

		/*
		 * Generate image of what we'd like to add
		 */
		sprintf(buf2, "%s%s(%d)",
			nent ? ", " : "",
			m->m_name, m->m_section);

		/*
		 * If it won't fit, flush the line, reset the counters,
		 * and push "x" back a notch so we can restart processing
		 * of the current entry.
		 */
		if ((col + strlen(buf2)) > 76) {
			printf("%s,\n", buf);
			strcpy(buf, " ");
			nline += 1;
			col = nent = 0;
			x -= 1;
			continue;
		}

		/*
		 * Add on this entry, update counts
		 */
		strcat(buf, buf2);
		nent += 1;
		col += strlen(buf2);
	}
	if (nent) {
		printf("%s\n", buf);
	}
}

main(int argc, char **argv)
{
	int x, section = 0;
	struct mapent *matches[MAXMATCHES];

	load_mandb();
	for (x = 1; x < argc; ++x) {
		if (isdigit(argv[x][0])) {
			section = atoi(argv[x]);
		} else {
			int y;

			y = find_matches(section, argv[x], matches);
			if (y > MAXMATCHES) {
				printf("More than %d matches for %s\n",
					MAXMATCHES, argv[x]);
				continue;
			}
			switch (y) {
			case 0:
				printf("No man page for %s\n", argv[x]);
				break;
			case 1:
				show_man(matches[0]);
				break;
			default:
				printf("Matches:\n");
				show_matches(matches, y);
			}
		}
	}
	return(0);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<