@@ -1176,7 +1176,10 @@ def find_word_in_code_line(
1176
1176
return line_no , word_range
1177
1177
1178
1178
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 ,
1180
1183
) -> tuple [list , list ]:
1181
1184
if pp_defs is None :
1182
1185
pp_defs = {}
@@ -1265,7 +1268,9 @@ def parse(
1265
1268
if self .preproc :
1266
1269
log .debug ("=== PreProc Pass ===\n " )
1267
1270
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 ,
1269
1274
)
1270
1275
for pp_reg in pp_skips :
1271
1276
file_ast .start_ppif (pp_reg [0 ])
@@ -2038,6 +2043,7 @@ def replace_ops(expr: str):
2038
2043
expr = expr .replace ("!=" , " <> " )
2039
2044
expr = expr .replace ("!" , " not " )
2040
2045
expr = expr .replace (" <> " , " != " )
2046
+
2041
2047
return expr
2042
2048
2043
2049
def replace_defined (line : str ):
@@ -2070,7 +2076,9 @@ def replace_vars(line: str):
2070
2076
2071
2077
if defs is None :
2072
2078
defs = {}
2073
- out_line = replace_defined (text )
2079
+
2080
+ out_line = text
2081
+ out_line = replace_defined (out_line )
2074
2082
out_line = replace_vars (out_line )
2075
2083
try :
2076
2084
line_res = eval (replace_ops (out_line ))
@@ -2098,26 +2106,27 @@ def replace_vars(line: str):
2098
2106
if def_cont_name is not None :
2099
2107
output_file .append ("" )
2100
2108
if line .rstrip ()[- 1 ] != "\\ " :
2101
- defs_tmp [ def_cont_name ] += line .strip ()
2109
+ append_multiline_macro ( defs_tmp , def_cont_name , line .strip () )
2102
2110
def_cont_name = None
2103
2111
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
+
2105
2114
continue
2106
2115
# Handle conditional statements
2107
2116
match = FRegex .PP_REGEX .match (line )
2108
- if match :
2117
+ if match and check_pp_prefix ( match . group ( 1 )) :
2109
2118
output_file .append (line )
2110
2119
def_name = None
2111
2120
if_start = False
2112
2121
# 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 )
2115
2124
if_start = True
2116
- elif match .group (1 ) == "ifdef" :
2125
+ elif match .group (2 ). lower ( ) == "ifdef" :
2117
2126
if_start = True
2118
2127
def_name = line [match .end (0 ) :].strip ()
2119
2128
is_path = def_name in defs_tmp
2120
- elif match .group (1 ) == "ifndef" :
2129
+ elif match .group (2 ). lower ( ) == "ifndef" :
2121
2130
if_start = True
2122
2131
def_name = line [match .end (0 ) :].strip ()
2123
2132
is_path = not (def_name in defs_tmp )
@@ -2135,7 +2144,7 @@ def replace_vars(line: str):
2135
2144
inc_start = False
2136
2145
exc_start = False
2137
2146
exc_continue = False
2138
- if match .group (1 ) == "elif" :
2147
+ if match .group (2 ). lower ( ) == "elif" :
2139
2148
if (not pp_stack_group ) or (pp_stack_group [- 1 ][0 ] != len (pp_stack )):
2140
2149
# First elif statement for this elif group
2141
2150
if pp_stack [- 1 ][0 ] < 0 :
@@ -2147,15 +2156,15 @@ def replace_vars(line: str):
2147
2156
exc_continue = True
2148
2157
if pp_stack [- 1 ][0 ] < 0 :
2149
2158
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 ):
2151
2160
pp_stack [- 1 ][1 ] = i + 1
2152
2161
pp_skips .append (pp_stack .pop ())
2153
2162
pp_stack_group [- 1 ][1 ] = True
2154
2163
pp_stack .append ([- 1 , - 1 ])
2155
2164
inc_start = True
2156
2165
else :
2157
2166
exc_start = True
2158
- elif match .group (1 ) == "else" :
2167
+ elif match .group (2 ). lower ( ) == "else" :
2159
2168
if pp_stack [- 1 ][0 ] < 0 :
2160
2169
pp_stack [- 1 ][0 ] = i + 1
2161
2170
exc_start = True
@@ -2171,7 +2180,7 @@ def replace_vars(line: str):
2171
2180
pp_skips .append (pp_stack .pop ())
2172
2181
pp_stack .append ([- 1 , - 1 ])
2173
2182
inc_start = True
2174
- elif match .group (1 ) == "endif" :
2183
+ elif match .group (2 ). lower ( ) == "endif" :
2175
2184
if pp_stack_group and (pp_stack_group [- 1 ][0 ] == len (pp_stack )):
2176
2185
pp_stack_group .pop ()
2177
2186
if pp_stack [- 1 ][0 ] < 0 :
@@ -2192,10 +2201,12 @@ def replace_vars(line: str):
2192
2201
continue
2193
2202
# Handle variable/macro definitions files
2194
2203
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
+ ):
2196
2207
output_file .append (line )
2197
2208
pp_defines .append (i + 1 )
2198
- def_name = match .group (2 )
2209
+ def_name = match .group (3 )
2199
2210
# If this is an argument list of a function add them to the name
2200
2211
# get_definition will only return the function name upon hover
2201
2212
# hence if the argument list is appended in the def_name then
@@ -2204,18 +2215,29 @@ def replace_vars(line: str):
2204
2215
# This also does not allow for multiline argument list definitions.
2205
2216
# if match.group(3):
2206
2217
# 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 ):
2208
2219
eq_ind = line [match .end (0 ) :].find (" " )
2220
+ if eq_ind < 0 :
2221
+ eq_ind = line [match .end (0 ) :].find ("\t " )
2222
+
2209
2223
if eq_ind >= 0 :
2210
2224
# Handle multiline macros
2211
2225
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 ()
2213
2227
def_cont_name = def_name
2214
2228
else :
2215
- defs_tmp [ def_name ] = line [match .end (0 ) + eq_ind :].strip ()
2229
+ def_value = line [match .end (0 ) + eq_ind :].strip ()
2216
2230
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 ):
2219
2241
defs_tmp .pop (def_name , None )
2220
2242
log .debug (f"{ line .strip ()} !!! Define statement({ i + 1 } )" )
2221
2243
continue
@@ -2265,8 +2287,16 @@ def replace_vars(line: str):
2265
2287
continue
2266
2288
def_regex = def_regexes .get (def_tmp )
2267
2289
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
+
2269
2295
def_regexes [def_tmp ] = def_regex
2296
+
2297
+ if isinstance (def_regex , tuple ):
2298
+ def_regex , value = def_regex
2299
+
2270
2300
line_new , nsubs = def_regex .subn (value , line )
2271
2301
if nsubs > 0 :
2272
2302
log .debug (
@@ -2275,3 +2305,33 @@ def replace_vars(line: str):
2275
2305
line = line_new
2276
2306
output_file .append (line )
2277
2307
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