@@ -1176,7 +1176,10 @@ def find_word_in_code_line(
11761176 return line_no , word_range
11771177
11781178 def preprocess (
1179- self , pp_defs : dict = None , include_dirs : set = None , debug : bool = False
1179+ self ,
1180+ pp_defs : dict = None ,
1181+ include_dirs : set = None ,
1182+ debug : bool = False ,
11801183 ) -> tuple [list , list ]:
11811184 if pp_defs is None :
11821185 pp_defs = {}
@@ -1265,7 +1268,9 @@ def parse(
12651268 if self .preproc :
12661269 log .debug ("=== PreProc Pass ===\n " )
12671270 pp_skips , pp_defines = self .preprocess (
1268- pp_defs = pp_defs , include_dirs = include_dirs , debug = debug
1271+ pp_defs = pp_defs ,
1272+ include_dirs = include_dirs ,
1273+ debug = debug ,
12691274 )
12701275 for pp_reg in pp_skips :
12711276 file_ast .start_ppif (pp_reg [0 ])
@@ -2038,6 +2043,7 @@ def replace_ops(expr: str):
20382043 expr = expr .replace ("!=" , " <> " )
20392044 expr = expr .replace ("!" , " not " )
20402045 expr = expr .replace (" <> " , " != " )
2046+
20412047 return expr
20422048
20432049 def replace_defined (line : str ):
@@ -2070,7 +2076,9 @@ def replace_vars(line: str):
20702076
20712077 if defs is None :
20722078 defs = {}
2073- out_line = replace_defined (text )
2079+
2080+ out_line = text
2081+ out_line = replace_defined (out_line )
20742082 out_line = replace_vars (out_line )
20752083 try :
20762084 line_res = eval (replace_ops (out_line ))
@@ -2098,26 +2106,27 @@ def replace_vars(line: str):
20982106 if def_cont_name is not None :
20992107 output_file .append ("" )
21002108 if line .rstrip ()[- 1 ] != "\\ " :
2101- defs_tmp [ def_cont_name ] += line .strip ()
2109+ append_multiline_macro ( defs_tmp , def_cont_name , line .strip () )
21022110 def_cont_name = None
21032111 else :
2104- defs_tmp [def_cont_name ] += line [0 :- 1 ].strip ()
2112+ append_multiline_macro (defs_tmp , def_cont_name , line [0 :- 1 ].strip ())
2113+
21052114 continue
21062115 # Handle conditional statements
21072116 match = FRegex .PP_REGEX .match (line )
2108- if match :
2117+ if match and check_pp_prefix ( match . group ( 1 )) :
21092118 output_file .append (line )
21102119 def_name = None
21112120 if_start = False
21122121 # Opening conditional statements
2113- if match .group (1 ) == "if " :
2114- is_path = eval_pp_if (line [match .end (1 ) :], defs_tmp )
2122+ if match .group (2 ). lower ( ) == "if " :
2123+ is_path = eval_pp_if (line [match .end (2 ) :], defs_tmp )
21152124 if_start = True
2116- elif match .group (1 ) == "ifdef" :
2125+ elif match .group (2 ). lower ( ) == "ifdef" :
21172126 if_start = True
21182127 def_name = line [match .end (0 ) :].strip ()
21192128 is_path = def_name in defs_tmp
2120- elif match .group (1 ) == "ifndef" :
2129+ elif match .group (2 ). lower ( ) == "ifndef" :
21212130 if_start = True
21222131 def_name = line [match .end (0 ) :].strip ()
21232132 is_path = not (def_name in defs_tmp )
@@ -2135,7 +2144,7 @@ def replace_vars(line: str):
21352144 inc_start = False
21362145 exc_start = False
21372146 exc_continue = False
2138- if match .group (1 ) == "elif" :
2147+ if match .group (2 ). lower ( ) == "elif" :
21392148 if (not pp_stack_group ) or (pp_stack_group [- 1 ][0 ] != len (pp_stack )):
21402149 # First elif statement for this elif group
21412150 if pp_stack [- 1 ][0 ] < 0 :
@@ -2147,15 +2156,15 @@ def replace_vars(line: str):
21472156 exc_continue = True
21482157 if pp_stack [- 1 ][0 ] < 0 :
21492158 pp_stack [- 1 ][0 ] = i + 1
2150- elif eval_pp_if (line [match .end (1 ) :], defs_tmp ):
2159+ elif eval_pp_if (line [match .end (2 ) :], defs_tmp ):
21512160 pp_stack [- 1 ][1 ] = i + 1
21522161 pp_skips .append (pp_stack .pop ())
21532162 pp_stack_group [- 1 ][1 ] = True
21542163 pp_stack .append ([- 1 , - 1 ])
21552164 inc_start = True
21562165 else :
21572166 exc_start = True
2158- elif match .group (1 ) == "else" :
2167+ elif match .group (2 ). lower ( ) == "else" :
21592168 if pp_stack [- 1 ][0 ] < 0 :
21602169 pp_stack [- 1 ][0 ] = i + 1
21612170 exc_start = True
@@ -2171,7 +2180,7 @@ def replace_vars(line: str):
21712180 pp_skips .append (pp_stack .pop ())
21722181 pp_stack .append ([- 1 , - 1 ])
21732182 inc_start = True
2174- elif match .group (1 ) == "endif" :
2183+ elif match .group (2 ). lower ( ) == "endif" :
21752184 if pp_stack_group and (pp_stack_group [- 1 ][0 ] == len (pp_stack )):
21762185 pp_stack_group .pop ()
21772186 if pp_stack [- 1 ][0 ] < 0 :
@@ -2192,10 +2201,12 @@ def replace_vars(line: str):
21922201 continue
21932202 # Handle variable/macro definitions files
21942203 match = FRegex .PP_DEF .match (line )
2195- if (match is not None ) and ((len (pp_stack ) == 0 ) or (pp_stack [- 1 ][0 ] < 0 )):
2204+ if (match is not None and check_pp_prefix (match .group (1 ))) and (
2205+ (len (pp_stack ) == 0 ) or (pp_stack [- 1 ][0 ] < 0 )
2206+ ):
21962207 output_file .append (line )
21972208 pp_defines .append (i + 1 )
2198- def_name = match .group (2 )
2209+ def_name = match .group (3 )
21992210 # If this is an argument list of a function add them to the name
22002211 # get_definition will only return the function name upon hover
22012212 # hence if the argument list is appended in the def_name then
@@ -2204,18 +2215,29 @@ def replace_vars(line: str):
22042215 # This also does not allow for multiline argument list definitions.
22052216 # if match.group(3):
22062217 # def_name += match.group(3)
2207- if (match .group (1 ) == "define" ) and (def_name not in defs_tmp ):
2218+ if (match .group (2 ) == "define" ) and (def_name not in defs_tmp ):
22082219 eq_ind = line [match .end (0 ) :].find (" " )
2220+ if eq_ind < 0 :
2221+ eq_ind = line [match .end (0 ) :].find ("\t " )
2222+
22092223 if eq_ind >= 0 :
22102224 # Handle multiline macros
22112225 if line .rstrip ()[- 1 ] == "\\ " :
2212- defs_tmp [ def_name ] = line [match .end (0 ) + eq_ind : - 1 ].strip ()
2226+ def_value = line [match .end (0 ) + eq_ind : - 1 ].strip ()
22132227 def_cont_name = def_name
22142228 else :
2215- defs_tmp [ def_name ] = line [match .end (0 ) + eq_ind :].strip ()
2229+ def_value = line [match .end (0 ) + eq_ind :].strip ()
22162230 else :
2217- defs_tmp [def_name ] = "True"
2218- elif (match .group (1 ) == "undef" ) and (def_name in defs_tmp ):
2231+ def_value = "True"
2232+
2233+ # are there arguments to parse?
2234+ if match .group (4 ):
2235+ def_value = (match .group (5 ), def_value )
2236+
2237+ defs_tmp [def_name ] = def_value
2238+ elif (
2239+ match .group (2 ) == "undef"
2240+ ) and (def_name in defs_tmp ):
22192241 defs_tmp .pop (def_name , None )
22202242 log .debug (f"{ line .strip ()} !!! Define statement({ i + 1 } )" )
22212243 continue
@@ -2265,8 +2287,16 @@ def replace_vars(line: str):
22652287 continue
22662288 def_regex = def_regexes .get (def_tmp )
22672289 if def_regex is None :
2268- def_regex = re .compile (rf"\b{ def_tmp } \b" )
2290+ if isinstance (value , tuple ):
2291+ def_regex = expand_def_func_macro (def_tmp , value )
2292+ else :
2293+ def_regex = re .compile (rf"\b{ def_tmp } \b" )
2294+
22692295 def_regexes [def_tmp ] = def_regex
2296+
2297+ if isinstance (def_regex , tuple ):
2298+ def_regex , value = def_regex
2299+
22702300 line_new , nsubs = def_regex .subn (value , line )
22712301 if nsubs > 0 :
22722302 log .debug (
@@ -2275,3 +2305,33 @@ def replace_vars(line: str):
22752305 line = line_new
22762306 output_file .append (line )
22772307 return output_file , pp_skips , pp_defines , defs_tmp
2308+
2309+
2310+ def expand_def_func_macro (def_name : str , def_value : tuple [str , str ]):
2311+ def_args , sub = def_value
2312+ def_args = def_args .split ("," )
2313+ regex = re .compile (rf"\b{ def_name } \s*\({ ',' .join (['(.*)' ]* len (def_args ))} \)" )
2314+
2315+ for i , arg in enumerate (def_args ):
2316+ arg = arg .strip ()
2317+ sub = re .sub (rf"\b({ arg } )\b" , rf"\\ { i + 1 } " , sub )
2318+
2319+ return regex , sub
2320+
2321+
2322+ def append_multiline_macro (pp_defs : dict , def_name : str , line : str ):
2323+ def_value = pp_defs [def_name ]
2324+ def_args = None
2325+ if isinstance (def_value , tuple ):
2326+ def_args , def_value = def_value
2327+
2328+ def_value += line
2329+
2330+ if def_args is not None :
2331+ def_value = (def_args , def_value )
2332+
2333+ pp_defs [def_name ] = def_value
2334+
2335+
2336+ def check_pp_prefix (prefix : str ):
2337+ return prefix == "#"
0 commit comments