/** * Test dict_getItem(): * Pass non-dict object; expect TypeError * Pass non-hashable key; expect KeyError * Pass empty dict, any key; expect KeyError * Pass non-empty list, non-present key; expect KeyError * Pass non-empty dict, present key; expect OK and value */ void ut_dict_getItem_000(CuTest *tc) { uint8_t heap[HEAP_SIZE]; pPmObj_t pobj = C_NULL; pPmObj_t pval; PmReturn_t retval; retval = pm_init(heap, HEAP_SIZE, MEMSPACE_RAM, C_NULL); retval = dict_new(&pobj); retval = dict_getItem(PM_ONE, PM_ONE, &pval); CuAssertTrue(tc, retval == PM_RET_EX_TYPE); retval = dict_new(&pobj); retval = dict_getItem(pobj, pobj, &pval); CuAssertTrue(tc, retval == PM_RET_EX_KEY); retval = dict_new(&pobj); retval = dict_getItem(pobj, PM_ONE, &pval); CuAssertTrue(tc, retval == PM_RET_EX_KEY); retval = dict_new(&pobj); retval = dict_setItem(pobj, PM_ONE, PM_ZERO); retval = dict_getItem(pobj, PM_NEGONE, &pval); CuAssertTrue(tc, retval == PM_RET_EX_KEY); retval = dict_new(&pobj); retval = dict_setItem(pobj, PM_ONE, PM_ZERO); retval = dict_getItem(pobj, PM_ONE, &pval); CuAssertTrue(tc, retval == PM_RET_OK); CuAssertTrue(tc, pval == PM_ZERO); }
PmReturn_t class_getAttr(pPmObj_t pobj, pPmObj_t pname, pPmObj_t *r_pobj) { PmReturn_t retval; uint16_t i; pPmObj_t pparent; /* If the given obj is an instance, check its attrs */ if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, pname, r_pobj); if (retval == PM_RET_OK) { return retval; } /* Otherwise, check the instance's class */ pobj = (pPmObj_t)((pPmInstance_t)pobj)->cli_class; } C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLO); retval = dict_getItem((pPmObj_t)((pPmClass_t)pobj)->cl_attrs, pname, r_pobj); /* If attr is not found, search parent(s) */ if ((retval == PM_RET_EX_KEY) && (((pPmClass_t)pobj)->cl_bases != C_NULL)) { for (i = 0; i < ((pPmClass_t)pobj)->cl_bases->length; i++) { pparent = ((pPmClass_t)pobj)->cl_bases->val[i]; retval = class_getAttr(pparent, pname, r_pobj); if (retval == PM_RET_OK) { break; } } } return retval; }
/** * Test dict_setItem(): * Pass valid vals, set(k,v); dict length must be 1 * Pass valid vals, set(k,v); item at k must be same v * Pass valid vals, set(k,v1); set(k,v2), item at k must be v2 */ void ut_dict_setItem_001(CuTest* tc) { uint8_t heap[HEAP_SIZE]; pPmObj_t pobj = C_NULL; pPmObj_t pval; PmReturn_t retval; retval = pm_init(heap, HEAP_SIZE, MEMSPACE_RAM, C_NULL); retval = dict_new(&pobj); retval = dict_setItem(pobj, PM_ZERO, PM_ONE); CuAssertTrue(tc, ((pPmDict_t)pobj)->length == 1); retval = dict_getItem(pobj, PM_ZERO, &pval); CuAssertTrue(tc, retval == PM_RET_OK); CuAssertPtrEquals(tc, PM_ONE, pval); retval = dict_setItem(pobj, PM_ZERO, PM_NEGONE); retval = dict_getItem(pobj, PM_ZERO, &pval); CuAssertTrue(tc, retval == PM_RET_OK); CuAssertPtrEquals(tc, PM_NEGONE, pval); }
/** * Unit Test ported from SNARF * This tests if it correctly creates the dictionary object * This also tests if dict_setItem correctly replaces the existing value * if the new val has the same key as the exisiting one. */ void ut_dict_getItem_001(CuTest *tc) { uint8_t heap[HEAP_SIZE]; p_test_str1 = test_str1; p_test_str2 = test_str2; p_test_str3 = test_str3; p_test_strnew = test_strnew; PmReturn_t retval; retval = pm_init(heap, HEAP_SIZE, MEMSPACE_RAM, C_NULL); retval = string_new((uint8_t const **)&test_str1, &p_firstval); retval = string_new((uint8_t const **)&test_str2, &p_secondval); retval = string_new((uint8_t const **)&test_str3, &p_thirdval); retval = string_new((uint8_t const **)&test_strnew, &p_newval); retval = int_new(1, (pPmObj_t *)&p_firstkey); retval = int_new(2, (pPmObj_t *)&p_secondkey); retval = int_new(3, (pPmObj_t *)&p_thirdkey); retval = int_new(2, (pPmObj_t *)&p_newkey); dict_new(&p_dict); dict_setItem(p_dict, (pPmObj_t)p_firstkey, p_firstval); dict_setItem(p_dict, (pPmObj_t)p_secondkey, p_secondval); dict_setItem(p_dict, (pPmObj_t)p_thirdkey, p_thirdval); dict_setItem(p_dict, (pPmObj_t)p_newkey, p_newval); dict_setItem(p_dict, (pPmObj_t)p_secondkey, p_secondval); dict_getItem(p_dict, (pPmObj_t)p_firstkey, &p_tempobj); CuAssertTrue(tc, obj_compare(p_tempobj, p_firstval) == C_SAME); dict_getItem(p_dict, (pPmObj_t)p_secondkey, &p_tempobj); CuAssertTrue(tc, obj_compare(p_tempobj, p_secondval) == C_SAME); dict_getItem(p_dict, (pPmObj_t)p_thirdkey, &p_tempobj); CuAssertTrue(tc, obj_compare(p_tempobj, p_thirdval) == C_SAME); }
int8_t dict_compare(pPmObj_t d1, pPmObj_t d2) { pPmDict_t pd1 = (pPmDict_t)d1; pPmDict_t pd2 = (pPmDict_t)d2; pPmObj_t pkey1; pPmObj_t pval1; pPmObj_t pval2; uint16_t i; PmReturn_t retval; /* Return if lengths are not equal */ if (pd1->length != pd2->length) { return C_DIFFER; } for (i = 0; i < pd1->length; i++) { /* Get the key,val from one dict */ retval = seglist_getItem(pd1->d_keys, i, &pkey1); PM_RETURN_IF_ERROR(retval); retval = seglist_getItem(pd1->d_vals, i, &pval1); PM_RETURN_IF_ERROR(retval); /* Return if the key,val pair is not in the other dict */ retval = dict_getItem(d2, pkey1, &pval2); if (retval != PM_RET_OK) { return C_DIFFER; } if (obj_compare(pval1, pval2) != C_SAME) { return C_DIFFER; } } /* All key,values match */ return C_SAME; }
PmReturn_t obj_print(pPmObj_t pobj, uint8_t is_expr_repr, uint8_t is_nested) { PmReturn_t retval = PM_RET_OK; C_ASSERT(pobj != C_NULL); /* Something gets printed unless it's None in an unnested expression */ if (!((OBJ_GET_TYPE(pobj) == OBJ_TYPE_NON) && is_expr_repr && !is_nested)) { gVmGlobal.somethingPrinted = C_TRUE; } switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_NON: if (!is_expr_repr || is_nested) { plat_putByte('N'); plat_putByte('o'); plat_putByte('n'); retval = plat_putByte('e'); } break; case OBJ_TYPE_INT: retval = int_print(pobj); break; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: retval = float_print(pobj); break; #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: retval = string_print(pobj, (is_expr_repr || is_nested)); break; case OBJ_TYPE_TUP: retval = tuple_print(pobj); break; case OBJ_TYPE_LST: retval = list_print(pobj); break; case OBJ_TYPE_DIC: retval = dict_print(pobj); break; case OBJ_TYPE_BOOL: if (((pPmBoolean_t) pobj)->val == C_TRUE) { plat_putByte('T'); plat_putByte('r'); plat_putByte('u'); } else { plat_putByte('F'); plat_putByte('a'); plat_putByte('l'); plat_putByte('s'); } retval = plat_putByte('e'); break; case OBJ_TYPE_CLI: #ifdef HAVE_BYTEARRAY { pPmObj_t pobj2; retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, PM_NONE, (pPmObj_t *)&pobj2); if ((retval == PM_RET_OK) && (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_BYA)) { retval = bytearray_print(pobj2); break; } } #endif /* HAVE_BYTEARRAY */ case OBJ_TYPE_COB: case OBJ_TYPE_MOD: case OBJ_TYPE_CLO: case OBJ_TYPE_FXN: case OBJ_TYPE_CIM: case OBJ_TYPE_NIM: case OBJ_TYPE_NOB: case OBJ_TYPE_THR: case OBJ_TYPE_CIO: case OBJ_TYPE_MTH: case OBJ_TYPE_SQI: plat_putByte('<'); plat_putByte('o'); plat_putByte('b'); plat_putByte('j'); plat_putByte(' '); plat_putByte('t'); plat_putByte('y'); plat_putByte('p'); plat_putByte('e'); plat_putByte(' '); plat_putByte('0'); plat_putByte('x'); int_printHexByte(OBJ_GET_TYPE(pobj)); plat_putByte(' '); plat_putByte('@'); plat_putByte(' '); plat_putByte('0'); plat_putByte('x'); _int_printHex((intptr_t)pobj); retval = plat_putByte('>'); break; default: /* Otherwise raise a TypeError */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } return retval; }
int8_t obj_compare(pPmObj_t pobj1, pPmObj_t pobj2) { #ifdef HAVE_BYTEARRAY PmReturn_t retval; pPmObj_t pobj; #endif /* HAVE_BYTEARRAY */ C_ASSERT(pobj1 != C_NULL); C_ASSERT(pobj2 != C_NULL); /* Check if pointers are same */ if (pobj1 == pobj2) { return C_SAME; } /* If types are different, objs must differ */ if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) { return C_DIFFER; } #ifdef HAVE_BYTEARRAY /* If object is an instance, get the thing it contains */ if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs, PM_NONE, &pobj); PM_RETURN_IF_ERROR(retval); pobj1 = pobj; } if (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj2)->cli_attrs, PM_NONE, &pobj); PM_RETURN_IF_ERROR(retval); pobj2 = pobj; } /* If types are different, objs must differ */ if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) { return C_DIFFER; } #endif /* HAVE_BYTEARRAY */ /* Otherwise handle types individually */ switch (OBJ_GET_TYPE(pobj1)) { case OBJ_TYPE_NON: return C_SAME; case OBJ_TYPE_INT: return ((pPmInt_t)pobj1)->val == ((pPmInt_t)pobj2)->val ? C_SAME : C_DIFFER; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: { pPmObj_t r_pobj; float_compare(pobj1, pobj2, &r_pobj, COMP_EQ); return (r_pobj == PM_TRUE) ? C_SAME : C_DIFFER; } #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: return string_compare((pPmString_t)pobj1, (pPmString_t)pobj2); case OBJ_TYPE_TUP: case OBJ_TYPE_LST: #ifdef HAVE_BYTEARRAY case OBJ_TYPE_BYA: #endif /* HAVE_BYTEARRAY */ return seq_compare(pobj1, pobj2); case OBJ_TYPE_DIC: return dict_compare(pobj1, pobj2); default: break; } /* All other types would need same pointer to be true */ return C_DIFFER; }
/* Returns true if the item is in the container object */ PmReturn_t obj_isIn(pPmObj_t pobj, pPmObj_t pitem) { PmReturn_t retval = PM_RET_NO; pPmObj_t ptestItem; int16_t i; uint8_t c; switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_TUP: /* Iterate over tuple to find item */ for (i = 0; i < ((pPmTuple_t)pobj)->length; i++) { PM_RETURN_IF_ERROR(tuple_getItem(pobj, i, &ptestItem)); if (obj_compare(pitem, ptestItem) == C_SAME) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_STR: /* Raise a TypeError if item is not a string */ if ((OBJ_GET_TYPE(pitem) != OBJ_TYPE_STR)) { retval = PM_RET_EX_TYPE; break; } /* Empty string is alway present */ if (((pPmString_t)pitem)->length == 0) { retval = PM_RET_OK; break; } /* Raise a ValueError if the string is more than 1 char */ else if (((pPmString_t)pitem)->length != 1) { retval = PM_RET_EX_VAL; break; } /* Iterate over string to find char */ c = ((pPmString_t)pitem)->val[0]; for (i = 0; i < ((pPmString_t)pobj)->length; i++) { if (c == ((pPmString_t)pobj)->val[i]) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_LST: /* Iterate over list to find item */ for (i = 0; i < ((pPmList_t)pobj)->length; i++) { PM_RETURN_IF_ERROR(list_getItem(pobj, i, &ptestItem)); if (obj_compare(pitem, ptestItem) == C_SAME) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_DIC: /* Check if the item is one of the keys of the dict */ retval = dict_getItem(pobj, pitem, &ptestItem); if (retval == PM_RET_EX_KEY) { retval = PM_RET_NO; } break; default: retval = PM_RET_EX_TYPE; break; } return retval; }
PmReturn_t obj_print(pPmObj_t pobj, uint8_t is_expr_repr, uint8_t is_nested) { PmReturn_t retval = PM_RET_OK; C_ASSERT(pobj != C_NULL); /* Something gets printed unless it's None in an unnested expression */ if (!((OBJ_GET_TYPE(pobj) == OBJ_TYPE_NON) && is_expr_repr && !is_nested)) { gVmGlobal.somethingPrinted = C_TRUE; } switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_NON: if (!is_expr_repr || is_nested) { sli_puts((uint8_t *)"None"); } break; case OBJ_TYPE_INT: retval = int_print(pobj); break; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: retval = float_print(pobj); break; #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: retval = string_print(pobj, (is_expr_repr || is_nested)); break; case OBJ_TYPE_TUP: retval = tuple_print(pobj); break; case OBJ_TYPE_LST: retval = list_print(pobj); break; case OBJ_TYPE_DIC: retval = dict_print(pobj); break; case OBJ_TYPE_BOOL: sli_puts( (((pPmBoolean_t) pobj)->val == C_TRUE) ? (uint8_t *)"True" : (uint8_t *)"False"); break; case OBJ_TYPE_CLI: #ifdef HAVE_BYTEARRAY { pPmObj_t pobj2; retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, PM_NONE, (pPmObj_t *)&pobj2); if ((retval == PM_RET_OK) && (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_BYA)) { retval = bytearray_print(pobj2); break; } } #endif /* HAVE_BYTEARRAY */ case OBJ_TYPE_COB: case OBJ_TYPE_MOD: case OBJ_TYPE_CLO: case OBJ_TYPE_FXN: case OBJ_TYPE_CIM: case OBJ_TYPE_NIM: case OBJ_TYPE_NOB: case OBJ_TYPE_THR: case OBJ_TYPE_CIO: case OBJ_TYPE_MTH: case OBJ_TYPE_SQI: { uint8_t buf[17]; sli_puts((uint8_t *)"<obj type 0x"); sli_btoa16(OBJ_GET_TYPE(pobj), buf, sizeof(buf), C_TRUE); sli_puts(buf); sli_puts((uint8_t *)" @ 0x"); sli_ptoa16((intptr_t)pobj, buf, sizeof(buf), C_TRUE); sli_puts(buf); retval = plat_putByte('>'); break; } default: /* Otherwise raise a TypeError */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } return retval; }