TAGS parser full reworked, add hungry search algorithm, change etags hash struct
Этот коммит содержится в:
родитель
8abf76df7c
Коммит
2a038f109a
142
edit/etags.c
142
edit/etags.c
@ -1,9 +1,9 @@
|
|||||||
/* editor C-code navigation via tags.
|
/* editor C-code navigation via tags.
|
||||||
make TAGS file via command:
|
make TAGS file via command:
|
||||||
$ find . -type f -name "*.[ch]" | etags -l c --declarations -
|
$ find . -type f -name "*.[ch]" | etags -l c --declarations -
|
||||||
|
|
||||||
or, if etags utility not installed:
|
or, if etags utility not installed:
|
||||||
$ ctags --languages=c -e -R -h '[ch]'
|
$ find . -type f -name "*.[ch]" | ctags -R --c-kinds=+p --fields=+iaS --extra=+q -e -L-
|
||||||
|
|
||||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@ -42,53 +42,98 @@
|
|||||||
#include "../src/global.h"
|
#include "../src/global.h"
|
||||||
#include "../edit/etags.h"
|
#include "../edit/etags.h"
|
||||||
|
|
||||||
/*** global variables **************************************************/
|
|
||||||
|
|
||||||
/*** file scope macro definitions **************************************/
|
|
||||||
|
|
||||||
/*** file scope type declarations **************************************/
|
|
||||||
|
|
||||||
/*** file scope variables **********************************************/
|
|
||||||
|
|
||||||
/*** file scope functions **********************************************/
|
/*** file scope functions **********************************************/
|
||||||
|
|
||||||
static long etags_get_pos_from(char *str)
|
int parse_define(char *buf, char **long_name, char **short_name, long *line)
|
||||||
{
|
{
|
||||||
static char buf[16];
|
enum {in_longname, in_shortname, in_line, finish} def_state = in_longname;
|
||||||
int i, j;
|
|
||||||
j = 0;
|
static char longdef[LONG_DEF_LEN];
|
||||||
int len = strlen( str );
|
static char shortdef[SHORT_DEF_LEN];
|
||||||
for ( i = 0; i < len && i < 16; i++ ) {
|
static char linedef[LINE_DEF_LEN];
|
||||||
char c = (char) str[i];
|
int nlong = 0;
|
||||||
if ( isdigit (c) ) {
|
int nshort = 0;
|
||||||
buf[j++] = c;
|
int nline = 0;
|
||||||
buf[j] = '\0';
|
char c = *buf;
|
||||||
} else {
|
|
||||||
return atol((char *)buf);
|
while ( !(c =='\0' || c =='\n') ) {
|
||||||
|
switch ( def_state ) {
|
||||||
|
case in_longname:
|
||||||
|
if ( c == 0x01 ) {
|
||||||
|
def_state = in_line;
|
||||||
|
} else if ( c == 0x7F ) {
|
||||||
|
def_state = in_shortname;
|
||||||
|
} else {
|
||||||
|
if ( nlong < LONG_DEF_LEN - 1 ) {
|
||||||
|
longdef[nlong++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case in_shortname:
|
||||||
|
if ( isdigit(c) ) {
|
||||||
|
nshort = 0;
|
||||||
|
buf--;
|
||||||
|
def_state = in_line;
|
||||||
|
} else if ( c == 0x01 ) {
|
||||||
|
def_state = in_line;
|
||||||
|
} else {
|
||||||
|
if ( nshort < SHORT_DEF_LEN - 1 ) {
|
||||||
|
shortdef[nshort++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case in_line:
|
||||||
|
if ( c == ',' ) {
|
||||||
|
def_state = finish;
|
||||||
|
} else if ( isdigit(c) ) {
|
||||||
|
if ( nline < LINE_DEF_LEN - 1 ) {
|
||||||
|
linedef[nline++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case finish:
|
||||||
|
longdef[nlong] = '\0';
|
||||||
|
shortdef[nshort] = '\0';
|
||||||
|
linedef[nline] = '\0';
|
||||||
|
*long_name = g_strdup (longdef);
|
||||||
|
*short_name = g_strdup (shortdef);
|
||||||
|
*line = atol (linedef);
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
buf++;
|
||||||
|
c = *buf;
|
||||||
}
|
}
|
||||||
|
*long_name = NULL;
|
||||||
|
*short_name = NULL;
|
||||||
|
*line = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** public functions **************************************************/
|
/*** public functions **************************************************/
|
||||||
|
|
||||||
|
int etags_set_definition_hash(const char *tagfile, const char *start_path,
|
||||||
int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num)
|
const char *match_func,
|
||||||
|
struct etags_hash_type *def_hash,
|
||||||
|
int *num)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
static char buf[4048];
|
static char buf[1024];
|
||||||
int len;
|
|
||||||
|
|
||||||
|
char *longname = NULL;
|
||||||
|
char *shortname = NULL;
|
||||||
|
long line;
|
||||||
|
|
||||||
|
char *chekedstr = NULL;
|
||||||
|
|
||||||
|
/* open file with positions */
|
||||||
f = fopen (tagfile, "r");
|
f = fopen (tagfile, "r");
|
||||||
int i;
|
|
||||||
if (!f)
|
if (!f)
|
||||||
return 1;
|
return 1;
|
||||||
len = strlen( match_func );
|
|
||||||
int pos;
|
|
||||||
|
|
||||||
|
int pos;
|
||||||
char *fullpath = NULL;
|
char *fullpath = NULL;
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
long line;
|
|
||||||
enum {start, in_filename, in_define} state = start;
|
enum {start, in_filename, in_define} state = start;
|
||||||
|
|
||||||
while (fgets (buf, sizeof (buf), f)) {
|
while (fgets (buf, sizeof (buf), f)) {
|
||||||
@ -102,8 +147,8 @@ int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct
|
|||||||
case in_filename:
|
case in_filename:
|
||||||
pos = strcspn(buf, ",");
|
pos = strcspn(buf, ",");
|
||||||
g_free(filename);
|
g_free(filename);
|
||||||
filename = malloc(pos + 2);
|
filename = malloc (pos + 2);
|
||||||
g_strlcpy ( filename, (char *)buf, pos + 1 );
|
g_strlcpy(filename, (char *)buf, pos + 1);
|
||||||
state = in_define;
|
state = in_define;
|
||||||
break;
|
break;
|
||||||
case in_define:
|
case in_define:
|
||||||
@ -112,22 +157,25 @@ int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* check if the filename matches the define pos */
|
/* check if the filename matches the define pos */
|
||||||
if ( strstr ( buf, match_func ) ) {
|
chekedstr = strstr (buf, match_func);
|
||||||
int l = (int)strlen( buf );
|
if ( chekedstr ) {
|
||||||
for ( i = 0; i < l; i++) {
|
parse_define (chekedstr, &longname, &shortname, &line);
|
||||||
if ( ( buf[i] == 0x7F || buf[i] == 0x01 ) && isdigit(buf[i+1]) ) {
|
if ( *num < MAX_DEFINITIONS - 1 ) {
|
||||||
line = etags_get_pos_from(&buf[i+1]);
|
def_hash[*num].filename_len = strlen (filename);
|
||||||
state = start;
|
fullpath = g_strdup_printf("%s/%s",start_path, filename);
|
||||||
if ( *num < MAX_DEFINITIONS ) {
|
canonicalize_pathname (fullpath);
|
||||||
def_hash[*num].filename_len = strlen(filename);
|
def_hash[*num].fullpath = g_strdup(fullpath);
|
||||||
fullpath = g_strdup_printf("%s/%s",start_path, filename);
|
g_free (fullpath);
|
||||||
canonicalize_pathname (fullpath);
|
def_hash[*num].filename = g_strdup (filename);
|
||||||
def_hash[*num].filename = g_strdup(fullpath);
|
if ( shortname ) {
|
||||||
g_free(fullpath);
|
def_hash[*num].short_define = g_strdup (shortname);
|
||||||
def_hash[*num].line = line;
|
} else {
|
||||||
(*num)++;
|
def_hash[*num].short_define = g_strdup (longname);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
def_hash[*num].line = line;
|
||||||
|
g_free(shortname);
|
||||||
|
g_free(longname);
|
||||||
|
(*num)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
#define MC_EDIT_ETAGS_H 1
|
#define MC_EDIT_ETAGS_H 1
|
||||||
|
|
||||||
#define MAX_DEFINITIONS 50
|
#define MAX_DEFINITIONS 50
|
||||||
|
#define SHORT_DEF_LEN 30
|
||||||
|
#define LONG_DEF_LEN 40
|
||||||
|
#define LINE_DEF_LEN 16
|
||||||
|
|
||||||
struct def_hash_type {
|
struct etags_hash_type {
|
||||||
int filename_len;
|
int filename_len;
|
||||||
|
unsigned char *fullpath;
|
||||||
unsigned char *filename;
|
unsigned char *filename;
|
||||||
|
unsigned char *short_define;
|
||||||
long line;
|
long line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user