''' A script used to extract almost all constants from C header files (*.h). (c) 2007-2018 Jan ONDREJ (SAL) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ''' import re, sys, os reg_define = re.compile( r'^#define\s+(CL_)([A-Z0-9a-z_]+)\s+(.*?) *$' ) reg_enum_start = re.compile( r'^(typedef +)?enum +([a-z0-9_]*) *{*' ) reg_enum_end = re.compile( r'^} *[a-z0-9_]*;$' ) if len(sys.argv)>1 and sys.argv[1] not in ['', '-']: sys.stdout = open(sys.argv[1], 'wt') clamav_version = os.popen('clamav-config --version').read().strip() \ or 'UNKNOWN' def cprint(s): print(s.rstrip()) cprint("""\ # This file is automatically generated by getconst.py # on system with clamav-%s. """ % clamav_version) if len(sys.argv)>2: clamav_h = open(sys.argv[2], 'rt') cprint("# source: %s" % sys.argv[2]) else: clamav_h = open('/usr/include/clamav.h', 'rt') enum_block = 0 for line in clamav_h.readlines(): # handle comments and trailing new lines if '/*' in line: line, comment = line.strip().split('/*', 1) comment = ' # /*'+comment else: line = line.strip() comment = '' # enum block if enum_block==0 and reg_enum_start.search(line): cprint("") cprint("# enum block start: %s %s" % (line, comment)) enum_block += 1 enum_counter = -1 continue if enum_block>0 and reg_enum_end.search(line): cprint("# enum block end: %s %s" % (line, comment)) cprint("") enum_block = 0 continue if enum_block>0: if '=' in line: enum_counter = int(line.split('#')[0].split('=')[1].strip(' ,')) line = line.strip(' ,') enum_block += line.split('#',1)[0].count(',') cprint("%s %s" % (line, comment)) elif line.startswith("CL_"): enum_counter += 1 #line = "%s = %d" % (line.strip(' ,'), enum_counter) value = ' = %d' % enum_counter line2 = line.replace(',', value, 1) if line2==line: line3 = line.lstrip().replace(' ', value ,1) if line3==line: line = line+value else: line = line3 else: line = line2 enum_block += line.split('#',1)[0].count(',') cprint("%s %s" % (line, comment)) # search for #define line r = reg_define.search(line) if r: cprint("%s%s = %s" % r.groups()) # add section to remove CL_ prefix for all constants cprint(""" for key, value in list(globals().items()): if key.startswith("CL_") and (key[3:] not in globals()): exec("%s = %s" % (key[3:], key)) from ctypes import Structure, c_uint32 class OPTIONS(Structure): _fields_ = [ ("general", c_uint32), ("parse", c_uint32), ("heuristic", c_uint32), ("mail", c_uint32), ("dev", c_uint32) ] """)