amalgamate.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from __future__ import print_function
  2. import re
  3. import argparse
  4. import os.path
  5. import io
  6. parser = argparse.ArgumentParser()
  7. parser.add_argument('version', help='version to include')
  8. parser.add_argument('outfile', help='outfile w/o extension')
  9. parser.add_argument('inputs', nargs='*', action='store', help='input filenames')
  10. args = parser.parse_args()
  11. outname = args.outfile.split("/")[-1]
  12. pos = outname.find(".")
  13. if pos > 0:
  14. outname = outname[:pos]
  15. include_re = re.compile("^#include ([\"<].*[\">]).*$")
  16. guard_re = re.compile("^#(?:(?:ifndef|define) [A-Z_]+_H_|endif /\* [A-Z_]+_H_ \*/)")
  17. includes = []
  18. is_c = False
  19. print ("Starting amalgamating file "+ args.outfile)
  20. for fname in args.inputs:
  21. if("util.h" in fname):
  22. is_c = True
  23. continue
  24. with io.open(fname, encoding="utf8") as infile:
  25. print ("Integrating file '" + fname + "'...", end=""),
  26. for line in infile:
  27. res = include_re.match(line)
  28. if res:
  29. inc = res.group(1)
  30. if not inc in includes and not inc[0] == '"':
  31. includes.append(inc)
  32. print ("done."),
  33. file = io.open(args.outfile, 'w')
  34. file.write(u'''/* THIS IS A SINGLE-FILE DISTRIBUTION CONCATENATED FROM THE OPEN62541 SOURCES
  35. * visit http://open62541.org/ for information about this software
  36. * Git-Revision: %s
  37. */
  38. /*
  39. * Copyright (C) 2015 the contributors as stated in the AUTHORS file
  40. *
  41. * This file is part of open62541. open62541 is free software: you can
  42. * redistribute it and/or modify it under the terms of the GNU Lesser General
  43. * Public License, version 3 (as published by the Free Software Foundation) with
  44. * a static linking exception as stated in the LICENSE file provided with
  45. * open62541.
  46. *
  47. * open62541 is distributed in the hope that it will be useful, but WITHOUT ANY
  48. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  49. * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  50. * details.
  51. */\n\n''' % args.version)
  52. if not is_c:
  53. file.write(u'''#ifndef %s
  54. #define %s
  55. #ifdef __cplusplus
  56. extern "C" {
  57. #endif\n\n''' % (outname.upper() + u"_H_", outname.upper() + u"_H_") )
  58. if not is_c:
  59. for inc in includes:
  60. file.write(u"#include " + inc + "\n")
  61. else:
  62. file.write(u"#define UA_AMALGAMATE\n")
  63. file.write(u'''#ifndef UA_DYNAMIC_LINKING
  64. # define UA_DYNAMIC_LINKING
  65. #endif\n\n''')
  66. for fname in args.inputs:
  67. if "ua_config.h" in fname or "ua_util.h" in fname:
  68. with io.open(fname, encoding="utf8") as infile:
  69. print ("Integrating file '" + fname + "'...", end=""),
  70. for line in infile:
  71. file.write(line)
  72. print ("done."),
  73. file.write(u"#include \"" + outname + ".h\"\n")
  74. for fname in args.inputs:
  75. if not "util.h" in fname:
  76. with io.open(fname, encoding="utf8") as infile:
  77. file.write(u"/*********************************** amalgamated original file \"" + fname + u"\" ***********************************/\n")
  78. print ("Integrating file '" + fname + "'...", end=""),
  79. for line in infile:
  80. inc_res = include_re.match(line)
  81. guard_res = guard_re.match(line)
  82. if not inc_res and not guard_res:
  83. file.write(line)
  84. print ("done."),
  85. if not is_c:
  86. file.write(u'''
  87. #ifdef __cplusplus
  88. } // extern "C"
  89. #endif
  90. #endif /* %s */''' % (outname.upper() + u"_H_"))
  91. file.close()
  92. print ("The size of "+args.outfile+" is "+ str(os.path.getsize(args.outfile))+" Bytes.")