flatten_gsl.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. #!/usr/bin/python
  2. #
  3. # djmw 20080323, 20120511, 20120515, 20120809
  4. #
  5. # Makes the directory structure of gsl flat by renaming all files and references by #include
  6. # E.g. the file 'd/a.c' will be renamed as: gsl_d__a.c
  7. # djmw 20100223 New makefile layout
  8. #
  9. import os, sys, glob, re, time, shutil
  10. version = '1.10'
  11. date = time.strftime('%Y%m%d')
  12. gslconfigh = 'gsl__config.h'
  13. fromdir = '/home/david/praat/gsl/gsl-' + version + '/'
  14. todir = '/home/david/praat/gsl/GSL-' + version + '/'
  15. log = open (todir + 'flatten_gsl' + version + '.log', 'w')
  16. gslconfigh = 'gsl__config.h'
  17. print >> log, date
  18. dirs = ['blas', 'block', 'bspline', 'cblas', 'cdf', 'combination', 'complex', 'const',
  19. 'deriv', 'dht', 'diff', 'doc', 'eigen', 'err', 'fft', 'fit', 'gsl', 'histogram', 'ieee-utils',
  20. 'integration', 'linalg', 'matrix', 'min', 'monte', 'multifit', 'multimin',
  21. 'multiroots', 'ntuple', 'ode-initval', 'permutation', 'poly', 'qrng', 'randist', 'rng', 'roots',
  22. 'siman', 'sort', 'specfunc', 'statistics', 'sum', 'sys', 'vector', 'wavelet']
  23. # left out: utils test
  24. itype = 0
  25. imake = 1
  26. idist = 2
  27. iname = 3
  28. icount = 4
  29. ihrep = 5
  30. # per file: [type inmakefile indist renamed_as ntimesincluded headerreplacement]
  31. # type = c h
  32. def write_to_file (todir, basename, multilinetext):
  33. f = open (todir + basename, 'w')
  34. f.write (multilinetext)
  35. f.close()
  36. def dict_from_list (dict, dir, list, type = 'c', inmake = 'y', indist = 'y'):
  37. for item in list:
  38. newname = 'gsl_' + dir + '__' + item
  39. if dir == 'gsl':
  40. newname = item
  41. dict[dir + '/' + item] = [type, inmake, indist, newname, 0 , '']
  42. def get_all_files (dirs):
  43. files = {'./config.h': ['h', 'n', 'y', gslconfigh, 0, ''], \
  44. './templates_on.h':['h', 'n', 'y', 'templates_on.h', 0, ''], \
  45. './templates_off.h':['h', 'n', 'y', 'templates_off.h', 0, '']}
  46. for dir in dirs:
  47. os.chdir (fromdir + dir)
  48. dict_from_list (files, dir, glob.glob('*.c'), 'c', 'y')
  49. dict_from_list (files, dir, glob.glob('*.h'), 'h', 'n')
  50. return files
  51. def quoted_include_get_newname (dict, key):
  52. if dict.has_key(key):
  53. dict[key][imake] = 'n'
  54. if dict[key][ihrep]:
  55. newname = dict[key][ihrep]
  56. dict['gsl/' + newname][icount] += 1
  57. print >> log, 'Corrected an include header error ' + key + ' ' + newname
  58. else:
  59. newname = dict[key][iname]
  60. dict[key][icount] += 1
  61. return '"' + newname + '"'
  62. return None
  63. # #include .....
  64. # rewrite <gsl/file.h> to "file.h"
  65. # <file.h> -> <file.h>
  66. # "file.(c|h)" -> "gsl_dir__file.(c|h)"
  67. def process_files (dict):
  68. include = re.compile (r'^(\s*\#\s*include\s+)([^\s]+)') # 2 groups
  69. delim = re.compile (r'(<|")\s*([^\s]+)\s*(>|")')
  70. for key, val in dict.items():
  71. (dir, base) = os.path.split (key)
  72. if dir == '.': # config.h will be/was done by hand, don't overwrite
  73. continue
  74. file_in_name = fromdir + key
  75. file_in = open (file_in_name, 'r')
  76. file_out_name = val[iname]
  77. output_lines = ''
  78. for line in file_in:
  79. minclude = include.search (line)
  80. if minclude:
  81. headerfile = minclude.group(2)
  82. mheader = delim.search (headerfile)
  83. header = mheader.group(2)
  84. if mheader.group(1) == '<':
  85. if header[0:4] == 'gsl/':
  86. newname = '"' + header[4:] +'"'
  87. dict[header][icount] += 1
  88. elif header == 'config.h':
  89. newname = '"' + gslconfigh + '"'
  90. dict['./'+header][icount] += 1
  91. else:
  92. newname = '<' + header + '>'
  93. else:
  94. newkey = dir + '/' + header
  95. newname = quoted_include_get_newname (dict, newkey)
  96. if not newname:
  97. newkey = './' + header
  98. newname = quoted_include_get_newname (dict, newkey)
  99. if not newname:
  100. newname = header
  101. print >> log, 'File does not exist: '+ header + ' From: ' + key
  102. output_lines += minclude.group(1) + newname + '\n'
  103. else:
  104. output_lines += line
  105. if val[idist] == 'y':
  106. write_to_file (todir, file_out_name, output_lines)
  107. else:
  108. dict[key][imake] = 'n'
  109. return dict
  110. def gen_make_objects (dict, suffix, endofline):
  111. make_objects = ''
  112. (i , imax) = (0, 3)
  113. keysd = dict.keys()
  114. keysd.sort()
  115. for key in keysd:
  116. val = dict[key]
  117. if val[imake] == 'n':
  118. continue
  119. i += 1
  120. post = ' '
  121. if i%imax == 0: post = endofline
  122. (root, ext) = os.path.splitext (val[iname])
  123. make_objects += root + suffix + post
  124. return make_objects
  125. def gen_sconscript(dict):
  126. make_objects = gen_make_objects (dict, '.c', ' \n ')
  127. sconscript = '''# SConscript for library gsl. This file was generated by the program flatten_gsl.py
  128. # djmw ''' + date + '''
  129. sources = Split(""" ''' + make_objects + '''""")
  130. Import ('env')
  131. env.Library ('GSL', sources)
  132. # End of SConscript
  133. '''
  134. write_to_file (todir, 'SConscript', sconscript)
  135. def gen_makefile (dict):
  136. make_objects = gen_make_objects (dict, '.o', ' \\\n ')
  137. makefile = """# Makefile for library gsl. This file was generated by the program flatten_gsl.py
  138. # djmw """ + date + """
  139. include ../makefile.defs
  140. CPPFLAGS = -I ../sys -I ../dwsys
  141. OBJECTS = """ + make_objects + """
  142. .PHONY: all clean
  143. all: libgsl.a
  144. clean:
  145. $(RM) $(OBJECTS)
  146. $(RM) libgsl.a
  147. $(OBJECTS): *.h ../sys/*.h ../dwsys/*.h
  148. libgsl.a: $(OBJECTS)
  149. touch libgsl.a
  150. rm libgsl.a
  151. ar cq libgsl.a $(OBJECTS)
  152. $(RANLIB) libgsl.a
  153. # end of Makefile
  154. """
  155. write_to_file (todir, 'Makefile', makefile)
  156. def copy_file (fromdir, todir, file):
  157. text = open(fromdir + file).read()
  158. write_to_file (todir, file, text)
  159. def preprocessing (current_gsl_version):
  160. if not os.path.exists (todir + gslconfigh):
  161. if not os.path.exists (fromdir + 'config.h'):
  162. sys.exit(todir + gslconfigh + ' and ' + fromdir + "config.h don't exist. Please run configure first!!")
  163. else:
  164. text = open(fromdir + 'config.h').read()
  165. write_to_file (todir, gslconfigh, text)
  166. print >> log, '----------- gsl__config.h created ------------------'
  167. copy_file (fromdir,todir, 'templates_on.h')
  168. copy_file (fromdir,todir, 'templates_off.h')
  169. print >> log, """
  170. Post/Preprocesing
  171. The layout of config.h/gsl__config.h varies from one version of gsl to the other
  172. Do it by hand in """ + todir + """gsl__config.h:
  173. Replace the #define "haves" with
  174. #define HAVE_IEEEFP_H 0
  175. #if defined(linux)
  176. #define HAVE_DECL_EXPM1 1
  177. #else
  178. #define HAVE_DECL_EXPM1 0
  179. #endif
  180. #if defined(linux) || defined (_WIN32)
  181. #define HAVE_DECL_FINITE 1
  182. #else
  183. #define HAVE_DECL_FINITE 0
  184. #endif
  185. #if defined(linux)
  186. #define HAVE_DECL_HYPOT 1
  187. #else
  188. #define HAVE_DECL_HYPOT 0
  189. #endif
  190. #if defined(linux)
  191. #define HAVE_DECL_ISFINITE 0
  192. #else
  193. #define HAVE_DECL_ISFINITE 0
  194. #endif
  195. #if defined(linux)
  196. #define HAVE_DECL_LOG1P 1
  197. #else
  198. #define HAVE_DECL_LOG1P 0
  199. #endif
  200. #if defined(linux)
  201. #define HAVE_STRDUP 1
  202. #else
  203. #define HAVE_STRDUP 0
  204. #endif
  205. #if defined(linux)
  206. #define HAVE_STRTOL 1
  207. #else
  208. #define HAVE_STRTOL 0
  209. #endif
  210. #if defined(linux)
  211. #define HAVE_STRTOUL 1
  212. #else
  213. #define HAVE_STRTOUL 0
  214. #endif
  215. #if defined(linux)
  216. #define HAVE_DLFCN_H 1
  217. #else
  218. #define HAVE_DLFCN_H 0
  219. #endif
  220. #if defined(linux)
  221. #define HAVE_DECL_FEENABLEEXCEPT 1
  222. #else
  223. #define HAVE_DECL_FEENABLEEXCEPT 0
  224. #endif
  225. # 3.Inlines:
  226. #undef HAVE_INLINE
  227. #ifdef sgi
  228. #define inline
  229. #endif
  230. #if defined(linux) || defined (macintosh) || defined (_WIN32)
  231. #define HAVE_DECL_ISINF 1
  232. #else
  233. #define HAVE_DECL_ISINF 0
  234. #endif
  235. #if defined(linux) || defined (macintosh) || defined (_WIN32)
  236. #define HAVE_DECL_ISNAN 1
  237. #else
  238. #define HAVE_DECL_ISNAN 0
  239. #endif
  240. # 4.
  241. #if defined(linux)
  242. #define HAVE_GNUX86_IEEE_INTERFACE 1
  243. #endif
  244. #undef HAVE_GNUSPARC_IEEE_INTERFACE
  245. #undef HAVE_GNUM68K_IEEE_INTERFACE
  246. #undef HAVE_GNUPPC_IEEE_INTERFACE
  247. #undef HAVE_SUNOS4_IEEE_INTERFACE
  248. #undef HAVE_SOLARIS_IEEE_INTERFACE
  249. #undef HAVE_HPUX11_IEEE_INTERFACE
  250. #undef HAVE_HPUX_IEEE_INTERFACE
  251. #undef HAVE_TRU64_IEEE_INTERFACE
  252. #undef HAVE_IRIX_IEEE_INTERFACE
  253. #undef HAVE_AIX_IEEE_INTERFACE
  254. #undef HAVE_FREEBSD_IEEE_INTERFACE
  255. #undef HAVE_OS2EMX_IEEE_INTERFACE
  256. #undef HAVE_NETBSD_IEEE_INTERFACE
  257. #undef HAVE_OPENBSD_IEEE_INTERFACE
  258. #undef HAVE_DARWIN_IEEE_INTERFACE
  259. #undef HAVE_DARWIN86_IEEE_INTERFACE
  260. #define GSL_DISABLE_DEPRECATED 1
  261. #define USE_BLAS 0
  262. By hand: Corrected in the fromdir/specfun/coupling.c:
  263. #if ! defined (GSL_DISABLE_DEPRECATED)
  264. gsl_sf_coupling_6j_INCORRECT_e ....
  265. #endif
  266. #if ! defined (GSL_DISABLE_DEPRECATED)
  267. gsl_sf_coupling_6j_INCORRECT ....
  268. #endif
  269. """
  270. def post_processing (current_gsl_version):
  271. def correct_missing_prototypes (file, linenumber, prototype):
  272. f = open (file, 'r')
  273. lines = f.readlines ()
  274. lines.insert (linenumber, prototype + '\n')
  275. f.close ()
  276. f = open (file, 'w')
  277. f.writelines (lines)
  278. f.close ()
  279. print >> log, 'Inserted prototype in file '+ file
  280. print >> log, ' ' + prototype
  281. if current_gsl_version == '1.10':
  282. here = todir + '/'
  283. correct_missing_prototypes (here + 'gsl_matrix_complex_double.h', 235, \
  284. 'int gsl_matrix_complex_isnonneg (const gsl_matrix_complex * m);')
  285. correct_missing_prototypes (here + 'gsl_matrix_complex_float.h', 235, \
  286. 'int gsl_matrix_complex_float_isnonneg (const gsl_matrix_complex_float * m);')
  287. correct_missing_prototypes (here + 'gsl_matrix_complex_long_double.h', 235, \
  288. 'int gsl_matrix_complex_long_double_isnonneg (const gsl_matrix_complex_long_double * m);')
  289. correct_missing_prototypes (here + 'gsl_vector_complex_double.h', 181, \
  290. 'int gsl_vector_complex_isnonneg (const gsl_vector_complex * v);')
  291. correct_missing_prototypes (here + 'gsl_vector_complex_float.h', 181, \
  292. 'int gsl_vector_complex_float_isnonneg (const gsl_vector_complex_float * v);')
  293. correct_missing_prototypes (here + 'gsl_vector_complex_long_double.h', 181, \
  294. 'int gsl_vector_complex_long_double_isnonneg (const gsl_vector_complex_long_double * v);')
  295. def remove_double_header_files (dict):
  296. num = 0
  297. for key,val in dict.items():
  298. (dir, base) = os.path.split (key)
  299. if dir == 'gsl': continue
  300. newkey = 'gsl/' + base
  301. if dict.has_key (newkey):
  302. f = open (fromdir + key, 'r')
  303. lines1 = f.read()
  304. f.close ()
  305. f = open (fromdir + newkey, 'r')
  306. lines2 = f.read()
  307. f.close ()
  308. if lines1 == lines2:
  309. num += 1
  310. dict[key][idist] = 'n'
  311. dict[key][ihrep] = base
  312. print >> log, 'Also in gsl/: ' + key
  313. return num
  314. def exclude_test_files (dict):
  315. starts_with_test = re.compile (r'^test')
  316. for key in dict.keys ():
  317. (dir, base) = os.path.split (key)
  318. if starts_with_test.search (base):
  319. dict[key][idist] = 'n'
  320. dict['siman/siman_tsp.c'][idist] = 'n'
  321. def print_file_selection (dict, type = 'c', inmake = 'n', indist = 'y'):
  322. selection = {}
  323. for key, val in dict.items():
  324. if val[itype] == type and val[imake] == inmake and val[idist] == indist:
  325. selection[key] = val[icount]
  326. keyss = selection.keys()
  327. keyss.sort()
  328. for key in keyss:
  329. print >> log, '%3d %s' % (selection[key], key)
  330. return len (keyss)
  331. preprocessing (version)
  332. files = get_all_files (dirs)
  333. exclude_test_files (files)
  334. print >> log, 'The following header files already exist in the gsl/ directory:'
  335. ll = remove_double_header_files (files)
  336. print >> log, 'Number of files = %d' % ll
  337. print >> log, '\n\n process files'
  338. process_files (files)
  339. print >> log, '\n\n corect some header files:'
  340. post_processing (version)
  341. gen_sconscript (files)
  342. gen_makefile (files)
  343. print >> log, '\n\n header-files'
  344. ll = print_file_selection (files, type = 'h')
  345. print >> log, 'Number of files = %d' % ll
  346. print >> log, '\n\n c-files'
  347. ll = print_file_selection (files, type = 'c', inmake = 'y', indist = 'y')
  348. print >> log, 'Number of files = %d' % ll
  349. print >> log, '\n\n c-files included in other files'
  350. ll = print_file_selection (files, type = 'c', inmake = 'n', indist = 'y')
  351. print >> log, 'Number of files = %d' % ll
  352. print >> log, '\n\n unused header-files'
  353. ll = print_file_selection (files, type = 'h', indist = 'n')
  354. print >> log, 'Number of files = %d' % ll
  355. print >> log, '\n\n unused c-files'
  356. ll = print_file_selection (files, type = 'c', indist = 'n')
  357. print >> log, 'Number of files = %d' % ll
  358. #print str(files)