Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions include/trick/AttributesUtils.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef ATTRIBUTES_UTILS_HH
#define ATTRIBUTES_UTILS_HH

/*
PURPOSE: ( Provides helper functions for working with ATTRIBUTES. )
*/

#include "trick/attributes.h"

namespace Trick
{

class AttributesUtils
{
public:
// Compute the byte size occupied by a member - references, arrays, and pointers.
static size_t compute_member_byte_size(const ATTRIBUTES& member);

// Return the ATTRIBUTES entry that contains the given offset within the struct/class.
static ATTRIBUTES* find_member_by_offset(ATTRIBUTES* structAttr, size_t addrOffsetFromStruct);

// Count the number of fixed dimensions on an ATTRIBUTES entry.
static int count_fixed_dims(const ATTRIBUTES& member);

/**
* Result of traversing a structure to find an attribute at a given address offset.
* This structure contains the common information for traversal.
*/
struct TraversalResult
{
ATTRIBUTES* found_attr = nullptr; // The attribute found at the given offset, or nullptr
// if the offset falls in an anonymous/hidden member region
size_t offset_from_found_attr = 0; // Offset relative to the found attribute; for structured arrays,
// this is adjusted to the selected element base.
int array_indices[TRICK_MAX_INDEX] = { }; // Computed array indices (if applicable)
int num_computed_indices = 0; // Number of valid indices in array_indices
bool is_in_anonymous_member = false; // True if the offset falls in an anonymous or otherwise unnamed member region
};

/**
* Traverse a structured type to find the attribute corresponding to a given address offset.
* This function provides the common traversal logic that can be used for the need to
* traverse structures but expecting different output formats.
*
* @param reference_offset Offset from the structure base address to the address we're looking for
* @param struct_attr ATTRIBUTES of the structure to traverse
* @param result Output parameter containing traversal results
* @return 0 if success, otherwise 1 or non-zero
*/
static int traverse_for_offset(
size_t reference_offset,
ATTRIBUTES* struct_attr,
TraversalResult& result);

// Given a byte offset within a member's storage, compute indices for fixed dimensions.
// Returns false if an invalid configuration is detected (e.g., divide-by-zero risk).
static bool compute_fixed_indices_for_linear_offset(
const ATTRIBUTES& member,
long offset_within_member_bytes,
int out_indices[TRICK_MAX_INDEX],
int& out_num_fixed_dims);
};

} // namespace Trick

#endif // ATTRIBUTES_UTILS_HH
10 changes: 10 additions & 0 deletions include/trick/MemoryManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,16 @@ namespace Trick {
*/
std::string make_decl_string(TRICK_TYPE type, std::string class_name, int n_stars, std::string var_name, int n_cdims, int *cdims);

/**
* Given an address, populate the attributes instance describing the properties of the address and any
* remaining offset to the address.
* @param address pointer to the address of interest
* @param attrOut reference to the ATTRIBUTES instance to be populated
* @param remainingOffset reference to the size_t to be populate with the number of bytes to the start of
* the attributes returned.
*/
void get_attributes_for_address(void* address, ATTRIBUTES& attrOut, size_t& remainingOffset);

/**
Return the size of the specified user-defined type.
@param user_type_name The name of a user-defined type.
Expand Down
8 changes: 4 additions & 4 deletions include/trick/PythonPrint.hh
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ class PythonPrint: public CheckPointAgent {
located. @c offset=0 means that the address points to the value
to be written.
*/
static void write_singleton( std::ostream& chkpnt_os, void* address,
ATTRIBUTES* attr, int offset, bool write_units = true , bool in_list = false );
static void write_singleton(std::ostream& chkpnt_os, void* address,
ATTRIBUTES* attr, int offset, bool write_units, bool in_list);

/**
I NEED DOCUMENTATION!
*/
static void write_rvalue( std::ostream& chkpnt_os, void* address,
ATTRIBUTES* attr, int curr_dim, int offset, bool write_units = true , bool in_list = false );
static void write_rvalue(std::ostream& chkpnt_os, void* address,
ATTRIBUTES* attr, int curr_dim, int offset, bool write_units, bool in_list, int* startingIndex);

/**
Convert a pointer into a text expression that represents that pointer and is
Expand Down
2 changes: 1 addition & 1 deletion include/trick/swig/PrimitiveAttributesMap.hh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace Trick {
static Trick::PrimitiveAttributesMap * attributes_map() ;

/**
* Gets the units for a specified variable.
* Gets the attributes for a specified primitive type name.
* @param param The name of the variable.
* @return The units of a specified variable.
*/
Expand Down
14 changes: 11 additions & 3 deletions include/trick/swig/swig_double.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@

class swig_double {
public:
double value ;
std::string units ;
double value{} ;
std::string units{"1"} ;
static char str_output[32] ;
static char fmt_specifiers[4][12];
bool isFloat{};

swig_double() ;
swig_double() = default;

template <typename T>
static bool isTypeFloat()
Comment thread
hchen99 marked this conversation as resolved.
{
return std::is_same<T, float>::value;
}

char * __str__() ;
char * __repr__() ;
Expand Down
126 changes: 126 additions & 0 deletions include/trick/swig/swig_int_templates.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,135 @@
#ifndef SWIG_INT_TEMPLATES_HH
#define SWIG_INT_TEMPLATES_HH

#include "trick/MemoryManager.hh"
#include "trick/UdUnits.hh"
#include "trick/attributes.h"

#include <string>
#include <type_traits>
#include <udunits2.h>

template <typename T>
static void test_attr_units_and_set(T& swig_inst, ATTRIBUTES& attr, const std::string& syname)
{
if (attr.units)
{
swig_inst.units = attr.units;
}
else
{
std::string temp_name = Trick::UnitsMap::units_map()->get_units(syname.substr(0, syname.length() - 4));
swig_inst.units = temp_name;
}
}

template <>
void test_attr_units_and_set<swig_ref>(swig_ref& swig_inst, ATTRIBUTES& attr, const std::string& syname)
{
if (attr.units)
{
swig_inst.ref.attr->units = strdup(attr.units);
}
else
{
std::string temp_name = Trick::UnitsMap::units_map()->get_units(syname.substr(0, syname.length() - 4));
swig_inst.ref.attr->units = strdup(temp_name.c_str());
}
}

static void init_swig_ref_attributes_for_dimensions(swig_ref& swig_inst,
ATTRIBUTES& addrAttr,
size_t offsetRemainder,
const std::string& symname,
const std::string& tname,
size_t expectedNumDimensions)
{
if (addrAttr.num_index == 0)
{
// Attributes weren't found resort to specifying a 2D unsized pointer
swig_inst.ref.attr->num_index = expectedNumDimensions;
for (int dim = 0; dim < expectedNumDimensions; ++dim)
{
swig_inst.ref.attr->index[dim].size = 0;
}
}
else
{
// Attributes were found, check if the right number of dimensions
if (addrAttr.num_index == expectedNumDimensions)
{
swig_inst.ref.attr->num_index = addrAttr.num_index;
swig_inst.ref.address = (char*)swig_inst.ref.address - offsetRemainder;
swig_inst.ref.attr->offset = offsetRemainder;
for (int dim = 0; dim < addrAttr.num_index; ++dim)
{
swig_inst.ref.attr->index[dim].size = addrAttr.index[dim].size;
}
}
else
{
if (addrAttr.num_index < expectedNumDimensions)
{
std::cout << symname << " warning: Mismatch in dimensions for swig typemap " << tname << ", required "
<< expectedNumDimensions << "D array but attributes report a " << addrAttr.num_index
<< "D array\n"
<< std::endl;
}
// Flatten to 1d
swig_inst.ref.attr->num_index = 1;
size_t totalElements = 1;
for (int dim = 0; dim < addrAttr.num_index; ++dim)
{
if (addrAttr.index[dim].size != 0)
{
totalElements *= addrAttr.index[dim].size;
}
}
swig_inst.ref.attr->index[0].size = totalElements - (offsetRemainder / swig_inst.ref.attr->size);
}
}
}

template <typename T>
static void alloc_and_get_primitive_vs_enum_attributes(
T* var_addr, swig_ref& swig_inst, const std::string& type_name, ATTRIBUTES& addrAttr, size_t& offsetRemainder)
{
using Decayed = std::decay_t<T>;
using Pointee = std::remove_pointer_t<Decayed>;

trick_MM->get_attributes_for_address(var_addr, addrAttr, offsetRemainder);
ATTRIBUTES* primAttr = Trick::PrimitiveAttributesMap::attributes_map()->get_attr(type_name);
// PrimitiveAttributes lookup failed. Probably an enum. Create a new attributes based on size of type.
if (primAttr == NULL)
{
primAttr = new ATTRIBUTES();
swig_inst.ref.attr = primAttr;
swig_inst.ref.attr->size = sizeof(Pointee);
switch (swig_inst.ref.attr->size)
{
case 1:
swig_inst.ref.attr->type = TRICK_CHARACTER;
break;
case 2:
swig_inst.ref.attr->type = TRICK_SHORT;
break;
case 4:
swig_inst.ref.attr->type = TRICK_INTEGER;
break;
case 8:
swig_inst.ref.attr->type = TRICK_LONG_LONG;
break;
default:
swig_inst.ref.attr->type = TRICK_INTEGER;
break;
}
swig_inst.ref.attr->io = TRICK_VAR_OUTPUT | TRICK_VAR_INPUT | TRICK_CHKPNT_OUTPUT | TRICK_CHKPNT_INPUT;
addrAttr.units = nullptr;
}
swig_inst.ref.attr = primAttr;
swig_inst.ref.attr->type_name = strdup(type_name.c_str());
}

template< class S , typename T > static int convert_and_set( T & output , void * my_argp , std::string to_units ) {
int ret = 0 ;

Expand Down
Loading
Loading