|
|
1.1 root 1: /* $Header$ */
2:
3: /*
4: * Author: Peter J. Nicklin
5: */
6: #include <sys/types.h>
7: #include <sys/dir.h>
8: #include <stdio.h>
9: #include "null.h"
10: #include "phelp.h"
11: #include "slist.h"
12: #include "tree.h"
13: #include "yesno.h"
14:
15: extern char *helpstack[MAXHELPLEVEL]; /* stack of topics and subtopics */
16: extern int HELPLEVEL; /* current level in help hierarchy */
17: static SLIST *index = NULL; /* index list */
18:
19: /*
20: * mkindex() reads topicdir and creates a list of topics. Topics may be
21: * regular file names or subtopic directories (`.d' suffix) or both. The
22: * topics are inserted into a binary tree (this eliminates duplicate
23: * topic names) and the resulting tree is copied to a list for printing
24: * purposes. Return integer NO if the directory can not be read or there
25: * aren't any topics, otherwise YES.
26: */
27: mkindex(topicdir)
28: char *topicdir; /* directory in which to find topics */
29: {
30: char *strcpy(); /* string copy */
31: char topic[MAXNAMLEN]; /* topic name buffer */
32: DIR *dirp; /* directory stream */
33: DIR *opendir(); /* open directory stream */
34: int status = YES; /* return status */
35: int treetolist(); /* copy tree to singly-linked list */
36: SLIST *slinit(); /* initialize list */
37: struct direct *dp; /* directory entry pointer */
38: struct direct *readdir(); /* read a directory entry */
39: TREE *topicroot; /* root of topic tree */
40: TREE *tree(); /* insert into topic tree */
41: TREE *treerm(); /* remove tree */
42: void slrm(); /* remove list */
43:
44: if ((dirp = opendir(topicdir)) == NULL)
45: return(NO);
46: if (index != NULL)
47: slrm(CNULL, index);
48: topicroot = NULL;
49: for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
50: if (*dp->d_name != '.')
51: if (dp->d_namlen > 2 &&
52: (dp->d_name)[dp->d_namlen-1] == 'd' &&
53: (dp->d_name)[dp->d_namlen-2] == '.')
54: {
55: strcpy(topic, dp->d_name);
56: topic[dp->d_namlen-2] = '\0';
57: topicroot = tree(topicroot, topic);
58: }
59: else
60: topicroot = tree(topicroot, dp->d_name);
61: closedir(dirp);
62:
63: index = slinit();
64: if (treetolist(topicroot) == NO)
65: status = NO;
66: treerm(topicroot, CNULL);
67: if (SLNUM(index) < 1)
68: status = NO;
69: return(status);
70: }
71:
72:
73:
74: /*
75: * printindex() prints an index of topics.
76: */
77: void
78: printindex(ofp)
79: FILE *ofp; /* output stream */
80: {
81: char *slget(); /* get a list item */
82: char *topic; /* next topic from index list */
83: int available_space; /* amount of space left on title line */
84: int colwidth; /* topic column width */
85: int ncol; /* number of columns to be printed */
86: int strlen(); /* string length */
87: void slprint(); /* print list */
88: void slrewind(); /* rewind list */
89:
90: colwidth = index->maxkey + MINIMUM_GAP;
91: if (HELPLEVEL < 1)
92: {
93: fprintf(ofp, "\nHelp topics available:");
94: available_space = MAXLINE - 22;
95: }
96: else {
97: fprintf(ofp, "\n%s subtopics:", helpstack[HELPLEVEL-1]);
98: available_space = MAXLINE - strlen(helpstack[HELPLEVEL-1]) - 11;
99: }
100: if ((available_space/colwidth) > SLNUM(index))
101: { /* topics on title line if possible */
102: slrewind(index);
103: while ((topic = slget(index)) != NULL)
104: fprintf(ofp, " %s", topic);
105: fprintf(ofp, "\n\n");
106: }
107: else {
108: fprintf(ofp, "\n\n");
109: if (colwidth % TABSIZE)
110: colwidth = TABSIZE * (colwidth/TABSIZE + 1);
111: ncol = MAXLINE/colwidth;
112: slprint(ncol, colwidth, YES, ofp, index);
113: putc('\n', ofp);
114: }
115: fflush(ofp);
116: }
117:
118:
119:
120: /*
121: * treetolist() copies a binary tree to singly linked list index. Returns
122: * YES if successful, otherwise NO.
123: */
124: treetolist(p)
125: TREE *p; /* current tree node */
126: {
127: char *slappend(); /* append key to list */
128:
129: if (p != NULL)
130: {
131: if (treetolist(p->left) == NO)
132: return(NO);
133: if (slappend(p->key, index) == NULL)
134: return(NO);
135: if (treetolist(p->right) == NO)
136: return(NO);
137: }
138: return(YES);
139: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.