/* */
This source file includes following definitions.
- makedupindex
1 /*
2 * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2010
3 * Tama Communications Corporation
4 *
5 * This file is part of GNU GLOBAL.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #else
27 #include <strings.h>
28 #endif
29 #include "cache.h"
30 #include "common.h"
31 #include "global.h"
32 #include "htags.h"
33
34 /*
35 * Data for each tag file.
36 *
37 * GTAGS GRTAGS GSYMS
38 */
39 static const char *dirs[] = {NULL, DEFS, REFS, SYMS};
40 static const char *kinds[] = {NULL, "definition", "reference", "symbol"};
41 static const char *options[] = {NULL, "", "r", "s"};
42
43 /**
44 * Make duplicate object index.
45 *
46 * If referred tag is only one, direct link which points the tag is generated.
47 * Else if two or more tag exists, indirect link which points the tag list
48 * is generated.
49 */
50 int
51 makedupindex(void)
52 {
53 STRBUF *sb = strbuf_open(0);
54 STRBUF *tmp = strbuf_open(0);
55 STRBUF *command = strbuf_open(0);
56 int definition_count = 0;
57 char srcdir[MAXPATHLEN];
58 int db;
59 FILEOP *fileop = NULL;
60 FILE *op = NULL;
61 FILE *ip = NULL;
62
63 snprintf(srcdir, sizeof(srcdir), "../%s", SRCS);
64 for (db = GTAGS; db < GTAGLIM; db++) {
65 const char *kind = kinds[db];
66 const char *option = options[db];
67 int writing = 0;
68 int count = 0;
69 int entry_count = 0;
70 const char *ctags_xid, *ctags_x;
71 char tag[IDENTLEN], prev[IDENTLEN], first_line[MAXBUFLEN];
72
73 if (gtags_exist[db] == 0)
74 continue;
75 prev[0] = 0;
76 first_line[0] = 0;
77 /*
78 * construct command line.
79 */
80 strbuf_reset(command);
81 #if defined(_WIN32) && !defined(__CYGWIN__)
82 strbuf_putc(command, '"');
83 #endif
84 strbuf_sprintf(command, "%s -x%s --result=ctags-xid --encode-path=\" \t\" --nofilter=path", quote_shell(global_path), option);
85 /*
86 * Optimization when the --dynamic option is specified.
87 */
88 if (dynamic) {
89 strbuf_puts(command, " --nosource");
90 if (db != GSYMS)
91 strbuf_puts(command, " --nofilter=sort");
92 }
93 strbuf_puts(command, " \".*\"");
94 #if defined(_WIN32) && !defined(__CYGWIN__)
95 strbuf_putc(command, '"');
96 #endif
97 if ((ip = popen(strbuf_value(command), "r")) == NULL)
98 die("cannot execute command '%s'.", strbuf_value(command));
99 while ((ctags_xid = strbuf_fgets(sb, ip, STRBUF_NOCRLF)) != NULL) {
100 char fid[MAXFIDLEN];
101
102 ctags_x = parse_xid(ctags_xid, fid, NULL);
103 /* tag name */
104 (void)strcpy_withterm(tag, ctags_x, sizeof(tag), ' ');
105 if (strcmp(prev, tag)) {
106 count++;
107 if (vflag)
108 fprintf(stderr, " [%d] adding %s %s\n", count, kind, tag);
109 if (writing) {
110 if (!dynamic) {
111 fputs_nl(gen_list_end(), op);
112 fputs_nl(body_end, op);
113 fputs_nl(gen_page_end(), op);
114 close_file(fileop);
115 html_count++;
116 }
117 writing = 0;
118 /*
119 * cache record: " <fid>\0<entry number>\0"
120 */
121 strbuf_reset(tmp);
122 strbuf_putc(tmp, ' ');
123 strbuf_putn(tmp, count - 1);
124 strbuf_putc(tmp, '\0');
125 strbuf_putn(tmp, entry_count);
126 cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
127 }
128 /* single entry */
129 if (first_line[0]) {
130 char fid[MAXFIDLEN];
131 const char *ctags_x = parse_xid(first_line, fid, NULL);
132 const char *lno = nextelement(ctags_x);
133
134 strbuf_reset(tmp);
135 strbuf_puts_withterm(tmp, lno, ' ');
136 strbuf_putc(tmp, '\0');
137 strbuf_puts(tmp, fid);
138 cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
139 }
140 /*
141 * Chop the tail of the line. It is not important.
142 * strlimcpy(first_line, ctags_x, sizeof(first_line));
143 */
144 strncpy(first_line, ctags_xid, sizeof(first_line));
145 first_line[sizeof(first_line) - 1] = '\0';
146 strlimcpy(prev, tag, sizeof(prev));
147 entry_count = 0;
148 } else {
149 /* duplicate entry */
150 if (first_line[0]) {
151 char fid[MAXFIDLEN];
152 const char *ctags_x = parse_xid(first_line, fid, NULL);
153
154 if (!dynamic) {
155 char path[MAXPATHLEN];
156
157 snprintf(path, sizeof(path), "%s/%s/%d.%s", distpath, dirs[db], count, HTML);
158 fileop = open_output_file(path, cflag);
159 op = get_descripter(fileop);
160 fputs_nl(gen_page_begin(tag, SUBDIR), op);
161 fputs_nl(body_begin, op);
162 fputs_nl(gen_list_begin(), op);
163 fputs_nl(gen_list_body(srcdir, ctags_x, fid), op);
164 }
165 writing = 1;
166 entry_count++;
167 first_line[0] = 0;
168 }
169 if (!dynamic) {
170 fputs_nl(gen_list_body(srcdir, ctags_x, fid), op);
171 }
172 entry_count++;
173 }
174 }
175 if (db == GTAGS)
176 definition_count = count;
177 if (pclose(ip) != 0)
178 die("'%s' failed.", strbuf_value(command));
179 if (writing) {
180 if (!dynamic) {
181 fputs_nl(gen_list_end(), op);
182 fputs_nl(body_end, op);
183 fputs_nl(gen_page_end(), op);
184 close_file(fileop);
185 html_count++;
186 }
187 /*
188 * cache record: " <fid>\0<entry number>\0"
189 */
190 strbuf_reset(tmp);
191 strbuf_putc(tmp, ' ');
192 strbuf_putn(tmp, count);
193 strbuf_putc(tmp, '\0');
194 strbuf_putn(tmp, entry_count);
195 cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
196 }
197 if (first_line[0]) {
198 char fid[MAXFIDLEN];
199 const char *ctags_x = parse_xid(first_line, fid, NULL);
200 const char *lno = nextelement(ctags_x);
201
202 strbuf_reset(tmp);
203 strbuf_puts_withterm(tmp, lno, ' ');
204 strbuf_putc(tmp, '\0');
205 strbuf_puts(tmp, fid);
206 cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
207 }
208 }
209 strbuf_close(sb);
210 strbuf_close(tmp);
211 strbuf_close(command);
212 return definition_count;
213 }
/* */