@@ -68,6 +68,9 @@ def parse_files(self, file_list, file_not_found_cb):
6868 handling directories if any
6969 """
7070
71+ if not file_list :
72+ return
73+
7174 for fname in file_list :
7275 if self .srctree :
7376 f = os .path .join (self .srctree , fname )
@@ -84,40 +87,70 @@ def parse_files(self, file_list, file_not_found_cb):
8487
8588class KernelFiles ():
8689 """
87- Parse lernel-doc tags on multiple kernel source files.
90+ Parse kernel-doc tags on multiple kernel source files.
91+
92+ There are two type of parsers defined here:
93+ - self.parse_file(): parses both kernel-doc markups and
94+ EXPORT_SYMBOL* macros;
95+ - self.process_export_file(): parses only EXPORT_SYMBOL* macros.
8896 """
8997
98+ def warning (self , msg ):
99+ """Ancillary routine to output a warning and increment error count"""
100+
101+ self .config .log .warning (msg )
102+ self .errors += 1
103+
104+ def error (self , msg ):
105+ """Ancillary routine to output an error and increment error count"""
106+
107+ self .config .log .error (msg )
108+ self .errors += 1
109+
90110 def parse_file (self , fname ):
91111 """
92112 Parse a single Kernel source.
93113 """
94114
115+ # Prevent parsing the same file twice if results are cached
116+ if fname in self .files :
117+ return
118+
95119 doc = KernelDoc (self .config , fname )
96- doc .run ()
120+ export_table , entries = doc .parse_kdoc ()
121+
122+ self .export_table [fname ] = export_table
123+
124+ self .files .add (fname )
125+ self .export_files .add (fname ) # parse_kdoc() already check exports
97126
98- return doc . entries
127+ self . results [ fname ] = entries
99128
100129 def process_export_file (self , fname ):
101130 """
102131 Parses EXPORT_SYMBOL* macros from a single Kernel source file.
103132 """
104- try :
105- with open (fname , "r" , encoding = "utf8" ,
106- errors = "backslashreplace" ) as fp :
107- for line in fp :
108- KernelDoc .process_export (self .config .function_table , line )
109133
110- except IOError :
111- self .config .log .error ("Error: Cannot open fname %s" , fname )
112- self .config .errors += 1
134+ # Prevent parsing the same file twice if results are cached
135+ if fname in self .export_files :
136+ return
137+
138+ doc = KernelDoc (self .config , fname )
139+ export_table = doc .parse_export ()
140+
141+ if not export_table :
142+ self .error (f"Error: Cannot check EXPORT_SYMBOL* on { fname } " )
143+ export_table = set ()
144+
145+ self .export_table [fname ] = export_table
146+ self .export_files .add (fname )
113147
114148 def file_not_found_cb (self , fname ):
115149 """
116150 Callback to warn if a file was not found.
117151 """
118152
119- self .config .log .error ("Cannot find file %s" , fname )
120- self .config .errors += 1
153+ self .error (f"Cannot find file { fname } " )
121154
122155 def __init__ (self , verbose = False , out_style = None ,
123156 werror = False , wreturn = False , wshort_desc = False ,
@@ -147,7 +180,9 @@ def __init__(self, verbose=False, out_style=None,
147180 if kdoc_werror :
148181 werror = kdoc_werror
149182
150- # Set global config data used on all files
183+ # Some variables are global to the parser logic as a whole as they are
184+ # used to send control configuration to KernelDoc class. As such,
185+ # those variables are read-only inside the KernelDoc.
151186 self .config = argparse .Namespace
152187
153188 self .config .verbose = verbose
@@ -156,27 +191,25 @@ def __init__(self, verbose=False, out_style=None,
156191 self .config .wshort_desc = wshort_desc
157192 self .config .wcontents_before_sections = wcontents_before_sections
158193
159- self .config .function_table = set ()
160- self .config .source_map = {}
161-
162194 if not logger :
163195 self .config .log = logging .getLogger ("kernel-doc" )
164196 else :
165197 self .config .log = logger
166198
167- self .config .kernel_version = os . environ . get ( "KERNELVERSION" ,
168- "unknown kernel version'" )
199+ self .config .warning = self . warning
200+
169201 self .config .src_tree = os .environ .get ("SRCTREE" , None )
170202
171- self . out_style = out_style
203+ # Initialize variables that are internal to KernelFiles
172204
173- # Initialize internal variables
205+ self . out_style = out_style
174206
175- self .config . errors = 0
207+ self .errors = 0
176208 self .results = {}
177209
178210 self .files = set ()
179211 self .export_files = set ()
212+ self .export_table = {}
180213
181214 def parse (self , file_list , export_file = None ):
182215 """
@@ -185,28 +218,11 @@ def parse(self, file_list, export_file=None):
185218
186219 glob = GlobSourceFiles (srctree = self .config .src_tree )
187220
188- # Prevent parsing the same file twice to speedup parsing and
189- # avoid reporting errors multiple times
190-
191221 for fname in glob .parse_files (file_list , self .file_not_found_cb ):
192- if fname not in self .files :
193- self .results [fname ] = self .parse_file (fname )
194- self .files .add (fname )
195-
196- # If a list of export files was provided, parse EXPORT_SYMBOL*
197- # from files that weren't fully parsed
198-
199- if not export_file :
200- return
201-
202- self .export_files |= self .files
203-
204- glob = GlobSourceFiles (srctree = self .config .src_tree )
222+ self .parse_file (fname )
205223
206224 for fname in glob .parse_files (export_file , self .file_not_found_cb ):
207- if fname not in self .export_files :
208- self .process_export_file (fname )
209- self .export_files .add (fname )
225+ self .process_export_file (fname )
210226
211227 def out_msg (self , fname , name , arg ):
212228 """
@@ -223,32 +239,35 @@ def out_msg(self, fname, name, arg):
223239
224240 def msg (self , enable_lineno = False , export = False , internal = False ,
225241 symbol = None , nosymbol = None , no_doc_sections = False ,
226- filenames = None ):
242+ filenames = None , export_file = None ):
227243 """
228244 Interacts over the kernel-doc results and output messages,
229245 returning kernel-doc markups on each interaction
230246 """
231247
232- function_table = self .config .function_table
233-
234- if symbol :
235- for s in symbol :
236- function_table .add (s )
237-
238- # Output none mode: only warnings will be shown
239- if not self .out_style :
240- return
241-
242248 self .out_style .set_config (self .config )
243249
244- self .out_style .set_filter (export , internal , symbol , nosymbol ,
245- function_table , enable_lineno ,
246- no_doc_sections )
247-
248250 if not filenames :
249251 filenames = sorted (self .results .keys ())
250252
251253 for fname in filenames :
254+ function_table = set ()
255+
256+ if internal or export :
257+ if not export_file :
258+ export_file = [fname ]
259+
260+ for f in export_file :
261+ function_table |= self .export_table [f ]
262+
263+ if symbol :
264+ for s in symbol :
265+ function_table .add (s )
266+
267+ self .out_style .set_filter (export , internal , symbol , nosymbol ,
268+ function_table , enable_lineno ,
269+ no_doc_sections )
270+
252271 msg = ""
253272 for name , arg in self .results [fname ]:
254273 msg += self .out_msg (fname , name , arg )
@@ -261,12 +280,3 @@ def msg(self, enable_lineno=False, export=False, internal=False,
261280 fname , ln , dtype )
262281 if msg :
263282 yield fname , msg
264-
265- @property
266- def errors (self ):
267- """
268- Return a count of the number of warnings found, including
269- the ones displayed while interacting over self.msg.
270- """
271-
272- return self .config .errors
0 commit comments