19#if defined (HAVE_SYS_TYPES_H)
20# include <sys/types.h>
22#if defined (HAVE_TYPES_H)
25#if defined (HAVE_UNISTD_H)
71#if !defined(HAVE_TRUNCATE) && !defined(HAVE_FTRUNCATE) && !defined(HAVE_CHSIZE)
72# define USE_REPLACEMENT_TRUNCATE
77#if defined (WIN32) && defined (_MSC_VER)
78# define chsize _chsize
81# define O_RDWR _O_RDWR
122 .patternCacheValid =
false,
130#ifdef NEED_PROTO_TRUNCATE
131extern int truncate (
const char *path, off_t length);
134#ifdef NEED_PROTO_FTRUNCATE
135extern int ftruncate (
int fd, off_t length);
212 const char *
const tab = strchr (
line,
'\t');
216 const long boolOffset = tab -
line + 1;
218 if (
line [boolOffset] ==
'0' ||
line [boolOffset] ==
'1')
223 error (
WARNING,
"Failed to update 'sorted' pseudo-tag");
231 while (c !=
'\t' && c !=
'\n');
234 if (c ==
'\t' && (d ==
'0' || d ==
'1') &&
252 enum { maxEntryLength = 20 };
253 char entry [maxEntryLength + 1];
254 unsigned long linesRead = 0;
260 entryLength = strlen (
entry);
261 Assert (entryLength < maxEntryLength);
268 if (strncmp (
line,
entry, entryLength) == 0)
270 char tab, classType [16];
272 if (sscanf (
line + entryLength,
"%15s%c", classType, &tab) == 2 &&
275 if (strcmp (classType,
"_SORTED") == 0)
296 bool isValid =
false;
298 if (strchr (
"/?", excmd [0]) !=
NULL)
302 char *address =
xMalloc (strlen (excmd) + 1,
char);
303 if (sscanf (excmd,
"%[^;\n]", address) == 1 &&
304 strspn (address,
"0123456789") == strlen (address))
313 enum fieldList { TAG, TAB1, SRC_FILE, TAB2, EXCMD, NUM_FIELDS };
315 const size_t fieldLength = strlen (
line) + 1;
316 char *
const fields =
xMalloc (NUM_FIELDS * fieldLength,
char);
322#define field(x) (fields + ((size_t) (x) * fieldLength))
324 const int numFields = sscanf (
325 line,
"%[^\t]%[\t]%[^\t]%[\t]%[^\r\n]",
338 if (numFields == NUM_FIELDS &&
339 strlen (
field (TAB1)) == 1 &&
340 strlen (
field (TAB2)) == 1 &&
341 field (TAG) [0] !=
'#' &&
342 field (SRC_FILE) [strlen (
field (SRC_FILE)) - 1] !=
';' &&
354 if (
line [0] ==
'\f')
355 result = (bool) (
line [1] ==
'\n' ||
line [1] ==
'\r');
366 else if (mio !=
NULL)
409 "\"%s\" doesn't look like a tag file; I refuse to overwrite it.",
451#ifdef USE_REPLACEMENT_TRUNCATE
455 enum { BufferSize = 1000 };
456 long toRead, numRead;
457 char* buffer =
xMalloc (BufferSize,
char);
458 long remaining = size;
461 toRead = (0 < remaining && remaining < BufferSize) ?
462 remaining : (
long) BufferSize;
463 numRead =
mio_read (fromMio, buffer, (
size_t) 1, (
size_t) toRead);
464 if (
mio_write (toMio, buffer, (
size_t)1, (
size_t)numRead) < (
size_t)numRead)
467 remaining -= numRead;
468 }
while (numRead == toRead && remaining != 0);
472static void copyFile (
const char *
const from,
const char *
const to,
const long size)
495#define WHOLE_FILE -1L
543 verbose (
"sorting tag file\n");
565#ifdef USE_REPLACEMENT_TRUNCATE
577# ifdef HAVE_FTRUNCATE
578 result = ftruncate (fd, (off_t) newSize);
581 result = chsize (fd, newSize);
589 fprintf (stderr,
"Cannot shorten tag file: errno = %d\n",
errno);
607 long desiredSize, size;
622 if (resize && desiredSize < size)
654 unsigned int patternLengthLimit,
655 void * data,
bool *omitted)
664 for (p =
line ; *p !=
'\0' ; ++p)
666 const int next = *(p + 1);
672 if (patternLengthLimit != 0 && length >= patternLengthLimit &&
676 ((((
unsigned char) c) & 0xc0) != 0x80 || ++extraLength > 3))
714 char * p = (
char *)&
pos;
718 for (i = 0; i <
sizeof(
pos); i++)
725 long *
const pSeekValue)
736 char *
const line,
const char *
const token,
const bool discardNewline)
744 if (*p !=
'\0' && ! (*p ==
'\n' && discardNewline))
768 if (!
scope->placeholder)
779 kindIndex =
scope->kindIndex;
780 lang =
scope->langType;
804 const char **kind,
const char **
name)
818 Assert (full_qualified_scope_name);
845 int (* putc_func) (
char ,
void *),
846 int (* puts_func) (
const char* ,
void *),
853 const char *terminator;
857 bool making_cache =
false;
858 int (* puts_o_func)(
const char* ,
void *);
861 static vString *cached_pattern;
862 static MIOPos cached_location;
866 return puts_func (
vStringValue (cached_pattern), output);
884 if (truncted_len > 0)
885 line_len = truncted_len;
889 terminator = (line_len > 0 && (
line [line_len - 1] ==
'\n')) ?
"$":
"";
896 puts_o_func = puts_func;
900 output = cached_pattern;
903 length += putc_func(searchChar, output);
905 length += putc_func(
'^', output);
908 length += puts_func (omitted?
"": terminator, output);
909 length += putc_func (searchChar, output);
1015 if (f && f->
ftype == ftype)
1053 unsigned int corkFlags)
1118 for (i = 0; i < n; i++)
1122 eFree ((
char *)value);
1187 int result = strcmp(item->
slot.
name, this->slot.name);
1192 new = &((*new)->rb_left);
1193 else if (result > 0)
1194 new = &((*new)->rb_right);
1197 unsigned long lthis = this->slot.lineNumber;
1202 new = &((*new)->rb_left);
1203 else if (litem > lthis)
1204 new = &((*new)->rb_right);
1209 new = &((*new)->rb_left);
1210 else if (item >
this)
1211 new = &((*new)->rb_right);
1221 verbose (
"symtbl[:=] %s<-%s/%p (line: %lu)\n",
1254 result = strcmp(
name,
entry->slot.name);
1258 else if (result > 0)
1282 if (strcmp(
name,
entry->slot.name) == 0)
1294 verbose (
"last for %d<%p>: %p\n", corkIndex, root, last);
1305 struct rb_node *cursor = last;
1306 bool revisited_rep =
false;
1310 if (!revisited_rep || !
name || strcmp(
name,
entry->slot.name))
1313 if (!func (
entry->corkIndex, &
entry->slot, data))
1316 revisited_rep =
true;
1321 while ((cursor =
rb_prev(cursor)));
1354 for (
int i = 0; i < kdata->
count; i++)
1356 int k = kdata->
kinds [i];
1357 if (
entry->kindIndex == k)
1359 kdata->
index = corkIndex;
1367 const char *
name,
int kind)
1443 "The tag entry queue overflows; drop the tag entry at %lu in %s",
1452 entry->corkIndex = corkIndex;
1477 size_t available_roles;
1492 for (
unsigned int roleIndex = 0; roleIndex < available_roles; roleIndex++)
1506 error (
WARNING,
"definition tag for refonly kind(%s) is made: %s",
1533 if (getFilenameSeparator(
Option.useSlashAsFilenameSeparator) == FILENAME_SEP_USE_SLASH)
1536 char *c = (
char *)(((
tagEntryInfo *
const)tag)->inputFileName);
1569 const char *
const fileName,
1570 const char *
const pattern,
1571 const char *
const parserName)
1576 pattern, parserName);
1773 const char *inputFileName,
1776 const char *sourceFileName,
1778 long sourceLineNumberDifference)
1839 int kindIndex,
int roleIndex)
1846 int kindIndex,
int roleIndex)
1863 unsigned int offset;
1870 index = (extra / 8);
1871 offset = (extra % 8);
1894 slot [
index ] |= (1 << offset);
1896 slot [
index ] &= ~(1 << offset);
1907 unsigned int offset;
1908 const uint8_t *slot;
1914 index = (extra / 8);
1915 offset = (extra % 8);
1929 return !! ((slot [
index ]) & (1 << offset));
1934 for (
unsigned int i = 0; i <
XTAG_COUNT; i++)
2010 "failed to get file position of the tag file\n");
2021 "failed to set file position of the tag file\n");
#define DebugStatement(x)
#define AssertNotReached()
void debugPrintf(const enum eDebugLevels level, const char *const format,...)
void debugEntry(const tagEntryInfo *const tag)
void notifyMakeTagEntry(const tagEntryInfo *tag, int corkIndex)
bool doesSubparserRun(void)
void tagFilePosition(MIOPos *p)
int makeTagEntry(const tagEntryInfo *const tag)
static bool isTagFile(const char *const filename)
static void deleteTagEnry(void *data)
static void addCommonPseudoTags(void)
tagEntryInfo * getEntryOfNestingLevel(const NestingLevel *nl)
static tagEntryInfoX * copyTagEntry(const tagEntryInfo *const tag, unsigned int corkFlags)
static tagField * tagFieldNew(fieldType ftype, const char *value, bool valueOwner)
void assignRole(tagEntryInfo *const e, int roleIndex)
void freeTagFileResources(void)
void markTagExtraBit(tagEntryInfo *const tag, xtagType extra)
static void internalSortTagFile(void)
void attachParserFieldToCorkEntry(int index, fieldType ftype, const char *value)
static char * getFullQualifiedScopeNameFromCorkQueue(const tagEntryInfo *inner_scope)
unsigned long numTagsAdded(void)
void getTagScopeInformation(tagEntryInfo *const tag, const char **kind, const char **name)
bool isTagExtra(const tagEntryInfo *const tag)
static void clearParserFields(tagEntryInfo *const tag)
bool isTagExtraBitMarked(const tagEntryInfo *const tag, xtagType extra)
void makeFileTag(const char *const fileName)
const char * tagFileName(void)
const tagField * getParserFieldForIndex(const tagEntryInfo *tag, int index)
bool writePseudoTag(const ptagDesc *desc, const char *const fileName, const char *const pattern, const char *const parserName)
void corkTagFile(unsigned int corkFlags)
void setupWriter(void *writerClientData)
static void sortTagFile(void)
static int makePatternStringCommon(const tagEntryInfo *const tag, int(*putc_func)(char, void *), int(*puts_func)(const char *, void *), void *output)
void setTagFilePosition(MIOPos *p)
size_t truncateTagLineAfterTag(char *const line, const char *const token, const bool discardNewline)
static void copyFile(const char *const from, const char *const to, const long size)
static void resizeTagFile(const long newSize)
static bool isEtagsLine(const char *const line)
static void writeEtagsIncludes(MIO *const mio)
static void markTagExtraBitFull(tagEntryInfo *const tag, xtagType extra, bool mark)
void invalidatePatternCache(void)
char * readLineFromBypassForTag(vString *const vLine, const tagEntryInfo *const tag, long *const pSeekValue)
static void assignRoleFull(tagEntryInfo *const e, int roleIndex, bool assign)
int makeQualifiedTagEntry(const tagEntryInfo *const e)
static tagEntryInfo * newNilTagEntry(unsigned int corkFlags)
void abort_if_ferror(MIO *const mio)
void initRefTagEntry(tagEntryInfo *const e, const char *const name, int kindIndex, int roleIndex)
static void initTagEntryFull(tagEntryInfo *const e, const char *const name, unsigned long lineNumber, langType langType_, MIOPos filePosition, const char *inputFileName, int kindIndex, roleBitsType roleBits, const char *sourceFileName, langType sourceLangType, long sourceLineNumberDifference)
static void writeTagEntry(const tagEntryInfo *const tag)
static bool findName(int corkIndex, tagEntryInfo *entry, void *data)
tagEntryInfo * getEntryInCorkQueue(int n)
void registerEntry(int corkIndex)
int anyKindsEntryInScopeRecursive(int corkIndex, const char *name, const int *kinds, int count)
static void rememberMaxLengths(const size_t nameLength, const size_t lineLength)
static void corkSymtabPut(tagEntryInfoX *scope, const char *name, tagEntryInfoX *item)
static void tagFieldDelete(tagField *f)
static void buildFqTagCache(tagEntryInfo *const tag)
void setNumTagsAdded(unsigned long nadded)
int anyKindsEntryInScope(int corkIndex, const char *name, const int *kinds, int count)
struct sTagEntryInfoX tagEntryInfoX
void closeTagFile(const bool resize)
void initTagEntry(tagEntryInfo *const e, const char *const name, int kindIndex)
static size_t appendInputLine(int putc_func(char, void *), const char *const line, unsigned int patternLengthLimit, void *data, bool *omitted)
void markAllEntriesInScopeAsPlaceholder(int index)
size_t countEntryInCorkQueue(void)
bool foreachEntriesInScope(int corkIndex, const char *name, entryForeachFunc func, void *data)
static long unsigned int updatePseudoTags(MIO *const mio)
char * makePatternString(const tagEntryInfo *const tag)
unsigned long maxTagsLine(void)
static bool findNameOfKinds(int corkIndex, tagEntryInfo *entry, void *data)
int anyEntryInScope(int corkIndex, const char *name)
static bool markAsPlaceholder(int index, tagEntryInfo *e, void *data)
void attachParserField(tagEntryInfo *const tag, bool inCorkQueue, fieldType ftype, const char *value)
bool isRoleAssigned(const tagEntryInfo *const e, int roleIndex)
static bool isTagWritable(const tagEntryInfo *const tag)
int anyKindEntryInScope(int corkIndex, const char *name, int kind)
static int vstring_puts(const char *s, void *data)
const char * getTagFileDirectory(void)
static void attachParserFieldGeneric(tagEntryInfo *const tag, fieldType ftype, const char *value, bool valueOwner)
const char * getParserFieldValueForType(tagEntryInfo *const tag, fieldType ftype)
static void copyParserFields(const tagEntryInfo *const tag, tagEntryInfo *slot)
static void updateSortedFlag(const char *const line, MIO *const mio, MIOPos startOfLine)
int makePlaceholder(const char *const name)
bool teardownWriter(const char *filename)
static int vstring_putc(char c, void *data)
static bool isValidTagAddress(const char *const excmd)
unsigned long numTagsTotal(void)
static int replacementTruncate(const char *const name, const long size)
static bool isCtagsLine(const char *const line)
static int queueTagEntry(const tagEntryInfo *const tag)
void initForeignRefTagEntry(tagEntryInfo *const e, const char *const name, langType langType, int kindIndex, int roleIndex)
static void copyBytes(MIO *const fromMio, MIO *const toMio, const long size)
#define PRE_ALLOCATED_PARSER_FIELDS
bool(* entryForeachFunc)(int corkIndex, tagEntryInfo *entry, void *data)
#define ROLE_DEFINITION_INDEX
static roleBitsType makeRoleBit(int roleIndex)
void error(const errorSelection selection, const char *const format,...)
bool isFieldEnabled(fieldType type)
enum eFieldType fieldType
#define CTAGS_ATTR_UNUSED
unsigned long int lineNumber
static vString * tempName
const char * scopeSeparatorFor(langType lang, int kindIndex, int parentKindIndex)
size_t mio_write(MIO *mio, const void *ptr, size_t size, size_t nmemb)
mio_write: @mio: A MIO object @ptr: Pointer to the memory to write on the stream @size: Size of each ...
int mio_getc(MIO *mio)
mio_getc: @mio: A MIO object
long mio_tell(MIO *mio)
mio_tell: @mio: A MIO object
MIO * mio_new_file(const char *filename, const char *mode)
mio_new_file: @filename: Filename to open, same as the fopen()'s first argument @mode: Mode in which ...
size_t mio_read(MIO *mio, void *ptr_, size_t size, size_t nmemb)
mio_read: @mio: A MIO object @ptr: Pointer to the memory to fill with the read data @size: Size of ea...
int mio_seek(MIO *mio, long offset, int whence)
mio_seek: @mio: A MIO object @offset: Offset of the new place, from @whence @whence: Move origin.
int mio_try_resize(MIO *mio, size_t new_size)
int mio_getpos(MIO *mio, MIOPos *pos)
mio_getpos: @mio: A MIO stream @pos: (out): A MIOPos object to fill-in
int mio_flush(MIO *mio)
mio_flush: @mio: A MIO object
int mio_error(MIO *mio)
mio_error: @mio: A MIO object
MIO * mio_new_memory(unsigned char *data, size_t size, MIOReallocFunc realloc_func, MIODestroyNotify free_func)
mio_new_memory: @data: Initial data (may be NULL) @size: Length of @data in bytes @realloc_func: A fu...
int mio_printf(MIO *mio, const char *format,...)
mio_printf: @mio: A MIO object @format: A print format string ...: Arguments of the format
int mio_putc(MIO *mio, int c)
mio_putc: @mio: A MIO object : The character to write
int mio_unref(MIO *mio)
mio_unref: @mio: A MIO object
int mio_setpos(MIO *mio, MIOPos *pos)
mio_setpos: @mio: A MIO object @pos: (in): A MIOPos object filled-in by a previous call of mio_getpos...
void verbose(const char *const format,...)
void setDefaultTagFileName(void)
bool isDestinationStdout(void)
#define includeExtensionFlags()
kindDefinition * getLanguageKind(const langType language, int kindIndex)
bool isLanguageKindRefOnly(const langType language, int kindIndex)
bool isLanguageKindEnabled(const langType language, int kindIndex)
bool isLanguageRoleEnabled(const langType language, int kindIndex, int roleIndex)
bool isParserMarkedNoEmission(void)
unsigned int countLanguageRoles(const langType language, int kindIndex)
unsigned int countLanguageKinds(const langType language)
bool isPtagCommonInParsers(ptagType type)
bool makePtagIfEnabled(ptagType type, langType language, const void *data)
#define PSEUDO_TAG_PREFIX
unsigned int ptrArrayCount(const ptrArray *const current)
void * ptrArrayItem(const ptrArray *const current, const unsigned int indx)
ptrArray * ptrArrayNew(ptrArrayDeleteFunc deleteFunc)
void ptrArrayDelete(ptrArray *const current)
unsigned int ptrArrayAdd(ptrArray *const current, void *ptr)
void(* ptrArrayDeleteFunc)(void *data)
struct rb_node * rb_prev(const struct rb_node *node)
struct rb_node * rb_next(const struct rb_node *node)
void rb_insert_color(struct rb_node *node, struct rb_root *root)
struct rb_node * rb_last(const struct rb_root *root)
static void rb_link_node(struct rb_node *node, struct rb_node *parent, struct rb_node **rb_link)
#define container_of(ptr, type, member)
char * readLineFromBypass(vString *const vLine, MIOPos location, long *const pSeekValue)
char * readLineRaw(vString *const vLine, MIO *const mio)
langType getSourceLanguage(void)
unsigned long getSourceLineNumber(void)
const char * getInputFileTagPath(void)
const unsigned char * readLineFromInputFile(void)
unsigned long getInputLineNumber(void)
langType getInputLanguage(void)
MIOPos getInputFilePosition(void)
const char * getSourceFileTagPath(void)
bool doesInputLanguageRequestAutomaticFQTag(void)
langType popLanguage(void)
const char * getInputFileName(void)
unsigned int getNestedInputBoundaryInfo(unsigned long lineNumber)
void pushLanguage(const langType language)
bool doesInputLanguageAllowNullTag(void)
bool doesParserRunAsGuest(void)
bool doesFileExist(const char *const fileName)
void eFreeNoNullCheck(void *const ptr)
char * absoluteDirname(char *file)
char * strstr(const char *str, const char *substr)
void * eRealloc(void *const ptr, const size_t size)
char * eStrdup(const char *str)
void eFree(void *const ptr)
MIO * tempFile(const char *const mode, char **const pName)
const char * baseFilename(const char *const filePath)
#define OUTPUT_PATH_SEPARATOR
void failedSort(MIO *const mio, const char *msg)
void internalSortTags(const bool toStdout, MIO *mio, size_t numTags)
if(!stash_group_load_from_file(group, filename)) g_warning(_("Could not load keyfile %s!")
stringList * stringListNew(void)
void stringListDelete(stringList *const current)
void stringListRemoveLast(stringList *const current)
vString * stringListItem(const stringList *const current, const unsigned int indx)
vString * stringListLast(const stringList *const current)
unsigned int stringListCount(const stringList *const current)
void stringListAdd(stringList *const current, vString *string)
struct eTagFile::sMax max
struct eTagFile::sNumTags numTags
struct rb_node * rb_right
unsigned int patternLengthLimit
stringList * etagsInclude
enum sOptionValues::interactiveMode interactive
struct sTagEntryInfo::@3 extensionFields
const char * implementation
unsigned int lineNumberEntry
unsigned int boundaryInfo
const char * inputFileName
ptrArray * parserFieldsDynamic
unsigned int skipAutoFQEmission
unsigned long sourceLineNumberDifference
unsigned int truncateLineAfterTag
unsigned int usedParserFields
uint8_t extra[((XTAG_COUNT)/8)+1]
const char * sourceFileName
#define PARSER_TRASH_BOX_TAKE_BACK(PTR)
#define PARSER_TRASH_BOX(PTR, PROC)
vString * vStringNew(void)
void vStringDelete(vString *const string)
vString * vStringNewOrClearWithAutoRelease(vString *const string)
void vStringCatS(vString *const string, const char *const s)
vString * vStringNewInit(const char *const s)
char * vStringDeleteUnwrap(vString *const string)
void vStringCat(vString *const string, const vString *const s)
#define vStringLength(vs)
static void vStringPut(vString *const string, const int c)
int writerWritePtag(MIO *mio, const ptagDesc *desc, const char *const fileName, const char *const pattern, const char *const parserName)
void writerSetup(MIO *mio, void *clientData)
bool writerTeardown(MIO *mio, const char *filename)
int writerWriteTag(MIO *mio, const tagEntryInfo *const tag)
bool isXtagEnabled(xtagType type)