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
125176f023SMasatake YAMATO #include <string.h>
135176f023SMasatake YAMATO
145176f023SMasatake YAMATO #include "debug.h"
158cbf052bSMasatake YAMATO #include "entry_p.h"
165176f023SMasatake YAMATO #include "mio.h"
1721996d92SMasatake YAMATO #include "options_p.h"
18*d5406d79SMasatake YAMATO #include "parse.h"
19*d5406d79SMasatake YAMATO #include "parse_p.h"
205176f023SMasatake YAMATO #include "read.h"
21934a26beSMasatake YAMATO #include "routines.h"
2229e40fb6SMasatake YAMATO #include "routines_p.h"
235176f023SMasatake YAMATO #include "vstring.h"
24285b4dfeSMasatake YAMATO #include "writer_p.h"
255176f023SMasatake YAMATO
265176f023SMasatake YAMATO
274b7a1543SMasatake YAMATO #define ETAGS_FILE "TAGS"
284b7a1543SMasatake YAMATO
294b7a1543SMasatake YAMATO
305053d6adSMasatake YAMATO static int writeEtagsEntry (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag,
315053d6adSMasatake YAMATO void *clientData CTAGS_ATTR_UNUSED);
325053d6adSMasatake YAMATO static void *beginEtagsFile (tagWriter *writer, MIO * mio,
335053d6adSMasatake YAMATO void *clientData CTAGS_ATTR_UNUSED);
345053d6adSMasatake YAMATO static bool endEtagsFile (tagWriter *writer, MIO * mio, const char* filename,
355053d6adSMasatake YAMATO void *clientData CTAGS_ATTR_UNUSED);
365176f023SMasatake YAMATO
375176f023SMasatake YAMATO tagWriter etagsWriter = {
385176f023SMasatake YAMATO .writeEntry = writeEtagsEntry,
395176f023SMasatake YAMATO .writePtagEntry = NULL,
405176f023SMasatake YAMATO .preWriteEntry = beginEtagsFile,
415176f023SMasatake YAMATO .postWriteEntry = endEtagsFile,
4267d1f12fSJiří Techet .rescanFailedEntry = NULL,
438182f840SMasatake YAMATO .treatFieldAsFixed = NULL,
444b7a1543SMasatake YAMATO .defaultFileName = ETAGS_FILE,
455176f023SMasatake YAMATO };
465176f023SMasatake YAMATO
475176f023SMasatake YAMATO struct sEtags {
485176f023SMasatake YAMATO char *name;
495176f023SMasatake YAMATO MIO *mio;
505176f023SMasatake YAMATO size_t byteCount;
515176f023SMasatake YAMATO vString *vLine;
525176f023SMasatake YAMATO };
535176f023SMasatake YAMATO
545176f023SMasatake YAMATO
555176f023SMasatake YAMATO
beginEtagsFile(tagWriter * writer CTAGS_ATTR_UNUSED,MIO * mio CTAGS_ATTR_UNUSED,void * clientData CTAGS_ATTR_UNUSED)565053d6adSMasatake YAMATO static void *beginEtagsFile (tagWriter *writer CTAGS_ATTR_UNUSED, MIO *mio CTAGS_ATTR_UNUSED,
575053d6adSMasatake YAMATO void *clientData CTAGS_ATTR_UNUSED)
585176f023SMasatake YAMATO {
595176f023SMasatake YAMATO static struct sEtags etags = { NULL, NULL, 0, NULL };
605176f023SMasatake YAMATO
615176f023SMasatake YAMATO etags.mio = tempFile ("w+b", &etags.name);
625176f023SMasatake YAMATO etags.byteCount = 0;
635176f023SMasatake YAMATO etags.vLine = vStringNew ();
645176f023SMasatake YAMATO return &etags;
655176f023SMasatake YAMATO }
665176f023SMasatake YAMATO
endEtagsFile(tagWriter * writer,MIO * mainfp,const char * filename,void * clientData CTAGS_ATTR_UNUSED)67975c73faSMasatake YAMATO static bool endEtagsFile (tagWriter *writer,
685053d6adSMasatake YAMATO MIO *mainfp, const char *filename,
695053d6adSMasatake YAMATO void *clientData CTAGS_ATTR_UNUSED)
705176f023SMasatake YAMATO {
715176f023SMasatake YAMATO const char *line;
720479e0a2SMasatake YAMATO struct sEtags *etags = writer->private;
735176f023SMasatake YAMATO
745176f023SMasatake YAMATO mio_printf (mainfp, "\f\n%s,%ld\n", filename, (long) etags->byteCount);
753d71bd5fSMasatake YAMATO setNumTagsAdded (numTagsAdded () + 1);
765176f023SMasatake YAMATO abort_if_ferror (mainfp);
775176f023SMasatake YAMATO
785176f023SMasatake YAMATO if (etags->mio != NULL)
795176f023SMasatake YAMATO {
805176f023SMasatake YAMATO mio_rewind (etags->mio);
815176f023SMasatake YAMATO
825176f023SMasatake YAMATO while ((line = readLineRaw (etags->vLine, etags->mio)) != NULL)
835176f023SMasatake YAMATO mio_puts (mainfp, line);
845176f023SMasatake YAMATO
855176f023SMasatake YAMATO vStringDelete (etags->vLine);
86b978efd6SMasatake YAMATO mio_unref (etags->mio);
875176f023SMasatake YAMATO remove (etags->name);
885176f023SMasatake YAMATO eFree (etags->name);
895176f023SMasatake YAMATO etags->vLine = NULL;
905176f023SMasatake YAMATO etags->mio = NULL;
915176f023SMasatake YAMATO etags->name = NULL;
925176f023SMasatake YAMATO }
93975c73faSMasatake YAMATO return false;
945176f023SMasatake YAMATO }
955176f023SMasatake YAMATO
ada_suffix(const tagEntryInfo * const tag,const char * const line)96*d5406d79SMasatake YAMATO static const char* ada_suffix (const tagEntryInfo *const tag, const char *const line)
97*d5406d79SMasatake YAMATO {
98*d5406d79SMasatake YAMATO kindDefinition *kdef = getLanguageKind(tag->langType, tag->kindIndex);
99*d5406d79SMasatake YAMATO
100*d5406d79SMasatake YAMATO Assert (kdef);
101*d5406d79SMasatake YAMATO
102*d5406d79SMasatake YAMATO /* Mapping from ctags' kind letter to etags's suffix string.
103*d5406d79SMasatake YAMATO * See https://www.gnu.org/software/emacs/manual/html_node/emacs/Tag-Syntax.html */
104*d5406d79SMasatake YAMATO switch (kdef->letter)
105*d5406d79SMasatake YAMATO {
106*d5406d79SMasatake YAMATO case 'p':
107*d5406d79SMasatake YAMATO case 'k':
108*d5406d79SMasatake YAMATO return "/b";
109*d5406d79SMasatake YAMATO case 'K':
110*d5406d79SMasatake YAMATO return "/k";
111*d5406d79SMasatake YAMATO case 'P':
112*d5406d79SMasatake YAMATO return "/s";
113*d5406d79SMasatake YAMATO case 't':
114*d5406d79SMasatake YAMATO return "/t";
115*d5406d79SMasatake YAMATO case 'R':
116*d5406d79SMasatake YAMATO case 'r':
117*d5406d79SMasatake YAMATO {
118*d5406d79SMasatake YAMATO /* Unlike etags, ctags uses the procedure kind for both
119*d5406d79SMasatake YAMATO * procedures and functions. So in the level, emitting a tag,
120*d5406d79SMasatake YAMATO * we cannot distinguish whether a tag is for a procedureor a
121*d5406d79SMasatake YAMATO * function.
122*d5406d79SMasatake YAMATO *
123*d5406d79SMasatake YAMATO * If the typeref field of the tag is filled, we can say the tag
124*d5406d79SMasatake YAMATO * is for a function. However, Ada parser doesn't implement the
125*d5406d79SMasatake YAMATO * typeref field yet, and implementing it is not so easy.
126*d5406d79SMasatake YAMATO *
127*d5406d79SMasatake YAMATO * So we have to take an unclean way here: scanning the input
128*d5406d79SMasatake YAMATO * line again.
129*d5406d79SMasatake YAMATO * FIXME: remove the scanning code and implement the typeref field
130*d5406d79SMasatake YAMATO * in Ada.
131*d5406d79SMasatake YAMATO */
132*d5406d79SMasatake YAMATO const char *r = strstr (line, "return");
133*d5406d79SMasatake YAMATO const char *f = strstr (line, "function");
134*d5406d79SMasatake YAMATO const char *p = strstr (line, "procedure");
135*d5406d79SMasatake YAMATO if (r && f)
136*d5406d79SMasatake YAMATO return "/f";
137*d5406d79SMasatake YAMATO else if (p && !r)
138*d5406d79SMasatake YAMATO return "/p";
139*d5406d79SMasatake YAMATO return ""; /* Unknown */
140*d5406d79SMasatake YAMATO }
141*d5406d79SMasatake YAMATO default:
142*d5406d79SMasatake YAMATO return "";
143*d5406d79SMasatake YAMATO }
144*d5406d79SMasatake YAMATO }
145*d5406d79SMasatake YAMATO
writeEtagsEntry(tagWriter * writer,MIO * mio,const tagEntryInfo * const tag,void * clientData CTAGS_ATTR_UNUSED)1460479e0a2SMasatake YAMATO static int writeEtagsEntry (tagWriter *writer,
1475053d6adSMasatake YAMATO MIO * mio, const tagEntryInfo *const tag,
1485053d6adSMasatake YAMATO void *clientData CTAGS_ATTR_UNUSED)
1495176f023SMasatake YAMATO {
150*d5406d79SMasatake YAMATO langType adaLangType = getNamedLanguage ("Ada", 0);
151*d5406d79SMasatake YAMATO Assert (adaLangType != LANG_IGNORE);
152*d5406d79SMasatake YAMATO
1535176f023SMasatake YAMATO int length;
1540479e0a2SMasatake YAMATO struct sEtags *etags = writer->private;
1555176f023SMasatake YAMATO
1565176f023SMasatake YAMATO mio = etags->mio;
1575176f023SMasatake YAMATO
1585176f023SMasatake YAMATO if (tag->isFileEntry)
1595176f023SMasatake YAMATO length = mio_printf (mio, "\177%s\001%lu,0\n",
1605176f023SMasatake YAMATO tag->name, tag->lineNumber);
1615176f023SMasatake YAMATO else
1625176f023SMasatake YAMATO {
16307087623SMasatake YAMATO size_t len;
1645176f023SMasatake YAMATO long seekValue;
1655176f023SMasatake YAMATO char *const line =
166c8c97f1cSMasatake YAMATO readLineFromBypassForTag (etags->vLine, tag, &seekValue);
1675d73ebeeSColomban Wendling if (line == NULL || line [0] == '\0')
1685176f023SMasatake YAMATO return 0;
1695176f023SMasatake YAMATO
17007087623SMasatake YAMATO len = strlen (line);
17107087623SMasatake YAMATO
1720e70b227SMasatake YAMATO if (tag->truncateLineAfterTag)
1730e70b227SMasatake YAMATO truncateTagLineAfterTag (line, tag->name, true);
1745d73ebeeSColomban Wendling else if (line [len - 1] == '\n')
1755d73ebeeSColomban Wendling line [--len] = '\0';
17607087623SMasatake YAMATO
177b4d9e03fSColomban Wendling if (Option.patternLengthLimit > 0 && Option.patternLengthLimit < len)
1784f39a655SColomban Wendling {
1794f39a655SColomban Wendling unsigned int truncationLength = Option.patternLengthLimit;
1804f39a655SColomban Wendling
1814f39a655SColomban Wendling /* don't cut in the middle of a UTF-8 character, but don't allow
1824f39a655SColomban Wendling * for more than one extra character in case it actually wasn't
1834f39a655SColomban Wendling * UTF-8. See also entry.c:appendInputLine() */
1845d73ebeeSColomban Wendling while (truncationLength < len &&
1854f39a655SColomban Wendling truncationLength < Option.patternLengthLimit + 3 &&
1864f39a655SColomban Wendling (((unsigned char) line[truncationLength]) & 0xc0) == 0x80)
1874f39a655SColomban Wendling truncationLength++;
1884f39a655SColomban Wendling
1894f39a655SColomban Wendling line [truncationLength] = '\0';
1904f39a655SColomban Wendling }
1915176f023SMasatake YAMATO
192*d5406d79SMasatake YAMATO length = mio_printf (mio, "%s\177%s%s\001%lu,%ld\n", line,
193*d5406d79SMasatake YAMATO tag->name,
194*d5406d79SMasatake YAMATO (tag->langType == adaLangType)
195*d5406d79SMasatake YAMATO ? ada_suffix (tag, line)
196*d5406d79SMasatake YAMATO : "",
197*d5406d79SMasatake YAMATO tag->lineNumber, seekValue);
1985176f023SMasatake YAMATO }
1995176f023SMasatake YAMATO etags->byteCount += length;
2005176f023SMasatake YAMATO
2015176f023SMasatake YAMATO return length;
2025176f023SMasatake YAMATO }
203