xref: /Universal-ctags/main/xtag.c (revision d61b5d962928c40700f3927046a56e295b5fd872)
135c59e96SMasatake YAMATO /*
235c59e96SMasatake YAMATO  *
335c59e96SMasatake YAMATO  *  Copyright (c) 2015, Red Hat, Inc.
435c59e96SMasatake YAMATO  *  Copyright (c) 2015, Masatake YAMATO
535c59e96SMasatake YAMATO  *
635c59e96SMasatake YAMATO  *  Author: Masatake YAMATO <yamato@redhat.com>
735c59e96SMasatake YAMATO  *
835c59e96SMasatake YAMATO  *   This source code is released for free distribution under the terms of the
935c59e96SMasatake YAMATO  *   GNU General Public License version 2 or (at your option) any later version.
1035c59e96SMasatake YAMATO  *
1135c59e96SMasatake YAMATO  */
1235c59e96SMasatake YAMATO 
1335c59e96SMasatake YAMATO #include "general.h"  /* must always come first */
14db2bf481SMasatake YAMATO #include "ctags.h"
1535c59e96SMasatake YAMATO #include "debug.h"
16e9eb4360SMasatake YAMATO #include "options.h"
17ecaa3a91SMasatake YAMATO #include "options_p.h"
180d502ef0SMasatake YAMATO #include "parse_p.h"
19158a3387SMasatake YAMATO #include "routines.h"
2056065e52SMasatake YAMATO #include "trashbox.h"
21285b4dfeSMasatake YAMATO #include "writer_p.h"
2235c59e96SMasatake YAMATO #include "xtag.h"
23e2a3289bSMasatake YAMATO #include "xtag_p.h"
2435c59e96SMasatake YAMATO 
251f65df85SMasatake YAMATO #include <string.h>
268643c5b5SMasatake YAMATO #include <ctype.h>
271f65df85SMasatake YAMATO 
2806e8f520SMasatake YAMATO typedef struct sXtagObject {
29a70e0bbeSMasatake YAMATO 	xtagDefinition *def;
308643c5b5SMasatake YAMATO 	langType language;
318643c5b5SMasatake YAMATO 	xtagType sibling;
3206e8f520SMasatake YAMATO } xtagObject;
331f65df85SMasatake YAMATO 
isPseudoTagsEnabled(xtagDefinition * pdef CTAGS_ATTR_UNUSED)34a70e0bbeSMasatake YAMATO static bool isPseudoTagsEnabled (xtagDefinition *pdef CTAGS_ATTR_UNUSED)
3540c4987bSMasatake YAMATO {
3663570e0cSMasatake YAMATO 	if (!writerCanPrintPtag())
3763570e0cSMasatake YAMATO 		return false;
38b9636b4dSMasatake YAMATO 	if (!writerPrintPtagByDefault())
39b9636b4dSMasatake YAMATO 		return false;
4063570e0cSMasatake YAMATO 
4140c4987bSMasatake YAMATO 	return ! isDestinationStdout ();
4240c4987bSMasatake YAMATO }
4340c4987bSMasatake YAMATO 
isPseudoTagsFixed(xtagDefinition * pdef CTAGS_ATTR_UNUSED)44d4dfe861SMasatake YAMATO static bool isPseudoTagsFixed (xtagDefinition *pdef CTAGS_ATTR_UNUSED)
45d4dfe861SMasatake YAMATO {
46d4dfe861SMasatake YAMATO 	if (!writerCanPrintPtag())
47d4dfe861SMasatake YAMATO 		return true;
48d4dfe861SMasatake YAMATO 	else
49d4dfe861SMasatake YAMATO 		return false;
50d4dfe861SMasatake YAMATO }
51d4dfe861SMasatake YAMATO 
enableFileKind(xtagDefinition * pdef,bool state)5264270418SMasatake YAMATO static void enableFileKind (xtagDefinition *pdef, bool state)
5364270418SMasatake YAMATO {
5464270418SMasatake YAMATO 	enableDefaultFileKind(state);
5564270418SMasatake YAMATO 	pdef->enabled = state;
5664270418SMasatake YAMATO }
5764270418SMasatake YAMATO 
58e3712f53SMasatake YAMATO static xtagDefinition xtagDefinitions [] = {
59ce990805SThomas Braun 	{ true, 'F',  "fileScope",
6035c59e96SMasatake YAMATO 	  "Include tags of file scope" },
61ce990805SThomas Braun 	{ false, 'f', "inputFile",
6264270418SMasatake YAMATO 	  "Include an entry for the base file name of every input file",
6364270418SMasatake YAMATO 	  NULL,
6464270418SMasatake YAMATO 	  NULL,
6564270418SMasatake YAMATO 	  enableFileKind},
66ce990805SThomas Braun 	{ false, 'p', "pseudo",
6740c4987bSMasatake YAMATO 	  "Include pseudo tags",
68d4dfe861SMasatake YAMATO 	  isPseudoTagsEnabled,
69d4dfe861SMasatake YAMATO 	  isPseudoTagsFixed},
70ce990805SThomas Braun 	{ false, 'q', "qualified",
7135c59e96SMasatake YAMATO 	  "Include an extra class-qualified tag entry for each tag"},
72ce990805SThomas Braun 	{ false, 'r', "reference",
7320703582SMasatake YAMATO 	  "Include reference tags"},
74b4c1d7b2SMasatake YAMATO 	{ false, 'g', "guest",
75b4c1d7b2SMasatake YAMATO 	  "Include tags generated by guest parsers"},
763abcac5dSMasatake YAMATO 	{ true, 's', "subparser",
773abcac5dSMasatake YAMATO 	  "Include tags generated by subparsers"},
780e4c5d4aSMasatake YAMATO 	{ true, '\0', "anonymous",
790e4c5d4aSMasatake YAMATO 	  "Include tags for non-named objects like lambda"},
8035c59e96SMasatake YAMATO };
8135c59e96SMasatake YAMATO 
8206e8f520SMasatake YAMATO static unsigned int       xtagObjectUsed;
8306e8f520SMasatake YAMATO static unsigned int       xtagObjectAllocated;
8406e8f520SMasatake YAMATO static xtagObject* xtagObjects;
858643c5b5SMasatake YAMATO 
getXtagObject(xtagType type)8606e8f520SMasatake YAMATO static xtagObject* getXtagObject (xtagType type)
8735c59e96SMasatake YAMATO {
8846ab94ccSMasatake YAMATO 	Assert ((0 <= type) && ((unsigned int)type < xtagObjectUsed));
8906e8f520SMasatake YAMATO 	return (xtagObjects + type);
9035c59e96SMasatake YAMATO }
9135c59e96SMasatake YAMATO 
getXtagDefinition(xtagType type)92e3712f53SMasatake YAMATO extern xtagDefinition* getXtagDefinition (xtagType type)
9335c59e96SMasatake YAMATO {
9446ab94ccSMasatake YAMATO 	Assert ((0 <= type) && ((unsigned int)type < xtagObjectUsed));
958643c5b5SMasatake YAMATO 
96a70e0bbeSMasatake YAMATO 	return getXtagObject (type)->def;
978643c5b5SMasatake YAMATO }
988643c5b5SMasatake YAMATO 
99a70e0bbeSMasatake YAMATO typedef bool (* xtagPredicate) (xtagObject *pobj, langType language, const void *user_data);
getXtagTypeGeneric(xtagPredicate predicate,langType language,const void * user_data)1008643c5b5SMasatake YAMATO static xtagType  getXtagTypeGeneric (xtagPredicate predicate, langType language, const void *user_data)
1018643c5b5SMasatake YAMATO {
1028643c5b5SMasatake YAMATO 	static bool initialized = false;
10346ab94ccSMasatake YAMATO 	unsigned int i;
10435c59e96SMasatake YAMATO 
1058643c5b5SMasatake YAMATO 	if (language == LANG_AUTO && (initialized == false))
10635c59e96SMasatake YAMATO 	{
1078643c5b5SMasatake YAMATO 		initialized = true;
1088643c5b5SMasatake YAMATO 		initializeParser (LANG_AUTO);
1098643c5b5SMasatake YAMATO 	}
1108643c5b5SMasatake YAMATO 	else if (language != LANG_IGNORE && (initialized == false))
1118643c5b5SMasatake YAMATO 		initializeParser (language);
1128643c5b5SMasatake YAMATO 
11306e8f520SMasatake YAMATO 	for (i = 0; i < xtagObjectUsed; i++)
1148643c5b5SMasatake YAMATO 	{
11506e8f520SMasatake YAMATO 		if (predicate (xtagObjects + i, language, user_data))
11635c59e96SMasatake YAMATO 			return i;
11735c59e96SMasatake YAMATO 	}
11835c59e96SMasatake YAMATO 	return XTAG_UNKNOWN;
11935c59e96SMasatake YAMATO }
12035c59e96SMasatake YAMATO 
xtagEqualByLetter(xtagObject * pobj,langType language CTAGS_ATTR_UNUSED,const void * user_data)121a70e0bbeSMasatake YAMATO static bool xtagEqualByLetter (xtagObject *pobj, langType language CTAGS_ATTR_UNUSED,
1228643c5b5SMasatake YAMATO 							   const void *user_data)
1231f65df85SMasatake YAMATO {
124a70e0bbeSMasatake YAMATO 	return (pobj->def->letter == *((char *)user_data))? true: false;
1251f65df85SMasatake YAMATO }
1261f65df85SMasatake YAMATO 
getXtagTypeForLetter(char letter)1271f65df85SMasatake YAMATO extern xtagType  getXtagTypeForLetter (char letter)
1281f65df85SMasatake YAMATO {
1298643c5b5SMasatake YAMATO 	return getXtagTypeGeneric (xtagEqualByLetter, LANG_IGNORE, &letter);
1301f65df85SMasatake YAMATO }
1311f65df85SMasatake YAMATO 
xtagEqualByNameAndLanguage(xtagObject * pobj,langType language,const void * user_data)132a70e0bbeSMasatake YAMATO static bool xtagEqualByNameAndLanguage (xtagObject *pobj, langType language, const void *user_data)
1331f65df85SMasatake YAMATO {
1348643c5b5SMasatake YAMATO 	const char* name = user_data;
1358643c5b5SMasatake YAMATO 
136a70e0bbeSMasatake YAMATO 	if ((language == LANG_AUTO || pobj->language == language)
137a70e0bbeSMasatake YAMATO 		&& (strcmp (pobj->def->name, name) == 0))
1388643c5b5SMasatake YAMATO 		return true;
1398643c5b5SMasatake YAMATO 	else
1408643c5b5SMasatake YAMATO 		return false;
1411f65df85SMasatake YAMATO }
1421f65df85SMasatake YAMATO 
getXtagTypeForNameAndLanguage(const char * name,langType language)1438643c5b5SMasatake YAMATO extern xtagType  getXtagTypeForNameAndLanguage (const char *name, langType language)
1441f65df85SMasatake YAMATO {
1458643c5b5SMasatake YAMATO 	return getXtagTypeGeneric (xtagEqualByNameAndLanguage, language, name);
1461f65df85SMasatake YAMATO }
1471f65df85SMasatake YAMATO 
xtagColprintTableNew(void)148ecb981e8SMasatake YAMATO extern struct colprintTable * xtagColprintTableNew (void)
149dab9500fSMasatake YAMATO {
150ecb981e8SMasatake YAMATO 	return colprintTableNew ("L:LETTER", "L:NAME", "L:ENABLED",
151f1396a31SMasatake YAMATO 							 "L:LANGUAGE", "L:FIXED", "L:DESCRIPTION", NULL);
152ecb981e8SMasatake YAMATO }
1538643c5b5SMasatake YAMATO 
xtagColprintAddLine(struct colprintTable * table,int xtype)154ecb981e8SMasatake YAMATO static void  xtagColprintAddLine (struct colprintTable *table, int xtype)
155ecb981e8SMasatake YAMATO {
156ecb981e8SMasatake YAMATO 	xtagObject* xobj = getXtagObject (xtype);
157ecb981e8SMasatake YAMATO 	xtagDefinition *xdef = xobj->def;
1588643c5b5SMasatake YAMATO 
159ecb981e8SMasatake YAMATO 	struct colprintLine *line = colprintTableGetNewLine(table);
1608643c5b5SMasatake YAMATO 
161ecb981e8SMasatake YAMATO 	colprintLineAppendColumnChar (line,
162ecb981e8SMasatake YAMATO 								  (xdef->letter == NUL_XTAG_LETTER)
163ecb981e8SMasatake YAMATO 								  ? '-'
164ecb981e8SMasatake YAMATO 								  : xdef->letter);
165ecb981e8SMasatake YAMATO 	colprintLineAppendColumnCString (line, xdef->name);
166eed7b1d5SMasatake YAMATO 	colprintLineAppendColumnBool (line, isXtagEnabled(xdef->xtype));
167ecb981e8SMasatake YAMATO 	colprintLineAppendColumnCString (line,
168ecb981e8SMasatake YAMATO 									 xobj->language == LANG_IGNORE
169db2bf481SMasatake YAMATO 									 ? RSV_NONE
170ecb981e8SMasatake YAMATO 									 : getLanguageName (xobj->language));
171f1396a31SMasatake YAMATO 	colprintLineAppendColumnBool (line, isXtagFixed(xdef->xtype));
172ecb981e8SMasatake YAMATO 	colprintLineAppendColumnCString (line, xdef->description);
173ecb981e8SMasatake YAMATO }
1748643c5b5SMasatake YAMATO 
xtagColprintAddCommonLines(struct colprintTable * table)175ecb981e8SMasatake YAMATO extern void xtagColprintAddCommonLines (struct colprintTable *table)
176ecb981e8SMasatake YAMATO {
177ecb981e8SMasatake YAMATO 	for (int i = 0; i < XTAG_COUNT; i++)
178ecb981e8SMasatake YAMATO 		xtagColprintAddLine (table, i);
179ecb981e8SMasatake YAMATO }
180ecb981e8SMasatake YAMATO 
xtagColprintAddLanguageLines(struct colprintTable * table,langType language)181ecb981e8SMasatake YAMATO extern void xtagColprintAddLanguageLines (struct colprintTable *table, langType language)
182ecb981e8SMasatake YAMATO {
1834c64e833SMasatake YAMATO 	for (unsigned int i = XTAG_COUNT; i < xtagObjectUsed; i++)
184ecb981e8SMasatake YAMATO 	{
185ecb981e8SMasatake YAMATO 		xtagObject* xobj = getXtagObject (i);
186ecb981e8SMasatake YAMATO 
187ecb981e8SMasatake YAMATO 		if (xobj->language == language)
188ecb981e8SMasatake YAMATO 			xtagColprintAddLine (table, i);
189ecb981e8SMasatake YAMATO 	}
190ecb981e8SMasatake YAMATO }
191ecb981e8SMasatake YAMATO 
xtagColprintCompareLines(struct colprintLine * a,struct colprintLine * b)192ecb981e8SMasatake YAMATO static int xtagColprintCompareLines (struct colprintLine *a , struct colprintLine *b)
193ecb981e8SMasatake YAMATO {
194ecb981e8SMasatake YAMATO 	const char *a_parser = colprintLineGetColumn (a, 3);
195ecb981e8SMasatake YAMATO 	const char *b_parser = colprintLineGetColumn (b, 3);
196ecb981e8SMasatake YAMATO 
197db2bf481SMasatake YAMATO 	if (strcmp (a_parser, RSV_NONE) == 0
198db2bf481SMasatake YAMATO 		&& strcmp (b_parser, RSV_NONE) != 0)
199ecb981e8SMasatake YAMATO 		return -1;
200db2bf481SMasatake YAMATO 	else if (strcmp (a_parser, RSV_NONE) != 0
201db2bf481SMasatake YAMATO 			 && strcmp (b_parser, RSV_NONE) == 0)
202ecb981e8SMasatake YAMATO 		return 1;
203db2bf481SMasatake YAMATO 	else if (strcmp (a_parser, RSV_NONE) != 0
204db2bf481SMasatake YAMATO 			 && strcmp (b_parser, RSV_NONE) != 0)
205ecb981e8SMasatake YAMATO 	{
206ecb981e8SMasatake YAMATO 		int r;
207ecb981e8SMasatake YAMATO 		r = strcmp (a_parser, b_parser);
208ecb981e8SMasatake YAMATO 		if (r != 0)
209ecb981e8SMasatake YAMATO 			return r;
210ae09640aSMasatake YAMATO 	}
211ae09640aSMasatake YAMATO 	else
212ae09640aSMasatake YAMATO 	{
213ae09640aSMasatake YAMATO 		int r;
214ae09640aSMasatake YAMATO 
215ae09640aSMasatake YAMATO 		const char *a_letter = colprintLineGetColumn (a, 0);
216ae09640aSMasatake YAMATO 		const char *b_letter = colprintLineGetColumn (b, 0);
217ae09640aSMasatake YAMATO 		r = strcmp(a_letter, b_letter);
218ae09640aSMasatake YAMATO 		if (r != 0)
219ae09640aSMasatake YAMATO 			return r;
220ae09640aSMasatake YAMATO 	}
221ecb981e8SMasatake YAMATO 
222ecb981e8SMasatake YAMATO 	const char *a_name = colprintLineGetColumn (a, 1);
223ecb981e8SMasatake YAMATO 	const char *b_name = colprintLineGetColumn (b, 1);
224ecb981e8SMasatake YAMATO 
225ecb981e8SMasatake YAMATO 	return strcmp(a_name, b_name);
226ecb981e8SMasatake YAMATO }
227e9eb4360SMasatake YAMATO 
xtagColprintTablePrint(struct colprintTable * table,bool withListHeader,bool machinable,FILE * fp)228ecb981e8SMasatake YAMATO extern void xtagColprintTablePrint (struct colprintTable *table,
229ecb981e8SMasatake YAMATO 									bool withListHeader, bool machinable, FILE *fp)
230e9eb4360SMasatake YAMATO {
231ecb981e8SMasatake YAMATO 	colprintTableSort (table, xtagColprintCompareLines);
232ecb981e8SMasatake YAMATO 	colprintTablePrint (table, 0, withListHeader, machinable, fp);
2338643c5b5SMasatake YAMATO }
2348643c5b5SMasatake YAMATO 
isXtagEnabled(xtagType type)235ce990805SThomas Braun extern bool isXtagEnabled (xtagType type)
23635c59e96SMasatake YAMATO {
237a70e0bbeSMasatake YAMATO 	xtagDefinition* def = getXtagDefinition (type);
23835c59e96SMasatake YAMATO 
239a70e0bbeSMasatake YAMATO 	Assert (def);
24035c59e96SMasatake YAMATO 
241a70e0bbeSMasatake YAMATO 	if (def->isEnabled)
242a70e0bbeSMasatake YAMATO 		return def->isEnabled (def);
24335c59e96SMasatake YAMATO 	else
244a70e0bbeSMasatake YAMATO 		return def->enabled;
24535c59e96SMasatake YAMATO }
24635c59e96SMasatake YAMATO 
isXtagFixed(xtagType type)247d4dfe861SMasatake YAMATO extern bool isXtagFixed (xtagType type)
248d4dfe861SMasatake YAMATO {
249d4dfe861SMasatake YAMATO 	xtagDefinition* def = getXtagDefinition (type);
250d4dfe861SMasatake YAMATO 
251d4dfe861SMasatake YAMATO 	Assert (def);
252d4dfe861SMasatake YAMATO 
253d4dfe861SMasatake YAMATO 	if (def->isFixed)
254d4dfe861SMasatake YAMATO 		return def->isFixed (def);
255d4dfe861SMasatake YAMATO 
256d4dfe861SMasatake YAMATO 	return false;
257d4dfe861SMasatake YAMATO }
258d4dfe861SMasatake YAMATO 
enableXtag(xtagType type,bool state)259ce990805SThomas Braun extern bool enableXtag (xtagType type, bool state)
26035c59e96SMasatake YAMATO {
261ce990805SThomas Braun 	bool old;
262a70e0bbeSMasatake YAMATO 	xtagDefinition* def = getXtagDefinition (type);
26335c59e96SMasatake YAMATO 
264a70e0bbeSMasatake YAMATO 	Assert (def);
26535c59e96SMasatake YAMATO 
26635c59e96SMasatake YAMATO 	old = isXtagEnabled (type);
267d4dfe861SMasatake YAMATO 
268d4dfe861SMasatake YAMATO 	if (isXtagFixed(type))
269d4dfe861SMasatake YAMATO 		def->enabled = old;
27064270418SMasatake YAMATO 	else if (def->enable)
27164270418SMasatake YAMATO 		def->enable (def, state);
272d4dfe861SMasatake YAMATO 	else
273a70e0bbeSMasatake YAMATO 		def->enabled = state;
274d4dfe861SMasatake YAMATO 
275a70e0bbeSMasatake YAMATO 	def->isEnabled = NULL;
27635c59e96SMasatake YAMATO 
27735c59e96SMasatake YAMATO 	return old;
27835c59e96SMasatake YAMATO }
2798cd893daSMasatake YAMATO 
isCommonXtag(xtagType type)2808643c5b5SMasatake YAMATO extern bool isCommonXtag (xtagType type)
2818643c5b5SMasatake YAMATO {
2828643c5b5SMasatake YAMATO 	return (type < XTAG_COUNT)? true: false;
2838643c5b5SMasatake YAMATO }
2848643c5b5SMasatake YAMATO 
getXtagOwner(xtagType type)28541c5eb82SMasatake YAMATO extern langType getXtagOwner (xtagType type)
2868643c5b5SMasatake YAMATO {
28706e8f520SMasatake YAMATO 	return getXtagObject (type)->language;
2888643c5b5SMasatake YAMATO }
2898643c5b5SMasatake YAMATO 
getXtagName(xtagType type)290*d61b5d96SMasatake YAMATO extern const char* getXtagName (xtagType type)
2918cd893daSMasatake YAMATO {
292a70e0bbeSMasatake YAMATO 	xtagDefinition* def = getXtagDefinition (type);
293a70e0bbeSMasatake YAMATO 	if (def)
294a70e0bbeSMasatake YAMATO 		return def->name;
2958cd893daSMasatake YAMATO 	else
2968cd893daSMasatake YAMATO 		return NULL;
2978cd893daSMasatake YAMATO }
2988643c5b5SMasatake YAMATO 
getXtagDescription(xtagType type)299*d61b5d96SMasatake YAMATO extern const char* getXtagDescription (xtagType type)
300726cac0cSMasatake YAMATO {
301726cac0cSMasatake YAMATO 	xtagDefinition* def = getXtagDefinition (type);
302726cac0cSMasatake YAMATO 	if (def)
303726cac0cSMasatake YAMATO 		return def->description;
304726cac0cSMasatake YAMATO 	else
305726cac0cSMasatake YAMATO 		return NULL;
306726cac0cSMasatake YAMATO }
307726cac0cSMasatake YAMATO 
initXtagObjects(void)30806e8f520SMasatake YAMATO extern void initXtagObjects (void)
3098643c5b5SMasatake YAMATO {
310a70e0bbeSMasatake YAMATO 	xtagObject *xobj;
3118643c5b5SMasatake YAMATO 
31206e8f520SMasatake YAMATO 	xtagObjectAllocated = ARRAY_SIZE (xtagDefinitions);
31306e8f520SMasatake YAMATO 	xtagObjects = xMalloc (xtagObjectAllocated, xtagObject);
31433a6fdb8SMasatake YAMATO 	DEFAULT_TRASH_BOX(&xtagObjects, eFreeIndirect);
3158643c5b5SMasatake YAMATO 
31646ab94ccSMasatake YAMATO 	for (unsigned int i = 0; i < ARRAY_SIZE (xtagDefinitions); i++)
3178643c5b5SMasatake YAMATO 	{
318a70e0bbeSMasatake YAMATO 		xobj = xtagObjects + i;
319a70e0bbeSMasatake YAMATO 		xobj->def = xtagDefinitions + i;
3204927280dSMasatake YAMATO 		xobj->def->xtype = i;
321a70e0bbeSMasatake YAMATO 		xobj->language = LANG_IGNORE;
322a70e0bbeSMasatake YAMATO 		xobj->sibling = XTAG_UNKNOWN;
32306e8f520SMasatake YAMATO 		xtagObjectUsed++;
3248643c5b5SMasatake YAMATO 	}
3258643c5b5SMasatake YAMATO }
3268643c5b5SMasatake YAMATO 
countXtags(void)3278643c5b5SMasatake YAMATO extern int countXtags (void)
3288643c5b5SMasatake YAMATO {
32906e8f520SMasatake YAMATO 	return xtagObjectUsed;
3308643c5b5SMasatake YAMATO }
3318643c5b5SMasatake YAMATO 
updateSiblingXtag(xtagType type,const char * name)3328643c5b5SMasatake YAMATO static void updateSiblingXtag (xtagType type, const char* name)
3338643c5b5SMasatake YAMATO {
3348643c5b5SMasatake YAMATO 	int i;
335a70e0bbeSMasatake YAMATO 	xtagObject *xobj;
3368643c5b5SMasatake YAMATO 
3378643c5b5SMasatake YAMATO 	for (i = type; i > 0; i--)
3388643c5b5SMasatake YAMATO 	{
339a70e0bbeSMasatake YAMATO 		xobj = xtagObjects + i - 1;
340a70e0bbeSMasatake YAMATO 		if (xobj->def->name && (strcmp (xobj->def->name, name) == 0))
3418643c5b5SMasatake YAMATO 		{
342a70e0bbeSMasatake YAMATO 			Assert (xobj->sibling == XTAG_UNKNOWN);
343a70e0bbeSMasatake YAMATO 			xobj->sibling = type;
3448643c5b5SMasatake YAMATO 			break;
3458643c5b5SMasatake YAMATO 		}
3468643c5b5SMasatake YAMATO 	}
3478643c5b5SMasatake YAMATO }
3488643c5b5SMasatake YAMATO 
defineXtag(xtagDefinition * def,langType language)349a70e0bbeSMasatake YAMATO extern int defineXtag (xtagDefinition *def, langType language)
3508643c5b5SMasatake YAMATO {
351a70e0bbeSMasatake YAMATO 	xtagObject *xobj;
3528643c5b5SMasatake YAMATO 	size_t i;
3538643c5b5SMasatake YAMATO 
354a70e0bbeSMasatake YAMATO 	Assert (def);
355a70e0bbeSMasatake YAMATO 	Assert (def->name);
356a70e0bbeSMasatake YAMATO 	for (i = 0; i < strlen (def->name); i++)
3578643c5b5SMasatake YAMATO 	{
358a70e0bbeSMasatake YAMATO 		Assert ( isalnum (def->name [i]) );
3598643c5b5SMasatake YAMATO 	}
360a70e0bbeSMasatake YAMATO 	def->letter = NUL_XTAG_LETTER;
3618643c5b5SMasatake YAMATO 
36206e8f520SMasatake YAMATO 	if (xtagObjectUsed == xtagObjectAllocated)
3638643c5b5SMasatake YAMATO 	{
36406e8f520SMasatake YAMATO 		xtagObjectAllocated *= 2;
36506e8f520SMasatake YAMATO 		xtagObjects = xRealloc (xtagObjects, xtagObjectAllocated, xtagObject);
3668643c5b5SMasatake YAMATO 	}
367a70e0bbeSMasatake YAMATO 	xobj = xtagObjects + (xtagObjectUsed);
368a70e0bbeSMasatake YAMATO 	def->xtype = xtagObjectUsed++;
369a70e0bbeSMasatake YAMATO 	xobj->def = def;
370a70e0bbeSMasatake YAMATO 	xobj->language = language;
371a70e0bbeSMasatake YAMATO 	xobj->sibling  = XTAG_UNKNOWN;
3728643c5b5SMasatake YAMATO 
373a70e0bbeSMasatake YAMATO 	updateSiblingXtag (def->xtype, def->name);
374c23a2717SMasatake YAMATO 
375c23a2717SMasatake YAMATO 	verbose ("Add extra[%d]: %s,%s in %s\n",
376c23a2717SMasatake YAMATO 			 def->xtype,
377c23a2717SMasatake YAMATO 			 def->name, def->description,
378c23a2717SMasatake YAMATO 			 getLanguageName (language));
379c23a2717SMasatake YAMATO 
380a70e0bbeSMasatake YAMATO 	return def->xtype;
3818643c5b5SMasatake YAMATO }
3828643c5b5SMasatake YAMATO 
nextSiblingXtag(xtagType type)3838643c5b5SMasatake YAMATO extern xtagType nextSiblingXtag (xtagType type)
3848643c5b5SMasatake YAMATO {
385a70e0bbeSMasatake YAMATO 	xtagObject *xobj;
3868643c5b5SMasatake YAMATO 
387a70e0bbeSMasatake YAMATO 	xobj = xtagObjects + type;
388a70e0bbeSMasatake YAMATO 	return xobj->sibling;
3898643c5b5SMasatake YAMATO }
390