xref: /Universal-ctags/main/writer.c (revision c0421c5ec596b5f2a3e1a16a61d6ee3368a68842)
1 /*
2 *   Copyright (c) 2016, Red Hat, Inc.
3 *   Copyright (c) 2016, Masatake YAMATO
4 *
5 *   This source code is released for free distribution under the terms of the
6 *   GNU General Public License version 2 or (at your option) any later version.
7 *
8 */
9 
10 #include "general.h"
11 
12 #include "debug.h"
13 #include "entry_p.h"
14 #include "options_p.h"
15 #include "writer_p.h"
16 
17 extern tagWriter uCtagsWriter;
18 extern tagWriter eCtagsWriter;
19 extern tagWriter etagsWriter;
20 extern tagWriter xrefWriter;
21 extern tagWriter jsonWriter;
22 
23 static tagWriter *writerTable [WRITER_COUNT] = {
24 	[WRITER_U_CTAGS] = &uCtagsWriter,
25 	[WRITER_E_CTAGS] = &eCtagsWriter,
26 	[WRITER_ETAGS] = &etagsWriter,
27 	[WRITER_XREF]  = &xrefWriter,
28 	[WRITER_JSON]  = &jsonWriter,
29 	[WRITER_CUSTOM] = NULL,
30 };
31 
32 static tagWriter *writer;
33 
setTagWriter(writerType wtype,tagWriter * customWriter)34 extern void setTagWriter (writerType wtype, tagWriter *customWriter)
35 {
36 	if (wtype != WRITER_CUSTOM)
37 		writer = writerTable [wtype];
38 	else
39 		writer = customWriter;
40 	writer->type = wtype;
41 }
42 
writerSetup(MIO * mio,void * clientData)43 extern void writerSetup (MIO *mio, void *clientData)
44 {
45 	writer->clientData = clientData;
46 
47 	if (writer->preWriteEntry)
48 		writer->private = writer->preWriteEntry (writer, mio,
49 												 writer->clientData);
50 	else
51 		writer->private = NULL;
52 }
53 
writerTeardown(MIO * mio,const char * filename)54 extern bool writerTeardown (MIO *mio, const char *filename)
55 {
56 	if (writer->postWriteEntry)
57 	{
58 		bool r;
59 		r = writer->postWriteEntry (writer, mio, filename,
60 									writer->clientData);
61 		writer->private = NULL;
62 		return r;
63 	}
64 	return false;
65 }
66 
writerWriteTag(MIO * mio,const tagEntryInfo * const tag)67 extern int writerWriteTag (MIO * mio, const tagEntryInfo *const tag)
68 {
69 	return writer->writeEntry (writer, mio, tag,
70 							   writer->clientData);
71 }
72 
writerWritePtag(MIO * mio,const ptagDesc * desc,const char * const fileName,const char * const pattern,const char * const parserName)73 extern int writerWritePtag (MIO * mio,
74 					 const ptagDesc *desc,
75 					 const char *const fileName,
76 					 const char *const pattern,
77 					 const char *const parserName)
78 {
79 	if (writer->writePtagEntry == NULL)
80 		return -1;
81 
82 	return writer->writePtagEntry (writer, mio, desc, fileName,
83 								   pattern, parserName,
84 								   writer->clientData);
85 
86 }
87 
writerRescanFailed(unsigned long validTagNum)88 extern void writerRescanFailed (unsigned long validTagNum)
89 {
90 	if (writer->rescanFailedEntry)
91 		writer->rescanFailedEntry(writer, validTagNum, writer->clientData);
92 }
93 
ptagMakeCtagsOutputMode(ptagDesc * desc,langType langType CTAGS_ATTR_UNUSED,const void * data CTAGS_ATTR_UNUSED)94 extern bool ptagMakeCtagsOutputMode (ptagDesc *desc, langType langType CTAGS_ATTR_UNUSED,
95 									 const void *data CTAGS_ATTR_UNUSED)
96 {
97 	const char *mode ="";
98 
99 	if (&uCtagsWriter == writer)
100 		mode = "u-ctags";
101 	else if (&eCtagsWriter == writer)
102 		mode = "e-ctags";
103 
104 	return writePseudoTag (desc,
105 						   mode,
106 						   "u-ctags or e-ctags",
107 						   NULL);
108 }
109 
outputDefaultFileName(void)110 extern const char *outputDefaultFileName (void)
111 {
112 	return writer->defaultFileName;
113 }
114 
writerCanPrintPtag(void)115 extern bool writerCanPrintPtag (void)
116 {
117 	return (writer->writePtagEntry)? true: false;
118 }
119 
writerDoesTreatFieldAsFixed(int fieldType)120 extern bool writerDoesTreatFieldAsFixed (int fieldType)
121 {
122 	if (writer->treatFieldAsFixed)
123 		return writer->treatFieldAsFixed (fieldType);
124 	return false;
125 }
126 
127 #ifdef WIN32
getFilenameSeparator(enum filenameSepOp currentSetting)128 extern enum filenameSepOp getFilenameSeparator (enum filenameSepOp currentSetting)
129 {
130 	if (writer->overrideFilenameSeparator)
131 		return writer->overrideFilenameSeparator (currentSetting);
132 	return currentSetting;
133 }
134 #endif
135 
ptagMakeCtagsOutputFilesep(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data)136 extern bool ptagMakeCtagsOutputFilesep (ptagDesc *desc,
137 										langType language CTAGS_ATTR_UNUSED,
138 										const void *data)
139 {
140 	const char *sep = "slash";
141 #ifdef WIN32
142 	const optionValues *opt = data;
143 	if (getFilenameSeparator (opt->useSlashAsFilenameSeparator)
144 		!= FILENAME_SEP_USE_SLASH)
145 		sep = "backslash";
146 #endif
147 	return writePseudoTag (desc, sep, "slash or backslash", NULL);
148 }
149 
ptagMakeCtagsOutputExcmd(ptagDesc * desc,langType language CTAGS_ATTR_UNUSED,const void * data)150 extern bool ptagMakeCtagsOutputExcmd (ptagDesc *desc,
151 									  langType language CTAGS_ATTR_UNUSED,
152 									  const void *data)
153 {
154 	const char *excmd;
155 	const optionValues *opt = data;
156 	switch (opt->locate)
157 	{
158 	case EX_MIX:
159 		excmd = "mixed";
160 		break;
161 	case EX_LINENUM:
162 		excmd = "number";
163 		break;
164 	case EX_PATTERN:
165 		excmd = "pattern";
166 		break;
167 	case EX_COMBINE:
168 		excmd = "combineV2";
169 		break;
170 	default:
171 		AssertNotReached ();
172 		excmd = "bug!";
173 		break;
174 	}
175 	return writePseudoTag (desc, excmd,
176 						   "number, pattern, mixed, or combineV2",
177 						   NULL);
178 }
179 
writerCheckOptions(bool fieldsWereReset)180 extern void writerCheckOptions (bool fieldsWereReset)
181 {
182 	if (writer->checkOptions)
183 		writer->checkOptions (writer, fieldsWereReset);
184 }
185 
writerPrintPtagByDefault(void)186 extern bool writerPrintPtagByDefault (void)
187 {
188 	return writer->printPtagByDefault;
189 }
190