1 /*
2 *
3 * Copyright (c) 1996-2002, Darren Hiebert
4 * Copyright (c) 2016, Red Hat, Inc.
5 * Copyright (c) 2016, Masatake YAMATO
6 *
7 * Author: Masatake YAMATO <yamato@redhat.com>
8 *
9 * This source code is released for free distribution under the terms of the
10 * GNU General Public License version 2 or (at your option) any later version.
11 *
12 */
13
14 #include "general.h" /* must always come first */
15
16 #include "colprint_p.h"
17 #include "ctags.h"
18 #include "debug.h"
19 #include "entry_p.h"
20 #include "options_p.h"
21 #include "parse_p.h"
22 #include "ptag_p.h"
23 #include "routines_p.h"
24 #include "writer_p.h"
25 #include <string.h>
26
27
ptagMakeFormat(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data CTAGS_ATTR_UNUSED)28 static bool ptagMakeFormat (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,
29 const void *data CTAGS_ATTR_UNUSED)
30 {
31 char format [11];
32 const char *formatComment = "unknown format";
33 const optionValues *opt = data;
34
35 sprintf (format, "%u", opt->tagFileFormat);
36 if (opt->tagFileFormat == 1)
37 formatComment = "original ctags format";
38 else if (opt->tagFileFormat == 2)
39 formatComment =
40 "extended format; --format=1 will not append ;\" to lines";
41 return writePseudoTag (desc, format, formatComment, NULL);
42 }
43
ptagMakeHowSorted(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data CTAGS_ATTR_UNUSED)44 static bool ptagMakeHowSorted (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,
45 const void *data CTAGS_ATTR_UNUSED)
46 {
47 const optionValues *opt = data;
48 return writePseudoTag (desc,
49 opt->sorted == SO_FOLDSORTED ? "2" :
50 (opt->sorted == SO_SORTED ? "1" : "0"),
51 "0=unsorted, 1=sorted, 2=foldcase",
52 NULL);
53 }
54
ptagMakeAuthor(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data CTAGS_ATTR_UNUSED)55 static bool ptagMakeAuthor (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,
56 const void *data CTAGS_ATTR_UNUSED)
57 {
58 return writePseudoTag (desc,
59 AUTHOR_NAME, "", NULL);
60 }
61
ptagMakeProgName(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data CTAGS_ATTR_UNUSED)62 static bool ptagMakeProgName (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,
63 const void *data CTAGS_ATTR_UNUSED)
64 {
65 return writePseudoTag (desc,
66 PROGRAM_NAME, "Derived from Exuberant Ctags", NULL);
67 }
68
ptagMakeProgURL(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data CTAGS_ATTR_UNUSED)69 static bool ptagMakeProgURL (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,
70 const void *data CTAGS_ATTR_UNUSED)
71 {
72 return writePseudoTag (desc,
73 PROGRAM_URL, "official site", NULL);
74 }
75
ptagMakeProgVersion(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data CTAGS_ATTR_UNUSED)76 static bool ptagMakeProgVersion (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,
77 const void *data CTAGS_ATTR_UNUSED)
78 {
79 const char* repoinfo = ctags_repoinfo? ctags_repoinfo: "";
80 return writePseudoTag (desc, PROGRAM_VERSION, repoinfo, NULL);
81 }
82
83 #ifdef HAVE_ICONV
ptagMakeFileEncoding(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data)84 static bool ptagMakeFileEncoding (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,
85 const void *data)
86 {
87 const optionValues *opt = data;
88 if (! opt->outputEncoding)
89 return false;
90
91 return writePseudoTag (desc, opt->outputEncoding, "", NULL);
92 }
93 #endif
94
ptagMakeKindSeparators(ptagDesc * desc,langType language,const void * data CTAGS_ATTR_UNUSED)95 static bool ptagMakeKindSeparators (ptagDesc *desc, langType language,
96 const void *data CTAGS_ATTR_UNUSED)
97 {
98 return makeKindSeparatorsPseudoTags (language, desc);
99 }
100
ptagMakeKindDescriptions(ptagDesc * desc,langType language,const void * data CTAGS_ATTR_UNUSED)101 static bool ptagMakeKindDescriptions (ptagDesc *desc, langType language,
102 const void *data CTAGS_ATTR_UNUSED)
103 {
104 return makeKindDescriptionsPseudoTags (language, desc);
105 }
106
ptagMakeFieldDescriptions(ptagDesc * desc,langType language,const void * data CTAGS_ATTR_UNUSED)107 static bool ptagMakeFieldDescriptions (ptagDesc *desc, langType language,
108 const void *data CTAGS_ATTR_UNUSED)
109 {
110 return makeFieldDescriptionsPseudoTags (language, desc);
111 }
112
ptagMakeExtraDescriptions(ptagDesc * desc,langType language,const void * data CTAGS_ATTR_UNUSED)113 static bool ptagMakeExtraDescriptions (ptagDesc *desc, langType language,
114 const void *data CTAGS_ATTR_UNUSED)
115 {
116 return makeExtraDescriptionsPseudoTags (language, desc);
117 }
118
ptagMakeRoleDescriptions(ptagDesc * desc,langType language,const void * data CTAGS_ATTR_UNUSED)119 static bool ptagMakeRoleDescriptions (ptagDesc *desc, langType language,
120 const void *data CTAGS_ATTR_UNUSED)
121 {
122 return makeRoleDescriptionsPseudoTags (language, desc);
123 }
124
ptagMakeProcCwd(ptagDesc * desc,langType language,const void * data CTAGS_ATTR_UNUSED)125 static bool ptagMakeProcCwd (ptagDesc *desc, langType language,
126 const void *data CTAGS_ATTR_UNUSED)
127 {
128 return writePseudoTag (desc, CurrentDirectory, "", NULL);
129 }
130
131 static ptagDesc ptagDescs [] = {
132 {
133 /* The prefix is not "TAG_".
134 Only --output-format=json use this ptag. */
135 false, "JSON_OUTPUT_VERSION",
136 "the version of json output stream format",
137 ptagMakeJsonOutputVersion,
138 PTAGF_COMMON },
139 { true, "TAG_FILE_FORMAT",
140 "the version of tags file format",
141 ptagMakeFormat,
142 PTAGF_COMMON },
143 { true, "TAG_FILE_SORTED",
144 "how tags are sorted",
145 ptagMakeHowSorted,
146 PTAGF_COMMON },
147 { true, "TAG_PROGRAM_AUTHOR",
148 "the author of this ctags implementation",
149 ptagMakeAuthor,
150 PTAGF_COMMON },
151 { true, "TAG_PROGRAM_NAME",
152 "the name of this ctags implementation",
153 ptagMakeProgName,
154 PTAGF_COMMON },
155 { true, "TAG_PROGRAM_URL",
156 "the official site URL of this ctags implementation",
157 ptagMakeProgURL,
158 PTAGF_COMMON },
159 { true, "TAG_PROGRAM_VERSION",
160 "the version of this ctags implementation",
161 ptagMakeProgVersion,
162 PTAGF_COMMON },
163 #ifdef HAVE_ICONV
164 { true, "TAG_FILE_ENCODING",
165 "the encoding used in output tags file",
166 ptagMakeFileEncoding,
167 PTAGF_COMMON },
168 #endif
169 { false, "TAG_KIND_SEPARATOR",
170 "the separators used in kinds",
171 ptagMakeKindSeparators,
172 PTAGF_PARSER },
173 { false, "TAG_KIND_DESCRIPTION",
174 "the letters, names and descriptions of enabled kinds in the language",
175 ptagMakeKindDescriptions,
176 PTAGF_PARSER },
177 { false, "TAG_FIELD_DESCRIPTION",
178 "the names and descriptions of enabled fields",
179 ptagMakeFieldDescriptions,
180 PTAGF_COMMON|PTAGF_PARSER },
181 { false, "TAG_EXTRA_DESCRIPTION",
182 "the names and descriptions of enabled extras",
183 ptagMakeExtraDescriptions,
184 PTAGF_COMMON|PTAGF_PARSER },
185 { false, "TAG_ROLE_DESCRIPTION",
186 "the names and descriptions of enabled roles",
187 ptagMakeRoleDescriptions,
188 PTAGF_PARSER },
189 { true, "TAG_OUTPUT_MODE",
190 "the output mode: u-ctags or e-ctags",
191 ptagMakeCtagsOutputMode,
192 PTAGF_COMMON },
193 { true, "TAG_OUTPUT_FILESEP",
194 "the separator used in file name (slash or backslash)",
195 ptagMakeCtagsOutputFilesep,
196 PTAGF_COMMON },
197 { true, "TAG_PATTERN_LENGTH_LIMIT",
198 "the limit of pattern length",
199 ptagMakePatternLengthLimit,
200 PTAGF_COMMON },
201 { true, "TAG_PROC_CWD",
202 "the current working directory of the tags generator",
203 ptagMakeProcCwd,
204 PTAGF_COMMON },
205 { true, "TAG_OUTPUT_EXCMD",
206 "the excmd: number, pattern, mixed, or combine",
207 ptagMakeCtagsOutputExcmd,
208 PTAGF_COMMON },
209 };
210
makePtagIfEnabled(ptagType type,langType language,const void * data)211 extern bool makePtagIfEnabled (ptagType type, langType language, const void *data)
212 {
213 ptagDesc *desc;
214
215 Assert (0 <= type && type < PTAG_COUNT);
216
217 desc = ptagDescs + type;
218 if (desc->enabled)
219 return desc->makeTag (desc, language, data);
220 else
221 return false;
222 }
223
isPtagEnabled(ptagType type)224 extern bool isPtagEnabled (ptagType type)
225 {
226 ptagDesc *desc;
227
228 Assert (0 <= type && type < PTAG_COUNT);
229
230 desc = ptagDescs + type;
231 return desc->enabled;
232
233 }
234
enablePtag(ptagType type,bool state)235 extern bool enablePtag (ptagType type, bool state)
236 {
237 bool oldstate;
238 ptagDesc *desc;
239
240 Assert (0 <= type && type < PTAG_COUNT);
241
242 desc = ptagDescs + type;
243 oldstate = desc->enabled;
244 desc->enabled = state;
245 return oldstate;
246 }
247
getPtagDesc(ptagType type)248 extern ptagDesc* getPtagDesc (ptagType type)
249 {
250 if (type == PTAG_UNKNOWN
251 || type >= PTAG_COUNT)
252 return NULL;
253
254 return ptagDescs + type;
255 }
256
getPtagTypeForName(const char * name)257 extern ptagType getPtagTypeForName (const char *name)
258 {
259 int i;
260
261 Assert (name);
262 for (i = 0; i < PTAG_COUNT; i++)
263 if (strcmp (ptagDescs [i].name, name) == 0)
264 return i;
265 return PTAG_UNKNOWN;
266 }
267
isPtagCommonInParsers(ptagType type)268 extern bool isPtagCommonInParsers (ptagType type)
269 {
270 ptagDesc* pdesc = getPtagDesc (type);
271 return pdesc->flags & PTAGF_COMMON;
272 }
273
isPtagParserSpecific(ptagType type)274 extern bool isPtagParserSpecific (ptagType type)
275 {
276 ptagDesc* pdesc = getPtagDesc (type);
277 return pdesc->flags & PTAGF_PARSER;
278 }
279
ptagCompare(struct colprintLine * a,struct colprintLine * b)280 static int ptagCompare (struct colprintLine *a, struct colprintLine *b)
281 {
282 const char *a_name = colprintLineGetColumn (a, 0);
283 const char *b_name = colprintLineGetColumn (b, 0);
284 return strcmp(a_name, b_name);
285 }
286
printPtags(bool withListHeader,bool machinable,FILE * fp)287 extern void printPtags (bool withListHeader, bool machinable, FILE *fp)
288 {
289 struct colprintTable *table = colprintTableNew ("L:NAME",
290 "L:ENABLED",
291 "L:DESCRIPTION",
292 NULL);
293 for (unsigned int i = 0; i < PTAG_COUNT; i++)
294 {
295 struct colprintLine *line = colprintTableGetNewLine (table);
296 colprintLineAppendColumnCString (line, ptagDescs[i].name);
297 colprintLineAppendColumnCString (line, ptagDescs[i].enabled
298 ? "on"
299 : "off");
300 colprintLineAppendColumnCString (line, ptagDescs[i].description);
301 }
302
303 colprintTableSort (table, ptagCompare);
304 colprintTablePrint (table, 0, withListHeader, machinable, fp);
305 colprintTableDelete (table);
306 }
307