from __future__ import print_function
import os
import os.path
import sys
from optparse import OptionParser, OptionGroup
index = 0
def harvest_constants(options, path, constants):
global index
try:
inputfile = open(path, "r")
except Exception as e:
print("File {path} could not be opened: {e}"
.format(path=path, e=e))
return 1, 0
try:
lines = inputfile.readlines()
except Exception as e:
print("Error reading file {path}: {e}"
.format(path=path, e=e))
inputfile.close()
return 1, 0
inputfile.close()
firstline = True
preamble = " \""
linesize = 53
for n in range(len(lines)):
line = lines[n]
myline = line.strip()
if "/*" in myline or "*/" in myline or myline.startswith("*"):
continue
if myline.startswith("#define"):
value = myline[8:]
if value.startswith("PMIx"):
continue
if value.startswith("PMIX_HAVE_VISIB"):
continue
if value.startswith("PMIX_LAUNCHER_RNDZ_FILE"):
continue
if value.startswith("PMIX_LAUNCHER_RNDZ_URI"):
continue
if value.startswith("PMIX_KEEPALIVE_PIPE"):
continue
tokens = value.split()
if len(tokens) >= 2:
if tokens[1][0] == '"':
if not firstline:
constants.write(",\n\n")
firstline = False
constants.write(" {.index = " + str(index) + ", .name = \"" + tokens[0] + "\", .string = " + tokens[1])
index = index + 1
if tokens[0] == "PMIX_EVENT_BASE":
dstart = 3
datatype = "PMIX_POINTER"
elif tokens[0] == "PMIX_ATTR_UNDEF":
constants.write(", .type = PMIX_POINTER,\n .description = (char *[]){\"NONE\", NULL}}")
continue
else:
dstart = 4
if tokens[3] == "(bool)":
datatype = "PMIX_BOOL"
elif tokens[3] == "(char*)":
datatype = "PMIX_STRING"
elif tokens[3] == "(pmix_rank_t)":
datatype = "PMIX_PROC_RANK"
elif tokens[3] == "(uint32_t)":
datatype = "PMIX_UINT32"
elif tokens[3] == "(int32_t)":
datatype = "PMIX_INT32"
elif tokens[3] == "(uint64_t)":
datatype = "PMIX_UINT64"
elif tokens[3] == "(int)":
datatype = "PMIX_INT"
elif tokens[3] == "(uint16_t)":
datatype = "PMIX_UINT16"
elif tokens[3] == "(pmix_data_array_t)" or tokens[3] == "(pmix_data_array_t*)":
datatype = "PMIX_DATA_ARRAY"
elif tokens[3] == "(pmix_proc_t*)":
datatype = "PMIX_PROC"
elif tokens[3] == "(pmix_coord_t*)":
datatype = "PMIX_COORD"
elif tokens[3] == "(pmix_coord_view_t)":
datatype = "PMIX_UINT8"
elif tokens[3] == "(float)":
datatype = "PMIX_FLOAT"
elif tokens[3] == "(pmix_byte_object_t)":
datatype = "PMIX_BYTE_OBJECT"
elif tokens[3] == "(hwloc_topology_t)":
datatype = "PMIX_POINTER"
elif tokens[3] == "(size_t)":
datatype = "PMIX_SIZE"
elif tokens[3] == "(pmix_data_range_t)":
datatype = "PMIX_UINT8"
elif tokens[3] == "(pmix_persistence_t)":
datatype = "PMIX_UINT8"
elif tokens[3] == "(pmix_scope_t)":
datatype = "PMIX_UINT8"
elif tokens[3] == "(pmix_status_t)":
datatype = "PMIX_STATUS"
elif tokens[3] == "(void*)":
datatype = "PMIX_POINTER"
elif tokens[3] == "(TBD)":
datatype = "TBD"
elif tokens[3] == "(time_t)":
datatype = "PMIX_TIME"
elif tokens[3] == "(struct" and tokens[4] == "timeval)":
datatype = "PMIX_TIMEVAL"
dstart = 5
elif tokens[3] == "(pmix_envar_t*)":
datatype = "PMIX_ENVAR"
elif tokens[3] == "(pid_t)":
datatype = "PMIX_PID"
elif tokens[3] == "(pmix_proc_state_t)":
datatype = "PMIX_PROC_STATE"
elif tokens[3] == "(pmix_link_state_t)":
datatype = "PMIX_LINK_STATE"
elif tokens[3] == "(pointer)":
datatype = "PMIX_POINTER"
elif tokens[3] == "(pmix_topology_t)" or tokens[3] == "(pmix_topology_t*)":
datatype = "PMIX_TOPO"
elif tokens[3] == "(pmix_cpuset_t)" or tokens[3] == "(pmix_cpuset_t*)":
datatype = "PMIX_PROC_CPUSET"
elif tokens[3] == "(pmix_geometry_t)" or tokens[3] == "(pmix_geometry_t*)":
datatype = "PMIX_GEOMETRY"
elif tokens[3] == "(pmix_device_distance_t)" or tokens[3] == "(pmix_device_distance_t*)":
datatype = "PMIX_DEVICE_DIST"
elif tokens[3] == "(pmix_endpoint_t)" or tokens[3] == "(pmix_endpoint_t*)":
datatype = "PMIX_ENDPOINT"
elif tokens[3] == "(pmix_device_type_t)":
datatype = "PMIX_DEVTYPE"
elif tokens[3] == "(varies)":
datatype = "PMIX_INT"
elif tokens[3] == "(pmix_storage_accessibility_t)":
datatype = "PMIX_UINT64"
elif tokens[3] == "(pmix_storage_medium_t)":
datatype = "PMIX_UINT64"
elif tokens[3] == "(pmix_storage_persistence_t)":
datatype = "PMIX_UINT64"
elif tokens[3] == "(pmix_storage_access_type_t)":
datatype = "PMIX_UINT16"
elif tokens[3] == "(double)":
datatype = "PMIX_DOUBLE"
else:
print("UNKNOWN TOKEN: {tok}".format(tok=tokens[3]))
return 1
constants.write(", .type = " + datatype + ",\n .description = (char *[]){\"")
m = dstart + 1
desc = tokens[dstart].replace("\"", "\\\"")
if "DEPRECATED" in desc:
constants.write(desc + "\"")
constants.write(", NULL}}")
continue
firstout = True
while m < len(tokens):
tmp = tokens[m].replace("\"", "\\\"")
if (len(tmp) + len(desc) + 1) > linesize:
if firstout:
constants.write(desc + "\"")
else:
constants.write(",\n" + preamble + desc + "\"")
firstout = False
desc = tmp
else:
desc += " " + tmp
m += 1
line = lines[n+1]
myline = line.strip()
while len(myline) > 0 and myline[0] == '/':
m = 1
while myline[m] == '/' or myline[m] == ' ':
m += 1
k = m
tmp = myline[k]
if tmp == '"':
tmp = "\\\""
k += 1
while k < len(myline):
while k < len(myline) and ' ' != myline[k]:
if myline[k] == '"':
tmp += "\\\""
else:
tmp += myline[k]
k += 1
if (len(tmp) + len(desc) + 1) > linesize:
if firstout:
constants.write(desc + "\"")
else:
constants.write(",\n" + preamble + desc + "\"")
firstout = False
desc = tmp
else:
if len(desc) > 0:
desc += " " + tmp
else:
desc = tmp
tmp = ""
k += 1
n += 1
line = lines[n+1]
myline = line.strip()
if len(desc) > 0:
if firstout:
constants.write(desc + "\"")
else:
constants.write(",\n" + preamble + desc + "\"")
constants.write(", NULL}}")
inputfile.close()
return 0
def _write_header(options, base_path, num_elements):
contents = '''/*
* This file is autogenerated by construct_dictionary.py.
* Do not edit this file by hand.
*/
#include "src/include/pmix_config.h"
#include "src/include/pmix_globals.h"
#include "include/pmix_common.h"
#ifndef PMIX_DICTIONARY_H
#define PMIX_DICTIONARY_H
BEGIN_C_DECLS
PMIX_EXPORT extern const pmix_regattr_input_t pmix_dictionary[{ne}];
#define PMIX_INDEX_BOUNDARY {ne}
END_C_DECLS
#endif\n
'''.format(ne=num_elements)
if options.dryrun:
constants = sys.stdout
outpath = None
else:
outpath = os.path.join(base_path, "pmix_dictionary.h")
try:
constants = open(outpath, "w+")
except Exception as e:
print("{outpath} CANNOT BE OPENED - DICTIONARY COULD NOT BE CONSTRUCTED: {e}"
.format(outpath=outpath, e=e))
return 1
constants.write(contents)
constants.close()
return 0
def main():
parser = OptionParser("usage: %prog [options]")
debugGroup = OptionGroup(parser, "Debug Options")
debugGroup.add_option("--dryrun",
action="store_true", dest="dryrun", default=False,
help="Show output to screen")
parser.add_option_group(debugGroup)
(options, args) = parser.parse_args()
top_src_dir = os.path.dirname(sys.argv[0])
top_src_dir = os.path.join(top_src_dir, "..")
top_src_dir = os.path.abspath(top_src_dir)
checkfile = os.path.join(top_src_dir, "VERSION")
if not os.path.exists(checkfile):
print("ERROR: Could not find top source directory for Open PMIx")
return 1
source_include_dir = os.path.join(top_src_dir, "include")
build_src_include_dir = os.getcwd()
checkfile = os.path.join(build_src_include_dir, "pmix_config.h")
if not os.path.exists(checkfile):
print("ERROR: Could not find build directory for Open PMIx")
return 1
if options.dryrun:
constants = sys.stdout
outpath = None
else:
outpath = os.path.join(build_src_include_dir, "pmix_dictionary.c")
try:
constants = open(outpath, "w+")
except Exception as e:
print("{outpath} CANNOT BE OPENED - DICTIONARY COULD NOT BE CONSTRUCTED: {e}"
.format(outpath=outpath, e=e))
return 1
constants.write("""/*
* This file is autogenerated by construct_dictionary.py.
* Do not edit this file by hand.
*/
#include "src/include/pmix_dictionary.h"
const pmix_regattr_input_t pmix_dictionary[] = {
""")
rc = harvest_constants(options,
os.path.join(source_include_dir, "pmix_common.h.in"),
constants)
if 0 != rc:
constants.close()
if outpath:
os.remove(outpath)
print("HARVEST PMIX_COMMON FAILED - DICTIONARY COULD NOT BE CONSTRUCTED")
return 1
constants.write(",\n")
rc = harvest_constants(options,
os.path.join(source_include_dir, "pmix_deprecated.h"),
constants)
if 0 != rc:
constants.close()
if outpath:
os.remove(outpath)
print("HARVEST PMIX_DEPRECATED FAILED - DICTIONARY COULD NOT BE CONSTRUCTED")
return 1
constants.write("""\n};""")
constants.write("\n")
constants.close()
return _write_header(options, build_src_include_dir, index)
if __name__ == '__main__':
exit(main())