Mercurial > ~dholland > hg > ag > index.cgi
comparison helpgen/helpgen.c @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 #include <getopt.h> | |
2 #include <stdio.h> | |
3 #include <stdlib.h> | |
4 #include <string.h> | |
5 | |
6 #include "utils.h" | |
7 #include "topic.h" | |
8 #include "helpgen.h" | |
9 | |
10 | |
11 #define MAXTOPICS 512 | |
12 #define MAXTOTTITLES (MAXTOPICS*4) | |
13 | |
14 static struct topic *topics[MAXTOPICS]; | |
15 static int ntopics; | |
16 | |
17 void help_addtopic(struct topic *t) { | |
18 if (ntopics >= MAXTOPICS) { | |
19 fprintf(stderr, "Too many help topics (increase MAXTOPICS)\n"); | |
20 exit(1); | |
21 } | |
22 topics[ntopics++] = t; | |
23 } | |
24 | |
25 //////////////////////////////////////////////////////////// | |
26 | |
27 static int titlesort(const void *av, const void *bv) { | |
28 const char *a = *(const char *const *)av; | |
29 const char *b = *(const char *const *)bv; | |
30 return strcasecmp(a, b); | |
31 } | |
32 | |
33 static int titlefind(const void *av, const void *bv) { | |
34 const char *a = (const char *)av; | |
35 const char *b = *(const char *const *)bv; | |
36 return strcasecmp(a, b); | |
37 } | |
38 | |
39 static void checkxrefs(void) { | |
40 // check for dangling xrefs and duplicate titles | |
41 | |
42 const char *alltitles[MAXTOTTITLES]; | |
43 int ntitles = 0; | |
44 | |
45 int i, j, n; | |
46 int bad = 0; | |
47 | |
48 for (i=0; i<ntopics; i++) { | |
49 n = topic_getnumtitles(topics[i]); | |
50 for (j=0; j<n; j++) { | |
51 if (ntitles >= MAXTOTTITLES) { | |
52 fprintf(stderr, "MAXTOTTITLES too small\n"); | |
53 exit(1); | |
54 } | |
55 alltitles[ntitles++] = topic_gettitle(topics[i], j); | |
56 } | |
57 } | |
58 | |
59 qsort(alltitles, ntitles, sizeof(alltitles[0]), titlesort); | |
60 | |
61 // check for dups | |
62 for (i=1; i<ntitles; i++) { | |
63 if (!strcasecmp(alltitles[i], alltitles[i-1])) { | |
64 fprintf(stderr, "Duplicate title %s\n", alltitles[i]); | |
65 bad = 1; | |
66 } | |
67 } | |
68 | |
69 // check refs | |
70 for (i=0; i<ntopics; i++) { | |
71 n = topic_getnumrefs(topics[i]); | |
72 for (j=0; j<n; j++) { | |
73 const char *ref; | |
74 const void *result; | |
75 | |
76 ref = topic_getref(topics[i], j); | |
77 result = bsearch(ref, alltitles, ntitles, sizeof(alltitles[0]), | |
78 titlefind); | |
79 if (!result) { | |
80 char *ref2; | |
81 size_t reflen; | |
82 | |
83 reflen = strlen(ref); | |
84 ref2 = dostrdup(ref); | |
85 if (reflen > 0 && ref2[reflen-1]=='s') { | |
86 ref2[reflen-1] = 0; | |
87 result = bsearch(ref2, alltitles, ntitles, sizeof(alltitles[0]), | |
88 titlefind); | |
89 } | |
90 free(ref2); | |
91 } | |
92 | |
93 if (!result) { | |
94 fprintf(stderr, "Dangling crossreference %s from %s\n", ref, | |
95 topic_gettitle(topics[i], 0)); | |
96 bad = 1; | |
97 } | |
98 } | |
99 } | |
100 | |
101 if (bad) { | |
102 exit(1); | |
103 } | |
104 } | |
105 | |
106 //////////////////////////////////////////////////////////// | |
107 | |
108 static void usage(const char *av0) { | |
109 fprintf(stderr, "usage: %s [-t type] infile outfile\n", av0); | |
110 fprintf(stderr, " type may be: c html\n"); | |
111 exit(1); | |
112 } | |
113 | |
114 int main(int argc, char *argv[]) { | |
115 void (*outfunc)(const char *, struct topic **, int); | |
116 const char *outputtype = "c"; | |
117 int ch; | |
118 | |
119 while ((ch = getopt(argc, argv, "t:"))!=-1) { | |
120 switch (ch) { | |
121 case 't': outputtype = optarg; break; | |
122 default: usage(argv[0]); break; | |
123 } | |
124 } | |
125 if (optind != argc-2) { | |
126 usage(argv[0]); | |
127 } | |
128 | |
129 const char *infile = argv[optind++]; | |
130 const char *outfile = argv[optind++]; | |
131 | |
132 if (!strcmp(outputtype, "c")) { | |
133 outfunc = cout; | |
134 } | |
135 else if (!strcmp(outputtype, "html")) { | |
136 outfunc = htmlout; | |
137 } | |
138 else { | |
139 usage(argv[0]); | |
140 } | |
141 | |
142 load(infile); | |
143 checkxrefs(); | |
144 outfunc(outfile, topics, ntopics); | |
145 | |
146 return 0; | |
147 } |