ngspice/src/frontend/help/readhelp.c

324 lines
7.7 KiB
C

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified 1999 Emmanuel Rouat
**********/
#include <config.h>
#include "ngspice.h"
#include "cpstd.h"
#include "hlpdefs.h"
#include "suffix.h"
static char *getsubject(fplace *place);
static toplink *getsubtoplink(char **ss);
static topic *alltopics = NULL;
static fplace *copy_fplace(fplace *place);
static int
sortcmp(const void *a, const void *b)
{
toplink **tlp1 = (toplink **) a;
toplink **tlp2 = (toplink **) b;
return (strcmp((*tlp1)->description, (*tlp2)->description));
}
static void
sortlist(toplink **tlp)
{
toplink **vec, *tl;
int num = 0, i;
for (tl = *tlp; tl; tl = tl->next)
num++;
if (!num)
return;
vec = (toplink **) tmalloc(sizeof (toplink *) * num);
for (tl = *tlp, i = 0; tl; tl = tl->next, i++)
vec[i] = tl;
(void) qsort((char *) vec, num, sizeof (toplink *), sortcmp);
*tlp = vec[0];
for (i = 0; i < num - 1; i++)
vec[i]->next = vec[i + 1];
vec[i]->next = NULL;
tfree(vec);
return;
}
topic *
hlp_read(fplace *place)
{
char buf[BSIZE_SP];
topic *top = alloc(topic);
toplink *topiclink;
toplink *tl, *tend = NULL;
wordlist *wl, *end = NULL;
int i, fchanges;
char *s;
bool mof;
if (!place)
return 0;
top->place = copy_fplace(place);
/* get the title */
if (!place->fp) place->fp = hlp_fopen(place->filename);
if (!place->fp) return(NULL);
fseek(place->fp, place->fpos, 0);
(void) fgets(buf, BSIZE_SP, place->fp); /* skip subject */
(void) fgets(buf, BSIZE_SP, place->fp);
for (s = buf; *s && (*s != '\n'); s++)
;
*s = '\0';
top->title = copy(&buf[7]); /* don't copy "TITLE: " */
/* get the text */
/* skip to TEXT: */
while (fgets(buf, BSIZE_SP, place->fp)) {
if (!strncmp("TEXT: ", buf, 6)) break;
if ((*buf = '\0') ||
!strncmp("SEEALSO: ", buf, 9) ||
!strncmp("SUBTOPIC: ", buf, 10)) {
/* no text */
top->text = NULL;
goto endtext;
}
}
mof = TRUE;
while (mof && !strncmp("TEXT: ", buf, 6)) {
for (s = &buf[6], fchanges = 0; *s && (*s != '\n'); s++)
if (((s[0] == '\033') && s[1]) ||
((s[0] == '_') && (s[1] == '\b')))
fchanges++;
*s = '\0';
wl = alloc(wordlist);
wl->wl_word = copy(&buf[6]);
if (end)
end->wl_next = wl;
else
top->text = wl;
wl->wl_prev = end;
end = wl;
top->numlines++;
if ((i = strlen(&buf[6]) - fchanges) > top->maxcols)
top->maxcols = i;
mof = fgets(buf, BSIZE_SP, place->fp) == NULL ? FALSE : TRUE;
}
endtext:
/* get subtopics */
while(mof && !strncmp("SUBTOPIC: ", buf, 10)) {
s = &buf[10];
/* process tokens within line, updating pointer */
while (*s) {
if ((topiclink = getsubtoplink(&s))) {
if (tend)
tend->next = topiclink;
else
top->subtopics = topiclink;
tend = topiclink;
}
}
mof = fgets(buf, BSIZE_SP, place->fp) == NULL ? FALSE : TRUE;
}
/* get see alsos */
tend = NULL;
while(mof && !strncmp("SEEALSO: ", buf, 9)) {
s = &buf[9];
/* process tokens within line, updating pointer */
while (*s) {
if ((topiclink = getsubtoplink(&s))) {
if (tend)
tend->next = topiclink;
else
top->seealso = topiclink;
tend = topiclink;
}
}
mof = fgets(buf, BSIZE_SP, place->fp) == NULL ? FALSE : TRUE;
}
/* Now we have to fill in the subjects
for the seealsos and subtopics. */
for (tl = top->seealso; tl; tl = tl->next)
tl->description = getsubject(tl->place);
for (tl = top->subtopics; tl; tl = tl->next)
tl->description = getsubject(tl->place);
sortlist(&top->seealso);
/* sortlist(&top->subtopics); It looks nicer if they
are in the original order */
top->readlink = alltopics;
alltopics = top;
return (top);
}
/* *ss is of the form filename:subject */
static toplink *getsubtoplink(char **ss)
{
toplink *tl;
char *tmp, *s, *t;
char subject[BSIZE_SP];
if (!**ss) return(NULL);
s = *ss;
tl = alloc(toplink);
if ((tmp =strchr(s, ':'))) {
tl->place = alloc(fplace);
tl->place->filename = strncpy(
calloc(1, (unsigned) (sizeof (char) * (tmp - s + 1))),
s, (tmp - s));
tl->place->filename[tmp - s] = '\0';
strtolower(tl->place->filename);
/* see if filename is on approved list */
if (!hlp_approvedfile(tl->place->filename)) {
tfree(tl->place);
tfree(tl);
/* skip up to next comma or newline */
while (*s && *s != ',' && *s != '\n') s++;
while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++;
*ss = s;
return(NULL);
}
tl->place->fp = hlp_fopen(tl->place->filename);
for (s = tmp + 1, t = subject; *s && *s != ',' && *s != '\n'; s++) {
*t++ = *s;
}
*t = '\0';
tl->place->fpos = findsubject(tl->place->filename, subject);
if (tl->place->fpos == -1) {
tfree(tl->place);
tfree(tl);
while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++;
*ss = s;
return(NULL);
}
} else {
fprintf(stderr, "bad filename:subject pair %s\n", s);
/* skip up to next free space */
while (*s && *s != ',' && *s != '\n') s++;
while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++;
*ss = s;
tfree(tl->place);
tfree(tl);
return(NULL);
}
while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++;
*ss = s;
return(tl);
}
/* returns a file position, -1 on error */
long
findsubject(char *filename, char *subject)
{
FILE *fp;
char buf[BSIZE_SP];
struct hlp_index indexitem;
if (!filename) {
return -1;
}
/* open up index for filename */
sprintf(buf, "%s%s%s.idx", hlp_directory, DIR_PATHSEP, filename);
hlp_pathfix(buf);
if (!(fp = fopen(buf, "rb"))) {
perror(buf);
return(-1);
}
while(fread((char *) &indexitem, sizeof (struct hlp_index), 1, fp)) {
if (!strncmp(subject, indexitem.subject, 64)) {
fclose(fp);
return(indexitem.fpos);
}
}
fclose(fp);
return(-1);
}
static char *
getsubject(fplace *place)
{
char buf[BSIZE_SP], *s;
if (!place->fp) place->fp = hlp_fopen(place->filename);
if (!place->fp) return(NULL);
fseek(place->fp, place->fpos, 0);
(void) fgets(buf, BSIZE_SP, place->fp);
for (s = buf; *s && (*s != '\n'); s++)
;
*s = '\0';
return (copy(&buf[9])); /* don't copy "SUBJECT: " */
}
static
void tlfree(toplink *tl)
{
toplink *nt = NULL;
while (tl) {
tfree(tl->description);
tfree(tl->place->filename);
tfree(tl->place);
/* Don't free the button stuff... */
nt = tl->next;
tfree(tl);
tl = nt;
}
return;
}
void
hlp_free(void)
{
topic *top, *nt = NULL;
for (top = alltopics; top; top = nt) {
nt = top->readlink;
tfree(top->title);
tfree(top->place);
wl_free(top->text);
tlfree(top->subtopics);
tlfree(top->seealso);
tfree(top);
}
alltopics = NULL;
return;
}
static fplace *
copy_fplace(fplace *place)
{
fplace *newplace;
newplace = (fplace *) malloc(sizeof(fplace));
newplace->filename = copy(place->filename);
newplace->fpos = place->fpos;
newplace->fp = place->fp;
return(newplace);
}