예제 #1
0
파일: python.c 프로젝트: masatake/ctags
static int makeFunctionTag (const tokenInfo *const token,
                            const vString *const arglist,
                            const vString *const decorators)
{
	if (PythonKinds[K_FUNCTION].enabled)
	{
		tagEntryInfo e;

		initPythonEntry (&e, token, K_FUNCTION);

		if (arglist)
			e.extensionFields.signature = vStringValue (arglist);
		if (decorators && vStringLength (decorators) > 0)
		{
			attachParserField (&e, PythonFields[F_DECORATORS].ftype,
			                   vStringValue (decorators));
		}

		return makeTagEntry (&e);
	}

	return CORK_NIL;
}
예제 #2
0
파일: clojure.c 프로젝트: lizh06/ctags
static void makeFunctionTag (vString * const name, const char *dbp, int scope_index)
{
	functionName (name, dbp);
	if (vStringLength (name) > 0 && ClojureKinds[K_FUNCTION].enabled)
	{
		tagEntryInfo e;
		initTagEntry (&e, vStringValue (name), K_FUNCTION);
		e.lineNumber = getInputLineNumber ();
		e.filePosition = getInputFilePosition ();

		e.extensionFields.scopeIndex =  scope_index;
		makeTagEntry (&e);
	}
}
예제 #3
0
파일: lregex.c 프로젝트: NIMBIT/ctags
static void makeRegexTag (
		const vString* const name, const struct sKind* const kind)
{
	if (kind->enabled)
	{
		tagEntryInfo e;
		Assert (name != NULL  &&  vStringLength (name) > 0);
		Assert (kind != NULL);
		initTagEntry (&e, vStringValue (name));
		e.kind     = kind->letter;
		e.kindName = kind->name;
		makeTagEntry (&e);
	}
}
예제 #4
0
파일: eiffel.c 프로젝트: att/uwin
static void parseType (tokenInfo *const token)
{
    boolean bitType;
    Assert (isType (token, TOKEN_IDENTIFIER));
#ifdef TYPE_REFERENCE_TOOL
    reportType (token);
#endif
    bitType = (boolean)(strcmp ("BIT", vStringValue (token->string)) == 0);
    readToken (token);
    if (bitType && isType (token, TOKEN_NUMERIC))
	readToken (token);
    else if (isType (token, TOKEN_OPEN_BRACKET))
	parseGeneric (token, FALSE);
}
예제 #5
0
파일: perl.c 프로젝트: oscarfv/ctags
/* `end' points to the equal sign.  Parse from right to left to get the
 * identifier.  Assume we're dealing with something of form \s*\w+\s*=>
 */
static void makeTagFromLeftSide (const char *begin, const char *end,
	vString *name, vString *package)
{
	tagEntryInfo entry;
	const char *b, *e;
	if (! PerlKinds[K_CONSTANT].enabled)
		return;
	for (e = end - 1; e > begin && isspace(*e); --e)
		;
	if (e < begin)
		return;
	for (b = e; b >= begin && isIdentifier(*b); --b)
		;
	/* Identifier must be either beginning of line of have some whitespace
	 * on its left:
	 */
	if (b < begin || isspace(*b) || ',' == *b)
		++b;
	else if (b != begin)
		return;
	Assert(e - b + 1 > 0);
	vStringClear(name);
	vStringNCatS(name, b, e - b + 1);
	initTagEntry(&entry, vStringValue(name));
	entry.kind = PerlKinds[K_CONSTANT].letter;
	entry.kindName = PerlKinds[K_CONSTANT].name;
	makeTagEntry(&entry);
	if (Option.include.qualifiedTags && package && vStringLength(package)) {
		vStringClear(name);
		vStringCopy(name, package);
		vStringNCatS(name, b, e - b + 1);
		initTagEntry(&entry, vStringValue(name));
		entry.kind = PerlKinds[K_CONSTANT].letter;
		entry.kindName = PerlKinds[K_CONSTANT].name;
		makeTagEntry(&entry);
	}
}
예제 #6
0
파일: ruby.c 프로젝트: pombredanne/ctags.rb
/*
* Emits a tag for the given 'name' of kind 'kind' at the current nesting.
*/
static void emitRubyTag (vString* name, rubyKind kind)
{
	tagEntryInfo tag;
	vString* scope;
	const char *this_name;

	vStringTerminate (name);
	scope = stringListToScope (nesting);

	/* extract scope and actual name from tag name in case of tags like
	 * "class Foo::Bar::Baz" which are parsed as a single name, "Foo.Bar.Baz" */
	this_name = strrchr (vStringValue (name), '.');
	if (this_name)
	{
		if (vStringLength (scope) > 0)
			vStringPut (scope, '.');
		vStringNCat (scope, name, this_name - vStringValue (name));
		vStringTerminate (scope);
		this_name ++;
	}
	else
		this_name = vStringValue (name);

	initTagEntry (&tag, this_name);
	if (vStringLength (scope) > 0) {
	    tag.extensionFields.scope [0] = "class";
	    tag.extensionFields.scope [1] = vStringValue (scope);
	}
	tag.kindName = RubyKinds [kind].name;
	tag.kind = RubyKinds [kind].letter;
	makeTagEntry (&tag);

	stringListAdd (nesting, vStringNewCopy (name));

	vStringClear (name);
	vStringDelete (scope);
}
예제 #7
0
파일: read.c 프로젝트: qzhuyan/ctags
static void setInputFileParametersCommon (inputFileInfo *finfo, vString *const fileName,
					  const langType language,
					  void (* setLang) (inputLangInfo *, langType),
					  stringList *holder)
{
	if (finfo->name != NULL)
		vStringDelete (finfo->name);
	finfo->name = fileName;

	if (finfo->tagPath != NULL)
	{
		if (holder)
			stringListAdd (holder, finfo->tagPath);
		else
			vStringDelete (finfo->tagPath);
	}

	if (0)
		;
	else if (  Option.tagRelative == TREL_ALWAYS )
		finfo->tagPath =
			vStringNewOwn (relativeFilename (vStringValue (fileName),
							 getTagFileDirectory ()));
	else if ( Option.tagRelative == TREL_NEVER )
		finfo->tagPath =
			vStringNewOwn (absoluteFilename (vStringValue (fileName)));
	else if ( Option.tagRelative == TREL_NO || isAbsolutePath (vStringValue (fileName)) )
		finfo->tagPath = vStringNewCopy (fileName);
	else
		finfo->tagPath =
			vStringNewOwn (relativeFilename (vStringValue (fileName),
							 getTagFileDirectory ()));

	finfo->isHeader = isIncludeFile (vStringValue (fileName));

	setLang (& (finfo->langInfo), language);
}
예제 #8
0
파일: verilog.c 프로젝트: shunlir/ctags
static void findVerilogTags (void)
{
	tokenInfo *const token = newToken ();
	int c = '\0';
	currentContext = newToken ();

	while (c != EOF)
	{
		c = vGetc ();
		c = skipWhite (c);
		switch (c)
		{
			/* Store current block name whenever a : is found
			 * This is used later by any tag type that requires this information
			 * */
			case ':':
				vStringCopy (currentContext->blockName, token->name);
				break;
			/* Skip interface modport port declarations */
			case '(':
				if (currentContext && currentContext->lastKind == K_MODPORT)
				{
					skipPastMatch ("()");
				}
				break;
			/* Drop context on single statements, which don't have an end
			 * statement */
			case ';':
				if (currentContext->scope && currentContext->scope->singleStat)
				{
					verbose ("Dropping context %s\n", vStringValue (currentContext->name));
					currentContext = popToken (currentContext);
					currentContext->singleStat = FALSE;
				}
				break;
			default :
				if (isIdentifierCharacter (c))
				{
					readIdentifier (token, c);
					updateKind (token);
					findTag (token);
				}
		}
	}

	deleteToken (token);
	pruneTokens (currentContext);
	currentContext = NULL;
}
예제 #9
0
static void makeFunctionTag (const tokenInfo *const token, const vString *const arglist,
							 const char *const access)
{
	if (PowerShellKinds[K_FUNCTION].enabled)
	{
		tagEntryInfo e;

		initPowerShellEntry (&e, token, K_FUNCTION, access);

		if (arglist)
			e.extensionFields.signature = vStringValue (arglist);

		makeTagEntry (&e);
	}
}
예제 #10
0
파일: go.c 프로젝트: Dev0Null/ctags
static void makeTag (tokenInfo *const token, const goKind kind,
	tokenInfo *const parent_token, const goKind parent_kind,
	const char *argList)
{
	const char *const name = vStringValue (token->string);

	tagEntryInfo e;
	initTagEntry (&e, name, &(GoKinds [kind]));

	if (!GoKinds [kind].enabled)
		return;

	e.lineNumber = token->lineNumber;
	e.filePosition = token->filePosition;
	if (argList)
		e.extensionFields.signature = argList;

	if (parent_kind != GOTAG_UNDEFINED && parent_token != NULL)
	{
		e.extensionFields.scopeKind = &(GoKinds[parent_kind]);
		e.extensionFields.scopeName = vStringValue (parent_token->string);
	}
	makeTagEntry (&e);

	if (scope && isXtagEnabled(XTAG_QUALIFIED_TAGS))
	{
		vString *qualifiedName = vStringNew ();
		vStringCopy (qualifiedName, scope);
		vStringCatS (qualifiedName, ".");
		vStringCat (qualifiedName, token->string);
		e.name = vStringValue (qualifiedName);
		markTagExtraBit (&e, XTAG_QUALIFIED_TAGS);
		makeTagEntry (&e);
		vStringDelete (qualifiedName);
	}
}
예제 #11
0
static void matchCallbackPattern (
		const vString* const line, const regexPattern* const patbuf,
		const regmatch_t* const pmatch)
{
	regexMatch matches [BACK_REFERENCE_COUNT];
	unsigned int count = 0;
	int i;
	for (i = 0  ;  i < BACK_REFERENCE_COUNT  &&  pmatch [i].rm_so != -1  ;  ++i)
	{
		matches [i].start  = pmatch [i].rm_so;
		matches [i].length = pmatch [i].rm_eo - pmatch [i].rm_so;
		++count;
	}
	patbuf->u.callback.function (vStringValue (line), matches, count);
}
예제 #12
0
파일: verilog.c 프로젝트: shunlir/ctags
static int skipMacro (int c)
{
	tokenInfo *token = newToken ();;

	if (c == '`')
	{
		/* Skip keyword */
		if (isIdentifierCharacter (c = vGetc ()))
		{
			readIdentifier (token, c);
			c = vGetc ();
			/* Skip next keyword if macro is `ifdef or `ifndef or `elsif*/
			if (strcmp (vStringValue (token->name), "ifdef") == 0 ||
			    strcmp (vStringValue (token->name), "ifndef") == 0 ||
				strcmp (vStringValue (token->name), "elsif") == 0)
			{
				verbose ("%c\n", c);
				c = skipWhite (c);
				readIdentifier (token, c);
				c = vGetc ();
				verbose ("Skipping conditional macro %s\n", vStringValue (token->name));
			}
			/* Skip macro functions */
			else
			{
				c = skipWhite (c);
				if (c == '(')
				{
					c = skipPastMatch ("()");
				}
			}
		}
	}
	deleteToken (token);
	return c;
}
예제 #13
0
파일: eiffel.c 프로젝트: amosbird/ctags
static void makeEiffelLocalTag (tokenInfo *const token)
{
	if (EiffelKinds [EKIND_LOCAL].enabled && isXtagEnabled(XTAG_FILE_SCOPE))
	{
		const char *const name = vStringValue (token->string);
		vString* scope = vStringNew ();
		tagEntryInfo e;

		initTagEntry (&e, name, &(EiffelKinds [EKIND_LOCAL]));

		e.isFileScope = TRUE;
		markTagExtraBit (&e, XTAG_FILE_SCOPE);

		vStringCopy (scope, token->className);
		vStringPut (scope, '.');
		vStringCat (scope, token->featureName);

		e.extensionFields.scopeKind = &(EiffelKinds [EKIND_FEATURE]);
		e.extensionFields.scopeName = vStringValue (scope);

		makeTagEntry (&e);
		vStringDelete (scope);
	}
}
예제 #14
0
파일: tex.c 프로젝트: shunlir/ctags
static void makeTexTag (tokenInfo *const token, texKind kind)
{
	if (TexKinds [kind].enabled)
	{
		const char *const name = vStringValue (token->string);
		vString *parentKind = vStringNew();
		vString *parentName = vStringNew();
		tagEntryInfo e;
		initTagEntry (&e, name, &(TexKinds [kind]));

		e.lineNumber   = token->lineNumber;
		e.filePosition = token->filePosition;

		getScopeInfo(kind, parentKind, parentName);
		if (vStringLength(parentKind) > 0) {
			e.extensionFields.scopeKind = kindFromName (vStringValue(parentKind));
			e.extensionFields.scopeName = vStringValue(parentName);
		}

		makeTagEntry (&e);
		vStringDelete (parentKind);
		vStringDelete (parentName);
	}
}
예제 #15
0
파일: json.c 프로젝트: SuvratAgrawal/geany
static void makeJsonTag (tokenInfo *const token, const jsonKind kind)
{
	tagEntryInfo e;

	if (! JsonKinds[kind].enabled)
		return;

	initTagEntry (&e, vStringValue (token->string));

	e.lineNumber	= token->lineNumber;
	e.filePosition	= token->filePosition;
	e.kindName		= JsonKinds[kind].name;
	e.kind			= JsonKinds[kind].letter;

	if (vStringLength (token->scope) > 0)
	{
		Assert (token->scopeKind > TAG_NONE && token->scopeKind < TAG_COUNT);

		e.extensionFields.scope[0] = JsonKinds[token->scopeKind].name;
		e.extensionFields.scope[1] = vStringValue (token->scope);
	}

	makeTagEntry (&e);
}
예제 #16
0
static void createPascalTag (tagEntryInfo* const tag,
							 const vString* const name, const int kind,
							 const char *arglist, const char *vartype)
{
	if (PascalKinds [kind].enabled  &&  name != NULL  &&  vStringLength (name) > 0)
	{
		initTagEntry (tag, vStringValue (name), &(PascalKinds [kind]));

		tag->extensionFields.signature = arglist;
		tag->extensionFields.varType = vartype;
	}
	else
		/* TODO: Passing NULL as name makes an assertion behind initTagEntry failure */
		initTagEntry (tag, NULL, NULL);
}
예제 #17
0
파일: clojure.c 프로젝트: amosbird/ctags
static int makeNamespaceTag (vString * const name, const char *dbp)
{
	functionName (name, dbp);
	if (vStringLength (name) > 0 && ClojureKinds[K_NAMESPACE].enabled)
	{
		tagEntryInfo e;
		initTagEntry (&e, vStringValue (name), &(ClojureKinds[K_NAMESPACE]));
		e.lineNumber = getInputLineNumber ();
		e.filePosition = getInputFilePosition ();

		return makeTagEntry (&e);
	}
	else
		return CORK_NIL;
}
예제 #18
0
파일: parse.c 프로젝트: FelikZ/ctags
/*  The name of the language interpreter, either directly or as the argument
 *  to "env".
 */
static vString* determineInterpreter (const char* const cmd)
{
	vString* const interpreter = vStringNew ();
	const char* p = cmd;
	do
	{
		vStringClear (interpreter);
		for ( ;  isspace ((int) *p)  ;  ++p)
			;  /* no-op */
		for ( ;  *p != '\0'  &&  ! isspace ((int) *p)  ;  ++p)
			vStringPut (interpreter, (int) *p);
		vStringTerminate (interpreter);
	} while (strcmp (vStringValue (interpreter), "env") == 0);
	return interpreter;
}
예제 #19
0
파일: plist.c 프로젝트: amosbird/ctags
static void plistFindTagsUnderKey (xmlNode *node,
				   const struct sTagXpathRecurSpec *spec,
				   xmlXPathContext *ctx,
				   void *userData)
{
	xmlNode *current;
	xmlNode *prev;
	stringList *queue;
	vString* path;
	vString* v;
	int c;

	queue = stringListNew ();
	current = node;
	for (current = node; current; current = current->parent)
	{
		if (isCompoundElement (current)
		    && (prev = getPrevKeyElement (current)))
		{
			char* parent = (char *)xmlNodeGetContent (prev);
			if (parent)
			{
				v = vStringNewInit (parent);
				stringListAdd (queue, v);
				xmlFree (parent);
			}
		}
	}

	path = vStringNew ();
	while ((c = stringListCount (queue)) > 0)
	{
		v = stringListLast (queue);
		vStringCat (path, v);
		vStringDelete (v);
		stringListRemoveLast (queue);
		if (c != 1)
			vStringPut (path, '.');
	}
	stringListDelete (queue);

	findXMLTags (ctx, node,
		     plistXpathTableTable + TABLE_TEXT,
		     PlistKinds,
		     (vStringLength (path) > 0)? vStringValue (path): NULL);

	vStringDelete (path);
}
예제 #20
0
파일: eiffel.c 프로젝트: amosbird/ctags
static int parseEscapedCharacter (void)
{
	int d = '\0';
	int c = getcFromInputFile ();

	switch (c)
	{
		case 'A':  d = '@';   break;
		case 'B':  d = '\b';  break;
		case 'C':  d = '^';   break;
		case 'D':  d = '$';   break;
		case 'F':  d = '\f';  break;
		case 'H':  d = '\\';  break;
		case 'L':  d = '~';   break;
		case 'N':  d = '\n';  break;
		case 'Q':  d = '`';   break;
		case 'R':  d = '\r';  break;
		case 'S':  d = '#';   break;
		case 'T':  d = '\t';  break;
		case 'U':  d = '\0';  break;
		case 'V':  d = '|';   break;
		case '%':  d = '%';   break;
		case '\'': d = '\'';  break;
		case '"':  d = '"';   break;
		case '(':  d = '[';   break;
		case ')':  d = ']';   break;
		case '<':  d = '{';   break;
		case '>':  d = '}';   break;

		case '\n': skipToCharacter ('%'); break;

		case '/':
		{
			vString *string = parseInteger ('\0');
			const char *value = vStringValue (string);
			const unsigned long ascii = atol (value);
			vStringDelete (string);

			c = getcFromInputFile ();
			if (c == '/'  &&  ascii < 256)
				d = ascii;
			break;
		}

		default: break;
	}
	return d;
}
예제 #21
0
static void matchTagPattern (const vString* const line,
		const regexPattern* const patbuf,
		const regmatch_t* const pmatch)
{
	vString *const name = substitute (vStringValue (line),
			patbuf->u.tag.name_pattern, BACK_REFERENCE_COUNT, pmatch);
	vStringStripLeading (name);
	vStringStripTrailing (name);
	if (vStringLength (name) > 0)
		makeRegexTag (name, &patbuf->u.tag.kind);
	else
		error (WARNING, "%s:%ld: null expansion of name pattern \"%s\"",
			getInputFileName (), getInputLineNumber (),
			patbuf->u.tag.name_pattern);
	vStringDelete (name);
}
예제 #22
0
파일: sml.c 프로젝트: 0xeuclid/vim_for_UEFI
static smlKind findNextIdentifier (const unsigned char **cp)
{
	smlKind result = K_NONE;
	vString *const identifier = vStringNew ();
	unsigned int count = sizeof (SmlKeywordTypes) / sizeof (SmlKeywordTypes [0]);
	unsigned int i;
	*cp = parseIdentifier (*cp, identifier);
	for (i = 0  ;  i < count  &&  result == K_NONE ;  ++i)
	{
		const char *id = vStringValue (identifier);
		if (strcmp (id, SmlKeywordTypes [i].keyword) == 0)
			result = SmlKeywordTypes [i].kind;
	}
	vStringDelete (identifier);
	return result;
}
예제 #23
0
파일: tex.c 프로젝트: pasnox/monkeystudio2
static void makeConstTag (tokenInfo *const token, const texKind kind)
{
    if (TexKinds [kind].enabled )
    {
        const char *const name = vStringValue (token->string);
        tagEntryInfo e;
        initTagEntry (&e, name);

        e.lineNumber   = token->lineNumber;
        e.filePosition = token->filePosition;
        e.kindName     = TexKinds [kind].name;
        e.kind         = TexKinds [kind].letter;

        makeTagEntry (&e);
    }
}
예제 #24
0
파일: objc.c 프로젝트: simlrh/ctags
static void parsePreproc (vString * const ident, objcToken what)
{
	switch (what)
	{
	case ObjcIDENTIFIER:
		if (strcmp (vStringValue (ident), "define") == 0)
			toDoNext = &parseMacroName;
		else
			toDoNext = &ignorePreprocStuff;
		break;

	default:
		toDoNext = &ignorePreprocStuff;
		break;
	}
}
예제 #25
0
파일: main.c 프로젝트: koron/ctags
static boolean createTagsForWildcardEntry (
		const char *const pattern, const size_t dirLength,
		const char *const entryName)
{
	boolean resize = FALSE;
	/* we must not recurse into the directories "." or ".." */
	if (strcmp (entryName, ".") != 0  &&  strcmp (entryName, "..") != 0)
	{
		vString *const filePath = vStringNew ();
		vStringNCopyS (filePath, pattern, dirLength);
		vStringCatS (filePath, entryName);
		resize = createTagsForEntry (vStringValue (filePath));
		vStringDelete (filePath);
	}
	return resize;
}
예제 #26
0
파일: lregex.c 프로젝트: alx741/ctags
static int makeRegexTag (
		const vString* const name, const kindOption* const kind, int scopeIndex, int placeholder)
{
	if (kind->enabled)
	{
		tagEntryInfo e;
		Assert (name != NULL  &&  ((vStringLength (name) > 0) || placeholder));
		Assert (kind != NULL);
		initTagEntry (&e, vStringValue (name), kind);
		e.extensionFields.scopeIndex = scopeIndex;
		e.placeholder = !!placeholder;
		return makeTagEntry (&e);
	}
	else
		return SCOPE_NIL;
}
예제 #27
0
파일: pascal.c 프로젝트: 15ramky/geany
static void createPascalTag (tagEntryInfo* const tag,
			     const vString* const name, const int kind,
			     const char *arglist, const char *vartype)
{
    if (PascalKinds [kind].enabled  &&  name != NULL  &&  vStringLength (name) > 0)
    {
        initTagEntry (tag, vStringValue (name));

        tag->kindName = PascalKinds [kind].name;
        tag->kind     = PascalKinds [kind].letter;
        tag->extensionFields.arglist = arglist;
        tag->extensionFields.varType = vartype;
    }
    else
        initTagEntry (tag, NULL);
}
예제 #28
0
static bool newIdentifierAsHeadOfMemberNotify (struct sCxxSubparser *pSubparser,
											   CXXToken *pToken)
{
	struct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser *)pSubparser;
	keywordId keyword = lookupKeyword (vStringValue (pToken->pszWord), Lang_QtMoc);

	if (keyword == KEYWORD_QOBJECT)
	{
		if (pQtMoc->iDepthOfQtClass == 0)
			pQtMoc->iDepthOfQtClass = pQtMoc->iBlockDepth;
		CXX_DEBUG_PRINT("Found \"Q_OBJECT\" Qt Object Marker in depth: %d",
						pQtMoc->iDepthOfQtClass);
		return true;
	}
	return false;
}
예제 #29
0
파일: eiffel.c 프로젝트: Figoer/i_figoer
static void makeEiffelClassTag (tokenInfo *const token)
{
    if (EiffelKinds [EKIND_CLASS].enabled)
    {
        const char *const name = vStringValue (token->string);
        tagEntryInfo e;

        initTagEntry (&e, name);

        e.kindName = EiffelKinds [EKIND_CLASS].name;
        e.kind     = EiffelKinds [EKIND_CLASS].letter;

        makeTagEntry (&e);
    }
    vStringCopy (token->className, token->string);
}
예제 #30
0
파일: python.c 프로젝트: MihailZenkov/geany
/* Given a string with the contents of a line directly after the "def" keyword,
 * extract all relevant information and create a tag.
 */
static void makeFunctionTag (vString *const function,
	vString *const parent, int is_class_parent, const char *arglist)
{
	tagEntryInfo tag;
	initTagEntry (&tag, vStringValue (function));

	tag.kindName = PythonKinds[K_FUNCTION].name;
	tag.kind = PythonKinds[K_FUNCTION].letter;
	tag.extensionFields.arglist = arglist;
	/* add argument list of __init__() methods to the class tag */
	if (strcmp (vStringValue (function), "__init__") == 0 && parent != NULL)
	{
		const char *parent_tag_name = get_class_name_from_parent (vStringValue (parent));
		if (parent_tag_name != NULL)
			setTagArglistByName (parent_tag_name, arglist);
	}

	if (vStringLength (parent) > 0)
	{
		if (is_class_parent)
		{
			tag.kindName = PythonKinds[K_METHOD].name;
			tag.kind = PythonKinds[K_METHOD].letter;
			tag.extensionFields.scope [0] = "class";
			tag.extensionFields.scope [1] = vStringValue (parent);
		}
		else
		{
			tag.extensionFields.scope [0] = "function";
			tag.extensionFields.scope [1] = vStringValue (parent);
		}
	}

	/* If a function starts with __, we mark it as file scope.
	 * FIXME: What is the proper way to signal such attributes?
	 * TODO: What does functions/classes starting with _ and __ mean in python?
	 */
	if (strncmp (vStringValue (function), "__", 2) == 0 &&
		strcmp (vStringValue (function), "__init__") != 0)
	{
		tag.extensionFields.access = "private";
		tag.isFileScope = TRUE;
	}
	else
	{
		tag.extensionFields.access = "public";
	}
	makeTagEntry (&tag);
}