11#!/usr/bin/python3
22
3- ## Copyright 2018-2023 John Donoghue
3+ ## Copyright 2018-2024 John Donoghue
44##
55## This program is free software: you can redistribute it and/or modify it
66## under the terms of the GNU General Public License as published by
1616## along with this program. If not, see
1717## <https://www.gnu.org/licenses/>.
1818
19- ## mkfuncdocs v1.0.7
19+ ## mkfuncdocs v1.0.8
2020## mkfuncdocs.py will attempt to extract the help texts from functions in src
2121## dirs, extracting only those that are in the specifed INDEX file and output them
2222## to stdout in texi format
@@ -89,6 +89,36 @@ def find_defun_line_in_file(filename, fnname):
8989
9090 return - 1
9191
92+ def find_function_line_in_file (filename , fnname ):
93+ linecnt = 0
94+ func = False
95+ defun_line = re .compile (r"^\s*function \s*" )
96+ with open (filename , 'rt' ) as f :
97+ for line in f :
98+ if func == True :
99+ x = line .strip ()
100+ if x .startswith ("## -*- texinfo -*-" ):
101+ return linecnt
102+ else :
103+ func = False
104+
105+ if re .match (defun_line , line ):
106+ if line .find ("=" ) != - 1 :
107+ x = line .split ("=" )
108+ x = x [- 1 ]
109+ else :
110+ x = line .replace ("function " , "" )
111+
112+ x = x .split ("(" )
113+ x = x [0 ].strip ()
114+ if x == fnname :
115+ func = True
116+
117+ linecnt = linecnt + 1
118+
119+ return - 1
120+
121+
92122def read_m_file (filename , skip = 0 ):
93123 help = []
94124 inhelp = False
@@ -195,6 +225,29 @@ def read_index (filename, ignore):
195225
196226 return index ;
197227
228+ def find_class_file (fname , paths ):
229+
230+ for f in paths :
231+ # class constructor ?
232+ name = f + "/@" + fname + "/" + fname + ".m"
233+ if os .path .isfile (name ):
234+ return name , 0
235+
236+ # perhaps classname.func format ?
237+ x = fname .split ("." )
238+ if len (x ) > 0 :
239+ zname = x .pop ()
240+ cname = "." .join (x )
241+ name = f + "/" + cname + ".m"
242+ if os .path .isfile (name ):
243+ idx = find_function_line_in_file (name , zname )
244+ if idx >= 0 :
245+ return name , idx
246+ name = f + "/@" + cname + "/" + zname + ".m"
247+ if os .path .isfile (name ):
248+ return name , 0
249+ return None , - 1
250+
198251def find_func_file (fname , paths , prefix , scanfiles = False ):
199252 for f in paths :
200253 name = f + "/" + fname + ".m"
@@ -205,7 +258,6 @@ def find_func_file(fname, paths, prefix, scanfiles=False):
205258 if os .path .isfile (name ):
206259 return name , 0
207260 name = f + "/" + fname + ".cc"
208- name = f + "/" + fname + ".cc"
209261 if os .path .isfile (name ):
210262 return name , 0
211263 name = f + "/" + fname + ".cpp"
@@ -335,19 +387,26 @@ def process (args):
335387 ref = f .split ("/" )[- 1 ]
336388 filename , lineno = find_func_file (path , options ["srcdir" ], options ["funcprefix" ])
337389 elif "." in f :
338- parts = f .split ('.' )
339- cnt = 0
340- path = ""
341- for p in parts :
390+ path = f
391+ ref = f .split ("." )[- 1 ]
392+ name = f .split ("." )[- 1 ]
393+ filename , lineno = find_class_file (path , options ["srcdir" ])
394+
395+ if not filename :
396+ parts = f .split ('.' )
397+ cnt = 0
398+ path = ""
399+ for p in parts :
342400 if cnt < len (parts )- 1 :
343401 path = path + "/+"
344402 else :
345403 path = path + "/"
346404 path = path + p
347405 cnt = cnt + 1
348- name = f ;
349- ref = parts [- 1 ]
350- filename , lineno = find_func_file (path , options ["srcdir" ], options ["funcprefix" ])
406+ name = f ;
407+ ref = parts [- 1 ]
408+ filename , lineno = find_func_file (path , options ["srcdir" ], options ["funcprefix" ])
409+
351410 elif "/" in f :
352411 path = f
353412 name = f
@@ -360,7 +419,7 @@ def process (args):
360419 filename , lineno = find_func_file (path , options ["srcdir" ], options ["funcprefix" ], options ['allowscan' ])
361420
362421 if not filename :
363- sys .stderr .write ("Warning: Cant find source file for {}\n " .format (path ))
422+ sys .stderr .write ("Warning: Cant find source file for {}\n " .format (f ))
364423 else :
365424 h = read_help (filename , lineno )
366425
0 commit comments