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: }
Defined functions
Defined variables