trick/bin/pm/s_source.pm
2015-02-26 09:02:31 -06:00

356 lines
12 KiB
Perl

package s_source ;
# $Id: s_source.pm 3711 2014-10-28 19:43:54Z alin $
use Exporter ();
@ISA = qw(Exporter);
@EXPORT = qw(s_source);
use strict ;
use gte ;
use trick_version ;
sub s_source($) {
my ($sim_ref) = @_ ;
my (@cpp_headers , @c_headers) ;
#--------------------------------------------------------------
# Generate S_source.c
open S_SOURCE, ">S_source.cpp" or die "Couldn't open S_source.cpp!\n";
open S_SOURCE_H, ">S_source.hh" or die "Couldn't open S_source.hh!\n";
# Get Trick version
my ($version, $thread) = get_trick_version() ;
$thread =~ s/\d+\.// ;
#---------------------------
# Get date
my $date = localtime ;
my ($sec,$min,$hour,$mday,$mon,$year) = localtime ;
$year += 1900 ;
$mon += 1 ;
my ($login) = getpwuid($<) ;
#---------------------------
# Print version - date
my ($temp) = "Id:" ;
printf S_SOURCE "\n/* \$$temp S_source.cpp auto $year/%02d/%02d %02d\:%02d\:%02d $login \$ */\n",
$mon , $mday , $hour , $min , $sec ;
#---------------------------
# Includes
print S_SOURCE_H "
/**
PURPOSE:
(Contains sim ojbects)
*/
#ifndef __S_SOURCE_HH__
#define __S_SOURCE_HH__
#include <new>
#include <iostream>
#include <stdlib.h>
#include \"sim_services/MemoryManager/include/attributes.h\"
#include \"sim_services/include/populate_attribute_maps.hh\"
#include \"sim_services/SimObject/include/SimObject.hh\"
#include \"sim_services/SimObject/include/JobData.hh\"
#include \"sim_services/Units/include/UnitsMap.hh\"\n\n" ;
# TODO get rid of this statement! This is still here because of the collect
print S_SOURCE_H "#define ip_alloc calloc\n" ;
print S_SOURCE_H "$$sim_ref{system_headers}\n" ;
foreach my $h ( @{$$sim_ref{sim_class_includes}} ) {
if ( $h !~ /\.h$/ ) {
push @cpp_headers , $h ;
}
else {
my ($full_path) ;
$full_path = $$sim_ref{headers_full_path}{$h} ;
if ($$sim_ref{headers_lang}{$h} eq "cpp" ) {
push @cpp_headers , $h ;
}
else {
push @c_headers , $h ;
}
}
}
my %temp_hash ;
@cpp_headers = grep ++$temp_hash{$_} < 2, @cpp_headers ;
foreach my $h ( sort @cpp_headers ) {
my $printed = 0 ;
# list header files that are not under the trick_source directory
# (e.g. trick_models/ directory)
if ( $h !~ s/^TRICK_HOME\/trick_source\/// ) {
foreach ( @{$$sim_ref{inc_paths}} ) {
if ($h =~ s,^$_/,, ) {
print S_SOURCE_H "#include \"$h\"\n";
$printed = 1 ;
last ;
}
}
}
# list header files that are in trick_source
if ( $printed eq 0 ) {
print S_SOURCE_H "#include \"$h\"\n";
}
}
if ( scalar @c_headers ) {
print S_SOURCE_H "\n#ifdef __cplusplus\n" ,
"extern \"C\" {\n" ,
"#endif\n\n" ;
foreach my $h ( sort @c_headers ) {
my $printed = 0 ;
if ( $h !~ s/^TRICK_HOME\/trick_source\/// ) {
foreach ( @{$$sim_ref{inc_paths}} ) {
if ($h =~ s,^$_/,, ) {
print S_SOURCE_H "#include \"$h\"\n";
$printed = 1 ;
last ;
}
}
}
if ( $printed eq 0 ) {
print S_SOURCE_H "#include \"$h\"\n";
}
}
print S_SOURCE_H "\n#ifdef __cplusplus\n" ,
"}\n" ,
"#endif\n" ;
}
print S_SOURCE_H "\n" ;
# prints the user defined header code
print S_SOURCE_H "$$sim_ref{user_header}\n" ;
# prints classes defined in S_define file. Set in parse_s_define.pm
print S_SOURCE_H $$sim_ref{sim_class_code} ;
# prints an instantiation for each templated sim object for ICG to process.
print S_SOURCE_H "#ifdef TRICK_ICG\n" ;
print S_SOURCE_H $$sim_ref{template_instance_declarations} ;
print S_SOURCE_H "#endif\n\n" ;
# prints an extern declaration for each sim object
print S_SOURCE_H "#ifndef SWIG\n" ;
print S_SOURCE_H $$sim_ref{extern_instance_declarations} ;
print S_SOURCE_H "#endif\n" ;
print S_SOURCE_H "\n\n#endif\n" ;
close S_SOURCE_H ;
print S_SOURCE "#include \"S_source.hh\"\n" ;
print S_SOURCE "$$sim_ref{user_code}\n" ;
# prints associated call functions
print S_SOURCE $$sim_ref{sim_class_call_functions} ;
# prints instantiations from S_define file. Set in parse_s_define.pm
print S_SOURCE "\n// Instantiate stuff\n" ;
print S_SOURCE $$sim_ref{instance_declarations} ;
# prints integration loop sim objects from S_define file
print S_SOURCE "\n// Integration Loop Sim Object(s) JMP\n" ;
foreach my $integ_loop ( @{$$sim_ref{integ_loop}} ) {
print S_SOURCE "IntegLoopSimObject $$integ_loop{name}($$integ_loop{cycle}, $$integ_loop{child}" ;
my @integ_loop_sim_objects = split(/\s*,\s*/, $$integ_loop{name_list} ) ;
foreach my $integ_loop_sim_obj (@integ_loop_sim_objects) {
print S_SOURCE ", &$integ_loop_sim_obj" ;
}
print S_SOURCE ", (void *)NULL);\n" ;
}
#---------------------------
# Default Environment
print S_SOURCE "\n/* Default Environment */\n" ,
"SimEnvironment::SimEnvironment() {\n\n" ;
print S_SOURCE gte("S_source");
print S_SOURCE "}\n\n" ;
#---------------------------
# Memory Init
print S_SOURCE "\n/* Memory Init */\n" ,
"void memory_init( void ) {\n\n" ;
print S_SOURCE " " x 4 , "ALLOC_INFO * ai ;\n" ;
print S_SOURCE " " x 4 , "exec_set_version_date_tag\( \"@(#)CP Version $version-$thread, $date\" \) ;\n" ;
print S_SOURCE " " x 4 , "exec_set_build_date\( \"$date\" \) ;\n" ;
print S_SOURCE " " x 4 , "exec_set_current_version\( \"$version-$thread\" \) ;\n\n" ;
print S_SOURCE " " x 4 , "populate_sim_services_class_map\(\) ;\n" ;
print S_SOURCE " " x 4 , "populate_sim_services_enum_map\(\) ;\n" ;
print S_SOURCE " " x 4 , "populate_class_map\(\) ;\n" ;
print S_SOURCE " " x 4 , "populate_enum_map\(\) ;\n" ;
print S_SOURCE "\n" ;
# prints the job class order for the cyclic jobs
foreach my $cl ( @{$$sim_ref{user_class_order}} ) {
print S_SOURCE" exec_add_scheduled_job_class(\"$cl\") ;\n" ;
}
print S_SOURCE "\n" ;
foreach my $inst ( @{$$sim_ref{instances}} ) {
print S_SOURCE " " x 4 , "exec_add_sim_object(&$inst, \"$inst\") ;\n" ;
my $temp_type = $$sim_ref{instances_type}{$inst} ;
$temp_type =~ s/\s//g ;
$temp_type =~ s/[<>,:*]/_/g ;
print S_SOURCE " " x 4 , "TMM_declare_ext_var(&$inst, TRICK_STRUCTURED,\"$temp_type\", 0, \"$inst\", 0, NULL) ;\n" ;
print S_SOURCE " " x 4 , "if ( (ai = get_alloc_info_at(&$inst)) != NULL ) {\n" ;
print S_SOURCE " " x 8 , "ai->alloced_in_memory_init = 1 ;\n" ;
print S_SOURCE " " x 4 , "}\n" ;
}
print S_SOURCE " " x 4 , "// Add Integration Loop Sim Object(s) JMP\n" ;
foreach my $integ_loop ( sort sim_integ_by_name @{$$sim_ref{integ_loop}} ) {
print S_SOURCE " " x 4 , "exec_add_sim_object(&$$integ_loop{name} , \"$$integ_loop{name}\") ;\n" ;
print S_SOURCE " " x 4 , "TMM_declare_ext_var(&$$integ_loop{name}, TRICK_STRUCTURED,\"IntegLoopSimObject\", 0, \"$$integ_loop{name}\", 0, NULL) ;\n" ;
}
print S_SOURCE "\n" ;
print S_SOURCE $$sim_ref{create_connections} ;
print S_SOURCE "\n" ,
" " x 4 , "return ;\n" ,
"}\n\n" ;
#------------------------------------------
# Write out the 'exec_collect_init()' function in S_source.c
#
# exec_collect_init() is responsible for initializing all the pointer
# management associated with 'collect' statements in the S_define file.
#
# For every collect statement, perform the following:
# (I highly recommended viewing S_source.c to get a clearer picture
# of what is going on here.)
# 1) Get a pointer to the collect info in the CP structures.
# 2) Allocate memory for the collect pointer list based on the number
# of items listed in the collect statement, allocate an additional
# 8 bytes to hold the number of items in the list.
# 3) store the address of the new memory in the 'n' parameter.
# 4) store the number of items in the list at the address pointed to
# by 'n'.
# 5) Shift the address f the original allocation past the 8 byte integer
# stored at 'n', and save this address in the pointer defined by the
# collect statement. This address represents the first element of an
# array of addresses of each of the elements listed in the collect list.
# 6) Save the address of each element in the collect list in the
# respective pointer list just created.
#
#-------------
# Write the exec_collect_init() entry point.
print S_SOURCE "\n/*---------------------------------------------------------------------*/\n\n" ;
print S_SOURCE "void exec_collect_init( void ) {\n\n" ;
if ( exists $$sim_ref{collect} ) {
# print S_SOURCE " " x 4 , "long * lp ;\n\n" ;
#
#
# foreach my $collect ( sort sim_collect_by_name @{$$sim_ref{collect}} ) {
# # Number of params in collect statement
# my $np = $$collect{num_params} ;
#
# print S_SOURCE " " x 4 , "$$collect{name} = (void**)ip_alloc( $np + 1 , sizeof(void*));\n" ,
# " " x 4 , "lp = (long *)$$collect{name} ;\n" ,
# " " x 4 , "*lp = $np ;\n" ,
# " " x 4 , "$$collect{name}++ ;\n" ;
#
# for ( my $i = 0; $i < $np ; $i++ ) {
# my $name = @{$$collect{params}}[$i] ;
# print S_SOURCE " " x 4 , "$$collect{name}\[$i\] = (void*)&($name);\n" ;
# }
# }
#print S_SOURCE "\n#if 0\n" ;
foreach my $collect ( @{$$sim_ref{collect}} ) {
print S_SOURCE " " x 4 , "$$collect{name} = NULL ;\n" ;
my $np = $$collect{num_params} ;
foreach my $name ( @{$$collect{params}} ) {
print S_SOURCE " " x 4 , "$$collect{name} = add_collect($$collect{name}, (void*)&($name));\n" ;
}
}
#print S_SOURCE "\n#endif\n" ;
}
if ( exists $$sim_ref{vcollect} ) {
foreach my $collect ( sort sim_vcollect_by_name @{$$sim_ref{vcollect}} ) {
my $name = $$collect{name} ;
my $func = $$collect{constructor} ;
undef $func if ( defined $func ) && ( $func eq "" ) ;
foreach my $item ( sort @{$$collect{items}} ) {
my $ref = $item ;
if ( $ref =~ s/&// ) {
$ref = "&($ref)" ;
} else {
$ref = "$ref" ;
}
if (defined $func ) {
$ref = "$func( $ref )" ;
}
print S_SOURCE " " x 4, "$name.push_back(\n", " " x 24, "$ref );\n" ;
}
print S_SOURCE "\n" ;
}
}
print S_SOURCE " " x 4, "return ;\n" ,
"}\n\n" ;
close S_SOURCE ;
}
#--------------------------------------------------------------
# Given an array of sim integrate statements, provide sort routines
#
sub sim_integ_by_name {
return
#Sort by sim integrate name in ASCII order
( ${$a}{name} cmp ${$b}{name} ) ||
#If two names are identical, then sort based on cycle time
( ${$a}{cycle} <=> ${$b}{cycle} );
}
#--------------------------------------------------------------
# Given an array of sim collect statements, provide sort routines
#
sub sim_collect_by_name {
return
#Sort by sim collect statement name in ASCII order
( ${$a}{name} cmp ${$b}{name} ) ||
#If two params are identical, then sort based on num_params
( ${$a}{num_params} <=> ${$b}{num_params} );
}
#--------------------------------------------------------------
# Given an array of sim Vcollect statements, provide sort routines
#
sub sim_vcollect_by_name {
return
#Sort by sim collect statement name in ASCII order
( ${$a}{name} cmp ${$b}{name} );
}
1;