#######################################################################
#   This file is part of FLINT.
#
#   FLINT 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.
#
#   FLINT is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with FLINT; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

###############################################################################
#
# Script for generating profiling information tables for C modules being
# profiled by profiler-main.c.
#
# It takes one command-line parameter: the name of the module, e.g. "xyz".
# It reads through xyz-profile.c, pulls out function names having certain
# initial substrings, and builds a file xyz-profile-tables.c which should
# be linked against xyz-profile.c and profiler-main.c.
#
# See the makefile for typical usage. See also profiler-main.c.
#
# (C) 2007 William Hart and David Harvey
#
###############################################################################


import sys
import re


if len(sys.argv) != 2:
   raise ValueError, "no file specified"
   
module = sys.argv[1]


############ process input file

cfilename = module + "-profile.c"
cfile = open(cfilename)

profDriver_re = re.compile("void profDriver_(.*)\(.*")
profDriverString_re = re.compile("char\* profDriverString_(.*)\(.*")
profDriverDefaultParams_re = re.compile("char\* profDriverDefaultParams_(.*)\(.*")

prof_re = [profDriver_re, profDriverString_re, profDriverDefaultParams_re]

# dictionary from profile name to a tuple of bools, indicating which
# functions are defined for each target
prof_data = {}

for line in cfile:
   for i in range(len(prof_re)):
      m = prof_re[i].match(line)
      if m is not None:
         name = m.group(1)
         if name not in prof_data:
            prof_data[name] = [False] * len(prof_re)
         else:
            if prof_data[name][i]:
               raise ValueError, "duplicate target \"%s\"" % name
         prof_data[name][i] = True


############ generate output file

tfilename = module + "-profile-tables.c"
tfile = open(tfilename, "w")

tfile.write(
   "/* ===================================================================\n"
   "\n"
   "   " + tfilename + "\n"
   "\n"
   "   This file was AUTOMATICALLY GENERATED by make-profile-tables.py.\n"
   "   DO NOT EDIT IT -- your changes will go the way of all LOST SOCKS.\n"
   "\n"
   "=================================================================== */\n"
   "\n"
)

tfile.write("#include <stdlib.h>\n")
tfile.write("#include \"profiler-main.h\"\n")
tfile.write("\n")

tfile.write("char* prof_module_name = \"" + module + "\";\n\n")

tfile.write("int prof_target_count = %s;\n\n" % len(prof_data))

for (name, flags) in prof_data.iteritems():
   if flags[0]:
      tfile.write("extern void profDriver_%s(char* params);\n" % name)
   if flags[1]:
      tfile.write("extern char* profDriverString_%s(char* params);\n" % name)
   if flags[2]:
      tfile.write("extern char* profDriverDefaultParams_%s();\n" % name)
tfile.write("\n")

tfile.write("char* prof_target_name[] = {\n")
for (name, flags) in prof_data.iteritems():
   tfile.write("   \"%s\",\n" % name)
tfile.write("};\n\n")


tfile.write("prof_Driver_t prof_Driver_list[] = {\n")
for (name, flags) in prof_data.iteritems():
   if flags[0]:
      tfile.write("   profDriver_%s,\n" % name)
   else:
      tfile.write("   NULL,\n")
tfile.write("};\n\n")


tfile.write("prof_DriverString_t prof_DriverString_list[] = {\n")
for (name, flags) in prof_data.iteritems():
   if flags[1]:
      tfile.write("   profDriverString_%s,\n" % name)
   else:
      tfile.write("   NULL,\n")
tfile.write("};\n\n")


tfile.write("prof_DriverDefaultParams_t prof_DriverDefaultParams_list[] = {\n")
for (name, flags) in prof_data.iteritems():
   if flags[2]:
      tfile.write("   profDriverDefaultParams_%s,\n" % name)
   else:
      tfile.write("   NULL,\n")
tfile.write("};\n\n")


########### end of file
