예제 #1
0
파일: scheme.c 프로젝트: qzhuyan/ctags
static void findSchemeTags (void)
{
	vString *name = vStringNew ();
	const unsigned char *line;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		const unsigned char *cp = line;

		if (cp [0] == '(' &&
			(cp [1] == 'D' || cp [1] == 'd') &&
			(cp [2] == 'E' || cp [2] == 'e') &&
			(cp [3] == 'F' || cp [3] == 'f'))
		{
			while (*cp != '\0'  &&  !isspace (*cp))
				cp++;
			/* Skip over open parens and white space */
			do {
				while (*cp != '\0' && (isspace (*cp) || *cp == '('))
					cp++;
				if (*cp == '\0')
					cp = line = readLineFromInputFile ();
				else
					break;
			} while (line);
			if (line == NULL)
				break;
			readIdentifier (name, cp);
			makeSimpleTag (name, SchemeKinds, K_FUNCTION);
		}
		if (cp [0] == '(' &&
			(cp [1] == 'S' || cp [1] == 's') &&
			(cp [2] == 'E' || cp [2] == 'e') &&
			(cp [3] == 'T' || cp [3] == 't') &&
			(cp [4] == '!') &&
			(isspace (cp [5]) || cp[5] == '\0'))
		{
			cp += 5;
			/* Skip over white space */
			do {
				while (*cp != '\0' && isspace (*cp))
					cp++;
				if (*cp == '\0')
					cp = line = readLineFromInputFile ();
				else
					break;
			} while (line);
			if (line == NULL)
				break;
			readIdentifier (name, cp);
			makeSimpleTag (name, SchemeKinds, K_SET);
		}
	}
	vStringDelete (name);
}
예제 #2
0
파일: clojure.c 프로젝트: amosbird/ctags
static void findClojureTags (void)
{
	vString *name = vStringNew ();
	const char *p;
	int scope_index = CORK_NIL;

	while ((p = (char *)readLineFromInputFile ()) != NULL)
	{
		vStringClear (name);

		while (isspace (*p))
			p++;

		if (*p == '(')
		{
			if (isNamespace (p))
			{
				skipToSymbol (&p);
				scope_index = makeNamespaceTag (name, p);
			}
			else if (isFunction (p))
			{
				skipToSymbol (&p);
				makeFunctionTag (name, p, scope_index);
			}
		}
	}
	vStringDelete (name);
}
예제 #3
0
파일: markdown.c 프로젝트: ParrotSec/geany
static void findMarkdownTags (void)
{
	vString *name = vStringNew();
	const unsigned char *line;

	while ((line = readLineFromInputFile()) != NULL)
	{
		int name_len = vStringLength(name);

		/* underlines must be the same length or more */
		if (name_len > 0 &&	(line[0] == '=' || line[0] == '-') && issame((const char*) line))
		{
			makeMarkdownTag(name, true);
		}
		else if (line[0] == '#') {
			vStringClear(name);
			vStringCatS(name, (const char *) line);
			makeMarkdownTag(name, false);
		}
		else {
			vStringClear (name);
			if (! isspace(*line))
				vStringCatS(name, (const char*) line);
		}
	}
	vStringDelete (name);
}
예제 #4
0
static void findBasicTags (void)
{
	const char *line;
	KeyWord *keywords;

	keywords = freebasic_keywords;

	while ((line = (const char *) readLineFromInputFile ()) != NULL)
	{
		const char *p = line;
		KeyWord const *kw;

		while (isspace (*p))
			p++;

		/* Empty line or comment? */
		if (!*p || *p == '\'')
			continue;

		/* In Basic, keywords always are at the start of the line. */
		for (kw = keywords; kw->token; kw++)
			if (match_keyword (p, kw)) break;

		/* Is it a label? */
		match_colon_label (p);
	}
}
예제 #5
0
파일: objc.c 프로젝트: pragmaware/ctags
static void eatComment (lexingState * st)
{
	bool unfinished = true;
	bool lastIsStar = false;
	const unsigned char *c = st->cp + 2;

	while (unfinished)
	{
		/* we've reached the end of the line..
		 * so we have to reload a line... */
		if (c == NULL || *c == '\0')
		{
			st->cp = readLineFromInputFile ();
			/* WOOPS... no more input...
			 * we return, next lexing read
			 * will be null and ok */
			if (st->cp == NULL)
				return;
			c = st->cp;
		}
		/* we've reached the end of the comment */
		else if (*c == '/' && lastIsStar)
			unfinished = false;
		else
		{
			lastIsStar = '*' == *c;
			c++;
		}
	}

	st->cp = c;
}
예제 #6
0
파일: ocaml.c 프로젝트: Dev0Null/ctags
static void eatComment (lexingState * st)
{
	boolean unfinished = TRUE;
	boolean lastIsStar = FALSE;
	const unsigned char *c = st->cp + 2;

	while (unfinished)
	{
		/* we've reached the end of the line..
		 * so we have to reload a line... */
		if (c == NULL || *c == '\0')
		{
			st->cp = readLineFromInputFile ();
			/* WOOPS... no more input...
			 * we return, next lexing read
			 * will be null and ok */
			if (st->cp == NULL)
				return;
			c = st->cp;
		}
		/* we've reached the end of the comment */
		else if (*c == ')' && lastIsStar)
			unfinished = FALSE;
		/* here we deal with imbricated comment, which
		 * are allowed in OCaml */
		else if (c[0] == '(' && c[1] == '*')
		{
			st->cp = c;
			eatComment (st);

			c = st->cp;
			if (c == NULL)
			    return;

			lastIsStar = FALSE;
            c++;
		}
		/* OCaml has a rule which says :
		 *
		 *   "Comments do not occur inside string or character literals.
		 *    Nested comments are handled correctly."
		 *
		 * So if we encounter a string beginning, we must parse it to
		 * get a good comment nesting (bug ID: 3117537)
		 */
        else if (*c == '"')
        {
            st->cp = c;
            eatString (st);
            c = st->cp;
        }
		else
        {
			lastIsStar = '*' == *c;
            c++;
        }
	}

	st->cp = c;
}
예제 #7
0
파일: ocaml.c 프로젝트: Dev0Null/ctags
static void findOcamlTags (void)
{
	vString *name = vStringNew ();
	lexingState st;
	ocaToken tok;

	initStack ();
	computeModuleName ();
	tempIdent = vStringNew ();
	lastModule = vStringNew ();
	lastClass = vStringNew ();
	voidName = vStringNew ();
	vStringCopyS (voidName, "_");

	st.name = vStringNew ();
	st.cp = readLineFromInputFile ();
	toDoNext = &globalScope;
	tok = lex (&st);
	while (tok != Tok_EOF)
	{
		(*toDoNext) (st.name, tok);
		tok = lex (&st);
	}

	vStringDelete (st.name);
	vStringDelete (name);
	vStringDelete (voidName);
	vStringDelete (tempIdent);
	vStringDelete (lastModule);
	vStringDelete (lastClass);
	clearStack ();
}
예제 #8
0
파일: awk.c 프로젝트: amosbird/ctags
static void findAwkTags (void)
{
	vString *name = vStringNew ();
	const unsigned char *line;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		if (strncmp ((const char*) line, "function", (size_t) 8) == 0  &&
			isspace ((int) line [8]))
		{
			const unsigned char *cp = line + 8;

			while (isspace ((int) *cp))
				++cp;
			while (isalnum ((int) *cp)  ||  *cp == '_')
			{
				vStringPut (name, (int) *cp);
				++cp;
			}
			vStringTerminate (name);
			while (isspace ((int) *cp))
				++cp;
			if (*cp == '(')
				makeSimpleTag (name, AwkKinds, K_FUNCTION);
			vStringClear (name);
			if (*cp != '\0')
				++cp;
		}
	}
	vStringDelete (name);
}
예제 #9
0
파일: docbook.c 프로젝트: giuspen/geany
static void findDocBookTags(void)
{
    const char *line;

    while ((line = (const char*)readLineFromInputFile()) != NULL)
    {
        const char *cp = line;

        for (; *cp != '\0'; cp++)
        {
            if (*cp == '<')
            {
                cp++;

                /* <section id="..."> */
                if (getWord("section", &cp))
                {
                    createTag(K_SECTION, cp);
                    continue;
                }
                /* <sect1 id="..."> */
                if (getWord("sect1", &cp))
                {
                    createTag(K_SECT1, cp);
                    continue;
                }
                /* <sect2 id="..."> */
                if (getWord("sect2", &cp))
                {
                    createTag(K_SECT2, cp);
                    continue;
                }
                /* <sect3 id="..."> */
                if (getWord("sect3", &cp) ||
                        getWord("sect4", &cp) ||
                        getWord("sect5", &cp))
                {
                    createTag(K_SECT3, cp);
                    continue;
                }
                /* <chapter id="..."> */
                if (getWord("chapter", &cp))
                {
                    createTag(K_CHAPTER, cp);
                    continue;
                }
                /* <appendix id="..."> */
                if (getWord("appendix", &cp))
                {
                    createTag(K_APPENDIX, cp);
                    continue;
                }
            }
        }
    }
}
예제 #10
0
파일: perl.c 프로젝트: pjkack/ctags
/*
 * Perl subroutine declaration may look like one of the following:
 *
 *  sub abc;
 *  sub abc :attr;
 *  sub abc (proto);
 *  sub abc (proto) :attr;
 *
 * Note that there may be more than one attribute.  Attributes may
 * have things in parentheses (they look like arguments).  Anything
 * inside of those parentheses goes.  Prototypes may contain semi-colons.
 * The matching end when we encounter (outside of any parentheses) either
 * a semi-colon (that'd be a declaration) or an left curly brace
 * (definition).
 *
 * This is pretty complicated parsing (plus we all know that only perl can
 * parse Perl), so we are only promising best effort here.
 *
 * If we can't determine what this is (due to a file ending, for example),
 * we will return false.
 */
static bool isSubroutineDeclaration (const unsigned char *cp)
{
	bool attr = false;
	int nparens = 0;

	do {
		for ( ; *cp; ++cp) {
SUB_DECL_SWITCH:
			switch (*cp) {
				case ':':
					if (nparens)
						break;
					else if (true == attr)
						return false;    /* Invalid attribute name */
					else
						attr = true;
					break;
				case '(':
					++nparens;
					break;
				case ')':
					--nparens;
					break;
				case ' ':
				case '\t':
					break;
				case ';':
					if (!nparens)
						return true;
				case '{':
					if (!nparens)
						return false;
				default:
					if (attr) {
						if (isIdentifier1(*cp)) {
							cp++;
							while (isIdentifier (*cp))
								cp++;
							attr = false;
							goto SUB_DECL_SWITCH; /* Instead of --cp; */
						} else {
							return false;
						}
					} else if (nparens) {
						break;
					} else {
						return false;
					}
			}
		}
	} while (NULL != (cp = readLineFromInputFile ()));

	return false;
}
예제 #11
0
파일: vim.c 프로젝트: amosbird/ctags
static const unsigned char *readVimballLine (void)
{
	const unsigned char *line;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		break;
	}

	return line;
}
예제 #12
0
파일: windres.c 프로젝트: pjkack/ctags
static void findResTags(void)
{
	const unsigned char *line;
	ResParserState state = P_STATE_NONE;
	_blockDepth = 0;

	while ((line = readLineFromInputFile()) != NULL)
	{
		state = parseResLine(line, state);
		if (state == P_STATE_AT_END)
			return;
	}
}
예제 #13
0
파일: sml.c 프로젝트: masatake/ctags
static void findSmlTags (void)
{
	vString *const identifier = vStringNew ();
	const unsigned char *line;
	smlKind lastTag = K_NONE;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		const unsigned char *cp = skipSpace (line);
		do
		{
			smlKind foundTag;
			if (CommentLevel != 0)
			{
				cp = (const unsigned char *) strstr ((const char *) cp, "*)");
				if (cp == NULL)
					continue;
				else
				{
					--CommentLevel;
					cp += 2;
				}
			}
			foundTag = findNextIdentifier (&cp);
			if (foundTag != K_NONE)
			{
				cp = skipSpace (cp);
				cp = parseIdentifier (cp, identifier);
				if (foundTag == K_AND)
				{
					if (lastTag != K_NONE)
						makeSmlTag (lastTag, identifier);
				}
				else
				{
					makeSmlTag (foundTag, identifier);
					lastTag = foundTag;
				}
			}
			if (strstr ((const char *) cp, "(*") != NULL)
			{
				cp += 2;
				cp = (const unsigned char *) strstr ((const char *) cp, "*)");
				if (cp == NULL)
					++CommentLevel;
			}
		} while (cp != NULL  &&  strcmp ((const char *) cp, "") != 0);
	}
	vStringDelete (identifier);
}
예제 #14
0
파일: sh.c 프로젝트: ParrotSec/geany
static void findShTags (void)
{
	vString *name = vStringNew ();
	const unsigned char *line;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		const unsigned char* cp = line;
		bool functionFound = false;

		if (line [0] == '#')
			continue;

		while (isspace (*cp))
			cp++;
		if (strncmp ((const char*) cp, "function", (size_t) 8) == 0  &&
			isspace ((int) cp [8]))
		{
			functionFound = true;
			cp += 8;
			if (! isspace ((int) *cp))
				continue;
			while (isspace ((int) *cp))
				++cp;
		}
		if (! (isalnum ((int) *cp) || *cp == '_'))
			continue;
		while (isalnum ((int) *cp)  ||  *cp == '_')
		{
			vStringPut (name, (int) *cp);
			++cp;
		}
		while (isspace ((int) *cp))
			++cp;
		if (*cp++ == '(')
		{
			while (isspace ((int) *cp))
				++cp;
			if (*cp == ')'  && ! hackReject (name))
				functionFound = true;
		}
		if (functionFound)
			makeSimpleTag (name, ShKinds, K_FUNCTION);
		vStringClear (name);
	}
	vStringDelete (name);
}
예제 #15
0
파일: vim.c 프로젝트: amosbird/ctags
static const unsigned char *readVimLine (void)
{
	const unsigned char *line;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		while (isspace ((int) *line))
			++line;

		if ((int) *line == '"')
			continue;  /* skip comment */

		break;
	}

	return line;
}
예제 #16
0
파일: lisp.c 프로젝트: pjkack/ctags
/* Algorithm adapted from from GNU etags.
 */
static void findLispTags (void)
{
	vString *name = vStringNew ();
	const unsigned char* p;


	while ((p = readLineFromInputFile ()) != NULL)
	{
		if (*p == '(')
		{
			if (L_isdef (p))
			{
				while (*p != '\0' && !isspace ((int) *p))
					p++;
				while (isspace ((int) *p))
					p++;
				L_getit (name, p);
			}
			else
			{
				/* Check for (foo::defmumble name-defined ... */
				do
					p++;
				while (*p != '\0' && !isspace ((int) *p)
						&& *p != ':' && *p != '(' && *p != ')');
				if (*p == ':')
				{
					do
						p++;
					while (*p == ':');

					if (L_isdef (p - 1))
					{
						while (*p != '\0' && !isspace ((int) *p))
							p++;
						while (isspace (*p))
							p++;
						L_getit (name, p);
					}
				}
			}
		}
	}
	vStringDelete (name);
}
예제 #17
0
파일: perl.c 프로젝트: pjkack/ctags
/* Parse constants declared via hash reference, like this:
 * use constant {
 *   A => 1,
 *   B => 2,
 * };
 * The approach we take is simplistic, but it covers the vast majority of
 * cases well.  There can be some false positives.
 * Returns 0 if found the end of the hashref, -1 if we hit EOF
 */
static int parseConstantsFromHashRef (const unsigned char *cp,
	vString *name, vString *package)
{
	while (1) {
		enum const_state state =
			parseConstantsFromLine((const char *) cp, name, package);
		switch (state) {
			case CONST_STATE_NEXT_LINE:
				cp = readLineFromInputFile();
				if (cp)
					break;
				else
					return -1;
			case CONST_STATE_HIT_END:
				return 0;
		}
	}
}
예제 #18
0
파일: rst.c 프로젝트: blackb1rd/ctags
/* TODO: parse overlining & underlining as distinct sections. */
static void findRstTags (void)
{
    vString *name = vStringNew ();
    fpos_t filepos;
    const unsigned char *line;

    memset(&filepos, 0, sizeof(fpos_t));
    memset(kindchars, 0, sizeof kindchars);
    nestingLevels = nestingLevelsNew();

    while ((line = readLineFromInputFile ()) != NULL)
    {
        int line_len = strlen((const char*) line);
        int name_len_bytes = vStringLength(name);
        int name_len = utf8_strlen(vStringValue(name), name_len_bytes);

        /* if the name doesn't look like UTF-8, assume one-byte charset */
        if (name_len < 0)
            name_len = name_len_bytes;

        /* underlines must be the same length or more */
        if (line_len >= name_len && name_len > 0 &&
                ispunct(line[0]) && issame((const char*) line))
        {
            char c = line[0];
            int kind = get_kind(c);

            if (kind >= 0)
            {
                makeRstTag(name, kind, filepos);
                continue;
            }
        }
        vStringClear (name);
        if (!isspace(*line))
        {
            vStringCatS(name, (const char*)line);
            filepos = getInputFilePosition();
        }
        vStringTerminate(name);
    }
    vStringDelete (name);
    nestingLevelsFree(nestingLevels);
}
예제 #19
0
파일: tcl.c 프로젝트: pjkack/ctags
static void findTclTags (void)
{
	vString *name = vStringNew ();
	const unsigned char *line;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		const unsigned char *cp;

		while (isspace (line [0])) 
			++line;
		
		if (line [0] == '\0'  ||  line [0] == '#')
			continue;

		/* read first word */
		for (cp = line ; *cp != '\0'  &&  ! isspace ((int) *cp) ; ++cp)
			;
		if (! isspace ((int) *cp))
			continue;
		while (isspace ((int) *cp))
			++cp;
		/* Now `line' points at first word and `cp' points at next word */

		if (match (line, "proc"))
			cp = makeTclTag (cp, name, K_PROCEDURE);
		else if (match (line, "class") || match (line, "itcl::class"))
			cp = makeTclTag (cp, name, K_CLASS);
		else if (match (line, "public") ||
				match (line, "protected") ||
				match (line, "private"))
		{
			if (match (cp, "method"))
			{
				cp += 6;
				while (isspace ((int) *cp))
					++cp;
				cp = makeTclTag (cp, name, K_METHOD);
			}
		}
	}
	vStringDelete (name);
}
예제 #20
0
파일: rpmspec.c 프로젝트: dkearns/ctags
static void found_macro_cb (const char *line,
			    const regexMatch *matches,
			    unsigned int count,
			    void *uesrData)
{
	struct macro_cb_data *data = uesrData;

	if (count > 0)
	{
		vString *signature = ((count > 1) && (matches[2].length > 0))? vStringNew(): NULL;
		vString *name = vStringNew ();
		tagEntryInfo tag;

		if (signature)
			vStringNCopyS (signature, line + matches[2].start, matches[2].length);
		vStringNCopyS (name, line + matches[1].start, matches[1].length);

		if (data->rindex == ROLE_INDEX_DEFINITION)
			initTagEntry (&tag, vStringValue (name), &(RpmSpecKinds[data->kindex]));
		else
			initRefTagEntry (&tag, vStringValue (name), &(RpmSpecKinds[data->kindex]), data->rindex);

		if (signature)
			tag.extensionFields.signature = vStringValue (signature);

		/* Skip the definition */
		while (line && is_line_continued (line))
		{
			rejecting = TRUE;
			line = (const char *)readLineFromInputFile ();
		}
		rejecting = FALSE;

		tag.extensionFields.endLine = getInputLineNumber();

		makeTagEntry (&tag);

		vStringDelete (name);
		if (signature)
			vStringDelete (signature);
	}
}
예제 #21
0
파일: entry.c 프로젝트: mapad/ctags
extern void makeFileTag (const char *const fileName)
{
	boolean via_line_directive = (strcmp (fileName, getInputFileName()) != 0);
	xtagType     xtag = XTAG_UNKNOWN;

	if (isXtagEnabled(XTAG_FILE_NAMES))
		xtag = XTAG_FILE_NAMES;
	if (isXtagEnabled(XTAG_FILE_NAMES_WITH_TOTAL_LINES))
		xtag = XTAG_FILE_NAMES_WITH_TOTAL_LINES;

	if (xtag != XTAG_UNKNOWN)
	{
		tagEntryInfo tag;
		kindOption  *kind;

		kind = getInputLanguageFileKind();
		Assert (kind);
		kind->enabled = isXtagEnabled(XTAG_FILE_NAMES);

		/* TODO: you can return here if enabled == FALSE. */

		initTagEntry (&tag, baseFilename (fileName), kind);

		tag.isFileEntry     = TRUE;
		tag.lineNumberEntry = TRUE;
		markTagExtraBit (&tag, xtag);

		if (via_line_directive || (!isXtagEnabled(XTAG_FILE_NAMES_WITH_TOTAL_LINES)))
		{
			tag.lineNumber = 1;
		}
		else
		{
			while (readLineFromInputFile () != NULL)
				;		/* Do nothing */
			tag.lineNumber = getInputLineNumber ();
		}

		makeTagEntry (&tag);
	}
}
예제 #22
0
파일: perl6.c 프로젝트: Dev0Null/ctags
/* Read next contiguous sequence of non-whitespace characters, store
 * the address in `ptok', and return its length.  Return value of zero
 * means EOF.
 *
 * TODO: Currently, POD and multi-line comments are not handled.
 */
static int
getNonSpaceStr (struct p6Ctx *ctx, const char **ptok)
{
    const char *s = ctx->line;
    if (!s) {
next_line:
        s = (const char *) readLineFromInputFile();
        if (!s)
            return 0;                           /* EOF */
    }
    while (*s && isspace(*s))                   /* Skip whitespace */
        ++s;
    if ('#' == *s)
        goto next_line;
    int non_white_len = strcspn(s, ",; \t");
    if (non_white_len) {
        ctx->line = s + non_white_len;          /* Save state */
        *ptok = s;
        return non_white_len;
    } else
        goto next_line;
}
예제 #23
0
static void findAbaqusTags(void)
{
    const char *line;

    while ((line = (const char*)readLineFromInputFile()) != NULL)
    {
        const char *cp = line;

        for (; *cp != '\0'; cp++)
        {
            if (*cp == '*')
            {
                cp++;

                /* Parts*/
                if (getWord("part", &cp))
                {
                    createTag(K_PART, cp);
                    continue;
                }
                /* Assembly */
                if (getWord("assembly", &cp))
                {
                    createTag(K_ASSEMBLY, cp);
                    continue;
                }
                /* Steps */
                if (getWord("step", &cp))
                {
                    createTag(K_STEP, cp);
                    continue;
                }
            }
        }
    }
}
예제 #24
0
파일: basic.c 프로젝트: dkearns/ctags
static void findBasicTags (void)
{
	const char *line;
	const char *extension = fileExtension (getInputFileName ());
	KeyWord *keywords;

	if (strcmp (extension, "bb") == 0)
		keywords = blitzbasic_keywords;
	else if (strcmp (extension, "pb") == 0)
		keywords = purebasic_keywords;
	else
		keywords = freebasic_keywords;

	while ((line = (const char *) readLineFromInputFile ()) != NULL)
	{
		const char *p = line;
		KeyWord const *kw;

		while (isspace (*p))
			p++;

		/* Empty line? */
		if (!*p)
			continue;

		/* In Basic, keywords always are at the start of the line. */
		for (kw = keywords; kw->token; kw++)
			if (match_keyword (p, kw)) break;

		/* Is it a label? */
		if (strcmp (extension, "bb") == 0)
			match_dot_label (p);
		else
			match_colon_label (p);
	}
}
예제 #25
0
파일: erlang.c 프로젝트: ParrotSec/geany
static void findErlangTags (void)
{
	vString *const module = vStringNew ();
	const unsigned char *line;

	while ((line = readLineFromInputFile ()) != NULL)
	{
		const unsigned char *cp = line;

		if (*cp == '%')  /* skip initial comment */
			continue;
		if (*cp == '"')  /* strings sometimes start in column one */
			continue;

		if ( *cp == '-')
		{
			++cp;  /* Move off of the '-' */
			parseDirective(cp, module);
		}
		else if (isIdentifierFirstCharacter ((int) *cp))
			parseFunctionTag (cp, module);
	}
	vStringDelete (module);
}
예제 #26
0
파일: jprop.c 프로젝트: masatake/ctags
static void findJavaPropertiesTags (void)
{
	const unsigned char *line;
	bool in_value = false;
	bool value_continues;
	static vString *key;

	if (key == NULL)
		key = vStringNew ();
	else
		vStringClear (key);

	while ((line = readLineFromInputFile ()) != NULL)
	{
		if (in_value)
		{
			value_continues = doesValueContinue (line);
			if (!value_continues)
				in_value = false;
			continue;
		}

		line = skipWhiteSpace (line);
		if (*line == '\0'
		    || *line == '!' || *line == '#')
			continue;

		line = extractKey (line, key);
		makeSimpleTag (key, K_KEY);
		vStringClear (key);

		value_continues = doesValueContinue (line);
		if (value_continues)
			in_value = true;
	}
}
예제 #27
0
파일: abc.c 프로젝트: FabianInostroza/geany
static void findAbcTags (void)
{
	vString *name = vStringNew();
	const unsigned char *line;

	while ((line = readLineFromInputFile()) != NULL)
	{
		/*int name_len = vStringLength(name);*/

		/* underlines must be the same length or more */
		/*if (name_len > 0 &&	(line[0] == '=' || line[0] == '-') && issame((const char*) line))
		{
			makeAbcTag(name, TRUE);
		}*/
/*		if (line[1] == '%') {
			vStringClear(name);
			vStringCatS(name, (const char *) line);
			vStringTerminate(name);
			makeAbcTag(name, FALSE);
		}*/
		if (line[0] == 'T') {
			/*vStringClear(name);*/
			vStringCatS(name, " / ");
			vStringCatS(name, (const char *) line);
			vStringTerminate(name);
			makeAbcTag(name, FALSE);
		}
		else {
			vStringClear (name);
			if (! isspace(*line))
				vStringCatS(name, (const char*) line);
			vStringTerminate(name);
		}
	}
	vStringDelete (name);
}
예제 #28
0
파일: objc.c 프로젝트: pragmaware/ctags
/* The lexer is in charge of reading the file.
 * Some of sub-lexer (like eatComment) also read file.
 * lexing is finished when the lexer return Tok_EOF */
static objcKeyword lex (lexingState * st)
{
	int retType;

	/* handling data input here */
	while (st->cp == NULL || st->cp[0] == '\0')
	{
		st->cp = readLineFromInputFile ();
		if (st->cp == NULL)
			return Tok_EOF;

		return Tok_EOL;
	}

	if (isAlpha (*st->cp) || (*st->cp == '_'))
	{
		readIdentifier (st);
		retType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC);

		if (retType == -1)	/* If it's not a keyword */
		{
			return ObjcIDENTIFIER;
		}
		else
		{
			return retType;
		}
	}
	else if (*st->cp == '@')
	{
		readIdentifierObjcDirective (st);
		retType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC);

		if (retType == -1)	/* If it's not a keyword */
		{
			return Tok_any;
		}
		else
		{
			return retType;
		}
	}
	else if (isSpace (*st->cp))
	{
		eatWhiteSpace (st);
		return lex (st);
	}
	else
		switch (*st->cp)
		{
		case '(':
			st->cp++;
			return Tok_PARL;

		case '\\':
			st->cp++;
			return Tok_Backslash;

		case '#':
			st->cp++;
			return Tok_Sharp;

		case '/':
			if (st->cp[1] == '*')	/* ergl, a comment */
			{
				eatComment (st);
				return lex (st);
			}
			else if (st->cp[1] == '/')
			{
				st->cp = NULL;
				return lex (st);
			}
			else
			{
				st->cp++;
				return Tok_any;
			}
			break;

		case ')':
			st->cp++;
			return Tok_PARR;
		case '{':
			st->cp++;
			return Tok_CurlL;
		case '}':
			st->cp++;
			return Tok_CurlR;
		case '[':
			st->cp++;
			return Tok_SQUAREL;
		case ']':
			st->cp++;
			return Tok_SQUARER;
		case ',':
			st->cp++;
			return Tok_COMA;
		case ';':
			st->cp++;
			return Tok_semi;
		case ':':
			st->cp++;
			return Tok_dpoint;
		case '"':
			eatString (st);
			return Tok_any;
		case '+':
			st->cp++;
			return Tok_PLUS;
		case '-':
			st->cp++;
			return Tok_MINUS;
		case '*':
			st->cp++;
			return Tok_Asterisk;
		case '<':
			st->cp++;
			return Tok_ANGLEL;
		case '>':
			st->cp++;
			return Tok_ANGLER;

		default:
			st->cp++;
			break;
		}

	/* default return if nothing is recognized,
	 * shouldn't happen, but at least, it will
	 * be handled without destroying the parsing. */
	return Tok_any;
}
예제 #29
0
파일: ruby.c 프로젝트: amosbird/ctags
static void findRubyTags (void)
{
	const unsigned char *line;
	boolean inMultiLineComment = FALSE;

	nesting = nestingLevelsNew (0);

	/* FIXME: this whole scheme is wrong, because Ruby isn't line-based.
	* You could perfectly well write:
	*
	*  def
	*  method
	*   puts("hello")
	*  end
	*
	* if you wished, and this function would fail to recognize anything.
	*/
	while ((line = readLineFromInputFile ()) != NULL)
	{
		const unsigned char *cp = line;
		/* if we expect a separator after a while, for, or until statement
		 * separators are "do", ";" or newline */
		boolean expect_separator = FALSE;

		if (canMatch (&cp, "=begin", isWhitespace))
		{
			inMultiLineComment = TRUE;
			continue;
		}
		if (canMatch (&cp, "=end", isWhitespace))
		{
			inMultiLineComment = FALSE;
			continue;
		}
		if (inMultiLineComment)
			continue;

		skipWhitespace (&cp);

		/* Avoid mistakenly starting a scope for modifiers such as
		*
		*   return if <exp>
		*
		* FIXME: this is fooled by code such as
		*
		*   result = if <exp>
		*               <a>
		*            else
		*               <b>
		*            end
		*
		* FIXME: we're also fooled if someone does something heinous such as
		*
		*   puts("hello") \
		*       unless <exp>
		*/
		if (canMatchKeyword (&cp, "for") ||
		    canMatchKeyword (&cp, "until") ||
		    canMatchKeyword (&cp, "while"))
		{
			expect_separator = TRUE;
			enterUnnamedScope ();
		}
		else if (canMatchKeyword (&cp, "case") ||
		         canMatchKeyword (&cp, "if") ||
		         canMatchKeyword (&cp, "unless"))
		{
			enterUnnamedScope ();
		}

		/*
		* "module M", "class C" and "def m" should only be at the beginning
		* of a line.
		*/
		if (canMatchKeyword (&cp, "module"))
		{
			readAndEmitTag (&cp, K_MODULE);
		}
		else if (canMatchKeyword (&cp, "class"))
		{
			readAndEmitTag (&cp, K_CLASS);
		}
		else if (canMatchKeyword (&cp, "def"))
		{
			rubyKind kind = K_METHOD;
			NestingLevel *nl = nestingLevelsGetCurrent (nesting);
			tagEntryInfo *e  = getEntryOfNestingLevel (nl);

			/* if the def is inside an unnamed scope at the class level, assume
			 * it's from a singleton from a construct like this:
			 *
			 * class C
			 *   class << self
			 *     def singleton
			 *       ...
			 *     end
			 *   end
			 * end
			 */
			if (e && (e->kind - RubyKinds) == K_CLASS && strlen (e->name) == 0)
				kind = K_SINGLETON;
			readAndEmitTag (&cp, kind);
		}
		while (*cp != '\0')
		{
			/* FIXME: we don't cope with here documents,
			* or regular expression literals, or ... you get the idea.
			* Hopefully, the restriction above that insists on seeing
			* definitions at the starts of lines should keep us out of
			* mischief.
			*/
			if (inMultiLineComment || isspace (*cp))
			{
				++cp;
			}
			else if (*cp == '#')
			{
				/* FIXME: this is wrong, but there *probably* won't be a
				* definition after an interpolated string (where # doesn't
				* mean 'comment').
				*/
				break;
			}
			else if (canMatchKeyword (&cp, "begin"))
			{
				enterUnnamedScope ();
			}
			else if (canMatchKeyword (&cp, "do"))
			{
				if (! expect_separator)
					enterUnnamedScope ();
				else
					expect_separator = FALSE;
			}
			else if (canMatchKeyword (&cp, "end") && nesting->n > 0)
			{
				/* Leave the most recent scope. */
				nestingLevelsPop (nesting);
			}
			else if (*cp == '"')
			{
				/* Skip string literals.
				 * FIXME: should cope with escapes and interpolation.
				 */
				do {
					++cp;
				} while (*cp != 0 && *cp != '"');
				if (*cp == '"')
					cp++; /* skip the last found '"' */
			}
			else if (*cp == ';')
			{
				++cp;
				expect_separator = FALSE;
			}
			else if (*cp != '\0')
			{
				do
					++cp;
				while (isIdentChar (*cp));
			}
		}
	}
	nestingLevelsFree (nesting);
}
예제 #30
0
파일: pascal.c 프로젝트: amosbird/ctags
/* Algorithm adapted from from GNU etags.
 * Locates tags for procedures & functions.  Doesn't do any type- or
 * var-definitions.  It does look for the keyword "extern" or "forward"
 * immediately following the procedure statement; if found, the tag is
 * skipped.
 */
static void findPascalTags (void)
{
	vString *name = vStringNew ();
	tagEntryInfo tag;
	pascalKind kind = K_FUNCTION;
		/* each of these flags is TRUE iff: */
	boolean incomment = FALSE;  /* point is inside a comment */
	int comment_char = '\0';    /* type of current comment */
	boolean inquote = FALSE;    /* point is inside '..' string */
	boolean get_tagname = FALSE;/* point is after PROCEDURE/FUNCTION
		keyword, so next item = potential tag */
	boolean found_tag = FALSE;  /* point is after a potential tag */
	boolean inparms = FALSE;    /* point is within parameter-list */
	boolean verify_tag = FALSE;
		/* point has passed the parm-list, so the next token will determine
		 * whether this is a FORWARD/EXTERN to be ignored, or whether it is a
		 * real tag
		 */

	dbp = readLineFromInputFile ();
	while (dbp != NULL)
	{
		int c = *dbp++;

		if (c == '\0')  /* if end of line */
		{
			dbp = readLineFromInputFile ();
			if (dbp == NULL  ||  *dbp == '\0')
				continue;
			if (!((found_tag && verify_tag) || get_tagname))
				c = *dbp++;
					/* only if don't need *dbp pointing to the beginning of
					 * the name of the procedure or function
					 */
		}
		if (incomment)
		{
			if (comment_char == '{' && c == '}')
				incomment = FALSE;
			else if (comment_char == '(' && c == '*' && *dbp == ')')
			{
				dbp++;
				incomment = FALSE;
			}
			continue;
		}
		else if (inquote)
		{
			if (c == '\'')
				inquote = FALSE;
			continue;
		}
		else switch (c)
		{
			case '\'':
				inquote = TRUE;  /* found first quote */
				continue;
			case '{':  /* found open { comment */
				incomment = TRUE;
				comment_char = c;
				continue;
			case '(':
				if (*dbp == '*')  /* found open (* comment */
				{
					incomment = TRUE;
					comment_char = c;
					dbp++;
				}
				else if (found_tag)  /* found '(' after tag, i.e., parm-list */
					inparms = TRUE;
				continue;
			case ')':  /* end of parms list */
				if (inparms)
					inparms = FALSE;
				continue;
			case ';':
				if (found_tag && !inparms)  /* end of proc or fn stmt */
				{
					verify_tag = TRUE;
					break;
				}
				continue;
		}
		if (found_tag && verify_tag && *dbp != ' ')
		{
			/* check if this is an "extern" declaration */
			if (*dbp == '\0')
				continue;
			if (tolower ((int) *dbp == 'e'))
			{
				if (tail ("extern"))  /* superfluous, really! */
				{
					found_tag = FALSE;
					verify_tag = FALSE;
				}
			}
			else if (tolower ((int) *dbp) == 'f')
			{
				if (tail ("forward"))  /*  check for forward reference */
				{
					found_tag = FALSE;
					verify_tag = FALSE;
				}
			}
			if (found_tag && verify_tag)  /* not external proc, so make tag */
			{
				found_tag = FALSE;
				verify_tag = FALSE;
				makePascalTag (&tag);
				continue;
			}
		}
		if (get_tagname)  /* grab name of proc or fn */
		{
			const unsigned char *cp;

			if (*dbp == '\0')
				continue;

			/* grab block name */
			while (isspace ((int) *dbp))
				++dbp;
			for (cp = dbp  ;  *cp != '\0' && !endtoken (*cp)  ;  cp++)
				continue;
			vStringNCopyS (name, (const char*) dbp,  cp - dbp);
			createPascalTag (&tag, name, kind);
			dbp = cp;  /* set dbp to e-o-token */
			get_tagname = FALSE;
			found_tag = TRUE;
			/* and proceed to check for "extern" */
		}
		else if (!incomment && !inquote && !found_tag)
		{
			switch (tolower ((int) c))
			{
				case 'c':
					if (tail ("onstructor"))
					{
						get_tagname = TRUE;
						kind = K_PROCEDURE;
					}
					break;
				case 'd':
					if (tail ("estructor"))
					{
						get_tagname = TRUE;
						kind = K_PROCEDURE;
					}
					break;
				case 'p':
					if (tail ("rocedure"))
					{
						get_tagname = TRUE;
						kind = K_PROCEDURE;
					}
					break;
				case 'f':
					if (tail ("unction"))
					{
						get_tagname = TRUE;
						kind = K_FUNCTION;
					}
					break;
			}
		}  /* while not eof */
	}
	vStringDelete (name);
}