/********** 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 #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); }