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: }