mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
TAGS parser full reworked, add hungry search algorithm, change etags hash struct
This commit is contained in:
parent
8abf76df7c
commit
2a038f109a
142
edit/etags.c
142
edit/etags.c
@ -1,9 +1,9 @@
|
||||
/* editor C-code navigation via tags.
|
||||
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:
|
||||
$ 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.
|
||||
|
||||
@ -42,53 +42,98 @@
|
||||
#include "../src/global.h"
|
||||
#include "../edit/etags.h"
|
||||
|
||||
/*** global variables **************************************************/
|
||||
|
||||
/*** file scope macro definitions **************************************/
|
||||
|
||||
/*** file scope type declarations **************************************/
|
||||
|
||||
/*** file scope variables **********************************************/
|
||||
|
||||
/*** 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];
|
||||
int i, j;
|
||||
j = 0;
|
||||
int len = strlen( str );
|
||||
for ( i = 0; i < len && i < 16; i++ ) {
|
||||
char c = (char) str[i];
|
||||
if ( isdigit (c) ) {
|
||||
buf[j++] = c;
|
||||
buf[j] = '\0';
|
||||
} else {
|
||||
return atol((char *)buf);
|
||||
enum {in_longname, in_shortname, in_line, finish} def_state = in_longname;
|
||||
|
||||
static char longdef[LONG_DEF_LEN];
|
||||
static char shortdef[SHORT_DEF_LEN];
|
||||
static char linedef[LINE_DEF_LEN];
|
||||
int nlong = 0;
|
||||
int nshort = 0;
|
||||
int nline = 0;
|
||||
char c = *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;
|
||||
}
|
||||
|
||||
/*** public functions **************************************************/
|
||||
|
||||
|
||||
int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct def_hash_type *def_hash, int *num)
|
||||
int etags_set_definition_hash(const char *tagfile, const char *start_path,
|
||||
const char *match_func,
|
||||
struct etags_hash_type *def_hash,
|
||||
int *num)
|
||||
{
|
||||
FILE *f;
|
||||
static char buf[4048];
|
||||
int len;
|
||||
static char buf[1024];
|
||||
|
||||
char *longname = NULL;
|
||||
char *shortname = NULL;
|
||||
long line;
|
||||
|
||||
char *chekedstr = NULL;
|
||||
|
||||
/* open file with positions */
|
||||
f = fopen (tagfile, "r");
|
||||
int i;
|
||||
if (!f)
|
||||
return 1;
|
||||
len = strlen( match_func );
|
||||
int pos;
|
||||
|
||||
int pos;
|
||||
char *fullpath = NULL;
|
||||
char *filename = NULL;
|
||||
long line;
|
||||
enum {start, in_filename, in_define} state = start;
|
||||
|
||||
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:
|
||||
pos = strcspn(buf, ",");
|
||||
g_free(filename);
|
||||
filename = malloc(pos + 2);
|
||||
g_strlcpy ( filename, (char *)buf, pos + 1 );
|
||||
filename = malloc (pos + 2);
|
||||
g_strlcpy(filename, (char *)buf, pos + 1);
|
||||
state = in_define;
|
||||
break;
|
||||
case in_define:
|
||||
@ -112,22 +157,25 @@ int etags_set_def_hash(char *tagfile, char *start_path, char *match_func, struct
|
||||
break;
|
||||
}
|
||||
/* check if the filename matches the define pos */
|
||||
if ( strstr ( buf, match_func ) ) {
|
||||
int l = (int)strlen( buf );
|
||||
for ( i = 0; i < l; i++) {
|
||||
if ( ( buf[i] == 0x7F || buf[i] == 0x01 ) && isdigit(buf[i+1]) ) {
|
||||
line = etags_get_pos_from(&buf[i+1]);
|
||||
state = start;
|
||||
if ( *num < MAX_DEFINITIONS ) {
|
||||
def_hash[*num].filename_len = strlen(filename);
|
||||
fullpath = g_strdup_printf("%s/%s",start_path, filename);
|
||||
canonicalize_pathname (fullpath);
|
||||
def_hash[*num].filename = g_strdup(fullpath);
|
||||
g_free(fullpath);
|
||||
def_hash[*num].line = line;
|
||||
(*num)++;
|
||||
}
|
||||
chekedstr = strstr (buf, match_func);
|
||||
if ( chekedstr ) {
|
||||
parse_define (chekedstr, &longname, &shortname, &line);
|
||||
if ( *num < MAX_DEFINITIONS - 1 ) {
|
||||
def_hash[*num].filename_len = strlen (filename);
|
||||
fullpath = g_strdup_printf("%s/%s",start_path, filename);
|
||||
canonicalize_pathname (fullpath);
|
||||
def_hash[*num].fullpath = g_strdup(fullpath);
|
||||
g_free (fullpath);
|
||||
def_hash[*num].filename = g_strdup (filename);
|
||||
if ( shortname ) {
|
||||
def_hash[*num].short_define = g_strdup (shortname);
|
||||
} else {
|
||||
def_hash[*num].short_define = g_strdup (longname);
|
||||
}
|
||||
def_hash[*num].line = line;
|
||||
g_free(shortname);
|
||||
g_free(longname);
|
||||
(*num)++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2,10 +2,15 @@
|
||||
#define MC_EDIT_ETAGS_H 1
|
||||
|
||||
#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;
|
||||
unsigned char *fullpath;
|
||||
unsigned char *filename;
|
||||
unsigned char *short_define;
|
||||
long line;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user