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

📄 lregex.c

📁 ctags-5.5.4.tar.gz,一个很好的代码开发以及编辑源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**   $Id: lregex.c,v 1.6 2003/07/11 01:21:53 darren Exp $**   Copyright (c) 2000-2003, Darren Hiebert**   This source code is released for free distribution under the terms of the*   GNU General Public License.**   This module contains functions for applying regular expression matching.**   The code for utlizing the Gnu regex package with regards to processing the*   regex option and checking for regex matches was adapted from routines in*   Gnu etags.*//**   INCLUDE FILES*/#include "general.h"	/* must always come first */#include <string.h>#ifdef HAVE_REGCOMP# include <ctype.h># include <stddef.h># ifdef HAVE_SYS_TYPES_H#  include <sys/types.h> /* declare off_t (not known to regex.h on FreeBSD) */# endif# include "regex.h"#endif#include "debug.h"#include "entry.h"#include "parse.h"#include "read.h"#include "routines.h"#ifdef HAVE_REGEX/**   MACROS*//* Back-references \0 through \9 */#define BACK_REFERENCE_COUNT 10#if defined (HAVE_REGCOMP) && !defined (REGCOMP_BROKEN)# define POSIX_REGEX#endif#define REGEX_NAME "Regex"/**   DATA DECLARATIONS*/#if defined (POSIX_REGEX)struct sKind {    boolean enabled;    char letter;    char* name;    char* description;};enum pType { PTRN_TAG, PTRN_CALLBACK };typedef struct {    regex_t *pattern;    enum pType type;    union {	struct {	    char *name_pattern;	    struct sKind kind;	} tag;	struct {	    regexCallback function;	} callback;    } u;} regexPattern;#endiftypedef struct {    regexPattern *patterns;    unsigned int count;} patternSet;/**   DATA DEFINITIONS*/static boolean regexBroken = FALSE;/* Array of pattern sets, indexed by language */static patternSet* Sets = NULL;static int SetUpper = -1;	/* upper language index in list *//**   FUNCTION DEFINITIONS*/static void clearPatternSet (const langType language){    if (language < SetUpper)    {	patternSet* const set = Sets + language;	unsigned int i;	for (i = 0  ;  i < set->count  ;  ++i)	{#if defined (POSIX_REGEX)	    regfree (set->patterns [i].pattern);#endif	    eFree (set->patterns [i].pattern);	    set->patterns [i].pattern = NULL;	    if (set->patterns [i].type == PTRN_TAG)	    {		eFree (set->patterns [i].u.tag.name_pattern);		set->patterns [i].u.tag.name_pattern = NULL;	    }	}	if (set->patterns != NULL)	    eFree (set->patterns);	set->patterns = NULL;	set->count = 0;    }}/**   Regex psuedo-parser*/static void makeRegexTag (	const vString* const name, const struct sKind* const kind){    if (kind->enabled)    {	tagEntryInfo e;	Assert (name != NULL  &&  vStringLength (name) > 0);	Assert (kind != NULL);	initTagEntry (&e, vStringValue (name));	e.kind     = kind->letter;	e.kindName = kind->name;	makeTagEntry (&e);    }}/**   Regex pattern definition*//* Take a string like "/blah/" and turn it into "blah", making sure * that the first and last characters are the same, and handling * quoted separator characters.  Actually, stops on the occurrence of * an unquoted separator.  Also turns "\t" into a Tab character. * Returns pointer to terminating separator.  Works in place.  Null * terminates name string. */static char* scanSeparators (char* name){    char sep = name [0];    char *copyto = name;    boolean quoted = FALSE;    for (++name ; *name != '\0' ; ++name)    {	if (quoted)	{	    if (*name == sep)		*copyto++ = sep;	    else if (*name == 't')		*copyto++ = '\t';	    else	    {		/* Something else is quoted, so preserve the quote. */		*copyto++ = '\\';		*copyto++ = *name;	    }	    quoted = FALSE;	}	else if (*name == '\\')	    quoted = TRUE;	else if (*name == sep)	{	    break;	}	else	    *copyto++ = *name;    }    *copyto = '\0';    return name;}/* Parse `regexp', in form "/regex/name/[k,Kind/]flags" (where the separator * character is whatever the first character of `regexp' is), by breaking it * up into null terminated strings, removing the separators, and expanding * '\t' into tabs. When complete, `regexp' points to the line matching * pattern, a pointer to the name matching pattern is written to `name', a * pointer to the kinds is written to `kinds' (possibly NULL), and a pointer * to the trailing flags is written to `flags'. If the pattern is not in the * correct format, a false value is returned. */static boolean parseTagRegex (	char* const regexp, char** const name,	char** const kinds, char** const flags){    boolean result = FALSE;    const int separator = (unsigned char) regexp [0];    *name = scanSeparators (regexp);    if (*regexp == '\0')	error (WARNING, "empty regexp");    else if (**name != separator)	error (WARNING, "%s: incomplete regexp", regexp);    else    {	char* const third = scanSeparators (*name);	if (**name == '\0')	    error (WARNING, "%s: regexp missing name pattern", regexp);	if ((*name) [strlen (*name) - 1] == '\\')	    error (WARNING, "error in name pattern: \"%s\"", *name);	if (*third != separator)	    error (WARNING, "%s: regexp missing final separator", regexp);	else	{	    char* const fourth = scanSeparators (third);	    if (*fourth == separator)	    {		*kinds = third;		scanSeparators (fourth);		*flags = fourth;	    }	    else	    {		*flags = third;		*kinds = NULL;	    }	    result = TRUE;	}    }    return result;}static void addCompiledTagPattern (	const langType language, regex_t* const pattern,	char* const name, const char kind, char* const kindName,	char *const description){    patternSet* set;    regexPattern *ptrn;    if (language > SetUpper)    {	int i;	Sets = xRealloc (Sets, (language + 1), patternSet);	for (i = SetUpper + 1  ;  i <= language  ;  ++i)	{	    Sets [i].patterns = NULL;	    Sets [i].count = 0;	}	SetUpper = language;    }    set = Sets + language;    set->patterns = xRealloc (set->patterns, (set->count + 1), regexPattern);    ptrn = &set->patterns [set->count];    set->count += 1;    ptrn->pattern = pattern;    ptrn->type    = PTRN_TAG;    ptrn->u.tag.name_pattern = name;    ptrn->u.tag.kind.enabled = TRUE;    ptrn->u.tag.kind.letter  = kind;    ptrn->u.tag.kind.name    = kindName;    ptrn->u.tag.kind.description = description;}static void addCompiledCallbackPattern (	const langType language, regex_t* const pattern,	const regexCallback callback){    patternSet* set;    regexPattern *ptrn;    if (language > SetUpper)    {	int i;	Sets = xRealloc (Sets, (language + 1), patternSet);	for (i = SetUpper + 1  ;  i <= language  ;  ++i)	{	    Sets [i].patterns = NULL;	    Sets [i].count = 0;	}	SetUpper = language;    }    set = Sets + language;    set->patterns = xRealloc (set->patterns, (set->count + 1), regexPattern);    ptrn = &set->patterns [set->count];    set->count += 1;    ptrn->pattern = pattern;    ptrn->type    = PTRN_CALLBACK;    ptrn->u.callback.function = callback;}#if defined (POSIX_REGEX)static regex_t* compileRegex (const char* const regexp, const char* const flags){    int cflags = REG_EXTENDED | REG_NEWLINE;    regex_t *result = NULL;    int errcode;    int i;    for (i = 0  ; flags != NULL  &&  flags [i] != '\0'  ;  ++i)    {	switch ((int) flags [i])	{	    case 'b': cflags &= ~REG_EXTENDED; break;	    case 'e': cflags |= REG_EXTENDED;  break;	    case 'i': cflags |= REG_ICASE;     break;	    default: error (WARNING, "unknown regex flag: '%c'", *flags); break;	}    }    result = xMalloc (1, regex_t);    errcode = regcomp (result, regexp, cflags);    if (errcode != 0)    {	char errmsg[256];	regerror (errcode, result, errmsg, 256);	error (WARNING, "%s", errmsg);	regfree (result);	eFree (result);	result = NULL;    }    return result;}#endifstatic void parseKinds (	const char* const kinds, char* const kind, char** const kindName,	char **description){    *kind = '\0';    *kindName = NULL;    *description = NULL;    if (kinds == NULL  ||  kinds [0] == '\0')    {	*kind = 'r';	*kindName = eStrdup ("regex");    }    else if (kinds [0] != '\0')

⌨️ 快捷键说明

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