Jspice3
readhelp.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1986 Wayne A. Christopher
5  1994 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * The main entry point for the help system.
10  */
11 
12 #include "spice.h"
13 #include "hlpdefs.h"
14 
18 
19 static struct sHlpEnt *HelpBase;
20 
21 #if __STDC__
22 static void sortlist(toplink**);
23 static int sortcmp(toplink**,toplink**);
24 static void tlfree(toplink*);
25 static FILE *db_open(char*,struct sHlpEnt**);
26 static void read_db(FILE*);
27 static struct sHlpEnt *find_entry(char*);
28 static char *my_fgets(char*,int,FILE*);
29 #else
30 static void sortlist();
31 static int sortcmp();
32 static void tlfree();
33 static FILE *db_open();
34 static void read_db();
35 static struct sHlpEnt *find_entry();
36 static char *my_fgets();
37 #endif
38 
39 #define prefix(x,y) ciprefix(x,y)
40 
41 
42 void
44 
45 char *path;
46 wordlist *wl;
47 {
48  topic *top = NULL;
49 
51  hlp_directory = copy(path);
52 
53  if (wl == NULL) {
54  if (!(top = hlp_read(NULL))) {
55  fprintf(stderr, "Error: no top level topic\n");
56  return;
57  }
58  hlp_provide(top);
59  }
60  while (wl) {
61  if (!(top = hlp_read(wl->wl_word))) {
62  if (wl->wl_word && *wl->wl_word)
63  fprintf(stderr, "Error: No such topic: %s\n",
64  wl->wl_word);
65  else
66  fprintf(stderr, "Error: no top level topic\n");
67  wl = wl->wl_next;
68  continue;
69  }
70  hlp_provide(top);
71  wl = wl->wl_next;
72  }
73 }
74 
75 
76 topic *
77 hlp_read(word)
78 
79 char *word;
80 {
81  char buf[BSIZE_SP], *s, *t;
82  int i, seealso, subtopics;
83  FILE *fp;
84  topic *top;
85  toplink *tl;
86  topic *alltopics = NULL;
87  struct sHlpEnt *bb;
88  wordlist *wl = NULL;
89 
90  if (!(fp = db_open(word,&bb))) {
91  fprintf(stderr,"Error: no title for topic %s.\n", word);
92  return (NULL);
93  }
94  top = alloc(topic);
95  top->keyword = copy(word);
96  top->title = copy(bb->title);
97  top->subtopics = NULL;
98  top->seealso = NULL;
99  top->text = NULL;
100  top->maxcols = 0;
101  seealso = false;
102  subtopics = false;
103 
104  while ((s = my_fgets(buf,BSIZE_SP,fp)) != NULL) {
105 
106  if (prefix(HLP_KEYWORD,s))
107  break;
108 
109  if (prefix(HLP_SEEALSO,s)) {
110  seealso = true;
111  subtopics = false;
112  tl = NULL;
113  continue;
114  }
115  if (prefix(HLP_SUBTOPICS,s)) {
116  subtopics = true;
117  seealso = false;
118  tl = NULL;
119  continue;
120  }
121 
122  if (seealso || subtopics) {
123 
124  if (*s == '#' || *s == '*')
125  continue;
126  while (isspace(*s))
127  s++;
128  if (!*s)
129  continue;
130 
131  t = s + strlen(s)-1;
132  while (*t <= ' ')
133  *t-- = '\0';
134 
135  if (tl) {
136  tl->next = alloc(toplink);
137  tl = tl->next;
138  }
139  else
140  tl = alloc(toplink);
141  tl->keyword = copy(s);
142  tl->next = NULL;
143  tl->top = top;
144  bb = find_entry(s);
145  if (bb)
146  tl->description = copy(bb->title);
147  else
148  tl->description = copy("<unknown>");
149 
150  if (seealso && !top->seealso)
151  top->seealso = tl;
152  else if (subtopics && !top->subtopics)
153  top->subtopics = tl;
154  continue;
155  }
156  if ((s = strchr(buf,'\n')) != NULL)
157  *s = '\0';
158  if (wl) {
159  wl->wl_next = alloc(wordlist);
160  wl->wl_next->wl_prev = wl;
161  wl = wl->wl_next;
162  }
163  else {
164  wl = alloc(wordlist);
165  wl->wl_prev = NULL;
166  }
167  wl->wl_next = NULL;
168  wl->wl_word = copy(buf);
169 
170  if (!top->text)
171  top->text = wl;
172 
173  top->numlines++;
174  if ((i = strlen(buf)) > top->maxcols)
175  top->maxcols = i;
176  }
177  (void) fclose(fp);
178 
179  sortlist(&top->seealso);
180  sortlist(&top->subtopics);
181 
182  return (top);
183 }
184 
185 
186 static void
188 
189 toplink **tlp;
190 {
191  toplink **vec, *tl;
192  int num, i;
193 
194  for (num = 0,tl = *tlp; tl; tl = tl->next) num++;
195 
196  if (!num) return;
197 
198  vec = (toplink **) tmalloc(sizeof (toplink *) * num);
199  for (tl = *tlp, i = 0; tl; tl = tl->next, i++)
200  vec[i] = tl;
201  (void) qsort((char *) vec, num, sizeof (toplink *),
202 #if __STDC__
203  (int(*)(const void*,const void*))sortcmp);
204 #else
205  sortcmp);
206 #endif
207  *tlp = vec[0];
208  for (i = 0; i < num - 1; i++)
209  vec[i]->next = vec[i + 1];
210  vec[i]->next = NULL;
211  free(vec);
212  return;
213 }
214 
215 
216 static int
217 sortcmp(tlp1, tlp2)
218 
219 toplink **tlp1, **tlp2;
220 {
221  return (strcmp((*tlp1)->description, (*tlp2)->description));
222 }
223 
224 
225 void
227 
228 topic *top;
229 {
230  txfree(top->title);
231  txfree(top->keyword);
232  txfree(top->chartext);
233  wl_free(top->text);
234  tlfree(top->subtopics);
235  tlfree(top->seealso);
236  free((char*)top);
237 }
238 
239 
240 static void
242 
243 toplink *tl;
244 {
245  toplink *nt = NULL;
246 
247  while (tl) {
248  txfree(tl->description);
249  txfree(tl->keyword);
250  /* Don't free the button stuff... */
251  nt = tl->next;
252  free((char*)tl);
253  tl = nt;
254  }
255 }
256 
257 
258 static FILE *
259 db_open(word,pb)
260 
261 char *word;
262 struct sHlpEnt **pb;
263 {
264  char buf[BSIZE_SP];
265  FILE *fp;
266  struct sHlpEnt *bb;
267 
268  (void) sprintf(buf,"%s/%s",hlp_directory,DBFILE);
269  cp_pathfix(buf);
270  /* open in binary mode, so ftell/fseek work in DOS */
271  fp = fopen(buf,"rb");
272  if (!fp) {
273  perror(buf);
274  return (NULL);
275  }
276  if (!HelpBase)
277  read_db(fp);
278 
279  if (!HelpBase)
280  return (NULL);
281 
282  bb = find_entry(word);
283  if (bb) {
284  *pb = bb;
285  fseek(fp,bb->offset,0);
286  }
287  else {
288  fclose(fp);
289  fp = NULL;
290  }
291  return (fp);
292 }
293 
294 
295 static void
297 
298 FILE *fp;
299 {
300  char buf[BSIZE_SP], *s, *t, *kw, *ti;
301  struct sHlpEnt *bb;
302  int keyword, title;
303 
304  while ((s = my_fgets(buf, BSIZE_SP, fp)) != NULL) {
305 
306  if (prefix(HLP_KEYWORD,buf)) {
307  keyword = true;
308  title = false;
309  kw = NULL;
310  continue;
311  }
312  if (prefix(HLP_TITLE,buf)) {
313  title = true;
314  keyword = false;
315  ti = NULL;
316  continue;
317  }
318  if (prefix(HLP_TEXT,buf)) {
319  if (ti && kw) {
320 
321  if (HelpBase == NULL) {
322  HelpBase = alloc(struct sHlpEnt);
323  bb = HelpBase;
324  }
325  else {
326  bb->next = alloc(struct sHlpEnt);
327  bb = bb->next;
328  }
329  bb->next = NULL;
330  bb->keyword = kw;
331  bb->title = ti;
332  bb->offset = ftell(fp);
333  ti = NULL;
334  kw = NULL;
335  keyword = false;
336  title = false;
337  }
338  continue;
339  }
340 
341  if (keyword || title) {
342 
343  while (isspace(*s))
344  s++;
345  if (!*s)
346  continue;
347 
348  t = s + strlen(s)-1;
349  while (*t <= ' ')
350  *t-- = '\0';
351 
352  if (keyword)
353  kw = copy(s);
354  else
355  ti = copy(s);
356 
357  }
358  }
359 }
360 
361 
362 static struct sHlpEnt *
364 
365 char *word;
366 {
367  struct sHlpEnt *bb;
368 
369  if (!word)
370  return (HelpBase);
371 
372  for (bb = HelpBase; bb; bb = bb->next) {
373  if (!strcmp(word,bb->keyword))
374  return (bb);
375  }
376  return (NULL);
377 }
378 
379 
380 static char *
381 my_fgets(buf,size,fp)
382 
383 char *buf;
384 int size;
385 FILE *fp;
386 {
387  char *s;
388  int i, c;
389  /* works with DOS or UNIX */
390 
391  for (s = buf, i = size; i; s++, i--) {
392  c = getc(fp);
393  if (c == '\r')
394  c = getc(fp);
395  if (c == EOF) {
396  *s = '\0';
397  if (s == buf)
398  return (NULL);
399  return (buf);
400  }
401  *s = c;
402  if (c == '\n') {
403  *++s = '\0';
404  return (buf);
405  }
406  }
407  buf[size-1] = '\0';
408  return (buf);
409 }
void cp_pathfix(char *buf)
Definition: help.c:198
#define HLP_KEYWORD
Definition: hlpdefs.h:23
static char buf[MAXPROMPT]
Definition: arg.c:18
#define BSIZE_SP
Definition: misc.h:19
int maxcols
Definition: hlpdefs.h:61
void hlp_main(char *path, wordlist *wl)
Definition: readhelp.c:43
#define prefix(x, y)
Definition: readhelp.c:39
static char * my_fgets()
Definition: cddefs.h:119
char * hlp_directory
Definition: readhelp.c:15
toplink * seealso
Definition: hlpdefs.h:54
wordlist * text
Definition: hlpdefs.h:51
toplink * subtopics
Definition: hlpdefs.h:53
int numlines
Definition: hlpdefs.h:60
static FILE * db_open()
void hlp_provide()
#define START_YPOS
Definition: hlpdefs.h:71
Definition: library.c:18
int hlp_initxpos
Definition: readhelp.c:16
static void read_db()
static struct sHlpEnt * HelpBase
Definition: readhelp.c:19
int hlp_initypos
Definition: readhelp.c:17
#define alloc(type)
Definition: cdmacs.h:21
#define HLP_SUBTOPICS
Definition: hlpdefs.h:27
topic * hlp_read(char *word)
Definition: readhelp.c:77
char * copy()
void wl_free()
char * tmalloc()
Definition: hlpdefs.h:48
struct wordlist * wl_prev
Definition: cpstd.h:24
#define HLP_SEEALSO
Definition: hlpdefs.h:26
void txfree()
#define START_XPOS
Definition: hlpdefs.h:70
#define NULL
Definition: spdefs.h:121
char * keyword
Definition: hlpdefs.h:31
#define HLP_TITLE
Definition: hlpdefs.h:24
static double c
Definition: vectors.c:16
static struct sHlpEnt * find_entry()
void perror()
#define DBFILE
Definition: hlpdefs.h:20
static int sortcmp()
Definition: cpstd.h:21
char * title
Definition: hlpdefs.h:49
char * title
Definition: hlpdefs.h:32
static void tlfree()
qsort()
Definition: string.c:375
long offset
Definition: hlpdefs.h:30
struct sHlpEnt * next
Definition: hlpdefs.h:33
static void sortlist()
struct wordlist * wl_next
Definition: cpstd.h:23
char * wl_word
Definition: cpstd.h:22
#define HLP_TEXT
Definition: hlpdefs.h:25
void hlp_free(topic *top)
Definition: readhelp.c:226
char * keyword
Definition: hlpdefs.h:50
static char * path
Definition: paths.c:13
Definition: cddefs.h:192
Definition: sced.h:130
void free()