⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readtags.cpp

📁 用Qt4编写的linux IDE开发环境
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************************************** * PROGRAM	  :  * DATE - TIME  : lundi 10 avril 2006 - 22:28 * AUTHOR	   : Darren Hiebert and Anacr0x ( fred.julian at gmail.com ) * FILENAME	 :  * LICENSE	  : GPL * COMMENTARY   : Modified file (with qt) of the ctags project ********************************************************************************************************//**   This module contains functions for reading tag files.*//**   INCLUDE FILES*/#include <stdlib.h>#include <string.h>#include <ctype.h>#include <stdio.h>#include <errno.h>#include <sys/types.h>		/* to declare off_t */#include "readtags.h"/**   MACROS*/#define TAB '\t'#include <QDebug>/**   DATA DECLARATIONS*/typedef struct{	size_t size;	char *buffer;}vstring;/* Information about current tag file */struct sTagFile{	/* has the file been opened and this structure initialized? */	short initialized;	/* format of tag file */	short format;	/* how is the tag file sorted? */	sortType sortMethod;	/* pointer to file structure */	FILE *fp;	/* file position of first character of `line' */	off_t pos;	/* size of tag file in seekable positions */	off_t size;	/* last line read */	vstring line;	/* name of tag in last line read */	vstring name;	/* defines tag search state */	struct	{		/* file position of last match for tag */		off_t pos;		/* name of tag last searched for */		const char *name;		/* length of name for partial matches */		size_t nameLength;		/* peforming partial match */		short partial;		/* ignoring case */		short ignorecase;	}	search;	/* miscellaneous extension fields */	struct	{		/* number of entries in `list' */		unsigned short max;		/* list of key value pairs */		tagExtensionField *list;	}	fields;	/* buffers to be freed at close */	struct	{		/* name of program author */		char *author;		/* name of program */		char *name;		/* URL of distribution */		char *url;		/* program version */		char *version;	}	program;};/**   DATA DEFINITIONS*/const char *const EmptyString = "";const char *const PseudoTagPrefix = "!_";/**   FUNCTION DEFINITIONS*//* * Compare two strings, ignoring case. * Return 0 for match, < 0 for smaller, > 0 for bigger * Make sure case is folded to uppercase in comparison (like for 'sort -f') * This makes a difference when one of the chars lies between upper and lower * ie. one of the chars [ \ ] ^ _ ` for ascii. (The '_' in particular !) */static int struppercmp(const char *s1, const char *s2){	int result;	do	{		result = toupper((int) *s1) - toupper((int) *s2);	}	while (result == 0 && *s1++ != '\0' && *s2++ != '\0');	return result;}static int strnuppercmp(const char *s1, const char *s2, size_t n){	int result;	do	{		result = toupper((int) *s1) - toupper((int) *s2);	}	while (result == 0 && --n > 0 && *s1++ != '\0' && *s2++ != '\0');	return result;}static int growString(vstring * s){	int result = 0;	size_t newLength;	char *newLine;	if (s->size == 0)	{		newLength = 128;		newLine = (char *) malloc(newLength);		*newLine = '\0';	}	else	{		newLength = 2 * s->size;		newLine = (char *) realloc(s->buffer, newLength);	}	if (newLine == NULL)		perror("string too large");	else	{		s->buffer = newLine;		s->size = newLength;		result = 1;	}	return result;}/* Copy name of tag out of tag line */static void copyName(tagFile * const file){	size_t length;	const char *end = strchr(file->line.buffer, '\t');	if (end == NULL)	{		end = strchr(file->line.buffer, '\n');		if (end == NULL)			end = strchr(file->line.buffer, '\r');	}	if (end != NULL)		length = end - file->line.buffer;	else		length = strlen(file->line.buffer);	while (length >= file->name.size)		growString(&file->name);	strncpy(file->name.buffer, file->line.buffer, length);	file->name.buffer[length] = '\0';}static int readTagLineRaw(tagFile * const file){	int result = 1;	int reReadLine;	/*  If reading the line places any character other than a null or a	 *  newline at the last character position in the buffer (one less than	 *  the buffer size), then we must resize the buffer and reattempt to read	 *  the line.	 */	do	{		char *const pLastChar = file->line.buffer + file->line.size - 2;		char *line;		file->pos = ftell(file->fp);		reReadLine = 0;		*pLastChar = '\0';		line = fgets(file->line.buffer, (int) file->line.size, file->fp);		if (line == NULL)		{			/* read error */			if (!feof(file->fp))				perror("readTagLine");			result = 0;		}		else if (*pLastChar != '\0' && *pLastChar != '\n' && *pLastChar != '\r')		{			/*  buffer overflow */			growString(&file->line);			fseek(file->fp, file->pos, SEEK_SET);			reReadLine = 1;		}		else		{			size_t i = strlen(file->line.buffer);			while (i > 0 &&			        (file->line.buffer[i - 1] == '\n'			         || file->line.buffer[i - 1] == '\r'))			{				file->line.buffer[i - 1] = '\0';				--i;			}		}	}	while (reReadLine && result);	if (result)		copyName(file);	return result;}static int readTagLine(tagFile * const file){	int result;	do	{		result = readTagLineRaw(file);	}	while (result && *file->name.buffer == '\0');	return result;}static tagResult growFields(tagFile * const file){	tagResult result = TagFailure;	unsigned short newCount = 2 * file->fields.max;	tagExtensionField *newFields = (tagExtensionField *)	                               realloc(file->fields.list, newCount * sizeof(tagExtensionField));	if (newFields == NULL)		perror("too many extension fields");	else	{		file->fields.list = newFields;		file->fields.max = newCount;		result = TagSuccess;	}	return result;}static void parseExtensionFields(tagFile * const file, tagEntry * const entry,                                 char *const string){	char *p = string;	while (p != NULL && *p != '\0')	{		while (*p == TAB)			*p++ = '\0';		if (*p != '\0')		{			char *colon;			char *field = p;			p = strchr(p, TAB);			if (p != NULL)				*p++ = '\0';			colon = strchr(field, ':');			if (colon == NULL)				entry->kind = field;			else			{				const char *key = field;				const char *value = colon + 1;				*colon = '\0';				if (strcmp(key, "kind") == 0)					entry->kind = value;				else if (strcmp(key, "file") == 0)					entry->fileScope = 1;				else if (strcmp(key, "line") == 0)					entry->address.lineNumber = atol(value);				else				{					if (entry->fields.count == file->fields.max)						growFields(file);					file->fields.list[entry->fields.count].key = key;					file->fields.list[entry->fields.count].value = value;					++entry->fields.count;				}			}		}	}}static void parseTagLine(tagFile * file, tagEntry * const entry){	int i;	char *p = file->line.buffer;	char *tab = strchr(p, TAB);	int fieldsPresent = 0;	entry->fields.list = NULL;	entry->fields.count = 0;	entry->kind = NULL;	entry->fileScope = 0;	entry->name = p;	if (tab != NULL)	{		*tab = '\0';		p = tab + 1;		entry->file = p;		tab = strchr(p, TAB);		if (tab != NULL)		{			*tab = '\0';			p = tab + 1;			if (*p == '/' || *p == '?')			{				/* parse pattern */				int delimiter = *(unsigned char *) p;				entry->address.lineNumber = 0;				entry->address.pattern = p;				do				{					p = strchr(p + 1, delimiter);				}				while (p != NULL && *(p - 1) == '\\');				if (p == NULL)				{					/* invalid pattern */				}				else					++p;			}			else if (isdigit((int) *(unsigned char *) p))			{				/* parse line number */				entry->address.pattern = p;				entry->address.lineNumber = atol(p);				while (isdigit((int) *(unsigned char *) p))					++p;			}			else			{				/* invalid pattern */			}			fieldsPresent = (strncmp(p, ";\"", 2) == 0);			*p = '\0';			if (fieldsPresent)				parseExtensionFields(file, entry, p + 2);		}	}	if (entry->fields.count > 0)		entry->fields.list = file->fields.list;	for (i = entry->fields.count; i < file->fields.max; ++i)	{		file->fields.list[i].key = NULL;		file->fields.list[i].value = NULL;	}}static char *duplicate(const char *str){	char *result = NULL;	if (str != NULL)	{		result = (char *) malloc(strlen(str) + 1);		if (result == NULL)			perror(NULL);		else			strcpy(result, str);	}	return result;}static void readPseudoTags(tagFile * const file, tagFileInfo * const info){	fpos_t startOfLine;	const size_t prefixLength = strlen(PseudoTagPrefix);	if (info != NULL)	{		info->file.format = 1;		info->file.sort = TAG_UNSORTED;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -