Mercurial > ~dholland > hg > ag > index.cgi
view helpgen/helpgen.c @ 1:60d3ca9d3f6b
Fix stupid bug in help2html.
author | David A. Holland |
---|---|
date | Tue, 12 Aug 2008 00:13:42 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
#include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "utils.h" #include "topic.h" #include "helpgen.h" #define MAXTOPICS 512 #define MAXTOTTITLES (MAXTOPICS*4) static struct topic *topics[MAXTOPICS]; static int ntopics; void help_addtopic(struct topic *t) { if (ntopics >= MAXTOPICS) { fprintf(stderr, "Too many help topics (increase MAXTOPICS)\n"); exit(1); } topics[ntopics++] = t; } //////////////////////////////////////////////////////////// static int titlesort(const void *av, const void *bv) { const char *a = *(const char *const *)av; const char *b = *(const char *const *)bv; return strcasecmp(a, b); } static int titlefind(const void *av, const void *bv) { const char *a = (const char *)av; const char *b = *(const char *const *)bv; return strcasecmp(a, b); } static void checkxrefs(void) { // check for dangling xrefs and duplicate titles const char *alltitles[MAXTOTTITLES]; int ntitles = 0; int i, j, n; int bad = 0; for (i=0; i<ntopics; i++) { n = topic_getnumtitles(topics[i]); for (j=0; j<n; j++) { if (ntitles >= MAXTOTTITLES) { fprintf(stderr, "MAXTOTTITLES too small\n"); exit(1); } alltitles[ntitles++] = topic_gettitle(topics[i], j); } } qsort(alltitles, ntitles, sizeof(alltitles[0]), titlesort); // check for dups for (i=1; i<ntitles; i++) { if (!strcasecmp(alltitles[i], alltitles[i-1])) { fprintf(stderr, "Duplicate title %s\n", alltitles[i]); bad = 1; } } // check refs for (i=0; i<ntopics; i++) { n = topic_getnumrefs(topics[i]); for (j=0; j<n; j++) { const char *ref; const void *result; ref = topic_getref(topics[i], j); result = bsearch(ref, alltitles, ntitles, sizeof(alltitles[0]), titlefind); if (!result) { char *ref2; size_t reflen; reflen = strlen(ref); ref2 = dostrdup(ref); if (reflen > 0 && ref2[reflen-1]=='s') { ref2[reflen-1] = 0; result = bsearch(ref2, alltitles, ntitles, sizeof(alltitles[0]), titlefind); } free(ref2); } if (!result) { fprintf(stderr, "Dangling crossreference %s from %s\n", ref, topic_gettitle(topics[i], 0)); bad = 1; } } } if (bad) { exit(1); } } //////////////////////////////////////////////////////////// static void usage(const char *av0) { fprintf(stderr, "usage: %s [-t type] infile outfile\n", av0); fprintf(stderr, " type may be: c html\n"); exit(1); } int main(int argc, char *argv[]) { void (*outfunc)(const char *, struct topic **, int); const char *outputtype = "c"; int ch; while ((ch = getopt(argc, argv, "t:"))!=-1) { switch (ch) { case 't': outputtype = optarg; break; default: usage(argv[0]); break; } } if (optind != argc-2) { usage(argv[0]); } const char *infile = argv[optind++]; const char *outfile = argv[optind++]; if (!strcmp(outputtype, "c")) { outfunc = cout; } else if (!strcmp(outputtype, "html")) { outfunc = htmlout; } else { usage(argv[0]); } load(infile); checkxrefs(); outfunc(outfile, topics, ntopics); return 0; }