123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /* editor C-code navigation via tags.
- make TAGS file via command:
- $ find . -type f -name "*.[ch]" | etags -l c --declarations -
- or, if etags utility not installed:
- $ find . -type f -name "*.[ch]" | ctags --c-kinds=+p --fields=+iaS --extra=+q -e -L-
- Copyright (C) 2009 Free Software Foundation, Inc.
- Authors:
- Ilia Maslakov <il.smind@gmail.com>, 2009
- Slava Zanko <slavazanko@gmail.com>, 2009
- This file is part of the Midnight Commander.
- The Midnight Commander is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
- The Midnight Commander is distributed in the hope that it will be
- useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301, USA.
- */
- #include <config.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <inttypes.h>
- #include <string.h>
- #include <ctype.h>
- #include "../src/global.h"
- #include "../src/util.h" /* canonicalize_pathname() */
- #include "../edit/etags.h"
- /*** file scope functions **********************************************/
- static gboolean parse_define(char *buf, char **long_name, char **short_name, long *line)
- {
- 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 TRUE;
- break;
- }
- buf++;
- c = *buf;
- }
- *long_name = NULL;
- *short_name = NULL;
- *line = 0;
- return FALSE;
- }
- /*** public functions **************************************************/
- int etags_set_definition_hash(const char *tagfile, const char *start_path,
- const char *match_func,
- etags_hash_t *def_hash)
- {
- enum {start, in_filename, in_define} state = start;
- FILE *f;
- static char buf[BUF_LARGE];
- char *longname = NULL;
- char *shortname = NULL;
- long line;
- char *chekedstr = NULL;
- int num = 0; /* returned value */
- int pos;
- char *filename = NULL;
- /* open file with positions */
- f = fopen (tagfile, "r");
- if (!f)
- return 0;
- while (fgets (buf, sizeof (buf), f)) {
- switch ( state ) {
- case start:
- if ( buf[0] == 0x0C ) {
- state = in_filename;
- }
- break;
- case in_filename:
- pos = strcspn(buf, ",");
- g_free(filename);
- filename = g_malloc (pos + 2);
- g_strlcpy(filename, (char *)buf, pos + 1);
- state = in_define;
- break;
- case in_define:
- if ( buf[0] == 0x0C ) {
- state = in_filename;
- break;
- }
- /* check if the filename matches the define pos */
- 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);
- def_hash[num].fullpath = g_build_filename ( start_path, filename, (char *) NULL);
- canonicalize_pathname (def_hash[num].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;
- }
- }
- g_free(filename);
- return num;
- }
|