geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

writer-etags.c
Go to the documentation of this file.
1/*
2* Copyright (c) 1998-2002, Darren Hiebert
3*
4* This source code is released for free distribution under the terms of the
5* GNU General Public License version 2 or (at your option) any later version.
6*
7* External interface to entry.c
8*/
9
10#include "general.h" /* must always come first */
11
12#include <string.h>
13
14#include "debug.h"
15#include "entry_p.h"
16#include "mio.h"
17#include "options_p.h"
18#include "parse.h"
19#include "parse_p.h"
20#include "read.h"
21#include "routines.h"
22#include "routines_p.h"
23#include "vstring.h"
24#include "writer_p.h"
25
26
27#define ETAGS_FILE "TAGS"
28
29
30static int writeEtagsEntry (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag,
31 void *clientData CTAGS_ATTR_UNUSED);
32static void *beginEtagsFile (tagWriter *writer, MIO * mio,
33 void *clientData CTAGS_ATTR_UNUSED);
34static bool endEtagsFile (tagWriter *writer, MIO * mio, const char* filename,
35 void *clientData CTAGS_ATTR_UNUSED);
36
39 .writePtagEntry = NULL,
40 .preWriteEntry = beginEtagsFile,
41 .postWriteEntry = endEtagsFile,
42 .rescanFailedEntry = NULL,
43 .treatFieldAsFixed = NULL,
44 .defaultFileName = ETAGS_FILE,
45};
46
47struct sEtags {
48 char *name;
50 size_t byteCount;
52};
53
54
55
57 void *clientData CTAGS_ATTR_UNUSED)
58{
59 static struct sEtags etags = { NULL, NULL, 0, NULL };
60
61 etags.mio = tempFile ("w+b", &etags.name);
62 etags.byteCount = 0;
63 etags.vLine = vStringNew ();
64 return &etags;
65}
66
68 MIO *mainfp, const char *filename,
69 void *clientData CTAGS_ATTR_UNUSED)
70{
71 const char *line;
72 struct sEtags *etags = writer->private;
73
74 mio_printf (mainfp, "\f\n%s,%ld\n", filename, (long) etags->byteCount);
76 abort_if_ferror (mainfp);
77
78 if (etags->mio != NULL)
79 {
80 mio_rewind (etags->mio);
81
82 while ((line = readLineRaw (etags->vLine, etags->mio)) != NULL)
83 mio_puts (mainfp, line);
84
85 vStringDelete (etags->vLine);
86 mio_unref (etags->mio);
87 remove (etags->name);
88 eFree (etags->name);
89 etags->vLine = NULL;
90 etags->mio = NULL;
91 etags->name = NULL;
92 }
93 return false;
94}
95
96static const char* ada_suffix (const tagEntryInfo *const tag, const char *const line)
97{
99
100 Assert (kdef);
101
102 /* Mapping from ctags' kind letter to etags's suffix string.
103 * See https://www.gnu.org/software/emacs/manual/html_node/emacs/Tag-Syntax.html */
104 switch (kdef->letter)
105 {
106 case 'p':
107 case 'k':
108 return "/b";
109 case 'K':
110 return "/k";
111 case 'P':
112 return "/s";
113 case 't':
114 return "/t";
115 case 'R':
116 case 'r':
117 {
118 /* Unlike etags, ctags uses the procedure kind for both
119 * procedures and functions. So in the level, emitting a tag,
120 * we cannot distinguish whether a tag is for a procedureor a
121 * function.
122 *
123 * If the typeref field of the tag is filled, we can say the tag
124 * is for a function. However, Ada parser doesn't implement the
125 * typeref field yet, and implementing it is not so easy.
126 *
127 * So we have to take an unclean way here: scanning the input
128 * line again.
129 * FIXME: remove the scanning code and implement the typeref field
130 * in Ada.
131 */
132 const char *r = strstr (line, "return");
133 const char *f = strstr (line, "function");
134 const char *p = strstr (line, "procedure");
135 if (r && f)
136 return "/f";
137 else if (p && !r)
138 return "/p";
139 return ""; /* Unknown */
140 }
141 default:
142 return "";
143 }
144}
145
147 MIO * mio, const tagEntryInfo *const tag,
148 void *clientData CTAGS_ATTR_UNUSED)
149{
150 langType adaLangType = getNamedLanguage ("Ada", 0);
151 Assert (adaLangType != LANG_IGNORE);
152
153 int length;
154 struct sEtags *etags = writer->private;
155
156 mio = etags->mio;
157
158 if (tag->isFileEntry)
159 length = mio_printf (mio, "\177%s\001%lu,0\n",
160 tag->name, tag->lineNumber);
161 else
162 {
163 size_t len;
164 long seekValue;
165 char *const line =
166 readLineFromBypassForTag (etags->vLine, tag, &seekValue);
167 if (line == NULL || line [0] == '\0')
168 return 0;
169
170 len = strlen (line);
171
172 if (tag->truncateLineAfterTag)
173 truncateTagLineAfterTag (line, tag->name, true);
174 else if (line [len - 1] == '\n')
175 line [--len] = '\0';
176
178 {
179 unsigned int truncationLength = Option.patternLengthLimit;
180
181 /* don't cut in the middle of a UTF-8 character, but don't allow
182 * for more than one extra character in case it actually wasn't
183 * UTF-8. See also entry.c:appendInputLine() */
184 while (truncationLength < len &&
185 truncationLength < Option.patternLengthLimit + 3 &&
186 (((unsigned char) line[truncationLength]) & 0xc0) == 0x80)
187 truncationLength++;
188
189 line [truncationLength] = '\0';
190 }
191
192 length = mio_printf (mio, "%s\177%s%s\001%lu,%ld\n", line,
193 tag->name,
194 (tag->langType == adaLangType)
195 ? ada_suffix (tag, line)
196 : "",
197 tag->lineNumber, seekValue);
198 }
199 etags->byteCount += length;
200
201 return length;
202}
#define Assert(c)
Definition: debug.h:47
unsigned long numTagsAdded(void)
Definition: entry.c:1977
size_t truncateTagLineAfterTag(char *const line, const char *const token, const bool discardNewline)
Definition: entry.c:735
char * readLineFromBypassForTag(vString *const vLine, const tagEntryInfo *const tag, long *const pSeekValue)
Definition: entry.c:724
void abort_if_ferror(MIO *const mio)
Definition: entry.c:158
void setNumTagsAdded(unsigned long nadded)
Definition: entry.c:1982
#define CTAGS_ATTR_UNUSED
Definition: gcc-attr.h:22
vString * line
Definition: geany_cobol.c:133
void mio_rewind(MIO *mio)
mio_rewind: @mio: A MIO object
Definition: mio.c:1208
int mio_printf(MIO *mio, const char *format,...)
mio_printf: @mio: A MIO object @format: A print format string ...: Arguments of the format
Definition: mio.c:863
int mio_puts(MIO *mio, const char *s)
mio_puts: @mio: A MIO object @s: The string to write
Definition: mio.c:762
int mio_unref(MIO *mio)
mio_unref: @mio: A MIO object
Definition: mio.c:480
optionValues Option
Definition: options.c:137
langType getNamedLanguage(const char *const name, size_t len)
Definition: parse.c:406
kindDefinition * getLanguageKind(const langType language, int kindIndex)
Definition: parse.c:317
#define LANG_IGNORE
Definition: parse.h:27
#define NULL
Definition: rbtree.h:150
char * readLineRaw(vString *const vLine, MIO *const mio)
Definition: read.c:1016
char * strstr(const char *str, const char *substr)
Definition: routines.c:304
void eFree(void *const ptr)
Definition: routines.c:252
MIO * tempFile(const char *const mode, char **const pName)
Definition: routines.c:896
const gchar filename[]
Definition: stash-example.c:4
MIO:
Definition: mio.c:136
size_t byteCount
Definition: writer-etags.c:50
vString * vLine
Definition: writer-etags.c:51
char * name
Definition: writer-etags.c:48
MIO * mio
Definition: writer-etags.c:49
char letter
Definition: kind.h:73
unsigned int patternLengthLimit
Definition: options_p.h:118
const char * name
Definition: entry.h:63
unsigned long lineNumber
Definition: entry.h:56
int kindIndex
Definition: entry.h:64
langType langType
Definition: entry.h:61
unsigned int truncateLineAfterTag
Definition: entry.h:47
unsigned int isFileEntry
Definition: entry.h:46
int(* writeEntry)(tagWriter *writer, MIO *mio, const tagEntryInfo *const tag, void *clientData)
Definition: writer_p.h:36
void * private
Definition: writer_p.h:65
int langType
Definition: types.h:13
vString * vStringNew(void)
Definition: vstring.c:70
void vStringDelete(vString *const string)
Definition: vstring.c:60
static int writeEtagsEntry(tagWriter *writer, MIO *mio, const tagEntryInfo *const tag, void *clientData)
Definition: writer-etags.c:146
static const char * ada_suffix(const tagEntryInfo *const tag, const char *const line)
Definition: writer-etags.c:96
#define ETAGS_FILE
Definition: writer-etags.c:27
static void * beginEtagsFile(tagWriter *writer, MIO *mio, void *clientData)
Definition: writer-etags.c:56
static bool endEtagsFile(tagWriter *writer, MIO *mio, const char *filename, void *clientData)
Definition: writer-etags.c:67
tagWriter etagsWriter
Definition: writer-etags.c:37
static tagWriter * writer
Definition: writer.c:32