| 
									
										
										
										
											2010-03-11 22:53:45 +00:00
										 |  |  | #! /usr/bin/env python3 | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  | """nm2def.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Helpers to extract symbols from Unix libs and auto-generate | 
					
						
							|  |  |  | Windows definition files from them. Depends on nm(1). Tested | 
					
						
							|  |  |  | on Linux and Solaris only (-p option to nm is for Solaris only). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By Marc-Andre Lemburg, Aug 1998. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Additional notes: the output of nm is supposed to look like this: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | acceler.o: | 
					
						
							|  |  |  | 000001fd T PyGrammar_AddAccelerators | 
					
						
							|  |  |  |          U PyGrammar_FindDFA | 
					
						
							|  |  |  | 00000237 T PyGrammar_RemoveAccelerators | 
					
						
							|  |  |  |          U _IO_stderr_ | 
					
						
							|  |  |  |          U exit | 
					
						
							|  |  |  |          U fprintf | 
					
						
							|  |  |  |          U free | 
					
						
							|  |  |  |          U malloc | 
					
						
							|  |  |  |          U printf | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | grammar1.o: | 
					
						
							|  |  |  | 00000000 T PyGrammar_FindDFA | 
					
						
							|  |  |  | 00000034 T PyGrammar_LabelRepr | 
					
						
							|  |  |  |          U _PyParser_TokenNames | 
					
						
							|  |  |  |          U abort | 
					
						
							|  |  |  |          U printf | 
					
						
							|  |  |  |          U sprintf | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Even if this isn't the default output of your nm, there is generally an | 
					
						
							|  |  |  | option to produce this format (since it is the original v7 Unix format). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2008-02-23 18:30:17 +00:00
										 |  |  | import os, sys | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-11 13:10:36 +02:00
										 |  |  | PYTHONLIB = 'libpython%d.%d.a' % sys.version_info[:2] | 
					
						
							|  |  |  | PC_PYTHONLIB = 'Python%d%d.dll' % sys.version_info[:2] | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  | NM = 'nm -p -g %s'                      # For Linux, use "nm -g %s" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def symbols(lib=PYTHONLIB,types=('T','C','D')): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 08:33:02 +02:00
										 |  |  |     with os.popen(NM % lib) as pipe: | 
					
						
							|  |  |  |         lines = pipe.readlines() | 
					
						
							| 
									
										
										
										
											2002-09-11 20:36:02 +00:00
										 |  |  |     lines = [s.strip() for s in lines] | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  |     symbols = {} | 
					
						
							|  |  |  |     for line in lines: | 
					
						
							| 
									
										
										
										
											1998-09-14 15:57:09 +00:00
										 |  |  |         if len(line) == 0 or ':' in line: | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2002-09-11 20:36:02 +00:00
										 |  |  |         items = line.split() | 
					
						
							| 
									
										
										
										
											1998-09-14 15:57:09 +00:00
										 |  |  |         if len(items) != 3: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         address, type, name = items | 
					
						
							|  |  |  |         if type not in types: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         symbols[name] = address,type | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  |     return symbols | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def export_list(symbols): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     data = [] | 
					
						
							|  |  |  |     code = [] | 
					
						
							|  |  |  |     for name,(addr,type) in symbols.items(): | 
					
						
							| 
									
										
										
										
											1998-09-14 15:57:09 +00:00
										 |  |  |         if type in ('C','D'): | 
					
						
							|  |  |  |             data.append('\t'+name) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             code.append('\t'+name) | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  |     data.sort() | 
					
						
							|  |  |  |     data.append('') | 
					
						
							|  |  |  |     code.sort() | 
					
						
							| 
									
										
										
										
											2002-09-11 20:36:02 +00:00
										 |  |  |     return ' DATA\n'.join(data)+'\n'+'\n'.join(code) | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Definition file template | 
					
						
							|  |  |  | DEF_TEMPLATE = """\
 | 
					
						
							|  |  |  | EXPORTS | 
					
						
							|  |  |  | %s | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Special symbols that have to be included even though they don't | 
					
						
							|  |  |  | # pass the filter | 
					
						
							|  |  |  | SPECIALS = ( | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def filter_Python(symbols,specials=SPECIALS): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-16 15:23:30 +00:00
										 |  |  |     for name in list(symbols.keys()): | 
					
						
							| 
									
										
										
										
											1998-09-14 15:57:09 +00:00
										 |  |  |         if name[:2] == 'Py' or name[:3] == '_Py': | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         elif name not in specials: | 
					
						
							|  |  |  |             del symbols[name] | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def main(): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s = symbols(PYTHONLIB) | 
					
						
							|  |  |  |     filter_Python(s) | 
					
						
							|  |  |  |     exports = export_list(s) | 
					
						
							|  |  |  |     f = sys.stdout # open('PC/python_nt.def','w') | 
					
						
							|  |  |  |     f.write(DEF_TEMPLATE % (exports)) | 
					
						
							| 
									
										
										
										
											2019-03-30 08:33:02 +02:00
										 |  |  |     # f.close() | 
					
						
							| 
									
										
										
										
											2001-01-17 08:48:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-08-10 13:12:22 +00:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     main() |