From: Oleg N. <ol...@re...> - 2025-08-01 13:25:49
|
cscope can't parse kernel/trace/trace_events.c (and some other files) in the linux kernel tree because this file has #define do_for_each_event_file(tr, file) \ list_for_each_entry(tr, &ftrace_trace_arrays, list) { \ list_for_each_entry(file, &tr->events, list) #define do_for_each_event_file_safe(tr, file) \ list_for_each_entry(tr, &ftrace_trace_arrays, list) { \ struct trace_event_file *___n; \ list_for_each_entry_safe(file, ___n, &tr->events, list) #define while_for_each_event_file() \ } at the top and thus the 2nd '{' in do_for_each_event_file_safe() above is not balanced. Simple example: $ cat -n test.c 1 #define open1 { 2 #define open2 { 3 #define close } 4 5 void func(void) 6 { 7 } Without this patch: $ ./src/cscope -bu test.c $ ./src/cscope -dL -1 func With this patch: $ ./src/cscope -bu test.c $ ./src/cscope -dL -1 func test.c func 5 void func(void ) Signed-off-by: Oleg Nesterov <ol...@re...> --- src/fscanner.l | 70 ++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/fscanner.l b/src/fscanner.l index 43880bf..46734ea 100644 --- a/src/fscanner.l +++ b/src/fscanner.l @@ -178,19 +178,21 @@ wsnl [ \t\r\v\f\n]|{comment} } \{ { /* count unmatched left braces for fcn def detection */ - ++braces; - - /* mark an untagged enum/struct/union so its beginning - can be found */ - if (tagdef) { - if (braces == 1) { - esudef = YES; + if (ppdefine == NO) { + ++braces; + + /* mark an untagged enum/struct/union so its beginning + can be found */ + if (tagdef) { + if (braces == 1) { + esudef = YES; + } + token = tagdef; + tagdef = '\0'; + last = first; + my_yymore(); + return(token); } - token = tagdef; - tagdef = '\0'; - last = first; - my_yymore(); - return(token); } goto more; /* NOTREACHED */ @@ -326,28 +328,30 @@ wsnl [ \t\r\v\f\n]|{comment} } \} { - /* could be the last enum member initializer */ - if (braces == initializerbraces) { - initializerbraces = -1; - initializer = NO; - } - if (--braces <= 0) { - endstate: - braces = 0; - classdef = NO; - } - if (braces == 0 || (braces == 1 && classdef == YES)) { - - /* if the end of an enum/struct/union definition */ - if (esudef == YES) { - esudef = NO; + if (ppdefine == NO) { + /* could be the last enum member initializer */ + if (braces == initializerbraces) { + initializerbraces = -1; + initializer = NO; } - /* if the end of the function */ - else if (fcndef == YES) { - fcndef = NO; - last = first; - my_yymore(); - return(FCNEND); + if (--braces <= 0) { + endstate: + braces = 0; + classdef = NO; + } + if (braces == 0 || (braces == 1 && classdef == YES)) { + + /* if the end of an enum/struct/union definition */ + if (esudef == YES) { + esudef = NO; + } + /* if the end of the function */ + else if (fcndef == YES) { + fcndef = NO; + last = first; + my_yymore(); + return(FCNEND); + } } } goto more; -- 2.25.1.362.g51ebf55 |
From: Oleg N. <ol...@re...> - 2025-08-01 13:26:26
|
The linux kernel uses a lot of annotations which confuse cscope. Simple example: $ cat -n test.c 1 void func1(void) __acquires(RCU) 2 { 3 X = 1; 4 } 5 6 void func2(void) __releases(RCU) 7 { 8 X = 1; 9 } Without this patch: $ ./src/cscope -bu test.c $ ./src/cscope -dL -0 X test.c __acquires 3 X = 1; test.c __releases 8 X = 1; With this patch: $ ./src/cscope -bu -K __acquires,__releases test.c $ ./src/cscope -dL -0 X test.c func1 3 X = 1; test.c func2 8 X = 1; Signed-off-by: Oleg Nesterov <ol...@re...> --- src/global.h | 1 + src/lookup.c | 35 +++++++++++++++++++++++++++++++---- src/main.c | 5 ++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/global.h b/src/global.h index a6f1486..5f75b68 100644 --- a/src/global.h +++ b/src/global.h @@ -342,6 +342,7 @@ char *read_block(void); char *scanpast(char c); +void add_keyword(char *csk); void addcmd(int f, char *s); void addsrcfile(char *path); void askforchar(void); diff --git a/src/lookup.c b/src/lookup.c index d8595db..71e4aac 100644 --- a/src/lookup.c +++ b/src/lookup.c @@ -51,7 +51,9 @@ char uniontext[] = "union"; * without changing the database file version and adding compatibility code * for old databases. */ -struct keystruct keyword[] = { +#define KEYWORDS 64 + +struct keystruct keyword[KEYWORDS] = { {"", '\0', NULL}, /* dummy entry */ {"#define", ' ', NULL}, /* must be table entry 1 */ {"#include", ' ', NULL}, /* must be table entry 2 */ @@ -93,7 +95,32 @@ struct keystruct keyword[] = { {"signed", ' ', NULL}, {"volatile", ' ', NULL}, }; -#define KEYWORDS (sizeof(keyword) / sizeof(keyword[0])) + +static int keyword_nr = 38; + +void add_keyword(char *csk) +{ + for (;;) { + char *eok = strchrnul(csk, ','); + int last = !*eok; + + *eok = 0; + if (*csk) { + if (keyword_nr == KEYWORDS) { + fprintf(stderr, "KEYWORDS overflow\n"); + myexit(1); + } + keyword[keyword_nr].text = csk; + keyword[keyword_nr].delim = '('; + keyword_nr++; + } + + if (last) + break; + csk = eok + 1; + } +} + #define HASHMOD (KEYWORDS * 2 + 1) @@ -106,8 +133,8 @@ initsymtab(void) { unsigned int i, j; struct keystruct *p; - - for (i = 1; i < KEYWORDS; ++i) { + + for (i = 1; i < keyword_nr; ++i) { p = keyword + i; j = hash(p->text) % HASHMOD; p->next = hashtab[j]; diff --git a/src/main.c b/src/main.c index 2ffabc3..055b222 100644 --- a/src/main.c +++ b/src/main.c @@ -153,7 +153,7 @@ char ** parse_options(int *argc, char **argv) while ((opt = getopt_long(argcc, argv, - "hVbcCdeF:f:I:i:kLl0:1:2:3:4:5:6:7:8:9:P:p:qRs:TUuvX", + "hVbcCdeF:f:I:i:kLl0:1:2:3:4:5:6:7:8:9:P:p:qRs:TUuvXK:", lopts, &longind)) != -1) { switch(opt) { @@ -273,6 +273,9 @@ char ** parse_options(int *argc, char **argv) case 's': /* additional source file directory */ sourcedir(optarg); break; + case 'K': + add_keyword(optarg); + break; } } /* -- 2.25.1.362.g51ebf55 |