|
|
1.1 ! root 1: /* $Header$ */ ! 2: ! 3: /* ! 4: * Author: Peter J. Nicklin ! 5: */ ! 6: #include <ctype.h> ! 7: #include <stdio.h> ! 8: #include "macro.h" ! 9: #include "null.h" ! 10: #include "path.h" ! 11: #include "phelp.h" ! 12: #include "slist.h" ! 13: #include "spms.h" ! 14: #include "system.h" ! 15: #include "yesno.h" ! 16: ! 17: char *helpstack[MAXHELPLEVEL]; /* stack of topics and subtopics */ ! 18: extern int HELPLEVEL; /* current level in help hierarchy */ ! 19: static SLIST *requestqueue = NULL; /* queue of topics to process */ ! 20: ! 21: /* ! 22: * gettopic() parses a help request from standard input into tokens and ! 23: * adds the tokens to a previously purged request queue. ! 24: */ ! 25: void ! 26: gettopic() ! 27: { ! 28: char *gets(); /* get a line from standard input */ ! 29: char *getword(); /* get next word on line from stdin */ ! 30: char request[REQUESTSIZE]; /* input line buffer */ ! 31: char *rp; /* request buffer pointer */ ! 32: char *topic; /* topic word pointer */ ! 33: void initrq(); /* initialize request queue */ ! 34: void puttopic(); /* add topic to request queue */ ! 35: void purgrq(); /* purge request queue */ ! 36: ! 37: if (requestqueue == NULL) ! 38: initrq(); ! 39: else ! 40: purgrq(); ! 41: if ((rp = gets(request)) != NULL) ! 42: { ! 43: do { ! 44: rp = getword(&topic, rp); ! 45: if (*topic != '\0') ! 46: puttopic(topic); ! 47: } while (*rp != '\0'); ! 48: } ! 49: } ! 50: ! 51: ! 52: ! 53: /* ! 54: * getword() gets the next word on a line from standard input and returns ! 55: * a pointer to the next word. ! 56: */ ! 57: char * ! 58: getword(word, bp) ! 59: char **word; /* receiving pointer for word */ ! 60: register char *bp; /* buffer pointer */ ! 61: { ! 62: ! 63: for (; *bp != '\0' && isspace(*bp); bp++) ! 64: continue; ! 65: *word = bp; ! 66: for (; *bp != '\0' && !isspace(*bp); bp++) ! 67: continue; ! 68: if (*bp != '\0') ! 69: *bp++ = '\0'; ! 70: return(bp); ! 71: } ! 72: ! 73: ! 74: ! 75: /* ! 76: * printnotopics() prints a "no topics" error message. ! 77: */ ! 78: void ! 79: printnotopics(ppathname) ! 80: char *ppathname; /* project pathname */ ! 81: { ! 82: if (HELPLEVEL < 1) ! 83: { ! 84: if (EQUAL(ppathname, CURPROJECT)) ! 85: { ! 86: warn("There is no help available for this project"); ! 87: } ! 88: else { ! 89: warn("There is no help available for project %s", ! 90: ppathname); ! 91: } ! 92: } ! 93: else { ! 94: warn("%s doesn't have any subtopics", helpstack[HELPLEVEL-1]); ! 95: } ! 96: } ! 97: ! 98: ! 99: ! 100: /* ! 101: * processtopic() interprets the request queue and controls the help ! 102: * stack. ! 103: */ ! 104: processtopic() ! 105: { ! 106: extern char PHELP_CMD[]; /* help command file pathname */ ! 107: extern char PHELP_HELP[]; /* help introduction file pathname */ ! 108: char *getcwp(); /* get current working project */ ! 109: char *mkndir(); /* make a directory name */ ! 110: char *ppathname; /* project pathname */ ! 111: char *slget(); /* get a list item */ ! 112: char *topic; /* next topic from request queue */ ! 113: char *strsav(); /* save a string somewhere */ ! 114: int chproject(); /* change project */ ! 115: int mkindex(); /* make topic index */ ! 116: int nrq; /* no. items in request queue */ ! 117: int printtopic(); /* print topic file and index */ ! 118: int status = 0; /* return status */ ! 119: void printindex(); /* print topic index */ ! 120: void printnotopics(); /* print "no topics" error message */ ! 121: void slrewind(); /* rewind list */ ! 122: ! 123: if ((nrq = SLNUM(requestqueue)) < 1) ! 124: { ! 125: /* go up one level */ ! 126: if (HELPLEVEL > 0) ! 127: { ! 128: chdir(PARENTDIR); ! 129: free(helpstack[--HELPLEVEL]); ! 130: } ! 131: else { ! 132: fprintf(stderr, "You are at the top level of help topics. "); ! 133: printtopic(PHELP_CMD, CURDIR); ! 134: } ! 135: ! 136: } ! 137: else { ! 138: slrewind(requestqueue); ! 139: ! 140: topic = slget(requestqueue); ! 141: if (EQUAL(topic, "help")) ! 142: { ! 143: /* print help introduction */ ! 144: printtopic(PHELP_HELP, CURDIR); ! 145: return(status); ! 146: } ! 147: else if (EQUAL(topic, "?")) ! 148: { ! 149: /* print command summary */ ! 150: printtopic(PHELP_CMD, CURDIR); ! 151: return(status); ! 152: } ! 153: else if (EQUAL(topic, "q")) ! 154: { ! 155: /* quit phelp */ ! 156: exit(status); ! 157: } ! 158: else if (EQUAL(topic, "~")) ! 159: { ! 160: /* return to top level help directory */ ! 161: for (; HELPLEVEL > 0; HELPLEVEL--) ! 162: { ! 163: chdir(PARENTDIR); ! 164: free(helpstack[HELPLEVEL-1]); ! 165: } ! 166: if (mkindex(CURDIR) == YES) ! 167: printindex(stdout); ! 168: return(status); ! 169: } ! 170: else if (EQUAL(topic, "P")) ! 171: { ! 172: /* change project */ ! 173: if (nrq < 2) ! 174: { ! 175: warn("Missing project name"); ! 176: status = 1; ! 177: } ! 178: else if (nrq > 2) ! 179: { ! 180: warn("Too many arguments"); ! 181: status = 1; ! 182: } ! 183: else { ! 184: ppathname = slget(requestqueue); ! 185: if (chghelp(ppathname) == NO) ! 186: { ! 187: status = 1; ! 188: } ! 189: else if (mkindex(CURDIR) == NO) ! 190: { ! 191: printnotopics(ppathname); ! 192: status = 1; ! 193: } ! 194: else { ! 195: printindex(stdout); ! 196: } ! 197: } ! 198: return(status); ! 199: } ! 200: else { ! 201: /* travel to the requested level */ ! 202: while (nrq-- > 1) ! 203: { ! 204: if (CHDIR(mkndir(topic))) ! 205: helpstack[HELPLEVEL++] = strsav(topic); ! 206: else if (FILEXIST(topic)) ! 207: { ! 208: warn("%s doesn't have any subtopics", topic); ! 209: status = 1; ! 210: } ! 211: else if (mkindex(CURDIR) == NO) ! 212: { ! 213: printnotopics(CURPROJECT); ! 214: status = 1; ! 215: } ! 216: else { ! 217: warn("Can't find %s", topic); ! 218: printindex(stderr); ! 219: status = 1; ! 220: } ! 221: if (status != 0) ! 222: break; ! 223: topic = slget(requestqueue); ! 224: } ! 225: } ! 226: ! 227: if (status != 0) ! 228: return(status); ! 229: ! 230: /* process help topic request */ ! 231: if (EQUAL(topic, "index")) ! 232: { ! 233: /* print topic index */ ! 234: if (mkindex(CURDIR) == YES) ! 235: printindex(stdout); ! 236: else { ! 237: printnotopics(CURPROJECT); ! 238: if (HELPLEVEL > 0) ! 239: { ! 240: chdir(PARENTDIR); ! 241: free(helpstack[--HELPLEVEL]); ! 242: } ! 243: status = 1; ! 244: } ! 245: } ! 246: else { ! 247: helpstack[HELPLEVEL++] = strsav(topic); ! 248: switch (printtopic(topic, mkndir(topic))) ! 249: { ! 250: case 0: /* help file and subtopics */ ! 251: case 1: /* subtopics only */ ! 252: chdir(mkndir(topic)); ! 253: break; ! 254: case 2: /* help file, no subtopics */ ! 255: free(helpstack[--HELPLEVEL]); ! 256: break; ! 257: case 3: /* no help available at all */ ! 258: free(helpstack[--HELPLEVEL]); ! 259: /* is there any help at */ ! 260: /* current level? */ ! 261: if (mkindex(CURDIR) == NO) ! 262: { ! 263: printnotopics(CURPROJECT); ! 264: status = 1; ! 265: } ! 266: else { ! 267: warn("Sorry, %s is not available", ! 268: topic); ! 269: printindex(stderr); ! 270: status = 1; ! 271: } ! 272: break; ! 273: } ! 274: } ! 275: } ! 276: return(status); ! 277: } ! 278: ! 279: ! 280: ! 281: /* ! 282: * prompt() prints the stack of topics and subtopics to the current ! 283: * level and prompts for the next command. ! 284: */ ! 285: void ! 286: prompt() ! 287: { ! 288: int tsindex; /* topic stack index */ ! 289: ! 290: if (HELPLEVEL > 3) ! 291: printf("-->"); ! 292: for (tsindex = MAX(0, HELPLEVEL-3); tsindex < HELPLEVEL; tsindex++) ! 293: printf("%s-->", helpstack[tsindex]); ! 294: printf("??? "); ! 295: } ! 296: ! 297: ! 298: ! 299: /* ! 300: * puttopic() adds a help topic to the end of the request queue. ! 301: */ ! 302: void ! 303: puttopic(topic) ! 304: char *topic; /* topic string */ ! 305: { ! 306: char *slappend(); /* append item to list */ ! 307: ! 308: if (requestqueue == NULL) ! 309: initrq(); ! 310: slappend(topic, requestqueue); ! 311: } ! 312: ! 313: ! 314: ! 315: /* ! 316: * initrq() initializes the request queue. ! 317: */ ! 318: void ! 319: initrq() ! 320: { ! 321: SLIST *slinit(); /* initialize list */ ! 322: ! 323: requestqueue = slinit(); ! 324: } ! 325: ! 326: ! 327: ! 328: /* ! 329: * purgrq() empties the request queue. ! 330: */ ! 331: void ! 332: purgrq() ! 333: { ! 334: int slpop(); /* pop items off list */ ! 335: ! 336: while (slpop(CNULL, 0, requestqueue) == YES) ! 337: continue; ! 338: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.