xref: /Universal-ctags/main/writer-ctags.c (revision 0b491fdf2257a9d084b3b4e41485d7146b5c4381)
15176f023SMasatake YAMATO /*
25176f023SMasatake YAMATO *   Copyright (c) 1998-2002, Darren Hiebert
35176f023SMasatake YAMATO *
45176f023SMasatake YAMATO *   This source code is released for free distribution under the terms of the
55176f023SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
65176f023SMasatake YAMATO *
75176f023SMasatake YAMATO *   External interface to entry.c
85176f023SMasatake YAMATO */
95176f023SMasatake YAMATO 
105176f023SMasatake YAMATO #include "general.h"  /* must always come first */
115176f023SMasatake YAMATO 
128cbf052bSMasatake YAMATO #include "entry_p.h"
138182f840SMasatake YAMATO #include "field.h"
14c08c70d0SMasatake YAMATO #include "field_p.h"
155176f023SMasatake YAMATO #include "mio.h"
1621996d92SMasatake YAMATO #include "options_p.h"
170d502ef0SMasatake YAMATO #include "parse_p.h"
180d81da14SMasatake YAMATO #include "ptag_p.h"
190d502ef0SMasatake YAMATO #include "read.h"
20285b4dfeSMasatake YAMATO #include "writer_p.h"
21545d1428SMasatake YAMATO #include "xtag.h"
22545d1428SMasatake YAMATO #include "xtag_p.h"
235176f023SMasatake YAMATO 
245176f023SMasatake YAMATO 
254b7a1543SMasatake YAMATO #define CTAGS_FILE  "tags"
264b7a1543SMasatake YAMATO 
274b7a1543SMasatake YAMATO 
280925aa59SMasatake YAMATO static int writeCtagsEntry (tagWriter *writer CTAGS_ATTR_UNUSED,
295053d6adSMasatake YAMATO 							MIO * mio, const tagEntryInfo *const tag,
305053d6adSMasatake YAMATO 							void *clientData);
310925aa59SMasatake YAMATO static int writeCtagsPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,
320925aa59SMasatake YAMATO 								MIO * mio, const ptagDesc *desc,
335176f023SMasatake YAMATO 								const char *const fileName,
345176f023SMasatake YAMATO 								const char *const pattern,
355053d6adSMasatake YAMATO 								const char *const parserName,
365053d6adSMasatake YAMATO 								void *clientData);
378182f840SMasatake YAMATO static bool treatFieldAsFixed (int fieldType);
38c0421c5eSMasatake YAMATO static void checkCtagsOptions (tagWriter *writer, bool fieldsWereReset);
395176f023SMasatake YAMATO 
40f4904b13SMasatake YAMATO #ifdef WIN32
41f4904b13SMasatake YAMATO static enum filenameSepOp overrideFilenameSeparator (enum filenameSepOp currentSetting);
42f4904b13SMasatake YAMATO #endif	/* WIN32 */
43f4904b13SMasatake YAMATO 
44eadb1895SMasatake YAMATO struct rejection {
45c8ea8819SMasatake YAMATO 	bool rejectionInThisInput;
46eadb1895SMasatake YAMATO };
47eadb1895SMasatake YAMATO 
48039bc97fSMasatake YAMATO tagWriter uCtagsWriter = {
49039bc97fSMasatake YAMATO 	.writeEntry = writeCtagsEntry,
50039bc97fSMasatake YAMATO 	.writePtagEntry = writeCtagsPtagEntry,
51b9636b4dSMasatake YAMATO 	.printPtagByDefault = true,
52039bc97fSMasatake YAMATO 	.preWriteEntry = NULL,
53039bc97fSMasatake YAMATO 	.postWriteEntry = NULL,
5467d1f12fSJiří Techet 	.rescanFailedEntry = NULL,
558182f840SMasatake YAMATO 	.treatFieldAsFixed = treatFieldAsFixed,
56681789f5SMasatake YAMATO 	.checkOptions = checkCtagsOptions,
57f4904b13SMasatake YAMATO #ifdef WIN32
58f4904b13SMasatake YAMATO 	.overrideFilenameSeparator = overrideFilenameSeparator,
59f4904b13SMasatake YAMATO #endif
60039bc97fSMasatake YAMATO 	.defaultFileName = CTAGS_FILE,
61039bc97fSMasatake YAMATO };
62039bc97fSMasatake YAMATO 
beginECtagsFile(tagWriter * writer CTAGS_ATTR_UNUSED,MIO * mio CTAGS_ATTR_UNUSED,void * clientData CTAGS_ATTR_UNUSED)635053d6adSMasatake YAMATO static void *beginECtagsFile (tagWriter *writer CTAGS_ATTR_UNUSED, MIO * mio CTAGS_ATTR_UNUSED,
645053d6adSMasatake YAMATO 							  void *clientData CTAGS_ATTR_UNUSED)
6511705bb3SMasatake YAMATO {
66eadb1895SMasatake YAMATO 	static struct rejection rej;
67eadb1895SMasatake YAMATO 
68c8ea8819SMasatake YAMATO 	rej.rejectionInThisInput = false;
69039bc97fSMasatake YAMATO 
70eadb1895SMasatake YAMATO 	return &rej;
71eadb1895SMasatake YAMATO }
72eadb1895SMasatake YAMATO 
endECTagsFile(tagWriter * writer,MIO * mio CTAGS_ATTR_UNUSED,const char * filename CTAGS_ATTR_UNUSED,void * clientData CTAGS_ATTR_UNUSED)735053d6adSMasatake YAMATO static bool endECTagsFile (tagWriter *writer, MIO * mio CTAGS_ATTR_UNUSED, const char* filename CTAGS_ATTR_UNUSED,
745053d6adSMasatake YAMATO 						   void *clientData CTAGS_ATTR_UNUSED)
75eadb1895SMasatake YAMATO {
76eadb1895SMasatake YAMATO 	struct rejection *rej = writer->private;
77c8ea8819SMasatake YAMATO 	return rej->rejectionInThisInput;
7811705bb3SMasatake YAMATO }
7911705bb3SMasatake YAMATO 
80f4904b13SMasatake YAMATO #ifdef WIN32
overrideFilenameSeparator(enum filenameSepOp currentSetting)81f4904b13SMasatake YAMATO static enum filenameSepOp overrideFilenameSeparator (enum filenameSepOp currentSetting)
82f4904b13SMasatake YAMATO {
83f4904b13SMasatake YAMATO 	if (currentSetting == FILENAME_SEP_UNSET)
84f4904b13SMasatake YAMATO 		return FILENAME_SEP_USE_SLASH;
85f4904b13SMasatake YAMATO 	return currentSetting;
86f4904b13SMasatake YAMATO }
87f4904b13SMasatake YAMATO #endif
88f4904b13SMasatake YAMATO 
89039bc97fSMasatake YAMATO tagWriter eCtagsWriter = {
906ccc5fc9SMasatake YAMATO 	.writeEntry = writeCtagsEntry,
916ccc5fc9SMasatake YAMATO 	.writePtagEntry = writeCtagsPtagEntry,
92b9636b4dSMasatake YAMATO 	.printPtagByDefault = true,
9311705bb3SMasatake YAMATO 	.preWriteEntry = beginECtagsFile,
94eadb1895SMasatake YAMATO 	.postWriteEntry = endECTagsFile,
9567d1f12fSJiří Techet 	.rescanFailedEntry = NULL,
968182f840SMasatake YAMATO 	.treatFieldAsFixed = treatFieldAsFixed,
974b7a1543SMasatake YAMATO 	.defaultFileName = CTAGS_FILE,
98681789f5SMasatake YAMATO 	.checkOptions = checkCtagsOptions,
996ccc5fc9SMasatake YAMATO };
100c77ec5ceSMasatake YAMATO 
hasTagEntryTabOrNewlineChar(const tagEntryInfo * const tag)1010647c2a9SMasatake YAMATO static bool hasTagEntryTabOrNewlineChar (const tagEntryInfo * const tag)
1025176f023SMasatake YAMATO {
103c77ec5ceSMasatake YAMATO 
1040647c2a9SMasatake YAMATO 	if (doesFieldHaveTabOrNewlineChar (FIELD_NAME, tag, NO_PARSER_FIELD)
1050647c2a9SMasatake YAMATO 		|| doesFieldHaveTabOrNewlineChar (FIELD_INPUT_FILE, tag, NO_PARSER_FIELD))
106c77ec5ceSMasatake YAMATO 		return true;
107c77ec5ceSMasatake YAMATO 
108c77ec5ceSMasatake YAMATO 	if (tag->lineNumberEntry)
109eadb1895SMasatake YAMATO 	{
110c77ec5ceSMasatake YAMATO 		if (Option.lineDirectives)
111c77ec5ceSMasatake YAMATO 		{
1120647c2a9SMasatake YAMATO 			if (doesFieldHaveTabOrNewlineChar (FIELD_LINE_NUMBER, tag, NO_PARSER_FIELD))
113c77ec5ceSMasatake YAMATO 				return true;
114c77ec5ceSMasatake YAMATO 		}
115c77ec5ceSMasatake YAMATO 	}
1160647c2a9SMasatake YAMATO 	else if (doesFieldHaveTabOrNewlineChar (FIELD_PATTERN, tag, NO_PARSER_FIELD))
117c77ec5ceSMasatake YAMATO 	{
1180647c2a9SMasatake YAMATO 		/* Pattern may have a tab char. However, doesFieldHaveTabOrNewlineChar returns
119c54f0614SMasatake YAMATO 		 * false because NO_PARSER_FIELD may not have doesContainAnyChar handler.
120c77ec5ceSMasatake YAMATO 		 */
121c77ec5ceSMasatake YAMATO 		return true;
122eadb1895SMasatake YAMATO 	}
1235e272693SMasatake YAMATO 
124c77ec5ceSMasatake YAMATO 	if (includeExtensionFlags ())
125c77ec5ceSMasatake YAMATO 	{
126c77ec5ceSMasatake YAMATO 		if (isFieldEnabled (FIELD_SCOPE) && doesFieldHaveValue (FIELD_SCOPE, tag)
1270647c2a9SMasatake YAMATO 			&& (doesFieldHaveTabOrNewlineChar (FIELD_SCOPE_KIND_LONG, tag, NO_PARSER_FIELD)
1280647c2a9SMasatake YAMATO 				|| doesFieldHaveTabOrNewlineChar (FIELD_SCOPE, tag, NO_PARSER_FIELD)))
129c77ec5ceSMasatake YAMATO 			return true;
130c77ec5ceSMasatake YAMATO 		if (isFieldEnabled (FIELD_TYPE_REF) && doesFieldHaveValue (FIELD_TYPE_REF, tag)
1310647c2a9SMasatake YAMATO 			&& doesFieldHaveTabOrNewlineChar (FIELD_TYPE_REF, tag, NO_PARSER_FIELD))
132c77ec5ceSMasatake YAMATO 			return true;
133c77ec5ceSMasatake YAMATO 		if (isFieldEnabled (FIELD_FILE_SCOPE) && doesFieldHaveValue (FIELD_FILE_SCOPE, tag)
1340647c2a9SMasatake YAMATO 			&& doesFieldHaveTabOrNewlineChar (FIELD_FILE_SCOPE, tag, NO_PARSER_FIELD))
135c77ec5ceSMasatake YAMATO 			return true;
136c77ec5ceSMasatake YAMATO 
137c77ec5ceSMasatake YAMATO 		int f[] = { FIELD_INHERITANCE,
138c77ec5ceSMasatake YAMATO 					FIELD_ACCESS,
139c77ec5ceSMasatake YAMATO 					FIELD_IMPLEMENTATION,
140c77ec5ceSMasatake YAMATO 					FIELD_SIGNATURE,
141c77ec5ceSMasatake YAMATO 					FIELD_ROLES,
142c77ec5ceSMasatake YAMATO 					FIELD_EXTRAS,
143c77ec5ceSMasatake YAMATO 					FIELD_XPATH,
144c77ec5ceSMasatake YAMATO 					FIELD_END_LINE,
145c77ec5ceSMasatake YAMATO 					-1};
146c77ec5ceSMasatake YAMATO 		for (unsigned int i = 0; f[i] >= 0; i++)
147c77ec5ceSMasatake YAMATO 		{
148c77ec5ceSMasatake YAMATO 			if (isFieldEnabled (f[i]) && doesFieldHaveValue (f[i], tag)
1490647c2a9SMasatake YAMATO 				&& doesFieldHaveTabOrNewlineChar (f[i], tag, NO_PARSER_FIELD))
150c77ec5ceSMasatake YAMATO 				return true;
151c77ec5ceSMasatake YAMATO 		}
152c77ec5ceSMasatake YAMATO 	}
153c77ec5ceSMasatake YAMATO 
154c77ec5ceSMasatake YAMATO 	for (unsigned int i = 0; i < tag->usedParserFields; i++)
155c77ec5ceSMasatake YAMATO 	{
1569353c835SMasatake YAMATO 		const tagField *f = getParserFieldForIndex(tag, i);
157c77ec5ceSMasatake YAMATO 		fieldType ftype = f->ftype;
158c77ec5ceSMasatake YAMATO 		if (isFieldEnabled (ftype))
159c77ec5ceSMasatake YAMATO 		{
1600647c2a9SMasatake YAMATO 			if (doesFieldHaveTabOrNewlineChar (ftype, tag, i))
161c77ec5ceSMasatake YAMATO 				return true;
162c77ec5ceSMasatake YAMATO 		}
163c77ec5ceSMasatake YAMATO 	}
164c77ec5ceSMasatake YAMATO 	return false;
165c77ec5ceSMasatake YAMATO }
166c77ec5ceSMasatake YAMATO 
167c77ec5ceSMasatake YAMATO 
escapeFieldValueFull(tagWriter * writer,const tagEntryInfo * tag,fieldType ftype,int fieldIndex)168c77ec5ceSMasatake YAMATO static const char* escapeFieldValueFull (tagWriter *writer, const tagEntryInfo * tag, fieldType ftype, int fieldIndex)
169c77ec5ceSMasatake YAMATO {
170d823c975SMasatake YAMATO 	const char *v;
1715e272693SMasatake YAMATO 	if (writer->type == WRITER_E_CTAGS && doesFieldHaveRenderer(ftype, true))
172b05a040bSMasatake YAMATO 		v = renderFieldNoEscaping (ftype, tag, fieldIndex);
1735e272693SMasatake YAMATO 	else
174b05a040bSMasatake YAMATO 		v = renderField (ftype, tag, fieldIndex);
175d823c975SMasatake YAMATO 
176d823c975SMasatake YAMATO 	return v;
1775176f023SMasatake YAMATO }
1785176f023SMasatake YAMATO 
escapeFieldValue(tagWriter * writer,const tagEntryInfo * tag,fieldType ftype)179b05a040bSMasatake YAMATO static const char* escapeFieldValue (tagWriter *writer, const tagEntryInfo * tag, fieldType ftype)
180b05a040bSMasatake YAMATO {
181b05a040bSMasatake YAMATO 	return escapeFieldValueFull (writer, tag, ftype, NO_PARSER_FIELD);
182b05a040bSMasatake YAMATO }
183b05a040bSMasatake YAMATO 
renderExtensionFieldMaybe(tagWriter * writer,int xftype,const tagEntryInfo * const tag,char sep[2],MIO * mio)1846ccc5fc9SMasatake YAMATO static int renderExtensionFieldMaybe (tagWriter *writer, int xftype, const tagEntryInfo *const tag, char sep[2], MIO *mio)
1855176f023SMasatake YAMATO {
1865176f023SMasatake YAMATO 	if (isFieldEnabled (xftype) && doesFieldHaveValue (xftype, tag))
1875176f023SMasatake YAMATO 	{
1885176f023SMasatake YAMATO 		int len;
1895176f023SMasatake YAMATO 		len = mio_printf (mio, "%s\t%s:%s", sep,
1905176f023SMasatake YAMATO 				  getFieldName (xftype),
1916ccc5fc9SMasatake YAMATO 				  escapeFieldValue (writer, tag, xftype));
1925176f023SMasatake YAMATO 		sep[0] = '\0';
1935176f023SMasatake YAMATO 		return len;
1945176f023SMasatake YAMATO 	}
1955176f023SMasatake YAMATO 	else
1965176f023SMasatake YAMATO 		return 0;
1975176f023SMasatake YAMATO }
1985176f023SMasatake YAMATO 
addParserFields(tagWriter * writer,MIO * mio,const tagEntryInfo * const tag)1996ccc5fc9SMasatake YAMATO static int addParserFields (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag)
2005176f023SMasatake YAMATO {
2015176f023SMasatake YAMATO 	unsigned int i;
2025176f023SMasatake YAMATO 	int length = 0;
2035176f023SMasatake YAMATO 
2045176f023SMasatake YAMATO 	for (i = 0; i < tag->usedParserFields; i++)
2055176f023SMasatake YAMATO 	{
2069353c835SMasatake YAMATO 		const tagField *f = getParserFieldForIndex(tag, i);
207d823c975SMasatake YAMATO 		fieldType ftype = f->ftype;
208d823c975SMasatake YAMATO 		if (! isFieldEnabled (ftype))
2095176f023SMasatake YAMATO 			continue;
2105176f023SMasatake YAMATO 
2115176f023SMasatake YAMATO 		length += mio_printf(mio, "\t%s:%s",
212d823c975SMasatake YAMATO 							 getFieldName (ftype),
213b05a040bSMasatake YAMATO 							 escapeFieldValueFull (writer, tag, ftype, i));
2145176f023SMasatake YAMATO 	}
2155176f023SMasatake YAMATO 	return length;
2165176f023SMasatake YAMATO }
2175176f023SMasatake YAMATO 
writeLineNumberEntry(tagWriter * writer,MIO * mio,const tagEntryInfo * const tag)2186ccc5fc9SMasatake YAMATO static int writeLineNumberEntry (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag)
2195176f023SMasatake YAMATO {
2205176f023SMasatake YAMATO 	if (Option.lineDirectives)
2216ccc5fc9SMasatake YAMATO 		return mio_printf (mio, "%s", escapeFieldValue (writer, tag, FIELD_LINE_NUMBER));
2225176f023SMasatake YAMATO 	else
2235176f023SMasatake YAMATO 		return mio_printf (mio, "%lu", tag->lineNumber);
2245176f023SMasatake YAMATO }
2255176f023SMasatake YAMATO 
addExtensionFields(tagWriter * writer,MIO * mio,const tagEntryInfo * const tag)2266ccc5fc9SMasatake YAMATO static int addExtensionFields (tagWriter *writer, MIO *mio, const tagEntryInfo *const tag)
2275176f023SMasatake YAMATO {
2285176f023SMasatake YAMATO 	bool isKindKeyEnabled = isFieldEnabled (FIELD_KIND_KEY);
2295176f023SMasatake YAMATO 	bool isScopeEnabled = isFieldEnabled   (FIELD_SCOPE_KEY);
2305176f023SMasatake YAMATO 
2315176f023SMasatake YAMATO 	const char* const kindKey = isKindKeyEnabled
2325176f023SMasatake YAMATO 		?getFieldName (FIELD_KIND_KEY)
2335176f023SMasatake YAMATO 		:"";
2345176f023SMasatake YAMATO 	const char* const kindFmt = isKindKeyEnabled
2355176f023SMasatake YAMATO 		?"%s\t%s:%s"
2365176f023SMasatake YAMATO 		:"%s\t%s%s";
2375176f023SMasatake YAMATO 	const char* const scopeKey = isScopeEnabled
2385176f023SMasatake YAMATO 		?getFieldName (FIELD_SCOPE_KEY)
2395176f023SMasatake YAMATO 		:"";
2405176f023SMasatake YAMATO 	const char* const scopeFmt = isScopeEnabled
2415176f023SMasatake YAMATO 		?"%s\t%s:%s:%s"
2425176f023SMasatake YAMATO 		:"%s\t%s%s:%s";
2435176f023SMasatake YAMATO 
2445176f023SMasatake YAMATO 	char sep [] = {';', '"', '\0'};
2455176f023SMasatake YAMATO 	int length = 0;
2465176f023SMasatake YAMATO 
247d67993f7SMasatake YAMATO 	const char *str = NULL;;
248f92e6bf2SMasatake YAMATO 	kindDefinition *kdef = getLanguageKind(tag->langType, tag->kindIndex);
249f92e6bf2SMasatake YAMATO 	const char kind_letter_str[2] = {kdef->letter, '\0'};
250d67993f7SMasatake YAMATO 
251f92e6bf2SMasatake YAMATO 	if (kdef->name != NULL && (isFieldEnabled (FIELD_KIND_LONG)  ||
2527e1bd430SMasatake YAMATO 		 (isFieldEnabled (FIELD_KIND)  && kdef->letter == KIND_NULL_LETTER)))
2535176f023SMasatake YAMATO 	{
254d67993f7SMasatake YAMATO 		/* Use kind long name */
255f92e6bf2SMasatake YAMATO 		str = kdef->name;
2565176f023SMasatake YAMATO 	}
2577e1bd430SMasatake YAMATO 	else if (kdef->letter != KIND_NULL_LETTER  && (isFieldEnabled (FIELD_KIND) ||
258f92e6bf2SMasatake YAMATO 			(isFieldEnabled (FIELD_KIND_LONG) &&  kdef->name == NULL)))
2595176f023SMasatake YAMATO 	{
260d67993f7SMasatake YAMATO 		/* Use kind letter */
261d67993f7SMasatake YAMATO 		str = kind_letter_str;
262d67993f7SMasatake YAMATO 	}
263d67993f7SMasatake YAMATO 
264d67993f7SMasatake YAMATO 	if (str)
265d67993f7SMasatake YAMATO 	{
2665176f023SMasatake YAMATO 		length += mio_printf (mio, kindFmt, sep, kindKey, str);
2675176f023SMasatake YAMATO 		sep [0] = '\0';
2685176f023SMasatake YAMATO 	}
2695176f023SMasatake YAMATO 
2705176f023SMasatake YAMATO 	if (isFieldEnabled (FIELD_LINE_NUMBER) &&  doesFieldHaveValue (FIELD_LINE_NUMBER, tag))
2715176f023SMasatake YAMATO 	{
2725176f023SMasatake YAMATO 		length += mio_printf (mio, "%s\t%s:%ld", sep,
2735176f023SMasatake YAMATO 				   getFieldName (FIELD_LINE_NUMBER),
2745176f023SMasatake YAMATO 				   tag->lineNumber);
2755176f023SMasatake YAMATO 		sep [0] = '\0';
2765176f023SMasatake YAMATO 	}
2775176f023SMasatake YAMATO 
2786ccc5fc9SMasatake YAMATO 	length += renderExtensionFieldMaybe (writer, FIELD_LANGUAGE, tag, sep, mio);
2795176f023SMasatake YAMATO 
2805176f023SMasatake YAMATO 	if (isFieldEnabled (FIELD_SCOPE))
2815176f023SMasatake YAMATO 	{
28262c9a9aaSMasatake YAMATO 		const char* k, *v;
2835176f023SMasatake YAMATO 
2846ccc5fc9SMasatake YAMATO 		k = escapeFieldValue (writer, tag, FIELD_SCOPE_KIND_LONG);
2856ccc5fc9SMasatake YAMATO 		v = escapeFieldValue (writer, tag, FIELD_SCOPE);
2865176f023SMasatake YAMATO 		if (k && v)
2875176f023SMasatake YAMATO 		{
2885176f023SMasatake YAMATO 			length += mio_printf (mio, scopeFmt, sep, scopeKey, k, v);
2895176f023SMasatake YAMATO 			sep [0] = '\0';
2905176f023SMasatake YAMATO 		}
2915176f023SMasatake YAMATO 	}
2925176f023SMasatake YAMATO 
2935176f023SMasatake YAMATO 	if (isFieldEnabled (FIELD_TYPE_REF) && doesFieldHaveValue (FIELD_TYPE_REF, tag))
2945176f023SMasatake YAMATO 	{
2955082c510SMasatake YAMATO 		length += mio_printf (mio, "%s\t%s:%s", sep,
2965176f023SMasatake YAMATO 				      getFieldName (FIELD_TYPE_REF),
2976ccc5fc9SMasatake YAMATO 				      escapeFieldValue (writer, tag, FIELD_TYPE_REF));
2985176f023SMasatake YAMATO 		sep [0] = '\0';
2995176f023SMasatake YAMATO 	}
3005176f023SMasatake YAMATO 
3015176f023SMasatake YAMATO 	if (isFieldEnabled (FIELD_FILE_SCOPE) &&  doesFieldHaveValue (FIELD_FILE_SCOPE, tag))
3025176f023SMasatake YAMATO 	{
3035176f023SMasatake YAMATO 		length += mio_printf (mio, "%s\t%s:", sep,
3045176f023SMasatake YAMATO 				      getFieldName (FIELD_FILE_SCOPE));
3055176f023SMasatake YAMATO 		sep [0] = '\0';
3065176f023SMasatake YAMATO 	}
3075176f023SMasatake YAMATO 
308*0b491fdfSMasatake YAMATO 	for (int k = FIELD_ECTAGS_LOOP_START; k <= FIELD_ECTAGS_LOOP_LAST; k++)
309*0b491fdfSMasatake YAMATO 		length += renderExtensionFieldMaybe (writer, k, tag, sep, mio);
310*0b491fdfSMasatake YAMATO 	for (int k = FIELD_UCTAGS_LOOP_START; k <= FIELD_BUILTIN_LAST; k++)
311*0b491fdfSMasatake YAMATO 		length += renderExtensionFieldMaybe (writer, k, tag, sep, mio);
3125176f023SMasatake YAMATO 
3135176f023SMasatake YAMATO 	return length;
3145176f023SMasatake YAMATO }
3155176f023SMasatake YAMATO 
writeCtagsEntry(tagWriter * writer,MIO * mio,const tagEntryInfo * const tag,void * clientData CTAGS_ATTR_UNUSED)3166ccc5fc9SMasatake YAMATO static int writeCtagsEntry (tagWriter *writer,
3175053d6adSMasatake YAMATO 							MIO * mio, const tagEntryInfo *const tag,
3185053d6adSMasatake YAMATO 							void *clientData CTAGS_ATTR_UNUSED)
3195176f023SMasatake YAMATO {
32011705bb3SMasatake YAMATO 	if (writer->private)
32111705bb3SMasatake YAMATO 	{
322eadb1895SMasatake YAMATO 		struct rejection *rej = writer->private;
3230647c2a9SMasatake YAMATO 		if (hasTagEntryTabOrNewlineChar (tag))
324c77ec5ceSMasatake YAMATO 		{
325c77ec5ceSMasatake YAMATO 			rej->rejectionInThisInput = true;
326c77ec5ceSMasatake YAMATO 			return 0;
327c77ec5ceSMasatake YAMATO 		}
32811705bb3SMasatake YAMATO 	}
32911705bb3SMasatake YAMATO 
3305176f023SMasatake YAMATO 	int length = mio_printf (mio, "%s\t%s\t",
3316ccc5fc9SMasatake YAMATO 			      escapeFieldValue (writer, tag, FIELD_NAME),
3326ccc5fc9SMasatake YAMATO 			      escapeFieldValue (writer, tag, FIELD_INPUT_FILE));
3335176f023SMasatake YAMATO 
334d8018a25SMasatake YAMATO 	/* This is for handling 'common' of 'fortran'.  See the
335d8018a25SMasatake YAMATO 	   description of --excmd=mixed in ctags.1.  In tags output, what
336d8018a25SMasatake YAMATO 	   we call "pattern" is instructions for vi.
337d8018a25SMasatake YAMATO 
338d8018a25SMasatake YAMATO 	   However, in the other formats, pattern should be pattern as its name. */
3395176f023SMasatake YAMATO 	if (tag->lineNumberEntry)
3406ccc5fc9SMasatake YAMATO 		length += writeLineNumberEntry (writer, mio, tag);
3415176f023SMasatake YAMATO 	else
342d62cebebSMasatake YAMATO 	{
343d62cebebSMasatake YAMATO 		if (Option.locate == EX_COMBINE)
3444a9f00a1SAmaiKinono 			length += mio_printf(mio, "%lu;", tag->lineNumber);
3451e25caaaSMasatake YAMATO 		length += mio_puts(mio, escapeFieldValue(writer, tag, FIELD_PATTERN));
346d62cebebSMasatake YAMATO 	}
3475176f023SMasatake YAMATO 
3485176f023SMasatake YAMATO 	if (includeExtensionFlags ())
3495176f023SMasatake YAMATO 	{
3506ccc5fc9SMasatake YAMATO 		length += addExtensionFields (writer, mio, tag);
3516ccc5fc9SMasatake YAMATO 		length += addParserFields (writer, mio, tag);
3525176f023SMasatake YAMATO 	}
3535176f023SMasatake YAMATO 
3545176f023SMasatake YAMATO 	length += mio_printf (mio, "\n");
3555176f023SMasatake YAMATO 
3565176f023SMasatake YAMATO 	return length;
3575176f023SMasatake YAMATO }
3585176f023SMasatake YAMATO 
writeCtagsPtagEntry(tagWriter * writer CTAGS_ATTR_UNUSED,MIO * mio,const ptagDesc * desc,const char * const fileName,const char * const pattern,const char * const parserName,void * clientData CTAGS_ATTR_UNUSED)3590925aa59SMasatake YAMATO static int writeCtagsPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,
3600925aa59SMasatake YAMATO 				MIO * mio, const ptagDesc *desc,
3615176f023SMasatake YAMATO 				const char *const fileName,
3625176f023SMasatake YAMATO 				const char *const pattern,
3635053d6adSMasatake YAMATO 				const char *const parserName,
3645053d6adSMasatake YAMATO 				void *clientData CTAGS_ATTR_UNUSED)
3655176f023SMasatake YAMATO {
366545d1428SMasatake YAMATO 
367545d1428SMasatake YAMATO 	bool extras = includeExtensionFlags () && isFieldEnabled (FIELD_EXTRAS);
368545d1428SMasatake YAMATO 	const char *xsep = extras? ";\"	": "";
369545d1428SMasatake YAMATO 	const char *fsep = extras? ":": "";
370545d1428SMasatake YAMATO 	const char *fieldx = extras? getFieldName (FIELD_EXTRAS): "";
371545d1428SMasatake YAMATO 	const char *xptag = extras? getXtagName (XTAG_PSEUDO_TAGS): "";
372545d1428SMasatake YAMATO 
3735176f023SMasatake YAMATO 	return parserName
3745176f023SMasatake YAMATO 
3755176f023SMasatake YAMATO #define OPT(X) ((X)?(X):"")
376545d1428SMasatake YAMATO 		? mio_printf (mio, "%s%s%s%s\t%s\t/%s/%s%s%s%s\n",
3775176f023SMasatake YAMATO 			      PSEUDO_TAG_PREFIX, desc->name, PSEUDO_TAG_SEPARATOR, parserName,
378545d1428SMasatake YAMATO 			      OPT(fileName), OPT(pattern),
379545d1428SMasatake YAMATO 				  xsep, fieldx, fsep, xptag)
380545d1428SMasatake YAMATO 		: mio_printf (mio, "%s%s\t%s\t/%s/%s%s%s%s\n",
3815176f023SMasatake YAMATO 			      PSEUDO_TAG_PREFIX, desc->name,
382545d1428SMasatake YAMATO 			      OPT(fileName), OPT(pattern),
383545d1428SMasatake YAMATO 			      xsep, fieldx, fsep, xptag);
3845176f023SMasatake YAMATO #undef OPT
3855176f023SMasatake YAMATO }
3868182f840SMasatake YAMATO 
387c0421c5eSMasatake YAMATO static fieldType fixedFields [] = {
388c0421c5eSMasatake YAMATO 	FIELD_NAME,
389c0421c5eSMasatake YAMATO 	FIELD_INPUT_FILE,
390c0421c5eSMasatake YAMATO 	FIELD_PATTERN,
391c0421c5eSMasatake YAMATO };
392c0421c5eSMasatake YAMATO 
treatFieldAsFixed(int fieldType)3938182f840SMasatake YAMATO static bool treatFieldAsFixed (int fieldType)
3948182f840SMasatake YAMATO {
395c0421c5eSMasatake YAMATO 	for (int i = 0; i < ARRAY_SIZE(fixedFields); i++)
396c0421c5eSMasatake YAMATO 		if (fixedFields [i] == fieldType)
3978182f840SMasatake YAMATO 			return true;
3988182f840SMasatake YAMATO 	return false;
3998182f840SMasatake YAMATO }
400681789f5SMasatake YAMATO 
checkCtagsOptions(tagWriter * writer CTAGS_ATTR_UNUSED,bool fieldsWereReset)401c0421c5eSMasatake YAMATO static void checkCtagsOptions (tagWriter *writer CTAGS_ATTR_UNUSED,
402c0421c5eSMasatake YAMATO 							   bool fieldsWereReset)
403681789f5SMasatake YAMATO {
404681789f5SMasatake YAMATO 	if (isFieldEnabled (FIELD_KIND_KEY)
405681789f5SMasatake YAMATO 		&& (!(isFieldEnabled (FIELD_KIND_LONG) ||
406681789f5SMasatake YAMATO 			  isFieldEnabled (FIELD_KIND))))
407681789f5SMasatake YAMATO 	{
408681789f5SMasatake YAMATO 		error (WARNING, "though %c/%s field is enabled, neither %c nor %c field is not enabled",
409681789f5SMasatake YAMATO 			   getFieldLetter (FIELD_KIND_KEY),
410681789f5SMasatake YAMATO 			   getFieldName (FIELD_KIND_KEY),
411681789f5SMasatake YAMATO 			   getFieldLetter (FIELD_KIND),
412681789f5SMasatake YAMATO 			   getFieldLetter (FIELD_KIND_LONG));
413681789f5SMasatake YAMATO 		error (WARNING, "enable the %c field to make the %c/%s field printable",
414681789f5SMasatake YAMATO 			   getFieldLetter (FIELD_KIND_LONG),
415681789f5SMasatake YAMATO 			   getFieldLetter (FIELD_KIND_KEY),
416681789f5SMasatake YAMATO 			   getFieldName (FIELD_KIND_KEY));
417c0421c5eSMasatake YAMATO 		enableField (FIELD_KIND_LONG, true);
418681789f5SMasatake YAMATO 	}
4196a5a9c4cSMasatake YAMATO 	if (isFieldEnabled (FIELD_SCOPE_KEY)
4206a5a9c4cSMasatake YAMATO 		&& !isFieldEnabled (FIELD_SCOPE))
4216a5a9c4cSMasatake YAMATO 	{
4226a5a9c4cSMasatake YAMATO 		error (WARNING, "though %c/%s field is enabled, %c field is not enabled",
4236a5a9c4cSMasatake YAMATO 			   getFieldLetter (FIELD_SCOPE_KEY),
4246a5a9c4cSMasatake YAMATO 			   getFieldName (FIELD_SCOPE_KEY),
4256a5a9c4cSMasatake YAMATO 			   getFieldLetter (FIELD_SCOPE));
4266a5a9c4cSMasatake YAMATO 		error (WARNING, "enable the %c field to make the %c/%s field printable",
4276a5a9c4cSMasatake YAMATO 			   getFieldLetter (FIELD_SCOPE),
4286a5a9c4cSMasatake YAMATO 			   getFieldLetter (FIELD_SCOPE_KEY),
4296a5a9c4cSMasatake YAMATO 			   getFieldName (FIELD_SCOPE_KEY));
430c0421c5eSMasatake YAMATO 		enableField (FIELD_SCOPE, true);
431c0421c5eSMasatake YAMATO 	}
432c0421c5eSMasatake YAMATO 
433c0421c5eSMasatake YAMATO 	for (int i = 0; i < ARRAY_SIZE (fixedFields); i++)
434c0421c5eSMasatake YAMATO 	{
435c0421c5eSMasatake YAMATO 		if (!isFieldEnabled (fixedFields [i]))
436c0421c5eSMasatake YAMATO 		{
437c0421c5eSMasatake YAMATO 			enableField (fixedFields [i], true);
438c0421c5eSMasatake YAMATO 
439c0421c5eSMasatake YAMATO 			if (fieldsWereReset)
440c0421c5eSMasatake YAMATO 				continue;
441c0421c5eSMasatake YAMATO 
442c0421c5eSMasatake YAMATO 			const char *name = getFieldName (fixedFields [i]);
443c0421c5eSMasatake YAMATO 			unsigned char letter = getFieldLetter (fixedFields [i]);
444c0421c5eSMasatake YAMATO 
445c0421c5eSMasatake YAMATO 			if (name && letter != NUL_FIELD_LETTER)
446c0421c5eSMasatake YAMATO 				error(WARNING, "Cannot disable fixed field: '%c'{%s} in ctags output mode",
447c0421c5eSMasatake YAMATO 				      letter, name);
448c0421c5eSMasatake YAMATO 			else if (name)
449c0421c5eSMasatake YAMATO 				error(WARNING, "Cannot disable fixed field: {%s} in ctags output mode",
450c0421c5eSMasatake YAMATO 				      name);
451c0421c5eSMasatake YAMATO 			else if (letter != NUL_FIELD_LETTER)
452c0421c5eSMasatake YAMATO 				error(WARNING, "Cannot disable fixed field: '%c' in ctags output mode",
453c0421c5eSMasatake YAMATO 				      letter);
454c0421c5eSMasatake YAMATO 		}
4556a5a9c4cSMasatake YAMATO 	}
456681789f5SMasatake YAMATO }
457