60 print(" -i or --ignore") |
59 print(" -i or --ignore") |
61 print(" Ignore the set of builtin modules") |
60 print(" Ignore the set of builtin modules") |
62 print(" -l language or --language=language") |
61 print(" -l language or --language=language") |
63 print(" Generate an API file for the given programming language.") |
62 print(" Generate an API file for the given programming language.") |
64 print(" Supported programming languages are:") |
63 print(" Supported programming languages are:") |
65 for lang in sorted( |
64 for lang in sorted(DocumentationTools.supportedExtensionsDictForApis.keys()): |
66 DocumentationTools.supportedExtensionsDictForApis.keys()): |
|
67 print(" * {0}".format(lang)) |
65 print(" * {0}".format(lang)) |
68 print(" The default is 'Python3'.") |
66 print(" The default is 'Python3'.") |
69 print(" This option may be repeated multiple times.") |
67 print(" This option may be repeated multiple times.") |
70 print(" -o filename or --output=filename") |
68 print(" -o filename or --output=filename") |
71 print(" Write the API information to the named file." |
69 print( |
72 " A '%L' placeholder") # __IGNORE_WARNING_M601__ |
70 " Write the API information to the named file." |
73 print(" is replaced by the language of the API file" |
71 " A '%L' placeholder" # __IGNORE_WARNING_M601__ |
74 " (see --language).") |
72 ) |
|
73 print(" is replaced by the language of the API file" " (see --language).") |
75 print(" -p or --private") |
74 print(" -p or --private") |
76 print(" Include private methods and functions.") |
75 print(" Include private methods and functions.") |
77 print(" -R, -r or --recursive") |
76 print(" -R, -r or --recursive") |
78 print(" Perform a recursive search for source files.") |
77 print(" Perform a recursive search for source files.") |
79 print(" -t ext or --extension=ext") |
78 print(" -t ext or --extension=ext") |
159 elif k in ["-p", "--private"]: |
181 elif k in ["-p", "--private"]: |
160 includePrivate = True |
182 includePrivate = True |
161 elif k in ["-l", "--language"]: |
183 elif k in ["-l", "--language"]: |
162 if v not in progLanguages: |
184 if v not in progLanguages: |
163 if v not in DocumentationTools.supportedExtensionsDictForApis: |
185 if v not in DocumentationTools.supportedExtensionsDictForApis: |
164 sys.stderr.write( |
186 sys.stderr.write("Wrong language given: {0}. Aborting\n".format(v)) |
165 "Wrong language given: {0}. Aborting\n".format(v)) |
|
166 sys.exit(1) |
187 sys.exit(1) |
167 else: |
188 else: |
168 progLanguages.append(v) |
189 progLanguages.append(v) |
169 elif k in ["-e", "--eol"]: |
190 elif k in ["-e", "--eol"]: |
170 if v.lower() == "cr": |
191 if v.lower() == "cr": |
171 newline = '\r' |
192 newline = "\r" |
172 elif v.lower() == "lf": |
193 elif v.lower() == "lf": |
173 newline = '\n' |
194 newline = "\n" |
174 elif v.lower() == "crlf": |
195 elif v.lower() == "crlf": |
175 newline = '\r\n' |
196 newline = "\r\n" |
176 |
197 |
177 if not args: |
198 if not args: |
178 usage() |
199 usage() |
179 |
200 |
180 if outputFileName == "": |
201 if outputFileName == "": |
181 sys.stderr.write("No output file given. Aborting\n") |
202 sys.stderr.write("No output file given. Aborting\n") |
182 sys.exit(1) |
203 sys.exit(1) |
183 |
204 |
184 if len(progLanguages) == 0: |
205 if len(progLanguages) == 0: |
185 progLanguages = ["Python3"] |
206 progLanguages = ["Python3"] |
186 |
207 |
187 for progLanguage in sorted(progLanguages): |
208 for progLanguage in sorted(progLanguages): |
188 basename = "" |
209 basename = "" |
189 apis = [] |
210 apis = [] |
190 basesDict = {} |
211 basesDict = {} |
191 |
212 |
192 supportedExtensions = ( |
213 supportedExtensions = DocumentationTools.supportedExtensionsDictForApis[ |
193 DocumentationTools.supportedExtensionsDictForApis[progLanguage] |
214 progLanguage |
194 ) |
215 ] |
195 supportedExtensions.extend(extensions) |
216 supportedExtensions.extend(extensions) |
196 |
217 |
197 if not outputFileName.endswith(".api"): |
218 if not outputFileName.endswith(".api"): |
198 # append the .api extension, if not given by the user |
219 # append the .api extension, if not given by the user |
199 outputFileName += ".api" |
220 outputFileName += ".api" |
200 if "%L" in outputFileName: |
221 if "%L" in outputFileName: |
201 outputFile = outputFileName.replace("%L", progLanguage) |
222 outputFile = outputFileName.replace("%L", progLanguage) |
202 else: |
223 else: |
203 if len(progLanguages) == 1: |
224 if len(progLanguages) == 1: |
204 outputFile = outputFileName |
225 outputFile = outputFileName |
205 else: |
226 else: |
206 root, ext = os.path.splitext(outputFileName) |
227 root, ext = os.path.splitext(outputFileName) |
207 outputFile = "{0}-{1}{2}".format(root, progLanguage.lower(), |
228 outputFile = "{0}-{1}{2}".format(root, progLanguage.lower(), ext) |
208 ext) |
229 basesFile = os.path.splitext(outputFile)[0] + ".bas" |
209 basesFile = os.path.splitext(outputFile)[0] + '.bas' |
230 |
210 |
|
211 for arg in args: |
231 for arg in args: |
212 if os.path.isdir(arg): |
232 if os.path.isdir(arg): |
213 if os.path.exists(os.path.join( |
233 if os.path.exists( |
214 arg, Utilities.joinext("__init__", ".py"))): |
234 os.path.join(arg, Utilities.joinext("__init__", ".py")) |
|
235 ): |
215 basename = os.path.dirname(arg) |
236 basename = os.path.dirname(arg) |
216 if arg == '.': |
237 if arg == ".": |
217 sys.stderr.write("The directory '.' is a package.\n") |
238 sys.stderr.write("The directory '.' is a package.\n") |
218 sys.stderr.write( |
239 sys.stderr.write( |
219 "Please repeat the call giving its real name.\n") |
240 "Please repeat the call giving its real name.\n" |
|
241 ) |
220 sys.stderr.write("Ignoring the directory.\n") |
242 sys.stderr.write("Ignoring the directory.\n") |
221 continue |
243 continue |
222 else: |
244 else: |
223 basename = arg |
245 basename = arg |
224 if basename: |
246 if basename: |
225 basename = "{0}{1}".format(basename, os.sep) |
247 basename = "{0}{1}".format(basename, os.sep) |
226 |
248 |
227 if recursive and not os.path.islink(arg): |
249 if recursive and not os.path.islink(arg): |
228 names = [arg] + Utilities.getDirs(arg, excludeDirs) |
250 names = [arg] + Utilities.getDirs(arg, excludeDirs) |
229 else: |
251 else: |
230 names = [arg] |
252 names = [arg] |
231 else: |
253 else: |
232 basename = "" |
254 basename = "" |
233 names = [arg] |
255 names = [arg] |
234 |
256 |
235 for filename in sorted(names): |
257 for filename in sorted(names): |
236 inpackage = False |
258 inpackage = False |
237 if os.path.isdir(filename): |
259 if os.path.isdir(filename): |
238 files = [] |
260 files = [] |
239 for ext in supportedExtensions: |
261 for ext in supportedExtensions: |
240 files.extend(glob.glob(os.path.join( |
262 files.extend( |
241 filename, Utilities.joinext("*", ext)))) |
263 glob.glob( |
|
264 os.path.join(filename, Utilities.joinext("*", ext)) |
|
265 ) |
|
266 ) |
242 initFile = os.path.join( |
267 initFile = os.path.join( |
243 filename, Utilities.joinext("__init__", ext)) |
268 filename, Utilities.joinext("__init__", ext) |
|
269 ) |
244 if initFile in files: |
270 if initFile in files: |
245 inpackage = True |
271 inpackage = True |
246 files.remove(initFile) |
272 files.remove(initFile) |
247 files.insert(0, initFile) |
273 files.insert(0, initFile) |
248 elif progLanguage != "Python3": |
274 elif progLanguage != "Python3": |
249 # assume package |
275 # assume package |
250 inpackage = True |
276 inpackage = True |
251 else: |
277 else: |
252 if ( |
278 if Utilities.isWindowsPlatform() and glob.has_magic(filename): |
253 Utilities.isWindowsPlatform() and |
|
254 glob.has_magic(filename) |
|
255 ): |
|
256 files = glob.glob(filename) |
279 files = glob.glob(filename) |
257 else: |
280 else: |
258 files = [filename] |
281 files = [filename] |
259 |
282 |
260 for file in files: |
283 for file in files: |
261 skipIt = False |
284 skipIt = False |
262 for pattern in excludePatterns: |
285 for pattern in excludePatterns: |
263 if fnmatch.fnmatch(os.path.basename(file), pattern): |
286 if fnmatch.fnmatch(os.path.basename(file), pattern): |
264 skipIt = True |
287 skipIt = True |
265 break |
288 break |
266 if skipIt: |
289 if skipIt: |
267 continue |
290 continue |
268 |
291 |
269 try: |
292 try: |
270 module = Utilities.ModuleParser.readModule( |
293 module = Utilities.ModuleParser.readModule( |
271 file, |
294 file, |
272 basename=basename, inpackage=inpackage, |
295 basename=basename, |
273 ignoreBuiltinModules=ignoreBuiltinModules) |
296 inpackage=inpackage, |
|
297 ignoreBuiltinModules=ignoreBuiltinModules, |
|
298 ) |
274 apiGenerator = APIGenerator(module) |
299 apiGenerator = APIGenerator(module) |
275 api = apiGenerator.genAPI(True, basePackage, |
300 api = apiGenerator.genAPI(True, basePackage, includePrivate) |
276 includePrivate) |
|
277 bases = apiGenerator.genBases(includePrivate) |
301 bases = apiGenerator.genBases(includePrivate) |
278 except OSError as v: |
302 except OSError as v: |
279 sys.stderr.write("{0} error: {1}\n".format(file, v[1])) |
303 sys.stderr.write("{0} error: {1}\n".format(file, v[1])) |
280 continue |
304 continue |
281 except ImportError as v: |
305 except ImportError as v: |
282 sys.stderr.write("{0} error: {1}\n".format(file, v)) |
306 sys.stderr.write("{0} error: {1}\n".format(file, v)) |
283 continue |
307 continue |
284 |
308 |
285 for apiEntry in api: |
309 for apiEntry in api: |
286 if apiEntry not in apis: |
310 if apiEntry not in apis: |
287 apis.append(apiEntry) |
311 apis.append(apiEntry) |
288 for basesEntry in bases: |
312 for basesEntry in bases: |
289 if bases[basesEntry]: |
313 if bases[basesEntry]: |
290 basesDict[basesEntry] = bases[basesEntry][:] |
314 basesDict[basesEntry] = bases[basesEntry][:] |
291 sys.stdout.write("-- {0} -- {1} ok\n".format( |
315 sys.stdout.write("-- {0} -- {1} ok\n".format(progLanguage, file)) |
292 progLanguage, file)) |
|
293 |
316 |
294 outdir = os.path.dirname(outputFile) |
317 outdir = os.path.dirname(outputFile) |
295 if outdir and not os.path.exists(outdir): |
318 if outdir and not os.path.exists(outdir): |
296 os.makedirs(outdir) |
319 os.makedirs(outdir) |
297 try: |
320 try: |
298 with open(outputFile, "w", encoding="utf-8", |
321 with open(outputFile, "w", encoding="utf-8", newline=newline) as out: |
299 newline=newline) as out: |
|
300 out.write("\n".join(sorted(apis)) + "\n") |
322 out.write("\n".join(sorted(apis)) + "\n") |
301 except OSError as v: |
323 except OSError as v: |
302 sys.stderr.write("{0} error: {1}\n".format(outputFile, v[1])) |
324 sys.stderr.write("{0} error: {1}\n".format(outputFile, v[1])) |
303 sys.exit(3) |
325 sys.exit(3) |
304 try: |
326 try: |
305 with open(basesFile, "w", encoding="utf-8", |
327 with open(basesFile, "w", encoding="utf-8", newline=newline) as out: |
306 newline=newline) as out: |
|
307 for baseEntry in sorted(basesDict.keys()): |
328 for baseEntry in sorted(basesDict.keys()): |
308 out.write("{0} {1}\n".format( |
329 out.write( |
309 baseEntry, " ".join(sorted(basesDict[baseEntry])))) |
330 "{0} {1}\n".format( |
|
331 baseEntry, " ".join(sorted(basesDict[baseEntry])) |
|
332 ) |
|
333 ) |
310 except OSError as v: |
334 except OSError as v: |
311 sys.stderr.write("{0} error: {1}\n".format(basesFile, v[1])) |
335 sys.stderr.write("{0} error: {1}\n".format(basesFile, v[1])) |
312 sys.exit(3) |
336 sys.exit(3) |
313 |
337 |
314 sys.stdout.write('\nDone.\n') |
338 sys.stdout.write("\nDone.\n") |
315 sys.exit(0) |
339 sys.exit(0) |
316 |
340 |
317 if __name__ == '__main__': |
341 |
|
342 if __name__ == "__main__": |
318 main() |
343 main() |
319 |
344 |
320 # |
345 # |
321 # eflag: noqa = M801 |
346 # eflag: noqa = M801 |