int bitTest(int bitSizes[], bool sign) { int start = sizeof(T) * 8; int bitVals[4] = {0, 0, 0, 0}; int num; T test = 0; union { T total; S b; }bitRep; if (sign) { bitVals[0] = (1 << (bitSizes[0] - 1)) - 1; bitVals[1] = -(1 << (bitSizes[1] - 1)); bitVals[2] = 0; bitVals[3] = (1 << (bitSizes[3] - 1)) + (1 << bitSizes[3]/2);; } else { bitVals[0] = (1 << bitSizes[0]) + (1 << bitSizes[0]/2); bitVals[1] = 0; bitVals[2] = (1 << (bitSizes[2]/2)) - 1; bitVals[3] = (1 << bitSizes[3]) - 1; } for (unsigned int i = 0; i < 4; i++) { start -= bitSizes[i]; test = insert_bitfield_any((T) test, bitVals[i], sizeof(T), start, bitSizes[i]); //std::cout << "Test: " << (int)test << std::endl; if (sign) { num = extract_bitfield_any((T) test, sizeof(T), start, bitSizes[i]); } else { num = extract_unsigned_bitfield_any((T) test, sizeof(T), 0, (start+bitSizes[i])); } if (bitVals[i] > num) { /* bit value inserted is too large for bit member, ensure correct behavior */ EXPECT_EQ(num, bitVals[i] - (1 << bitSizes[i])); } else if (bitVals[i] < num) { EXPECT_EQ(num, -2*(1 << bitSizes[i]) + bitVals[i]); } else { EXPECT_EQ(num, bitVals[i]); } } bitRep.b.var1 = bitVals[0]; bitRep.b.var2 = bitVals[1]; bitRep.b.var3 = bitVals[2]; bitRep.b.var4 = bitVals[3]; EXPECT_EQ(test, bitRep.total); //printf("Decimal: %d %d %d %d\n", bitVals[0], bitVals[1], bitVals[2], bitVals[3]); return 0; }
int Trick::MemoryManager::assign_recursive(void* base_addr, ATTRIBUTES* attr, int curr_dim, int offset, V_TREE* v_tree, UCFn* cf) { char* assign_addr; int remaining_dimensions = attr->num_index - curr_dim; if ( remaining_dimensions == 0 ) { switch (attr->type) { case TRICK_CHARACTER : case TRICK_UNSIGNED_CHARACTER : assign_addr = (char*)base_addr + offset * sizeof(char); if (v_tree && v_tree->v_data) { *(char*)assign_addr = vval_char(v_tree->v_data); } else { *(char*)assign_addr = '\0'; } if (debug_level) { std::cout << std::endl << "Assignment: *(char*)" << (void*)assign_addr << " = "; if (isprint(*(char*)assign_addr)) { std::cout << *(char*)assign_addr; } else { std::cout << (int)*(char*)assign_addr; } std::cout << ";" << std::endl; std::cout.flush(); } break; case TRICK_WCHAR : assign_addr = (char*)base_addr + offset * sizeof(wchar_t); if (v_tree && v_tree->v_data) { *(wchar_t*)assign_addr = vval_char(v_tree->v_data); } else { *(wchar_t*)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(wchar_t*)" << (void*)assign_addr << " = " << *(wchar_t*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_SHORT : case TRICK_UNSIGNED_SHORT : assign_addr = (char*)base_addr + offset * sizeof(short); if (v_tree && v_tree->v_data) { *(short *)assign_addr = vval_short(v_tree->v_data); } else { *(short *)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(short*)" << (void*)assign_addr << " = " << *(short*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_INTEGER : case TRICK_UNSIGNED_INTEGER : assign_addr = (char*)base_addr + offset * sizeof(int); if (v_tree && v_tree->v_data) { int input_value; input_value = vval_int(v_tree->v_data); if (cf == NULL) { *(int *)assign_addr = input_value; } else { *(int *)assign_addr = input_value * cf->C[1] + cf->C[0]; } } else { *(int *)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(int*)" << (void*)assign_addr << " = " << *(int*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_BOOLEAN : assign_addr = (char*)base_addr + offset * sizeof(bool); if (v_tree && v_tree->v_data) { *(bool *)assign_addr = (vval_short(v_tree->v_data)!=0); } else { *(bool *)assign_addr = false; } if (debug_level) { std::cout << std::endl << "Assignment: *(bool*)" << (void*)assign_addr << " = " << *(bool*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_ENUMERATED : if (v_tree && v_tree->v_data) { if ((size_t)attr->size == sizeof(int)) { assign_addr = (char*)base_addr + offset * sizeof(int); *(int *)assign_addr = vval_int(v_tree->v_data); if (debug_level) { std::cout << std::endl << "Assignment (Enum): *(int*)" << (void*)assign_addr << " = " << *(int*)assign_addr << ";" << std::endl; std::cout.flush(); } } else if ((size_t)attr->size == sizeof(short)) { assign_addr = (char*)base_addr + offset * sizeof(short); *(short *)assign_addr = vval_short(v_tree->v_data); if (debug_level) { std::cout << std::endl << "Assignment (Enum): *(short*)" << (void*)assign_addr << " = " << *(short*)assign_addr << ";" << std::endl; std::cout.flush(); } } else { std::stringstream message; message << "Enumeration of size " << attr->size << " is not supported."; emitError(message.str()); } } else { emitError("v_tree data appears to be corrupted."); } break; case TRICK_LONG : case TRICK_UNSIGNED_LONG : assign_addr = (char*)base_addr + offset * sizeof(long); if (v_tree && v_tree->v_data) { long input_value; input_value = vval_long(v_tree->v_data); if (cf == NULL) { *(long *)assign_addr = input_value; } else { *(long *)assign_addr = input_value * cf->C[1] + cf->C[0]; } } else { *(long *)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(long*)" << (void*)assign_addr << " = " << *(long*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_FLOAT : assign_addr = (char*)base_addr + offset * sizeof(float); if (v_tree && v_tree->v_data) { float input_value; input_value = vval_float(v_tree->v_data); if (cf == NULL) { // There is no units conversion. *(float *)assign_addr = input_value; } else { // There is units conversion. *(float *)assign_addr = input_value * cf->C[1] + cf->C[0]; } } else { *(float *)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(float*)" << (void*)assign_addr << " = " << *(float*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_DOUBLE : assign_addr = (char*)base_addr + offset * sizeof(double); if (v_tree && v_tree->v_data) { double input_value; input_value = vval_double(v_tree->v_data); if (cf == NULL) { *(double *)assign_addr = input_value; } else { *(double *)assign_addr = input_value * cf->C[1] + cf->C[0]; } } else { *(double *)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(double*)" << (void*)assign_addr << " = " << *(double*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_LONG_LONG : case TRICK_UNSIGNED_LONG_LONG : assign_addr = (char*)base_addr + offset * sizeof(long long); if (v_tree && v_tree->v_data) { *(long long *)assign_addr = vval_longlong(v_tree->v_data); } else { *(long long *)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(long long*)" << (void*)assign_addr << " = " << *(long long*)assign_addr << ";" << std::endl; std::cout.flush(); } break; case TRICK_BITFIELD : case TRICK_UNSIGNED_BITFIELD : { int input_value; assign_addr = (char*)base_addr + offset * (size_t)attr->size; if (v_tree && v_tree->v_data) { input_value = vval_int(v_tree->v_data); } else { input_value = 0; } if (attr->size == sizeof(int)) { *(unsigned int*)assign_addr = insert_bitfield_any( *(unsigned int*)assign_addr, input_value, attr->size, attr->index[0].start, attr->index[0].size); } else if (attr->size == sizeof(short)) { *(unsigned short*)assign_addr = insert_bitfield_any( *(unsigned short*)assign_addr, input_value, attr->size, attr->index[0].start, attr->index[0].size); } else if (attr->size == sizeof(char)) { *(unsigned char*)assign_addr = insert_bitfield_any( *(unsigned char*)assign_addr, input_value, attr->size, attr->index[0].start, attr->index[0].size); } else { std::stringstream message; message << "Unhandled bitfield struct size (" << attr->size << ") in bitfield assignment."; emitError(message.str()); } if (debug_level) { std::cout << std::endl << "Assignment: " << "Within the " << attr->size << " byte struct at " << (void*)assign_addr << ", the bitfield ["<< attr->index[0].start << ".." << attr->index[0].start + attr->index[0].size - 1 << "] = " << input_value << ";" << std::endl; std::cout.flush(); } } break; case TRICK_FILE_PTR : if (debug_level) { std::cout << std::endl << "Assignment: TRICK_FILE_PTR assignments not yet implemented." << std::endl; std::cout.flush(); } break; case TRICK_VOID_PTR : if (debug_level) { std::cout << std::endl << "Assignment: TRICK_VOID_PTR assignments not yet implemented." << std::endl; std::cout.flush(); } break; case TRICK_STRING : assign_addr = (char*)base_addr + offset * sizeof(char*); if (v_tree && v_tree->v_data) { *(std::string*)assign_addr = vval_string(v_tree->v_data); } else { *(std::string*)assign_addr = ""; } if (debug_level) { std::cout << std::endl << "Assignment: *(std::string)" << (void*)assign_addr << " = \"" << *(std::string*)assign_addr << "\";" << std::endl; std::cout.flush(); } break; default: std::stringstream message; message << "Unhandled Type (" << attr->type << ") in assignment."; emitError(message.str()); return (1); break; } } else if ( remaining_dimensions > 0 ) { int size_of_curr_dim; size_of_curr_dim = attr->index[curr_dim].size ; assign_addr = (char*)base_addr + offset * sizeof(void*); if ( size_of_curr_dim == 0) { // the remaining dimensions are pointer dimensions. if (v_tree && v_tree->v_data) { if ((remaining_dimensions == 1) && (v_tree->v_data->type == TRICK_STRING)) { *(char**)assign_addr = mm_strdup( vval_string(v_tree->v_data)); } else { *(void**)assign_addr = vval_voidp(v_tree->v_data); } } else { *(void**)assign_addr = 0; } if (debug_level) { std::cout << std::endl << "Assignment: *(void**)" << (void*)assign_addr << " = " << *(void**)assign_addr << ";" << std::endl; std::cout.flush(); } } else { // next dimension is fixed. if ((attr->type == TRICK_CHARACTER) && (remaining_dimensions == 1) && (v_tree) && (v_tree->v_data) ) { if ((v_tree->v_data->type == TRICK_STRING) && (v_tree->v_data->value.cp != NULL)) { int rhs_len = (int)strlen(v_tree->v_data->value.cp) + 1; if (rhs_len <= size_of_curr_dim ) { strcpy((char*)assign_addr, v_tree->v_data->value.cp); } else { emitError("Memory Manager: char array is too small for the attempted string assignment."); return (1); } } else { *(char*)assign_addr = '\0'; } } else if ( (attr->type == TRICK_WCHAR) && (remaining_dimensions == 1)) { if ((v_tree) && (v_tree->v_data->type == TRICK_WSTRING) && (v_tree->v_data->value.wcp != NULL)) { int rhs_len = (int)wcslen(v_tree->v_data->value.wcp) + 1; if (rhs_len <= size_of_curr_dim ) { wcscpy((wchar_t*)assign_addr, v_tree->v_data->value.wcp); } else { std::stringstream message; message << "wchar_t array at [" << (void*)assign_addr << "] is to small for the attempted string assignment." ; emitError(message.str()); return (1); } } else if ((v_tree) && (v_tree->v_data->type == TRICK_STRING) && (v_tree->v_data->value.cp != NULL)) { int rhs_len = (int)ncs_to_wcs_len(v_tree->v_data->value.cp) + 1; if (rhs_len <= size_of_curr_dim ) { ncs_to_wcs( v_tree->v_data->value.cp, (wchar_t*)assign_addr, rhs_len); } else { std::stringstream message; message << "wchar_t array at [" << (void*)assign_addr << "] is too small for the attempted string assignment." ; emitError(message.str()); return (1); } } else { *(wchar_t*)assign_addr = (wchar_t) NULL; } } else { int ii; V_TREE* curr_vt_node; if (v_tree) { curr_vt_node = v_tree->down; } else { curr_vt_node = NULL; } for (ii=0; ii < size_of_curr_dim; ii++) { int ret; ret = assign_recursive (base_addr, attr, curr_dim+1, offset * size_of_curr_dim + ii, curr_vt_node, cf); if (ret !=0) { return(1); } if (curr_vt_node) { curr_vt_node = curr_vt_node->next; } } } } } else { emitError("This is bad. In assign_recursive(), remaining_dimensions is negative."); return (1); } return (0); }
void Trick::MemoryManager::clear_rvalue( void* base_address, ATTRIBUTES* attr, int curr_dim, int offset) { char* final_address; int remaining_dimensions = attr->num_index - curr_dim; /** @par Detailed Description: */ /** @par If we're referencing a singleton then calculate the address from the (base) address, the offset and the data-type. Then set the value at that address to nil. */ if (remaining_dimensions ==0) { switch (attr->type) { case TRICK_CHARACTER : case TRICK_UNSIGNED_CHARACTER : final_address = (char*)base_address + offset * sizeof(char); *(char*)final_address = '\0'; break; case TRICK_BOOLEAN: final_address = (char*)base_address + offset * sizeof(bool); *(bool*)final_address = false; break; case TRICK_WCHAR : final_address = (char*)base_address + offset * sizeof(wchar_t); *(wchar_t*)final_address = 0; break; case TRICK_SHORT : case TRICK_UNSIGNED_SHORT : final_address = (char*)base_address + offset * sizeof(short); *(short*)final_address = 0; break; case TRICK_INTEGER : case TRICK_UNSIGNED_INTEGER : final_address = (char*)base_address + offset * sizeof(int); *(int*)final_address = 0; break; case TRICK_ENUMERATED : if ((size_t)attr->size == sizeof(int)) { final_address = (char*)base_address + offset * sizeof(int); *(int*)final_address = 0; } else if ((size_t)attr->size == sizeof(short)) { final_address = (char*)base_address + offset * sizeof(short); *(short*)final_address = 0; } else { emitError("INTERNAL-ERROR - Unexpected size of ENUMERATION type.") ; } break; case TRICK_LONG : case TRICK_UNSIGNED_LONG : final_address = (char*)base_address + offset * sizeof(long); *(long*)final_address = 0; break; case TRICK_FLOAT : final_address = (char*)base_address + offset * sizeof(float); *(float*)final_address = 0.0; break; case TRICK_DOUBLE : final_address = (char*)base_address + offset * sizeof(double); *(double*)final_address = 0.0; break; case TRICK_LONG_LONG : case TRICK_UNSIGNED_LONG_LONG : final_address = (char*)base_address + offset * sizeof(long long); *(long long*)final_address = 0; break; case TRICK_BITFIELD : case TRICK_UNSIGNED_BITFIELD : final_address = (char*)base_address + offset * (size_t)attr->size; if (attr->size == sizeof(int)) { *(unsigned int*)final_address = insert_bitfield_any( *(unsigned int*)final_address, 0, attr->size, attr->index[0].start, attr->index[0].size); } else if (attr->size == sizeof(short)) { *(unsigned short*)final_address = insert_bitfield_any( *(unsigned short*)final_address, 0, attr->size, attr->index[0].start, attr->index[0].size); } else if (attr->size == sizeof(char)) { *(unsigned char*)final_address = insert_bitfield_any( *(unsigned char*)final_address, 0, attr->size, attr->index[0].start, attr->index[0].size); } else { std::stringstream message; message << "INTERNAL - Unhandled bitfield struct size (" << attr->size << ") in bitfield assignment."; emitError(message.str()); } break; case TRICK_FILE_PTR : final_address = (char*)base_address + offset * sizeof(void*); *(void**)final_address = (void*)NULL; break; case TRICK_STRING : final_address = (char*)base_address + offset * sizeof(void*); *(std::string*)final_address = ""; break; case TRICK_STL : final_address = (char*)base_address + offset * attr->size ; if ( attr->clear_stl ) { (*attr->clear_stl)(final_address) ; } break; default : std::stringstream message; message << "Unhandled Type (" << (int)attr->type << ")."; emitError(message.str()); break; } /** @par If on the otherhand we are referencing an array, then we must consider two cases. */ } else if (remaining_dimensions > 0) { int extent; extent = attr->index[curr_dim].size ; /** @par If the array is unconstrained (i.e., it's a pointer) then we just need to check whether the pointer is NULL. */ if ( extent == 0) { final_address = (char*)base_address; *(void**)final_address = NULL; /** @par If the array (at this dimension) is constrained (i.e., it's a fixed array ) then it is nil if and only if each of it's sub-elements (at the next dimension, which can themselves be arrays) are nil. So, for each of the elements in current dimension, we recursively call is_nil_valued() on each of the sub-elements to find out whether this array is nil valued and return the result. */ } else { int ii; for (ii=0; ii < extent; ii++) { clear_rvalue( base_address, attr, curr_dim + 1, offset * extent + ii); } } } else { std::stringstream message; message << "This is bad. Remaining dimensions are negative!?."; emitError(message.str()); } }