/* */
This source file includes following definitions.
- makedefineindex
1 /*
2 * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005,
3 * 2010
4 * Tama Communications Corporation
5 *
6 * This file is part of GNU GLOBAL.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <ctype.h>
25 #include <stdio.h>
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #else
29 #include <strings.h>
30 #endif
31 #include "queue.h"
32 #include "global.h"
33 #include "cache.h"
34 #include "htags.h"
35 #include "path2url.h"
36 #include "common.h"
37
38 /**
39 * makedefineindex: make definition index (including alphabetic index)
40 *
41 * @param[in] file definition index file
42 * @param[in] total definitions total
43 * @param[out] defines \@defines
44 * @par Globals used (input):
45 * tag cache XXX: should this be global output, not input?
46 */
47 int
48 makedefineindex(const char *file, int total, STRBUF *defines)
49 {
50 int count = 0;
51 int alpha_count = 0;
52 FILEOP *fileop_MAP = NULL, *fileop_DEFINES, *fileop_ALPHA = NULL;
53 FILE *MAP = NULL;
54 FILE *DEFINES, *STDOUT, *TAGS, *ALPHA = NULL;
55 STRBUF *sb = strbuf_open(0);
56 STRBUF *url = strbuf_open(0);
57 /* Index link */
58 const char *target = (Fflag) ? "mains" : "_top";
59 const char *indexlink;
60 const char *index_string = "Index Page";
61 char command[1024], buf[1024], alpha[32], alpha_f[32], *_;
62
63 if (!aflag && !Fflag)
64 indexlink = "mains";
65 else if (Fflag)
66 indexlink = "../defines";
67 else
68 indexlink = "../mains";
69
70 if (map_file) {
71 fileop_MAP = open_output_file(makepath(distpath, "MAP", NULL), 0);
72 MAP = get_descripter(fileop_MAP);
73 }
74 fileop_DEFINES = open_output_file(makepath(distpath, file, NULL), 0);
75 DEFINES = get_descripter(fileop_DEFINES);
76 fputs_nl(gen_page_begin(title_define_index, TOPDIR), DEFINES);
77 fputs_nl(body_begin, DEFINES);
78 fputs(header_begin, DEFINES);
79 if (Fflag)
80 fputs(gen_href_begin(NULL, "defines", normal_suffix, NULL), DEFINES);
81 fputs(title_define_index, DEFINES);
82 if (Fflag)
83 fputs(gen_href_end(), DEFINES);
84 fputs_nl(header_end, DEFINES);
85 if (!aflag && !Fflag) {
86 fputs(gen_href_begin_with_title(NULL, indexlink, normal_suffix, NULL, index_string), DEFINES);
87 if (Iflag)
88 fputs(gen_image(CURRENT, back_icon, ".."), DEFINES);
89 else
90 fputs("[..]", DEFINES);
91 fputs_nl(gen_href_end(), DEFINES);
92 }
93 if (!aflag) {
94 if (!no_order_list)
95 fputs_nl(list_begin, DEFINES);
96 }
97 /*
98 * map DEFINES to STDOUT.
99 */
100 STDOUT = DEFINES;
101 snprintf(command, sizeof(command), PQUOTE "%s -c" PQUOTE, quote_shell(global_path));
102 if ((TAGS = popen(command, "r")) == NULL)
103 die("cannot fork.");
104 alpha[0] = '\0';
105 while ((_ = strbuf_fgets(sb, TAGS, STRBUF_NOCRLF)) != NULL) {
106 const char *tag, *line;
107 char guide[1024], url_for_map[1024];
108
109 count++;
110 tag = _;
111 message(" [%d/%d] adding %s", count, total, tag);
112 if (aflag && (alpha[0] == '\0' || !locatestring(tag, alpha, MATCH_AT_FIRST))) {
113 const char *msg = (alpha_count == 1) ? "definition" : "definitions";
114 int c;
115
116 if (alpha[0]) {
117 char tmp[128];
118 snprintf(tmp, sizeof(tmp), "%d %s", alpha_count, msg);
119 strbuf_puts(defines, gen_href_begin_with_title("defines", alpha_f, HTML, NULL, tmp));
120 strbuf_sprintf(defines, "[%s]", alpha);
121 strbuf_puts_nl(defines, gen_href_end());
122 alpha_count = 0;
123 if (!no_order_list)
124 fputs_nl(list_end, ALPHA);
125 else
126 fputs_nl(br, ALPHA);
127 fputs(gen_href_begin_with_title(NULL, indexlink, normal_suffix, NULL, index_string), ALPHA);
128 if (Iflag)
129 fputs(gen_image(PARENT, back_icon, ".."), ALPHA);
130 else
131 fputs("[..]", ALPHA);
132 fputs_nl(gen_href_end(), ALPHA);
133 fputs_nl(body_end, ALPHA);
134 fputs_nl(gen_page_end(), ALPHA);
135 close_file(fileop_ALPHA);
136 html_count++;
137 }
138 /*
139 * setup index char (for example, 'a' of '[a]').
140 * alpha is used for display.
141 * alpha_f is used for part of path.
142 */
143 c = (unsigned char)*tag;
144 if (c > 127) {
145 int i2 = *(tag + 1) & 0xff;
146 /*
147 * for multi-byte(EUC) code.
148 */
149 alpha[0] = *tag;
150 alpha[1] = *(tag + 1);
151 alpha[2] = '\0';
152 snprintf(alpha_f, sizeof(alpha_f), "%03d%03d", c, i2);
153 } else if (isalpha(c) || c == '_') {
154 alpha[0] = *tag;
155 alpha[1] = '\0';
156 /*
157 * for CD9660 or FAT file system
158 */
159 if (islower(c)) {
160 alpha_f[0] = 'l';
161 alpha_f[1] = *tag;
162 alpha_f[2] = '\0';
163 } else {
164 alpha_f[0] = *tag;
165 alpha_f[1] = '\0';
166 }
167 } else {
168 alpha[0] = *tag;
169 alpha[1] = '\0';
170 snprintf(alpha_f, sizeof(alpha_f), "%03d", c);
171 }
172 snprintf(buf, sizeof(buf), "%s/defines/%s.%s", distpath, alpha_f, HTML);
173 fileop_ALPHA = open_output_file(buf, cflag);
174 ALPHA = get_descripter(fileop_ALPHA);
175 snprintf(buf, sizeof(buf), "[%s]", alpha);
176 fputs_nl(gen_page_begin(buf, SUBDIR), ALPHA);
177 fputs_nl(body_begin, ALPHA);
178 fprintf(ALPHA, "%s[%s]%s\n", header_begin, alpha, header_end);
179 fputs(gen_href_begin_with_title(NULL, indexlink, normal_suffix, NULL, index_string), ALPHA);
180 if (Iflag)
181 fputs(gen_image(PARENT, back_icon, ".."), ALPHA);
182 else
183 fputs("[..]", ALPHA);
184 fputs_nl(gen_href_end(), ALPHA);
185 if (!no_order_list)
186 fputs_nl(list_begin, ALPHA);
187 else
188 fprintf(ALPHA, "%s%s\n", br, br);
189 STDOUT = ALPHA;
190 }
191 alpha_count++;
192 /*
193 * generating url for function definition.
194 */
195 line = cache_get(GTAGS, tag);
196 strbuf_reset(url);
197
198 if (line == NULL)
199 die("internal error in makedefineindex().");
200 /*
201 * About the format of 'line', please see the head comment of cache.c.
202 */
203 if (*line == ' ') {
204 const char *fid = line + 1;
205 const char *enumber = nextstring(fid);
206
207 snprintf(url_for_map, sizeof(url_for_map), "%s/%s.%s",
208 DEFS, fid, HTML);
209 if (dynamic) {
210 if (*action != '/' && aflag)
211 strbuf_puts(url, "../");
212 strbuf_puts(url, action);
213 strbuf_sprintf(url, "?pattern=%s%stype=definitions", tag, quote_amp);
214 } else {
215 if (aflag)
216 strbuf_puts(url, "../");
217 strbuf_sprintf(url, "%s/%s.%s", DEFS, fid, HTML);
218 }
219 snprintf(guide, sizeof(guide), "Multiple defined in %s places.", enumber);
220 } else {
221 const char *lno = line;
222 const char *fid = nextstring(line);
223 const char *path = gpath_fid2path(fid, NULL);
224
225 path += 2; /* remove './' */
226 snprintf(url_for_map, sizeof(url_for_map), "%s/%s.%s#L%s",
227 SRCS, fid, HTML, lno);
228 if (aflag)
229 strbuf_puts(url, "../");
230 strbuf_sprintf(url, "%s/%s.%s#L%s", SRCS, fid, HTML, lno);
231 snprintf(guide, sizeof(guide), "Defined at %s in %s.", lno, path);
232 }
233 if (!no_order_list)
234 fputs(item_begin, STDOUT);
235 fputs(gen_href_begin_with_title_target(NULL, strbuf_value(url), NULL, NULL, guide, target), STDOUT);
236 fputs(tag, STDOUT);
237 fputs(gen_href_end(), STDOUT);
238 if (!no_order_list)
239 fputs(item_end, STDOUT);
240 else
241 fputs(br, STDOUT);
242 fputc('\n', STDOUT);
243 if (map_file)
244 fprintf(MAP, "%s\t%s\n", tag, url_for_map);
245 }
246 if (pclose(TAGS) != 0)
247 die("'%s' failed.", command);
248 if (aflag && alpha[0]) {
249 char tmp[128];
250 const char *msg = (alpha_count == 1) ? "definition" : "definitions";
251
252 snprintf(tmp, sizeof(tmp), "%d %s", alpha_count, msg);
253 strbuf_puts(defines, gen_href_begin_with_title("defines", alpha_f, HTML, NULL, tmp));
254 strbuf_sprintf(defines, "[%s]", alpha);
255 strbuf_puts_nl(defines, gen_href_end());
256 if (!no_order_list)
257 fputs_nl(list_end, ALPHA);
258 else
259 fputs_nl(br, ALPHA);
260 fputs(gen_href_begin_with_title(NULL, indexlink, normal_suffix, NULL, index_string), ALPHA);
261 if (Iflag)
262 fputs(gen_image(PARENT, back_icon, ".."), ALPHA);
263 else
264 fputs("[..]", ALPHA);
265 fputs_nl(gen_href_end(), ALPHA);
266 fputs_nl(body_end, ALPHA);
267 fputs_nl(gen_page_end(), ALPHA);
268 close_file(fileop_ALPHA);
269 html_count++;
270
271 fputs(strbuf_value(defines), DEFINES);
272 }
273 if (!no_order_list && !aflag)
274 fputs_nl(list_end, DEFINES);
275 if (!aflag && !Fflag) {
276 fputs(gen_href_begin_with_title(NULL, "mains", normal_suffix, NULL, index_string), DEFINES);
277 if (Iflag)
278 fputs(gen_image(CURRENT, back_icon, ".."), DEFINES);
279 else
280 fputs("[..]", DEFINES);
281 fputs_nl(gen_href_end(), DEFINES);
282 }
283 fputs_nl(body_end, DEFINES);
284 fputs_nl(gen_page_end(), DEFINES);
285 close_file(fileop_DEFINES);
286 html_count++;
287 if (map_file)
288 close_file(fileop_MAP);
289 strbuf_close(sb);
290 strbuf_close(url);
291 return count;
292 }
/* */