From e17b3564ffefa0b30cfce779f64131e251df0d72 Mon Sep 17 00:00:00 2001 From: Greg Beeley Date: Fri, 7 Aug 2020 11:50:38 -0600 Subject: [PATCH 001/129] Sample money test --- centrallix/tests/test_sample_money.cmp | 1 + centrallix/tests/test_sample_money.to | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 centrallix/tests/test_sample_money.cmp create mode 100644 centrallix/tests/test_sample_money.to diff --git a/centrallix/tests/test_sample_money.cmp b/centrallix/tests/test_sample_money.cmp new file mode 100644 index 000000000..b1180a931 --- /dev/null +++ b/centrallix/tests/test_sample_money.cmp @@ -0,0 +1 @@ +Attribute [column_000]: money $5.50 diff --git a/centrallix/tests/test_sample_money.to b/centrallix/tests/test_sample_money.to new file mode 100644 index 000000000..0574b1e96 --- /dev/null +++ b/centrallix/tests/test_sample_money.to @@ -0,0 +1,2 @@ +##NAME Money Test 2 +query select $4 + 1.5 From c9313c8c5b10163204120fff48244828cd2f31f9 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 7 Aug 2020 20:30:41 -0600 Subject: [PATCH 002/129] A second set of test files to determine if I still appear as gbeeley when committing. --- centrallix/tests/test_sample_money_00.cmp | 1 + centrallix/tests/test_sample_money_00.to | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 centrallix/tests/test_sample_money_00.cmp create mode 100644 centrallix/tests/test_sample_money_00.to diff --git a/centrallix/tests/test_sample_money_00.cmp b/centrallix/tests/test_sample_money_00.cmp new file mode 100644 index 000000000..457fc5998 --- /dev/null +++ b/centrallix/tests/test_sample_money_00.cmp @@ -0,0 +1 @@ +Attribute [column000]: money $5.25 diff --git a/centrallix/tests/test_sample_money_00.to b/centrallix/tests/test_sample_money_00.to new file mode 100644 index 000000000..01b29ab09 --- /dev/null +++ b/centrallix/tests/test_sample_money_00.to @@ -0,0 +1,2 @@ +##NAME Sample Test Functionality +query select $4 + 1.25 From 2838eab782908a8e547f7b623bb9e166745c821b Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 10 Aug 2020 11:35:42 -0600 Subject: [PATCH 003/129] Change MoneyType struct to contain a single long long instead of WholePart/FractionPart --- centrallix-lib/include/datatypes.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/centrallix-lib/include/datatypes.h b/centrallix-lib/include/datatypes.h index da7b509d8..af78f5e46 100644 --- a/centrallix-lib/include/datatypes.h +++ b/centrallix-lib/include/datatypes.h @@ -56,8 +56,11 @@ typedef struct _SV /** Money structure **/ typedef struct _MN { - int WholePart; /* integer part = floor($amount) */ - unsigned short FractionPart; /* fract part = $amount - floor($amount) */ + /* Commented out old structure */ + //int WholePart; /* integer part = floor($amount) */ + //unsigned short FractionPart; /* fract part = $amount - floor($amount) */ + + long long MoneyValue; /* Fixed-point representation in 1/10000 of a dollar */ } MoneyType, *pMoneyType; From 204f78bb1e3a91041906ec97903f9c5861348fb3 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 10 Aug 2020 12:06:52 -0600 Subject: [PATCH 004/129] Commenting out direct MoneyType usage in centrallix/utility --- centrallix/utility/json_util.c | 4 ++-- centrallix/utility/obfuscate.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index ce4b678d3..0e800f987 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -235,12 +235,12 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) if (!strcmp(iter.key, "wholepart")) { has_whole = 1; - m->WholePart = json_object_get_int(iter.val); + //m->WholePart = json_object_get_int(iter.val); } else if (!strcmp(iter.key, "fractionpart")) { has_fraction = 1; - m->FractionPart = json_object_get_int(iter.val); + //m->FractionPart = json_object_get_int(iter.val); } else { diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index 75eb8cea0..98606dbf0 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1200,7 +1200,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname break; case DATA_T_MONEY: - iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); + //iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); if (strchr(param,'i')) dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); else @@ -1209,8 +1209,8 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = iv/10 + 1; dv = obf_internal_ObfuscateInteger(hash, hash_novalue, &bitcnt, iv); } - m.WholePart = floor(dv/100.0); - m.FractionPart = (dv - m.WholePart*100) * 100; + //m.WholePart = floor(dv/100.0); + //m.FractionPart = (dv - m.WholePart*100) * 100; dstval->Money = &m; break; From 4f3170d3a3ca18e5ceaae38887a899ed2c3f1587 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 10 Aug 2020 22:18:54 -0600 Subject: [PATCH 005/129] Commenting out direct MoneyType usage in centrallix/expression --- centrallix/expression/exp_compiler.c | 4 +- centrallix/expression/exp_evaluate.c | 62 +++++++++++++-------------- centrallix/expression/exp_functions.c | 28 ++++++------ centrallix/expression/exp_main.c | 6 +-- centrallix/expression/exp_params.c | 8 ++-- 5 files changed, 54 insertions(+), 54 deletions(-) diff --git a/centrallix/expression/exp_compiler.c b/centrallix/expression/exp_compiler.c index 613c87c3f..9bcbd9340 100644 --- a/centrallix/expression/exp_compiler.c +++ b/centrallix/expression/exp_compiler.c @@ -152,8 +152,8 @@ exp_internal_CompileExpression_r(pLxSession lxs, int level, pParamObjects objlis if (t == MLX_TOK_INTEGER) { i = mlxIntVal(lxs); - etmp->Types.Money.WholePart = i; - etmp->Types.Money.FractionPart = 0; + //etmp->Types.Money.WholePart = i; + //etmp->Types.Money.FractionPart = 0; } else { diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index e8abd254f..0d17affd6 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -226,9 +226,9 @@ expEvalDivide(pExpression tree, pParamObjects objlist) /** Check for divide by zero **/ if ((i1->DataType == DATA_T_INTEGER && i1->Integer == 0) || - (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0) || - (i1->DataType == DATA_T_MONEY && i1->Types.Money.WholePart == 0 && i1->Types.Money.FractionPart == 0)) - { + (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0)){ //|| + //(i1->DataType == DATA_T_MONEY && i1->Types.Money.WholePart == 0 && i1->Types.Money.FractionPart == 0)) + //{ mssError(1,"EXP","Attempted divide by zero"); return -1; } @@ -275,7 +275,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: - switch(i1->DataType) + /*Carl switch(i1->DataType) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; @@ -301,8 +301,8 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - tree->Types.Money.WholePart = m.WholePart / i; - tree->Types.Money.FractionPart = (10000*(m.WholePart % i) + m.FractionPart)/i; + //tree->Types.Money.WholePart = m.WholePart / i; + //tree->Types.Money.FractionPart = (10000*(m.WholePart % i) + m.FractionPart)/i; if (is_negative) { if (tree->Types.Money.FractionPart != 0) @@ -353,7 +353,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) tree->Types.Double = (double)mv / (double)mv2; } break; - } + }*/ break; default: @@ -428,8 +428,8 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - mv *= i0->Integer; + //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; + //mv *= i0->Integer; break; case DATA_T_STRING: tree->DataType = DATA_T_STRING; @@ -453,8 +453,8 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) { case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - mv *= i0->Types.Double; + //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; + //mv *= i0->Types.Double; break; default: tree->Types.Double = i0->Types.Double * objDataToDouble(i1->DataType, dptr); @@ -465,7 +465,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + /*Carl mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; switch(i1->DataType) { case DATA_T_INTEGER: @@ -483,7 +483,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) default: mssError(1,"EXP","Can only multiply a money data type by an integer or double"); return -1; - } + }*/ break; case DATA_T_STRING: @@ -505,14 +505,14 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) /** Common processing **/ if (tree->DataType == DATA_T_MONEY) { - tree->Types.Money.WholePart = mv/10000; + /*Carl tree->Types.Money.WholePart = mv/10000; mv = mv % 10000; if (mv < 0) { mv += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mv; + tree->Types.Money.FractionPart = mv;*/ } else if (tree->DataType == DATA_T_STRING) { @@ -605,7 +605,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Integer - i1->Types.Money.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Integer - i1->Types.Money.WholePart; if (i1->Types.Money.FractionPart == 0) { tree->Types.Money.FractionPart = 0; @@ -614,7 +614,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) { tree->Types.Money.WholePart--; tree->Types.Money.FractionPart = 10000 - i1->Types.Money.FractionPart; - } + }*/ break; default: tree->Integer = i0->Integer - objDataToInteger(i1->DataType, dptr, NULL); @@ -635,7 +635,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_DOUBLE; - tree->Types.Double = i0->Types.Double - (i1->Types.Money.WholePart + i1->Types.Money.FractionPart/10000.0); + //tree->Types.Double = i0->Types.Double - (i1->Types.Money.WholePart + i1->Types.Money.FractionPart/10000.0); break; default: tree->DataType = DATA_T_DOUBLE; @@ -649,16 +649,16 @@ expEvalMinus(pExpression tree, pParamObjects objlist) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Integer; - tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; + //tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Integer; + //tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; break; case DATA_T_DOUBLE: tree->DataType = DATA_T_DOUBLE; - tree->Types.Double = (i0->Types.Money.WholePart + i0->Types.Money.FractionPart/10000.0) - i1->Types.Double; + //tree->Types.Double = (i0->Types.Money.WholePart + i0->Types.Money.FractionPart/10000.0) - i1->Types.Double; break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Types.Money.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Types.Money.WholePart; tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - i1->Types.Money.FractionPart; if (tree->Types.Money.FractionPart >= 10000) { @@ -667,7 +667,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) else { tree->Types.Money.WholePart--; - } + }*/ break; default: if (objDataToMoney(i1->DataType, dptr, &m) < 0) @@ -676,12 +676,12 @@ expEvalMinus(pExpression tree, pParamObjects objlist) return -1; } tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Types.Money.WholePart - m.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - m.WholePart; tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - m.FractionPart; if (tree->Types.Money.FractionPart >= 10000) tree->Types.Money.FractionPart -= 10000; else - tree->Types.Money.WholePart--; + tree->Types.Money.WholePart--; */ break; } break; @@ -806,8 +806,8 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i1->Types.Money.WholePart + i0->Integer; - tree->Types.Money.FractionPart = i1->Types.Money.FractionPart; + //tree->Types.Money.WholePart = i1->Types.Money.WholePart + i0->Integer; + //tree->Types.Money.FractionPart = i1->Types.Money.FractionPart; break; default: @@ -843,13 +843,13 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: objDataToMoney(i1->DataType, dptr, &m); - tree->Types.Money.WholePart = i0->Types.Money.WholePart + m.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart + m.WholePart; tree->Types.Money.FractionPart = i0->Types.Money.FractionPart + m.FractionPart; if (tree->Types.Money.FractionPart >= 10000) { tree->Types.Money.FractionPart -= 10000; tree->Types.Money.WholePart++; - } + }*/ break; case DATA_T_DATETIME: @@ -1498,8 +1498,8 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) } else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { - tree->Types.Money.WholePart = tree->Integer; - tree->Types.Money.FractionPart = 0; + //tree->Types.Money.WholePart = tree->Integer; + //tree->Types.Money.FractionPart = 0; } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/expression/exp_functions.c b/centrallix/expression/exp_functions.c index 6d949640e..2ffa2ac4b 100644 --- a/centrallix/expression/exp_functions.c +++ b/centrallix/expression/exp_functions.c @@ -266,7 +266,7 @@ int exp_fn_abs(pExpression tree, pParamObjects objlist, pExpression i0, pExpress break; case DATA_T_MONEY: - if (i0->Types.Money.WholePart >= 0) + /*Carl if (i0->Types.Money.WholePart >= 0) { tree->Types.Money.WholePart = i0->Types.Money.WholePart; tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; @@ -283,7 +283,7 @@ int exp_fn_abs(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->Types.Money.WholePart = -i0->Types.Money.WholePart; tree->Types.Money.FractionPart = 0; } - } + }*/ break; default: @@ -1663,7 +1663,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre break; case DATA_T_MONEY: - mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; if (dec < 4) { mv = 1; @@ -1682,7 +1682,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre mt += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mt; + tree->Types.Money.FractionPart = mt;*/ break; } return 0; @@ -1936,7 +1936,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx break; case DATA_T_MONEY: - mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; if (dec < 4) { mv = 1; @@ -1951,7 +1951,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx mt += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mt; + tree->Types.Money.FractionPart = mt;*/ break; } return 0; @@ -2947,8 +2947,8 @@ int exp_fn_avg(pExpression tree, pParamObjects objlist, pExpression i0, pExpress sumexp->String[0] = '\0'; sumexp->Integer = 0; sumexp->Types.Double = 0; - sumexp->Types.Money.FractionPart = 0; - sumexp->Types.Money.WholePart = 0; + //sumexp->Types.Money.FractionPart = 0; + //sumexp->Types.Money.WholePart = 0; cntexp->Integer = 0; } @@ -3035,8 +3035,8 @@ int exp_fn_sum(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->AggExp->String[0] = '\0'; tree->AggExp->Integer = 0; tree->AggExp->Types.Double = 0; - tree->AggExp->Types.Money.FractionPart = 0; - tree->AggExp->Types.Money.WholePart = 0; + //tree->AggExp->Types.Money.FractionPart = 0; + //tree->AggExp->Types.Money.WholePart = 0; } expCopyValue(tree->AggExp, (pExpression)(tree->AggExp->Children.Items[0]), 1); expCopyValue(i0, (pExpression)(tree->AggExp->Children.Items[1]), 0); @@ -3098,8 +3098,8 @@ int exp_fn_max(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->String[0] = '\0'; tree->Integer = 0; tree->Types.Double = 0; - tree->Types.Money.FractionPart = 0; - tree->Types.Money.WholePart = 0; + //tree->Types.Money.FractionPart = 0; + //tree->Types.Money.WholePart = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); @@ -3160,8 +3160,8 @@ int exp_fn_min(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->Alloc = 0; tree->Integer = 0; tree->Types.Double = 0; - tree->Types.Money.FractionPart = 0; - tree->Types.Money.WholePart = 0; + //tree->Types.Money.FractionPart = 0; + //tree->Types.Money.WholePart = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); diff --git a/centrallix/expression/exp_main.c b/centrallix/expression/exp_main.c index 79c2dcf02..0bdbcd0a3 100644 --- a/centrallix/expression/exp_main.c +++ b/centrallix/expression/exp_main.c @@ -523,7 +523,7 @@ exp_internal_DumpExpression_r(pExpression this, int level) case EXPR_N_INTEGER: printf("INTEGER = %d", this->Integer); break; case EXPR_N_STRING: printf("STRING = <%s>", this->String); break; case EXPR_N_DOUBLE: printf("DOUBLE = %.2f", this->Types.Double); break; - case EXPR_N_MONEY: printf("MONEY = %d.%4.4d", this->Types.Money.WholePart, this->Types.Money.FractionPart); break; + case EXPR_N_MONEY: printf("MONEY");/*printf("MONEY = %d.%4.4d", this->Types.Money.WholePart, this->Types.Money.FractionPart);*/ break; case EXPR_N_DATETIME: printf("DATETIME = %s", objDataToStringTmp(DATA_T_DATETIME,&(this->Types.Date), 0)); break; case EXPR_N_PLUS: printf("PLUS"); break; case EXPR_N_MULTIPLY: printf("MULTIPLY"); break; @@ -863,8 +863,8 @@ expCompareExpressionValues(pExpression exp1, pExpression exp2) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DOUBLE && exp1->Types.Double != exp2->Types.Double) return 0; - if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && (exp1->Types.Money.WholePart != exp2->Types.Money.WholePart || exp1->Types.Money.FractionPart != exp2->Types.Money.FractionPart)) - return 0; + //if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && (exp1->Types.Money.WholePart != exp2->Types.Money.WholePart || exp1->Types.Money.FractionPart != exp2->Types.Money.FractionPart)) + //return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DATETIME && (exp1->Types.Date.Part.Second != exp2->Types.Date.Part.Second || exp1->Types.Date.Part.Minute != exp2->Types.Date.Part.Minute || exp1->Types.Date.Part.Hour != exp2->Types.Date.Part.Hour || exp1->Types.Date.Part.Day != exp2->Types.Date.Part.Day || exp1->Types.Date.Part.Month != exp2->Types.Date.Part.Month || exp1->Types.Date.Part.Year != exp2->Types.Date.Part.Year)) return 0; diff --git a/centrallix/expression/exp_params.c b/centrallix/expression/exp_params.c index fc0c4f984..83fa66167 100644 --- a/centrallix/expression/exp_params.c +++ b/centrallix/expression/exp_params.c @@ -602,14 +602,14 @@ exp_internal_ResetAggregates(pExpression this, int reset_id, int level) { this->AggExp->Integer = 0; this->AggExp->Types.Double = 0; - this->AggExp->Types.Money.WholePart = 0; - this->AggExp->Types.Money.FractionPart = 0; + //this->AggExp->Types.Money.WholePart = 0; + //this->AggExp->Types.Money.FractionPart = 0; this->Flags |= EXPR_F_AGGLOCKED; } this->Integer = 0; this->Types.Double = 0; - this->Types.Money.WholePart = 0; - this->Types.Money.FractionPart = 0; + //this->Types.Money.WholePart = 0; + //this->Types.Money.FractionPart = 0; if (!strcmp(this->Name,"count")) { this->Flags &= ~EXPR_F_NULL; From 016e2a77b40d5154333ef1a97d8875d6288048f5 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 11 Aug 2020 11:15:15 -0600 Subject: [PATCH 006/129] Commenting out direct MoneyType usage --- centrallix/netdrivers/net_http_rest.c | 4 +- centrallix/objectsystem/obj_datatypes.c | 77 +++++++++++++++---------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index c236c4da2..ae9546dd0 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -114,10 +114,10 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty break; case DATA_T_MONEY: - nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", + /*Carl nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", od.Money->WholePart, od.Money->FractionPart - ); + );*/ break; default: diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 6de7b1f31..581afee1f 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -475,14 +475,14 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (tens_multiplier > 0) tens_multiplier /= 10; /** Special handling of zeros **/ - if (m->WholePart == 0 && m->FractionPart == 0 && zero_type != 0) + /* Carl if (m->WholePart == 0 && m->FractionPart == 0 && zero_type != 0) { if (strlen(zero_strings[zero_type]) >= length) return -1; else strcpy(str, zero_strings[zero_type]); return 0; - } + }*/ xsInit(&xs); @@ -490,7 +490,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - if (m->WholePart >= 0 || m->FractionPart == 0) + /*Carl if (m->WholePart >= 0 || m->FractionPart == 0) { print_whole = m->WholePart; print_fract = m->FractionPart; @@ -501,10 +501,10 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) print_fract = 10000 - m->FractionPart; } orig_print_whole = m->WholePart; - if (print_whole < 0) print_whole = -print_whole; + if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ - while(*fmt) + /*Carl while(*fmt) { if (automatic_sign) { @@ -513,7 +513,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) *(str++) = '-'; /*else *(str++) = ' ';*/ - } + /*Carl } switch(*fmt) { case '$': @@ -557,7 +557,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) else { /** Replace comma with space if no digits and surrounded by placeholders **/ - if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) + /*Carl if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) { xsConcatenate(&xs," ",1); } @@ -610,7 +610,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) break; } fmt++; - } + }*/ if(strlen(xs.String) < length) { @@ -801,11 +801,14 @@ objDataToInteger(int data_type, void* data_ptr, char* format) v = (int)(*(double*)data_ptr); break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr; + /*Carl m = (pMoneyType)data_ptr; if (m->FractionPart==0 || m->WholePart>=0) v = m->WholePart; else - v = m->WholePart + 1; + v = m->WholePart + 1;*/ + + //Adding a value for v so this function does not return an uninitialized variable + v = 2; break; case DATA_T_INTVEC: @@ -840,7 +843,7 @@ objDataToDouble(int data_type, void* data_ptr) { case DATA_T_INTEGER: v = *(int*)data_ptr; break; case DATA_T_STRING: v = strtod((char*)data_ptr, NULL); break; - case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->WholePart + (m->FractionPart/10000.0); break; + case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = 2;/*Carl m->WholePart + (m->FractionPart/10000.0);*/ break; case DATA_T_DOUBLE: v = *(double*)data_ptr; break; default: v = 0.0; break; } @@ -1409,7 +1412,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* tptr; /** Select the correct type. **/ - switch(data_type) + /*Carl switch(data_type) { case DATA_T_STRING: cxssGetVariable("mfmt", &fmt, obj_default_money_fmt); @@ -1420,7 +1423,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) if (strlen(ptr) < sizeof(tmpbuf)) { /** strip commas (or periods, if in intl format) **/ - tptr = tmpbuf; + /*Carl tptr = tmpbuf; while(*ptr) { if (*ptr != (intl_format?'.':',')) @@ -1495,7 +1498,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) m->WholePart = ((pMoneyType)data_ptr)->WholePart; m->FractionPart = ((pMoneyType)data_ptr)->FractionPart; break; - } + }*/ return 0; } @@ -1573,10 +1576,13 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr_2; + /*Carl m = (pMoneyType)data_ptr_2; if (m->WholePart > intval) cmp_value = -1; else if (m->WholePart < intval) cmp_value = 1; - else cmp_value = m->FractionPart?-1:0; + else cmp_value = m->FractionPart?-1:0;*/ + + //Adding an arbitrary value for cmp_value so no reference uninitialized var + cmp_value = 2; break; case DATA_T_INTVEC: @@ -1615,11 +1621,14 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); + /*Carl objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); m = (pMoneyType)data_ptr_2; if (m_v.WholePart > m->WholePart) cmp_value = 1; else if (m_v.WholePart < m->WholePart) cmp_value = -1; - else cmp_value = m_v.FractionPart - m->FractionPart; + else cmp_value = m_v.FractionPart - m->FractionPart;*/ + + //Arbitrary value for cmp_value + cmp_value = 2; break; case DATA_T_DOUBLE: @@ -1672,11 +1681,14 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr_2; + /*Carl m = (pMoneyType)data_ptr_2; dblval = m->WholePart + (m->FractionPart/10000.0); if (dblval == *(double*)data_ptr_1) cmp_value = 0; else if (dblval > *(double*)data_ptr_1) cmp_value = -1; - else cmp_value = 1; + else cmp_value = 1;*/ + + //Arbitrary value + cmp_value = 2; break; case DATA_T_STRINGVEC: @@ -1762,7 +1774,7 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr_2; + /*Carl m = (pMoneyType)data_ptr_2; if (iv->nIntegers != 2) { err = 1; @@ -1772,7 +1784,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt if (m->WholePart > iv->Integers[0]) cmp_value = -1; else if (m->WholePart < iv->Integers[0]) cmp_value = 1; else cmp_value = iv->Integers[1] - m->FractionPart; - } + }*/ + //Arbitrary cmp value + cmp_value = 2; break; default: @@ -1821,9 +1835,12 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt switch(data_type_2) { case DATA_T_MONEY: - if (m->WholePart > ((pMoneyType)data_ptr_2)->WholePart) cmp_value = 1; + /*Carl if (m->WholePart > ((pMoneyType)data_ptr_2)->WholePart) cmp_value = 1; else if (m->WholePart < ((pMoneyType)data_ptr_2)->WholePart) cmp_value = -1; - else cmp_value = m->FractionPart - ((pMoneyType)data_ptr_2)->FractionPart; + else cmp_value = m->FractionPart - ((pMoneyType)data_ptr_2)->FractionPart;*/ + + //Arbitrary cmp value + cmp_value = 2; break; default: @@ -1898,7 +1915,7 @@ objDataToWords(int data_type, void* data_ptr) } else if (data_type == DATA_T_MONEY) { - m = (pMoneyType)data_ptr; + /*Carl m = (pMoneyType)data_ptr; if (m->WholePart < 0) { if (m->FractionPart == 0) @@ -1917,7 +1934,7 @@ objDataToWords(int data_type, void* data_ptr) { integer_part = m->WholePart; fraction_part = m->FractionPart; - } + }*/ } else { @@ -1989,7 +2006,7 @@ objDataToWords(int data_type, void* data_ptr) } /** Now take care of cents if a money type **/ - if (data_type == DATA_T_MONEY) + /*Carl if (data_type == DATA_T_MONEY) { if (fraction_part == 0) { @@ -2000,7 +2017,7 @@ objDataToWords(int data_type, void* data_ptr) sprintf(nbuf, "And %2.2ld/100 ", fraction_part/100); xsConcatenate(&tmpbuf, nbuf, -1); } - } + }*/ return tmpbuf.String; } @@ -2185,10 +2202,10 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x80000000 to convert to Offset Zero form. **/ - ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); + /*Carl ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); ((unsigned short*)tmp_buf)[2] = htons(exp->Types.Money.FractionPart); *item = (char*)(tmp_buf); - *itemlen = 6; + *itemlen = 6;*/ break; case DATA_T_DOUBLE: From 19d8480d4c6069a8e1ab75c786b5230d0662abda Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 12:03:27 -0600 Subject: [PATCH 007/129] Converted obj_internal_FormatMoney to use the new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 581afee1f..2a7ba030a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -475,14 +475,14 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (tens_multiplier > 0) tens_multiplier /= 10; /** Special handling of zeros **/ - /* Carl if (m->WholePart == 0 && m->FractionPart == 0 && zero_type != 0) + if (m->MoneyValue == 0 && zero_type != 0) { if (strlen(zero_strings[zero_type]) >= length) return -1; else strcpy(str, zero_strings[zero_type]); return 0; - }*/ + } xsInit(&xs); @@ -490,21 +490,21 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - /*Carl if (m->WholePart >= 0 || m->FractionPart == 0) + if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) { - print_whole = m->WholePart; - print_fract = m->FractionPart; + print_whole = m->MoneyValue/10000; + print_fract = m->MoneyValue%10000; } else { - print_whole = m->WholePart + 1; - print_fract = 10000 - m->FractionPart; + print_whole = m->MoneyValue/10000 + 1; + print_fract = 10000 - m->MoneyValue%10000; } - orig_print_whole = m->WholePart; - if (print_whole < 0) print_whole = -print_whole;*/ + orig_print_whole = m->MoneyValue/10000; + if (print_whole < 0) print_whole = -print_whole; /** Ok, start generating the thing. **/ - /*Carl while(*fmt) + while(*fmt) { if (automatic_sign) { @@ -513,29 +513,29 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) *(str++) = '-'; /*else *(str++) = ' ';*/ - /*Carl } + } switch(*fmt) { case '$': *(str++) = '$'; break; - case ' ': - case '*': + case ' ': + case '*': case '0': case '^': case '#': if (in_decimal_part) { - d = (print_fract/tens_multiplier)%10; - tens_multiplier /= 10; - } + d = (print_fract/tens_multiplier)%10; + tens_multiplier /= 10; + } else { - d = print_whole/tens_multiplier; - print_whole -= d*tens_multiplier; - tens_multiplier /= 10; - } + d = print_whole/tens_multiplier; + print_whole -= d*tens_multiplier; + tens_multiplier /= 10; + } if (d != 0 || *fmt == '0' || *fmt == '^') suppressing_zeros = 0; if (suppressing_zeros) { @@ -557,7 +557,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) else { /** Replace comma with space if no digits and surrounded by placeholders **/ - /*Carl if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) + if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) { xsConcatenate(&xs," ",1); } @@ -610,7 +610,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) break; } fmt++; - }*/ + } if(strlen(xs.String) < length) { From 114334dbc71b8b58ad06cdcbfb2fc5a59bf9a48e Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 12:31:54 -0600 Subject: [PATCH 008/129] Converted objDataToDouble to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 2a7ba030a..6b768398b 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -801,14 +801,11 @@ objDataToInteger(int data_type, void* data_ptr, char* format) v = (int)(*(double*)data_ptr); break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr; + m = (pMoneyType)data_ptr; if (m->FractionPart==0 || m->WholePart>=0) v = m->WholePart; else - v = m->WholePart + 1;*/ - - //Adding a value for v so this function does not return an uninitialized variable - v = 2; + v = m->WholePart + 1; break; case DATA_T_INTVEC: @@ -843,7 +840,7 @@ objDataToDouble(int data_type, void* data_ptr) { case DATA_T_INTEGER: v = *(int*)data_ptr; break; case DATA_T_STRING: v = strtod((char*)data_ptr, NULL); break; - case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = 2;/*Carl m->WholePart + (m->FractionPart/10000.0);*/ break; + case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); break; case DATA_T_DOUBLE: v = *(double*)data_ptr; break; default: v = 0.0; break; } From 065399fd717f99ea5c3d058e9da3a98abc7ed526 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 13:18:04 -0600 Subject: [PATCH 009/129] Converted objDataCompare to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 52 +++++++++---------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 6b768398b..b5f0b1b93 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1573,13 +1573,10 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr_2; - if (m->WholePart > intval) cmp_value = -1; - else if (m->WholePart < intval) cmp_value = 1; - else cmp_value = m->FractionPart?-1:0;*/ - - //Adding an arbitrary value for cmp_value so no reference uninitialized var - cmp_value = 2; + m = (pMoneyType)data_ptr_2; + if (m->MoneyValue/10000 > intval) cmp_value = -1; + else if (m->MoneyValue/10000 < intval) cmp_value = 1; + else cmp_value = m->MoneyValue%10000?-1:0; break; case DATA_T_INTVEC: @@ -1618,14 +1615,11 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); + objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); m = (pMoneyType)data_ptr_2; - if (m_v.WholePart > m->WholePart) cmp_value = 1; - else if (m_v.WholePart < m->WholePart) cmp_value = -1; - else cmp_value = m_v.FractionPart - m->FractionPart;*/ - - //Arbitrary value for cmp_value - cmp_value = 2; + if (m_v.MoneyValue/10000 > m->MoneyValue/10000) cmp_value = 1; + else if (m_v.MoneyValue/10000 < m->MoneyValue/10000) cmp_value = -1; + else cmp_value = m_v.MoneyValue%10000 - m->MoneyValue%10000; break; case DATA_T_DOUBLE: @@ -1678,14 +1672,11 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr_2; - dblval = m->WholePart + (m->FractionPart/10000.0); + m = (pMoneyType)data_ptr_2; + dblval = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); if (dblval == *(double*)data_ptr_1) cmp_value = 0; else if (dblval > *(double*)data_ptr_1) cmp_value = -1; - else cmp_value = 1;*/ - - //Arbitrary value - cmp_value = 2; + else cmp_value = 1; break; case DATA_T_STRINGVEC: @@ -1771,19 +1762,17 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr_2; + m = (pMoneyType)data_ptr_2; if (iv->nIntegers != 2) { err = 1; } else { - if (m->WholePart > iv->Integers[0]) cmp_value = -1; - else if (m->WholePart < iv->Integers[0]) cmp_value = 1; - else cmp_value = iv->Integers[1] - m->FractionPart; - }*/ - //Arbitrary cmp value - cmp_value = 2; + if (m->MoneyValue/10000 > iv->Integers[0]) cmp_value = -1; + else if (m->MoneyValue/10000 < iv->Integers[0]) cmp_value = 1; + else cmp_value = iv->Integers[1] - m->MoneyValue%10000; + } break; default: @@ -1832,12 +1821,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt switch(data_type_2) { case DATA_T_MONEY: - /*Carl if (m->WholePart > ((pMoneyType)data_ptr_2)->WholePart) cmp_value = 1; - else if (m->WholePart < ((pMoneyType)data_ptr_2)->WholePart) cmp_value = -1; - else cmp_value = m->FractionPart - ((pMoneyType)data_ptr_2)->FractionPart;*/ - - //Arbitrary cmp value - cmp_value = 2; + if (m->MoneyValue/10000 > ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = 1; + else if (m->MoneyValue/10000 < ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = -1; + else cmp_value = m->MoneyValue%10000 - ((pMoneyType)data_ptr_2)->MoneyValue%10000; break; default: From c50ffc9c1cd2aa613f5dc04966dc885ba0496583 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 13:29:50 -0600 Subject: [PATCH 010/129] Converted objDataToWords to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index b5f0b1b93..3913acd30 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1898,26 +1898,26 @@ objDataToWords(int data_type, void* data_ptr) } else if (data_type == DATA_T_MONEY) { - /*Carl m = (pMoneyType)data_ptr; - if (m->WholePart < 0) + m = (pMoneyType)data_ptr; + if (m->MoneyValue/10000 < 0) { - if (m->FractionPart == 0) + if (m->MoneyValue%10000 == 0) { - integer_part = -m->WholePart; + integer_part = -m->MoneyValue/10000; fraction_part = 0; } else { - integer_part = (-m->WholePart) - 1; - fraction_part = 10000 - m->FractionPart; + integer_part = (-m->MoneyValue/10000) - 1; + fraction_part = 10000 - m->MoneyValue%10000; } xsConcatenate(&tmpbuf, "Negative ", -1); } else { - integer_part = m->WholePart; - fraction_part = m->FractionPart; - }*/ + integer_part = m->MoneyValue/10000; + fraction_part = m->MoneyValue%10000; + } } else { @@ -1989,7 +1989,7 @@ objDataToWords(int data_type, void* data_ptr) } /** Now take care of cents if a money type **/ - /*Carl if (data_type == DATA_T_MONEY) + if (data_type == DATA_T_MONEY) { if (fraction_part == 0) { @@ -2000,7 +2000,7 @@ objDataToWords(int data_type, void* data_ptr) sprintf(nbuf, "And %2.2ld/100 ", fraction_part/100); xsConcatenate(&tmpbuf, nbuf, -1); } - }*/ + } return tmpbuf.String; } From a04da4979e5cfeab8830e37fe8ea30be8d3f18a1 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 15:03:29 -0600 Subject: [PATCH 011/129] Converted objDataToInteger to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 3913acd30..1ced03017 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -802,10 +802,10 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - if (m->FractionPart==0 || m->WholePart>=0) - v = m->WholePart; + if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) + v = m->MoneyValue/10000; else - v = m->WholePart + 1; + v = m->MoneyValue/10000 + 1; break; case DATA_T_INTVEC: From 754bbf946d8e94353b255a5ff4f8422d5b8b8e83 Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 12 Aug 2020 17:08:15 -0600 Subject: [PATCH 012/129] Basic testrunner file for running arbitrary Centrallix functions --- .gitignore | 1 + centrallix/Makefile.in | 3 +++ centrallix/temp_testrunner.c | 17 +++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 centrallix/temp_testrunner.c diff --git a/.gitignore b/.gitignore index fc4513857..b25dc9924 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ centrallix/man/test_obj.1.gz centrallix/osdrivers/*.so centrallix/netdrivers/*.so centrallix/test_obj +centrallix/temp_testrunner centrallix/test_prt centrallix-os/apps/kardia centrallix-lib/include/cxlib diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index f4e2566c9..94047aee6 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -601,6 +601,9 @@ jsengine: $(JSVM) test_obj: test_obj.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) $(CC) centrallix.o test_obj.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o test_obj $(LIBS) +temp_testrunner: temp_testrunner.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) + $(CC) centrallix.o temp_testrunner.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o temp_testrunner $(LIBS) + test_prt: test_prt.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) $(CC) centrallix.o test_prt.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o test_prt $(LIBS) diff --git a/centrallix/temp_testrunner.c b/centrallix/temp_testrunner.c new file mode 100644 index 000000000..79f98ae5e --- /dev/null +++ b/centrallix/temp_testrunner.c @@ -0,0 +1,17 @@ +#include "cxlib/mtask.h" +#include "obj.h" +#include + +void +start(void* v) +{ + MoneyType test = {1, 1}; + printf("%s\n", objFormatMoneyTmp(&test, NULL)); +} + +int +main() +{ + mtInitialize(0, start); + return 0; +} From 9c4b38789af568613769bdbe1bf7d1022c655f95 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 14:36:11 -0600 Subject: [PATCH 013/129] Basic system for native C tests in /centrallix using assert --- centrallix/Makefile.in | 42 +++++++++++---------------- centrallix/tests/t_driver.c | 22 +++++++++----- centrallix/tests/test_00baseline_04.c | 3 +- centrallix/tests/test_00baseline_05.c | 3 +- centrallix/tests/test_00baseline_06.c | 3 +- centrallix/tests/test_00baseline_07.c | 3 +- 6 files changed, 40 insertions(+), 36 deletions(-) diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index 94047aee6..4b1c51a15 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -526,8 +526,8 @@ tests/centrallix.conf-test: tests/centrallix.conf-test.in RUNLIBDIR=$${LIBDIR#$(builddir)}; \ $(SED) -e "s|##SYSCONFDIR##|$$RUNSYSCONFDIR|g" -e "s|##LIBDIR##|$$RUNLIBDIR|g" -e "s|##LOGMETHOD##|@LOGMETHOD@|g" tests/centrallix.conf-test.in > tests/centrallix.conf-test -tests/test_%.bin: tests/test_%.o .testdepend - $(CC) $< tests/t_driver.c $$(sed -n 's#^$@: ##p' < .testdepend) $(LIBS) -o $@ +tests/test_%.bin: tests/test_%.o tests/t_driver.c centrallix.o $(V3LSOBJS) $(STATIC_LIBS) + $(CC) $< tests/t_driver.c centrallix.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o $@ $(LIBS) test: tests/centrallix.conf-test $(TOTESTDEPS) $(TOTESTFILES) $(CBTESTFILES) @printf "%-62.62s %s\n" "Test Name" "Stat" @@ -540,7 +540,7 @@ test: tests/centrallix.conf-test $(TOTESTDEPS) $(TOTESTFILES) $(CBTESTFILES) CGREEN=$$(/usr/bin/tput setaf 2); \ CBOLD=$$(/usr/bin/tput bold); \ CNORM=$$(/usr/bin/tput sgr0); \ - if [ "$${TOFILE%.to}" != "$${TOFILE}" ]; then \ + if [ "$${TOFILE%.to}" != "$${TOFILE}" ]; then \ TOBASE="$${TOFILE%.to}"; \ TONAME=$$(sed -n 's/^##NAME //p' < $$TOBASE.to); \ TOUNDO=$$(sed -n 's/^##UNDO //p' < $$TOBASE.to); \ @@ -551,31 +551,23 @@ test: tests/centrallix.conf-test $(TOTESTDEPS) $(TOTESTFILES) $(CBTESTFILES) echo -n "$$CBLUE"; \ "$(bindir)/test_obj" -q -c tests/centrallix.conf-test -u cxtest -p cxtestpass -f "$$PWD/$$TOBASE.to" -o "$$PWD/$$TOBASE.out" -i 4 2>&1 | grep -v 'Notice: Max thread count reduced from' | sed 's/^/ /'; \ RET="$${PIPESTATUS[0]}"; \ + [ -f "$$CXOS/$$TOUNDOBAK" ] && /bin/mv -f "$$CXOS/$$TOUNDOBAK" "$$CXOS/$$TOUNDO"; \ + if [ "$$RET" -eq 142 ]; then \ + printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CRED$${CBOLD}LOCKUP$$CNORM"; \ + elif [ "$$RET" -gt 120 ]; then \ + printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CRED$${CBOLD}CRASH$$CNORM"; \ + elif cmp -s "$$TOBASE.out" "$$TOBASE.cmp"; then \ + printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CGREEN$${CBOLD}Pass$$CNORM"; \ + /bin/rm -f "$$PWD/$$TOBASE.out"; \ + else \ + echo -n "$$CRED"; \ + diff --label EXPECTED -U0 -N "$$TOBASE.cmp" "$$TOBASE.out" | sed 's/^/ /'; \ + printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CRED$${CBOLD}FAIL$$CNORM"; \ + fi; \ else \ TOBASE="$${TOFILE%.bin}"; \ - TONAME=$$(sed -n 's/^\/\/NAME //p' < $$TOBASE.c); \ - TOUNDO=$$(sed -n 's/^\/\/UNDO //p' < $$TOBASE.c); \ - TOUNDOBAK="$${TOUNDO}-$$RANDOM-$$RANDOM"; \ - TOSIMPLE="$${TOBASE#tests/test_}"; \ - /bin/rm -f "$$PWD/$$TOBASE.out"; \ - [ -f "$$CXOS/$$TOUNDO" ] && /bin/cp -a "$$CXOS/$$TOUNDO" "$$CXOS/$$TOUNDOBAK"; \ - echo -n "$$CBLUE"; \ ulimit -s 16384; \ - ./$$TOBASE.bin 2>&1 > $$TOBASE.out | grep -v 'Notice: Max thread count reduced from' | sed 's/^/ /'; \ - RET="$${PIPESTATUS[0]}"; \ - fi; \ - [ -f "$$CXOS/$$TOUNDOBAK" ] && /bin/mv -f "$$CXOS/$$TOUNDOBAK" "$$CXOS/$$TOUNDO"; \ - if [ "$$RET" -eq 142 ]; then \ - printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CRED$${CBOLD}LOCKUP$$CNORM"; \ - elif [ "$$RET" -gt 120 ]; then \ - printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CRED$${CBOLD}CRASH$$CNORM"; \ - elif cmp -s "$$TOBASE.out" "$$TOBASE.cmp"; then \ - printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CGREEN$${CBOLD}Pass$$CNORM"; \ - /bin/rm -f "$$PWD/$$TOBASE.out"; \ - else \ - echo -n "$$CRED"; \ - diff --label EXPECTED -U0 -N "$$TOBASE.cmp" "$$TOBASE.out" | sed 's/^/ /'; \ - printf "$$CNORM%-62.62s %s\n" "$$TOSIMPLE $$TONAME" "$$CRED$${CBOLD}FAIL$$CNORM"; \ + ./$$TOBASE.bin; \ fi; \ fi \ done diff --git a/centrallix/tests/t_driver.c b/centrallix/tests/t_driver.c index cdd88b300..7d63227b6 100644 --- a/centrallix/tests/t_driver.c +++ b/centrallix/tests/t_driver.c @@ -25,23 +25,31 @@ /************************************************************************/ -long long test(void); +#define RED "\033[1m\x1B[31m" +#define GREEN "\033[1m\x1B[32m" +#define RESET "\x1B[0m" + +long long test(char**); + +char * test_name = "?"; void segv_handler(int v) { - exit(121); + printf("%-62.62s " RED "CRASH\n" RESET, test_name); + exit(0); } void abort_handler(int v) { - printf("FAIL\n"); + printf("%-62.62s " RED "ABORT\n" RESET, test_name); exit(0); } void alarm_handler(int v) { - exit(142); + printf("%-62.62s " RED "LOCKUP\n" RESET, test_name); + exit(0); } void @@ -57,13 +65,13 @@ start(void* v) alarm(4); times(&t); start = t.tms_utime + t.tms_stime + t.tms_cutime + t.tms_cstime; - rval = test(); + rval = test(&test_name); times(&t); end = t.tms_utime + t.tms_stime + t.tms_cutime + t.tms_cstime; if (rval < 0) - printf("FAIL\n"); + printf("%-62.62s " RED "FAIL\n" RESET, test_name); else - printf("Pass\n"); + printf("%-62.62s " GREEN "Pass\n" RESET, test_name); return; } diff --git a/centrallix/tests/test_00baseline_04.c b/centrallix/tests/test_00baseline_04.c index a230f6175..fa3fb2e36 100644 --- a/centrallix/tests/test_00baseline_04.c +++ b/centrallix/tests/test_00baseline_04.c @@ -1,7 +1,8 @@ //NAME Native C ** SHOULD Pass ** long long -test(void) +test(char** name) { + *name = "Native C ** SHOULD Pass **"; return 0; } diff --git a/centrallix/tests/test_00baseline_05.c b/centrallix/tests/test_00baseline_05.c index 9ff547115..948217b73 100644 --- a/centrallix/tests/test_00baseline_05.c +++ b/centrallix/tests/test_00baseline_05.c @@ -1,7 +1,8 @@ //NAME Native C ** SHOULD FAIL ** long long -test(void) +test(char** name) { + *name = "Native C ** SHOULD FAIL **"; return -1; } diff --git a/centrallix/tests/test_00baseline_06.c b/centrallix/tests/test_00baseline_06.c index 5e9f9a4e9..19ed5a9de 100644 --- a/centrallix/tests/test_00baseline_06.c +++ b/centrallix/tests/test_00baseline_06.c @@ -3,8 +3,9 @@ #include long long -test(void) +test(char** name) { + *name = "Native C ** SHOULD CRASH **"; raise(SIGSEGV); return 0; } diff --git a/centrallix/tests/test_00baseline_07.c b/centrallix/tests/test_00baseline_07.c index 555351d6e..7106529b4 100644 --- a/centrallix/tests/test_00baseline_07.c +++ b/centrallix/tests/test_00baseline_07.c @@ -1,8 +1,9 @@ //NAME Native C ** SHOULD LOCKUP ** long long -test(void) +test(char** name) { + *name = "Native C ** SHOULD LOCKUP **"; while(1); return 0; } From 3db48cf855ec9f3b8db428322aee64cc6eac3ae1 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 14:46:23 -0600 Subject: [PATCH 014/129] Display native C test output in blue --- centrallix/Makefile.in | 3 ++- centrallix/tests/t_driver.c | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index 4b1c51a15..3c2206dfd 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -567,7 +567,8 @@ test: tests/centrallix.conf-test $(TOTESTDEPS) $(TOTESTFILES) $(CBTESTFILES) else \ TOBASE="$${TOFILE%.bin}"; \ ulimit -s 16384; \ - ./$$TOBASE.bin; \ + echo -n "$$CBLUE"; \ + ./$$TOBASE.bin 2>&1; \ fi; \ fi \ done diff --git a/centrallix/tests/t_driver.c b/centrallix/tests/t_driver.c index 7d63227b6..f7f27c1ab 100644 --- a/centrallix/tests/t_driver.c +++ b/centrallix/tests/t_driver.c @@ -36,19 +36,19 @@ char * test_name = "?"; void segv_handler(int v) { - printf("%-62.62s " RED "CRASH\n" RESET, test_name); + printf(RESET "%-62.62s " RED "CRASH\n" RESET, test_name); exit(0); } void abort_handler(int v) { - printf("%-62.62s " RED "ABORT\n" RESET, test_name); + printf(RESET "%-62.62s " RED "ABORT\n" RESET, test_name); exit(0); } void alarm_handler(int v) { - printf("%-62.62s " RED "LOCKUP\n" RESET, test_name); + printf(RESET "%-62.62s " RED "LOCKUP\n" RESET, test_name); exit(0); } @@ -69,9 +69,9 @@ start(void* v) times(&t); end = t.tms_utime + t.tms_stime + t.tms_cutime + t.tms_cstime; if (rval < 0) - printf("%-62.62s " RED "FAIL\n" RESET, test_name); + printf(RESET "%-62.62s " RED "FAIL\n" RESET, test_name); else - printf("%-62.62s " GREEN "Pass\n" RESET, test_name); + printf(RESET "%-62.62s " GREEN "Pass\n" RESET, test_name); return; } From 713863a8327387efc99fa0b04c0b1735444c8ef9 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 15:13:38 -0600 Subject: [PATCH 015/129] Removing old native C testing framework --- .gitignore | 1 - centrallix/Makefile.in | 7 ------- centrallix/tests/test_00baseline_04.cmp | 1 - centrallix/tests/test_00baseline_04.deps | 0 centrallix/tests/test_00baseline_05.cmp | 1 - centrallix/tests/test_00baseline_05.deps | 0 centrallix/tests/test_00baseline_06.cmp | 1 - centrallix/tests/test_00baseline_06.deps | 0 centrallix/tests/test_00baseline_07.cmp | 1 - centrallix/tests/test_00baseline_07.deps | 0 10 files changed, 12 deletions(-) delete mode 100644 centrallix/tests/test_00baseline_04.cmp delete mode 100644 centrallix/tests/test_00baseline_04.deps delete mode 100644 centrallix/tests/test_00baseline_05.cmp delete mode 100644 centrallix/tests/test_00baseline_05.deps delete mode 100644 centrallix/tests/test_00baseline_06.cmp delete mode 100644 centrallix/tests/test_00baseline_06.deps delete mode 100644 centrallix/tests/test_00baseline_07.cmp delete mode 100644 centrallix/tests/test_00baseline_07.deps diff --git a/.gitignore b/.gitignore index b25dc9924..dc66b6971 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .depend -.testdepend Makefile config.log config.status diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index 3c2206dfd..087525fa6 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -672,11 +672,6 @@ depend: .depend @makedepend -o.o -Yinclude -I . -I @CXINCDIR@ -f - *.c */*.c */*/*.c >.depend 2>/dev/null @makedepend -o.so -Yinclude -I . -I @CXINCDIR@ -f - *.c */*.c */*/*.c >>.depend 2>/dev/null -.testdepend: tests/test_*.deps - @echo "Rebuilding test dependencies..." - @echo > $@ - @for FILE in $<; do echo -n "$${FILE/.deps/.bin}: " >> $@; echo $$(cat $$FILE) >> $@; done - .subbuild: @echo '1' >.subbuild @@ -712,8 +707,6 @@ netdrivers/net_ldap.so: netdrivers/net_ldap.c %.so: %.c $(CC) $(CFLAGS) -DMODULE -Wno-unused -shared -fPIC $< -o $@ - -include .testdepend # Dependencies made by "make depend" include .depend diff --git a/centrallix/tests/test_00baseline_04.cmp b/centrallix/tests/test_00baseline_04.cmp deleted file mode 100644 index 656dfc57d..000000000 --- a/centrallix/tests/test_00baseline_04.cmp +++ /dev/null @@ -1 +0,0 @@ -Pass diff --git a/centrallix/tests/test_00baseline_04.deps b/centrallix/tests/test_00baseline_04.deps deleted file mode 100644 index e69de29bb..000000000 diff --git a/centrallix/tests/test_00baseline_05.cmp b/centrallix/tests/test_00baseline_05.cmp deleted file mode 100644 index 656dfc57d..000000000 --- a/centrallix/tests/test_00baseline_05.cmp +++ /dev/null @@ -1 +0,0 @@ -Pass diff --git a/centrallix/tests/test_00baseline_05.deps b/centrallix/tests/test_00baseline_05.deps deleted file mode 100644 index e69de29bb..000000000 diff --git a/centrallix/tests/test_00baseline_06.cmp b/centrallix/tests/test_00baseline_06.cmp deleted file mode 100644 index 656dfc57d..000000000 --- a/centrallix/tests/test_00baseline_06.cmp +++ /dev/null @@ -1 +0,0 @@ -Pass diff --git a/centrallix/tests/test_00baseline_06.deps b/centrallix/tests/test_00baseline_06.deps deleted file mode 100644 index e69de29bb..000000000 diff --git a/centrallix/tests/test_00baseline_07.cmp b/centrallix/tests/test_00baseline_07.cmp deleted file mode 100644 index 656dfc57d..000000000 --- a/centrallix/tests/test_00baseline_07.cmp +++ /dev/null @@ -1 +0,0 @@ -Pass diff --git a/centrallix/tests/test_00baseline_07.deps b/centrallix/tests/test_00baseline_07.deps deleted file mode 100644 index e69de29bb..000000000 From 50eea7864c2720a32d5f466885a75e59f93c5542 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 15:17:56 -0600 Subject: [PATCH 016/129] Remove old temporary testrunner --- .gitignore | 1 - centrallix/Makefile.in | 3 --- centrallix/temp_testrunner.c | 17 ----------------- 3 files changed, 21 deletions(-) delete mode 100644 centrallix/temp_testrunner.c diff --git a/.gitignore b/.gitignore index dc66b6971..54d42628c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ centrallix/man/test_obj.1.gz centrallix/osdrivers/*.so centrallix/netdrivers/*.so centrallix/test_obj -centrallix/temp_testrunner centrallix/test_prt centrallix-os/apps/kardia centrallix-lib/include/cxlib diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index 087525fa6..238eee1ed 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -594,9 +594,6 @@ jsengine: $(JSVM) test_obj: test_obj.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) $(CC) centrallix.o test_obj.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o test_obj $(LIBS) -temp_testrunner: temp_testrunner.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) - $(CC) centrallix.o temp_testrunner.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o temp_testrunner $(LIBS) - test_prt: test_prt.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) $(CC) centrallix.o test_prt.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o test_prt $(LIBS) diff --git a/centrallix/temp_testrunner.c b/centrallix/temp_testrunner.c deleted file mode 100644 index 79f98ae5e..000000000 --- a/centrallix/temp_testrunner.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "cxlib/mtask.h" -#include "obj.h" -#include - -void -start(void* v) -{ - MoneyType test = {1, 1}; - printf("%s\n", objFormatMoneyTmp(&test, NULL)); -} - -int -main() -{ - mtInitialize(0, start); - return 0; -} From cfc6473d5759657f9659ee1183e360963af19598 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 15:27:57 -0600 Subject: [PATCH 017/129] Update README --- centrallix/tests/README | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/centrallix/tests/README b/centrallix/tests/README index c3b9f4d4e..9bc3b1487 100644 --- a/centrallix/tests/README +++ b/centrallix/tests/README @@ -74,29 +74,23 @@ help streamline your development. == CREATING TEST SUITE ENTRIES - DIRECT C CODE == -Each test suite item should have three files: +Each direct C test suite item just needs one file: tests/test_{category}_NN.c - C test suite code with test() function - tests/test_{category}_NN.cmp - "correct" output - tests/test_{category}_NN.deps - whitespace-separated list of dependency - .o files that need to be linked in NN is the subtest number, starting with 00 or 01, and {category} is a category name for the group of tests. -The *.cmp file can be copied from the *.out file that is generated by -running a test without a *.cmp file, but be sure the *.out file is correct!! - -The description of the test should be contained in the .c file itself, in a -comment prefixed by "//NAME ". For example, - - //NAME just testing... - -If the test modifies a file in the objectsystem, the modifications can be -automatically undone post-test by including an "//UNDO " tag inside the file: +The file should implement a function `long long test(**char name)` that +returns 0 if it is successful; if it is not, it should either abort using +something like assert() or return 1. - //NAME an update test - //UNDO /tests/updatetest.csv +This function should also set the name parameter to the name of the test, +for instance: + + *name = "moneytype_00 - Converting string to MoneyType" + +You can include and use any Centrallix libraries that you want in these tests. As you develop new test suite entires to cover new or existing functionality, see the discussion above about the $TONLY environment variable, as well, to From d7d4c14227129e1f1c956d5f59ab2710a0b3d5e5 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 15:27:57 -0600 Subject: [PATCH 018/129] Update README for new direct C testing system --- centrallix/tests/README | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/centrallix/tests/README b/centrallix/tests/README index c3b9f4d4e..9bc3b1487 100644 --- a/centrallix/tests/README +++ b/centrallix/tests/README @@ -74,29 +74,23 @@ help streamline your development. == CREATING TEST SUITE ENTRIES - DIRECT C CODE == -Each test suite item should have three files: +Each direct C test suite item just needs one file: tests/test_{category}_NN.c - C test suite code with test() function - tests/test_{category}_NN.cmp - "correct" output - tests/test_{category}_NN.deps - whitespace-separated list of dependency - .o files that need to be linked in NN is the subtest number, starting with 00 or 01, and {category} is a category name for the group of tests. -The *.cmp file can be copied from the *.out file that is generated by -running a test without a *.cmp file, but be sure the *.out file is correct!! - -The description of the test should be contained in the .c file itself, in a -comment prefixed by "//NAME ". For example, - - //NAME just testing... - -If the test modifies a file in the objectsystem, the modifications can be -automatically undone post-test by including an "//UNDO " tag inside the file: +The file should implement a function `long long test(**char name)` that +returns 0 if it is successful; if it is not, it should either abort using +something like assert() or return 1. - //NAME an update test - //UNDO /tests/updatetest.csv +This function should also set the name parameter to the name of the test, +for instance: + + *name = "moneytype_00 - Converting string to MoneyType" + +You can include and use any Centrallix libraries that you want in these tests. As you develop new test suite entires to cover new or existing functionality, see the discussion above about the $TONLY environment variable, as well, to From 982068f01fa5ffb2abae1bb295b6b373fbe7a8a7 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 15:35:02 -0600 Subject: [PATCH 019/129] Remove extraneous name comments from old native C baselines --- centrallix/tests/test_00baseline_04.c | 4 +--- centrallix/tests/test_00baseline_05.c | 4 +--- centrallix/tests/test_00baseline_06.c | 4 +--- centrallix/tests/test_00baseline_07.c | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/centrallix/tests/test_00baseline_04.c b/centrallix/tests/test_00baseline_04.c index fa3fb2e36..e1287ab02 100644 --- a/centrallix/tests/test_00baseline_04.c +++ b/centrallix/tests/test_00baseline_04.c @@ -1,8 +1,6 @@ -//NAME Native C ** SHOULD Pass ** - long long test(char** name) { - *name = "Native C ** SHOULD Pass **"; + *name = "00baseline_04 Native C ** SHOULD Pass **"; return 0; } diff --git a/centrallix/tests/test_00baseline_05.c b/centrallix/tests/test_00baseline_05.c index 948217b73..2b98a28b3 100644 --- a/centrallix/tests/test_00baseline_05.c +++ b/centrallix/tests/test_00baseline_05.c @@ -1,8 +1,6 @@ -//NAME Native C ** SHOULD FAIL ** - long long test(char** name) { - *name = "Native C ** SHOULD FAIL **"; + *name = "00baseline_05 Native C ** SHOULD FAIL **"; return -1; } diff --git a/centrallix/tests/test_00baseline_06.c b/centrallix/tests/test_00baseline_06.c index 19ed5a9de..8d5c675a1 100644 --- a/centrallix/tests/test_00baseline_06.c +++ b/centrallix/tests/test_00baseline_06.c @@ -1,11 +1,9 @@ -//NAME Native C ** SHOULD CRASH ** - #include long long test(char** name) { - *name = "Native C ** SHOULD CRASH **"; + *name = "00baseline_06 Native C ** SHOULD CRASH **"; raise(SIGSEGV); return 0; } diff --git a/centrallix/tests/test_00baseline_07.c b/centrallix/tests/test_00baseline_07.c index 7106529b4..ef85e97d3 100644 --- a/centrallix/tests/test_00baseline_07.c +++ b/centrallix/tests/test_00baseline_07.c @@ -1,9 +1,7 @@ -//NAME Native C ** SHOULD LOCKUP ** - long long test(char** name) { - *name = "Native C ** SHOULD LOCKUP **"; + *name = "00baseline_07 Native C ** SHOULD LOCKUP **"; while(1); return 0; } From 64a74515a4a75958d3ec87c5c180865f667207b7 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 Aug 2020 15:38:03 -0600 Subject: [PATCH 020/129] Example direct C test with assert and include --- centrallix/tests/test_moneytype_example.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 centrallix/tests/test_moneytype_example.c diff --git a/centrallix/tests/test_moneytype_example.c b/centrallix/tests/test_moneytype_example.c new file mode 100644 index 000000000..16c2fbf6b --- /dev/null +++ b/centrallix/tests/test_moneytype_example.c @@ -0,0 +1,11 @@ +#include "obj.h" +#include + +long long +test(char** name) +{ + *name = "MoneyType example"; + MoneyType test = {1, 1}; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "$1.00") == 0); + return 0; +} From c4fe74201f329de58b65877fc0bb73fc7d433883 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 13 Aug 2020 16:37:59 -0600 Subject: [PATCH 021/129] Converted objDataToMoney to 64 bit MoneyType representaion --- centrallix/objectsystem/obj_datatypes.c | 64 +++++++++++++++---------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 1ced03017..9d5b247d3 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -490,18 +490,26 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) + orig_print_whole = m->MoneyValue/10000; + print_whole = m->MoneyValue/10000; + print_fract = m->MoneyValue%10000; + if (print_whole < 0) + { + print_whole = -print_whole; + print_fract = -print_fract; + } + /*if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) { print_whole = m->MoneyValue/10000; print_fract = m->MoneyValue%10000; } else - { + { //This handled the unsigned representation of FractionPart print_whole = m->MoneyValue/10000 + 1; print_fract = 10000 - m->MoneyValue%10000; } orig_print_whole = m->MoneyValue/10000; - if (print_whole < 0) print_whole = -print_whole; + if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ while(*fmt) @@ -1401,7 +1409,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* endptr2; double dbl; int is_neg = 0; - unsigned long intval; + long long intval; int scale; char* fmt; int intl_format; @@ -1409,7 +1417,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* tptr; /** Select the correct type. **/ - /*Carl switch(data_type) + switch(data_type) { case DATA_T_STRING: cxssGetVariable("mfmt", &fmt, obj_default_money_fmt); @@ -1420,7 +1428,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) if (strlen(ptr) < sizeof(tmpbuf)) { /** strip commas (or periods, if in intl format) **/ - /*Carl tptr = tmpbuf; + tptr = tmpbuf; while(*ptr) { if (*ptr != (intl_format?'.':',')) @@ -1442,26 +1450,33 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) ptr++; } intval = 0; - m->FractionPart = 0; - m->WholePart = 0; - intval = strtoul(ptr, &endptr, 10); - if (intval > 0x7FFFFFFFUL) + m->MoneyValue = 0; + intval = strtoll(ptr, &endptr, 10); + if (intval > 0x7FFFFFFFFFFFFFFFLL) return -1; if ((endptr - ptr) != strspn(ptr, "0123456789")) return -1; if (is_neg) - m->WholePart = -intval; + m->MoneyValue = -intval*10000; else - m->WholePart = intval; + m->MoneyValue = intval*10000; if (*endptr == (intl_format?',':'.')) { - intval = strtoul(endptr+1, &endptr2, 10); + intval = strtoll(endptr+1, &endptr2, 10); scale = endptr2 - (endptr+1); if (scale != strspn(endptr+1, "0123456789")) return -1; while(scale < 4) { scale++; intval *= 10; } while(scale > 4) { scale--; intval /= 10; } - m->FractionPart = intval; + if (is_neg) + { + m->MoneyValue -= intval; + } + else + { + m->MoneyValue += intval; + } + //m->FractionPart = intval; endptr = endptr2; } if (endptr == ptr) @@ -1470,32 +1485,31 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) } if (*endptr == '-') { - m->WholePart = -m->WholePart; + m->MoneyValue = -m->MoneyValue; is_neg = !is_neg; } - if (is_neg && m->FractionPart != 0) - { + /*if (is_neg && m->FractionPart != 0) + { //This handled the unsigned representation of FractionPart m->WholePart--; m->FractionPart = 10000 - m->FractionPart; - } + }*/ break; case DATA_T_DOUBLE: dbl = *(double*)data_ptr + 0.000001; - m->WholePart = floor(dbl); - m->FractionPart = (dbl - m->WholePart)*10000; + long long WholePart = floor(dbl); + int FractionPart = (dbl - WholePart)*10000; + m->MoneyValue = (WholePart*10000) + FractionPart; break; case DATA_T_INTEGER: - m->WholePart = *(int*)data_ptr; - m->FractionPart = 0; + m->MoneyValue = *(long long*)data_ptr; break; case DATA_T_MONEY: - m->WholePart = ((pMoneyType)data_ptr)->WholePart; - m->FractionPart = ((pMoneyType)data_ptr)->FractionPart; + m->MoneyValue = ((pMoneyType)data_ptr)->MoneyValue; break; - }*/ + } return 0; } From 54c84cc78fb7f1e7eda57e05f9ad32eaefb187bd Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 13 Aug 2020 17:16:30 -0600 Subject: [PATCH 022/129] Updated functions that accounted for the unsigned nature of FractionPart --- centrallix/objectsystem/obj_datatypes.c | 29 ++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 9d5b247d3..debbcd25a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -491,12 +491,15 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) /** Determine the 'print' version of whole/fraction parts **/ orig_print_whole = m->MoneyValue/10000; - print_whole = m->MoneyValue/10000; - print_fract = m->MoneyValue%10000; - if (print_whole < 0) + if (m->MoneyValue < 0) { - print_whole = -print_whole; - print_fract = -print_fract; + print_whole = -m->MoneyValue/10000; + print_fract = -m->MoneyValue%10000; + } + else + { + print_whole = m->MoneyValue/10000; + print_fract = m->MoneyValue%10000; } /*if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) { @@ -810,10 +813,12 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) + v = m->MoneyValue/10000; + //This handled the unsigned representation of FractionPart + /* if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) v = m->MoneyValue/10000; else - v = m->MoneyValue/10000 + 1; + v = m->MoneyValue/10000 + 1;*/ break; case DATA_T_INTVEC: @@ -1913,9 +1918,13 @@ objDataToWords(int data_type, void* data_ptr) else if (data_type == DATA_T_MONEY) { m = (pMoneyType)data_ptr; - if (m->MoneyValue/10000 < 0) + if (m->MoneyValue < 0) { - if (m->MoneyValue%10000 == 0) + /** Keep the opposite (positive) value for printing **/ + integer_part = -m->MoneyValue/10000; + fraction_part = -m->MoneyValue%10000; + + /*if (m->MoneyValue%10000 == 0) { integer_part = -m->MoneyValue/10000; fraction_part = 0; @@ -1924,7 +1933,7 @@ objDataToWords(int data_type, void* data_ptr) { integer_part = (-m->MoneyValue/10000) - 1; fraction_part = 10000 - m->MoneyValue%10000; - } + }*/ xsConcatenate(&tmpbuf, "Negative ", -1); } else From ebb86ebc051d2de9be7b30ed92ac01e571801ab7 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 14 Aug 2020 13:24:26 -0600 Subject: [PATCH 023/129] Resolving Code Review Comments --- centrallix-lib/include/datatypes.h | 6 +- centrallix/objectsystem/obj_datatypes.c | 140 ++++++++++++------------ 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/centrallix-lib/include/datatypes.h b/centrallix-lib/include/datatypes.h index af78f5e46..465c99bb2 100644 --- a/centrallix-lib/include/datatypes.h +++ b/centrallix-lib/include/datatypes.h @@ -56,11 +56,7 @@ typedef struct _SV /** Money structure **/ typedef struct _MN { - /* Commented out old structure */ - //int WholePart; /* integer part = floor($amount) */ - //unsigned short FractionPart; /* fract part = $amount - floor($amount) */ - - long long MoneyValue; /* Fixed-point representation in 1/10000 of a dollar */ + long long Value; /* Fixed-point representation in 1/10000 of a dollar */ } MoneyType, *pMoneyType; diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index debbcd25a..529b2b95a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -475,7 +475,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (tens_multiplier > 0) tens_multiplier /= 10; /** Special handling of zeros **/ - if (m->MoneyValue == 0 && zero_type != 0) + if (m->Value == 0 && zero_type != 0) { if (strlen(zero_strings[zero_type]) >= length) return -1; @@ -490,28 +490,28 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - orig_print_whole = m->MoneyValue/10000; - if (m->MoneyValue < 0) + orig_print_whole = m->Value/10000; + if (m->Value < 0) { - print_whole = -m->MoneyValue/10000; - print_fract = -m->MoneyValue%10000; + print_whole = -m->Value/10000; + print_fract = -m->Value%10000; } else { - print_whole = m->MoneyValue/10000; - print_fract = m->MoneyValue%10000; + print_whole = m->Value/10000; + print_fract = m->Value%10000; } - /*if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) + /*if (m->Value/10000 >= 0 || m->Value%10000 == 0) { - print_whole = m->MoneyValue/10000; - print_fract = m->MoneyValue%10000; + print_whole = m->Value/10000; + print_fract = m->Value%10000; } else { //This handled the unsigned representation of FractionPart - print_whole = m->MoneyValue/10000 + 1; - print_fract = 10000 - m->MoneyValue%10000; + print_whole = m->Value/10000 + 1; + print_fract = 10000 - m->Value%10000; } - orig_print_whole = m->MoneyValue/10000; + orig_print_whole = m->Value/10000; if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ @@ -531,22 +531,22 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) *(str++) = '$'; break; - case ' ': - case '*': + case ' ': + case '*': case '0': case '^': case '#': if (in_decimal_part) { - d = (print_fract/tens_multiplier)%10; - tens_multiplier /= 10; - } + d = (print_fract/tens_multiplier)%10; + tens_multiplier /= 10; + } else { - d = print_whole/tens_multiplier; - print_whole -= d*tens_multiplier; - tens_multiplier /= 10; - } + d = print_whole/tens_multiplier; + print_whole -= d*tens_multiplier; + tens_multiplier /= 10; + } if (d != 0 || *fmt == '0' || *fmt == '^') suppressing_zeros = 0; if (suppressing_zeros) { @@ -813,12 +813,15 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - v = m->MoneyValue/10000; + if (m->Value/10000 > INT_MAX) + mssError(1,"OBJ","Warning: %d overflow; cannot fit value of that size in int ", data_type); + else + v = m->Value/10000; //This handled the unsigned representation of FractionPart - /* if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) - v = m->MoneyValue/10000; + /* if (m->Value%10000==0 || m->Value/10000>=0) + v = m->Value/10000; else - v = m->MoneyValue/10000 + 1;*/ + v = m->Value/10000 + 1;*/ break; case DATA_T_INTVEC: @@ -853,7 +856,7 @@ objDataToDouble(int data_type, void* data_ptr) { case DATA_T_INTEGER: v = *(int*)data_ptr; break; case DATA_T_STRING: v = strtod((char*)data_ptr, NULL); break; - case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); break; + case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->Value/10000.0; break; case DATA_T_DOUBLE: v = *(double*)data_ptr; break; default: v = 0.0; break; } @@ -1414,7 +1417,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* endptr2; double dbl; int is_neg = 0; - long long intval; + unsigned long intval; int scale; char* fmt; int intl_format; @@ -1455,19 +1458,22 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) ptr++; } intval = 0; - m->MoneyValue = 0; - intval = strtoll(ptr, &endptr, 10); + m->Value = 0; + intval = strtoul(ptr, &endptr, 10); + /** Checking for overflow, Max UL can be greater than Max LL **/ if (intval > 0x7FFFFFFFFFFFFFFFLL) return -1; if ((endptr - ptr) != strspn(ptr, "0123456789")) return -1; if (is_neg) - m->MoneyValue = -intval*10000; + m->Value = -intval*10000; else - m->MoneyValue = intval*10000; + m->Value = intval*10000; + + /** Handling the "fraction" portion after the decimal point **/ if (*endptr == (intl_format?',':'.')) { - intval = strtoll(endptr+1, &endptr2, 10); + intval = strtoul(endptr+1, &endptr2, 10); scale = endptr2 - (endptr+1); if (scale != strspn(endptr+1, "0123456789")) return -1; @@ -1475,13 +1481,12 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) while(scale > 4) { scale--; intval /= 10; } if (is_neg) { - m->MoneyValue -= intval; + m->Value -= intval; } else { - m->MoneyValue += intval; + m->Value += intval; } - //m->FractionPart = intval; endptr = endptr2; } if (endptr == ptr) @@ -1490,29 +1495,21 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) } if (*endptr == '-') { - m->MoneyValue = -m->MoneyValue; + m->Value = -m->Value; is_neg = !is_neg; } - /*if (is_neg && m->FractionPart != 0) - { //This handled the unsigned representation of FractionPart - m->WholePart--; - m->FractionPart = 10000 - m->FractionPart; - }*/ break; case DATA_T_DOUBLE: - dbl = *(double*)data_ptr + 0.000001; - long long WholePart = floor(dbl); - int FractionPart = (dbl - WholePart)*10000; - m->MoneyValue = (WholePart*10000) + FractionPart; + m->Value = *(double*)data_ptr * 10000.0; break; case DATA_T_INTEGER: - m->MoneyValue = *(long long*)data_ptr; + m->Value = *(long long*)data_ptr * 10000; break; case DATA_T_MONEY: - m->MoneyValue = ((pMoneyType)data_ptr)->MoneyValue; + m->Value = ((pMoneyType)data_ptr)->Value; break; } @@ -1593,9 +1590,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: m = (pMoneyType)data_ptr_2; - if (m->MoneyValue/10000 > intval) cmp_value = -1; - else if (m->MoneyValue/10000 < intval) cmp_value = 1; - else cmp_value = m->MoneyValue%10000?-1:0; + if (m->Value/10000 > intval) cmp_value = -1; + else if (m->Value/10000 < intval) cmp_value = 1; + else cmp_value = m->Value%10000?-1:0; break; case DATA_T_INTVEC: @@ -1636,9 +1633,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); m = (pMoneyType)data_ptr_2; - if (m_v.MoneyValue/10000 > m->MoneyValue/10000) cmp_value = 1; - else if (m_v.MoneyValue/10000 < m->MoneyValue/10000) cmp_value = -1; - else cmp_value = m_v.MoneyValue%10000 - m->MoneyValue%10000; + if (m_v.Value > m->Value) cmp_value = 1; + else if (m_v.Value < m->Value) cmp_value = -1; + else cmp_value = 0; break; case DATA_T_DOUBLE: @@ -1692,7 +1689,7 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: m = (pMoneyType)data_ptr_2; - dblval = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); + dblval = m->Value/10000.0; if (dblval == *(double*)data_ptr_1) cmp_value = 0; else if (dblval > *(double*)data_ptr_1) cmp_value = -1; else cmp_value = 1; @@ -1788,9 +1785,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt } else { - if (m->MoneyValue/10000 > iv->Integers[0]) cmp_value = -1; - else if (m->MoneyValue/10000 < iv->Integers[0]) cmp_value = 1; - else cmp_value = iv->Integers[1] - m->MoneyValue%10000; + if (m->Value/10000 > iv->Integers[0]) cmp_value = -1; + else if (m->Value/10000 < iv->Integers[0]) cmp_value = 1; + else cmp_value = iv->Integers[1] - m->Value%10000; } break; @@ -1840,9 +1837,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt switch(data_type_2) { case DATA_T_MONEY: - if (m->MoneyValue/10000 > ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = 1; - else if (m->MoneyValue/10000 < ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = -1; - else cmp_value = m->MoneyValue%10000 - ((pMoneyType)data_ptr_2)->MoneyValue%10000; + if (m->Value > ((pMoneyType)data_ptr_2)->Value) cmp_value = 1; + else if (m->Value < ((pMoneyType)data_ptr_2)->Value) cmp_value = -1; + else cmp_value = 0; break; default: @@ -1918,28 +1915,28 @@ objDataToWords(int data_type, void* data_ptr) else if (data_type == DATA_T_MONEY) { m = (pMoneyType)data_ptr; - if (m->MoneyValue < 0) + if (m->Value < 0) { /** Keep the opposite (positive) value for printing **/ - integer_part = -m->MoneyValue/10000; - fraction_part = -m->MoneyValue%10000; + integer_part = -m->Value/10000; + fraction_part = -m->Value%10000; - /*if (m->MoneyValue%10000 == 0) + /*if (m->Value%10000 == 0) { - integer_part = -m->MoneyValue/10000; + integer_part = -m->Value/10000; fraction_part = 0; } else { - integer_part = (-m->MoneyValue/10000) - 1; - fraction_part = 10000 - m->MoneyValue%10000; + integer_part = (-m->Value/10000) - 1; + fraction_part = 10000 - m->Value%10000; }*/ xsConcatenate(&tmpbuf, "Negative ", -1); } else { - integer_part = m->MoneyValue/10000; - fraction_part = m->MoneyValue%10000; + integer_part = m->Value/10000; + fraction_part = m->Value%10000; } } else @@ -2208,6 +2205,9 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x80000000 to convert to Offset Zero form. **/ + //((long long*)tmp_buf)[0] = htonll(exp->Types.Money.Value ^ 0x8000000000000000); + *item = (char*)(tmp_buf); + *itemlen = 8; /*Carl ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); ((unsigned short*)tmp_buf)[2] = htons(exp->Types.Money.FractionPart); *item = (char*)(tmp_buf); From 56d86be458c571e851230dcda7a9e54bf6f77b70 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 14 Aug 2020 13:51:23 -0600 Subject: [PATCH 024/129] Included byteswap.h and cleaned up old comments --- centrallix/objectsystem/obj_datatypes.c | 35 ++----------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 529b2b95a..745ba9914 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -501,18 +502,6 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) print_whole = m->Value/10000; print_fract = m->Value%10000; } - /*if (m->Value/10000 >= 0 || m->Value%10000 == 0) - { - print_whole = m->Value/10000; - print_fract = m->Value%10000; - } - else - { //This handled the unsigned representation of FractionPart - print_whole = m->Value/10000 + 1; - print_fract = 10000 - m->Value%10000; - } - orig_print_whole = m->Value/10000; - if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ while(*fmt) @@ -817,11 +806,6 @@ objDataToInteger(int data_type, void* data_ptr, char* format) mssError(1,"OBJ","Warning: %d overflow; cannot fit value of that size in int ", data_type); else v = m->Value/10000; - //This handled the unsigned representation of FractionPart - /* if (m->Value%10000==0 || m->Value/10000>=0) - v = m->Value/10000; - else - v = m->Value/10000 + 1;*/ break; case DATA_T_INTVEC: @@ -1920,17 +1904,6 @@ objDataToWords(int data_type, void* data_ptr) /** Keep the opposite (positive) value for printing **/ integer_part = -m->Value/10000; fraction_part = -m->Value%10000; - - /*if (m->Value%10000 == 0) - { - integer_part = -m->Value/10000; - fraction_part = 0; - } - else - { - integer_part = (-m->Value/10000) - 1; - fraction_part = 10000 - m->Value%10000; - }*/ xsConcatenate(&tmpbuf, "Negative ", -1); } else @@ -2205,13 +2178,9 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x80000000 to convert to Offset Zero form. **/ - //((long long*)tmp_buf)[0] = htonll(exp->Types.Money.Value ^ 0x8000000000000000); + ((long long*)tmp_buf)[0] = bswap_64(exp->Types.Money.Value ^ 0x8000000000000000); *item = (char*)(tmp_buf); *itemlen = 8; - /*Carl ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); - ((unsigned short*)tmp_buf)[2] = htons(exp->Types.Money.FractionPart); - *item = (char*)(tmp_buf); - *itemlen = 6;*/ break; case DATA_T_DOUBLE: From 875da6e510ff50c315237f935320048970279480 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 18 Aug 2020 10:16:09 -0600 Subject: [PATCH 025/129] Initial MoneyType Tests for obj_datatype functions --- centrallix/objectsystem/obj_datatypes.c | 2 +- centrallix/tests/test_moneytype_example.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 745ba9914..b6212f6d6 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -803,7 +803,7 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; if (m->Value/10000 > INT_MAX) - mssError(1,"OBJ","Warning: %d overflow; cannot fit value of that size in int ", data_type); + mssError(1, "OBJ", "Warning: %d overflow; cannot fit value of that size in int ", data_type); else v = m->Value/10000; break; diff --git a/centrallix/tests/test_moneytype_example.c b/centrallix/tests/test_moneytype_example.c index 16c2fbf6b..742446200 100644 --- a/centrallix/tests/test_moneytype_example.c +++ b/centrallix/tests/test_moneytype_example.c @@ -5,7 +5,9 @@ long long test(char** name) { *name = "MoneyType example"; - MoneyType test = {1, 1}; + + MoneyType test = {10000}; assert(strcmp(objFormatMoneyTmp(&test, NULL), "$1.00") == 0); + return 0; } From d876235dc74c4e046f8b9971038055feec96ba45 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 18 Aug 2020 10:41:12 -0600 Subject: [PATCH 026/129] MoneyType Tests for obj_datatype functions; Removal of Example --- centrallix/.testdepend | 2 + centrallix/tests/test_moneytype_00.c | 30 ++++++++++++++ centrallix/tests/test_moneytype_01.c | 44 ++++++++++++++++++++ centrallix/tests/test_moneytype_02.c | 31 ++++++++++++++ centrallix/tests/test_moneytype_03.c | 35 ++++++++++++++++ centrallix/tests/test_moneytype_04.c | 49 +++++++++++++++++++++++ centrallix/tests/test_moneytype_example.c | 13 ------ 7 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 centrallix/.testdepend create mode 100644 centrallix/tests/test_moneytype_00.c create mode 100644 centrallix/tests/test_moneytype_01.c create mode 100644 centrallix/tests/test_moneytype_02.c create mode 100644 centrallix/tests/test_moneytype_03.c create mode 100644 centrallix/tests/test_moneytype_04.c delete mode 100644 centrallix/tests/test_moneytype_example.c diff --git a/centrallix/.testdepend b/centrallix/.testdepend new file mode 100644 index 000000000..563e7cb65 --- /dev/null +++ b/centrallix/.testdepend @@ -0,0 +1,2 @@ + +tests/test_00baseline_07.bin: diff --git a/centrallix/tests/test_moneytype_00.c b/centrallix/tests/test_moneytype_00.c new file mode 100644 index 000000000..931ee6505 --- /dev/null +++ b/centrallix/tests/test_moneytype_00.c @@ -0,0 +1,30 @@ +#include "obj.h" +#include + +long long +test(char** name) +{ + *name = "moneytype_00 - obj_internal_FormatMoney"; + + /** 0 Case **/ + MoneyType test = {0}; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "$0.00") == 0); + + /** Positive Case **/ + test.Value = 70000; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "$7.00") == 0); + + /** Negative Case **/ + test.Value = -70000; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "-$7.00") == 0); + + /** Nonzero Cent Case **/ + test.Value = -75000; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "-$7.50") == 0); + + /** Fractional Cent Case **/ + test.Value = -70001; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "-$7.00") == 0); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_01.c b/centrallix/tests/test_moneytype_01.c new file mode 100644 index 000000000..0256d31d6 --- /dev/null +++ b/centrallix/tests/test_moneytype_01.c @@ -0,0 +1,44 @@ +#include "obj.h" +#include +#include +//#include "xstring.h" +//#include "mtsession.h" +//#include "mtask.h" + +long long +test(char** name) +{ + *name = "moneytype_01 - objDataToInteger"; + int testValue; + + /** Zero Case **/ + MoneyType test = {0}; + testValue = objDataToInteger(7,&test,NULL); + assert(testValue == 0); + + /** Positive Case **/ + test.Value = 10000; + testValue = objDataToInteger(7,&test,NULL); + assert(testValue == 1); + + /** Negative Case **/ + test.Value = -10000; + testValue = objDataToInteger(7,&test,NULL); + assert(testValue == -1); + + /** Overflow Case **/ + //Manual Testing showed this section to work properly on overflow + //Currently, I do not know how to print the error messages, so this part + //will remain commented out. + + //test.Value = 250000000000000000; + //testValue = objDataToInteger(7,&test,NULL); + + //assert(testValue); + //assert(testValue == 5); + //mssStringError(pXString); + //printf("%s", pXString); + + + return 0; +} diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_02.c new file mode 100644 index 000000000..97347f46c --- /dev/null +++ b/centrallix/tests/test_moneytype_02.c @@ -0,0 +1,31 @@ +#include "obj.h" +#include + +long long +test(char** name) +{ + *name = "moneytype_02 - objDataToDouble"; + double testValue; + + /** Zero Case **/ + MoneyType test = {0}; + testValue = objDataToDouble(7,&test); + assert(testValue == 0.0); + + /** Positive Case **/ + test.Value = 10000; + testValue = objDataToDouble(7,&test); + assert(testValue == 1.0); + + /** Negative Case **/ + test.Value = -10000; + testValue = objDataToDouble(7,&test); + assert(testValue == -1.0); + + /** Fraction Case **/ + test.Value = -25000; + testValue = objDataToDouble(7,&test); + assert(testValue == -2.5); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c new file mode 100644 index 000000000..5287a1cfb --- /dev/null +++ b/centrallix/tests/test_moneytype_03.c @@ -0,0 +1,35 @@ +#include "obj.h" +#include +#include + +long long +test(char** name) +{ + *name = "moneytype_03 - objDataToMoney"; + MoneyType test = {0}; + + /** String Case **/ + char data_ptr[] = "$4.50"; + assert(objDataToMoney(2,data_ptr,&test) == 0); + assert(test.Value == 45000); + //printf("%lld", test.Value); + + //Edge Cases + + /** Double Case **/ + double testDouble = 5.5; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == 55000); + + /** Int Case **/ + int testInt = 6; + assert(objDataToMoney(1,&testInt,&test) == 0); + assert(test.Value == 60000); + + /** Money Case **/ + MoneyType testMoney = {900000}; + assert(objDataToMoney(7,&testMoney,&test) == 0); + assert(test.Value == 900000); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c new file mode 100644 index 000000000..bbae6842c --- /dev/null +++ b/centrallix/tests/test_moneytype_04.c @@ -0,0 +1,49 @@ +#include "obj.h" +#include +#include + +long long +test(char** name) +{ + *name = "moneytype_04 - objDataCompare"; + MoneyType test = {70500}; + + /** Compare Int with Money Case **/ + int testInt = 6; + assert(objDataCompare(1,&testInt,7,&test) == -1); + + ////Edge Cases + // + ///** Compare Double with Money Case **/ + //double testDouble = 5.5; + //assert(objDataToMoney(3,&testDouble,&test) == 0); + //assert(test.Value == 55000); + // + ///** Compare String with Money Case **/ + //char data_ptr[] = "$4.50"; + //int testInt = 6; + //assert(objDataToMoney(1,&testInt,&test) == 0); + //assert(test.Value == 60000); + // + ///** Compare Money with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + ///** Compare DateTime with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + ///** Compare IntV with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + ///** Compare StrV with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_example.c b/centrallix/tests/test_moneytype_example.c deleted file mode 100644 index 742446200..000000000 --- a/centrallix/tests/test_moneytype_example.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "obj.h" -#include - -long long -test(char** name) -{ - *name = "MoneyType example"; - - MoneyType test = {10000}; - assert(strcmp(objFormatMoneyTmp(&test, NULL), "$1.00") == 0); - - return 0; -} From a912e91108e6543ec5155e44137e7f6c1aef6bac Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:45:16 -0600 Subject: [PATCH 027/129] More MoneyType Tests for obj_datatype functions --- centrallix/objectsystem/obj_datatypes.c | 2 +- centrallix/tests/test_moneytype_04.c | 49 ++++++++++--------------- centrallix/tests/test_moneytype_05.c | 25 +++++++++++++ centrallix/tests/test_moneytype_06.c | 30 +++++++++++++++ 4 files changed, 76 insertions(+), 30 deletions(-) create mode 100644 centrallix/tests/test_moneytype_05.c create mode 100644 centrallix/tests/test_moneytype_06.c diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index b6212f6d6..6d227bf79 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -2177,7 +2177,7 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO break; case DATA_T_MONEY: - /** XOR 0x80000000 to convert to Offset Zero form. **/ + /** XOR 0x8000000000000000 to convert to Offset Zero form. **/ ((long long*)tmp_buf)[0] = bswap_64(exp->Types.Money.Value ^ 0x8000000000000000); *item = (char*)(tmp_buf); *itemlen = 8; diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c index bbae6842c..eba9fadbf 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_04.c @@ -12,38 +12,29 @@ test(char** name) int testInt = 6; assert(objDataCompare(1,&testInt,7,&test) == -1); - ////Edge Cases - // - ///** Compare Double with Money Case **/ - //double testDouble = 5.5; - //assert(objDataToMoney(3,&testDouble,&test) == 0); - //assert(test.Value == 55000); - // - ///** Compare String with Money Case **/ - //char data_ptr[] = "$4.50"; - //int testInt = 6; - //assert(objDataToMoney(1,&testInt,&test) == 0); - //assert(test.Value == 60000); - // - ///** Compare Money with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare Double with Money Case **/ + double testDouble = 5.5; + assert(objDataCompare(3,&testDouble,7,&test) == -1); + + /** Compare String with Money Case **/ + char data_ptr[] = "$4.50"; + assert(objDataCompare(2,data_ptr,7,&test) == -1); + + /** Compare Money with Money Case **/ + MoneyType testMoney = {70500}; + assert(objDataCompare(7,&testMoney,7,&test) == 0); - ///** Compare DateTime with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare DateTime with Money Case **/ + DateTime testDate = {0}; + assert(objDataCompare(4,&testDate,7,&test) == -2); - ///** Compare IntV with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare IntV with Money Case **/ + IntVec testIV = {0}; + assert(objDataCompare(5,&testIV,7,&test) == -2); - ///** Compare StrV with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare StrV with Money Case **/ + StringVec testSV = {0}; + assert(objDataCompare(6,&testSV,7,&test) == -2); return 0; } diff --git a/centrallix/tests/test_moneytype_05.c b/centrallix/tests/test_moneytype_05.c new file mode 100644 index 000000000..c013fa13e --- /dev/null +++ b/centrallix/tests/test_moneytype_05.c @@ -0,0 +1,25 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" + +long long +test(char** name) +{ + *name = "moneytype_05 - objDataToWords"; + MoneyType test = {70500}; + + /** Positive Case **/ + char* data_ptr = "Seven And 05/100 "; + char* returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); + + /** Negative Case **/ + test.Value = -70500; + data_ptr = "Negative Seven And 05/100 "; + returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_06.c b/centrallix/tests/test_moneytype_06.c new file mode 100644 index 000000000..9df19b1a9 --- /dev/null +++ b/centrallix/tests/test_moneytype_06.c @@ -0,0 +1,30 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" + +long long +test(char** name) +{ + *name = "moneytype_06 - obj_internal_BuildBinaryItem"; + char** item; + int* itemlen; + pExpression testExp = expAllocExpression(); + pParamObjects testParamObjects = expCreateParamList(); + unsigned char tmpbuf[12]; + + /** Positive Case **/ + testExp->Types.Money.Value = 90000; + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + + /** Negative Case **/ + //test.Value = -70500; + //data_ptr = "Negative Seven And 05/100 "; + //returnStr = objDataToWords(7,&test); + //assert(strcmp(data_ptr, returnStr) == 0); + + expFreeExpression(testExp); + + return 0; +} From afc2e99d3ba9f6b1940d0c0858524e5948383e7b Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 19 Aug 2020 10:37:54 -0600 Subject: [PATCH 028/129] Expanded functionality for moneytype tests --- centrallix/tests/test_moneytype_02.c | 2 +- centrallix/tests/test_moneytype_03.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_02.c index 97347f46c..8a9b57331 100644 --- a/centrallix/tests/test_moneytype_02.c +++ b/centrallix/tests/test_moneytype_02.c @@ -22,7 +22,7 @@ test(char** name) testValue = objDataToDouble(7,&test); assert(testValue == -1.0); - /** Fraction Case **/ + /** Rational Case **/ test.Value = -25000; testValue = objDataToDouble(7,&test); assert(testValue == -2.5); diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c index 5287a1cfb..1dd177d1e 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_03.c @@ -12,9 +12,6 @@ test(char** name) char data_ptr[] = "$4.50"; assert(objDataToMoney(2,data_ptr,&test) == 0); assert(test.Value == 45000); - //printf("%lld", test.Value); - - //Edge Cases /** Double Case **/ double testDouble = 5.5; @@ -31,5 +28,9 @@ test(char** name) assert(objDataToMoney(7,&testMoney,&test) == 0); assert(test.Value == 900000); + /** Overflow Case (intval > LL max) **/ + char overflow_ptr[] = "$10000000000000000000.50"; + assert(objDataToMoney(2,overflow_ptr,&test) == -1); + return 0; } From e8c63433fe84670ec3279fe156299b8d8d636230 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 19 Aug 2020 16:12:46 -0600 Subject: [PATCH 029/129] Converted to 64 bit MoneyType Representation --- centrallix/expression/exp_evaluate.c | 119 +++++++++------------------ centrallix/expression/exp_main.c | 6 +- 2 files changed, 43 insertions(+), 82 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index 0d17affd6..d706ca7db 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -226,9 +226,9 @@ expEvalDivide(pExpression tree, pParamObjects objlist) /** Check for divide by zero **/ if ((i1->DataType == DATA_T_INTEGER && i1->Integer == 0) || - (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0)){ //|| - //(i1->DataType == DATA_T_MONEY && i1->Types.Money.WholePart == 0 && i1->Types.Money.FractionPart == 0)) - //{ + (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0) || + (i1->DataType == DATA_T_MONEY && i1->Types.Money.Value == 0)) + { mssError(1,"EXP","Attempted divide by zero"); return -1; } @@ -275,20 +275,15 @@ expEvalDivide(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: - /*Carl switch(i1->DataType) + switch(i1->DataType) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; memcpy(&m, &(i0->Types.Money), sizeof(MoneyType)); - if (m.WholePart < 0) + if (m.Value < 0) { is_negative = !is_negative; - if (m.FractionPart != 0) - { - m.WholePart = m.WholePart + 1; - m.FractionPart = 10000 - m.FractionPart; - } - m.WholePart = -m.WholePart; + m.Value = -m.Value; } i = i1->Integer; if (i < 0) @@ -301,16 +296,10 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - //tree->Types.Money.WholePart = m.WholePart / i; - //tree->Types.Money.FractionPart = (10000*(m.WholePart % i) + m.FractionPart)/i; + tree->Types.Money.Value = m.Value / i; if (is_negative) { - if (tree->Types.Money.FractionPart != 0) - { - tree->Types.Money.WholePart = tree->Types.Money.WholePart + 1; - tree->Types.Money.FractionPart = 10000 - tree->Types.Money.FractionPart; - } - tree->Types.Money.WholePart = -tree->Types.Money.WholePart; + tree->Types.Money.Value = -tree->Types.Money.Value; } break; case DATA_T_DOUBLE: @@ -320,7 +309,11 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + md = i0->Types.Money.Value / 10000.0; + md = md / i1->Types.Double; + tree->Types.Money.Value = (long long)(md * 10000); + //Old Definition + /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; md = mv / i1->Types.Double; if (md < 0) md -= 0.5; else md += 0.5; @@ -332,12 +325,12 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mv += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mv; + tree->Types.Money.FractionPart = mv;*/ break; case DATA_T_MONEY: - mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; - mv2 = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - if (mv2 == 0) + mv = i0->Types.Money.Value; + mv2 = i1->Types.Money.Value; + if (i1->Types.Money.Value == 0) { mssError(1,"EXP","Attempted divide by zero"); return -1; @@ -353,7 +346,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) tree->Types.Double = (double)mv / (double)mv2; } break; - }*/ + } break; default: @@ -453,8 +446,8 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) { case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - //mv *= i0->Types.Double; + //Double check that casting is working properly + mv = i1->Types.Money.Value * i0->Types.Double; break; default: tree->Types.Double = i0->Types.Double * objDataToDouble(i1->DataType, dptr); @@ -465,25 +458,28 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - /*Carl mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + mv = i0->Types.Money.Value; switch(i1->DataType) { case DATA_T_INTEGER: mv *= i1->Integer; break; - case DATA_T_DOUBLE: + + case DATA_T_DOUBLE: md = mv * i1->Types.Double; if (md < 0) md -= 0.5; else md += 0.5; mv = md; break; + case DATA_T_MONEY: mssError(1,"EXP","Cannot multiply a money data type by another money data type"); return -1; + default: mssError(1,"EXP","Can only multiply a money data type by an integer or double"); return -1; - }*/ + } break; case DATA_T_STRING: @@ -505,14 +501,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) /** Common processing **/ if (tree->DataType == DATA_T_MONEY) { - /*Carl tree->Types.Money.WholePart = mv/10000; - mv = mv % 10000; - if (mv < 0) - { - mv += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mv;*/ + tree->Types.Money.Value = mv; } else if (tree->DataType == DATA_T_STRING) { @@ -604,17 +593,9 @@ expEvalMinus(pExpression tree, pParamObjects objlist) tree->Types.Double = (double)(i0->Integer) - i1->Types.Double; break; case DATA_T_MONEY: + /** Treat Int as a dollar value **/ tree->DataType = DATA_T_MONEY; - /*Carl tree->Types.Money.WholePart = i0->Integer - i1->Types.Money.WholePart; - if (i1->Types.Money.FractionPart == 0) - { - tree->Types.Money.FractionPart = 0; - } - else - { - tree->Types.Money.WholePart--; - tree->Types.Money.FractionPart = 10000 - i1->Types.Money.FractionPart; - }*/ + tree->Types.Money.Value = (i0->Integer * 10000) - i1->Types.Money.Value; break; default: tree->Integer = i0->Integer - objDataToInteger(i1->DataType, dptr, NULL); @@ -635,7 +616,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_DOUBLE; - //tree->Types.Double = i0->Types.Double - (i1->Types.Money.WholePart + i1->Types.Money.FractionPart/10000.0); + tree->Types.Double = i0->Types.Double - (i1->Types.Money.Value / 10000.0); break; default: tree->DataType = DATA_T_DOUBLE; @@ -649,25 +630,16 @@ expEvalMinus(pExpression tree, pParamObjects objlist) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; - //tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Integer; - //tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; + /** Since Value is in 1/10000 of a dollar, integer must be multiplied to scale **/ + tree->Types.Money.Value = i0->Types.Money.Value - (i1->Integer * 10000); break; case DATA_T_DOUBLE: tree->DataType = DATA_T_DOUBLE; - //tree->Types.Double = (i0->Types.Money.WholePart + i0->Types.Money.FractionPart/10000.0) - i1->Types.Double; + tree->Types.Double = (i0->Types.Money.Value / 10000.0) - i1->Types.Double; break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Types.Money.WholePart; - tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - i1->Types.Money.FractionPart; - if (tree->Types.Money.FractionPart >= 10000) - { - tree->Types.Money.FractionPart -= 10000; - } - else - { - tree->Types.Money.WholePart--; - }*/ + tree->Types.Money.Value = i0->Types.Money.Value - i1->Types.Money.Value; break; default: if (objDataToMoney(i1->DataType, dptr, &m) < 0) @@ -676,12 +648,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) return -1; } tree->DataType = DATA_T_MONEY; - /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - m.WholePart; - tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - m.FractionPart; - if (tree->Types.Money.FractionPart >= 10000) - tree->Types.Money.FractionPart -= 10000; - else - tree->Types.Money.WholePart--; */ + tree->Types.Money.Value = i0->Types.Money.Value - m.Value; break; } break; @@ -806,8 +773,8 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - //tree->Types.Money.WholePart = i1->Types.Money.WholePart + i0->Integer; - //tree->Types.Money.FractionPart = i1->Types.Money.FractionPart; + /** Int must be converted to 1/10000 of a dollar **/ + tree->Types.Money.Value = i1->Types.Money.Value + (i0->Integer * 10000); break; default: @@ -843,13 +810,7 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: objDataToMoney(i1->DataType, dptr, &m); - /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart + m.WholePart; - tree->Types.Money.FractionPart = i0->Types.Money.FractionPart + m.FractionPart; - if (tree->Types.Money.FractionPart >= 10000) - { - tree->Types.Money.FractionPart -= 10000; - tree->Types.Money.WholePart++; - }*/ + tree->Types.Money.Value = i0->Types.Money.Value + m.Value; break; case DATA_T_DATETIME: @@ -1498,8 +1459,8 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) } else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { - //tree->Types.Money.WholePart = tree->Integer; - //tree->Types.Money.FractionPart = 0; + tree->Types.Money.Value = (tree->Integer * 10000); + tree->Types.Money.FractionPart = 0; } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/expression/exp_main.c b/centrallix/expression/exp_main.c index 0bdbcd0a3..ef2598709 100644 --- a/centrallix/expression/exp_main.c +++ b/centrallix/expression/exp_main.c @@ -523,7 +523,7 @@ exp_internal_DumpExpression_r(pExpression this, int level) case EXPR_N_INTEGER: printf("INTEGER = %d", this->Integer); break; case EXPR_N_STRING: printf("STRING = <%s>", this->String); break; case EXPR_N_DOUBLE: printf("DOUBLE = %.2f", this->Types.Double); break; - case EXPR_N_MONEY: printf("MONEY");/*printf("MONEY = %d.%4.4d", this->Types.Money.WholePart, this->Types.Money.FractionPart);*/ break; + case EXPR_N_MONEY: printf("MONEY = %4.4lld", this->Types.Money.Value); break; case EXPR_N_DATETIME: printf("DATETIME = %s", objDataToStringTmp(DATA_T_DATETIME,&(this->Types.Date), 0)); break; case EXPR_N_PLUS: printf("PLUS"); break; case EXPR_N_MULTIPLY: printf("MULTIPLY"); break; @@ -863,8 +863,8 @@ expCompareExpressionValues(pExpression exp1, pExpression exp2) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DOUBLE && exp1->Types.Double != exp2->Types.Double) return 0; - //if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && (exp1->Types.Money.WholePart != exp2->Types.Money.WholePart || exp1->Types.Money.FractionPart != exp2->Types.Money.FractionPart)) - //return 0; + if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && exp1->Types.Money.Value != exp2->Types.Money.Value + return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DATETIME && (exp1->Types.Date.Part.Second != exp2->Types.Date.Part.Second || exp1->Types.Date.Part.Minute != exp2->Types.Date.Part.Minute || exp1->Types.Date.Part.Hour != exp2->Types.Date.Part.Hour || exp1->Types.Date.Part.Day != exp2->Types.Date.Part.Day || exp1->Types.Date.Part.Month != exp2->Types.Date.Part.Month || exp1->Types.Date.Part.Year != exp2->Types.Date.Part.Year)) return 0; From aa64e399e4068539476f0ebdf2065ac2ca8d93e0 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 19 Aug 2020 16:59:41 -0600 Subject: [PATCH 030/129] Converted to 64 bit MoneyType Representation --- centrallix/expression/exp_compiler.c | 3 +-- centrallix/expression/exp_functions.c | 33 +++++++-------------------- centrallix/expression/exp_params.c | 6 ++--- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/centrallix/expression/exp_compiler.c b/centrallix/expression/exp_compiler.c index 9bcbd9340..d47bea653 100644 --- a/centrallix/expression/exp_compiler.c +++ b/centrallix/expression/exp_compiler.c @@ -152,8 +152,7 @@ exp_internal_CompileExpression_r(pLxSession lxs, int level, pParamObjects objlis if (t == MLX_TOK_INTEGER) { i = mlxIntVal(lxs); - //etmp->Types.Money.WholePart = i; - //etmp->Types.Money.FractionPart = 0; + etmp->Types.Money.Value = (i * 10000); } else { diff --git a/centrallix/expression/exp_functions.c b/centrallix/expression/exp_functions.c index 2ffa2ac4b..1f2e399b7 100644 --- a/centrallix/expression/exp_functions.c +++ b/centrallix/expression/exp_functions.c @@ -266,24 +266,11 @@ int exp_fn_abs(pExpression tree, pParamObjects objlist, pExpression i0, pExpress break; case DATA_T_MONEY: - /*Carl if (i0->Types.Money.WholePart >= 0) - { - tree->Types.Money.WholePart = i0->Types.Money.WholePart; - tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; - } - else - { - if (i0->Types.Money.FractionPart != 0) - { - tree->Types.Money.WholePart = -(i0->Types.Money.WholePart + 1); - tree->Types.Money.FractionPart = 10000 - i0->Types.Money.FractionPart; - } + if (i0->Types.Money.Value >= 0) + tree->Types.Money.Value = i0->Types.Money.Value; else - { - tree->Types.Money.WholePart = -i0->Types.Money.WholePart; - tree->Types.Money.FractionPart = 0; - } - }*/ + tree->Types.Money.Value = -i0->Types.Money.Value; + break; default: @@ -2947,8 +2934,7 @@ int exp_fn_avg(pExpression tree, pParamObjects objlist, pExpression i0, pExpress sumexp->String[0] = '\0'; sumexp->Integer = 0; sumexp->Types.Double = 0; - //sumexp->Types.Money.FractionPart = 0; - //sumexp->Types.Money.WholePart = 0; + sumexp->Types.Money.Value = 0; cntexp->Integer = 0; } @@ -3035,8 +3021,7 @@ int exp_fn_sum(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->AggExp->String[0] = '\0'; tree->AggExp->Integer = 0; tree->AggExp->Types.Double = 0; - //tree->AggExp->Types.Money.FractionPart = 0; - //tree->AggExp->Types.Money.WholePart = 0; + tree->AggExp->Types.Money.Value = 0; } expCopyValue(tree->AggExp, (pExpression)(tree->AggExp->Children.Items[0]), 1); expCopyValue(i0, (pExpression)(tree->AggExp->Children.Items[1]), 0); @@ -3098,8 +3083,7 @@ int exp_fn_max(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->String[0] = '\0'; tree->Integer = 0; tree->Types.Double = 0; - //tree->Types.Money.FractionPart = 0; - //tree->Types.Money.WholePart = 0; + tree->Types.Money.Value = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); @@ -3160,8 +3144,7 @@ int exp_fn_min(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->Alloc = 0; tree->Integer = 0; tree->Types.Double = 0; - //tree->Types.Money.FractionPart = 0; - //tree->Types.Money.WholePart = 0; + tree->Types.Money.Value = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); diff --git a/centrallix/expression/exp_params.c b/centrallix/expression/exp_params.c index 83fa66167..260febff2 100644 --- a/centrallix/expression/exp_params.c +++ b/centrallix/expression/exp_params.c @@ -602,14 +602,12 @@ exp_internal_ResetAggregates(pExpression this, int reset_id, int level) { this->AggExp->Integer = 0; this->AggExp->Types.Double = 0; - //this->AggExp->Types.Money.WholePart = 0; - //this->AggExp->Types.Money.FractionPart = 0; + this->AggExp->Types.Money.Value = 0; this->Flags |= EXPR_F_AGGLOCKED; } this->Integer = 0; this->Types.Double = 0; - //this->Types.Money.WholePart = 0; - //this->Types.Money.FractionPart = 0; + this->Types.Money.Value = 0; if (!strcmp(this->Name,"count")) { this->Flags &= ~EXPR_F_NULL; From af21f8b5d99fa0d38aafb24220f890329bd32cf4 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 20 Aug 2020 12:05:10 -0600 Subject: [PATCH 031/129] Round and truncate exp functions converted to 64 bit --- centrallix/expression/exp_functions.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/centrallix/expression/exp_functions.c b/centrallix/expression/exp_functions.c index 1f2e399b7..11d2a7d7f 100644 --- a/centrallix/expression/exp_functions.c +++ b/centrallix/expression/exp_functions.c @@ -1650,7 +1650,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre break; case DATA_T_MONEY: - /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + mt = i0->Types.Money.Value; if (dec < 4) { mv = 1; @@ -1662,14 +1662,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre mt /= mv; mt *= mv; } - tree->Types.Money.WholePart = mt/10000; - mt = mt % 10000; - if (mt < 0) - { - mt += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mt;*/ + tree->Types.Money.Value = mt; break; } return 0; @@ -1923,7 +1916,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx break; case DATA_T_MONEY: - /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + mt = i0->Types.Money.Value; if (dec < 4) { mv = 1; @@ -1931,14 +1924,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx mt /= mv; mt *= mv; } - tree->Types.Money.WholePart = mt/10000; - mt = mt % 10000; - if (mt < 0) - { - mt += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mt;*/ + tree->Types.Money.Value = mt; break; } return 0; From 4a61dfaec499ae19060ed98aabe1d09ef34178d6 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 20 Aug 2020 20:20:20 -0600 Subject: [PATCH 032/129] Addressing Code Review Comments and Improving Tests --- centrallix/expression/exp_evaluate.c | 8 ++-- centrallix/expression/exp_main.c | 2 +- centrallix/objectsystem/obj_datatypes.c | 13 +++--- centrallix/tests/test_moneytype_00.c | 4 ++ centrallix/tests/test_moneytype_01.c | 14 +++--- centrallix/tests/test_moneytype_02.c | 13 ++---- centrallix/tests/test_moneytype_03.c | 21 +++++++-- centrallix/tests/test_moneytype_04.c | 58 ++++++++++++++++++++++--- centrallix/tests/test_moneytype_05.c | 13 ++++++ 9 files changed, 110 insertions(+), 36 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index d706ca7db..e1b5d8bc2 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -311,6 +311,8 @@ expEvalDivide(pExpression tree, pParamObjects objlist) } md = i0->Types.Money.Value / 10000.0; md = md / i1->Types.Double; + if (md < 0) md -= 0.5; + else md += 0.5; tree->Types.Money.Value = (long long)(md * 10000); //Old Definition /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; @@ -330,7 +332,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: mv = i0->Types.Money.Value; mv2 = i1->Types.Money.Value; - if (i1->Types.Money.Value == 0) + if (mv2 == 0) { mssError(1,"EXP","Attempted divide by zero"); return -1; @@ -464,18 +466,15 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: mv *= i1->Integer; break; - case DATA_T_DOUBLE: md = mv * i1->Types.Double; if (md < 0) md -= 0.5; else md += 0.5; mv = md; break; - case DATA_T_MONEY: mssError(1,"EXP","Cannot multiply a money data type by another money data type"); return -1; - default: mssError(1,"EXP","Can only multiply a money data type by an integer or double"); return -1; @@ -1460,7 +1459,6 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { tree->Types.Money.Value = (tree->Integer * 10000); - tree->Types.Money.FractionPart = 0; } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/expression/exp_main.c b/centrallix/expression/exp_main.c index ef2598709..8ef286801 100644 --- a/centrallix/expression/exp_main.c +++ b/centrallix/expression/exp_main.c @@ -863,7 +863,7 @@ expCompareExpressionValues(pExpression exp1, pExpression exp2) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DOUBLE && exp1->Types.Double != exp2->Types.Double) return 0; - if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && exp1->Types.Money.Value != exp2->Types.Money.Value + if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && exp1->Types.Money.Value != exp2->Types.Money.Value) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DATETIME && (exp1->Types.Date.Part.Second != exp2->Types.Date.Part.Second || exp1->Types.Date.Part.Minute != exp2->Types.Date.Part.Minute || exp1->Types.Date.Part.Hour != exp2->Types.Date.Part.Hour || exp1->Types.Date.Part.Day != exp2->Types.Date.Part.Day || exp1->Types.Date.Part.Month != exp2->Types.Date.Part.Month || exp1->Types.Date.Part.Year != exp2->Types.Date.Part.Year)) return 0; diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 6d227bf79..ec85f12cb 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1485,11 +1485,12 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) break; case DATA_T_DOUBLE: - m->Value = *(double*)data_ptr * 10000.0; + dbl = *(double*)data_ptr * 10000.0; + m->Value = (long long)dbl; break; case DATA_T_INTEGER: - m->Value = *(long long*)data_ptr * 10000; + m->Value = *(int*)data_ptr * 10000; break; case DATA_T_MONEY: @@ -1769,9 +1770,11 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt } else { - if (m->Value/10000 > iv->Integers[0]) cmp_value = -1; - else if (m->Value/10000 < iv->Integers[0]) cmp_value = 1; - else cmp_value = iv->Integers[1] - m->Value%10000; + if (m->Value/10000 > iv->Integers[0]) + {cmp_value = -1; printf("Reached -1");} + else if (m->Value/10000 < iv->Integers[0]) + {cmp_value = 1; printf("Reached 1");} + else {cmp_value = iv->Integers[1] - m->Value%10000; printf("Reached 0");} } break; diff --git a/centrallix/tests/test_moneytype_00.c b/centrallix/tests/test_moneytype_00.c index 931ee6505..7901cd348 100644 --- a/centrallix/tests/test_moneytype_00.c +++ b/centrallix/tests/test_moneytype_00.c @@ -4,6 +4,10 @@ long long test(char** name) { + /** objFormatMoneyTmp is a wrapper that calls obj_internal_FormatMoney + ** Functionality was changed in obj_internal_FormatMoney, so the point of + ** these tests is to test obj_internal_FormatMoney, even with a different function call + **/ *name = "moneytype_00 - obj_internal_FormatMoney"; /** 0 Case **/ diff --git a/centrallix/tests/test_moneytype_01.c b/centrallix/tests/test_moneytype_01.c index 0256d31d6..b66efe70d 100644 --- a/centrallix/tests/test_moneytype_01.c +++ b/centrallix/tests/test_moneytype_01.c @@ -9,22 +9,22 @@ long long test(char** name) { *name = "moneytype_01 - objDataToInteger"; - int testValue; /** Zero Case **/ MoneyType test = {0}; - testValue = objDataToInteger(7,&test,NULL); - assert(testValue == 0); + assert(objDataToInteger(7,&test,NULL) == 0); /** Positive Case **/ test.Value = 10000; - testValue = objDataToInteger(7,&test,NULL); - assert(testValue == 1); + assert(objDataToInteger(7,&test,NULL) == 1); /** Negative Case **/ test.Value = -10000; - testValue = objDataToInteger(7,&test,NULL); - assert(testValue == -1); + assert(objDataToInteger(7,&test,NULL) == -1); + + /** Fractional Case **/ + test.Value = 15000; + assert(objDataToInteger(7,&test,NULL) == 1); /** Overflow Case **/ //Manual Testing showed this section to work properly on overflow diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_02.c index 8a9b57331..d2dfd1e97 100644 --- a/centrallix/tests/test_moneytype_02.c +++ b/centrallix/tests/test_moneytype_02.c @@ -5,27 +5,22 @@ long long test(char** name) { *name = "moneytype_02 - objDataToDouble"; - double testValue; /** Zero Case **/ MoneyType test = {0}; - testValue = objDataToDouble(7,&test); - assert(testValue == 0.0); + assert(objDataToDouble(7,&test) == 0.0); /** Positive Case **/ test.Value = 10000; - testValue = objDataToDouble(7,&test); - assert(testValue == 1.0); + assert(objDataToDouble(7,&test) == 1.0); /** Negative Case **/ test.Value = -10000; - testValue = objDataToDouble(7,&test); - assert(testValue == -1.0); + assert(objDataToDouble(7,&test) == -1.0); /** Rational Case **/ test.Value = -25000; - testValue = objDataToDouble(7,&test); - assert(testValue == -2.5); + assert(objDataToDouble(7,&test) == -2.5); return 0; } diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c index 1dd177d1e..f862c0edd 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_03.c @@ -13,10 +13,27 @@ test(char** name) assert(objDataToMoney(2,data_ptr,&test) == 0); assert(test.Value == 45000); + char data_ptr2[] = "-$4.50"; + assert(objDataToMoney(2,data_ptr2,&test) == 0); + assert(test.Value == -45000); + + /** Overflow Case (intval > LL max) **/ + char overflow_ptr[] = "$10000000000000000000.50"; + assert(objDataToMoney(2,overflow_ptr,&test) == -1); + /** Double Case **/ double testDouble = 5.5; assert(objDataToMoney(3,&testDouble,&test) == 0); assert(test.Value == 55000); + + testDouble = -5.5; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == -55000); + + //Double Fraction Overflow + testDouble = 5.159999999999; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == 51599); /** Int Case **/ int testInt = 6; @@ -28,9 +45,7 @@ test(char** name) assert(objDataToMoney(7,&testMoney,&test) == 0); assert(test.Value == 900000); - /** Overflow Case (intval > LL max) **/ - char overflow_ptr[] = "$10000000000000000000.50"; - assert(objDataToMoney(2,overflow_ptr,&test) == -1); + return 0; } diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c index eba9fadbf..345bff04f 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_04.c @@ -1,27 +1,56 @@ #include "obj.h" #include #include +//#include long long test(char** name) { *name = "moneytype_04 - objDataCompare"; - MoneyType test = {70500}; + MoneyType test = {70000}; /** Compare Int with Money Case **/ - int testInt = 6; + /** Greater Than **/ + int testInt = 8; + assert(objDataCompare(1,&testInt,7,&test) == 1); + /** Less Than **/ + testInt = 6; assert(objDataCompare(1,&testInt,7,&test) == -1); + /** Equal To **/ + testInt = 7; + assert(objDataCompare(1,&testInt,7,&test) == 0); /** Compare Double with Money Case **/ - double testDouble = 5.5; + /** Greater Than **/ + double testDouble = 7.5; + assert(objDataCompare(3,&testDouble,7,&test) == 1); + /** Less Than **/ + testDouble = 5.5; assert(objDataCompare(3,&testDouble,7,&test) == -1); + /** Equal To **/ + testDouble = 7.0; + assert(objDataCompare(3,&testDouble,7,&test) == 0); /** Compare String with Money Case **/ - char data_ptr[] = "$4.50"; - assert(objDataCompare(2,data_ptr,7,&test) == -1); + /** Greater Than **/ + char data_ptr[] = "$8.50"; + assert(objDataCompare(2,data_ptr,7,&test) == 1); + /** Less Than **/ + char data_ptr2[] = "$4.50"; + assert(objDataCompare(2,data_ptr2,7,&test) == -1); + /** Equal To **/ + char data_ptr3[] = "$7.00"; + assert(objDataCompare(2,data_ptr3,7,&test) == 0); /** Compare Money with Money Case **/ - MoneyType testMoney = {70500}; + /** Greater Than **/ + MoneyType testMoney = {80500}; + assert(objDataCompare(7,&testMoney,7,&test) == 1); + /** Less Than **/ + testMoney.Value = 50000; + assert(objDataCompare(7,&testMoney,7,&test) == -1); + /** Equal To **/ + testMoney.Value = 70000; assert(objDataCompare(7,&testMoney,7,&test) == 0); /** Compare DateTime with Money Case **/ @@ -29,9 +58,26 @@ test(char** name) assert(objDataCompare(4,&testDate,7,&test) == -2); /** Compare IntV with Money Case **/ + /** IntV fails with any value other than 2 **/ IntVec testIV = {0}; assert(objDataCompare(5,&testIV,7,&test) == -2); + int* argArray[2]; + IntVec validTestIV = {0}; + validTestIV.nIntegers = 2; + validTestIV.Integers = argArray; + validTestIV.Integers[0] = 9; + validTestIV.Integers[1] = 20; + assert(objDataCompare(5,&validTestIV,7,&test) == 1); + + validTestIV.Integers[0] = 4; + validTestIV.Integers[1] = 35; + assert(objDataCompare(5,&validTestIV,7,&test) == -1); + + validTestIV.Integers[0] = 7; + validTestIV.Integers[1] = 0; + assert(objDataCompare(5,&testIV,7,&test) == 0); + /** Compare StrV with Money Case **/ StringVec testSV = {0}; assert(objDataCompare(6,&testSV,7,&test) == -2); diff --git a/centrallix/tests/test_moneytype_05.c b/centrallix/tests/test_moneytype_05.c index c013fa13e..b9caac0cb 100644 --- a/centrallix/tests/test_moneytype_05.c +++ b/centrallix/tests/test_moneytype_05.c @@ -20,6 +20,19 @@ test(char** name) data_ptr = "Negative Seven And 05/100 "; returnStr = objDataToWords(7,&test); assert(strcmp(data_ptr, returnStr) == 0); + + /**objDataToWords Truncates fractional cent values past 100ths**/ + /** Fractional Case **/ + test.Value = -70525; + data_ptr = "Negative Seven And 05/100 "; + returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); + + /** Fractional Case **/ + test.Value = -70575; + data_ptr = "Negative Seven And 05/100 "; + returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); return 0; } From b4d87af366caf3572f9b897838be6d27874619dd Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 20 Aug 2020 20:40:13 -0600 Subject: [PATCH 033/129] Fixing mt test 4 and removing testing comments --- centrallix/objectsystem/obj_datatypes.c | 8 +++----- centrallix/tests/test_moneytype_04.c | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index ec85f12cb..39966e9ce 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1770,11 +1770,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt } else { - if (m->Value/10000 > iv->Integers[0]) - {cmp_value = -1; printf("Reached -1");} - else if (m->Value/10000 < iv->Integers[0]) - {cmp_value = 1; printf("Reached 1");} - else {cmp_value = iv->Integers[1] - m->Value%10000; printf("Reached 0");} + if (m->Value/10000 > iv->Integers[0]) cmp_value = -1; + else if (m->Value/10000 < iv->Integers[0])cmp_value = 1; + else cmp_value = iv->Integers[1] - m->Value%10000; } break; diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c index 345bff04f..b6d5b9f30 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_04.c @@ -76,7 +76,7 @@ test(char** name) validTestIV.Integers[0] = 7; validTestIV.Integers[1] = 0; - assert(objDataCompare(5,&testIV,7,&test) == 0); + assert(objDataCompare(5,&validTestIV,7,&test) == 0); /** Compare StrV with Money Case **/ StringVec testSV = {0}; From 88bffb8076205775495a5f01720b4bc2b7e41ea7 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 21 Aug 2020 13:03:07 -0600 Subject: [PATCH 034/129] Resolving Code Review comments --- centrallix/.testdepend | 2 -- centrallix/objectsystem/obj_datatypes.c | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) delete mode 100644 centrallix/.testdepend diff --git a/centrallix/.testdepend b/centrallix/.testdepend deleted file mode 100644 index 563e7cb65..000000000 --- a/centrallix/.testdepend +++ /dev/null @@ -1,2 +0,0 @@ - -tests/test_00baseline_07.bin: diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 39966e9ce..49cc02bf8 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -2179,6 +2179,10 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x8000000000000000 to convert to Offset Zero form. **/ + /** Offset Zero form is a signed number representation where all + ** values below a certain bit (usually most significant) are negative + ** and all values above are positive. It allows sorting based on raw bit value. + ** It essentially functions like 2's complement with the sign bit inversed.**/ ((long long*)tmp_buf)[0] = bswap_64(exp->Types.Money.Value ^ 0x8000000000000000); *item = (char*)(tmp_buf); *itemlen = 8; From 7a9a8a37475227efe7d46aaaf01b8ec7c1f55d85 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 24 Aug 2020 18:47:09 -0600 Subject: [PATCH 035/129] Handling roudning, code review comments --- centrallix/expression/exp_evaluate.c | 4 ++-- centrallix/objectsystem/obj_datatypes.c | 1 + centrallix/tests/test_moneytype_03.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index e1b5d8bc2..b1022a58b 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -311,8 +311,8 @@ expEvalDivide(pExpression tree, pParamObjects objlist) } md = i0->Types.Money.Value / 10000.0; md = md / i1->Types.Double; - if (md < 0) md -= 0.5; - else md += 0.5; + //if (md < 0) md -= 0.5; + //else md += 0.5; tree->Types.Money.Value = (long long)(md * 10000); //Old Definition /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 49cc02bf8..d2259dfc2 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1486,6 +1486,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) case DATA_T_DOUBLE: dbl = *(double*)data_ptr * 10000.0; + dbl = round(dbl); m->Value = (long long)dbl; break; diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c index f862c0edd..30a948ec5 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_03.c @@ -33,7 +33,7 @@ test(char** name) //Double Fraction Overflow testDouble = 5.159999999999; assert(objDataToMoney(3,&testDouble,&test) == 0); - assert(test.Value == 51599); + assert(test.Value == 51600); /** Int Case **/ int testInt = 6; From 3f85d4f0745805b3281640799d1b564124a1878e Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 26 Aug 2020 16:09:34 -0600 Subject: [PATCH 036/129] Conversion to 64bit MoneyType in /osdrivers --- centrallix/osdrivers/objdrv_dbl.c | 6 ++++-- centrallix/osdrivers/objdrv_fp.c | 8 +++++--- centrallix/osdrivers/objdrv_sybase.c | 30 ++++++++++++++++------------ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/centrallix/osdrivers/objdrv_dbl.c b/centrallix/osdrivers/objdrv_dbl.c index d1c311bf9..6e70e5a92 100755 --- a/centrallix/osdrivers/objdrv_dbl.c +++ b/centrallix/osdrivers/objdrv_dbl.c @@ -1654,13 +1654,15 @@ dbl_internal_ParseColumn(pDblColInf column, pObjData pod, char* data, char* row_ f = 1; for(i=0;iDecimalOffset;i++) f *= 10; pod->Money = (pMoneyType)data; - pod->Money->WholePart = v/f; + pod->Money->Value = (v/f) * 10000; + //pod->Money->WholePart = v/f; v = (v/f)*f; if (column->DecimalOffset <= 4) for(i=column->DecimalOffset;i<4;i++) v *= 10; else for(i=4;iDecimalOffset;i++) v /= 10; - pod->Money->FractionPart = v; + //pod->Money->FractionPart = v; + pod->Money->Value += v; break; default: mssError(1, "DBL", "Bark! Unhandled data type for column '%s'", column->Name); diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 62c1deb11..16c4b63fb 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1227,7 +1227,7 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da case DATA_T_INTEGER: if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; pod->Integer = strtoi(ibuf, NULL, 10); - break; + break case DATA_T_STRING: pod->String = data; if (fp_internal_MappedCopy(data, column->Length+1, column, row_data) < 0) return -1; @@ -1248,13 +1248,15 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da f = 1; for(i=0;iDecimalOffset;i++) f *= 10; pod->Money = (pMoneyType)data; - pod->Money->WholePart = v/f; + pod->Money->Value = (v/f) * 10000; + //pod->Money->WholePart = v/f; v = (v/f)*f; if (column->DecimalOffset <= 4) for(i=column->DecimalOffset;i<4;i++) v *= 10; else for(i=4;iDecimalOffset;i++) v /= 10; - pod->Money->FractionPart = v; + pod->Money->Value += v; + //pod->Money->FractionPart = v; break; default: mssError(1, "FP", "Bark! Unhandled data type for column '%s'", column->Name); diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 50d408797..a8e9304cc 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -775,9 +775,10 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) { /** smallmoney, 4-byte **/ memcpy(&i, ptr, 4); - val->Money->WholePart = i/10000; - if (i < 0 && (i%10000) != 0) val->Money->WholePart--; - val->Money->FractionPart = i - (val->Money->WholePart*10000); + val->Money->Value = i; + //val->Money->WholePart = i/10000; + //if (i < 0 && (i%10000) != 0) val->Money->WholePart--; + //val->Money->FractionPart = i - (val->Money->WholePart*10000); return 0; } else @@ -807,17 +808,20 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) divtmp = msl/10000; n = (n<<16) + divtmp; msl -= divtmp*10000; - val->Money->WholePart = n; - val->Money->FractionPart = msl; + val->Money->Value = (n*10000) + msl; if (minus) - { - val->Money->WholePart = -val->Money->WholePart; - if (val->Money->FractionPart > 0) - { - val->Money->WholePart--; - val->Money->FractionPart = 10000 - val->Money->FractionPart; - } - } + val->Money->Value = -val->Money->Value; + //val->Money->WholePart = n; + //val->Money->FractionPart = msl; + //if (minus) + // { + // val->Money->WholePart = -val->Money->WholePart; + // if (val->Money->FractionPart > 0) + // { + // val->Money->WholePart--; + // val->Money->FractionPart = 10000 - val->Money->FractionPart; + // } + // } return 0; } } From 925a6826052cae8f39e58ebdcd5db1d815b59404 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 1 Sep 2020 15:59:14 -0600 Subject: [PATCH 037/129] Remaining miscellaneous conversions to 64 bit moneytype --- centrallix-lib/src/net_raw_api.c | 8 ++++---- centrallix/netdrivers/net_http_rest.c | 8 ++++---- centrallix/utility/json_util.c | 2 ++ centrallix/utility/obfuscate.c | 2 ++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/centrallix-lib/src/net_raw_api.c b/centrallix-lib/src/net_raw_api.c index 87db4ab67..cb138d723 100644 --- a/centrallix-lib/src/net_raw_api.c +++ b/centrallix-lib/src/net_raw_api.c @@ -106,7 +106,7 @@ raw_internal_SkipCmd(pNetManagedConn conn, pNetCmdHeader cmd) case NET_PARAM_REF: len = 4; break; case NET_PARAM_DOUBLE: len = 8; break; case NET_PARAM_DATETIME: len= 5; break; - case NET_PARAM_MONEY: len = 6; break; + case NET_PARAM_MONEY: len = 8; break; case NET_PARAM_NULL: len = 0; break; case NET_PARAM_STRING: rcnt = fdRead(conn->ConnFD, &len, 4, 0, FD_U_PACKET); @@ -192,7 +192,7 @@ rawSendParam(pNetManagedConn conn, char param_type, pObjData value, int cmd_id) break; case NET_PARAM_MONEY: - memcpy(buf+1, value->Money, 6); + memcpy(buf+1, value->Money, 8); len = 7; break; @@ -276,10 +276,10 @@ raw_internal_NextParam(pNetManagedConn conn, char expected_type, char* param_typ value->Money = nmMalloc(sizeof(MoneyType)); if (!value->Money) { - raw_internal_ReadBytes(conn, 6); + raw_internal_ReadBytes(conn, 8); return -1; } - fdRead(conn->ConnFD, value->Money, 6, 0, FD_U_PACKET); + fdRead(conn->ConnFD, value->Money, 8, 0, FD_U_PACKET); break; case NET_PARAM_DATETIME: diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index ae9546dd0..d73589109 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -114,10 +114,10 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty break; case DATA_T_MONEY: - /*Carl nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", - od.Money->WholePart, - od.Money->FractionPart - );*/ + nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", + od.Money->Value/10000, + od.Money->Value%10000 + ); break; default: diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index 0e800f987..a2c9f15c8 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -236,11 +236,13 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) { has_whole = 1; //m->WholePart = json_object_get_int(iter.val); + m->Value += json_object_get_int(iter.val) * 10000; } else if (!strcmp(iter.key, "fractionpart")) { has_fraction = 1; //m->FractionPart = json_object_get_int(iter.val); + m->Value += json_object_get_int(iter.val); } else { diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index 98606dbf0..286724b67 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1201,6 +1201,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname case DATA_T_MONEY: //iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); + iv = srcval->Money->Value/10000 * 100 + (srcval->Money->Value%10000 / 100); if (strchr(param,'i')) dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); else @@ -1211,6 +1212,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname } //m.WholePart = floor(dv/100.0); //m.FractionPart = (dv - m.WholePart*100) * 100; + m.Value = dv * 100; dstval->Money = &m; break; From a83b8c8f76c1553c1742dfc23cdb61ca99604bc2 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 3 Sep 2020 15:02:18 -0600 Subject: [PATCH 038/129] obj_internal_BuildBinaryItem Expression initialization and hex comparison --- centrallix/tests/test_moneytype_06.c | 45 ++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/centrallix/tests/test_moneytype_06.c b/centrallix/tests/test_moneytype_06.c index 9df19b1a9..6317ee996 100644 --- a/centrallix/tests/test_moneytype_06.c +++ b/centrallix/tests/test_moneytype_06.c @@ -9,20 +9,53 @@ test(char** name) { *name = "moneytype_06 - obj_internal_BuildBinaryItem"; char** item; + item = (char**)malloc(24); int* itemlen; + itemlen = (int*)malloc(4); + + //Creating an ObjData with a moneytype inside, pObjData for parameters + ObjData moneyData; + MoneyType unionFiller = {70000}; + moneyData.Money = &unionFiller; + pObjData moneyDataPtr = &moneyData; + + //Utilizing expression.h functions to initialize expression and paramobjects pExpression testExp = expAllocExpression(); pParamObjects testParamObjects = expCreateParamList(); + + //Buffer must be at least 12 bytes unsigned char tmpbuf[12]; - /** Positive Case **/ - testExp->Types.Money.Value = 90000; + /** NULL Case **/ assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + /** Positive Case **/ + testExp = expPodToExpression(moneyDataPtr, 7, testExp); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); + + assert(tmpbuf[0] == 0x80); + assert(tmpbuf[1] == 0x0); + assert(tmpbuf[2] == 0x0); + assert(tmpbuf[3] == 0x0); + assert(tmpbuf[4] == 0x0); + assert(tmpbuf[5] == 0x1); + assert(tmpbuf[6] == 0x11); + assert(tmpbuf[7] == 0x70); + /** Negative Case **/ - //test.Value = -70500; - //data_ptr = "Negative Seven And 05/100 "; - //returnStr = objDataToWords(7,&test); - //assert(strcmp(data_ptr, returnStr) == 0); + unionFiller.Value = -70000; + + testExp = expPodToExpression(moneyDataPtr, 7, testExp); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); + + assert(tmpbuf[0] == 0x7f); + assert(tmpbuf[1] == 0xff); + assert(tmpbuf[2] == 0xff); + assert(tmpbuf[3] == 0xff); + assert(tmpbuf[4] == 0xff); + assert(tmpbuf[5] == 0xfe); + assert(tmpbuf[6] == 0xee); + assert(tmpbuf[7] == 0x90); expFreeExpression(testExp); From f597aec62094c5c937259dffa1df16d36f03f3b1 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 3 Sep 2020 18:32:47 -0600 Subject: [PATCH 039/129] Renamed tests to be more specific --- ...est_moneytype_fp_internal_ParseColumn_00.c | 35 +++++++++++++++++++ ...4.c => test_moneytype_objDataCompare_00.c} | 2 +- ....c => test_moneytype_objDataToDouble_00.c} | 2 +- ...c => test_moneytype_objDataToInteger_00.c} | 2 +- ...3.c => test_moneytype_objDataToMoney_00.c} | 2 +- ...5.c => test_moneytype_objDataToWords_00.c} | 2 +- ...neytype_obj_internal_BuildBinaryItem_00.c} | 2 +- ...t_moneytype_obj_internal_FormatMoney_00.c} | 0 8 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c rename centrallix/tests/{test_moneytype_04.c => test_moneytype_objDataCompare_00.c} (98%) rename centrallix/tests/{test_moneytype_02.c => test_moneytype_objDataToDouble_00.c} (91%) rename centrallix/tests/{test_moneytype_01.c => test_moneytype_objDataToInteger_00.c} (95%) rename centrallix/tests/{test_moneytype_03.c => test_moneytype_objDataToMoney_00.c} (96%) rename centrallix/tests/{test_moneytype_05.c => test_moneytype_objDataToWords_00.c} (95%) rename centrallix/tests/{test_moneytype_06.c => test_moneytype_obj_internal_BuildBinaryItem_00.c} (96%) rename centrallix/tests/{test_moneytype_00.c => test_moneytype_obj_internal_FormatMoney_00.c} (100%) diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c new file mode 100644 index 000000000..37b560c5b --- /dev/null +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -0,0 +1,35 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" + +long long +test(char** name) +{ + *name = "moneytype_00 - fp_internal_ParseColumn"; + char** item; + int* itemlen; + pExpression testExp = expAllocExpression(); + pParamObjects testParamObjects = expCreateParamList(); + unsigned char tmpbuf[12]; + + /** NULL Case **/ + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + + /** Positive Case **/ + testExp->Types.Money.Value = 90000; + testExp->DataType = DATA_T_MONEY; + testExp->NodeType = EXPR_N_MONEY; + + + /** Negative Case **/ + //test.Value = -70500; + //data_ptr = "Negative Seven And 05/100 "; + //returnStr = objDataToWords(7,&test); + //assert(strcmp(data_ptr, returnStr) == 0); + + expFreeExpression(testExp); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_objDataCompare_00.c similarity index 98% rename from centrallix/tests/test_moneytype_04.c rename to centrallix/tests/test_moneytype_objDataCompare_00.c index b6d5b9f30..524c74a44 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_objDataCompare_00.c @@ -6,7 +6,7 @@ long long test(char** name) { - *name = "moneytype_04 - objDataCompare"; + *name = "moneytype_00 - objDataCompare"; MoneyType test = {70000}; /** Compare Int with Money Case **/ diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_objDataToDouble_00.c similarity index 91% rename from centrallix/tests/test_moneytype_02.c rename to centrallix/tests/test_moneytype_objDataToDouble_00.c index d2dfd1e97..6b86ea384 100644 --- a/centrallix/tests/test_moneytype_02.c +++ b/centrallix/tests/test_moneytype_objDataToDouble_00.c @@ -4,7 +4,7 @@ long long test(char** name) { - *name = "moneytype_02 - objDataToDouble"; + *name = "moneytype_00 - objDataToDouble"; /** Zero Case **/ MoneyType test = {0}; diff --git a/centrallix/tests/test_moneytype_01.c b/centrallix/tests/test_moneytype_objDataToInteger_00.c similarity index 95% rename from centrallix/tests/test_moneytype_01.c rename to centrallix/tests/test_moneytype_objDataToInteger_00.c index b66efe70d..9dc71ec01 100644 --- a/centrallix/tests/test_moneytype_01.c +++ b/centrallix/tests/test_moneytype_objDataToInteger_00.c @@ -8,7 +8,7 @@ long long test(char** name) { - *name = "moneytype_01 - objDataToInteger"; + *name = "moneytype_00 - objDataToInteger"; /** Zero Case **/ MoneyType test = {0}; diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_objDataToMoney_00.c similarity index 96% rename from centrallix/tests/test_moneytype_03.c rename to centrallix/tests/test_moneytype_objDataToMoney_00.c index 30a948ec5..8a2f0c031 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_objDataToMoney_00.c @@ -5,7 +5,7 @@ long long test(char** name) { - *name = "moneytype_03 - objDataToMoney"; + *name = "moneytype_00 - objDataToMoney"; MoneyType test = {0}; /** String Case **/ diff --git a/centrallix/tests/test_moneytype_05.c b/centrallix/tests/test_moneytype_objDataToWords_00.c similarity index 95% rename from centrallix/tests/test_moneytype_05.c rename to centrallix/tests/test_moneytype_objDataToWords_00.c index b9caac0cb..9722b6ec1 100644 --- a/centrallix/tests/test_moneytype_05.c +++ b/centrallix/tests/test_moneytype_objDataToWords_00.c @@ -7,7 +7,7 @@ long long test(char** name) { - *name = "moneytype_05 - objDataToWords"; + *name = "moneytype_00 - objDataToWords"; MoneyType test = {70500}; /** Positive Case **/ diff --git a/centrallix/tests/test_moneytype_06.c b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c similarity index 96% rename from centrallix/tests/test_moneytype_06.c rename to centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c index 6317ee996..15641f10a 100644 --- a/centrallix/tests/test_moneytype_06.c +++ b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c @@ -7,7 +7,7 @@ long long test(char** name) { - *name = "moneytype_06 - obj_internal_BuildBinaryItem"; + *name = "moneytype_00 - obj_internal_BuildBinaryItem"; char** item; item = (char**)malloc(24); int* itemlen; diff --git a/centrallix/tests/test_moneytype_00.c b/centrallix/tests/test_moneytype_obj_internal_FormatMoney_00.c similarity index 100% rename from centrallix/tests/test_moneytype_00.c rename to centrallix/tests/test_moneytype_obj_internal_FormatMoney_00.c From ec90c3883baf15bbf9e2f9aa31b5608111f5534d Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 8 Sep 2020 16:56:42 -0600 Subject: [PATCH 040/129] Resolving Code Review comments and Expression Testing --- centrallix-lib/src/net_raw_api.c | 2 +- centrallix/expression/exp_evaluate.c | 3 +-- centrallix/osdrivers/objdrv_fp.c | 2 +- .../tests/test_moneytype_fp_internal_ParseColumn_00.c | 6 ++++++ centrallix/utility/json_util.c | 1 + 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/centrallix-lib/src/net_raw_api.c b/centrallix-lib/src/net_raw_api.c index cb138d723..aac822aee 100644 --- a/centrallix-lib/src/net_raw_api.c +++ b/centrallix-lib/src/net_raw_api.c @@ -193,7 +193,7 @@ rawSendParam(pNetManagedConn conn, char param_type, pObjData value, int cmd_id) case NET_PARAM_MONEY: memcpy(buf+1, value->Money, 8); - len = 7; + len = 9; break; case NET_PARAM_NULL: diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index b1022a58b..e66628f07 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -423,8 +423,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - //mv *= i0->Integer; + mv = i1->Types.Money.Value * i0->Integer; break; case DATA_T_STRING: tree->DataType = DATA_T_STRING; diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 16c4b63fb..9b54ed69d 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1227,7 +1227,7 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da case DATA_T_INTEGER: if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; pod->Integer = strtoi(ibuf, NULL, 10); - break + break; case DATA_T_STRING: pod->String = data; if (fp_internal_MappedCopy(data, column->Length+1, column, row_data) < 0) return -1; diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index 37b560c5b..b3f626a42 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -8,6 +8,12 @@ long long test(char** name) { *name = "moneytype_00 - fp_internal_ParseColumn"; + + FpColInf testColInf = {0}; + pFpColInf testColInfPtr = &FpColInf; + + + char** item; int* itemlen; pExpression testExp = expAllocExpression(); diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index a2c9f15c8..f1c0120f0 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -228,6 +228,7 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) /** Search the object's properties **/ memset(m, 0, sizeof(MoneyType)); + m->Value = 0; json_object_object_foreachC(jobj, iter) { if (json_object_is_type(iter.val, json_type_int)) From 4d00e6e6acc739e47415cb142b53de975bef2ddf Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 22 Sep 2020 23:22:40 -0600 Subject: [PATCH 041/129] Initial setup for ParseColumn; Creation of Obfuscate Test --- ...est_moneytype_fp_internal_ParseColumn_00.c | 25 +++++++++++-------- .../tests/test_moneytype_obfuscate_00.c | 16 ++++++++++++ ...oneytype_obj_internal_BuildBinaryItem_00.c | 12 ++++----- centrallix/utility/obfuscate.c | 3 --- 4 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 centrallix/tests/test_moneytype_obfuscate_00.c diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index b3f626a42..611ab9988 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -3,25 +3,32 @@ #include #include "expression.h" #include "cxlib/xstring.h" +#include "osdrivers/objdrv_fp.c" long long test(char** name) { *name = "moneytype_00 - fp_internal_ParseColumn"; - FpColInf testColInf = {0}; - pFpColInf testColInfPtr = &FpColInf; + //FpColInf testColInf = {0}; + pFpColInf = &FpColInf; + //7 for money type + FpColInf.Type = 7; + FpColInf.Length = 8; + FpColInf.RecordOffset = 0; + FpColInf.DecimalOffset = 4; + ObjData moneyData; + pObjData moneyDataPtr = &moneyData; + MoneyType testMoneyData = {0}; + pMoneyType pTestMoneyData = &testMoneyData; + //Raw data for row data. + char* testString = "450"; - char** item; - int* itemlen; - pExpression testExp = expAllocExpression(); - pParamObjects testParamObjects = expCreateParamList(); - unsigned char tmpbuf[12]; + assert(fp_internal_ParseColumn(pFpColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); /** NULL Case **/ - assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); /** Positive Case **/ testExp->Types.Money.Value = 90000; @@ -35,7 +42,5 @@ test(char** name) //returnStr = objDataToWords(7,&test); //assert(strcmp(data_ptr, returnStr) == 0); - expFreeExpression(testExp); - return 0; } diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c new file mode 100644 index 000000000..a34d1c934 --- /dev/null +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -0,0 +1,16 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" +#include "utility/obfuscate.c" + +long long +test(char** name) +{ + *name = "moneytype_00 - obfuscate"; + + obfObfuscateData(); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c index 15641f10a..0b854d39d 100644 --- a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c +++ b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c @@ -13,12 +13,6 @@ test(char** name) int* itemlen; itemlen = (int*)malloc(4); - //Creating an ObjData with a moneytype inside, pObjData for parameters - ObjData moneyData; - MoneyType unionFiller = {70000}; - moneyData.Money = &unionFiller; - pObjData moneyDataPtr = &moneyData; - //Utilizing expression.h functions to initialize expression and paramobjects pExpression testExp = expAllocExpression(); pParamObjects testParamObjects = expCreateParamList(); @@ -29,6 +23,12 @@ test(char** name) /** NULL Case **/ assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + //For remaining cases, creating an ObjData with a moneytype inside, pObjData for parameters + ObjData moneyData; + MoneyType unionFiller = {70000}; + moneyData.Money = &unionFiller; + pObjData moneyDataPtr = &moneyData; + /** Positive Case **/ testExp = expPodToExpression(moneyDataPtr, 7, testExp); assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index 286724b67..2ee98ab80 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1200,7 +1200,6 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname break; case DATA_T_MONEY: - //iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); iv = srcval->Money->Value/10000 * 100 + (srcval->Money->Value%10000 / 100); if (strchr(param,'i')) dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); @@ -1210,8 +1209,6 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = iv/10 + 1; dv = obf_internal_ObfuscateInteger(hash, hash_novalue, &bitcnt, iv); } - //m.WholePart = floor(dv/100.0); - //m.FractionPart = (dv - m.WholePart*100) * 100; m.Value = dv * 100; dstval->Money = &m; break; From d72779125d6dd27bef507910c447994400c3e184 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 28 Sep 2020 23:38:44 -0600 Subject: [PATCH 042/129] Working fp_internal_ParseColumn function and testing for 64bit MoneyType --- centrallix/osdrivers/objdrv_fp.c | 18 +++---- ...est_moneytype_fp_internal_ParseColumn_00.c | 48 ++++++++++--------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 9b54ed69d..86816031d 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1221,6 +1221,7 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da char dtbuf[32]; unsigned long long v; int i,f; + double decimalOffsetValue = 10000; switch(column->Type) { @@ -1243,20 +1244,15 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da if (column->DecimalOffset) pod->Double /= pow(10, column->DecimalOffset); break; case DATA_T_MONEY: + //decimalOffsetValue is originally 10000 to convert v to 10000ths of a dollar + //decimalOffsetValue is divided by 10, column->DecimalOffset times, + //keeping the decimal as a double in case it drops below 0 + //Finally, I multiple v by decimalOffsetValue to get my Money->Value if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; v = strtoll(ibuf, NULL, 10); - f = 1; - for(i=0;iDecimalOffset;i++) f *= 10; + for (i=0; iDecimalOffset; i++) decimalOffsetValue /= 10.0; pod->Money = (pMoneyType)data; - pod->Money->Value = (v/f) * 10000; - //pod->Money->WholePart = v/f; - v = (v/f)*f; - if (column->DecimalOffset <= 4) - for(i=column->DecimalOffset;i<4;i++) v *= 10; - else - for(i=4;iDecimalOffset;i++) v /= 10; - pod->Money->Value += v; - //pod->Money->FractionPart = v; + pod->Money->Value = v*decimalOffsetValue; break; default: mssError(1, "FP", "Bark! Unhandled data type for column '%s'", column->Name); diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index 611ab9988..cc1b671ec 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -10,37 +10,41 @@ test(char** name) { *name = "moneytype_00 - fp_internal_ParseColumn"; - //FpColInf testColInf = {0}; - pFpColInf = &FpColInf; + //This Test is making the assumption that the raw data passed in testString here (row_data in objdrv_fp.c) + //is in units dollars. So, the function now converts it to 1/10000ths like the new moneyType requires. + + FpColInf testColInf = {0}; + pFpColInf pTestColInf = &testColInf; //7 for money type - FpColInf.Type = 7; - FpColInf.Length = 8; - FpColInf.RecordOffset = 0; - FpColInf.DecimalOffset = 4; + testColInf.Type = 7; + testColInf.Length = 8; + testColInf.RecordOffset = 0; + testColInf.DecimalOffset = 0; ObjData moneyData; pObjData moneyDataPtr = &moneyData; MoneyType testMoneyData = {0}; pMoneyType pTestMoneyData = &testMoneyData; - + + /** No Decimal Offset Case **/ //Raw data for row data. char* testString = "450"; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); - assert(fp_internal_ParseColumn(pFpColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); - - /** NULL Case **/ - - /** Positive Case **/ - testExp->Types.Money.Value = 90000; - testExp->DataType = DATA_T_MONEY; - testExp->NodeType = EXPR_N_MONEY; - - - /** Negative Case **/ - //test.Value = -70500; - //data_ptr = "Negative Seven And 05/100 "; - //returnStr = objDataToWords(7,&test); - //assert(strcmp(data_ptr, returnStr) == 0); + assert(moneyDataPtr->Money->Value == 4500000); + /** Decimal Offset, Value > 1 Case **/ + //Value will be greater than one after dividing by + //10 a DecimalOffset # of times + testColInf.DecimalOffset = 1; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); + assert(moneyDataPtr->Money->Value == 450000); + + /** Decimal Offset, Value < 1 Case **/ + testColInf.DecimalOffset = 3; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); + assert(moneyDataPtr->Money->Value == 4500); + + return 0; } From 1d8e5897d4d6c3cde8537bc41512711975983df9 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 9 Dec 2020 18:53:36 -0700 Subject: [PATCH 043/129] Added ll const tag to literals. Removed old comments in json_util.c. --- centrallix/expression/exp_evaluate.c | 6 +++--- centrallix/objectsystem/obj_datatypes.c | 4 ++-- centrallix/utility/json_util.c | 4 +--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index e66628f07..18a45435b 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -629,7 +629,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; /** Since Value is in 1/10000 of a dollar, integer must be multiplied to scale **/ - tree->Types.Money.Value = i0->Types.Money.Value - (i1->Integer * 10000); + tree->Types.Money.Value = i0->Types.Money.Value - (i1->Integer * 10000ll); break; case DATA_T_DOUBLE: tree->DataType = DATA_T_DOUBLE; @@ -772,7 +772,7 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; /** Int must be converted to 1/10000 of a dollar **/ - tree->Types.Money.Value = i1->Types.Money.Value + (i0->Integer * 10000); + tree->Types.Money.Value = i1->Types.Money.Value + (i0->Integer * 10000ll); break; default: @@ -1457,7 +1457,7 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) } else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { - tree->Types.Money.Value = (tree->Integer * 10000); + tree->Types.Money.Value = (tree->Integer * 10000ll); } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index d2259dfc2..b4424a181 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1450,9 +1450,9 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) if ((endptr - ptr) != strspn(ptr, "0123456789")) return -1; if (is_neg) - m->Value = -intval*10000; + m->Value = -intval*10000ll; else - m->Value = intval*10000; + m->Value = intval*10000ll; /** Handling the "fraction" portion after the decimal point **/ if (*endptr == (intl_format?',':'.')) diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index f1c0120f0..eb1400d48 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -236,13 +236,11 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) if (!strcmp(iter.key, "wholepart")) { has_whole = 1; - //m->WholePart = json_object_get_int(iter.val); - m->Value += json_object_get_int(iter.val) * 10000; + m->Value += json_object_get_int(iter.val) * 10000ll; } else if (!strcmp(iter.key, "fractionpart")) { has_fraction = 1; - //m->FractionPart = json_object_get_int(iter.val); m->Value += json_object_get_int(iter.val); } else From e224e66fdd5e01eddcd0568b3c0e3c4aacdaf048 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 9 Dec 2020 19:19:16 -0700 Subject: [PATCH 044/129] Added ll const tag to literals. Cleaned up math and comparisons --- centrallix/expression/exp_compiler.c | 2 +- centrallix/expression/exp_evaluate.c | 38 ++----------------------- centrallix/objectsystem/obj_datatypes.c | 8 +++--- centrallix/osdrivers/objdrv_sybase.c | 2 +- 4 files changed, 8 insertions(+), 42 deletions(-) diff --git a/centrallix/expression/exp_compiler.c b/centrallix/expression/exp_compiler.c index d47bea653..28a6f48f2 100644 --- a/centrallix/expression/exp_compiler.c +++ b/centrallix/expression/exp_compiler.c @@ -152,7 +152,7 @@ exp_internal_CompileExpression_r(pLxSession lxs, int level, pParamObjects objlis if (t == MLX_TOK_INTEGER) { i = mlxIntVal(lxs); - etmp->Types.Money.Value = (i * 10000); + etmp->Types.Money.Value = (i * 10000ll); } else { diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index 18a45435b..c216b27f4 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -191,7 +191,6 @@ expEvalDivide(pExpression tree, pParamObjects objlist) pExpression i0,i1; MoneyType m; int i; - int is_negative = 0; long long mv, mv2; double md; @@ -280,27 +279,12 @@ expEvalDivide(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; memcpy(&m, &(i0->Types.Money), sizeof(MoneyType)); - if (m.Value < 0) - { - is_negative = !is_negative; - m.Value = -m.Value; - } - i = i1->Integer; - if (i < 0) - { - i = -i; - is_negative = !is_negative; - } if (i == 0) { mssError(1,"EXP","Attempted divide by zero"); return -1; } tree->Types.Money.Value = m.Value / i; - if (is_negative) - { - tree->Types.Money.Value = -tree->Types.Money.Value; - } break; case DATA_T_DOUBLE: tree->DataType = DATA_T_MONEY; @@ -309,25 +293,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - md = i0->Types.Money.Value / 10000.0; - md = md / i1->Types.Double; - //if (md < 0) md -= 0.5; - //else md += 0.5; - tree->Types.Money.Value = (long long)(md * 10000); - //Old Definition - /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; - md = mv / i1->Types.Double; - if (md < 0) md -= 0.5; - else md += 0.5; - mv = md; - tree->Types.Money.WholePart = mv/10000; - mv = mv % 10000; - if (mv < 0) - { - mv += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mv;*/ + tree->Types.Money.Value = (long long)(i0->Types.Money.Value/i1->Types.Double); break; case DATA_T_MONEY: mv = i0->Types.Money.Value; @@ -593,7 +559,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: /** Treat Int as a dollar value **/ tree->DataType = DATA_T_MONEY; - tree->Types.Money.Value = (i0->Integer * 10000) - i1->Types.Money.Value; + tree->Types.Money.Value = (i0->Integer * 10000ll) - i1->Types.Money.Value; break; default: tree->Integer = i0->Integer - objDataToInteger(i1->DataType, dptr, NULL); diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index b4424a181..85b90e15a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1491,7 +1491,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) break; case DATA_T_INTEGER: - m->Value = *(int*)data_ptr * 10000; + m->Value = *(int*)data_ptr * 10000ll; break; case DATA_T_MONEY: @@ -1576,9 +1576,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: m = (pMoneyType)data_ptr_2; - if (m->Value/10000 > intval) cmp_value = -1; - else if (m->Value/10000 < intval) cmp_value = 1; - else cmp_value = m->Value%10000?-1:0; + if (m->Value > intval*10000ll) cmp_value = -1; + else if (m->Value < intval*10000ll) cmp_value = 1; + else cmp_value = 0; break; case DATA_T_INTVEC: diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index a8e9304cc..dde7be337 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -808,7 +808,7 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) divtmp = msl/10000; n = (n<<16) + divtmp; msl -= divtmp*10000; - val->Money->Value = (n*10000) + msl; + val->Money->Value = (n*10000ll) + msl; if (minus) val->Money->Value = -val->Money->Value; //val->Money->WholePart = n; From 669e7eb1733c4589ce8c497fe18c08e0a06ae330 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 10 Dec 2020 18:14:52 -0700 Subject: [PATCH 045/129] Resolving code review comments. Comments for obj, and comparison for BuildBinaryItem --- centrallix/objectsystem/obj_datatypes.c | 4 +- ...oneytype_obj_internal_BuildBinaryItem_00.c | 43 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 85b90e15a..8dc39db0c 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -802,8 +802,8 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - if (m->Value/10000 > INT_MAX) - mssError(1, "OBJ", "Warning: %d overflow; cannot fit value of that size in int ", data_type); + if (m->Value/10000 > INT_MAX || m->Value/10000 < INT_MIN) + mssError(1, "OBJ", "Warning: %d (MoneyType) overflow; cannot fit value of that size in int", data_type); else v = m->Value/10000; break; diff --git a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c index 0b854d39d..676de1281 100644 --- a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c +++ b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c @@ -15,49 +15,50 @@ test(char** name) //Utilizing expression.h functions to initialize expression and paramobjects pExpression testExp = expAllocExpression(); + pExpression testExpCmp = expAllocExpression(); pParamObjects testParamObjects = expCreateParamList(); - //Buffer must be at least 12 bytes + //Buffer must be at least 12 bytes for data types not yet implemented. + //Current highest byte size is 9, but 12 may come later unsigned char tmpbuf[12]; + unsigned char cmpbuf[12]; /** NULL Case **/ assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); - //For remaining cases, creating an ObjData with a moneytype inside, pObjData for parameters + //For remaining cases, creating two ObjData with a moneytype inside, pObjData for parameters + //After passing through BuildBinaryItem, they will be compared with memcmp() because it is not the binary value + //itself that matters, but the comparison between the two objects. ObjData moneyData; MoneyType unionFiller = {70000}; moneyData.Money = &unionFiller; pObjData moneyDataPtr = &moneyData; + + ObjData moneyDataCmp; + MoneyType unionFiller2 = {65000}; + moneyDataCmp.Money = &unionFiller2; + pObjData moneyDataPtrCmp = &moneyDataCmp; /** Positive Case **/ testExp = expPodToExpression(moneyDataPtr, 7, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExpCmp, testParamObjects, cmpbuf) == 0); - assert(tmpbuf[0] == 0x80); - assert(tmpbuf[1] == 0x0); - assert(tmpbuf[2] == 0x0); - assert(tmpbuf[3] == 0x0); - assert(tmpbuf[4] == 0x0); - assert(tmpbuf[5] == 0x1); - assert(tmpbuf[6] == 0x11); - assert(tmpbuf[7] == 0x70); + assert(memcmp(tmpbuf,cmpbuf,8) > 0); /** Negative Case **/ unionFiller.Value = -70000; - + unionFiller2.Value = -65000; testExp = expPodToExpression(moneyDataPtr, 7, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); - - assert(tmpbuf[0] == 0x7f); - assert(tmpbuf[1] == 0xff); - assert(tmpbuf[2] == 0xff); - assert(tmpbuf[3] == 0xff); - assert(tmpbuf[4] == 0xff); - assert(tmpbuf[5] == 0xfe); - assert(tmpbuf[6] == 0xee); - assert(tmpbuf[7] == 0x90); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExpCmp, testParamObjects, cmpbuf) == 0); + + assert(memcmp(tmpbuf,cmpbuf,8) < 0); expFreeExpression(testExp); - + expFreeExpression(testExpCmp); + return 0; } From 6b5f5ed78c86c930cffbc355902255881d3b4cb6 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 10 Dec 2020 18:18:57 -0700 Subject: [PATCH 046/129] Updated QPrintf documentation. Added %LL specifier and shifted IDs for QPrintf. Attempted adding a case for %LL --- centrallix-lib/src/qprintf.c | 97 +++++++++++++++++++---------------- centrallix-sysdoc/QPrintf.txt | 3 ++ 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/centrallix-lib/src/qprintf.c b/centrallix-lib/src/qprintf.c index a377157d3..2490b7699 100644 --- a/centrallix-lib/src/qprintf.c +++ b/centrallix-lib/src/qprintf.c @@ -59,46 +59,47 @@ #define QPF_SPEC_T_NSTR (5) #define QPF_SPEC_T_CHR (6) #define QPF_SPEC_T_ENDSRC (6) +#define QPF_SPEC_T_LL (7) /*** builtin filtering specifiers ***/ -#define QPF_SPEC_T_STARTFILT (7) -#define QPF_SPEC_T_QUOT (7) -#define QPF_SPEC_T_DQUOT (8) -#define QPF_SPEC_T_SYM (9) -#define QPF_SPEC_T_JSSTR (10) -#define QPF_SPEC_T_NLEN (11) -#define QPF_SPEC_T_WS (12) -#define QPF_SPEC_T_ESCWS (13) -#define QPF_SPEC_T_ESCSP (14) -#define QPF_SPEC_T_UNESC (15) -#define QPF_SPEC_T_SSYB (16) -#define QPF_SPEC_T_DSYB (17) -#define QPF_SPEC_T_FILE (18) -#define QPF_SPEC_T_PATH (19) -#define QPF_SPEC_T_HEX (20) -#define QPF_SPEC_T_DHEX (21) -#define QPF_SPEC_T_B64 (22) -#define QPF_SPEC_T_DB64 (23) -#define QPF_SPEC_T_RF (24) -#define QPF_SPEC_T_RR (25) -#define QPF_SPEC_T_HTENLBR (26) -#define QPF_SPEC_T_DHTE (27) -#define QPF_SPEC_T_URL (28) -#define QPF_SPEC_T_DURL (29) -#define QPF_SPEC_T_NLSET (30) -#define QPF_SPEC_T_NRSET (31) -#define QPF_SPEC_T_NZRSET (32) -#define QPF_SPEC_T_SQLARG (33) -#define QPF_SPEC_T_SQLSYM (34) -#define QPF_SPEC_T_HTDATA (35) -#define QPF_SPEC_T_HTE (36) -#define QPF_SPEC_T_ESCQWS (37) -#define QPF_SPEC_T_ESCQ (38) -#define QPF_SPEC_T_CSSVAL (39) -#define QPF_SPEC_T_CSSURL (40) -#define QPF_SPEC_T_JSONSTR (41) -#define QPF_SPEC_T_ENDFILT (41) -#define QPF_SPEC_T_MAXSPEC (41) +#define QPF_SPEC_T_STARTFILT (8) +#define QPF_SPEC_T_QUOT (8) +#define QPF_SPEC_T_DQUOT (9) +#define QPF_SPEC_T_SYM (10) +#define QPF_SPEC_T_JSSTR (11) +#define QPF_SPEC_T_NLEN (12) +#define QPF_SPEC_T_WS (13) +#define QPF_SPEC_T_ESCWS (14) +#define QPF_SPEC_T_ESCSP (15) +#define QPF_SPEC_T_UNESC (16) +#define QPF_SPEC_T_SSYB (17) +#define QPF_SPEC_T_DSYB (18) +#define QPF_SPEC_T_FILE (19) +#define QPF_SPEC_T_PATH (20) +#define QPF_SPEC_T_HEX (21) +#define QPF_SPEC_T_DHEX (22) +#define QPF_SPEC_T_B64 (23) +#define QPF_SPEC_T_DB64 (24) +#define QPF_SPEC_T_RF (25) +#define QPF_SPEC_T_RR (26) +#define QPF_SPEC_T_HTENLBR (27) +#define QPF_SPEC_T_DHTE (28) +#define QPF_SPEC_T_URL (29) +#define QPF_SPEC_T_DURL (30) +#define QPF_SPEC_T_NLSET (31) +#define QPF_SPEC_T_NRSET (32) +#define QPF_SPEC_T_NZRSET (33) +#define QPF_SPEC_T_SQLARG (34) +#define QPF_SPEC_T_SQLSYM (35) +#define QPF_SPEC_T_HTDATA (36) +#define QPF_SPEC_T_HTE (37) +#define QPF_SPEC_T_ESCQWS (38) +#define QPF_SPEC_T_ESCQ (39) +#define QPF_SPEC_T_CSSVAL (40) +#define QPF_SPEC_T_CSSURL (41) +#define QPF_SPEC_T_JSONSTR (42) +#define QPF_SPEC_T_ENDFILT (42) +#define QPF_SPEC_T_MAXSPEC (42) /** Names for specifiers as used in format string - must match the above. **/ const char* @@ -111,6 +112,7 @@ qpf_spec_names[] = "DBL", "nSTR", "CHR", + "LL", "QUOT", "DQUOT", "SYM", @@ -139,13 +141,13 @@ qpf_spec_names[] = "nZRSET", "SQLARG", "SQLSYM", - "HTDATA", /* 35 */ + "HTDATA", /* 36 */ "HTE", - "ESCQWS", /* 37 */ - "ESCQ", /* 38 */ - "CSSVAL", /* 39 */ - "CSSURL", /* 40 */ - "JSONSTR", /* 41 */ + "ESCQWS", /* 38 */ + "ESCQ", /* 39 */ + "CSSVAL", /* 40 */ + "CSSURL", /* 41 */ + "JSONSTR", /* 42 */ NULL }; @@ -754,6 +756,7 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow int n; int found; int intval; + long long llval; const char* strval; double dblval; char tmpbuf[64]; @@ -970,6 +973,12 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow strval = tmpbuf; break; + case QPF_SPEC_T_LL: + llval = va_arg(ap, long long); + cplen = snprintf(tmpbuf, sizeof(tmpbuf), "%lld", llval); + strval = tmpbuf; + break; + case QPF_SPEC_T_DBL: dblval = va_arg(ap, double); cplen = snprintf(tmpbuf, sizeof(tmpbuf), "%lf", dblval); diff --git a/centrallix-sysdoc/QPrintf.txt b/centrallix-sysdoc/QPrintf.txt index ac6714381..2f08fa59f 100644 --- a/centrallix-sysdoc/QPrintf.txt +++ b/centrallix-sysdoc/QPrintf.txt @@ -66,6 +66,9 @@ FORMATTING... %INT An integer value, with range of the normal 'int' value in the C language. Can be positive, negative, or zero. + + %LL A 64-bit integer value, with range of 'long long' value + in the C language. Can be positive, negative, or zero. %POS A non-negative integer value (zero allowed). From a70e287ae84cbf6d458dbfe392c697cf92aa1cb1 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 14 Dec 2020 10:36:20 -0700 Subject: [PATCH 047/129] Cleaning up test suite items. Showed truncation in fp test. --- .../tests/test_moneytype_fp_internal_ParseColumn_00.c | 8 +++++++- centrallix/tests/test_moneytype_obfuscate_00.c | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index cc1b671ec..7e7a1ffb3 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -45,6 +45,12 @@ test(char** name) assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); assert(moneyDataPtr->Money->Value == 4500); - + //This function truncates answers + char* testRoundedString = "45011999"; + testColInf.DecimalOffset = 5; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testRoundedString) == 0); + assert(moneyDataPtr->Money->Value == 4501199); + + return 0; } diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c index a34d1c934..7054a57b5 100644 --- a/centrallix/tests/test_moneytype_obfuscate_00.c +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -3,14 +3,14 @@ #include #include "expression.h" #include "cxlib/xstring.h" -#include "utility/obfuscate.c" +//#include "utility/obfuscate.c" long long test(char** name) { *name = "moneytype_00 - obfuscate"; - obfObfuscateData(); + //obfObfuscateData(); return 0; } From 1b727d27b16a6cdf5b039e359b16f20dc149b7ec Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 14 Dec 2020 17:03:16 -0700 Subject: [PATCH 048/129] Updated qprintf sysdoc to contain %LL. Creation of test for %LL, not yet fully functional --- centrallix-lib/tests/test_qprintf_64.c | 51 ++++++++++++++++++++++++++ centrallix-sysdoc/QPrintf.txt | 1 + 2 files changed, 52 insertions(+) create mode 100644 centrallix-lib/tests/test_qprintf_64.c diff --git a/centrallix-lib/tests/test_qprintf_64.c b/centrallix-lib/tests/test_qprintf_64.c new file mode 100644 index 000000000..44ec2c333 --- /dev/null +++ b/centrallix-lib/tests/test_qprintf_64.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include "qprintf.h" +#include + +long long +test(char** tname) +{ + int i, rval; + int iter; + unsigned char buf[44]; + + *tname = "qprintf-64 %LL insertion in middle without overflow"; + iter = 200000; + for(i=0;i Date: Fri, 7 Aug 2020 11:50:38 -0600 Subject: [PATCH 049/129] Sample money test --- centrallix/tests/test_sample_money.cmp | 1 + centrallix/tests/test_sample_money.to | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 centrallix/tests/test_sample_money.cmp create mode 100644 centrallix/tests/test_sample_money.to diff --git a/centrallix/tests/test_sample_money.cmp b/centrallix/tests/test_sample_money.cmp new file mode 100644 index 000000000..b1180a931 --- /dev/null +++ b/centrallix/tests/test_sample_money.cmp @@ -0,0 +1 @@ +Attribute [column_000]: money $5.50 diff --git a/centrallix/tests/test_sample_money.to b/centrallix/tests/test_sample_money.to new file mode 100644 index 000000000..0574b1e96 --- /dev/null +++ b/centrallix/tests/test_sample_money.to @@ -0,0 +1,2 @@ +##NAME Money Test 2 +query select $4 + 1.5 From de1a32523d1503390f0396a41632e31f6bdc31c2 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 7 Aug 2020 20:30:41 -0600 Subject: [PATCH 050/129] A second set of test files to determine if I still appear as gbeeley when committing. --- centrallix/tests/test_sample_money_00.cmp | 1 + centrallix/tests/test_sample_money_00.to | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 centrallix/tests/test_sample_money_00.cmp create mode 100644 centrallix/tests/test_sample_money_00.to diff --git a/centrallix/tests/test_sample_money_00.cmp b/centrallix/tests/test_sample_money_00.cmp new file mode 100644 index 000000000..457fc5998 --- /dev/null +++ b/centrallix/tests/test_sample_money_00.cmp @@ -0,0 +1 @@ +Attribute [column000]: money $5.25 diff --git a/centrallix/tests/test_sample_money_00.to b/centrallix/tests/test_sample_money_00.to new file mode 100644 index 000000000..01b29ab09 --- /dev/null +++ b/centrallix/tests/test_sample_money_00.to @@ -0,0 +1,2 @@ +##NAME Sample Test Functionality +query select $4 + 1.25 From e320fe5c37f7f31dfce783a43e25c2c3e8100860 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 10 Aug 2020 11:35:42 -0600 Subject: [PATCH 051/129] Change MoneyType struct to contain a single long long instead of WholePart/FractionPart --- centrallix-lib/include/datatypes.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/centrallix-lib/include/datatypes.h b/centrallix-lib/include/datatypes.h index da7b509d8..af78f5e46 100644 --- a/centrallix-lib/include/datatypes.h +++ b/centrallix-lib/include/datatypes.h @@ -56,8 +56,11 @@ typedef struct _SV /** Money structure **/ typedef struct _MN { - int WholePart; /* integer part = floor($amount) */ - unsigned short FractionPart; /* fract part = $amount - floor($amount) */ + /* Commented out old structure */ + //int WholePart; /* integer part = floor($amount) */ + //unsigned short FractionPart; /* fract part = $amount - floor($amount) */ + + long long MoneyValue; /* Fixed-point representation in 1/10000 of a dollar */ } MoneyType, *pMoneyType; From f7623e435e0bbd9b54a3f604846c647f52a57639 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 10 Aug 2020 12:06:52 -0600 Subject: [PATCH 052/129] Commenting out direct MoneyType usage in centrallix/utility --- centrallix/utility/json_util.c | 4 ++-- centrallix/utility/obfuscate.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index ce4b678d3..0e800f987 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -235,12 +235,12 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) if (!strcmp(iter.key, "wholepart")) { has_whole = 1; - m->WholePart = json_object_get_int(iter.val); + //m->WholePart = json_object_get_int(iter.val); } else if (!strcmp(iter.key, "fractionpart")) { has_fraction = 1; - m->FractionPart = json_object_get_int(iter.val); + //m->FractionPart = json_object_get_int(iter.val); } else { diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index 75eb8cea0..98606dbf0 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1200,7 +1200,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname break; case DATA_T_MONEY: - iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); + //iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); if (strchr(param,'i')) dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); else @@ -1209,8 +1209,8 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = iv/10 + 1; dv = obf_internal_ObfuscateInteger(hash, hash_novalue, &bitcnt, iv); } - m.WholePart = floor(dv/100.0); - m.FractionPart = (dv - m.WholePart*100) * 100; + //m.WholePart = floor(dv/100.0); + //m.FractionPart = (dv - m.WholePart*100) * 100; dstval->Money = &m; break; From 0bbc802cf83b4831fd5cb5b4fc54a3564e4ee2d7 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 10 Aug 2020 22:18:54 -0600 Subject: [PATCH 053/129] Commenting out direct MoneyType usage in centrallix/expression --- centrallix/expression/exp_compiler.c | 4 +- centrallix/expression/exp_evaluate.c | 62 +++++++++++++-------------- centrallix/expression/exp_functions.c | 28 ++++++------ centrallix/expression/exp_main.c | 6 +-- centrallix/expression/exp_params.c | 8 ++-- 5 files changed, 54 insertions(+), 54 deletions(-) diff --git a/centrallix/expression/exp_compiler.c b/centrallix/expression/exp_compiler.c index 613c87c3f..9bcbd9340 100644 --- a/centrallix/expression/exp_compiler.c +++ b/centrallix/expression/exp_compiler.c @@ -152,8 +152,8 @@ exp_internal_CompileExpression_r(pLxSession lxs, int level, pParamObjects objlis if (t == MLX_TOK_INTEGER) { i = mlxIntVal(lxs); - etmp->Types.Money.WholePart = i; - etmp->Types.Money.FractionPart = 0; + //etmp->Types.Money.WholePart = i; + //etmp->Types.Money.FractionPart = 0; } else { diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index e8abd254f..0d17affd6 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -226,9 +226,9 @@ expEvalDivide(pExpression tree, pParamObjects objlist) /** Check for divide by zero **/ if ((i1->DataType == DATA_T_INTEGER && i1->Integer == 0) || - (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0) || - (i1->DataType == DATA_T_MONEY && i1->Types.Money.WholePart == 0 && i1->Types.Money.FractionPart == 0)) - { + (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0)){ //|| + //(i1->DataType == DATA_T_MONEY && i1->Types.Money.WholePart == 0 && i1->Types.Money.FractionPart == 0)) + //{ mssError(1,"EXP","Attempted divide by zero"); return -1; } @@ -275,7 +275,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: - switch(i1->DataType) + /*Carl switch(i1->DataType) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; @@ -301,8 +301,8 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - tree->Types.Money.WholePart = m.WholePart / i; - tree->Types.Money.FractionPart = (10000*(m.WholePart % i) + m.FractionPart)/i; + //tree->Types.Money.WholePart = m.WholePart / i; + //tree->Types.Money.FractionPart = (10000*(m.WholePart % i) + m.FractionPart)/i; if (is_negative) { if (tree->Types.Money.FractionPart != 0) @@ -353,7 +353,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) tree->Types.Double = (double)mv / (double)mv2; } break; - } + }*/ break; default: @@ -428,8 +428,8 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - mv *= i0->Integer; + //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; + //mv *= i0->Integer; break; case DATA_T_STRING: tree->DataType = DATA_T_STRING; @@ -453,8 +453,8 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) { case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - mv *= i0->Types.Double; + //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; + //mv *= i0->Types.Double; break; default: tree->Types.Double = i0->Types.Double * objDataToDouble(i1->DataType, dptr); @@ -465,7 +465,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + /*Carl mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; switch(i1->DataType) { case DATA_T_INTEGER: @@ -483,7 +483,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) default: mssError(1,"EXP","Can only multiply a money data type by an integer or double"); return -1; - } + }*/ break; case DATA_T_STRING: @@ -505,14 +505,14 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) /** Common processing **/ if (tree->DataType == DATA_T_MONEY) { - tree->Types.Money.WholePart = mv/10000; + /*Carl tree->Types.Money.WholePart = mv/10000; mv = mv % 10000; if (mv < 0) { mv += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mv; + tree->Types.Money.FractionPart = mv;*/ } else if (tree->DataType == DATA_T_STRING) { @@ -605,7 +605,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Integer - i1->Types.Money.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Integer - i1->Types.Money.WholePart; if (i1->Types.Money.FractionPart == 0) { tree->Types.Money.FractionPart = 0; @@ -614,7 +614,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) { tree->Types.Money.WholePart--; tree->Types.Money.FractionPart = 10000 - i1->Types.Money.FractionPart; - } + }*/ break; default: tree->Integer = i0->Integer - objDataToInteger(i1->DataType, dptr, NULL); @@ -635,7 +635,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_DOUBLE; - tree->Types.Double = i0->Types.Double - (i1->Types.Money.WholePart + i1->Types.Money.FractionPart/10000.0); + //tree->Types.Double = i0->Types.Double - (i1->Types.Money.WholePart + i1->Types.Money.FractionPart/10000.0); break; default: tree->DataType = DATA_T_DOUBLE; @@ -649,16 +649,16 @@ expEvalMinus(pExpression tree, pParamObjects objlist) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Integer; - tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; + //tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Integer; + //tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; break; case DATA_T_DOUBLE: tree->DataType = DATA_T_DOUBLE; - tree->Types.Double = (i0->Types.Money.WholePart + i0->Types.Money.FractionPart/10000.0) - i1->Types.Double; + //tree->Types.Double = (i0->Types.Money.WholePart + i0->Types.Money.FractionPart/10000.0) - i1->Types.Double; break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Types.Money.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Types.Money.WholePart; tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - i1->Types.Money.FractionPart; if (tree->Types.Money.FractionPart >= 10000) { @@ -667,7 +667,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) else { tree->Types.Money.WholePart--; - } + }*/ break; default: if (objDataToMoney(i1->DataType, dptr, &m) < 0) @@ -676,12 +676,12 @@ expEvalMinus(pExpression tree, pParamObjects objlist) return -1; } tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i0->Types.Money.WholePart - m.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - m.WholePart; tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - m.FractionPart; if (tree->Types.Money.FractionPart >= 10000) tree->Types.Money.FractionPart -= 10000; else - tree->Types.Money.WholePart--; + tree->Types.Money.WholePart--; */ break; } break; @@ -806,8 +806,8 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - tree->Types.Money.WholePart = i1->Types.Money.WholePart + i0->Integer; - tree->Types.Money.FractionPart = i1->Types.Money.FractionPart; + //tree->Types.Money.WholePart = i1->Types.Money.WholePart + i0->Integer; + //tree->Types.Money.FractionPart = i1->Types.Money.FractionPart; break; default: @@ -843,13 +843,13 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: objDataToMoney(i1->DataType, dptr, &m); - tree->Types.Money.WholePart = i0->Types.Money.WholePart + m.WholePart; + /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart + m.WholePart; tree->Types.Money.FractionPart = i0->Types.Money.FractionPart + m.FractionPart; if (tree->Types.Money.FractionPart >= 10000) { tree->Types.Money.FractionPart -= 10000; tree->Types.Money.WholePart++; - } + }*/ break; case DATA_T_DATETIME: @@ -1498,8 +1498,8 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) } else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { - tree->Types.Money.WholePart = tree->Integer; - tree->Types.Money.FractionPart = 0; + //tree->Types.Money.WholePart = tree->Integer; + //tree->Types.Money.FractionPart = 0; } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/expression/exp_functions.c b/centrallix/expression/exp_functions.c index 6d949640e..2ffa2ac4b 100644 --- a/centrallix/expression/exp_functions.c +++ b/centrallix/expression/exp_functions.c @@ -266,7 +266,7 @@ int exp_fn_abs(pExpression tree, pParamObjects objlist, pExpression i0, pExpress break; case DATA_T_MONEY: - if (i0->Types.Money.WholePart >= 0) + /*Carl if (i0->Types.Money.WholePart >= 0) { tree->Types.Money.WholePart = i0->Types.Money.WholePart; tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; @@ -283,7 +283,7 @@ int exp_fn_abs(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->Types.Money.WholePart = -i0->Types.Money.WholePart; tree->Types.Money.FractionPart = 0; } - } + }*/ break; default: @@ -1663,7 +1663,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre break; case DATA_T_MONEY: - mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; if (dec < 4) { mv = 1; @@ -1682,7 +1682,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre mt += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mt; + tree->Types.Money.FractionPart = mt;*/ break; } return 0; @@ -1936,7 +1936,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx break; case DATA_T_MONEY: - mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; if (dec < 4) { mv = 1; @@ -1951,7 +1951,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx mt += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mt; + tree->Types.Money.FractionPart = mt;*/ break; } return 0; @@ -2947,8 +2947,8 @@ int exp_fn_avg(pExpression tree, pParamObjects objlist, pExpression i0, pExpress sumexp->String[0] = '\0'; sumexp->Integer = 0; sumexp->Types.Double = 0; - sumexp->Types.Money.FractionPart = 0; - sumexp->Types.Money.WholePart = 0; + //sumexp->Types.Money.FractionPart = 0; + //sumexp->Types.Money.WholePart = 0; cntexp->Integer = 0; } @@ -3035,8 +3035,8 @@ int exp_fn_sum(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->AggExp->String[0] = '\0'; tree->AggExp->Integer = 0; tree->AggExp->Types.Double = 0; - tree->AggExp->Types.Money.FractionPart = 0; - tree->AggExp->Types.Money.WholePart = 0; + //tree->AggExp->Types.Money.FractionPart = 0; + //tree->AggExp->Types.Money.WholePart = 0; } expCopyValue(tree->AggExp, (pExpression)(tree->AggExp->Children.Items[0]), 1); expCopyValue(i0, (pExpression)(tree->AggExp->Children.Items[1]), 0); @@ -3098,8 +3098,8 @@ int exp_fn_max(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->String[0] = '\0'; tree->Integer = 0; tree->Types.Double = 0; - tree->Types.Money.FractionPart = 0; - tree->Types.Money.WholePart = 0; + //tree->Types.Money.FractionPart = 0; + //tree->Types.Money.WholePart = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); @@ -3160,8 +3160,8 @@ int exp_fn_min(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->Alloc = 0; tree->Integer = 0; tree->Types.Double = 0; - tree->Types.Money.FractionPart = 0; - tree->Types.Money.WholePart = 0; + //tree->Types.Money.FractionPart = 0; + //tree->Types.Money.WholePart = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); diff --git a/centrallix/expression/exp_main.c b/centrallix/expression/exp_main.c index 79c2dcf02..0bdbcd0a3 100644 --- a/centrallix/expression/exp_main.c +++ b/centrallix/expression/exp_main.c @@ -523,7 +523,7 @@ exp_internal_DumpExpression_r(pExpression this, int level) case EXPR_N_INTEGER: printf("INTEGER = %d", this->Integer); break; case EXPR_N_STRING: printf("STRING = <%s>", this->String); break; case EXPR_N_DOUBLE: printf("DOUBLE = %.2f", this->Types.Double); break; - case EXPR_N_MONEY: printf("MONEY = %d.%4.4d", this->Types.Money.WholePart, this->Types.Money.FractionPart); break; + case EXPR_N_MONEY: printf("MONEY");/*printf("MONEY = %d.%4.4d", this->Types.Money.WholePart, this->Types.Money.FractionPart);*/ break; case EXPR_N_DATETIME: printf("DATETIME = %s", objDataToStringTmp(DATA_T_DATETIME,&(this->Types.Date), 0)); break; case EXPR_N_PLUS: printf("PLUS"); break; case EXPR_N_MULTIPLY: printf("MULTIPLY"); break; @@ -863,8 +863,8 @@ expCompareExpressionValues(pExpression exp1, pExpression exp2) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DOUBLE && exp1->Types.Double != exp2->Types.Double) return 0; - if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && (exp1->Types.Money.WholePart != exp2->Types.Money.WholePart || exp1->Types.Money.FractionPart != exp2->Types.Money.FractionPart)) - return 0; + //if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && (exp1->Types.Money.WholePart != exp2->Types.Money.WholePart || exp1->Types.Money.FractionPart != exp2->Types.Money.FractionPart)) + //return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DATETIME && (exp1->Types.Date.Part.Second != exp2->Types.Date.Part.Second || exp1->Types.Date.Part.Minute != exp2->Types.Date.Part.Minute || exp1->Types.Date.Part.Hour != exp2->Types.Date.Part.Hour || exp1->Types.Date.Part.Day != exp2->Types.Date.Part.Day || exp1->Types.Date.Part.Month != exp2->Types.Date.Part.Month || exp1->Types.Date.Part.Year != exp2->Types.Date.Part.Year)) return 0; diff --git a/centrallix/expression/exp_params.c b/centrallix/expression/exp_params.c index fc0c4f984..83fa66167 100644 --- a/centrallix/expression/exp_params.c +++ b/centrallix/expression/exp_params.c @@ -602,14 +602,14 @@ exp_internal_ResetAggregates(pExpression this, int reset_id, int level) { this->AggExp->Integer = 0; this->AggExp->Types.Double = 0; - this->AggExp->Types.Money.WholePart = 0; - this->AggExp->Types.Money.FractionPart = 0; + //this->AggExp->Types.Money.WholePart = 0; + //this->AggExp->Types.Money.FractionPart = 0; this->Flags |= EXPR_F_AGGLOCKED; } this->Integer = 0; this->Types.Double = 0; - this->Types.Money.WholePart = 0; - this->Types.Money.FractionPart = 0; + //this->Types.Money.WholePart = 0; + //this->Types.Money.FractionPart = 0; if (!strcmp(this->Name,"count")) { this->Flags &= ~EXPR_F_NULL; From 20f8685b0a5578fd94b5572efd09826b52344fa4 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 11 Aug 2020 11:15:15 -0600 Subject: [PATCH 054/129] Commenting out direct MoneyType usage --- centrallix/netdrivers/net_http_rest.c | 4 +- centrallix/objectsystem/obj_datatypes.c | 77 +++++++++++++++---------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index c236c4da2..ae9546dd0 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -114,10 +114,10 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty break; case DATA_T_MONEY: - nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", + /*Carl nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", od.Money->WholePart, od.Money->FractionPart - ); + );*/ break; default: diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 6de7b1f31..581afee1f 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -475,14 +475,14 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (tens_multiplier > 0) tens_multiplier /= 10; /** Special handling of zeros **/ - if (m->WholePart == 0 && m->FractionPart == 0 && zero_type != 0) + /* Carl if (m->WholePart == 0 && m->FractionPart == 0 && zero_type != 0) { if (strlen(zero_strings[zero_type]) >= length) return -1; else strcpy(str, zero_strings[zero_type]); return 0; - } + }*/ xsInit(&xs); @@ -490,7 +490,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - if (m->WholePart >= 0 || m->FractionPart == 0) + /*Carl if (m->WholePart >= 0 || m->FractionPart == 0) { print_whole = m->WholePart; print_fract = m->FractionPart; @@ -501,10 +501,10 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) print_fract = 10000 - m->FractionPart; } orig_print_whole = m->WholePart; - if (print_whole < 0) print_whole = -print_whole; + if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ - while(*fmt) + /*Carl while(*fmt) { if (automatic_sign) { @@ -513,7 +513,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) *(str++) = '-'; /*else *(str++) = ' ';*/ - } + /*Carl } switch(*fmt) { case '$': @@ -557,7 +557,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) else { /** Replace comma with space if no digits and surrounded by placeholders **/ - if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) + /*Carl if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) { xsConcatenate(&xs," ",1); } @@ -610,7 +610,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) break; } fmt++; - } + }*/ if(strlen(xs.String) < length) { @@ -801,11 +801,14 @@ objDataToInteger(int data_type, void* data_ptr, char* format) v = (int)(*(double*)data_ptr); break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr; + /*Carl m = (pMoneyType)data_ptr; if (m->FractionPart==0 || m->WholePart>=0) v = m->WholePart; else - v = m->WholePart + 1; + v = m->WholePart + 1;*/ + + //Adding a value for v so this function does not return an uninitialized variable + v = 2; break; case DATA_T_INTVEC: @@ -840,7 +843,7 @@ objDataToDouble(int data_type, void* data_ptr) { case DATA_T_INTEGER: v = *(int*)data_ptr; break; case DATA_T_STRING: v = strtod((char*)data_ptr, NULL); break; - case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->WholePart + (m->FractionPart/10000.0); break; + case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = 2;/*Carl m->WholePart + (m->FractionPart/10000.0);*/ break; case DATA_T_DOUBLE: v = *(double*)data_ptr; break; default: v = 0.0; break; } @@ -1409,7 +1412,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* tptr; /** Select the correct type. **/ - switch(data_type) + /*Carl switch(data_type) { case DATA_T_STRING: cxssGetVariable("mfmt", &fmt, obj_default_money_fmt); @@ -1420,7 +1423,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) if (strlen(ptr) < sizeof(tmpbuf)) { /** strip commas (or periods, if in intl format) **/ - tptr = tmpbuf; + /*Carl tptr = tmpbuf; while(*ptr) { if (*ptr != (intl_format?'.':',')) @@ -1495,7 +1498,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) m->WholePart = ((pMoneyType)data_ptr)->WholePart; m->FractionPart = ((pMoneyType)data_ptr)->FractionPart; break; - } + }*/ return 0; } @@ -1573,10 +1576,13 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr_2; + /*Carl m = (pMoneyType)data_ptr_2; if (m->WholePart > intval) cmp_value = -1; else if (m->WholePart < intval) cmp_value = 1; - else cmp_value = m->FractionPart?-1:0; + else cmp_value = m->FractionPart?-1:0;*/ + + //Adding an arbitrary value for cmp_value so no reference uninitialized var + cmp_value = 2; break; case DATA_T_INTVEC: @@ -1615,11 +1621,14 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); + /*Carl objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); m = (pMoneyType)data_ptr_2; if (m_v.WholePart > m->WholePart) cmp_value = 1; else if (m_v.WholePart < m->WholePart) cmp_value = -1; - else cmp_value = m_v.FractionPart - m->FractionPart; + else cmp_value = m_v.FractionPart - m->FractionPart;*/ + + //Arbitrary value for cmp_value + cmp_value = 2; break; case DATA_T_DOUBLE: @@ -1672,11 +1681,14 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr_2; + /*Carl m = (pMoneyType)data_ptr_2; dblval = m->WholePart + (m->FractionPart/10000.0); if (dblval == *(double*)data_ptr_1) cmp_value = 0; else if (dblval > *(double*)data_ptr_1) cmp_value = -1; - else cmp_value = 1; + else cmp_value = 1;*/ + + //Arbitrary value + cmp_value = 2; break; case DATA_T_STRINGVEC: @@ -1762,7 +1774,7 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - m = (pMoneyType)data_ptr_2; + /*Carl m = (pMoneyType)data_ptr_2; if (iv->nIntegers != 2) { err = 1; @@ -1772,7 +1784,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt if (m->WholePart > iv->Integers[0]) cmp_value = -1; else if (m->WholePart < iv->Integers[0]) cmp_value = 1; else cmp_value = iv->Integers[1] - m->FractionPart; - } + }*/ + //Arbitrary cmp value + cmp_value = 2; break; default: @@ -1821,9 +1835,12 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt switch(data_type_2) { case DATA_T_MONEY: - if (m->WholePart > ((pMoneyType)data_ptr_2)->WholePart) cmp_value = 1; + /*Carl if (m->WholePart > ((pMoneyType)data_ptr_2)->WholePart) cmp_value = 1; else if (m->WholePart < ((pMoneyType)data_ptr_2)->WholePart) cmp_value = -1; - else cmp_value = m->FractionPart - ((pMoneyType)data_ptr_2)->FractionPart; + else cmp_value = m->FractionPart - ((pMoneyType)data_ptr_2)->FractionPart;*/ + + //Arbitrary cmp value + cmp_value = 2; break; default: @@ -1898,7 +1915,7 @@ objDataToWords(int data_type, void* data_ptr) } else if (data_type == DATA_T_MONEY) { - m = (pMoneyType)data_ptr; + /*Carl m = (pMoneyType)data_ptr; if (m->WholePart < 0) { if (m->FractionPart == 0) @@ -1917,7 +1934,7 @@ objDataToWords(int data_type, void* data_ptr) { integer_part = m->WholePart; fraction_part = m->FractionPart; - } + }*/ } else { @@ -1989,7 +2006,7 @@ objDataToWords(int data_type, void* data_ptr) } /** Now take care of cents if a money type **/ - if (data_type == DATA_T_MONEY) + /*Carl if (data_type == DATA_T_MONEY) { if (fraction_part == 0) { @@ -2000,7 +2017,7 @@ objDataToWords(int data_type, void* data_ptr) sprintf(nbuf, "And %2.2ld/100 ", fraction_part/100); xsConcatenate(&tmpbuf, nbuf, -1); } - } + }*/ return tmpbuf.String; } @@ -2185,10 +2202,10 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x80000000 to convert to Offset Zero form. **/ - ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); + /*Carl ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); ((unsigned short*)tmp_buf)[2] = htons(exp->Types.Money.FractionPart); *item = (char*)(tmp_buf); - *itemlen = 6; + *itemlen = 6;*/ break; case DATA_T_DOUBLE: From 34ef3f95898e8de246ca86133858e33cfd29e94a Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 12:03:27 -0600 Subject: [PATCH 055/129] Converted obj_internal_FormatMoney to use the new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 581afee1f..2a7ba030a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -475,14 +475,14 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (tens_multiplier > 0) tens_multiplier /= 10; /** Special handling of zeros **/ - /* Carl if (m->WholePart == 0 && m->FractionPart == 0 && zero_type != 0) + if (m->MoneyValue == 0 && zero_type != 0) { if (strlen(zero_strings[zero_type]) >= length) return -1; else strcpy(str, zero_strings[zero_type]); return 0; - }*/ + } xsInit(&xs); @@ -490,21 +490,21 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - /*Carl if (m->WholePart >= 0 || m->FractionPart == 0) + if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) { - print_whole = m->WholePart; - print_fract = m->FractionPart; + print_whole = m->MoneyValue/10000; + print_fract = m->MoneyValue%10000; } else { - print_whole = m->WholePart + 1; - print_fract = 10000 - m->FractionPart; + print_whole = m->MoneyValue/10000 + 1; + print_fract = 10000 - m->MoneyValue%10000; } - orig_print_whole = m->WholePart; - if (print_whole < 0) print_whole = -print_whole;*/ + orig_print_whole = m->MoneyValue/10000; + if (print_whole < 0) print_whole = -print_whole; /** Ok, start generating the thing. **/ - /*Carl while(*fmt) + while(*fmt) { if (automatic_sign) { @@ -513,29 +513,29 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) *(str++) = '-'; /*else *(str++) = ' ';*/ - /*Carl } + } switch(*fmt) { case '$': *(str++) = '$'; break; - case ' ': - case '*': + case ' ': + case '*': case '0': case '^': case '#': if (in_decimal_part) { - d = (print_fract/tens_multiplier)%10; - tens_multiplier /= 10; - } + d = (print_fract/tens_multiplier)%10; + tens_multiplier /= 10; + } else { - d = print_whole/tens_multiplier; - print_whole -= d*tens_multiplier; - tens_multiplier /= 10; - } + d = print_whole/tens_multiplier; + print_whole -= d*tens_multiplier; + tens_multiplier /= 10; + } if (d != 0 || *fmt == '0' || *fmt == '^') suppressing_zeros = 0; if (suppressing_zeros) { @@ -557,7 +557,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) else { /** Replace comma with space if no digits and surrounded by placeholders **/ - /*Carl if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) + if (!((start_fmt != fmt && fmt[-1] == '#') || fmt[1] == '#')) { xsConcatenate(&xs," ",1); } @@ -610,7 +610,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) break; } fmt++; - }*/ + } if(strlen(xs.String) < length) { From a8d47cfd46295b2066a77a7a3bfd1ce3ec780759 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 12:31:54 -0600 Subject: [PATCH 056/129] Converted objDataToDouble to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 2a7ba030a..6b768398b 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -801,14 +801,11 @@ objDataToInteger(int data_type, void* data_ptr, char* format) v = (int)(*(double*)data_ptr); break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr; + m = (pMoneyType)data_ptr; if (m->FractionPart==0 || m->WholePart>=0) v = m->WholePart; else - v = m->WholePart + 1;*/ - - //Adding a value for v so this function does not return an uninitialized variable - v = 2; + v = m->WholePart + 1; break; case DATA_T_INTVEC: @@ -843,7 +840,7 @@ objDataToDouble(int data_type, void* data_ptr) { case DATA_T_INTEGER: v = *(int*)data_ptr; break; case DATA_T_STRING: v = strtod((char*)data_ptr, NULL); break; - case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = 2;/*Carl m->WholePart + (m->FractionPart/10000.0);*/ break; + case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); break; case DATA_T_DOUBLE: v = *(double*)data_ptr; break; default: v = 0.0; break; } From 11b0a3cc683ab7d71858085f957f85fbe51f4b59 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 13:18:04 -0600 Subject: [PATCH 057/129] Converted objDataCompare to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 52 +++++++++---------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 6b768398b..b5f0b1b93 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1573,13 +1573,10 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr_2; - if (m->WholePart > intval) cmp_value = -1; - else if (m->WholePart < intval) cmp_value = 1; - else cmp_value = m->FractionPart?-1:0;*/ - - //Adding an arbitrary value for cmp_value so no reference uninitialized var - cmp_value = 2; + m = (pMoneyType)data_ptr_2; + if (m->MoneyValue/10000 > intval) cmp_value = -1; + else if (m->MoneyValue/10000 < intval) cmp_value = 1; + else cmp_value = m->MoneyValue%10000?-1:0; break; case DATA_T_INTVEC: @@ -1618,14 +1615,11 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); + objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); m = (pMoneyType)data_ptr_2; - if (m_v.WholePart > m->WholePart) cmp_value = 1; - else if (m_v.WholePart < m->WholePart) cmp_value = -1; - else cmp_value = m_v.FractionPart - m->FractionPart;*/ - - //Arbitrary value for cmp_value - cmp_value = 2; + if (m_v.MoneyValue/10000 > m->MoneyValue/10000) cmp_value = 1; + else if (m_v.MoneyValue/10000 < m->MoneyValue/10000) cmp_value = -1; + else cmp_value = m_v.MoneyValue%10000 - m->MoneyValue%10000; break; case DATA_T_DOUBLE: @@ -1678,14 +1672,11 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr_2; - dblval = m->WholePart + (m->FractionPart/10000.0); + m = (pMoneyType)data_ptr_2; + dblval = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); if (dblval == *(double*)data_ptr_1) cmp_value = 0; else if (dblval > *(double*)data_ptr_1) cmp_value = -1; - else cmp_value = 1;*/ - - //Arbitrary value - cmp_value = 2; + else cmp_value = 1; break; case DATA_T_STRINGVEC: @@ -1771,19 +1762,17 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt break; case DATA_T_MONEY: - /*Carl m = (pMoneyType)data_ptr_2; + m = (pMoneyType)data_ptr_2; if (iv->nIntegers != 2) { err = 1; } else { - if (m->WholePart > iv->Integers[0]) cmp_value = -1; - else if (m->WholePart < iv->Integers[0]) cmp_value = 1; - else cmp_value = iv->Integers[1] - m->FractionPart; - }*/ - //Arbitrary cmp value - cmp_value = 2; + if (m->MoneyValue/10000 > iv->Integers[0]) cmp_value = -1; + else if (m->MoneyValue/10000 < iv->Integers[0]) cmp_value = 1; + else cmp_value = iv->Integers[1] - m->MoneyValue%10000; + } break; default: @@ -1832,12 +1821,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt switch(data_type_2) { case DATA_T_MONEY: - /*Carl if (m->WholePart > ((pMoneyType)data_ptr_2)->WholePart) cmp_value = 1; - else if (m->WholePart < ((pMoneyType)data_ptr_2)->WholePart) cmp_value = -1; - else cmp_value = m->FractionPart - ((pMoneyType)data_ptr_2)->FractionPart;*/ - - //Arbitrary cmp value - cmp_value = 2; + if (m->MoneyValue/10000 > ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = 1; + else if (m->MoneyValue/10000 < ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = -1; + else cmp_value = m->MoneyValue%10000 - ((pMoneyType)data_ptr_2)->MoneyValue%10000; break; default: From 31d5cebb5e133ee40b7092f32438389aa6912872 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 13:29:50 -0600 Subject: [PATCH 058/129] Converted objDataToWords to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index b5f0b1b93..3913acd30 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1898,26 +1898,26 @@ objDataToWords(int data_type, void* data_ptr) } else if (data_type == DATA_T_MONEY) { - /*Carl m = (pMoneyType)data_ptr; - if (m->WholePart < 0) + m = (pMoneyType)data_ptr; + if (m->MoneyValue/10000 < 0) { - if (m->FractionPart == 0) + if (m->MoneyValue%10000 == 0) { - integer_part = -m->WholePart; + integer_part = -m->MoneyValue/10000; fraction_part = 0; } else { - integer_part = (-m->WholePart) - 1; - fraction_part = 10000 - m->FractionPart; + integer_part = (-m->MoneyValue/10000) - 1; + fraction_part = 10000 - m->MoneyValue%10000; } xsConcatenate(&tmpbuf, "Negative ", -1); } else { - integer_part = m->WholePart; - fraction_part = m->FractionPart; - }*/ + integer_part = m->MoneyValue/10000; + fraction_part = m->MoneyValue%10000; + } } else { @@ -1989,7 +1989,7 @@ objDataToWords(int data_type, void* data_ptr) } /** Now take care of cents if a money type **/ - /*Carl if (data_type == DATA_T_MONEY) + if (data_type == DATA_T_MONEY) { if (fraction_part == 0) { @@ -2000,7 +2000,7 @@ objDataToWords(int data_type, void* data_ptr) sprintf(nbuf, "And %2.2ld/100 ", fraction_part/100); xsConcatenate(&tmpbuf, nbuf, -1); } - }*/ + } return tmpbuf.String; } From 2e1d133a4f5a4d55f3824cb9d517ea14c654ad8c Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 12 Aug 2020 15:03:29 -0600 Subject: [PATCH 059/129] Converted objDataToInteger to new 64 bit MoneyType --- centrallix/objectsystem/obj_datatypes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 3913acd30..1ced03017 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -802,10 +802,10 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - if (m->FractionPart==0 || m->WholePart>=0) - v = m->WholePart; + if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) + v = m->MoneyValue/10000; else - v = m->WholePart + 1; + v = m->MoneyValue/10000 + 1; break; case DATA_T_INTVEC: From 13ac93ba1a8099f1b5bad3dfe34aa62cc1af5e92 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 13 Aug 2020 16:37:59 -0600 Subject: [PATCH 060/129] Converted objDataToMoney to 64 bit MoneyType representaion --- centrallix/objectsystem/obj_datatypes.c | 64 +++++++++++++++---------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 1ced03017..9d5b247d3 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -490,18 +490,26 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) + orig_print_whole = m->MoneyValue/10000; + print_whole = m->MoneyValue/10000; + print_fract = m->MoneyValue%10000; + if (print_whole < 0) + { + print_whole = -print_whole; + print_fract = -print_fract; + } + /*if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) { print_whole = m->MoneyValue/10000; print_fract = m->MoneyValue%10000; } else - { + { //This handled the unsigned representation of FractionPart print_whole = m->MoneyValue/10000 + 1; print_fract = 10000 - m->MoneyValue%10000; } orig_print_whole = m->MoneyValue/10000; - if (print_whole < 0) print_whole = -print_whole; + if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ while(*fmt) @@ -1401,7 +1409,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* endptr2; double dbl; int is_neg = 0; - unsigned long intval; + long long intval; int scale; char* fmt; int intl_format; @@ -1409,7 +1417,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* tptr; /** Select the correct type. **/ - /*Carl switch(data_type) + switch(data_type) { case DATA_T_STRING: cxssGetVariable("mfmt", &fmt, obj_default_money_fmt); @@ -1420,7 +1428,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) if (strlen(ptr) < sizeof(tmpbuf)) { /** strip commas (or periods, if in intl format) **/ - /*Carl tptr = tmpbuf; + tptr = tmpbuf; while(*ptr) { if (*ptr != (intl_format?'.':',')) @@ -1442,26 +1450,33 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) ptr++; } intval = 0; - m->FractionPart = 0; - m->WholePart = 0; - intval = strtoul(ptr, &endptr, 10); - if (intval > 0x7FFFFFFFUL) + m->MoneyValue = 0; + intval = strtoll(ptr, &endptr, 10); + if (intval > 0x7FFFFFFFFFFFFFFFLL) return -1; if ((endptr - ptr) != strspn(ptr, "0123456789")) return -1; if (is_neg) - m->WholePart = -intval; + m->MoneyValue = -intval*10000; else - m->WholePart = intval; + m->MoneyValue = intval*10000; if (*endptr == (intl_format?',':'.')) { - intval = strtoul(endptr+1, &endptr2, 10); + intval = strtoll(endptr+1, &endptr2, 10); scale = endptr2 - (endptr+1); if (scale != strspn(endptr+1, "0123456789")) return -1; while(scale < 4) { scale++; intval *= 10; } while(scale > 4) { scale--; intval /= 10; } - m->FractionPart = intval; + if (is_neg) + { + m->MoneyValue -= intval; + } + else + { + m->MoneyValue += intval; + } + //m->FractionPart = intval; endptr = endptr2; } if (endptr == ptr) @@ -1470,32 +1485,31 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) } if (*endptr == '-') { - m->WholePart = -m->WholePart; + m->MoneyValue = -m->MoneyValue; is_neg = !is_neg; } - if (is_neg && m->FractionPart != 0) - { + /*if (is_neg && m->FractionPart != 0) + { //This handled the unsigned representation of FractionPart m->WholePart--; m->FractionPart = 10000 - m->FractionPart; - } + }*/ break; case DATA_T_DOUBLE: dbl = *(double*)data_ptr + 0.000001; - m->WholePart = floor(dbl); - m->FractionPart = (dbl - m->WholePart)*10000; + long long WholePart = floor(dbl); + int FractionPart = (dbl - WholePart)*10000; + m->MoneyValue = (WholePart*10000) + FractionPart; break; case DATA_T_INTEGER: - m->WholePart = *(int*)data_ptr; - m->FractionPart = 0; + m->MoneyValue = *(long long*)data_ptr; break; case DATA_T_MONEY: - m->WholePart = ((pMoneyType)data_ptr)->WholePart; - m->FractionPart = ((pMoneyType)data_ptr)->FractionPart; + m->MoneyValue = ((pMoneyType)data_ptr)->MoneyValue; break; - }*/ + } return 0; } From 351c2e3d6110d528bf2e9c2f325bd122d35cd88e Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 13 Aug 2020 17:16:30 -0600 Subject: [PATCH 061/129] Updated functions that accounted for the unsigned nature of FractionPart --- centrallix/objectsystem/obj_datatypes.c | 29 ++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 9d5b247d3..debbcd25a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -491,12 +491,15 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) /** Determine the 'print' version of whole/fraction parts **/ orig_print_whole = m->MoneyValue/10000; - print_whole = m->MoneyValue/10000; - print_fract = m->MoneyValue%10000; - if (print_whole < 0) + if (m->MoneyValue < 0) { - print_whole = -print_whole; - print_fract = -print_fract; + print_whole = -m->MoneyValue/10000; + print_fract = -m->MoneyValue%10000; + } + else + { + print_whole = m->MoneyValue/10000; + print_fract = m->MoneyValue%10000; } /*if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) { @@ -810,10 +813,12 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) + v = m->MoneyValue/10000; + //This handled the unsigned representation of FractionPart + /* if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) v = m->MoneyValue/10000; else - v = m->MoneyValue/10000 + 1; + v = m->MoneyValue/10000 + 1;*/ break; case DATA_T_INTVEC: @@ -1913,9 +1918,13 @@ objDataToWords(int data_type, void* data_ptr) else if (data_type == DATA_T_MONEY) { m = (pMoneyType)data_ptr; - if (m->MoneyValue/10000 < 0) + if (m->MoneyValue < 0) { - if (m->MoneyValue%10000 == 0) + /** Keep the opposite (positive) value for printing **/ + integer_part = -m->MoneyValue/10000; + fraction_part = -m->MoneyValue%10000; + + /*if (m->MoneyValue%10000 == 0) { integer_part = -m->MoneyValue/10000; fraction_part = 0; @@ -1924,7 +1933,7 @@ objDataToWords(int data_type, void* data_ptr) { integer_part = (-m->MoneyValue/10000) - 1; fraction_part = 10000 - m->MoneyValue%10000; - } + }*/ xsConcatenate(&tmpbuf, "Negative ", -1); } else From eddbd77449b528af87d12b884f619f2b3da0d234 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 14 Aug 2020 13:24:26 -0600 Subject: [PATCH 062/129] Resolving Code Review Comments --- centrallix-lib/include/datatypes.h | 6 +- centrallix/objectsystem/obj_datatypes.c | 140 ++++++++++++------------ 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/centrallix-lib/include/datatypes.h b/centrallix-lib/include/datatypes.h index af78f5e46..465c99bb2 100644 --- a/centrallix-lib/include/datatypes.h +++ b/centrallix-lib/include/datatypes.h @@ -56,11 +56,7 @@ typedef struct _SV /** Money structure **/ typedef struct _MN { - /* Commented out old structure */ - //int WholePart; /* integer part = floor($amount) */ - //unsigned short FractionPart; /* fract part = $amount - floor($amount) */ - - long long MoneyValue; /* Fixed-point representation in 1/10000 of a dollar */ + long long Value; /* Fixed-point representation in 1/10000 of a dollar */ } MoneyType, *pMoneyType; diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index debbcd25a..529b2b95a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -475,7 +475,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (tens_multiplier > 0) tens_multiplier /= 10; /** Special handling of zeros **/ - if (m->MoneyValue == 0 && zero_type != 0) + if (m->Value == 0 && zero_type != 0) { if (strlen(zero_strings[zero_type]) >= length) return -1; @@ -490,28 +490,28 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (strpbrk(fmt,"+-()[]")) automatic_sign = 0; /** Determine the 'print' version of whole/fraction parts **/ - orig_print_whole = m->MoneyValue/10000; - if (m->MoneyValue < 0) + orig_print_whole = m->Value/10000; + if (m->Value < 0) { - print_whole = -m->MoneyValue/10000; - print_fract = -m->MoneyValue%10000; + print_whole = -m->Value/10000; + print_fract = -m->Value%10000; } else { - print_whole = m->MoneyValue/10000; - print_fract = m->MoneyValue%10000; + print_whole = m->Value/10000; + print_fract = m->Value%10000; } - /*if (m->MoneyValue/10000 >= 0 || m->MoneyValue%10000 == 0) + /*if (m->Value/10000 >= 0 || m->Value%10000 == 0) { - print_whole = m->MoneyValue/10000; - print_fract = m->MoneyValue%10000; + print_whole = m->Value/10000; + print_fract = m->Value%10000; } else { //This handled the unsigned representation of FractionPart - print_whole = m->MoneyValue/10000 + 1; - print_fract = 10000 - m->MoneyValue%10000; + print_whole = m->Value/10000 + 1; + print_fract = 10000 - m->Value%10000; } - orig_print_whole = m->MoneyValue/10000; + orig_print_whole = m->Value/10000; if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ @@ -531,22 +531,22 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) *(str++) = '$'; break; - case ' ': - case '*': + case ' ': + case '*': case '0': case '^': case '#': if (in_decimal_part) { - d = (print_fract/tens_multiplier)%10; - tens_multiplier /= 10; - } + d = (print_fract/tens_multiplier)%10; + tens_multiplier /= 10; + } else { - d = print_whole/tens_multiplier; - print_whole -= d*tens_multiplier; - tens_multiplier /= 10; - } + d = print_whole/tens_multiplier; + print_whole -= d*tens_multiplier; + tens_multiplier /= 10; + } if (d != 0 || *fmt == '0' || *fmt == '^') suppressing_zeros = 0; if (suppressing_zeros) { @@ -813,12 +813,15 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - v = m->MoneyValue/10000; + if (m->Value/10000 > INT_MAX) + mssError(1,"OBJ","Warning: %d overflow; cannot fit value of that size in int ", data_type); + else + v = m->Value/10000; //This handled the unsigned representation of FractionPart - /* if (m->MoneyValue%10000==0 || m->MoneyValue/10000>=0) - v = m->MoneyValue/10000; + /* if (m->Value%10000==0 || m->Value/10000>=0) + v = m->Value/10000; else - v = m->MoneyValue/10000 + 1;*/ + v = m->Value/10000 + 1;*/ break; case DATA_T_INTVEC: @@ -853,7 +856,7 @@ objDataToDouble(int data_type, void* data_ptr) { case DATA_T_INTEGER: v = *(int*)data_ptr; break; case DATA_T_STRING: v = strtod((char*)data_ptr, NULL); break; - case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); break; + case DATA_T_MONEY: m = (pMoneyType)data_ptr; v = m->Value/10000.0; break; case DATA_T_DOUBLE: v = *(double*)data_ptr; break; default: v = 0.0; break; } @@ -1414,7 +1417,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) char* endptr2; double dbl; int is_neg = 0; - long long intval; + unsigned long intval; int scale; char* fmt; int intl_format; @@ -1455,19 +1458,22 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) ptr++; } intval = 0; - m->MoneyValue = 0; - intval = strtoll(ptr, &endptr, 10); + m->Value = 0; + intval = strtoul(ptr, &endptr, 10); + /** Checking for overflow, Max UL can be greater than Max LL **/ if (intval > 0x7FFFFFFFFFFFFFFFLL) return -1; if ((endptr - ptr) != strspn(ptr, "0123456789")) return -1; if (is_neg) - m->MoneyValue = -intval*10000; + m->Value = -intval*10000; else - m->MoneyValue = intval*10000; + m->Value = intval*10000; + + /** Handling the "fraction" portion after the decimal point **/ if (*endptr == (intl_format?',':'.')) { - intval = strtoll(endptr+1, &endptr2, 10); + intval = strtoul(endptr+1, &endptr2, 10); scale = endptr2 - (endptr+1); if (scale != strspn(endptr+1, "0123456789")) return -1; @@ -1475,13 +1481,12 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) while(scale > 4) { scale--; intval /= 10; } if (is_neg) { - m->MoneyValue -= intval; + m->Value -= intval; } else { - m->MoneyValue += intval; + m->Value += intval; } - //m->FractionPart = intval; endptr = endptr2; } if (endptr == ptr) @@ -1490,29 +1495,21 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) } if (*endptr == '-') { - m->MoneyValue = -m->MoneyValue; + m->Value = -m->Value; is_neg = !is_neg; } - /*if (is_neg && m->FractionPart != 0) - { //This handled the unsigned representation of FractionPart - m->WholePart--; - m->FractionPart = 10000 - m->FractionPart; - }*/ break; case DATA_T_DOUBLE: - dbl = *(double*)data_ptr + 0.000001; - long long WholePart = floor(dbl); - int FractionPart = (dbl - WholePart)*10000; - m->MoneyValue = (WholePart*10000) + FractionPart; + m->Value = *(double*)data_ptr * 10000.0; break; case DATA_T_INTEGER: - m->MoneyValue = *(long long*)data_ptr; + m->Value = *(long long*)data_ptr * 10000; break; case DATA_T_MONEY: - m->MoneyValue = ((pMoneyType)data_ptr)->MoneyValue; + m->Value = ((pMoneyType)data_ptr)->Value; break; } @@ -1593,9 +1590,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: m = (pMoneyType)data_ptr_2; - if (m->MoneyValue/10000 > intval) cmp_value = -1; - else if (m->MoneyValue/10000 < intval) cmp_value = 1; - else cmp_value = m->MoneyValue%10000?-1:0; + if (m->Value/10000 > intval) cmp_value = -1; + else if (m->Value/10000 < intval) cmp_value = 1; + else cmp_value = m->Value%10000?-1:0; break; case DATA_T_INTVEC: @@ -1636,9 +1633,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: objDataToMoney(DATA_T_STRING, data_ptr_1, &m_v); m = (pMoneyType)data_ptr_2; - if (m_v.MoneyValue/10000 > m->MoneyValue/10000) cmp_value = 1; - else if (m_v.MoneyValue/10000 < m->MoneyValue/10000) cmp_value = -1; - else cmp_value = m_v.MoneyValue%10000 - m->MoneyValue%10000; + if (m_v.Value > m->Value) cmp_value = 1; + else if (m_v.Value < m->Value) cmp_value = -1; + else cmp_value = 0; break; case DATA_T_DOUBLE: @@ -1692,7 +1689,7 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: m = (pMoneyType)data_ptr_2; - dblval = m->MoneyValue/10000 + ((m->MoneyValue%10000)/10000.0); + dblval = m->Value/10000.0; if (dblval == *(double*)data_ptr_1) cmp_value = 0; else if (dblval > *(double*)data_ptr_1) cmp_value = -1; else cmp_value = 1; @@ -1788,9 +1785,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt } else { - if (m->MoneyValue/10000 > iv->Integers[0]) cmp_value = -1; - else if (m->MoneyValue/10000 < iv->Integers[0]) cmp_value = 1; - else cmp_value = iv->Integers[1] - m->MoneyValue%10000; + if (m->Value/10000 > iv->Integers[0]) cmp_value = -1; + else if (m->Value/10000 < iv->Integers[0]) cmp_value = 1; + else cmp_value = iv->Integers[1] - m->Value%10000; } break; @@ -1840,9 +1837,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt switch(data_type_2) { case DATA_T_MONEY: - if (m->MoneyValue/10000 > ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = 1; - else if (m->MoneyValue/10000 < ((pMoneyType)data_ptr_2)->MoneyValue/10000) cmp_value = -1; - else cmp_value = m->MoneyValue%10000 - ((pMoneyType)data_ptr_2)->MoneyValue%10000; + if (m->Value > ((pMoneyType)data_ptr_2)->Value) cmp_value = 1; + else if (m->Value < ((pMoneyType)data_ptr_2)->Value) cmp_value = -1; + else cmp_value = 0; break; default: @@ -1918,28 +1915,28 @@ objDataToWords(int data_type, void* data_ptr) else if (data_type == DATA_T_MONEY) { m = (pMoneyType)data_ptr; - if (m->MoneyValue < 0) + if (m->Value < 0) { /** Keep the opposite (positive) value for printing **/ - integer_part = -m->MoneyValue/10000; - fraction_part = -m->MoneyValue%10000; + integer_part = -m->Value/10000; + fraction_part = -m->Value%10000; - /*if (m->MoneyValue%10000 == 0) + /*if (m->Value%10000 == 0) { - integer_part = -m->MoneyValue/10000; + integer_part = -m->Value/10000; fraction_part = 0; } else { - integer_part = (-m->MoneyValue/10000) - 1; - fraction_part = 10000 - m->MoneyValue%10000; + integer_part = (-m->Value/10000) - 1; + fraction_part = 10000 - m->Value%10000; }*/ xsConcatenate(&tmpbuf, "Negative ", -1); } else { - integer_part = m->MoneyValue/10000; - fraction_part = m->MoneyValue%10000; + integer_part = m->Value/10000; + fraction_part = m->Value%10000; } } else @@ -2208,6 +2205,9 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x80000000 to convert to Offset Zero form. **/ + //((long long*)tmp_buf)[0] = htonll(exp->Types.Money.Value ^ 0x8000000000000000); + *item = (char*)(tmp_buf); + *itemlen = 8; /*Carl ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); ((unsigned short*)tmp_buf)[2] = htons(exp->Types.Money.FractionPart); *item = (char*)(tmp_buf); From 05960ba3f68a6ec91c00111ca7ddcdcc9e2b3b7c Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 14 Aug 2020 13:51:23 -0600 Subject: [PATCH 063/129] Included byteswap.h and cleaned up old comments --- centrallix/objectsystem/obj_datatypes.c | 35 ++----------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 529b2b95a..745ba9914 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -501,18 +502,6 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) print_whole = m->Value/10000; print_fract = m->Value%10000; } - /*if (m->Value/10000 >= 0 || m->Value%10000 == 0) - { - print_whole = m->Value/10000; - print_fract = m->Value%10000; - } - else - { //This handled the unsigned representation of FractionPart - print_whole = m->Value/10000 + 1; - print_fract = 10000 - m->Value%10000; - } - orig_print_whole = m->Value/10000; - if (print_whole < 0) print_whole = -print_whole;*/ /** Ok, start generating the thing. **/ while(*fmt) @@ -817,11 +806,6 @@ objDataToInteger(int data_type, void* data_ptr, char* format) mssError(1,"OBJ","Warning: %d overflow; cannot fit value of that size in int ", data_type); else v = m->Value/10000; - //This handled the unsigned representation of FractionPart - /* if (m->Value%10000==0 || m->Value/10000>=0) - v = m->Value/10000; - else - v = m->Value/10000 + 1;*/ break; case DATA_T_INTVEC: @@ -1920,17 +1904,6 @@ objDataToWords(int data_type, void* data_ptr) /** Keep the opposite (positive) value for printing **/ integer_part = -m->Value/10000; fraction_part = -m->Value%10000; - - /*if (m->Value%10000 == 0) - { - integer_part = -m->Value/10000; - fraction_part = 0; - } - else - { - integer_part = (-m->Value/10000) - 1; - fraction_part = 10000 - m->Value%10000; - }*/ xsConcatenate(&tmpbuf, "Negative ", -1); } else @@ -2205,13 +2178,9 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x80000000 to convert to Offset Zero form. **/ - //((long long*)tmp_buf)[0] = htonll(exp->Types.Money.Value ^ 0x8000000000000000); + ((long long*)tmp_buf)[0] = bswap_64(exp->Types.Money.Value ^ 0x8000000000000000); *item = (char*)(tmp_buf); *itemlen = 8; - /*Carl ((unsigned int*)tmp_buf)[0] = htonl(exp->Types.Money.WholePart ^ 0x80000000); - ((unsigned short*)tmp_buf)[2] = htons(exp->Types.Money.FractionPart); - *item = (char*)(tmp_buf); - *itemlen = 6;*/ break; case DATA_T_DOUBLE: From c3a35d573cf7dc4cdc515f9262c709ae4f40a425 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 18 Aug 2020 10:16:09 -0600 Subject: [PATCH 064/129] Initial MoneyType Tests for obj_datatype functions --- centrallix/objectsystem/obj_datatypes.c | 2 +- centrallix/tests/test_moneytype_example.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 745ba9914..b6212f6d6 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -803,7 +803,7 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; if (m->Value/10000 > INT_MAX) - mssError(1,"OBJ","Warning: %d overflow; cannot fit value of that size in int ", data_type); + mssError(1, "OBJ", "Warning: %d overflow; cannot fit value of that size in int ", data_type); else v = m->Value/10000; break; diff --git a/centrallix/tests/test_moneytype_example.c b/centrallix/tests/test_moneytype_example.c index 16c2fbf6b..742446200 100644 --- a/centrallix/tests/test_moneytype_example.c +++ b/centrallix/tests/test_moneytype_example.c @@ -5,7 +5,9 @@ long long test(char** name) { *name = "MoneyType example"; - MoneyType test = {1, 1}; + + MoneyType test = {10000}; assert(strcmp(objFormatMoneyTmp(&test, NULL), "$1.00") == 0); + return 0; } From 1515d913384e1e8915c71ff692640071d57176c3 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 18 Aug 2020 10:41:12 -0600 Subject: [PATCH 065/129] MoneyType Tests for obj_datatype functions; Removal of Example --- centrallix/.testdepend | 2 + centrallix/tests/test_moneytype_00.c | 30 ++++++++++++++ centrallix/tests/test_moneytype_01.c | 44 ++++++++++++++++++++ centrallix/tests/test_moneytype_02.c | 31 ++++++++++++++ centrallix/tests/test_moneytype_03.c | 35 ++++++++++++++++ centrallix/tests/test_moneytype_04.c | 49 +++++++++++++++++++++++ centrallix/tests/test_moneytype_example.c | 13 ------ 7 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 centrallix/.testdepend create mode 100644 centrallix/tests/test_moneytype_00.c create mode 100644 centrallix/tests/test_moneytype_01.c create mode 100644 centrallix/tests/test_moneytype_02.c create mode 100644 centrallix/tests/test_moneytype_03.c create mode 100644 centrallix/tests/test_moneytype_04.c delete mode 100644 centrallix/tests/test_moneytype_example.c diff --git a/centrallix/.testdepend b/centrallix/.testdepend new file mode 100644 index 000000000..563e7cb65 --- /dev/null +++ b/centrallix/.testdepend @@ -0,0 +1,2 @@ + +tests/test_00baseline_07.bin: diff --git a/centrallix/tests/test_moneytype_00.c b/centrallix/tests/test_moneytype_00.c new file mode 100644 index 000000000..931ee6505 --- /dev/null +++ b/centrallix/tests/test_moneytype_00.c @@ -0,0 +1,30 @@ +#include "obj.h" +#include + +long long +test(char** name) +{ + *name = "moneytype_00 - obj_internal_FormatMoney"; + + /** 0 Case **/ + MoneyType test = {0}; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "$0.00") == 0); + + /** Positive Case **/ + test.Value = 70000; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "$7.00") == 0); + + /** Negative Case **/ + test.Value = -70000; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "-$7.00") == 0); + + /** Nonzero Cent Case **/ + test.Value = -75000; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "-$7.50") == 0); + + /** Fractional Cent Case **/ + test.Value = -70001; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "-$7.00") == 0); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_01.c b/centrallix/tests/test_moneytype_01.c new file mode 100644 index 000000000..0256d31d6 --- /dev/null +++ b/centrallix/tests/test_moneytype_01.c @@ -0,0 +1,44 @@ +#include "obj.h" +#include +#include +//#include "xstring.h" +//#include "mtsession.h" +//#include "mtask.h" + +long long +test(char** name) +{ + *name = "moneytype_01 - objDataToInteger"; + int testValue; + + /** Zero Case **/ + MoneyType test = {0}; + testValue = objDataToInteger(7,&test,NULL); + assert(testValue == 0); + + /** Positive Case **/ + test.Value = 10000; + testValue = objDataToInteger(7,&test,NULL); + assert(testValue == 1); + + /** Negative Case **/ + test.Value = -10000; + testValue = objDataToInteger(7,&test,NULL); + assert(testValue == -1); + + /** Overflow Case **/ + //Manual Testing showed this section to work properly on overflow + //Currently, I do not know how to print the error messages, so this part + //will remain commented out. + + //test.Value = 250000000000000000; + //testValue = objDataToInteger(7,&test,NULL); + + //assert(testValue); + //assert(testValue == 5); + //mssStringError(pXString); + //printf("%s", pXString); + + + return 0; +} diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_02.c new file mode 100644 index 000000000..97347f46c --- /dev/null +++ b/centrallix/tests/test_moneytype_02.c @@ -0,0 +1,31 @@ +#include "obj.h" +#include + +long long +test(char** name) +{ + *name = "moneytype_02 - objDataToDouble"; + double testValue; + + /** Zero Case **/ + MoneyType test = {0}; + testValue = objDataToDouble(7,&test); + assert(testValue == 0.0); + + /** Positive Case **/ + test.Value = 10000; + testValue = objDataToDouble(7,&test); + assert(testValue == 1.0); + + /** Negative Case **/ + test.Value = -10000; + testValue = objDataToDouble(7,&test); + assert(testValue == -1.0); + + /** Fraction Case **/ + test.Value = -25000; + testValue = objDataToDouble(7,&test); + assert(testValue == -2.5); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c new file mode 100644 index 000000000..5287a1cfb --- /dev/null +++ b/centrallix/tests/test_moneytype_03.c @@ -0,0 +1,35 @@ +#include "obj.h" +#include +#include + +long long +test(char** name) +{ + *name = "moneytype_03 - objDataToMoney"; + MoneyType test = {0}; + + /** String Case **/ + char data_ptr[] = "$4.50"; + assert(objDataToMoney(2,data_ptr,&test) == 0); + assert(test.Value == 45000); + //printf("%lld", test.Value); + + //Edge Cases + + /** Double Case **/ + double testDouble = 5.5; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == 55000); + + /** Int Case **/ + int testInt = 6; + assert(objDataToMoney(1,&testInt,&test) == 0); + assert(test.Value == 60000); + + /** Money Case **/ + MoneyType testMoney = {900000}; + assert(objDataToMoney(7,&testMoney,&test) == 0); + assert(test.Value == 900000); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c new file mode 100644 index 000000000..bbae6842c --- /dev/null +++ b/centrallix/tests/test_moneytype_04.c @@ -0,0 +1,49 @@ +#include "obj.h" +#include +#include + +long long +test(char** name) +{ + *name = "moneytype_04 - objDataCompare"; + MoneyType test = {70500}; + + /** Compare Int with Money Case **/ + int testInt = 6; + assert(objDataCompare(1,&testInt,7,&test) == -1); + + ////Edge Cases + // + ///** Compare Double with Money Case **/ + //double testDouble = 5.5; + //assert(objDataToMoney(3,&testDouble,&test) == 0); + //assert(test.Value == 55000); + // + ///** Compare String with Money Case **/ + //char data_ptr[] = "$4.50"; + //int testInt = 6; + //assert(objDataToMoney(1,&testInt,&test) == 0); + //assert(test.Value == 60000); + // + ///** Compare Money with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + ///** Compare DateTime with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + ///** Compare IntV with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + ///** Compare StrV with Money Case **/ + //MoneyType testMoney = {900000}; + //assert(objDataToMoney(7,&testMoney,&test) == 0); + //assert(test.Value == 900000); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_example.c b/centrallix/tests/test_moneytype_example.c deleted file mode 100644 index 742446200..000000000 --- a/centrallix/tests/test_moneytype_example.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "obj.h" -#include - -long long -test(char** name) -{ - *name = "MoneyType example"; - - MoneyType test = {10000}; - assert(strcmp(objFormatMoneyTmp(&test, NULL), "$1.00") == 0); - - return 0; -} From 32cf3615e5a330ff8eddd4ae8bf3554c72dd9657 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:45:16 -0600 Subject: [PATCH 066/129] More MoneyType Tests for obj_datatype functions --- centrallix/objectsystem/obj_datatypes.c | 2 +- centrallix/tests/test_moneytype_04.c | 49 ++++++++++--------------- centrallix/tests/test_moneytype_05.c | 25 +++++++++++++ centrallix/tests/test_moneytype_06.c | 30 +++++++++++++++ 4 files changed, 76 insertions(+), 30 deletions(-) create mode 100644 centrallix/tests/test_moneytype_05.c create mode 100644 centrallix/tests/test_moneytype_06.c diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index b6212f6d6..6d227bf79 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -2177,7 +2177,7 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO break; case DATA_T_MONEY: - /** XOR 0x80000000 to convert to Offset Zero form. **/ + /** XOR 0x8000000000000000 to convert to Offset Zero form. **/ ((long long*)tmp_buf)[0] = bswap_64(exp->Types.Money.Value ^ 0x8000000000000000); *item = (char*)(tmp_buf); *itemlen = 8; diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c index bbae6842c..eba9fadbf 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_04.c @@ -12,38 +12,29 @@ test(char** name) int testInt = 6; assert(objDataCompare(1,&testInt,7,&test) == -1); - ////Edge Cases - // - ///** Compare Double with Money Case **/ - //double testDouble = 5.5; - //assert(objDataToMoney(3,&testDouble,&test) == 0); - //assert(test.Value == 55000); - // - ///** Compare String with Money Case **/ - //char data_ptr[] = "$4.50"; - //int testInt = 6; - //assert(objDataToMoney(1,&testInt,&test) == 0); - //assert(test.Value == 60000); - // - ///** Compare Money with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare Double with Money Case **/ + double testDouble = 5.5; + assert(objDataCompare(3,&testDouble,7,&test) == -1); + + /** Compare String with Money Case **/ + char data_ptr[] = "$4.50"; + assert(objDataCompare(2,data_ptr,7,&test) == -1); + + /** Compare Money with Money Case **/ + MoneyType testMoney = {70500}; + assert(objDataCompare(7,&testMoney,7,&test) == 0); - ///** Compare DateTime with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare DateTime with Money Case **/ + DateTime testDate = {0}; + assert(objDataCompare(4,&testDate,7,&test) == -2); - ///** Compare IntV with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare IntV with Money Case **/ + IntVec testIV = {0}; + assert(objDataCompare(5,&testIV,7,&test) == -2); - ///** Compare StrV with Money Case **/ - //MoneyType testMoney = {900000}; - //assert(objDataToMoney(7,&testMoney,&test) == 0); - //assert(test.Value == 900000); + /** Compare StrV with Money Case **/ + StringVec testSV = {0}; + assert(objDataCompare(6,&testSV,7,&test) == -2); return 0; } diff --git a/centrallix/tests/test_moneytype_05.c b/centrallix/tests/test_moneytype_05.c new file mode 100644 index 000000000..c013fa13e --- /dev/null +++ b/centrallix/tests/test_moneytype_05.c @@ -0,0 +1,25 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" + +long long +test(char** name) +{ + *name = "moneytype_05 - objDataToWords"; + MoneyType test = {70500}; + + /** Positive Case **/ + char* data_ptr = "Seven And 05/100 "; + char* returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); + + /** Negative Case **/ + test.Value = -70500; + data_ptr = "Negative Seven And 05/100 "; + returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_06.c b/centrallix/tests/test_moneytype_06.c new file mode 100644 index 000000000..9df19b1a9 --- /dev/null +++ b/centrallix/tests/test_moneytype_06.c @@ -0,0 +1,30 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" + +long long +test(char** name) +{ + *name = "moneytype_06 - obj_internal_BuildBinaryItem"; + char** item; + int* itemlen; + pExpression testExp = expAllocExpression(); + pParamObjects testParamObjects = expCreateParamList(); + unsigned char tmpbuf[12]; + + /** Positive Case **/ + testExp->Types.Money.Value = 90000; + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + + /** Negative Case **/ + //test.Value = -70500; + //data_ptr = "Negative Seven And 05/100 "; + //returnStr = objDataToWords(7,&test); + //assert(strcmp(data_ptr, returnStr) == 0); + + expFreeExpression(testExp); + + return 0; +} From 5ee4218b28f233aba08765ddcf78d46ff63218a0 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 19 Aug 2020 10:37:54 -0600 Subject: [PATCH 067/129] Expanded functionality for moneytype tests --- centrallix/tests/test_moneytype_02.c | 2 +- centrallix/tests/test_moneytype_03.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_02.c index 97347f46c..8a9b57331 100644 --- a/centrallix/tests/test_moneytype_02.c +++ b/centrallix/tests/test_moneytype_02.c @@ -22,7 +22,7 @@ test(char** name) testValue = objDataToDouble(7,&test); assert(testValue == -1.0); - /** Fraction Case **/ + /** Rational Case **/ test.Value = -25000; testValue = objDataToDouble(7,&test); assert(testValue == -2.5); diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c index 5287a1cfb..1dd177d1e 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_03.c @@ -12,9 +12,6 @@ test(char** name) char data_ptr[] = "$4.50"; assert(objDataToMoney(2,data_ptr,&test) == 0); assert(test.Value == 45000); - //printf("%lld", test.Value); - - //Edge Cases /** Double Case **/ double testDouble = 5.5; @@ -31,5 +28,9 @@ test(char** name) assert(objDataToMoney(7,&testMoney,&test) == 0); assert(test.Value == 900000); + /** Overflow Case (intval > LL max) **/ + char overflow_ptr[] = "$10000000000000000000.50"; + assert(objDataToMoney(2,overflow_ptr,&test) == -1); + return 0; } From 9a174791455e2c60e866eeede3e0fb4ba6381d04 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 19 Aug 2020 16:12:46 -0600 Subject: [PATCH 068/129] Converted to 64 bit MoneyType Representation --- centrallix/expression/exp_evaluate.c | 119 +++++++++------------------ centrallix/expression/exp_main.c | 6 +- 2 files changed, 43 insertions(+), 82 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index 0d17affd6..d706ca7db 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -226,9 +226,9 @@ expEvalDivide(pExpression tree, pParamObjects objlist) /** Check for divide by zero **/ if ((i1->DataType == DATA_T_INTEGER && i1->Integer == 0) || - (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0)){ //|| - //(i1->DataType == DATA_T_MONEY && i1->Types.Money.WholePart == 0 && i1->Types.Money.FractionPart == 0)) - //{ + (i1->DataType == DATA_T_DOUBLE && i1->Types.Double == 0.0) || + (i1->DataType == DATA_T_MONEY && i1->Types.Money.Value == 0)) + { mssError(1,"EXP","Attempted divide by zero"); return -1; } @@ -275,20 +275,15 @@ expEvalDivide(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: - /*Carl switch(i1->DataType) + switch(i1->DataType) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; memcpy(&m, &(i0->Types.Money), sizeof(MoneyType)); - if (m.WholePart < 0) + if (m.Value < 0) { is_negative = !is_negative; - if (m.FractionPart != 0) - { - m.WholePart = m.WholePart + 1; - m.FractionPart = 10000 - m.FractionPart; - } - m.WholePart = -m.WholePart; + m.Value = -m.Value; } i = i1->Integer; if (i < 0) @@ -301,16 +296,10 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - //tree->Types.Money.WholePart = m.WholePart / i; - //tree->Types.Money.FractionPart = (10000*(m.WholePart % i) + m.FractionPart)/i; + tree->Types.Money.Value = m.Value / i; if (is_negative) { - if (tree->Types.Money.FractionPart != 0) - { - tree->Types.Money.WholePart = tree->Types.Money.WholePart + 1; - tree->Types.Money.FractionPart = 10000 - tree->Types.Money.FractionPart; - } - tree->Types.Money.WholePart = -tree->Types.Money.WholePart; + tree->Types.Money.Value = -tree->Types.Money.Value; } break; case DATA_T_DOUBLE: @@ -320,7 +309,11 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + md = i0->Types.Money.Value / 10000.0; + md = md / i1->Types.Double; + tree->Types.Money.Value = (long long)(md * 10000); + //Old Definition + /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; md = mv / i1->Types.Double; if (md < 0) md -= 0.5; else md += 0.5; @@ -332,12 +325,12 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mv += 10000; tree->Types.Money.WholePart -= 1; } - tree->Types.Money.FractionPart = mv; + tree->Types.Money.FractionPart = mv;*/ break; case DATA_T_MONEY: - mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; - mv2 = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - if (mv2 == 0) + mv = i0->Types.Money.Value; + mv2 = i1->Types.Money.Value; + if (i1->Types.Money.Value == 0) { mssError(1,"EXP","Attempted divide by zero"); return -1; @@ -353,7 +346,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) tree->Types.Double = (double)mv / (double)mv2; } break; - }*/ + } break; default: @@ -453,8 +446,8 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) { case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - //mv *= i0->Types.Double; + //Double check that casting is working properly + mv = i1->Types.Money.Value * i0->Types.Double; break; default: tree->Types.Double = i0->Types.Double * objDataToDouble(i1->DataType, dptr); @@ -465,25 +458,28 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - /*Carl mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + mv = i0->Types.Money.Value; switch(i1->DataType) { case DATA_T_INTEGER: mv *= i1->Integer; break; - case DATA_T_DOUBLE: + + case DATA_T_DOUBLE: md = mv * i1->Types.Double; if (md < 0) md -= 0.5; else md += 0.5; mv = md; break; + case DATA_T_MONEY: mssError(1,"EXP","Cannot multiply a money data type by another money data type"); return -1; + default: mssError(1,"EXP","Can only multiply a money data type by an integer or double"); return -1; - }*/ + } break; case DATA_T_STRING: @@ -505,14 +501,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) /** Common processing **/ if (tree->DataType == DATA_T_MONEY) { - /*Carl tree->Types.Money.WholePart = mv/10000; - mv = mv % 10000; - if (mv < 0) - { - mv += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mv;*/ + tree->Types.Money.Value = mv; } else if (tree->DataType == DATA_T_STRING) { @@ -604,17 +593,9 @@ expEvalMinus(pExpression tree, pParamObjects objlist) tree->Types.Double = (double)(i0->Integer) - i1->Types.Double; break; case DATA_T_MONEY: + /** Treat Int as a dollar value **/ tree->DataType = DATA_T_MONEY; - /*Carl tree->Types.Money.WholePart = i0->Integer - i1->Types.Money.WholePart; - if (i1->Types.Money.FractionPart == 0) - { - tree->Types.Money.FractionPart = 0; - } - else - { - tree->Types.Money.WholePart--; - tree->Types.Money.FractionPart = 10000 - i1->Types.Money.FractionPart; - }*/ + tree->Types.Money.Value = (i0->Integer * 10000) - i1->Types.Money.Value; break; default: tree->Integer = i0->Integer - objDataToInteger(i1->DataType, dptr, NULL); @@ -635,7 +616,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_DOUBLE; - //tree->Types.Double = i0->Types.Double - (i1->Types.Money.WholePart + i1->Types.Money.FractionPart/10000.0); + tree->Types.Double = i0->Types.Double - (i1->Types.Money.Value / 10000.0); break; default: tree->DataType = DATA_T_DOUBLE; @@ -649,25 +630,16 @@ expEvalMinus(pExpression tree, pParamObjects objlist) { case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; - //tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Integer; - //tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; + /** Since Value is in 1/10000 of a dollar, integer must be multiplied to scale **/ + tree->Types.Money.Value = i0->Types.Money.Value - (i1->Integer * 10000); break; case DATA_T_DOUBLE: tree->DataType = DATA_T_DOUBLE; - //tree->Types.Double = (i0->Types.Money.WholePart + i0->Types.Money.FractionPart/10000.0) - i1->Types.Double; + tree->Types.Double = (i0->Types.Money.Value / 10000.0) - i1->Types.Double; break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - i1->Types.Money.WholePart; - tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - i1->Types.Money.FractionPart; - if (tree->Types.Money.FractionPart >= 10000) - { - tree->Types.Money.FractionPart -= 10000; - } - else - { - tree->Types.Money.WholePart--; - }*/ + tree->Types.Money.Value = i0->Types.Money.Value - i1->Types.Money.Value; break; default: if (objDataToMoney(i1->DataType, dptr, &m) < 0) @@ -676,12 +648,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) return -1; } tree->DataType = DATA_T_MONEY; - /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart - m.WholePart; - tree->Types.Money.FractionPart = 10000 + i0->Types.Money.FractionPart - m.FractionPart; - if (tree->Types.Money.FractionPart >= 10000) - tree->Types.Money.FractionPart -= 10000; - else - tree->Types.Money.WholePart--; */ + tree->Types.Money.Value = i0->Types.Money.Value - m.Value; break; } break; @@ -806,8 +773,8 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - //tree->Types.Money.WholePart = i1->Types.Money.WholePart + i0->Integer; - //tree->Types.Money.FractionPart = i1->Types.Money.FractionPart; + /** Int must be converted to 1/10000 of a dollar **/ + tree->Types.Money.Value = i1->Types.Money.Value + (i0->Integer * 10000); break; default: @@ -843,13 +810,7 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: objDataToMoney(i1->DataType, dptr, &m); - /*Carl tree->Types.Money.WholePart = i0->Types.Money.WholePart + m.WholePart; - tree->Types.Money.FractionPart = i0->Types.Money.FractionPart + m.FractionPart; - if (tree->Types.Money.FractionPart >= 10000) - { - tree->Types.Money.FractionPart -= 10000; - tree->Types.Money.WholePart++; - }*/ + tree->Types.Money.Value = i0->Types.Money.Value + m.Value; break; case DATA_T_DATETIME: @@ -1498,8 +1459,8 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) } else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { - //tree->Types.Money.WholePart = tree->Integer; - //tree->Types.Money.FractionPart = 0; + tree->Types.Money.Value = (tree->Integer * 10000); + tree->Types.Money.FractionPart = 0; } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/expression/exp_main.c b/centrallix/expression/exp_main.c index 0bdbcd0a3..ef2598709 100644 --- a/centrallix/expression/exp_main.c +++ b/centrallix/expression/exp_main.c @@ -523,7 +523,7 @@ exp_internal_DumpExpression_r(pExpression this, int level) case EXPR_N_INTEGER: printf("INTEGER = %d", this->Integer); break; case EXPR_N_STRING: printf("STRING = <%s>", this->String); break; case EXPR_N_DOUBLE: printf("DOUBLE = %.2f", this->Types.Double); break; - case EXPR_N_MONEY: printf("MONEY");/*printf("MONEY = %d.%4.4d", this->Types.Money.WholePart, this->Types.Money.FractionPart);*/ break; + case EXPR_N_MONEY: printf("MONEY = %4.4lld", this->Types.Money.Value); break; case EXPR_N_DATETIME: printf("DATETIME = %s", objDataToStringTmp(DATA_T_DATETIME,&(this->Types.Date), 0)); break; case EXPR_N_PLUS: printf("PLUS"); break; case EXPR_N_MULTIPLY: printf("MULTIPLY"); break; @@ -863,8 +863,8 @@ expCompareExpressionValues(pExpression exp1, pExpression exp2) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DOUBLE && exp1->Types.Double != exp2->Types.Double) return 0; - //if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && (exp1->Types.Money.WholePart != exp2->Types.Money.WholePart || exp1->Types.Money.FractionPart != exp2->Types.Money.FractionPart)) - //return 0; + if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && exp1->Types.Money.Value != exp2->Types.Money.Value + return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DATETIME && (exp1->Types.Date.Part.Second != exp2->Types.Date.Part.Second || exp1->Types.Date.Part.Minute != exp2->Types.Date.Part.Minute || exp1->Types.Date.Part.Hour != exp2->Types.Date.Part.Hour || exp1->Types.Date.Part.Day != exp2->Types.Date.Part.Day || exp1->Types.Date.Part.Month != exp2->Types.Date.Part.Month || exp1->Types.Date.Part.Year != exp2->Types.Date.Part.Year)) return 0; From d293cb7565089b7c0f5dd07c22de2fa9618de357 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 19 Aug 2020 16:59:41 -0600 Subject: [PATCH 069/129] Converted to 64 bit MoneyType Representation --- centrallix/expression/exp_compiler.c | 3 +-- centrallix/expression/exp_functions.c | 33 +++++++-------------------- centrallix/expression/exp_params.c | 6 ++--- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/centrallix/expression/exp_compiler.c b/centrallix/expression/exp_compiler.c index 9bcbd9340..d47bea653 100644 --- a/centrallix/expression/exp_compiler.c +++ b/centrallix/expression/exp_compiler.c @@ -152,8 +152,7 @@ exp_internal_CompileExpression_r(pLxSession lxs, int level, pParamObjects objlis if (t == MLX_TOK_INTEGER) { i = mlxIntVal(lxs); - //etmp->Types.Money.WholePart = i; - //etmp->Types.Money.FractionPart = 0; + etmp->Types.Money.Value = (i * 10000); } else { diff --git a/centrallix/expression/exp_functions.c b/centrallix/expression/exp_functions.c index 2ffa2ac4b..1f2e399b7 100644 --- a/centrallix/expression/exp_functions.c +++ b/centrallix/expression/exp_functions.c @@ -266,24 +266,11 @@ int exp_fn_abs(pExpression tree, pParamObjects objlist, pExpression i0, pExpress break; case DATA_T_MONEY: - /*Carl if (i0->Types.Money.WholePart >= 0) - { - tree->Types.Money.WholePart = i0->Types.Money.WholePart; - tree->Types.Money.FractionPart = i0->Types.Money.FractionPart; - } - else - { - if (i0->Types.Money.FractionPart != 0) - { - tree->Types.Money.WholePart = -(i0->Types.Money.WholePart + 1); - tree->Types.Money.FractionPart = 10000 - i0->Types.Money.FractionPart; - } + if (i0->Types.Money.Value >= 0) + tree->Types.Money.Value = i0->Types.Money.Value; else - { - tree->Types.Money.WholePart = -i0->Types.Money.WholePart; - tree->Types.Money.FractionPart = 0; - } - }*/ + tree->Types.Money.Value = -i0->Types.Money.Value; + break; default: @@ -2947,8 +2934,7 @@ int exp_fn_avg(pExpression tree, pParamObjects objlist, pExpression i0, pExpress sumexp->String[0] = '\0'; sumexp->Integer = 0; sumexp->Types.Double = 0; - //sumexp->Types.Money.FractionPart = 0; - //sumexp->Types.Money.WholePart = 0; + sumexp->Types.Money.Value = 0; cntexp->Integer = 0; } @@ -3035,8 +3021,7 @@ int exp_fn_sum(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->AggExp->String[0] = '\0'; tree->AggExp->Integer = 0; tree->AggExp->Types.Double = 0; - //tree->AggExp->Types.Money.FractionPart = 0; - //tree->AggExp->Types.Money.WholePart = 0; + tree->AggExp->Types.Money.Value = 0; } expCopyValue(tree->AggExp, (pExpression)(tree->AggExp->Children.Items[0]), 1); expCopyValue(i0, (pExpression)(tree->AggExp->Children.Items[1]), 0); @@ -3098,8 +3083,7 @@ int exp_fn_max(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->String[0] = '\0'; tree->Integer = 0; tree->Types.Double = 0; - //tree->Types.Money.FractionPart = 0; - //tree->Types.Money.WholePart = 0; + tree->Types.Money.Value = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); @@ -3160,8 +3144,7 @@ int exp_fn_min(pExpression tree, pParamObjects objlist, pExpression i0, pExpress tree->Alloc = 0; tree->Integer = 0; tree->Types.Double = 0; - //tree->Types.Money.FractionPart = 0; - //tree->Types.Money.WholePart = 0; + tree->Types.Money.Value = 0; expCopyValue(i0,tree,0); } subexp = ((pExpression)(tree->AggExp->Children.Items[2])); diff --git a/centrallix/expression/exp_params.c b/centrallix/expression/exp_params.c index 83fa66167..260febff2 100644 --- a/centrallix/expression/exp_params.c +++ b/centrallix/expression/exp_params.c @@ -602,14 +602,12 @@ exp_internal_ResetAggregates(pExpression this, int reset_id, int level) { this->AggExp->Integer = 0; this->AggExp->Types.Double = 0; - //this->AggExp->Types.Money.WholePart = 0; - //this->AggExp->Types.Money.FractionPart = 0; + this->AggExp->Types.Money.Value = 0; this->Flags |= EXPR_F_AGGLOCKED; } this->Integer = 0; this->Types.Double = 0; - //this->Types.Money.WholePart = 0; - //this->Types.Money.FractionPart = 0; + this->Types.Money.Value = 0; if (!strcmp(this->Name,"count")) { this->Flags &= ~EXPR_F_NULL; From 20863523a307c14363cf2aee808eeccd3f0e4a96 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 20 Aug 2020 12:05:10 -0600 Subject: [PATCH 070/129] Round and truncate exp functions converted to 64 bit --- centrallix/expression/exp_functions.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/centrallix/expression/exp_functions.c b/centrallix/expression/exp_functions.c index 1f2e399b7..11d2a7d7f 100644 --- a/centrallix/expression/exp_functions.c +++ b/centrallix/expression/exp_functions.c @@ -1650,7 +1650,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre break; case DATA_T_MONEY: - /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + mt = i0->Types.Money.Value; if (dec < 4) { mv = 1; @@ -1662,14 +1662,7 @@ int exp_fn_round(pExpression tree, pParamObjects objlist, pExpression i0, pExpre mt /= mv; mt *= mv; } - tree->Types.Money.WholePart = mt/10000; - mt = mt % 10000; - if (mt < 0) - { - mt += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mt;*/ + tree->Types.Money.Value = mt; break; } return 0; @@ -1923,7 +1916,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx break; case DATA_T_MONEY: - /*Carl mt = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; + mt = i0->Types.Money.Value; if (dec < 4) { mv = 1; @@ -1931,14 +1924,7 @@ int exp_fn_truncate(pExpression tree, pParamObjects objlist, pExpression i0, pEx mt /= mv; mt *= mv; } - tree->Types.Money.WholePart = mt/10000; - mt = mt % 10000; - if (mt < 0) - { - mt += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mt;*/ + tree->Types.Money.Value = mt; break; } return 0; From 6841adbe0876d316869b7f4db622cf27ad6ade3b Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 20 Aug 2020 20:20:20 -0600 Subject: [PATCH 071/129] Addressing Code Review Comments and Improving Tests --- centrallix/expression/exp_evaluate.c | 8 ++-- centrallix/expression/exp_main.c | 2 +- centrallix/objectsystem/obj_datatypes.c | 13 +++--- centrallix/tests/test_moneytype_00.c | 4 ++ centrallix/tests/test_moneytype_01.c | 14 +++--- centrallix/tests/test_moneytype_02.c | 13 ++---- centrallix/tests/test_moneytype_03.c | 21 +++++++-- centrallix/tests/test_moneytype_04.c | 58 ++++++++++++++++++++++--- centrallix/tests/test_moneytype_05.c | 13 ++++++ 9 files changed, 110 insertions(+), 36 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index d706ca7db..e1b5d8bc2 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -311,6 +311,8 @@ expEvalDivide(pExpression tree, pParamObjects objlist) } md = i0->Types.Money.Value / 10000.0; md = md / i1->Types.Double; + if (md < 0) md -= 0.5; + else md += 0.5; tree->Types.Money.Value = (long long)(md * 10000); //Old Definition /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; @@ -330,7 +332,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: mv = i0->Types.Money.Value; mv2 = i1->Types.Money.Value; - if (i1->Types.Money.Value == 0) + if (mv2 == 0) { mssError(1,"EXP","Attempted divide by zero"); return -1; @@ -464,18 +466,15 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: mv *= i1->Integer; break; - case DATA_T_DOUBLE: md = mv * i1->Types.Double; if (md < 0) md -= 0.5; else md += 0.5; mv = md; break; - case DATA_T_MONEY: mssError(1,"EXP","Cannot multiply a money data type by another money data type"); return -1; - default: mssError(1,"EXP","Can only multiply a money data type by an integer or double"); return -1; @@ -1460,7 +1459,6 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { tree->Types.Money.Value = (tree->Integer * 10000); - tree->Types.Money.FractionPart = 0; } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/expression/exp_main.c b/centrallix/expression/exp_main.c index ef2598709..8ef286801 100644 --- a/centrallix/expression/exp_main.c +++ b/centrallix/expression/exp_main.c @@ -863,7 +863,7 @@ expCompareExpressionValues(pExpression exp1, pExpression exp2) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DOUBLE && exp1->Types.Double != exp2->Types.Double) return 0; - if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && exp1->Types.Money.Value != exp2->Types.Money.Value + if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_MONEY && exp1->Types.Money.Value != exp2->Types.Money.Value) return 0; if (!(exp1->Flags & EXPR_F_NULL) && exp1->DataType == DATA_T_DATETIME && (exp1->Types.Date.Part.Second != exp2->Types.Date.Part.Second || exp1->Types.Date.Part.Minute != exp2->Types.Date.Part.Minute || exp1->Types.Date.Part.Hour != exp2->Types.Date.Part.Hour || exp1->Types.Date.Part.Day != exp2->Types.Date.Part.Day || exp1->Types.Date.Part.Month != exp2->Types.Date.Part.Month || exp1->Types.Date.Part.Year != exp2->Types.Date.Part.Year)) return 0; diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 6d227bf79..ec85f12cb 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1485,11 +1485,12 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) break; case DATA_T_DOUBLE: - m->Value = *(double*)data_ptr * 10000.0; + dbl = *(double*)data_ptr * 10000.0; + m->Value = (long long)dbl; break; case DATA_T_INTEGER: - m->Value = *(long long*)data_ptr * 10000; + m->Value = *(int*)data_ptr * 10000; break; case DATA_T_MONEY: @@ -1769,9 +1770,11 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt } else { - if (m->Value/10000 > iv->Integers[0]) cmp_value = -1; - else if (m->Value/10000 < iv->Integers[0]) cmp_value = 1; - else cmp_value = iv->Integers[1] - m->Value%10000; + if (m->Value/10000 > iv->Integers[0]) + {cmp_value = -1; printf("Reached -1");} + else if (m->Value/10000 < iv->Integers[0]) + {cmp_value = 1; printf("Reached 1");} + else {cmp_value = iv->Integers[1] - m->Value%10000; printf("Reached 0");} } break; diff --git a/centrallix/tests/test_moneytype_00.c b/centrallix/tests/test_moneytype_00.c index 931ee6505..7901cd348 100644 --- a/centrallix/tests/test_moneytype_00.c +++ b/centrallix/tests/test_moneytype_00.c @@ -4,6 +4,10 @@ long long test(char** name) { + /** objFormatMoneyTmp is a wrapper that calls obj_internal_FormatMoney + ** Functionality was changed in obj_internal_FormatMoney, so the point of + ** these tests is to test obj_internal_FormatMoney, even with a different function call + **/ *name = "moneytype_00 - obj_internal_FormatMoney"; /** 0 Case **/ diff --git a/centrallix/tests/test_moneytype_01.c b/centrallix/tests/test_moneytype_01.c index 0256d31d6..b66efe70d 100644 --- a/centrallix/tests/test_moneytype_01.c +++ b/centrallix/tests/test_moneytype_01.c @@ -9,22 +9,22 @@ long long test(char** name) { *name = "moneytype_01 - objDataToInteger"; - int testValue; /** Zero Case **/ MoneyType test = {0}; - testValue = objDataToInteger(7,&test,NULL); - assert(testValue == 0); + assert(objDataToInteger(7,&test,NULL) == 0); /** Positive Case **/ test.Value = 10000; - testValue = objDataToInteger(7,&test,NULL); - assert(testValue == 1); + assert(objDataToInteger(7,&test,NULL) == 1); /** Negative Case **/ test.Value = -10000; - testValue = objDataToInteger(7,&test,NULL); - assert(testValue == -1); + assert(objDataToInteger(7,&test,NULL) == -1); + + /** Fractional Case **/ + test.Value = 15000; + assert(objDataToInteger(7,&test,NULL) == 1); /** Overflow Case **/ //Manual Testing showed this section to work properly on overflow diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_02.c index 8a9b57331..d2dfd1e97 100644 --- a/centrallix/tests/test_moneytype_02.c +++ b/centrallix/tests/test_moneytype_02.c @@ -5,27 +5,22 @@ long long test(char** name) { *name = "moneytype_02 - objDataToDouble"; - double testValue; /** Zero Case **/ MoneyType test = {0}; - testValue = objDataToDouble(7,&test); - assert(testValue == 0.0); + assert(objDataToDouble(7,&test) == 0.0); /** Positive Case **/ test.Value = 10000; - testValue = objDataToDouble(7,&test); - assert(testValue == 1.0); + assert(objDataToDouble(7,&test) == 1.0); /** Negative Case **/ test.Value = -10000; - testValue = objDataToDouble(7,&test); - assert(testValue == -1.0); + assert(objDataToDouble(7,&test) == -1.0); /** Rational Case **/ test.Value = -25000; - testValue = objDataToDouble(7,&test); - assert(testValue == -2.5); + assert(objDataToDouble(7,&test) == -2.5); return 0; } diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c index 1dd177d1e..f862c0edd 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_03.c @@ -13,10 +13,27 @@ test(char** name) assert(objDataToMoney(2,data_ptr,&test) == 0); assert(test.Value == 45000); + char data_ptr2[] = "-$4.50"; + assert(objDataToMoney(2,data_ptr2,&test) == 0); + assert(test.Value == -45000); + + /** Overflow Case (intval > LL max) **/ + char overflow_ptr[] = "$10000000000000000000.50"; + assert(objDataToMoney(2,overflow_ptr,&test) == -1); + /** Double Case **/ double testDouble = 5.5; assert(objDataToMoney(3,&testDouble,&test) == 0); assert(test.Value == 55000); + + testDouble = -5.5; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == -55000); + + //Double Fraction Overflow + testDouble = 5.159999999999; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == 51599); /** Int Case **/ int testInt = 6; @@ -28,9 +45,7 @@ test(char** name) assert(objDataToMoney(7,&testMoney,&test) == 0); assert(test.Value == 900000); - /** Overflow Case (intval > LL max) **/ - char overflow_ptr[] = "$10000000000000000000.50"; - assert(objDataToMoney(2,overflow_ptr,&test) == -1); + return 0; } diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c index eba9fadbf..345bff04f 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_04.c @@ -1,27 +1,56 @@ #include "obj.h" #include #include +//#include long long test(char** name) { *name = "moneytype_04 - objDataCompare"; - MoneyType test = {70500}; + MoneyType test = {70000}; /** Compare Int with Money Case **/ - int testInt = 6; + /** Greater Than **/ + int testInt = 8; + assert(objDataCompare(1,&testInt,7,&test) == 1); + /** Less Than **/ + testInt = 6; assert(objDataCompare(1,&testInt,7,&test) == -1); + /** Equal To **/ + testInt = 7; + assert(objDataCompare(1,&testInt,7,&test) == 0); /** Compare Double with Money Case **/ - double testDouble = 5.5; + /** Greater Than **/ + double testDouble = 7.5; + assert(objDataCompare(3,&testDouble,7,&test) == 1); + /** Less Than **/ + testDouble = 5.5; assert(objDataCompare(3,&testDouble,7,&test) == -1); + /** Equal To **/ + testDouble = 7.0; + assert(objDataCompare(3,&testDouble,7,&test) == 0); /** Compare String with Money Case **/ - char data_ptr[] = "$4.50"; - assert(objDataCompare(2,data_ptr,7,&test) == -1); + /** Greater Than **/ + char data_ptr[] = "$8.50"; + assert(objDataCompare(2,data_ptr,7,&test) == 1); + /** Less Than **/ + char data_ptr2[] = "$4.50"; + assert(objDataCompare(2,data_ptr2,7,&test) == -1); + /** Equal To **/ + char data_ptr3[] = "$7.00"; + assert(objDataCompare(2,data_ptr3,7,&test) == 0); /** Compare Money with Money Case **/ - MoneyType testMoney = {70500}; + /** Greater Than **/ + MoneyType testMoney = {80500}; + assert(objDataCompare(7,&testMoney,7,&test) == 1); + /** Less Than **/ + testMoney.Value = 50000; + assert(objDataCompare(7,&testMoney,7,&test) == -1); + /** Equal To **/ + testMoney.Value = 70000; assert(objDataCompare(7,&testMoney,7,&test) == 0); /** Compare DateTime with Money Case **/ @@ -29,9 +58,26 @@ test(char** name) assert(objDataCompare(4,&testDate,7,&test) == -2); /** Compare IntV with Money Case **/ + /** IntV fails with any value other than 2 **/ IntVec testIV = {0}; assert(objDataCompare(5,&testIV,7,&test) == -2); + int* argArray[2]; + IntVec validTestIV = {0}; + validTestIV.nIntegers = 2; + validTestIV.Integers = argArray; + validTestIV.Integers[0] = 9; + validTestIV.Integers[1] = 20; + assert(objDataCompare(5,&validTestIV,7,&test) == 1); + + validTestIV.Integers[0] = 4; + validTestIV.Integers[1] = 35; + assert(objDataCompare(5,&validTestIV,7,&test) == -1); + + validTestIV.Integers[0] = 7; + validTestIV.Integers[1] = 0; + assert(objDataCompare(5,&testIV,7,&test) == 0); + /** Compare StrV with Money Case **/ StringVec testSV = {0}; assert(objDataCompare(6,&testSV,7,&test) == -2); diff --git a/centrallix/tests/test_moneytype_05.c b/centrallix/tests/test_moneytype_05.c index c013fa13e..b9caac0cb 100644 --- a/centrallix/tests/test_moneytype_05.c +++ b/centrallix/tests/test_moneytype_05.c @@ -20,6 +20,19 @@ test(char** name) data_ptr = "Negative Seven And 05/100 "; returnStr = objDataToWords(7,&test); assert(strcmp(data_ptr, returnStr) == 0); + + /**objDataToWords Truncates fractional cent values past 100ths**/ + /** Fractional Case **/ + test.Value = -70525; + data_ptr = "Negative Seven And 05/100 "; + returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); + + /** Fractional Case **/ + test.Value = -70575; + data_ptr = "Negative Seven And 05/100 "; + returnStr = objDataToWords(7,&test); + assert(strcmp(data_ptr, returnStr) == 0); return 0; } From 39b8deb7a23ab8658a82624f6400c447820b284a Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 20 Aug 2020 20:40:13 -0600 Subject: [PATCH 072/129] Fixing mt test 4 and removing testing comments --- centrallix/objectsystem/obj_datatypes.c | 8 +++----- centrallix/tests/test_moneytype_04.c | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index ec85f12cb..39966e9ce 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1770,11 +1770,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt } else { - if (m->Value/10000 > iv->Integers[0]) - {cmp_value = -1; printf("Reached -1");} - else if (m->Value/10000 < iv->Integers[0]) - {cmp_value = 1; printf("Reached 1");} - else {cmp_value = iv->Integers[1] - m->Value%10000; printf("Reached 0");} + if (m->Value/10000 > iv->Integers[0]) cmp_value = -1; + else if (m->Value/10000 < iv->Integers[0])cmp_value = 1; + else cmp_value = iv->Integers[1] - m->Value%10000; } break; diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_04.c index 345bff04f..b6d5b9f30 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_04.c @@ -76,7 +76,7 @@ test(char** name) validTestIV.Integers[0] = 7; validTestIV.Integers[1] = 0; - assert(objDataCompare(5,&testIV,7,&test) == 0); + assert(objDataCompare(5,&validTestIV,7,&test) == 0); /** Compare StrV with Money Case **/ StringVec testSV = {0}; From 12b99938460ef5d53886f33b621d6478a40f9f2f Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 21 Aug 2020 13:03:07 -0600 Subject: [PATCH 073/129] Resolving Code Review comments --- centrallix/.testdepend | 2 -- centrallix/objectsystem/obj_datatypes.c | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) delete mode 100644 centrallix/.testdepend diff --git a/centrallix/.testdepend b/centrallix/.testdepend deleted file mode 100644 index 563e7cb65..000000000 --- a/centrallix/.testdepend +++ /dev/null @@ -1,2 +0,0 @@ - -tests/test_00baseline_07.bin: diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 39966e9ce..49cc02bf8 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -2179,6 +2179,10 @@ obj_internal_BuildBinaryItem(char** item, int* itemlen, pExpression exp, pParamO case DATA_T_MONEY: /** XOR 0x8000000000000000 to convert to Offset Zero form. **/ + /** Offset Zero form is a signed number representation where all + ** values below a certain bit (usually most significant) are negative + ** and all values above are positive. It allows sorting based on raw bit value. + ** It essentially functions like 2's complement with the sign bit inversed.**/ ((long long*)tmp_buf)[0] = bswap_64(exp->Types.Money.Value ^ 0x8000000000000000); *item = (char*)(tmp_buf); *itemlen = 8; From 2d70028c411c9d2bdb6eff0cf021b32558c75a2a Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 24 Aug 2020 18:47:09 -0600 Subject: [PATCH 074/129] Handling roudning, code review comments --- centrallix/expression/exp_evaluate.c | 4 ++-- centrallix/objectsystem/obj_datatypes.c | 1 + centrallix/tests/test_moneytype_03.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index e1b5d8bc2..b1022a58b 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -311,8 +311,8 @@ expEvalDivide(pExpression tree, pParamObjects objlist) } md = i0->Types.Money.Value / 10000.0; md = md / i1->Types.Double; - if (md < 0) md -= 0.5; - else md += 0.5; + //if (md < 0) md -= 0.5; + //else md += 0.5; tree->Types.Money.Value = (long long)(md * 10000); //Old Definition /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 49cc02bf8..d2259dfc2 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1486,6 +1486,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) case DATA_T_DOUBLE: dbl = *(double*)data_ptr * 10000.0; + dbl = round(dbl); m->Value = (long long)dbl; break; diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_03.c index f862c0edd..30a948ec5 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_03.c @@ -33,7 +33,7 @@ test(char** name) //Double Fraction Overflow testDouble = 5.159999999999; assert(objDataToMoney(3,&testDouble,&test) == 0); - assert(test.Value == 51599); + assert(test.Value == 51600); /** Int Case **/ int testInt = 6; From bf0ca3d723e4f5b7f70ed5b004d7f3d63f362516 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 26 Aug 2020 16:09:34 -0600 Subject: [PATCH 075/129] Conversion to 64bit MoneyType in /osdrivers --- centrallix/osdrivers/objdrv_dbl.c | 6 ++++-- centrallix/osdrivers/objdrv_fp.c | 8 +++++--- centrallix/osdrivers/objdrv_sybase.c | 30 ++++++++++++++++------------ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/centrallix/osdrivers/objdrv_dbl.c b/centrallix/osdrivers/objdrv_dbl.c index d1c311bf9..6e70e5a92 100755 --- a/centrallix/osdrivers/objdrv_dbl.c +++ b/centrallix/osdrivers/objdrv_dbl.c @@ -1654,13 +1654,15 @@ dbl_internal_ParseColumn(pDblColInf column, pObjData pod, char* data, char* row_ f = 1; for(i=0;iDecimalOffset;i++) f *= 10; pod->Money = (pMoneyType)data; - pod->Money->WholePart = v/f; + pod->Money->Value = (v/f) * 10000; + //pod->Money->WholePart = v/f; v = (v/f)*f; if (column->DecimalOffset <= 4) for(i=column->DecimalOffset;i<4;i++) v *= 10; else for(i=4;iDecimalOffset;i++) v /= 10; - pod->Money->FractionPart = v; + //pod->Money->FractionPart = v; + pod->Money->Value += v; break; default: mssError(1, "DBL", "Bark! Unhandled data type for column '%s'", column->Name); diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 62c1deb11..16c4b63fb 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1227,7 +1227,7 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da case DATA_T_INTEGER: if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; pod->Integer = strtoi(ibuf, NULL, 10); - break; + break case DATA_T_STRING: pod->String = data; if (fp_internal_MappedCopy(data, column->Length+1, column, row_data) < 0) return -1; @@ -1248,13 +1248,15 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da f = 1; for(i=0;iDecimalOffset;i++) f *= 10; pod->Money = (pMoneyType)data; - pod->Money->WholePart = v/f; + pod->Money->Value = (v/f) * 10000; + //pod->Money->WholePart = v/f; v = (v/f)*f; if (column->DecimalOffset <= 4) for(i=column->DecimalOffset;i<4;i++) v *= 10; else for(i=4;iDecimalOffset;i++) v /= 10; - pod->Money->FractionPart = v; + pod->Money->Value += v; + //pod->Money->FractionPart = v; break; default: mssError(1, "FP", "Bark! Unhandled data type for column '%s'", column->Name); diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 50d408797..a8e9304cc 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -775,9 +775,10 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) { /** smallmoney, 4-byte **/ memcpy(&i, ptr, 4); - val->Money->WholePart = i/10000; - if (i < 0 && (i%10000) != 0) val->Money->WholePart--; - val->Money->FractionPart = i - (val->Money->WholePart*10000); + val->Money->Value = i; + //val->Money->WholePart = i/10000; + //if (i < 0 && (i%10000) != 0) val->Money->WholePart--; + //val->Money->FractionPart = i - (val->Money->WholePart*10000); return 0; } else @@ -807,17 +808,20 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) divtmp = msl/10000; n = (n<<16) + divtmp; msl -= divtmp*10000; - val->Money->WholePart = n; - val->Money->FractionPart = msl; + val->Money->Value = (n*10000) + msl; if (minus) - { - val->Money->WholePart = -val->Money->WholePart; - if (val->Money->FractionPart > 0) - { - val->Money->WholePart--; - val->Money->FractionPart = 10000 - val->Money->FractionPart; - } - } + val->Money->Value = -val->Money->Value; + //val->Money->WholePart = n; + //val->Money->FractionPart = msl; + //if (minus) + // { + // val->Money->WholePart = -val->Money->WholePart; + // if (val->Money->FractionPart > 0) + // { + // val->Money->WholePart--; + // val->Money->FractionPart = 10000 - val->Money->FractionPart; + // } + // } return 0; } } From 074005302b40c04edefe7536ad3d9230a9718c6e Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 1 Sep 2020 15:59:14 -0600 Subject: [PATCH 076/129] Remaining miscellaneous conversions to 64 bit moneytype --- centrallix-lib/src/net_raw_api.c | 8 ++++---- centrallix/netdrivers/net_http_rest.c | 8 ++++---- centrallix/utility/json_util.c | 2 ++ centrallix/utility/obfuscate.c | 2 ++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/centrallix-lib/src/net_raw_api.c b/centrallix-lib/src/net_raw_api.c index 87db4ab67..cb138d723 100644 --- a/centrallix-lib/src/net_raw_api.c +++ b/centrallix-lib/src/net_raw_api.c @@ -106,7 +106,7 @@ raw_internal_SkipCmd(pNetManagedConn conn, pNetCmdHeader cmd) case NET_PARAM_REF: len = 4; break; case NET_PARAM_DOUBLE: len = 8; break; case NET_PARAM_DATETIME: len= 5; break; - case NET_PARAM_MONEY: len = 6; break; + case NET_PARAM_MONEY: len = 8; break; case NET_PARAM_NULL: len = 0; break; case NET_PARAM_STRING: rcnt = fdRead(conn->ConnFD, &len, 4, 0, FD_U_PACKET); @@ -192,7 +192,7 @@ rawSendParam(pNetManagedConn conn, char param_type, pObjData value, int cmd_id) break; case NET_PARAM_MONEY: - memcpy(buf+1, value->Money, 6); + memcpy(buf+1, value->Money, 8); len = 7; break; @@ -276,10 +276,10 @@ raw_internal_NextParam(pNetManagedConn conn, char expected_type, char* param_typ value->Money = nmMalloc(sizeof(MoneyType)); if (!value->Money) { - raw_internal_ReadBytes(conn, 6); + raw_internal_ReadBytes(conn, 8); return -1; } - fdRead(conn->ConnFD, value->Money, 6, 0, FD_U_PACKET); + fdRead(conn->ConnFD, value->Money, 8, 0, FD_U_PACKET); break; case NET_PARAM_DATETIME: diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index ae9546dd0..d73589109 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -114,10 +114,10 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty break; case DATA_T_MONEY: - /*Carl nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", - od.Money->WholePart, - od.Money->FractionPart - );*/ + nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", + od.Money->Value/10000, + od.Money->Value%10000 + ); break; default: diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index 0e800f987..a2c9f15c8 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -236,11 +236,13 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) { has_whole = 1; //m->WholePart = json_object_get_int(iter.val); + m->Value += json_object_get_int(iter.val) * 10000; } else if (!strcmp(iter.key, "fractionpart")) { has_fraction = 1; //m->FractionPart = json_object_get_int(iter.val); + m->Value += json_object_get_int(iter.val); } else { diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index 98606dbf0..286724b67 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1201,6 +1201,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname case DATA_T_MONEY: //iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); + iv = srcval->Money->Value/10000 * 100 + (srcval->Money->Value%10000 / 100); if (strchr(param,'i')) dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); else @@ -1211,6 +1212,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname } //m.WholePart = floor(dv/100.0); //m.FractionPart = (dv - m.WholePart*100) * 100; + m.Value = dv * 100; dstval->Money = &m; break; From a0bb05d2b7f4ec9fde8bce2eb7622787f4812cb2 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 3 Sep 2020 15:02:18 -0600 Subject: [PATCH 077/129] obj_internal_BuildBinaryItem Expression initialization and hex comparison --- centrallix/tests/test_moneytype_06.c | 45 ++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/centrallix/tests/test_moneytype_06.c b/centrallix/tests/test_moneytype_06.c index 9df19b1a9..6317ee996 100644 --- a/centrallix/tests/test_moneytype_06.c +++ b/centrallix/tests/test_moneytype_06.c @@ -9,20 +9,53 @@ test(char** name) { *name = "moneytype_06 - obj_internal_BuildBinaryItem"; char** item; + item = (char**)malloc(24); int* itemlen; + itemlen = (int*)malloc(4); + + //Creating an ObjData with a moneytype inside, pObjData for parameters + ObjData moneyData; + MoneyType unionFiller = {70000}; + moneyData.Money = &unionFiller; + pObjData moneyDataPtr = &moneyData; + + //Utilizing expression.h functions to initialize expression and paramobjects pExpression testExp = expAllocExpression(); pParamObjects testParamObjects = expCreateParamList(); + + //Buffer must be at least 12 bytes unsigned char tmpbuf[12]; - /** Positive Case **/ - testExp->Types.Money.Value = 90000; + /** NULL Case **/ assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + /** Positive Case **/ + testExp = expPodToExpression(moneyDataPtr, 7, testExp); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); + + assert(tmpbuf[0] == 0x80); + assert(tmpbuf[1] == 0x0); + assert(tmpbuf[2] == 0x0); + assert(tmpbuf[3] == 0x0); + assert(tmpbuf[4] == 0x0); + assert(tmpbuf[5] == 0x1); + assert(tmpbuf[6] == 0x11); + assert(tmpbuf[7] == 0x70); + /** Negative Case **/ - //test.Value = -70500; - //data_ptr = "Negative Seven And 05/100 "; - //returnStr = objDataToWords(7,&test); - //assert(strcmp(data_ptr, returnStr) == 0); + unionFiller.Value = -70000; + + testExp = expPodToExpression(moneyDataPtr, 7, testExp); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); + + assert(tmpbuf[0] == 0x7f); + assert(tmpbuf[1] == 0xff); + assert(tmpbuf[2] == 0xff); + assert(tmpbuf[3] == 0xff); + assert(tmpbuf[4] == 0xff); + assert(tmpbuf[5] == 0xfe); + assert(tmpbuf[6] == 0xee); + assert(tmpbuf[7] == 0x90); expFreeExpression(testExp); From 8fc1cef138cc9a57f17dcc99550af6cf73b57216 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 3 Sep 2020 18:32:47 -0600 Subject: [PATCH 078/129] Renamed tests to be more specific --- ...est_moneytype_fp_internal_ParseColumn_00.c | 35 +++++++++++++++++++ ...4.c => test_moneytype_objDataCompare_00.c} | 2 +- ....c => test_moneytype_objDataToDouble_00.c} | 2 +- ...c => test_moneytype_objDataToInteger_00.c} | 2 +- ...3.c => test_moneytype_objDataToMoney_00.c} | 2 +- ...5.c => test_moneytype_objDataToWords_00.c} | 2 +- ...neytype_obj_internal_BuildBinaryItem_00.c} | 2 +- ...t_moneytype_obj_internal_FormatMoney_00.c} | 0 8 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c rename centrallix/tests/{test_moneytype_04.c => test_moneytype_objDataCompare_00.c} (98%) rename centrallix/tests/{test_moneytype_02.c => test_moneytype_objDataToDouble_00.c} (91%) rename centrallix/tests/{test_moneytype_01.c => test_moneytype_objDataToInteger_00.c} (95%) rename centrallix/tests/{test_moneytype_03.c => test_moneytype_objDataToMoney_00.c} (96%) rename centrallix/tests/{test_moneytype_05.c => test_moneytype_objDataToWords_00.c} (95%) rename centrallix/tests/{test_moneytype_06.c => test_moneytype_obj_internal_BuildBinaryItem_00.c} (96%) rename centrallix/tests/{test_moneytype_00.c => test_moneytype_obj_internal_FormatMoney_00.c} (100%) diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c new file mode 100644 index 000000000..37b560c5b --- /dev/null +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -0,0 +1,35 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" + +long long +test(char** name) +{ + *name = "moneytype_00 - fp_internal_ParseColumn"; + char** item; + int* itemlen; + pExpression testExp = expAllocExpression(); + pParamObjects testParamObjects = expCreateParamList(); + unsigned char tmpbuf[12]; + + /** NULL Case **/ + assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + + /** Positive Case **/ + testExp->Types.Money.Value = 90000; + testExp->DataType = DATA_T_MONEY; + testExp->NodeType = EXPR_N_MONEY; + + + /** Negative Case **/ + //test.Value = -70500; + //data_ptr = "Negative Seven And 05/100 "; + //returnStr = objDataToWords(7,&test); + //assert(strcmp(data_ptr, returnStr) == 0); + + expFreeExpression(testExp); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_04.c b/centrallix/tests/test_moneytype_objDataCompare_00.c similarity index 98% rename from centrallix/tests/test_moneytype_04.c rename to centrallix/tests/test_moneytype_objDataCompare_00.c index b6d5b9f30..524c74a44 100644 --- a/centrallix/tests/test_moneytype_04.c +++ b/centrallix/tests/test_moneytype_objDataCompare_00.c @@ -6,7 +6,7 @@ long long test(char** name) { - *name = "moneytype_04 - objDataCompare"; + *name = "moneytype_00 - objDataCompare"; MoneyType test = {70000}; /** Compare Int with Money Case **/ diff --git a/centrallix/tests/test_moneytype_02.c b/centrallix/tests/test_moneytype_objDataToDouble_00.c similarity index 91% rename from centrallix/tests/test_moneytype_02.c rename to centrallix/tests/test_moneytype_objDataToDouble_00.c index d2dfd1e97..6b86ea384 100644 --- a/centrallix/tests/test_moneytype_02.c +++ b/centrallix/tests/test_moneytype_objDataToDouble_00.c @@ -4,7 +4,7 @@ long long test(char** name) { - *name = "moneytype_02 - objDataToDouble"; + *name = "moneytype_00 - objDataToDouble"; /** Zero Case **/ MoneyType test = {0}; diff --git a/centrallix/tests/test_moneytype_01.c b/centrallix/tests/test_moneytype_objDataToInteger_00.c similarity index 95% rename from centrallix/tests/test_moneytype_01.c rename to centrallix/tests/test_moneytype_objDataToInteger_00.c index b66efe70d..9dc71ec01 100644 --- a/centrallix/tests/test_moneytype_01.c +++ b/centrallix/tests/test_moneytype_objDataToInteger_00.c @@ -8,7 +8,7 @@ long long test(char** name) { - *name = "moneytype_01 - objDataToInteger"; + *name = "moneytype_00 - objDataToInteger"; /** Zero Case **/ MoneyType test = {0}; diff --git a/centrallix/tests/test_moneytype_03.c b/centrallix/tests/test_moneytype_objDataToMoney_00.c similarity index 96% rename from centrallix/tests/test_moneytype_03.c rename to centrallix/tests/test_moneytype_objDataToMoney_00.c index 30a948ec5..8a2f0c031 100644 --- a/centrallix/tests/test_moneytype_03.c +++ b/centrallix/tests/test_moneytype_objDataToMoney_00.c @@ -5,7 +5,7 @@ long long test(char** name) { - *name = "moneytype_03 - objDataToMoney"; + *name = "moneytype_00 - objDataToMoney"; MoneyType test = {0}; /** String Case **/ diff --git a/centrallix/tests/test_moneytype_05.c b/centrallix/tests/test_moneytype_objDataToWords_00.c similarity index 95% rename from centrallix/tests/test_moneytype_05.c rename to centrallix/tests/test_moneytype_objDataToWords_00.c index b9caac0cb..9722b6ec1 100644 --- a/centrallix/tests/test_moneytype_05.c +++ b/centrallix/tests/test_moneytype_objDataToWords_00.c @@ -7,7 +7,7 @@ long long test(char** name) { - *name = "moneytype_05 - objDataToWords"; + *name = "moneytype_00 - objDataToWords"; MoneyType test = {70500}; /** Positive Case **/ diff --git a/centrallix/tests/test_moneytype_06.c b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c similarity index 96% rename from centrallix/tests/test_moneytype_06.c rename to centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c index 6317ee996..15641f10a 100644 --- a/centrallix/tests/test_moneytype_06.c +++ b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c @@ -7,7 +7,7 @@ long long test(char** name) { - *name = "moneytype_06 - obj_internal_BuildBinaryItem"; + *name = "moneytype_00 - obj_internal_BuildBinaryItem"; char** item; item = (char**)malloc(24); int* itemlen; diff --git a/centrallix/tests/test_moneytype_00.c b/centrallix/tests/test_moneytype_obj_internal_FormatMoney_00.c similarity index 100% rename from centrallix/tests/test_moneytype_00.c rename to centrallix/tests/test_moneytype_obj_internal_FormatMoney_00.c From a94c668dbe688585de0ef5c5b4e95a5b6a74c243 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 8 Sep 2020 16:56:42 -0600 Subject: [PATCH 079/129] Resolving Code Review comments and Expression Testing --- centrallix-lib/src/net_raw_api.c | 2 +- centrallix/expression/exp_evaluate.c | 3 +-- centrallix/osdrivers/objdrv_fp.c | 2 +- .../tests/test_moneytype_fp_internal_ParseColumn_00.c | 6 ++++++ centrallix/utility/json_util.c | 1 + 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/centrallix-lib/src/net_raw_api.c b/centrallix-lib/src/net_raw_api.c index cb138d723..aac822aee 100644 --- a/centrallix-lib/src/net_raw_api.c +++ b/centrallix-lib/src/net_raw_api.c @@ -193,7 +193,7 @@ rawSendParam(pNetManagedConn conn, char param_type, pObjData value, int cmd_id) case NET_PARAM_MONEY: memcpy(buf+1, value->Money, 8); - len = 7; + len = 9; break; case NET_PARAM_NULL: diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index b1022a58b..e66628f07 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -423,8 +423,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) break; case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - //mv = ((long long)(i1->Types.Money.WholePart)) * 10000 + i1->Types.Money.FractionPart; - //mv *= i0->Integer; + mv = i1->Types.Money.Value * i0->Integer; break; case DATA_T_STRING: tree->DataType = DATA_T_STRING; diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 16c4b63fb..9b54ed69d 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1227,7 +1227,7 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da case DATA_T_INTEGER: if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; pod->Integer = strtoi(ibuf, NULL, 10); - break + break; case DATA_T_STRING: pod->String = data; if (fp_internal_MappedCopy(data, column->Length+1, column, row_data) < 0) return -1; diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index 37b560c5b..b3f626a42 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -8,6 +8,12 @@ long long test(char** name) { *name = "moneytype_00 - fp_internal_ParseColumn"; + + FpColInf testColInf = {0}; + pFpColInf testColInfPtr = &FpColInf; + + + char** item; int* itemlen; pExpression testExp = expAllocExpression(); diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index a2c9f15c8..f1c0120f0 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -228,6 +228,7 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) /** Search the object's properties **/ memset(m, 0, sizeof(MoneyType)); + m->Value = 0; json_object_object_foreachC(jobj, iter) { if (json_object_is_type(iter.val, json_type_int)) From 908729dbef56e4cc02a79c6dc66594ed186623f7 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 22 Sep 2020 23:22:40 -0600 Subject: [PATCH 080/129] Initial setup for ParseColumn; Creation of Obfuscate Test --- ...est_moneytype_fp_internal_ParseColumn_00.c | 25 +++++++++++-------- .../tests/test_moneytype_obfuscate_00.c | 16 ++++++++++++ ...oneytype_obj_internal_BuildBinaryItem_00.c | 12 ++++----- centrallix/utility/obfuscate.c | 3 --- 4 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 centrallix/tests/test_moneytype_obfuscate_00.c diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index b3f626a42..611ab9988 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -3,25 +3,32 @@ #include #include "expression.h" #include "cxlib/xstring.h" +#include "osdrivers/objdrv_fp.c" long long test(char** name) { *name = "moneytype_00 - fp_internal_ParseColumn"; - FpColInf testColInf = {0}; - pFpColInf testColInfPtr = &FpColInf; + //FpColInf testColInf = {0}; + pFpColInf = &FpColInf; + //7 for money type + FpColInf.Type = 7; + FpColInf.Length = 8; + FpColInf.RecordOffset = 0; + FpColInf.DecimalOffset = 4; + ObjData moneyData; + pObjData moneyDataPtr = &moneyData; + MoneyType testMoneyData = {0}; + pMoneyType pTestMoneyData = &testMoneyData; + //Raw data for row data. + char* testString = "450"; - char** item; - int* itemlen; - pExpression testExp = expAllocExpression(); - pParamObjects testParamObjects = expCreateParamList(); - unsigned char tmpbuf[12]; + assert(fp_internal_ParseColumn(pFpColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); /** NULL Case **/ - assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); /** Positive Case **/ testExp->Types.Money.Value = 90000; @@ -35,7 +42,5 @@ test(char** name) //returnStr = objDataToWords(7,&test); //assert(strcmp(data_ptr, returnStr) == 0); - expFreeExpression(testExp); - return 0; } diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c new file mode 100644 index 000000000..a34d1c934 --- /dev/null +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -0,0 +1,16 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" +#include "utility/obfuscate.c" + +long long +test(char** name) +{ + *name = "moneytype_00 - obfuscate"; + + obfObfuscateData(); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c index 15641f10a..0b854d39d 100644 --- a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c +++ b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c @@ -13,12 +13,6 @@ test(char** name) int* itemlen; itemlen = (int*)malloc(4); - //Creating an ObjData with a moneytype inside, pObjData for parameters - ObjData moneyData; - MoneyType unionFiller = {70000}; - moneyData.Money = &unionFiller; - pObjData moneyDataPtr = &moneyData; - //Utilizing expression.h functions to initialize expression and paramobjects pExpression testExp = expAllocExpression(); pParamObjects testParamObjects = expCreateParamList(); @@ -29,6 +23,12 @@ test(char** name) /** NULL Case **/ assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); + //For remaining cases, creating an ObjData with a moneytype inside, pObjData for parameters + ObjData moneyData; + MoneyType unionFiller = {70000}; + moneyData.Money = &unionFiller; + pObjData moneyDataPtr = &moneyData; + /** Positive Case **/ testExp = expPodToExpression(moneyDataPtr, 7, testExp); assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index 286724b67..2ee98ab80 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1200,7 +1200,6 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname break; case DATA_T_MONEY: - //iv = srcval->Money->WholePart * 100 + (srcval->Money->FractionPart / 100); iv = srcval->Money->Value/10000 * 100 + (srcval->Money->Value%10000 / 100); if (strchr(param,'i')) dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); @@ -1210,8 +1209,6 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = iv/10 + 1; dv = obf_internal_ObfuscateInteger(hash, hash_novalue, &bitcnt, iv); } - //m.WholePart = floor(dv/100.0); - //m.FractionPart = (dv - m.WholePart*100) * 100; m.Value = dv * 100; dstval->Money = &m; break; From 9ef21dd1e00bfe287c2e01001a2f85823fd8d837 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 28 Sep 2020 23:38:44 -0600 Subject: [PATCH 081/129] Working fp_internal_ParseColumn function and testing for 64bit MoneyType --- centrallix/osdrivers/objdrv_fp.c | 18 +++---- ...est_moneytype_fp_internal_ParseColumn_00.c | 48 ++++++++++--------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 9b54ed69d..86816031d 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1221,6 +1221,7 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da char dtbuf[32]; unsigned long long v; int i,f; + double decimalOffsetValue = 10000; switch(column->Type) { @@ -1243,20 +1244,15 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da if (column->DecimalOffset) pod->Double /= pow(10, column->DecimalOffset); break; case DATA_T_MONEY: + //decimalOffsetValue is originally 10000 to convert v to 10000ths of a dollar + //decimalOffsetValue is divided by 10, column->DecimalOffset times, + //keeping the decimal as a double in case it drops below 0 + //Finally, I multiple v by decimalOffsetValue to get my Money->Value if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; v = strtoll(ibuf, NULL, 10); - f = 1; - for(i=0;iDecimalOffset;i++) f *= 10; + for (i=0; iDecimalOffset; i++) decimalOffsetValue /= 10.0; pod->Money = (pMoneyType)data; - pod->Money->Value = (v/f) * 10000; - //pod->Money->WholePart = v/f; - v = (v/f)*f; - if (column->DecimalOffset <= 4) - for(i=column->DecimalOffset;i<4;i++) v *= 10; - else - for(i=4;iDecimalOffset;i++) v /= 10; - pod->Money->Value += v; - //pod->Money->FractionPart = v; + pod->Money->Value = v*decimalOffsetValue; break; default: mssError(1, "FP", "Bark! Unhandled data type for column '%s'", column->Name); diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index 611ab9988..cc1b671ec 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -10,37 +10,41 @@ test(char** name) { *name = "moneytype_00 - fp_internal_ParseColumn"; - //FpColInf testColInf = {0}; - pFpColInf = &FpColInf; + //This Test is making the assumption that the raw data passed in testString here (row_data in objdrv_fp.c) + //is in units dollars. So, the function now converts it to 1/10000ths like the new moneyType requires. + + FpColInf testColInf = {0}; + pFpColInf pTestColInf = &testColInf; //7 for money type - FpColInf.Type = 7; - FpColInf.Length = 8; - FpColInf.RecordOffset = 0; - FpColInf.DecimalOffset = 4; + testColInf.Type = 7; + testColInf.Length = 8; + testColInf.RecordOffset = 0; + testColInf.DecimalOffset = 0; ObjData moneyData; pObjData moneyDataPtr = &moneyData; MoneyType testMoneyData = {0}; pMoneyType pTestMoneyData = &testMoneyData; - + + /** No Decimal Offset Case **/ //Raw data for row data. char* testString = "450"; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); - assert(fp_internal_ParseColumn(pFpColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); - - /** NULL Case **/ - - /** Positive Case **/ - testExp->Types.Money.Value = 90000; - testExp->DataType = DATA_T_MONEY; - testExp->NodeType = EXPR_N_MONEY; - - - /** Negative Case **/ - //test.Value = -70500; - //data_ptr = "Negative Seven And 05/100 "; - //returnStr = objDataToWords(7,&test); - //assert(strcmp(data_ptr, returnStr) == 0); + assert(moneyDataPtr->Money->Value == 4500000); + /** Decimal Offset, Value > 1 Case **/ + //Value will be greater than one after dividing by + //10 a DecimalOffset # of times + testColInf.DecimalOffset = 1; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); + assert(moneyDataPtr->Money->Value == 450000); + + /** Decimal Offset, Value < 1 Case **/ + testColInf.DecimalOffset = 3; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); + assert(moneyDataPtr->Money->Value == 4500); + + return 0; } From 9f7c9464a010abffcde38323f7c9cd50c1804e9e Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 9 Dec 2020 18:53:36 -0700 Subject: [PATCH 082/129] Added ll const tag to literals. Removed old comments in json_util.c. --- centrallix/expression/exp_evaluate.c | 6 +++--- centrallix/objectsystem/obj_datatypes.c | 4 ++-- centrallix/utility/json_util.c | 4 +--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index e66628f07..18a45435b 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -629,7 +629,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; /** Since Value is in 1/10000 of a dollar, integer must be multiplied to scale **/ - tree->Types.Money.Value = i0->Types.Money.Value - (i1->Integer * 10000); + tree->Types.Money.Value = i0->Types.Money.Value - (i1->Integer * 10000ll); break; case DATA_T_DOUBLE: tree->DataType = DATA_T_DOUBLE; @@ -772,7 +772,7 @@ expEvalPlus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; /** Int must be converted to 1/10000 of a dollar **/ - tree->Types.Money.Value = i1->Types.Money.Value + (i0->Integer * 10000); + tree->Types.Money.Value = i1->Types.Money.Value + (i0->Integer * 10000ll); break; default: @@ -1457,7 +1457,7 @@ expRevEvalProperty(pExpression tree, pParamObjects objlist) } else if (tree->DataType == DATA_T_INTEGER && attr_type == DATA_T_MONEY) { - tree->Types.Money.Value = (tree->Integer * 10000); + tree->Types.Money.Value = (tree->Integer * 10000ll); } else if (tree->DataType == DATA_T_DOUBLE && attr_type == DATA_T_MONEY) { diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index d2259dfc2..b4424a181 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1450,9 +1450,9 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) if ((endptr - ptr) != strspn(ptr, "0123456789")) return -1; if (is_neg) - m->Value = -intval*10000; + m->Value = -intval*10000ll; else - m->Value = intval*10000; + m->Value = intval*10000ll; /** Handling the "fraction" portion after the decimal point **/ if (*endptr == (intl_format?',':'.')) diff --git a/centrallix/utility/json_util.c b/centrallix/utility/json_util.c index f1c0120f0..eb1400d48 100644 --- a/centrallix/utility/json_util.c +++ b/centrallix/utility/json_util.c @@ -236,13 +236,11 @@ jutilGetMoneyObject(struct json_object* jobj, pMoneyType m) if (!strcmp(iter.key, "wholepart")) { has_whole = 1; - //m->WholePart = json_object_get_int(iter.val); - m->Value += json_object_get_int(iter.val) * 10000; + m->Value += json_object_get_int(iter.val) * 10000ll; } else if (!strcmp(iter.key, "fractionpart")) { has_fraction = 1; - //m->FractionPart = json_object_get_int(iter.val); m->Value += json_object_get_int(iter.val); } else From 1b37e5071315364f52b87cee41b5a9883daf29ed Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 9 Dec 2020 19:19:16 -0700 Subject: [PATCH 083/129] Added ll const tag to literals. Cleaned up math and comparisons --- centrallix/expression/exp_compiler.c | 2 +- centrallix/expression/exp_evaluate.c | 38 ++----------------------- centrallix/objectsystem/obj_datatypes.c | 8 +++--- centrallix/osdrivers/objdrv_sybase.c | 2 +- 4 files changed, 8 insertions(+), 42 deletions(-) diff --git a/centrallix/expression/exp_compiler.c b/centrallix/expression/exp_compiler.c index d47bea653..28a6f48f2 100644 --- a/centrallix/expression/exp_compiler.c +++ b/centrallix/expression/exp_compiler.c @@ -152,7 +152,7 @@ exp_internal_CompileExpression_r(pLxSession lxs, int level, pParamObjects objlis if (t == MLX_TOK_INTEGER) { i = mlxIntVal(lxs); - etmp->Types.Money.Value = (i * 10000); + etmp->Types.Money.Value = (i * 10000ll); } else { diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index 18a45435b..c216b27f4 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -191,7 +191,6 @@ expEvalDivide(pExpression tree, pParamObjects objlist) pExpression i0,i1; MoneyType m; int i; - int is_negative = 0; long long mv, mv2; double md; @@ -280,27 +279,12 @@ expEvalDivide(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; memcpy(&m, &(i0->Types.Money), sizeof(MoneyType)); - if (m.Value < 0) - { - is_negative = !is_negative; - m.Value = -m.Value; - } - i = i1->Integer; - if (i < 0) - { - i = -i; - is_negative = !is_negative; - } if (i == 0) { mssError(1,"EXP","Attempted divide by zero"); return -1; } tree->Types.Money.Value = m.Value / i; - if (is_negative) - { - tree->Types.Money.Value = -tree->Types.Money.Value; - } break; case DATA_T_DOUBLE: tree->DataType = DATA_T_MONEY; @@ -309,25 +293,7 @@ expEvalDivide(pExpression tree, pParamObjects objlist) mssError(1,"EXP","Attempted divide by zero"); return -1; } - md = i0->Types.Money.Value / 10000.0; - md = md / i1->Types.Double; - //if (md < 0) md -= 0.5; - //else md += 0.5; - tree->Types.Money.Value = (long long)(md * 10000); - //Old Definition - /*mv = ((long long)(i0->Types.Money.WholePart)) * 10000 + i0->Types.Money.FractionPart; - md = mv / i1->Types.Double; - if (md < 0) md -= 0.5; - else md += 0.5; - mv = md; - tree->Types.Money.WholePart = mv/10000; - mv = mv % 10000; - if (mv < 0) - { - mv += 10000; - tree->Types.Money.WholePart -= 1; - } - tree->Types.Money.FractionPart = mv;*/ + tree->Types.Money.Value = (long long)(i0->Types.Money.Value/i1->Types.Double); break; case DATA_T_MONEY: mv = i0->Types.Money.Value; @@ -593,7 +559,7 @@ expEvalMinus(pExpression tree, pParamObjects objlist) case DATA_T_MONEY: /** Treat Int as a dollar value **/ tree->DataType = DATA_T_MONEY; - tree->Types.Money.Value = (i0->Integer * 10000) - i1->Types.Money.Value; + tree->Types.Money.Value = (i0->Integer * 10000ll) - i1->Types.Money.Value; break; default: tree->Integer = i0->Integer - objDataToInteger(i1->DataType, dptr, NULL); diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index b4424a181..85b90e15a 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1491,7 +1491,7 @@ objDataToMoney(int data_type, void* data_ptr, pMoneyType m) break; case DATA_T_INTEGER: - m->Value = *(int*)data_ptr * 10000; + m->Value = *(int*)data_ptr * 10000ll; break; case DATA_T_MONEY: @@ -1576,9 +1576,9 @@ objDataCompare(int data_type_1, void* data_ptr_1, int data_type_2, void* data_pt case DATA_T_MONEY: m = (pMoneyType)data_ptr_2; - if (m->Value/10000 > intval) cmp_value = -1; - else if (m->Value/10000 < intval) cmp_value = 1; - else cmp_value = m->Value%10000?-1:0; + if (m->Value > intval*10000ll) cmp_value = -1; + else if (m->Value < intval*10000ll) cmp_value = 1; + else cmp_value = 0; break; case DATA_T_INTVEC: diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index a8e9304cc..dde7be337 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -808,7 +808,7 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) divtmp = msl/10000; n = (n<<16) + divtmp; msl -= divtmp*10000; - val->Money->Value = (n*10000) + msl; + val->Money->Value = (n*10000ll) + msl; if (minus) val->Money->Value = -val->Money->Value; //val->Money->WholePart = n; From 9c9f8db3b53a584450b11f34171ca79ff69869a5 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 10 Dec 2020 18:14:52 -0700 Subject: [PATCH 084/129] Resolving code review comments. Comments for obj, and comparison for BuildBinaryItem --- centrallix/objectsystem/obj_datatypes.c | 4 +- ...oneytype_obj_internal_BuildBinaryItem_00.c | 43 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 85b90e15a..8dc39db0c 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -802,8 +802,8 @@ objDataToInteger(int data_type, void* data_ptr, char* format) case DATA_T_MONEY: m = (pMoneyType)data_ptr; - if (m->Value/10000 > INT_MAX) - mssError(1, "OBJ", "Warning: %d overflow; cannot fit value of that size in int ", data_type); + if (m->Value/10000 > INT_MAX || m->Value/10000 < INT_MIN) + mssError(1, "OBJ", "Warning: %d (MoneyType) overflow; cannot fit value of that size in int", data_type); else v = m->Value/10000; break; diff --git a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c index 0b854d39d..676de1281 100644 --- a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c +++ b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c @@ -15,49 +15,50 @@ test(char** name) //Utilizing expression.h functions to initialize expression and paramobjects pExpression testExp = expAllocExpression(); + pExpression testExpCmp = expAllocExpression(); pParamObjects testParamObjects = expCreateParamList(); - //Buffer must be at least 12 bytes + //Buffer must be at least 12 bytes for data types not yet implemented. + //Current highest byte size is 9, but 12 may come later unsigned char tmpbuf[12]; + unsigned char cmpbuf[12]; /** NULL Case **/ assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); - //For remaining cases, creating an ObjData with a moneytype inside, pObjData for parameters + //For remaining cases, creating two ObjData with a moneytype inside, pObjData for parameters + //After passing through BuildBinaryItem, they will be compared with memcmp() because it is not the binary value + //itself that matters, but the comparison between the two objects. ObjData moneyData; MoneyType unionFiller = {70000}; moneyData.Money = &unionFiller; pObjData moneyDataPtr = &moneyData; + + ObjData moneyDataCmp; + MoneyType unionFiller2 = {65000}; + moneyDataCmp.Money = &unionFiller2; + pObjData moneyDataPtrCmp = &moneyDataCmp; /** Positive Case **/ testExp = expPodToExpression(moneyDataPtr, 7, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExpCmp, testParamObjects, cmpbuf) == 0); - assert(tmpbuf[0] == 0x80); - assert(tmpbuf[1] == 0x0); - assert(tmpbuf[2] == 0x0); - assert(tmpbuf[3] == 0x0); - assert(tmpbuf[4] == 0x0); - assert(tmpbuf[5] == 0x1); - assert(tmpbuf[6] == 0x11); - assert(tmpbuf[7] == 0x70); + assert(memcmp(tmpbuf,cmpbuf,8) > 0); /** Negative Case **/ unionFiller.Value = -70000; - + unionFiller2.Value = -65000; testExp = expPodToExpression(moneyDataPtr, 7, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); - - assert(tmpbuf[0] == 0x7f); - assert(tmpbuf[1] == 0xff); - assert(tmpbuf[2] == 0xff); - assert(tmpbuf[3] == 0xff); - assert(tmpbuf[4] == 0xff); - assert(tmpbuf[5] == 0xfe); - assert(tmpbuf[6] == 0xee); - assert(tmpbuf[7] == 0x90); + assert(obj_internal_BuildBinaryItem(item, itemlen, testExpCmp, testParamObjects, cmpbuf) == 0); + + assert(memcmp(tmpbuf,cmpbuf,8) < 0); expFreeExpression(testExp); - + expFreeExpression(testExpCmp); + return 0; } From afc313a16d0bf585cb022c9bbc1a86335929ee80 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 10 Dec 2020 18:18:57 -0700 Subject: [PATCH 085/129] Updated QPrintf documentation. Added %LL specifier and shifted IDs for QPrintf. Attempted adding a case for %LL --- centrallix-lib/src/qprintf.c | 97 +++++++++++++++++++---------------- centrallix-sysdoc/QPrintf.txt | 3 ++ 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/centrallix-lib/src/qprintf.c b/centrallix-lib/src/qprintf.c index a377157d3..2490b7699 100644 --- a/centrallix-lib/src/qprintf.c +++ b/centrallix-lib/src/qprintf.c @@ -59,46 +59,47 @@ #define QPF_SPEC_T_NSTR (5) #define QPF_SPEC_T_CHR (6) #define QPF_SPEC_T_ENDSRC (6) +#define QPF_SPEC_T_LL (7) /*** builtin filtering specifiers ***/ -#define QPF_SPEC_T_STARTFILT (7) -#define QPF_SPEC_T_QUOT (7) -#define QPF_SPEC_T_DQUOT (8) -#define QPF_SPEC_T_SYM (9) -#define QPF_SPEC_T_JSSTR (10) -#define QPF_SPEC_T_NLEN (11) -#define QPF_SPEC_T_WS (12) -#define QPF_SPEC_T_ESCWS (13) -#define QPF_SPEC_T_ESCSP (14) -#define QPF_SPEC_T_UNESC (15) -#define QPF_SPEC_T_SSYB (16) -#define QPF_SPEC_T_DSYB (17) -#define QPF_SPEC_T_FILE (18) -#define QPF_SPEC_T_PATH (19) -#define QPF_SPEC_T_HEX (20) -#define QPF_SPEC_T_DHEX (21) -#define QPF_SPEC_T_B64 (22) -#define QPF_SPEC_T_DB64 (23) -#define QPF_SPEC_T_RF (24) -#define QPF_SPEC_T_RR (25) -#define QPF_SPEC_T_HTENLBR (26) -#define QPF_SPEC_T_DHTE (27) -#define QPF_SPEC_T_URL (28) -#define QPF_SPEC_T_DURL (29) -#define QPF_SPEC_T_NLSET (30) -#define QPF_SPEC_T_NRSET (31) -#define QPF_SPEC_T_NZRSET (32) -#define QPF_SPEC_T_SQLARG (33) -#define QPF_SPEC_T_SQLSYM (34) -#define QPF_SPEC_T_HTDATA (35) -#define QPF_SPEC_T_HTE (36) -#define QPF_SPEC_T_ESCQWS (37) -#define QPF_SPEC_T_ESCQ (38) -#define QPF_SPEC_T_CSSVAL (39) -#define QPF_SPEC_T_CSSURL (40) -#define QPF_SPEC_T_JSONSTR (41) -#define QPF_SPEC_T_ENDFILT (41) -#define QPF_SPEC_T_MAXSPEC (41) +#define QPF_SPEC_T_STARTFILT (8) +#define QPF_SPEC_T_QUOT (8) +#define QPF_SPEC_T_DQUOT (9) +#define QPF_SPEC_T_SYM (10) +#define QPF_SPEC_T_JSSTR (11) +#define QPF_SPEC_T_NLEN (12) +#define QPF_SPEC_T_WS (13) +#define QPF_SPEC_T_ESCWS (14) +#define QPF_SPEC_T_ESCSP (15) +#define QPF_SPEC_T_UNESC (16) +#define QPF_SPEC_T_SSYB (17) +#define QPF_SPEC_T_DSYB (18) +#define QPF_SPEC_T_FILE (19) +#define QPF_SPEC_T_PATH (20) +#define QPF_SPEC_T_HEX (21) +#define QPF_SPEC_T_DHEX (22) +#define QPF_SPEC_T_B64 (23) +#define QPF_SPEC_T_DB64 (24) +#define QPF_SPEC_T_RF (25) +#define QPF_SPEC_T_RR (26) +#define QPF_SPEC_T_HTENLBR (27) +#define QPF_SPEC_T_DHTE (28) +#define QPF_SPEC_T_URL (29) +#define QPF_SPEC_T_DURL (30) +#define QPF_SPEC_T_NLSET (31) +#define QPF_SPEC_T_NRSET (32) +#define QPF_SPEC_T_NZRSET (33) +#define QPF_SPEC_T_SQLARG (34) +#define QPF_SPEC_T_SQLSYM (35) +#define QPF_SPEC_T_HTDATA (36) +#define QPF_SPEC_T_HTE (37) +#define QPF_SPEC_T_ESCQWS (38) +#define QPF_SPEC_T_ESCQ (39) +#define QPF_SPEC_T_CSSVAL (40) +#define QPF_SPEC_T_CSSURL (41) +#define QPF_SPEC_T_JSONSTR (42) +#define QPF_SPEC_T_ENDFILT (42) +#define QPF_SPEC_T_MAXSPEC (42) /** Names for specifiers as used in format string - must match the above. **/ const char* @@ -111,6 +112,7 @@ qpf_spec_names[] = "DBL", "nSTR", "CHR", + "LL", "QUOT", "DQUOT", "SYM", @@ -139,13 +141,13 @@ qpf_spec_names[] = "nZRSET", "SQLARG", "SQLSYM", - "HTDATA", /* 35 */ + "HTDATA", /* 36 */ "HTE", - "ESCQWS", /* 37 */ - "ESCQ", /* 38 */ - "CSSVAL", /* 39 */ - "CSSURL", /* 40 */ - "JSONSTR", /* 41 */ + "ESCQWS", /* 38 */ + "ESCQ", /* 39 */ + "CSSVAL", /* 40 */ + "CSSURL", /* 41 */ + "JSONSTR", /* 42 */ NULL }; @@ -754,6 +756,7 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow int n; int found; int intval; + long long llval; const char* strval; double dblval; char tmpbuf[64]; @@ -970,6 +973,12 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow strval = tmpbuf; break; + case QPF_SPEC_T_LL: + llval = va_arg(ap, long long); + cplen = snprintf(tmpbuf, sizeof(tmpbuf), "%lld", llval); + strval = tmpbuf; + break; + case QPF_SPEC_T_DBL: dblval = va_arg(ap, double); cplen = snprintf(tmpbuf, sizeof(tmpbuf), "%lf", dblval); diff --git a/centrallix-sysdoc/QPrintf.txt b/centrallix-sysdoc/QPrintf.txt index ac6714381..2f08fa59f 100644 --- a/centrallix-sysdoc/QPrintf.txt +++ b/centrallix-sysdoc/QPrintf.txt @@ -66,6 +66,9 @@ FORMATTING... %INT An integer value, with range of the normal 'int' value in the C language. Can be positive, negative, or zero. + + %LL A 64-bit integer value, with range of 'long long' value + in the C language. Can be positive, negative, or zero. %POS A non-negative integer value (zero allowed). From 34e5c46609c8f287a02945bd912cca1ac3faf6aa Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 14 Dec 2020 10:36:20 -0700 Subject: [PATCH 086/129] Cleaning up test suite items. Showed truncation in fp test. --- .../tests/test_moneytype_fp_internal_ParseColumn_00.c | 8 +++++++- centrallix/tests/test_moneytype_obfuscate_00.c | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index cc1b671ec..7e7a1ffb3 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -45,6 +45,12 @@ test(char** name) assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); assert(moneyDataPtr->Money->Value == 4500); - + //This function truncates answers + char* testRoundedString = "45011999"; + testColInf.DecimalOffset = 5; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testRoundedString) == 0); + assert(moneyDataPtr->Money->Value == 4501199); + + return 0; } diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c index a34d1c934..7054a57b5 100644 --- a/centrallix/tests/test_moneytype_obfuscate_00.c +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -3,14 +3,14 @@ #include #include "expression.h" #include "cxlib/xstring.h" -#include "utility/obfuscate.c" +//#include "utility/obfuscate.c" long long test(char** name) { *name = "moneytype_00 - obfuscate"; - obfObfuscateData(); + //obfObfuscateData(); return 0; } From 92c7c9abf4814ee112470369934654ecf52483af Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Mon, 14 Dec 2020 17:03:16 -0700 Subject: [PATCH 087/129] Updated qprintf sysdoc to contain %LL. Creation of test for %LL, not yet fully functional --- centrallix-lib/tests/test_qprintf_64.c | 51 ++++++++++++++++++++++++++ centrallix-sysdoc/QPrintf.txt | 1 + 2 files changed, 52 insertions(+) create mode 100644 centrallix-lib/tests/test_qprintf_64.c diff --git a/centrallix-lib/tests/test_qprintf_64.c b/centrallix-lib/tests/test_qprintf_64.c new file mode 100644 index 000000000..44ec2c333 --- /dev/null +++ b/centrallix-lib/tests/test_qprintf_64.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include "qprintf.h" +#include + +long long +test(char** tname) +{ + int i, rval; + int iter; + unsigned char buf[44]; + + *tname = "qprintf-64 %LL insertion in middle without overflow"; + iter = 200000; + for(i=0;i Date: Wed, 16 Dec 2020 11:39:17 -0700 Subject: [PATCH 088/129] First sybase simplification attempt. Fixing endianness by shifting and using bitwise OR. --- centrallix/osdrivers/objdrv_sybase.c | 35 ++++++++-------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index dde7be337..de3f7a88c 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -686,6 +686,7 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) { int i,minus,n; unsigned int msl,lsl,divtmp; + long long ll_msl, ll_lsl; unsigned int days,fsec; float f; @@ -796,32 +797,16 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) if (lsl == 0xFFFFFFFF) msl++; lsl++; } - /** Long division, 16 bits = 1 "digit" **/ - divtmp = msl/10000; - n = divtmp; - msl -= divtmp*10000; - msl = (msl<<16) + (lsl>>16); - divtmp = msl/10000; - n = (n<<16) + divtmp; - msl -= divtmp*10000; - msl = (msl<<16) + (lsl & 0xFFFF); - divtmp = msl/10000; - n = (n<<16) + divtmp; - msl -= divtmp*10000; - val->Money->Value = (n*10000ll) + msl; + /** Both msl and lsl are little endian, so I want lsl to come before msl. + ** I do this by shifting lsl left in a long long (ll_lsl) by 32 bits, and then OR it with msl + **/ + ll_msl = msl; + ll_lsl = lsl; + ll_lsl = ll_lsl << 32; + ll_lsl = ll_lsl | ll_msl; + val->Money->Value = lsll; if (minus) - val->Money->Value = -val->Money->Value; - //val->Money->WholePart = n; - //val->Money->FractionPart = msl; - //if (minus) - // { - // val->Money->WholePart = -val->Money->WholePart; - // if (val->Money->FractionPart > 0) - // { - // val->Money->WholePart--; - // val->Money->FractionPart = 10000 - val->Money->FractionPart; - // } - // } + val->Money->Value = -val->Money->Value; return 0; } } From b8f338e15f5b5b0f0741f2126573b761f4638863 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Thu, 17 Dec 2020 10:50:13 -0700 Subject: [PATCH 089/129] Fixing Expression Testing, fixed division and internal format. Proper assigment for Sybase. --- centrallix/expression/exp_evaluate.c | 4 ++-- centrallix/objectsystem/obj_datatypes.c | 2 +- centrallix/osdrivers/objdrv_sybase.c | 2 +- centrallix/tests/test_moneytype_objDataToMoney_00.c | 4 ++++ centrallix/tests/test_sample_money_00.cmp | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index c216b27f4..8aad7fe86 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -279,12 +279,12 @@ expEvalDivide(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: tree->DataType = DATA_T_MONEY; memcpy(&m, &(i0->Types.Money), sizeof(MoneyType)); - if (i == 0) + if (i1->Integer == 0) { mssError(1,"EXP","Attempted divide by zero"); return -1; } - tree->Types.Money.Value = m.Value / i; + tree->Types.Money.Value = (long long)(m.Value / i1->Integer); break; case DATA_T_DOUBLE: tree->DataType = DATA_T_MONEY; diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 8dc39db0c..7ceecbaba 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -509,7 +509,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) if (automatic_sign) { automatic_sign = 0; - if (orig_print_whole < 0) + if (m->Value < 0) *(str++) = '-'; /*else *(str++) = ' ';*/ diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index de3f7a88c..d5dbe173b 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -804,7 +804,7 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) ll_lsl = lsl; ll_lsl = ll_lsl << 32; ll_lsl = ll_lsl | ll_msl; - val->Money->Value = lsll; + val->Money->Value = ll_lsll; if (minus) val->Money->Value = -val->Money->Value; return 0; diff --git a/centrallix/tests/test_moneytype_objDataToMoney_00.c b/centrallix/tests/test_moneytype_objDataToMoney_00.c index 8a2f0c031..f46e42f53 100644 --- a/centrallix/tests/test_moneytype_objDataToMoney_00.c +++ b/centrallix/tests/test_moneytype_objDataToMoney_00.c @@ -17,6 +17,10 @@ test(char** name) assert(objDataToMoney(2,data_ptr2,&test) == 0); assert(test.Value == -45000); + char data_ptr3[] = "-$0.01"; + assert(objDataToMoney(2,data_ptr3,&test) == 0); + assert(test.Value == -100); + /** Overflow Case (intval > LL max) **/ char overflow_ptr[] = "$10000000000000000000.50"; assert(objDataToMoney(2,overflow_ptr,&test) == -1); diff --git a/centrallix/tests/test_sample_money_00.cmp b/centrallix/tests/test_sample_money_00.cmp index 457fc5998..27d691b8d 100644 --- a/centrallix/tests/test_sample_money_00.cmp +++ b/centrallix/tests/test_sample_money_00.cmp @@ -1 +1 @@ -Attribute [column000]: money $5.25 +Attribute [column_000]: money $5.25 From 55af8533a4380f15f833af9326bdb12a419c9aa8 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Fri, 18 Dec 2020 15:34:36 -0700 Subject: [PATCH 090/129] QPrintf for %LL specifier and accompanying test. --- centrallix-lib/src/qprintf.c | 2 +- centrallix-lib/tests/test_qprintf_64.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/centrallix-lib/src/qprintf.c b/centrallix-lib/src/qprintf.c index 2490b7699..ce3e854da 100644 --- a/centrallix-lib/src/qprintf.c +++ b/centrallix-lib/src/qprintf.c @@ -58,7 +58,7 @@ #define QPF_SPEC_T_DBL (4) #define QPF_SPEC_T_NSTR (5) #define QPF_SPEC_T_CHR (6) -#define QPF_SPEC_T_ENDSRC (6) +#define QPF_SPEC_T_ENDSRC (7) #define QPF_SPEC_T_LL (7) /*** builtin filtering specifiers ***/ diff --git a/centrallix-lib/tests/test_qprintf_64.c b/centrallix-lib/tests/test_qprintf_64.c index 44ec2c333..c0a9a5041 100644 --- a/centrallix-lib/tests/test_qprintf_64.c +++ b/centrallix-lib/tests/test_qprintf_64.c @@ -29,8 +29,6 @@ test(char** tname) qpfPrintf(NULL, buf+4, 36, "Here is the long long: %LL...", 12345ll); qpfPrintf(NULL, buf+4, 36, "Here is the long long: %LL...", 12345ll); rval = qpfPrintf(NULL, buf+4, 36, "Here is the long long: %LL...", 12345ll); - //Currently rval == -22 (EINVAL error code, overflow). - printf("%d", rval); assert(!strcmp(buf+4, "Here is the long long: 12345...")); //For the long long case, rval will be set to the return value of snprintf, i.e. length of string assert(rval == 31); @@ -45,7 +43,5 @@ test(char** tname) } return iter*4; - - return iter*6; } From 2b340255b09e848e9cb3f4273ef97a2f0128743f Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 22 Dec 2020 13:04:53 -0700 Subject: [PATCH 091/129] Http_rest JSON negative handling. Obfuscate long long to int conversion. --- centrallix/netdrivers/net_http_rest.c | 27 ++++++++++++++++++++---- centrallix/utility/obfuscate.c | 30 +++++++++++++++++---------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index d73589109..9dbeb5d2d 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -76,6 +76,7 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty { ObjData od; int rval; + long long whole, fraction; /** Get the data value **/ rval = objGetAttrValue(obj, attrname, data_type, &od); @@ -114,10 +115,28 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty break; case DATA_T_MONEY: - nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%INT, \"fractionpart\":%INT }", - od.Money->Value/10000, - od.Money->Value%10000 - ); + /** For the time being, 64-bit representation will mimic whole and fraction part handling of negatives + ** with regards to JSON data. It will use the new %LL specifier, but the JSON returned will + ** contain an inverted fraction part that always counts in the positive direction. + **/ + + /** If there is a negative with a non-zero fraction part **/ + if (od.Money->Value < 0 && od.Money->Value%10000 != 0) + { + whole = (od.Money->Value + 10000)/10000ll; + fraction = 10000ll - od.Money->Value%10000; + nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%LL, \"fractionpart\":%LL }", + whole, + fraction + ); + } + else + { + nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%LL, \"fractionpart\":%LL }", + od.Money->Value/10000ll, + od.Money->Value%10000ll + ); + } break; default: diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index 2ee98ab80..aaa4e5cb4 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1140,6 +1140,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname static char* str = NULL; int bitcnt = 0; int iv, dv; + long long lliv, lldv; int scale; XString xs; @@ -1200,17 +1201,24 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname break; case DATA_T_MONEY: - iv = srcval->Money->Value/10000 * 100 + (srcval->Money->Value%10000 / 100); - if (strchr(param,'i')) - dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); - else - { - if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = (iv + 1)*10; - if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = iv/10 + 1; - dv = obf_internal_ObfuscateInteger(hash, hash_novalue, &bitcnt, iv); - } - m.Value = dv * 100; - dstval->Money = &m; + if (srcval->Money->Value < INT_MAX) + { + iv = srcval->Money->Value * 100; + if (strchr(param,'i')) + dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); + else + { + if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = (iv + 1)*10; + if (obf_internal_GetBits(hash, &bitcnt, 1)) iv = iv/10 + 1; + dv = obf_internal_ObfuscateInteger(hash, hash_novalue, &bitcnt, iv); + } + m.Value = (long long)(dv * 100); + dstval->Money = &m; + } + else + { + mssError(1,"OBF","Obfuscate not supported for Money Type greater than INT_MAX"); + } break; case DATA_T_DOUBLE: From 4bcfa780086f54c5f4124d368db885cee3b6899c Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 23 Dec 2020 12:08:00 -0700 Subject: [PATCH 092/129] Objdrv_fp.c, using pow() instead of repeated division. --- centrallix/osdrivers/objdrv_fp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 86816031d..92b06fa3d 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1250,9 +1250,9 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da //Finally, I multiple v by decimalOffsetValue to get my Money->Value if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; v = strtoll(ibuf, NULL, 10); - for (i=0; iDecimalOffset; i++) decimalOffsetValue /= 10.0; + decimalOffsetValue /= pow(10, DecimalOffset); pod->Money = (pMoneyType)data; - pod->Money->Value = v*decimalOffsetValue; + pod->Money->Value = (v*decimalOffsetValue)+ 0.1; break; default: mssError(1, "FP", "Bark! Unhandled data type for column '%s'", column->Name); From 161497e97088c96db738ed82c0f1fdf0170b8249 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 23 Dec 2020 18:54:15 -0700 Subject: [PATCH 093/129] Test updates, fixing a reference in osdriver. Obfuscate test framework but not functional --- centrallix/osdrivers/objdrv_fp.c | 2 +- ...est_moneytype_fp_internal_ParseColumn_00.c | 4 +-- .../tests/test_moneytype_obfuscate_00.c | 26 +++++++++++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/centrallix/osdrivers/objdrv_fp.c b/centrallix/osdrivers/objdrv_fp.c index 92b06fa3d..452a31008 100644 --- a/centrallix/osdrivers/objdrv_fp.c +++ b/centrallix/osdrivers/objdrv_fp.c @@ -1250,7 +1250,7 @@ fp_internal_ParseColumn(pFpColInf column, pObjData pod, char* data, char* row_da //Finally, I multiple v by decimalOffsetValue to get my Money->Value if (fp_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; v = strtoll(ibuf, NULL, 10); - decimalOffsetValue /= pow(10, DecimalOffset); + decimalOffsetValue /= pow(10, column->DecimalOffset); pod->Money = (pMoneyType)data; pod->Money->Value = (v*decimalOffsetValue)+ 0.1; break; diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c index 7e7a1ffb3..c840cc769 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c @@ -45,11 +45,11 @@ test(char** name) assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); assert(moneyDataPtr->Money->Value == 4500); - //This function truncates answers + //This function now rounds properly with the addition of adding .1 for floating point error handling char* testRoundedString = "45011999"; testColInf.DecimalOffset = 5; assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testRoundedString) == 0); - assert(moneyDataPtr->Money->Value == 4501199); + assert(moneyDataPtr->Money->Value == 4501200); return 0; diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c index 7054a57b5..b58783f8b 100644 --- a/centrallix/tests/test_moneytype_obfuscate_00.c +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -3,14 +3,36 @@ #include #include "expression.h" #include "cxlib/xstring.h" -//#include "utility/obfuscate.c" +#include "obfuscate.h" long long test(char** name) { *name = "moneytype_00 - obfuscate"; - //obfObfuscateData(); + //MoneyType + int dataType = 7; + + pObfWord wordList; + pObfWordCat catList; + char* attrname, objname, type_name, key, which, param; + char example[] = "exampleWord"; + char ex2[] = "key"; + char ex3[] = "type_name"; + char ex4[] = "objname"; + char ex5[] = "attrname"; + which = example; key = ex2; type_name = ex3; objname = ex4; attrname = ex5; + + void* generic = example; + + ObjData srcValFiller, dstValFiller; + MoneyType unionFiller = {70000}; + srcValFiller.Money = &unionFiller; + srcValFiller.Generic = generic; + pObjData srcVal = &srcValFiller; + pObjData dstVal = &dstValFiller; + + obfObfuscateData(srcVal, dstVal, dataType, attrname, objname, type_name, key, which, param, wordList, catList); return 0; } From 83a0b2efaec8cd03c6051f568584c5cce11eab4f Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Tue, 29 Dec 2020 18:08:14 -0700 Subject: [PATCH 094/129] Renamed internal format Money test to accurately reflect function being called --- ...l_FormatMoney_00.c => test_moneytype_objFormatMoneyTmp_00.c} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename centrallix/tests/{test_moneytype_obj_internal_FormatMoney_00.c => test_moneytype_objFormatMoneyTmp_00.c} (94%) diff --git a/centrallix/tests/test_moneytype_obj_internal_FormatMoney_00.c b/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c similarity index 94% rename from centrallix/tests/test_moneytype_obj_internal_FormatMoney_00.c rename to centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c index 7901cd348..4193eaa92 100644 --- a/centrallix/tests/test_moneytype_obj_internal_FormatMoney_00.c +++ b/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c @@ -8,7 +8,7 @@ test(char** name) ** Functionality was changed in obj_internal_FormatMoney, so the point of ** these tests is to test obj_internal_FormatMoney, even with a different function call **/ - *name = "moneytype_00 - obj_internal_FormatMoney"; + *name = "moneytype_00 - objFormatMoneyTmp"; /** 0 Case **/ MoneyType test = {0}; From 1b27fd61a93915507c25d7170016112732b4c953 Mon Sep 17 00:00:00 2001 From: Carl Cederborg <45981643+cscederborg@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:19:30 -0700 Subject: [PATCH 095/129] Resolving code review comments. Bound checking, more test cases, negative handling, fixing endianness --- centrallix-lib/tests/test_qprintf_65.c | 47 +++++++++++++++++++ centrallix/expression/exp_evaluate.c | 2 +- centrallix/netdrivers/net_http_rest.c | 6 ++- centrallix/osdrivers/objdrv_sybase.c | 10 ++-- .../tests/test_moneytype_objDataToMoney_00.c | 31 +++++++++--- centrallix/utility/obfuscate.c | 2 +- 6 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 centrallix-lib/tests/test_qprintf_65.c diff --git a/centrallix-lib/tests/test_qprintf_65.c b/centrallix-lib/tests/test_qprintf_65.c new file mode 100644 index 000000000..52c4a01ae --- /dev/null +++ b/centrallix-lib/tests/test_qprintf_65.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include "qprintf.h" +#include + +long long +test(char** tname) +{ + int i, rval; + int iter; + unsigned char buf[44]; + + *tname = "qprintf-65 %LL > INT_MAX insertion in middle without overflow"; + iter = 200000; + for(i=0;iTypes.Money.Value = (long long)(i0->Types.Money.Value/i1->Types.Double); + tree->Types.Money.Value = llround(i0->Types.Money.Value/i1->Types.Double); break; case DATA_T_MONEY: mv = i0->Types.Money.Value; diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index 9dbeb5d2d..525127e86 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -123,8 +123,10 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty /** If there is a negative with a non-zero fraction part **/ if (od.Money->Value < 0 && od.Money->Value%10000 != 0) { - whole = (od.Money->Value + 10000)/10000ll; - fraction = 10000ll - od.Money->Value%10000; + /** Add negative 1 then truncate fraction. (essentially floor() )**/ + whole = (od.Money->Value - 10000)/10000ll; + /** Since fraction always counts away from zero, it is inverted**/ + fraction = 10000ll - abs(od.Money->Value%10000); nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%LL, \"fractionpart\":%LL }", whole, fraction diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index d5dbe173b..7e66c3f79 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -797,14 +797,10 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) if (lsl == 0xFFFFFFFF) msl++; lsl++; } - /** Both msl and lsl are little endian, so I want lsl to come before msl. - ** I do this by shifting lsl left in a long long (ll_lsl) by 32 bits, and then OR it with msl + /** msl is the most significant 32-bit value and needs to come before lsl + ** I do this by shifting msl left cast to a long long by 32 bits, and then OR it with lsl **/ - ll_msl = msl; - ll_lsl = lsl; - ll_lsl = ll_lsl << 32; - ll_lsl = ll_lsl | ll_msl; - val->Money->Value = ll_lsll; + val->Money->Value = (((long long)msl)<<32) | (long long)lsl; if (minus) val->Money->Value = -val->Money->Value; return 0; diff --git a/centrallix/tests/test_moneytype_objDataToMoney_00.c b/centrallix/tests/test_moneytype_objDataToMoney_00.c index f46e42f53..39aa2231a 100644 --- a/centrallix/tests/test_moneytype_objDataToMoney_00.c +++ b/centrallix/tests/test_moneytype_objDataToMoney_00.c @@ -1,6 +1,7 @@ #include "obj.h" #include #include +#include long long test(char** name) @@ -9,18 +10,27 @@ test(char** name) MoneyType test = {0}; /** String Case **/ - char data_ptr[] = "$4.50"; + char data_ptr[20] = "$4.50"; assert(objDataToMoney(2,data_ptr,&test) == 0); assert(test.Value == 45000); - char data_ptr2[] = "-$4.50"; - assert(objDataToMoney(2,data_ptr2,&test) == 0); + strcpy(data_ptr, "-$4.50"); + assert(objDataToMoney(2,data_ptr,&test) == 0); assert(test.Value == -45000); - char data_ptr3[] = "-$0.01"; - assert(objDataToMoney(2,data_ptr3,&test) == 0); + strcpy(data_ptr, "-$0.01"); + assert(objDataToMoney(2,data_ptr,&test) == 0); assert(test.Value == -100); + + /** String Case that would overflow INT_MAX and INT_MIN **/ + strcpy(data_ptr, "$2200000000.00"); + assert(objDataToMoney(2,data_ptr,&test) == 0); + assert(test.Value == 22000000000000); + strcpy(data_ptr, "-$2200000000.00"); + assert(objDataToMoney(2,data_ptr,&test) == 0); + assert(test.Value == -22000000000000); + /** Overflow Case (intval > LL max) **/ char overflow_ptr[] = "$10000000000000000000.50"; assert(objDataToMoney(2,overflow_ptr,&test) == -1); @@ -34,7 +44,16 @@ test(char** name) assert(objDataToMoney(3,&testDouble,&test) == 0); assert(test.Value == -55000); - //Double Fraction Overflow + /** Double Case that would overflow INT_MAX and INT_MIN **/ + testDouble = 2200000000.5; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == 22000000005000); + + testDouble = -2200000000.5; + assert(objDataToMoney(3,&testDouble,&test) == 0); + assert(test.Value == -22000000005000); + + /** Double Fraction Overflow **/ testDouble = 5.159999999999; assert(objDataToMoney(3,&testDouble,&test) == 0); assert(test.Value == 51600); diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index aaa4e5cb4..e5e33bd60 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1201,7 +1201,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname break; case DATA_T_MONEY: - if (srcval->Money->Value < INT_MAX) + if (srcval->Money->Value <= INT_MAX/100 && srcval->Money->Value >= INT_MIN/100) { iv = srcval->Money->Value * 100; if (strchr(param,'i')) From 8d4457a5d515c23dbc0e6e3f33e2833f85da5c0f Mon Sep 17 00:00:00 2001 From: sheesania Date: Fri, 9 Apr 2021 12:41:23 -0600 Subject: [PATCH 096/129] Fixing extra spacing and commented-out code --- centrallix/expression/exp_evaluate.c | 2 +- centrallix/netdrivers/net_http_rest.c | 2 +- centrallix/osdrivers/objdrv_dbl.c | 2 -- centrallix/osdrivers/objdrv_sybase.c | 3 --- centrallix/tests/test_moneytype_objDataToInteger_00.c | 3 --- 5 files changed, 2 insertions(+), 10 deletions(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index 2514dfff1..6ff3aafb8 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -431,7 +431,7 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) case DATA_T_INTEGER: mv *= i1->Integer; break; - case DATA_T_DOUBLE: + case DATA_T_DOUBLE: md = mv * i1->Types.Double; if (md < 0) md -= 0.5; else md += 0.5; diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index 525127e86..42a255367 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -76,7 +76,7 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty { ObjData od; int rval; - long long whole, fraction; + long long whole, fraction; /** Get the data value **/ rval = objGetAttrValue(obj, attrname, data_type, &od); diff --git a/centrallix/osdrivers/objdrv_dbl.c b/centrallix/osdrivers/objdrv_dbl.c index 6e70e5a92..be6437cee 100755 --- a/centrallix/osdrivers/objdrv_dbl.c +++ b/centrallix/osdrivers/objdrv_dbl.c @@ -1655,13 +1655,11 @@ dbl_internal_ParseColumn(pDblColInf column, pObjData pod, char* data, char* row_ for(i=0;iDecimalOffset;i++) f *= 10; pod->Money = (pMoneyType)data; pod->Money->Value = (v/f) * 10000; - //pod->Money->WholePart = v/f; v = (v/f)*f; if (column->DecimalOffset <= 4) for(i=column->DecimalOffset;i<4;i++) v *= 10; else for(i=4;iDecimalOffset;i++) v /= 10; - //pod->Money->FractionPart = v; pod->Money->Value += v; break; default: diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 7e66c3f79..f20167f2b 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -777,9 +777,6 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) /** smallmoney, 4-byte **/ memcpy(&i, ptr, 4); val->Money->Value = i; - //val->Money->WholePart = i/10000; - //if (i < 0 && (i%10000) != 0) val->Money->WholePart--; - //val->Money->FractionPart = i - (val->Money->WholePart*10000); return 0; } else diff --git a/centrallix/tests/test_moneytype_objDataToInteger_00.c b/centrallix/tests/test_moneytype_objDataToInteger_00.c index 9dc71ec01..465e4db44 100644 --- a/centrallix/tests/test_moneytype_objDataToInteger_00.c +++ b/centrallix/tests/test_moneytype_objDataToInteger_00.c @@ -1,9 +1,6 @@ #include "obj.h" #include #include -//#include "xstring.h" -//#include "mtsession.h" -//#include "mtask.h" long long test(char** name) From 41b9a183730fcf1823c1e8cae83c8658c7623850 Mon Sep 17 00:00:00 2001 From: sheesania Date: Tue, 13 Apr 2021 13:09:31 -0600 Subject: [PATCH 097/129] Change obj_internal_BuildBinaryItem test to using public function objBuildBinaryImage --- .../test_moneytype_objBuildBinaryImage_00.c | 58 +++++++++++++++++ ...oneytype_obj_internal_BuildBinaryItem_00.c | 64 ------------------- 2 files changed, 58 insertions(+), 64 deletions(-) create mode 100644 centrallix/tests/test_moneytype_objBuildBinaryImage_00.c delete mode 100644 centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c diff --git a/centrallix/tests/test_moneytype_objBuildBinaryImage_00.c b/centrallix/tests/test_moneytype_objBuildBinaryImage_00.c new file mode 100644 index 000000000..27e658148 --- /dev/null +++ b/centrallix/tests/test_moneytype_objBuildBinaryImage_00.c @@ -0,0 +1,58 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" + +long long +test(char** name) +{ + *name = "moneytype_00 - objBuildBinaryImage"; + + pExpression testExp = expAllocExpression(); + pExpression testExpCmp = expAllocExpression(); + pParamObjects testParamObjects = expCreateParamList(); + + //Buffer must be at least 12 bytes for data types not yet implemented. + //Current highest byte size is 9, but 12 may come later + char buf[12]; + char cmpBuf[12]; + int buflen = 12; + + /** NULL Case **/ + assert(objBuildBinaryImage(buf, buflen, &testExp, 1, testParamObjects, 0) == -1); + + //For remaining cases, creating two ObjData with a moneytype inside, pObjData for parameters + //After passing through BuildBinaryImage, they will be compared with memcmp() because it is not the binary value + //itself that matters, but the comparison between the two objects. + ObjData moneyData; + MoneyType money = {70000}; + moneyData.Money = &money; + pObjData moneyDataPtr = &moneyData; + + ObjData moneyDataCmp; + MoneyType moneyCmp = {65000}; + moneyDataCmp.Money = &moneyCmp; + pObjData moneyDataPtrCmp = &moneyDataCmp; + + /** Positive Case **/ + testExp = expPodToExpression(moneyDataPtr, 7, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); + objBuildBinaryImage(buf, buflen, &testExp, 1, testParamObjects, 0); + objBuildBinaryImage(cmpBuf, buflen, &testExpCmp, 1, testParamObjects, 0); + assert(memcmp(buf,cmpBuf,8) > 0); + + /** Negative Case **/ + money.Value = -70000; + moneyCmp.Value = -65000; + testExp = expPodToExpression(moneyDataPtr, 7, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); + objBuildBinaryImage(buf, buflen, &testExp, 1, testParamObjects, 0); + objBuildBinaryImage(cmpBuf, buflen, &testExpCmp, 1, testParamObjects, 0); + assert(memcmp(buf,cmpBuf,8) < 0); + + expFreeExpression(testExp); + expFreeExpression(testExpCmp); + + return 0; +} diff --git a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c b/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c deleted file mode 100644 index 676de1281..000000000 --- a/centrallix/tests/test_moneytype_obj_internal_BuildBinaryItem_00.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "obj.h" -#include -#include -#include "expression.h" -#include "cxlib/xstring.h" - -long long -test(char** name) -{ - *name = "moneytype_00 - obj_internal_BuildBinaryItem"; - char** item; - item = (char**)malloc(24); - int* itemlen; - itemlen = (int*)malloc(4); - - //Utilizing expression.h functions to initialize expression and paramobjects - pExpression testExp = expAllocExpression(); - pExpression testExpCmp = expAllocExpression(); - pParamObjects testParamObjects = expCreateParamList(); - - //Buffer must be at least 12 bytes for data types not yet implemented. - //Current highest byte size is 9, but 12 may come later - unsigned char tmpbuf[12]; - unsigned char cmpbuf[12]; - - /** NULL Case **/ - assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == -1); - - //For remaining cases, creating two ObjData with a moneytype inside, pObjData for parameters - //After passing through BuildBinaryItem, they will be compared with memcmp() because it is not the binary value - //itself that matters, but the comparison between the two objects. - ObjData moneyData; - MoneyType unionFiller = {70000}; - moneyData.Money = &unionFiller; - pObjData moneyDataPtr = &moneyData; - - ObjData moneyDataCmp; - MoneyType unionFiller2 = {65000}; - moneyDataCmp.Money = &unionFiller2; - pObjData moneyDataPtrCmp = &moneyDataCmp; - - /** Positive Case **/ - testExp = expPodToExpression(moneyDataPtr, 7, testExp); - testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); - assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); - assert(obj_internal_BuildBinaryItem(item, itemlen, testExpCmp, testParamObjects, cmpbuf) == 0); - - assert(memcmp(tmpbuf,cmpbuf,8) > 0); - - /** Negative Case **/ - unionFiller.Value = -70000; - unionFiller2.Value = -65000; - testExp = expPodToExpression(moneyDataPtr, 7, testExp); - testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); - assert(obj_internal_BuildBinaryItem(item, itemlen, testExp, testParamObjects, tmpbuf) == 0); - assert(obj_internal_BuildBinaryItem(item, itemlen, testExpCmp, testParamObjects, cmpbuf) == 0); - - assert(memcmp(tmpbuf,cmpbuf,8) < 0); - - expFreeExpression(testExp); - expFreeExpression(testExpCmp); - - return 0; -} From ee8f7d4bacb40b9ee43c42b129946f44c42c0c19 Mon Sep 17 00:00:00 2001 From: sheesania Date: Tue, 13 Apr 2021 14:44:16 -0600 Subject: [PATCH 098/129] Remove extraneous qprintf %LL test --- centrallix-lib/tests/test_qprintf_66.c | 17 ++++++---- centrallix-lib/tests/test_qprintf_67.c | 46 -------------------------- 2 files changed, 11 insertions(+), 52 deletions(-) delete mode 100644 centrallix-lib/tests/test_qprintf_67.c diff --git a/centrallix-lib/tests/test_qprintf_66.c b/centrallix-lib/tests/test_qprintf_66.c index 3d614a0e3..1de4840c3 100644 --- a/centrallix-lib/tests/test_qprintf_66.c +++ b/centrallix-lib/tests/test_qprintf_66.c @@ -25,13 +25,18 @@ test(char** tname) buf[2] = '\0'; buf[1] = 0xff; buf[0] = '\0'; - qpfPrintf(NULL, buf+4, 36, "Here is the long long: %LL...", 12345ll); - qpfPrintf(NULL, buf+4, 36, "Here is the long long: %LL...", 12345ll); - qpfPrintf(NULL, buf+4, 36, "Here is the long long: %LL...", 12345ll); - rval = qpfPrintf(NULL, buf+4, 36, "Here is the long long: %LL...", 12345ll); - assert(!strcmp(buf+4, "Here is the long long: 12345...")); + + //Test value > INT_MAX + long long testNum = 2200000000ll; + + qpfPrintf(NULL, buf + 4, 36, "Here is the ll: %LL...", testNum); + qpfPrintf(NULL, buf+4, 36, "Here is the ll: %LL...", testNum); + qpfPrintf(NULL, buf+4, 36, "Here is the ll: %LL...", testNum); + rval = qpfPrintf(NULL, buf+4, 36, "Here is the ll: %LL...", testNum); + + assert(!strcmp(buf+4, "Here is the ll: 2200000000...")); //For the long long case, rval will be set to the return value of snprintf, i.e. length of string - assert(rval == 31); + assert(rval == 29); assert(buf[43] == '\n'); assert(buf[42] == '\0'); assert(buf[41] == 0xff); diff --git a/centrallix-lib/tests/test_qprintf_67.c b/centrallix-lib/tests/test_qprintf_67.c deleted file mode 100644 index 3883a994d..000000000 --- a/centrallix-lib/tests/test_qprintf_67.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include -#include "qprintf.h" -#include - -long long -test(char** tname) -{ - int i, rval; - int iter; - unsigned char buf[44]; - - *tname = "qprintf-67 %LL > INT_MAX insertion in middle without overflow"; - iter = 200000; - for(i=0;i Date: Tue, 20 Apr 2021 15:29:01 -0600 Subject: [PATCH 099/129] Remove comment --- centrallix/expression/exp_evaluate.c | 1 - 1 file changed, 1 deletion(-) diff --git a/centrallix/expression/exp_evaluate.c b/centrallix/expression/exp_evaluate.c index 8a466895d..5514c1c07 100644 --- a/centrallix/expression/exp_evaluate.c +++ b/centrallix/expression/exp_evaluate.c @@ -413,7 +413,6 @@ expEvalMultiply(pExpression tree, pParamObjects objlist) { case DATA_T_MONEY: tree->DataType = DATA_T_MONEY; - //Double check that casting is working properly mv = i1->Types.Money.Value * i0->Types.Double; break; default: From 02ee697b60c1394b038967ead991363791cf2e1d Mon Sep 17 00:00:00 2001 From: sheesania Date: Tue, 27 Apr 2021 13:59:42 -0600 Subject: [PATCH 100/129] Fix moneytype obfuscation + tests --- .../tests/test_moneytype_obfuscate_00.c | 78 +++++++++++++------ centrallix/utility/obfuscate.c | 6 +- 2 files changed, 58 insertions(+), 26 deletions(-) diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c index b58783f8b..6568c74e6 100644 --- a/centrallix/tests/test_moneytype_obfuscate_00.c +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -5,34 +5,64 @@ #include "cxlib/xstring.h" #include "obfuscate.h" +void +testObfuscationWIntegerMultiples() +{ + ObjData srcVal, dstVal; + long long moneyValue = 1100; + MoneyType money = {moneyValue}; + srcVal.Money = &money; + int numsToObfuscate = 50; + int obfuscated = 0; + int i; + + for (i = 0; i < numsToObfuscate; i++) + { + money.Value = moneyValue; + int rval = obfObfuscateData(&srcVal, &dstVal, DATA_T_MONEY, NULL, NULL, NULL, NULL, "V", "i", NULL, NULL); + assert(rval == 0); + if (dstVal.Money->Value != srcVal.Money->Value) { + obfuscated++; + } + moneyValue *= 2; + } + float percentObfuscated = (float)obfuscated / (float)numsToObfuscate; + assert(percentObfuscated > 0.70); +} + +void +testObfuscationWIntegerObfuscate() +{ + ObjData srcVal, dstVal; + long long moneyValue = 1100; + MoneyType money = {moneyValue}; + srcVal.Money = &money; + int i; + + for (i = 0; i < 50; i++) + { + money.Value = moneyValue; + int rval = obfObfuscateData(&srcVal, &dstVal, DATA_T_MONEY, NULL, NULL, NULL, NULL, "V", NULL, NULL, NULL); + assert(rval == 0); + assert(dstVal.Money->Value != srcVal.Money->Value); + moneyValue *= 2; + } +} + +void +testMoneyTooLarge() +{ + +} + long long test(char** name) { *name = "moneytype_00 - obfuscate"; - //MoneyType - int dataType = 7; - - pObfWord wordList; - pObfWordCat catList; - char* attrname, objname, type_name, key, which, param; - char example[] = "exampleWord"; - char ex2[] = "key"; - char ex3[] = "type_name"; - char ex4[] = "objname"; - char ex5[] = "attrname"; - which = example; key = ex2; type_name = ex3; objname = ex4; attrname = ex5; - - void* generic = example; - - ObjData srcValFiller, dstValFiller; - MoneyType unionFiller = {70000}; - srcValFiller.Money = &unionFiller; - srcValFiller.Generic = generic; - pObjData srcVal = &srcValFiller; - pObjData dstVal = &dstValFiller; - - obfObfuscateData(srcVal, dstVal, dataType, attrname, objname, type_name, key, which, param, wordList, catList); - + testObfuscationWIntegerMultiples(); + testObfuscationWIntegerObfuscate(); + testMoneyTooLarge(); + return 0; } diff --git a/centrallix/utility/obfuscate.c b/centrallix/utility/obfuscate.c index e5e33bd60..3f0f020a3 100644 --- a/centrallix/utility/obfuscate.c +++ b/centrallix/utility/obfuscate.c @@ -1143,6 +1143,7 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname long long lliv, lldv; int scale; XString xs; + long long twoDecimalPlacesMoney; /** Empty param? **/ if (!param) @@ -1201,9 +1202,10 @@ obfObfuscateData(pObjData srcval, pObjData dstval, int data_type, char* attrname break; case DATA_T_MONEY: - if (srcval->Money->Value <= INT_MAX/100 && srcval->Money->Value >= INT_MIN/100) + twoDecimalPlacesMoney = srcval->Money->Value / 100; + if (twoDecimalPlacesMoney <= INT_MAX && twoDecimalPlacesMoney >= INT_MIN) { - iv = srcval->Money->Value * 100; + iv = twoDecimalPlacesMoney; if (strchr(param,'i')) dv = obf_internal_ObfuscateIntegerMultiples(hash, hash_novalue, &bitcnt, iv); else From 7085c006fb363ad52c9501f8fdb5e40fcdf99689 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 3 May 2021 11:06:36 -0600 Subject: [PATCH 101/129] Basic helper for testing calls to mssError --- centrallix/Makefile.in | 5 +++-- .../include/testhelpers/mssErrorHelper.h | 8 +++++++ centrallix/tests/helpers/mssErrorHelper.c | 22 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 centrallix/include/testhelpers/mssErrorHelper.h create mode 100644 centrallix/tests/helpers/mssErrorHelper.c diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index 4bd52d1ee..22f8db06e 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -367,6 +367,7 @@ ifeq ($TOTESTFILES,) else TOTESTDEPS=test_install endif +TESTHELPERS:=$(wildcard tests/helpers/*.o) # Some basic build parameters. PROFILE=@PROFILE@ @@ -529,8 +530,8 @@ tests/centrallix.conf-test: tests/centrallix.conf-test.in tests/t_driver.o: tests/t_driver.c $(CC) $(CFLAGS) $< -c -o $@ -tests/test_%.bin: tests/test_%.o tests/t_driver.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) - $(CC) $< tests/t_driver.o centrallix.o $(V3LSOBJS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o $@ $(LIBS) @NCURSES_LIBS@ +tests/test_%.bin: tests/test_%.o tests/t_driver.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) $(TESTHELPERS) + $(CC) $< tests/t_driver.o centrallix.o $(V3LSOBJS) $(TESTHELPERS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o $@ $(LIBS) @NCURSES_LIBS@ test: tests/centrallix.conf-test $(TOTESTDEPS) $(TOTESTFILES) $(CBTESTFILES) @printf "%-62.62s %s\n" "Test Name" "Stat" diff --git a/centrallix/include/testhelpers/mssErrorHelper.h b/centrallix/include/testhelpers/mssErrorHelper.h new file mode 100644 index 000000000..6e4abb208 --- /dev/null +++ b/centrallix/include/testhelpers/mssErrorHelper.h @@ -0,0 +1,8 @@ +#ifndef _MSS_ERROR_HELPER_H +#define _MSS_ERROR_HELPER_H + +/** doc string */ +int mssErrorHelper_init(); +int mssErrorHelper_mostRecentErrorContains(char *message); + +#endif /* not defined _MSS_ERROR_HELPER_H */ \ No newline at end of file diff --git a/centrallix/tests/helpers/mssErrorHelper.c b/centrallix/tests/helpers/mssErrorHelper.c new file mode 100644 index 000000000..ca5384028 --- /dev/null +++ b/centrallix/tests/helpers/mssErrorHelper.c @@ -0,0 +1,22 @@ +#include +#include +#include "testhelpers/mssErrorHelper.h" +#include "cxlib/xstring.h" + +int +mssErrorHelper_init() +{ + mssInitialize("altpasswd", "/usr/local/etc/centrallix/cxpasswd-test", "", 0, "test"); + mssAuthenticate("cxtest", "cxtestpass"); + return 0; +} + +int +mssErrorHelper_mostRecentErrorContains(char* message) +{ + pXString err = xsNew(); + mssStringError(err); + char* foundPtr = strstr(xsString(err), message); + xsFree(err); + return !(!foundPtr); +} \ No newline at end of file From 2cd7a94ce41c8645d62b409e8262f674b0be3a99 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 3 May 2021 12:31:35 -0600 Subject: [PATCH 102/129] Working test for MoneyType to integer overflows --- centrallix/tests/helpers/mssErrorHelper.c | 3 +-- .../test_moneytype_objDataToInteger_00.c | 22 +++++++------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/centrallix/tests/helpers/mssErrorHelper.c b/centrallix/tests/helpers/mssErrorHelper.c index ca5384028..af8a456dd 100644 --- a/centrallix/tests/helpers/mssErrorHelper.c +++ b/centrallix/tests/helpers/mssErrorHelper.c @@ -7,8 +7,7 @@ int mssErrorHelper_init() { mssInitialize("altpasswd", "/usr/local/etc/centrallix/cxpasswd-test", "", 0, "test"); - mssAuthenticate("cxtest", "cxtestpass"); - return 0; + return mssAuthenticate("cxtest", "cxtestpass"); } int diff --git a/centrallix/tests/test_moneytype_objDataToInteger_00.c b/centrallix/tests/test_moneytype_objDataToInteger_00.c index 465e4db44..c42f627f9 100644 --- a/centrallix/tests/test_moneytype_objDataToInteger_00.c +++ b/centrallix/tests/test_moneytype_objDataToInteger_00.c @@ -1,6 +1,7 @@ -#include "obj.h" #include #include +#include "obj.h" +#include "testhelpers/mssErrorHelper.h" long long test(char** name) @@ -24,18 +25,11 @@ test(char** name) assert(objDataToInteger(7,&test,NULL) == 1); /** Overflow Case **/ - //Manual Testing showed this section to work properly on overflow - //Currently, I do not know how to print the error messages, so this part - //will remain commented out. - - //test.Value = 250000000000000000; - //testValue = objDataToInteger(7,&test,NULL); - - //assert(testValue); - //assert(testValue == 5); - //mssStringError(pXString); - //printf("%s", pXString); - - + mssErrorHelper_init(); + test.Value = 250000000000000000; + objDataToInteger(7,&test,NULL); + assert(mssErrorHelper_mostRecentErrorContains( + "OBJ: Warning: 7 (MoneyType) overflow; cannot fit value of that size in int")); + return 0; } From 83d9c80e4e6875108c221b1039db4184df9d0c81 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 3 May 2021 13:13:48 -0600 Subject: [PATCH 103/129] Test for obfuscating MoneyTypes > INT_MAX --- centrallix/tests/test_moneytype_obfuscate_00.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c index 6568c74e6..223bc88d6 100644 --- a/centrallix/tests/test_moneytype_obfuscate_00.c +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -4,6 +4,7 @@ #include "expression.h" #include "cxlib/xstring.h" #include "obfuscate.h" +#include "testhelpers/mssErrorHelper.h" void testObfuscationWIntegerMultiples() @@ -52,7 +53,13 @@ testObfuscationWIntegerObfuscate() void testMoneyTooLarge() { + ObjData srcVal, dstVal; + MoneyType money = {25000000000000000000}; + srcVal.Money = &money; + mssErrorHelper_init(); + obfObfuscateData(&srcVal, &dstVal, DATA_T_MONEY, NULL, NULL, NULL, NULL, "V", NULL, NULL, NULL); + assert(mssErrorHelper_mostRecentErrorContains("Obfuscate not supported for Money Type greater than INT_MAX")); } long long From 07506efa2eb0d7d8d9db7628fc58d732c56ea12f Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 3 May 2021 14:26:04 -0600 Subject: [PATCH 104/129] Remove extraneous comment --- centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c b/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c index 4193eaa92..be42ee3f7 100644 --- a/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c +++ b/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c @@ -4,10 +4,6 @@ long long test(char** name) { - /** objFormatMoneyTmp is a wrapper that calls obj_internal_FormatMoney - ** Functionality was changed in obj_internal_FormatMoney, so the point of - ** these tests is to test obj_internal_FormatMoney, even with a different function call - **/ *name = "moneytype_00 - objFormatMoneyTmp"; /** 0 Case **/ From 69d13c37f1ade4d3813458918489bde02f0055ff Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 3 May 2021 14:28:45 -0600 Subject: [PATCH 105/129] Remove sample test files --- centrallix/tests/test_sample_money.cmp | 1 - centrallix/tests/test_sample_money.to | 2 -- centrallix/tests/test_sample_money_00.cmp | 1 - centrallix/tests/test_sample_money_00.to | 2 -- 4 files changed, 6 deletions(-) delete mode 100644 centrallix/tests/test_sample_money.cmp delete mode 100644 centrallix/tests/test_sample_money.to delete mode 100644 centrallix/tests/test_sample_money_00.cmp delete mode 100644 centrallix/tests/test_sample_money_00.to diff --git a/centrallix/tests/test_sample_money.cmp b/centrallix/tests/test_sample_money.cmp deleted file mode 100644 index b1180a931..000000000 --- a/centrallix/tests/test_sample_money.cmp +++ /dev/null @@ -1 +0,0 @@ -Attribute [column_000]: money $5.50 diff --git a/centrallix/tests/test_sample_money.to b/centrallix/tests/test_sample_money.to deleted file mode 100644 index 0574b1e96..000000000 --- a/centrallix/tests/test_sample_money.to +++ /dev/null @@ -1,2 +0,0 @@ -##NAME Money Test 2 -query select $4 + 1.5 diff --git a/centrallix/tests/test_sample_money_00.cmp b/centrallix/tests/test_sample_money_00.cmp deleted file mode 100644 index 27d691b8d..000000000 --- a/centrallix/tests/test_sample_money_00.cmp +++ /dev/null @@ -1 +0,0 @@ -Attribute [column_000]: money $5.25 diff --git a/centrallix/tests/test_sample_money_00.to b/centrallix/tests/test_sample_money_00.to deleted file mode 100644 index 01b29ab09..000000000 --- a/centrallix/tests/test_sample_money_00.to +++ /dev/null @@ -1,2 +0,0 @@ -##NAME Sample Test Functionality -query select $4 + 1.25 From 7e5183cd64727b1ad04777a8035fed167368657f Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 May 2021 10:28:03 -0600 Subject: [PATCH 106/129] Fix "integer constant too large for its type" --- centrallix/tests/test_moneytype_obfuscate_00.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/centrallix/tests/test_moneytype_obfuscate_00.c b/centrallix/tests/test_moneytype_obfuscate_00.c index 223bc88d6..fb76003d7 100644 --- a/centrallix/tests/test_moneytype_obfuscate_00.c +++ b/centrallix/tests/test_moneytype_obfuscate_00.c @@ -54,7 +54,7 @@ void testMoneyTooLarge() { ObjData srcVal, dstVal; - MoneyType money = {25000000000000000000}; + MoneyType money = {250000000000000000ll}; srcVal.Money = &money; mssErrorHelper_init(); From cd073cd9557bf5825a3be14936aeb2817e790d26 Mon Sep 17 00:00:00 2001 From: sheesania Date: Thu, 13 May 2021 14:02:26 -0600 Subject: [PATCH 107/129] Fix makefile for test helpers --- centrallix/Makefile.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index 22f8db06e..113f03d0a 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -367,7 +367,8 @@ ifeq ($TOTESTFILES,) else TOTESTDEPS=test_install endif -TESTHELPERS:=$(wildcard tests/helpers/*.o) +CTESTHELPERS:=$(wildcard tests/helpers/*.c) +TESTHELPERS:=$(patsubst %.c,%.o,$(CTESTHELPERS)) # Some basic build parameters. PROFILE=@PROFILE@ @@ -647,6 +648,7 @@ clean: @rm -f man/*.gz @rm -f tests/*.to.tmp tests/*.out @rm -f tests/*.o tests/*.bin + @rm -f tests/helpers/*.o @rm -rf thirdparty/*-inst @rm -f *.gcov */*.gcov @rm -f *.gcda */*.gcda From a65f43884f42aadba80f16c12b331d787c640168 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 24 May 2021 11:54:12 -0600 Subject: [PATCH 108/129] Basic test helper for stdout output --- centrallix/include/testhelpers/stdoutHelper.h | 10 +++++ centrallix/tests/helpers/stdoutHelper.c | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 centrallix/include/testhelpers/stdoutHelper.h create mode 100644 centrallix/tests/helpers/stdoutHelper.c diff --git a/centrallix/include/testhelpers/stdoutHelper.h b/centrallix/include/testhelpers/stdoutHelper.h new file mode 100644 index 000000000..b3e869291 --- /dev/null +++ b/centrallix/include/testhelpers/stdoutHelper.h @@ -0,0 +1,10 @@ +#ifndef _STDOUT_HELPER_H +#define _STDOUT_HELPER_H + +/** Begin redirecting and capturing stdout output. It will no longer output to the terminal (or wherever else you have it going) */ +int stdoutHelper_startCapture(); + +/** Stop redirecting stdout and return the redirected contents that were captured */ +char* stdoutHelper_stopCaptureAndGetContents(); + +#endif /* not defined _STDOUT_HELPER_H */ \ No newline at end of file diff --git a/centrallix/tests/helpers/stdoutHelper.c b/centrallix/tests/helpers/stdoutHelper.c new file mode 100644 index 000000000..377b40e4d --- /dev/null +++ b/centrallix/tests/helpers/stdoutHelper.c @@ -0,0 +1,38 @@ +#include +#include +#include "testhelpers/stdoutHelper.h" + +int stdoutHelper_stdoutCopy; +FILE *stdoutHelper_tmpfile; + +int +stdoutHelper_startCapture() +{ + // Redirect stdout to a file + fflush(stdout); + stdoutHelper_stdoutCopy = dup(STDOUT_FILENO); + stdoutHelper_tmpfile = fopen(".test-helper-stdout", "w+"); + dup2(fileno(stdoutHelper_tmpfile), STDOUT_FILENO); +} + +char* +stdoutHelper_stopCaptureAndGetContents() +{ + // Stop redirecting stdout + fflush(stdout); + dup2(stdoutHelper_stdoutCopy, STDOUT_FILENO); + close(stdoutHelper_stdoutCopy); + + // Read the contents of the file with stdout contents + fseek(stdoutHelper_tmpfile, 0, SEEK_END); + long size = ftell(stdoutHelper_tmpfile); + char *contents = malloc(size + 1); + rewind(stdoutHelper_tmpfile); + fread(contents, 1, size, stdoutHelper_tmpfile); + contents[size] = 0; + + // Close and remove the file and return its contents + fclose(stdoutHelper_tmpfile); + remove(".test-helper-stdout"); + return contents; +} \ No newline at end of file From 5e019e566af85ef12482163cc864c3466dbe10b6 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 24 May 2021 14:35:37 -0600 Subject: [PATCH 109/129] Better error/edge case handling for stdout error helper --- centrallix/tests/helpers/stdoutHelper.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/centrallix/tests/helpers/stdoutHelper.c b/centrallix/tests/helpers/stdoutHelper.c index 377b40e4d..2d295dd9a 100644 --- a/centrallix/tests/helpers/stdoutHelper.c +++ b/centrallix/tests/helpers/stdoutHelper.c @@ -24,12 +24,15 @@ stdoutHelper_stopCaptureAndGetContents() close(stdoutHelper_stdoutCopy); // Read the contents of the file with stdout contents + char* contents = ""; fseek(stdoutHelper_tmpfile, 0, SEEK_END); long size = ftell(stdoutHelper_tmpfile); - char *contents = malloc(size + 1); - rewind(stdoutHelper_tmpfile); - fread(contents, 1, size, stdoutHelper_tmpfile); - contents[size] = 0; + if (size > 0) { + contents = malloc(size + 1); + rewind(stdoutHelper_tmpfile); + fread(contents, 1, size, stdoutHelper_tmpfile); + contents[size] = 0; + } // Close and remove the file and return its contents fclose(stdoutHelper_tmpfile); From a5420a0b143526274c445ca294dbd66465964e70 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 24 May 2021 14:39:07 -0600 Subject: [PATCH 110/129] Better test helper doc strings --- centrallix/include/testhelpers/mssErrorHelper.h | 7 ++++++- centrallix/include/testhelpers/stdoutHelper.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/centrallix/include/testhelpers/mssErrorHelper.h b/centrallix/include/testhelpers/mssErrorHelper.h index 6e4abb208..54a93c8f1 100644 --- a/centrallix/include/testhelpers/mssErrorHelper.h +++ b/centrallix/include/testhelpers/mssErrorHelper.h @@ -1,8 +1,13 @@ #ifndef _MSS_ERROR_HELPER_H #define _MSS_ERROR_HELPER_H -/** doc string */ +/** Authenticates with Centrallix so errors are captured */ int mssErrorHelper_init(); + +/** + * Returns 1 if the most recent call to mssError contains the string in "message", 0 otherwise. + * You must call mssErrorHelper_init() first so calls to mssError are captured. + */ int mssErrorHelper_mostRecentErrorContains(char *message); #endif /* not defined _MSS_ERROR_HELPER_H */ \ No newline at end of file diff --git a/centrallix/include/testhelpers/stdoutHelper.h b/centrallix/include/testhelpers/stdoutHelper.h index b3e869291..15a9812bd 100644 --- a/centrallix/include/testhelpers/stdoutHelper.h +++ b/centrallix/include/testhelpers/stdoutHelper.h @@ -4,7 +4,7 @@ /** Begin redirecting and capturing stdout output. It will no longer output to the terminal (or wherever else you have it going) */ int stdoutHelper_startCapture(); -/** Stop redirecting stdout and return the redirected contents that were captured */ +/** Stop redirecting stdout and return the redirected contents that were captured. You must call stdoutHelper_startCapture() first */ char* stdoutHelper_stopCaptureAndGetContents(); #endif /* not defined _STDOUT_HELPER_H */ \ No newline at end of file From adca88df699c0f0da396e364522d91e903985a83 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 24 May 2021 14:54:33 -0600 Subject: [PATCH 111/129] Test for moneytype changes in exp_internal_DumpExpression_r --- .../test_moneytype_expDumpExpression_00.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 centrallix/tests/test_moneytype_expDumpExpression_00.c diff --git a/centrallix/tests/test_moneytype_expDumpExpression_00.c b/centrallix/tests/test_moneytype_expDumpExpression_00.c new file mode 100644 index 000000000..b92317e57 --- /dev/null +++ b/centrallix/tests/test_moneytype_expDumpExpression_00.c @@ -0,0 +1,29 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" +#include "testhelpers/stdoutHelper.h" + +long long +test(char** name) +{ + *name = "moneytype_00 - expDumpExpression"; + + pExpression testExp = expAllocExpression(); + ObjData moneyData; + MoneyType money = {70000}; + moneyData.Money = &money; + pObjData moneyDataPtr = &moneyData; + + testExp = expPodToExpression(moneyDataPtr, 7, testExp); + + stdoutHelper_startCapture(); + expDumpExpression(testExp); + char* stdoutContents = stdoutHelper_stopCaptureAndGetContents(); + assert(strstr(stdoutContents, "MONEY = 70000, 0 child(ren), money=$7.00, NEW")); + + expFreeExpression(testExp); + + return 0; +} From d2149f9ec6ae75a81f8288339101a7c87d3923e2 Mon Sep 17 00:00:00 2001 From: sheesania Date: Tue, 25 May 2021 14:13:28 -0600 Subject: [PATCH 112/129] Test comparing MoneyType expressions --- ...est_moneytype_expCompareExpressionValues.c | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 centrallix/tests/test_moneytype_expCompareExpressionValues.c diff --git a/centrallix/tests/test_moneytype_expCompareExpressionValues.c b/centrallix/tests/test_moneytype_expCompareExpressionValues.c new file mode 100644 index 000000000..82430b465 --- /dev/null +++ b/centrallix/tests/test_moneytype_expCompareExpressionValues.c @@ -0,0 +1,35 @@ +#include "obj.h" +#include +#include +#include "expression.h" + +long long +test(char** name) +{ + *name = "moneytype_00 - expCompareExpressionValues"; + + pExpression exp1 = expAllocExpression(); + ObjData moneyData1; + MoneyType money1 = {70000}; + moneyData1.Money = &money1; + exp1 = expPodToExpression(&moneyData1, DATA_T_MONEY, exp1); + + pExpression exp2 = expAllocExpression(); + ObjData moneyData2; + MoneyType money2 = {70000}; + moneyData2.Money = &money2; + exp2 = expPodToExpression(&moneyData2, DATA_T_MONEY, exp2); + + // true case (exp1 == exp2) + assert(expCompareExpressionValues(exp1, exp2) == 1); + + // false case (exp1 != exp2) + money2.Value = 8000; + exp2 = expPodToExpression(&moneyData2, DATA_T_MONEY, exp2); + assert(expCompareExpressionValues(exp1, exp2) == 0); + + expFreeExpression(exp1); + expFreeExpression(exp2); + + return 0; +} From 9eea4371a8a0800c8d8e8d73e5b2baf4272fe8b3 Mon Sep 17 00:00:00 2001 From: sheesania Date: Fri, 28 May 2021 14:46:00 -0600 Subject: [PATCH 113/129] Move conversion to old money representation for JSON into separate function to enable test. However, even though most of the business logic is being tested now, nht_i_RestWriteAttrValue (or public callers) still is not tested at all. It would be trivially easy to test with mocks/stubs, but is quite complex to test otherwise, and so I judged that it wasn't worth it to spend a lot of time writing a complete test right now when we might be implementing a test framework with mocks/stubs relatively soon. Please, future me, save us from the screaming void. --- centrallix/netdrivers/net_http_rest.c | 39 ++++++------------- centrallix/objectsystem/obj_datatypes.c | 25 ++++++++++++ ...moneytype_objGetOldRepresentationOfMoney.c | 34 ++++++++++++++++ 3 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 centrallix/tests/test_moneytype_objGetOldRepresentationOfMoney.c diff --git a/centrallix/netdrivers/net_http_rest.c b/centrallix/netdrivers/net_http_rest.c index 42a255367..418a1da4e 100644 --- a/centrallix/netdrivers/net_http_rest.c +++ b/centrallix/netdrivers/net_http_rest.c @@ -76,9 +76,10 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty { ObjData od; int rval; - long long whole, fraction; + long long whole; + unsigned short fraction; - /** Get the data value **/ + /** Get the data value **/ rval = objGetAttrValue(obj, attrname, data_type, &od); if (rval != 0) { @@ -114,32 +115,14 @@ nht_i_RestWriteAttrValue(pNhtConn conn, pObject obj, char* attrname, int data_ty ); break; - case DATA_T_MONEY: - /** For the time being, 64-bit representation will mimic whole and fraction part handling of negatives - ** with regards to JSON data. It will use the new %LL specifier, but the JSON returned will - ** contain an inverted fraction part that always counts in the positive direction. - **/ - - /** If there is a negative with a non-zero fraction part **/ - if (od.Money->Value < 0 && od.Money->Value%10000 != 0) - { - /** Add negative 1 then truncate fraction. (essentially floor() )**/ - whole = (od.Money->Value - 10000)/10000ll; - /** Since fraction always counts away from zero, it is inverted**/ - fraction = 10000ll - abs(od.Money->Value%10000); - nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%LL, \"fractionpart\":%LL }", - whole, - fraction - ); - } - else - { - nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%LL, \"fractionpart\":%LL }", - od.Money->Value/10000ll, - od.Money->Value%10000ll - ); - } - break; + case DATA_T_MONEY: + /** For the time being, 64-bit representation will mimic whole and fraction part handling of negatives + ** with regards to JSON data. It will use the new %LL specifier, but the JSON returned will + ** contain an inverted fraction part that always counts in the positive direction. + **/ + objGetOldRepresentationOfMoney(*(od.Money), &whole, &fraction); + nht_i_QPrintfConn(conn, 0, "{ \"wholepart\":%LL, \"fractionpart\":%INT }", whole, fraction); + break; default: /** Unknown or unimplemented data type **/ diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 7ceecbaba..c0f2bb86c 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -2472,3 +2472,28 @@ objDateAdd(pDateTime dt, int diff_sec, int diff_min, int diff_hr, int diff_day, return 0; } + +/*** Convert the given MoneyType into the old representation with separate + *** whole/fraction parts, then put it into the given pointer parameters. + ***/ +void +objGetOldRepresentationOfMoney(MoneyType money, long long* wholePart, unsigned short* fractionPart) +{ + /** + * In the old representation, whole = floor($amount) and fraction = $amount - floor($amount). This means that + * fraction is always positive and always counts towards the total $amount in a positive direction. + * So if there is a negative with a non-zero fraction part... + **/ + if (money.Value < 0 && money.Value%10000 != 0) + { + /** Add negative 1 then truncate fraction. (essentially floor() )**/ + *wholePart = (money.Value - 10000)/10000ll; + /** Since fraction always counts away from zero, it is inverted**/ + *fractionPart = 10000ll - abs(money.Value%10000); + } + else + { + *wholePart = money.Value / 10000ll; + *fractionPart = money.Value % 10000ll; + } +} \ No newline at end of file diff --git a/centrallix/tests/test_moneytype_objGetOldRepresentationOfMoney.c b/centrallix/tests/test_moneytype_objGetOldRepresentationOfMoney.c new file mode 100644 index 000000000..55db44e57 --- /dev/null +++ b/centrallix/tests/test_moneytype_objGetOldRepresentationOfMoney.c @@ -0,0 +1,34 @@ +#include "obj.h" +#include + +long long +test(char** name) +{ + *name = "moneytype_00 - objGetOldRepresentationOfMoney"; + + /* Positive case */ + MoneyType money = {75000}; + long long wholePart = 0; + unsigned short fractionPart = 0; + objGetOldRepresentationOfMoney(money, &wholePart, &fractionPart); + assert(wholePart == 7); + assert(fractionPart == 5000); + + /* Negative with non-zero fraction part */ + money.Value = -75000; + wholePart = 0; + fractionPart = 0; + objGetOldRepresentationOfMoney(money, &wholePart, &fractionPart); + assert(wholePart == -8); + assert(fractionPart == 5000); + + /* Handles money.Value larger than INT_MAX */ + money.Value = 250000000000005000; + wholePart = 0; + fractionPart = 0; + objGetOldRepresentationOfMoney(money, &wholePart, &fractionPart); + assert(wholePart == 25000000000000); + assert(fractionPart == 5000); + + return 0; +} From 5b87af45963d1e8e77095c50933beb527e68fc5d Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 2 Jun 2021 15:16:01 -0600 Subject: [PATCH 114/129] Fix dbl_internal_ParseColumn for MoneyType + test --- centrallix/osdrivers/objdrv_dbl.c | 24 +++++---- centrallix/tests/test_moneytype_objdrv_dbl.c | 52 ++++++++++++++++++++ 2 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 centrallix/tests/test_moneytype_objdrv_dbl.c diff --git a/centrallix/osdrivers/objdrv_dbl.c b/centrallix/osdrivers/objdrv_dbl.c index be6437cee..8d5e25adf 100755 --- a/centrallix/osdrivers/objdrv_dbl.c +++ b/centrallix/osdrivers/objdrv_dbl.c @@ -1627,6 +1627,7 @@ dbl_internal_ParseColumn(pDblColInf column, pObjData pod, char* data, char* row_ char dtbuf[32]; unsigned long long v; int i,f; + double decimalOffsetValue = 10000; switch(column->Type) { @@ -1649,19 +1650,16 @@ dbl_internal_ParseColumn(pDblColInf column, pObjData pod, char* data, char* row_ if (column->DecimalOffset) pod->Double /= pow(10, column->DecimalOffset); break; case DATA_T_MONEY: - if (dbl_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; - v = strtoll(ibuf, NULL, 10); - f = 1; - for(i=0;iDecimalOffset;i++) f *= 10; - pod->Money = (pMoneyType)data; - pod->Money->Value = (v/f) * 10000; - v = (v/f)*f; - if (column->DecimalOffset <= 4) - for(i=column->DecimalOffset;i<4;i++) v *= 10; - else - for(i=4;iDecimalOffset;i++) v /= 10; - pod->Money->Value += v; - break; + //decimalOffsetValue is originally 10000 to convert v to 10000ths of a dollar + //decimalOffsetValue is divided by 10, column->DecimalOffset times, + //keeping the decimal as a double in case it drops below 0 + //Finally, I multiple v by decimalOffsetValue to get my Money->Value + if (dbl_internal_MappedCopy(ibuf, sizeof(ibuf), column, row_data) < 0) return -1; + v = strtoll(ibuf, NULL, 10); + decimalOffsetValue /= pow(10, column->DecimalOffset); + pod->Money = (pMoneyType)data; + pod->Money->Value = (v*decimalOffsetValue)+ 0.1; + break; default: mssError(1, "DBL", "Bark! Unhandled data type for column '%s'", column->Name); return -1; diff --git a/centrallix/tests/test_moneytype_objdrv_dbl.c b/centrallix/tests/test_moneytype_objdrv_dbl.c new file mode 100644 index 000000000..e65d232a6 --- /dev/null +++ b/centrallix/tests/test_moneytype_objdrv_dbl.c @@ -0,0 +1,52 @@ +#include "obj.h" +#include +#include +#include "expression.h" +#include "cxlib/xstring.h" +#include "osdrivers/objdrv_dbl.c" + +long long +test(char** name) +{ + *name = "moneytype_00 - objdrv_dbl"; + + //This test is making the assumption that the raw data passed in testString here (row_data in objdrv_dbl.c) + //is in units of dollars (and so dbl_internal_ParseColumn should convert it to 1/10000ths of a dollar when putting + //it into a MoneyType representation) + + DblColInf testColInf; + pDblColInf pTestColInf = &testColInf; + testColInf.Type = DATA_T_MONEY; + testColInf.Length = 8; + unsigned short byteMap[] = {0}; + testColInf.ByteMap = byteMap; + testColInf.DecimalOffset = 0; + + ObjData moneyData; + pObjData moneyDataPtr = &moneyData; + MoneyType testMoneyData = {0}; + pMoneyType pTestMoneyData = &testMoneyData; + + /** No Decimal Offset Case **/ + char* rowData = "450"; + assert(dbl_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, rowData) == 0); + assert(moneyDataPtr->Money->Value == 4500000); + + /** Decimal Offset, multiplier > 1 case **/ + testColInf.DecimalOffset = 1; + assert(dbl_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, rowData) == 0); + assert(moneyDataPtr->Money->Value == 450000); + + /** Decimal Offset, multiplier < 1 case **/ + testColInf.DecimalOffset = 5; + assert(dbl_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, rowData) == 0); + assert(moneyDataPtr->Money->Value == 45); + + /** Rounding for floating point error handling **/ + char* testRoundedString = "45011999"; + testColInf.DecimalOffset = 5; + assert(dbl_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testRoundedString) == 0); + assert(moneyDataPtr->Money->Value == 4501200); + + return 0; +} From cb8df455f3f9bc12ae1da3c3fe7c8baa897698a8 Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 2 Jun 2021 15:23:45 -0600 Subject: [PATCH 115/129] Small fixes and cleanup of objdrv_fp MoneyType test --- ...Column_00.c => test_moneytype_objdrv_fp.c} | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) rename centrallix/tests/{test_moneytype_fp_internal_ParseColumn_00.c => test_moneytype_objdrv_fp.c} (56%) diff --git a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c b/centrallix/tests/test_moneytype_objdrv_fp.c similarity index 56% rename from centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c rename to centrallix/tests/test_moneytype_objdrv_fp.c index c840cc769..73039fb9d 100644 --- a/centrallix/tests/test_moneytype_fp_internal_ParseColumn_00.c +++ b/centrallix/tests/test_moneytype_objdrv_fp.c @@ -8,16 +8,16 @@ long long test(char** name) { - *name = "moneytype_00 - fp_internal_ParseColumn"; + *name = "moneytype_00 - objdrv_fp"; - //This Test is making the assumption that the raw data passed in testString here (row_data in objdrv_fp.c) - //is in units dollars. So, the function now converts it to 1/10000ths like the new moneyType requires. + //This test is making the assumption that the raw data passed in testString here (row_data in objdrv_fp.c) + //is in units of dollars (and so dbl_internal_ParseColumn should convert it to 1/10000ths of a dollar when putting + //it into a MoneyType representation) - FpColInf testColInf = {0}; + FpColInf testColInf; pFpColInf pTestColInf = &testColInf; - //7 for money type - testColInf.Type = 7; + testColInf.Type = DATA_T_MONEY; testColInf.Length = 8; testColInf.RecordOffset = 0; testColInf.DecimalOffset = 0; @@ -27,30 +27,25 @@ test(char** name) pMoneyType pTestMoneyData = &testMoneyData; /** No Decimal Offset Case **/ - //Raw data for row data. - char* testString = "450"; - assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); - + char* rowData = "450"; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, rowData) == 0); assert(moneyDataPtr->Money->Value == 4500000); - /** Decimal Offset, Value > 1 Case **/ - //Value will be greater than one after dividing by - //10 a DecimalOffset # of times + /** Decimal Offset, multiplier > 1 case **/ testColInf.DecimalOffset = 1; - assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, rowData) == 0); assert(moneyDataPtr->Money->Value == 450000); - /** Decimal Offset, Value < 1 Case **/ - testColInf.DecimalOffset = 3; - assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testString) == 0); - assert(moneyDataPtr->Money->Value == 4500); + /** Decimal Offset, multiplier < 1 case **/ + testColInf.DecimalOffset = 5; + assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, rowData) == 0); + assert(moneyDataPtr->Money->Value == 45); - //This function now rounds properly with the addition of adding .1 for floating point error handling + /** Rounding for floating point error handling **/ char* testRoundedString = "45011999"; testColInf.DecimalOffset = 5; assert(fp_internal_ParseColumn(pTestColInf, moneyDataPtr, (char*)pTestMoneyData, testRoundedString) == 0); assert(moneyDataPtr->Money->Value == 4501200); - - + return 0; } From dea8823f9336b06b4746aed7277081e07519dbce Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 16 Jun 2021 13:03:00 -0600 Subject: [PATCH 116/129] Test for json > MoneyType parsing --- centrallix/tests/test_moneytype_json_util.c | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 centrallix/tests/test_moneytype_json_util.c diff --git a/centrallix/tests/test_moneytype_json_util.c b/centrallix/tests/test_moneytype_json_util.c new file mode 100644 index 000000000..857d23518 --- /dev/null +++ b/centrallix/tests/test_moneytype_json_util.c @@ -0,0 +1,37 @@ +#include "obj.h" +#include +#include +#include "json/json_util.h" + +long long +test(char** name) +{ + *name = "moneytype_00 - json_util"; + + // Positive + json_object *json = json_tokener_parse("{\"wholepart\": 7, \"fractionpart\": 5000}"); + MoneyType money = {0}; + assert(jutilGetMoneyObject(json, &money) == 0); + assert(money.Value == 75000); + + // Negative + json = json_tokener_parse("{\"wholepart\": -8, \"fractionpart\": 5000}"); + assert(jutilGetMoneyObject(json, &money) == 0); + assert(money.Value == -75000); + + // wholepart / fractionpart in different order + json = json_tokener_parse("{\"fractionpart\": 5000, \"wholepart\": 7}"); + assert(jutilGetMoneyObject(json, &money) == 0); + assert(money.Value == 75000); + + // Value > INT_MAX + json = json_tokener_parse("{\"wholepart\": 220000000, \"fractionpart\": 5000}"); + assert(jutilGetMoneyObject(json, &money) == 0); + assert(money.Value == 2200000005000ll); + + // Json objects with other attributes are not accepted + json = json_tokener_parse("{\"wholepart\": 7, \"fractionpart\": 5000, \"nope\": 0}"); + assert(jutilGetMoneyObject(json, &money) == -1); + + return 0; +} From e8ec84d66dc7309bfb049cecf8b2997ac5211231 Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 16 Jun 2021 14:52:52 -0600 Subject: [PATCH 117/129] Tests for MoneyType round expressions --- centrallix/tests/test_expfn_round_money.cmp | 6 ++++++ centrallix/tests/test_expfn_round_money.to | 8 ++++++++ 2 files changed, 14 insertions(+) create mode 100644 centrallix/tests/test_expfn_round_money.cmp create mode 100644 centrallix/tests/test_expfn_round_money.to diff --git a/centrallix/tests/test_expfn_round_money.cmp b/centrallix/tests/test_expfn_round_money.cmp new file mode 100644 index 000000000..f1f98f235 --- /dev/null +++ b/centrallix/tests/test_expfn_round_money.cmp @@ -0,0 +1,6 @@ +Attribute [round($1.225, 2)]: money $1.23 +Attribute [round($1.224, 2)]: money $1.22 +Attribute [round($1.50, 0)]: money $2.00 +Attribute [round($1.40, 0)]: money $1.00 +Attribute [round($16.25, -1)]: money $20.00 +Attribute [round($12.25, -1)]: money $10.00 diff --git a/centrallix/tests/test_expfn_round_money.to b/centrallix/tests/test_expfn_round_money.to new file mode 100644 index 000000000..3ad5508f0 --- /dev/null +++ b/centrallix/tests/test_expfn_round_money.to @@ -0,0 +1,8 @@ +##NAME round() function on money type + +query select 'round($1.225, 2)' = round($1.225, 2) +query select 'round($1.224, 2)' = round($1.224, 2) +query select 'round($1.50, 0)' = round($1.50, 0) +query select 'round($1.40, 0)' = round($1.40, 0) +query select 'round($16.25, -1)' = round($16.25, -1) +query select 'round($12.25, -1)' = round($12.25, -1) \ No newline at end of file From ad91c3b8fd19f1aa6ab3a17a90530b717d2fcb80 Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 16 Jun 2021 14:55:13 -0600 Subject: [PATCH 118/129] Test MoneyType round behavior with no decimal places parameter --- centrallix/tests/test_expfn_round_money.cmp | 1 + centrallix/tests/test_expfn_round_money.to | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/centrallix/tests/test_expfn_round_money.cmp b/centrallix/tests/test_expfn_round_money.cmp index f1f98f235..557029d0c 100644 --- a/centrallix/tests/test_expfn_round_money.cmp +++ b/centrallix/tests/test_expfn_round_money.cmp @@ -4,3 +4,4 @@ Attribute [round($1.50, 0)]: money $2.00 Attribute [round($1.40, 0)]: money $1.00 Attribute [round($16.25, -1)]: money $20.00 Attribute [round($12.25, -1)]: money $10.00 +Attribute [round($12.25)]: money $12.00 diff --git a/centrallix/tests/test_expfn_round_money.to b/centrallix/tests/test_expfn_round_money.to index 3ad5508f0..a468451ab 100644 --- a/centrallix/tests/test_expfn_round_money.to +++ b/centrallix/tests/test_expfn_round_money.to @@ -5,4 +5,5 @@ query select 'round($1.224, 2)' = round($1.224, 2) query select 'round($1.50, 0)' = round($1.50, 0) query select 'round($1.40, 0)' = round($1.40, 0) query select 'round($16.25, -1)' = round($16.25, -1) -query select 'round($12.25, -1)' = round($12.25, -1) \ No newline at end of file +query select 'round($12.25, -1)' = round($12.25, -1) +query select 'round($12.25)' = round($12.25) \ No newline at end of file From e936ff35d4a0b4de2ba78a3c096f0c4a037a04a2 Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 16 Jun 2021 14:58:12 -0600 Subject: [PATCH 119/129] Tests for MoneyType truncate expressions --- centrallix/tests/test_expfn_truncate_money.cmp | 7 +++++++ centrallix/tests/test_expfn_truncate_money.to | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 centrallix/tests/test_expfn_truncate_money.cmp create mode 100644 centrallix/tests/test_expfn_truncate_money.to diff --git a/centrallix/tests/test_expfn_truncate_money.cmp b/centrallix/tests/test_expfn_truncate_money.cmp new file mode 100644 index 000000000..7d91a7200 --- /dev/null +++ b/centrallix/tests/test_expfn_truncate_money.cmp @@ -0,0 +1,7 @@ +Attribute [truncate($1.225, 2)]: money $1.22 +Attribute [truncate($1.224, 2)]: money $1.22 +Attribute [truncate($1.50, 0)]: money $1.00 +Attribute [truncate($1.40, 0)]: money $1.00 +Attribute [truncate($16.25, -1)]: money $10.00 +Attribute [truncate($12.25, -1)]: money $10.00 +Attribute [truncate($12.25)]: money $12.00 diff --git a/centrallix/tests/test_expfn_truncate_money.to b/centrallix/tests/test_expfn_truncate_money.to new file mode 100644 index 000000000..9e582803c --- /dev/null +++ b/centrallix/tests/test_expfn_truncate_money.to @@ -0,0 +1,9 @@ +##NAME truncate() function on money type + +query select 'truncate($1.225, 2)' = truncate($1.225, 2) +query select 'truncate($1.224, 2)' = truncate($1.224, 2) +query select 'truncate($1.50, 0)' = truncate($1.50, 0) +query select 'truncate($1.40, 0)' = truncate($1.40, 0) +query select 'truncate($16.25, -1)' = truncate($16.25, -1) +query select 'truncate($12.25, -1)' = truncate($12.25, -1) +query select 'truncate($12.25)' = truncate($12.25) \ No newline at end of file From c64cf6e0ac44db2db8e9ff12adbf2dcb27177663 Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 16 Jun 2021 15:16:34 -0600 Subject: [PATCH 120/129] Tests for MoneyType max expression --- centrallix/tests/test_expfn_max_money.cmp | 1 + centrallix/tests/test_expfn_max_money.to | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 centrallix/tests/test_expfn_max_money.cmp create mode 100644 centrallix/tests/test_expfn_max_money.to diff --git a/centrallix/tests/test_expfn_max_money.cmp b/centrallix/tests/test_expfn_max_money.cmp new file mode 100644 index 000000000..de207dca4 --- /dev/null +++ b/centrallix/tests/test_expfn_max_money.cmp @@ -0,0 +1 @@ +Attribute [max(:f_money)]: money $2147483647.99 diff --git a/centrallix/tests/test_expfn_max_money.to b/centrallix/tests/test_expfn_max_money.to new file mode 100644 index 000000000..f3222b935 --- /dev/null +++ b/centrallix/tests/test_expfn_max_money.to @@ -0,0 +1,3 @@ +##NAME max() function on money type + +query select 'max(:f_money)' = max(:f_money) from /tests/Datatypes.csv/rows From 79888de11a0276ce67ac3f0c222143c17d963305 Mon Sep 17 00:00:00 2001 From: sheesania Date: Wed, 16 Jun 2021 15:18:25 -0600 Subject: [PATCH 121/129] Tests for MoneyType min expressions --- centrallix/tests/test_expfn_min_money.cmp | 1 + centrallix/tests/test_expfn_min_money.to | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 centrallix/tests/test_expfn_min_money.cmp create mode 100644 centrallix/tests/test_expfn_min_money.to diff --git a/centrallix/tests/test_expfn_min_money.cmp b/centrallix/tests/test_expfn_min_money.cmp new file mode 100644 index 000000000..52cfa9c0c --- /dev/null +++ b/centrallix/tests/test_expfn_min_money.cmp @@ -0,0 +1 @@ +Attribute [min(:f_money)]: money -$2147483647.99 diff --git a/centrallix/tests/test_expfn_min_money.to b/centrallix/tests/test_expfn_min_money.to new file mode 100644 index 000000000..e131c83e0 --- /dev/null +++ b/centrallix/tests/test_expfn_min_money.to @@ -0,0 +1,3 @@ +##NAME min() function on money type + +query select 'min(:f_money)' = min(:f_money) from /tests/Datatypes.csv/rows From 86f2f82f2072ced9b0e4274134c5b38b89bbcd1b Mon Sep 17 00:00:00 2001 From: sheesania Date: Tue, 13 Jul 2021 14:01:49 -0600 Subject: [PATCH 122/129] Basic framework for Sybase -> MoneyType test --- centrallix/Makefile.in | 2 +- .../tests/test_moneytype_objdrv_sybase.c | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 centrallix/tests/test_moneytype_objdrv_sybase.c diff --git a/centrallix/Makefile.in b/centrallix/Makefile.in index 173c06206..2bbb74912 100644 --- a/centrallix/Makefile.in +++ b/centrallix/Makefile.in @@ -532,7 +532,7 @@ tests/t_driver.o: tests/t_driver.c $(CC) $(CFLAGS) $< -c -o $@ tests/test_%.bin: tests/test_%.o tests/t_driver.o centrallix.o $(V3LSOBJS) $(STATIC_LIBS) $(TESTHELPERS) - $(CC) $< tests/t_driver.o centrallix.o $(V3LSOBJS) $(TESTHELPERS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o $@ $(LIBS) @NCURSES_LIBS@ + $(CC) $< tests/t_driver.o centrallix.o $(V3LSOBJS) $(TESTHELPERS) $(LIBDIRS) $(PROFILE) $(COVERAGE) -Wl@EXPORT_DYNAMIC@ -o $@ $(LIBS) @NCURSES_LIBS@ @SYBASE_LIBS@ test: tests/centrallix.conf-test $(TOTESTDEPS) $(TOTESTFILES) $(CBTESTFILES) @printf "%-62.62s %s\n" "Test Name" "Stat" diff --git a/centrallix/tests/test_moneytype_objdrv_sybase.c b/centrallix/tests/test_moneytype_objdrv_sybase.c new file mode 100644 index 000000000..88ab06723 --- /dev/null +++ b/centrallix/tests/test_moneytype_objdrv_sybase.c @@ -0,0 +1,34 @@ +#include "config.h" +#ifdef USE_SYBASE +#include "obj.h" +#include +#include "osdrivers/objdrv_sybase.c" +#endif + +long long +test(char** name) +{ + *name = "moneytype_00 - objdrv_sybase"; + + #ifdef USE_SYBASE + MoneyType moneyResult; + ObjData objDataResult; + objDataResult.Money = &moneyResult; + + /** smallmoney **/ + int smallMoneyType = 21; + int smallMoneyToConvert = 45000; + assert(sybd_internal_GetCxValue(&smallMoneyToConvert, smallMoneyType, &objDataResult, DATA_T_MONEY) == 0); + assert(objDataResult.Money->Value == 45000); + + /** positive 8-byte money **/ + + /** negative 8-byte money (in two's complement!) **/ + + /** explicit test of bit shifting? 0x44447777 or something **/ + + return 0; + #else + return 1; + #endif +} From 5a528cd986f878669d15a8e1c8d856497dba18e7 Mon Sep 17 00:00:00 2001 From: sheesania Date: Tue, 13 Jul 2021 15:35:51 -0600 Subject: [PATCH 123/129] Tests for getting MoneyType from objdrv_sybase + simplification of objdrv_sybase logic --- centrallix/osdrivers/objdrv_sybase.c | 14 ++------ .../tests/test_moneytype_objdrv_sybase.c | 34 ++++++++++++------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index f20167f2b..80f59e8e7 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -784,22 +784,12 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) /** normal 8-byte money **/ memcpy(&lsl, ptr+4, 4); memcpy(&msl, ptr, 4); - minus = 0; - if (msl >= 0x80000000) - { - /** Negate **/ - minus = 1; - msl = ~msl; - lsl = ~lsl; - if (lsl == 0xFFFFFFFF) msl++; - lsl++; - } + /** msl is the most significant 32-bit value and needs to come before lsl ** I do this by shifting msl left cast to a long long by 32 bits, and then OR it with lsl **/ val->Money->Value = (((long long)msl)<<32) | (long long)lsl; - if (minus) - val->Money->Value = -val->Money->Value; + return 0; } } diff --git a/centrallix/tests/test_moneytype_objdrv_sybase.c b/centrallix/tests/test_moneytype_objdrv_sybase.c index 88ab06723..dbe6d70c1 100644 --- a/centrallix/tests/test_moneytype_objdrv_sybase.c +++ b/centrallix/tests/test_moneytype_objdrv_sybase.c @@ -11,24 +11,32 @@ test(char** name) *name = "moneytype_00 - objdrv_sybase"; #ifdef USE_SYBASE - MoneyType moneyResult; - ObjData objDataResult; - objDataResult.Money = &moneyResult; + MoneyType moneyResult; + ObjData objDataResult; + objDataResult.Money = &moneyResult; - /** smallmoney **/ - int smallMoneyType = 21; - int smallMoneyToConvert = 45000; - assert(sybd_internal_GetCxValue(&smallMoneyToConvert, smallMoneyType, &objDataResult, DATA_T_MONEY) == 0); - assert(objDataResult.Money->Value == 45000); + /** smallmoney **/ + int smallMoneyType = 21; + int smallMoneyToConvert = 45000; + assert(sybd_internal_GetCxValue(&smallMoneyToConvert, smallMoneyType, &objDataResult, DATA_T_MONEY) == 0); + assert(objDataResult.Money->Value == 45000); - /** positive 8-byte money **/ + /** 8-byte money **/ + int eightByteMoneyType = 11; + //Sybase 8 byte money is mixed endian: 0 = least significant bit, f = most significant bit + unsigned long long moneyToConvert = 0x76543210fedcba98; + assert(sybd_internal_GetCxValue(&moneyToConvert, eightByteMoneyType, &objDataResult, DATA_T_MONEY) == 0); + //mixed-endianness should be fixed now + assert(objDataResult.Money->Value == 0xfedcba9876543210); - /** negative 8-byte money (in two's complement!) **/ + /** confirm positive 8-byte money works as well **/ + moneyToConvert = 0xfedcba9876543210; + assert(sybd_internal_GetCxValue(&moneyToConvert, eightByteMoneyType, &objDataResult, DATA_T_MONEY) == 0); + assert(objDataResult.Money->Value == 0x76543210fedcba98); - /** explicit test of bit shifting? 0x44447777 or something **/ + return 0; - return 0; #else - return 1; + return 1; #endif } From c05cc67166cd7e54691a57093c623c8fc739a615 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 19 Jul 2021 13:42:35 -0600 Subject: [PATCH 124/129] Fix and test int overflow when printing money type > INT_MAX --- centrallix/objectsystem/obj_datatypes.c | 10 +++++----- centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index c0f2bb86c..5850e97f7 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -426,15 +426,15 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) char* fmt; char* ptr; int n_whole_digits = 0; - int print_whole; + long long print_whole; int print_fract; int in_decimal_part = 0; int suppressing_zeros = 1; int automatic_sign = 1; int tens_multiplier = 1; - int d; + long long d; char* start_fmt; - int orig_print_whole; + long long orig_print_whole; char tmp[20]; XString xs; /*int intl_format = 0;*/ @@ -544,7 +544,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) } else { - sprintf(tmp,"%d",d); + sprintf(tmp,"%lld",d); xsConcatenate(&xs,tmp,-1); } break; @@ -567,7 +567,7 @@ obj_internal_FormatMoney(pMoneyType m, char* str, char* format, int length) case '.': if (print_whole != 0) { - sprintf(tmp,"%d",print_whole); + sprintf(tmp,"%lld",print_whole); xsConcatenate(&xs,tmp,1); } in_decimal_part = 1; diff --git a/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c b/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c index be42ee3f7..d8d1da6d5 100644 --- a/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c +++ b/centrallix/tests/test_moneytype_objFormatMoneyTmp_00.c @@ -25,6 +25,10 @@ test(char** name) /** Fractional Cent Case **/ test.Value = -70001; assert(strcmp(objFormatMoneyTmp(&test, NULL), "-$7.00") == 0); + + /** Whole Part > INT_MAX **/ + test.Value = 1836475854449306500; + assert(strcmp(objFormatMoneyTmp(&test, NULL), "$183647585444930.65") == 0); return 0; } From a7b6b80c3d5459b56b42d73d2c13a3f96dd643a1 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 19 Jul 2021 14:25:48 -0600 Subject: [PATCH 125/129] Test for expDumpExpression with money > INT_MAX --- centrallix/tests/test_moneytype_expDumpExpression_00.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/centrallix/tests/test_moneytype_expDumpExpression_00.c b/centrallix/tests/test_moneytype_expDumpExpression_00.c index b92317e57..7266b8f20 100644 --- a/centrallix/tests/test_moneytype_expDumpExpression_00.c +++ b/centrallix/tests/test_moneytype_expDumpExpression_00.c @@ -16,13 +16,21 @@ test(char** name) moneyData.Money = &money; pObjData moneyDataPtr = &moneyData; - testExp = expPodToExpression(moneyDataPtr, 7, testExp); + testExp = expPodToExpression(moneyDataPtr, DATA_T_MONEY, testExp); stdoutHelper_startCapture(); expDumpExpression(testExp); char* stdoutContents = stdoutHelper_stopCaptureAndGetContents(); assert(strstr(stdoutContents, "MONEY = 70000, 0 child(ren), money=$7.00, NEW")); + /** Money > INT_MAX **/ + money.Value = 18888888888888888; + testExp = expPodToExpression(moneyDataPtr, DATA_T_MONEY, testExp); + stdoutHelper_startCapture(); + expDumpExpression(testExp); + stdoutContents = stdoutHelper_stopCaptureAndGetContents(); + assert(strstr(stdoutContents, "MONEY = 18888888888888888, 0 child(ren), money=$1888888888888.88, NEW")); + expFreeExpression(testExp); return 0; From 52aad43b1dcca27899c99a76bcabcbc4180c9196 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 19 Jul 2021 14:29:36 -0600 Subject: [PATCH 126/129] Test for objBuildBinaryImage with money > INT_MAX --- .../test_moneytype_objBuildBinaryImage_00.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/centrallix/tests/test_moneytype_objBuildBinaryImage_00.c b/centrallix/tests/test_moneytype_objBuildBinaryImage_00.c index 27e658148..dbf0e2c97 100644 --- a/centrallix/tests/test_moneytype_objBuildBinaryImage_00.c +++ b/centrallix/tests/test_moneytype_objBuildBinaryImage_00.c @@ -36,8 +36,8 @@ test(char** name) pObjData moneyDataPtrCmp = &moneyDataCmp; /** Positive Case **/ - testExp = expPodToExpression(moneyDataPtr, 7, testExp); - testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); + testExp = expPodToExpression(moneyDataPtr, DATA_T_MONEY, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, DATA_T_MONEY, testExpCmp); objBuildBinaryImage(buf, buflen, &testExp, 1, testParamObjects, 0); objBuildBinaryImage(cmpBuf, buflen, &testExpCmp, 1, testParamObjects, 0); assert(memcmp(buf,cmpBuf,8) > 0); @@ -45,11 +45,20 @@ test(char** name) /** Negative Case **/ money.Value = -70000; moneyCmp.Value = -65000; - testExp = expPodToExpression(moneyDataPtr, 7, testExp); - testExpCmp = expPodToExpression(moneyDataPtrCmp, 7, testExpCmp); + testExp = expPodToExpression(moneyDataPtr, DATA_T_MONEY, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, DATA_T_MONEY, testExpCmp); objBuildBinaryImage(buf, buflen, &testExp, 1, testParamObjects, 0); objBuildBinaryImage(cmpBuf, buflen, &testExpCmp, 1, testParamObjects, 0); assert(memcmp(buf,cmpBuf,8) < 0); + + /** Money > INT_MAX Case **/ + money.Value = 18888888888888888; + moneyCmp.Value = 17777777777777777; + testExp = expPodToExpression(moneyDataPtr, DATA_T_MONEY, testExp); + testExpCmp = expPodToExpression(moneyDataPtrCmp, DATA_T_MONEY, testExpCmp); + objBuildBinaryImage(buf, buflen, &testExp, 1, testParamObjects, 0); + objBuildBinaryImage(cmpBuf, buflen, &testExpCmp, 1, testParamObjects, 0); + assert(memcmp(buf,cmpBuf,8) > 0); expFreeExpression(testExp); expFreeExpression(testExpCmp); From ff310de02a8644809316485566adcffd0e937b85 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 19 Jul 2021 14:45:32 -0600 Subject: [PATCH 127/129] Add test for potential int overflow in objDataCompare for money + small fixes to make test clearer --- .../tests/test_moneytype_objDataCompare_00.c | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/centrallix/tests/test_moneytype_objDataCompare_00.c b/centrallix/tests/test_moneytype_objDataCompare_00.c index 524c74a44..8f70a1ee8 100644 --- a/centrallix/tests/test_moneytype_objDataCompare_00.c +++ b/centrallix/tests/test_moneytype_objDataCompare_00.c @@ -12,55 +12,58 @@ test(char** name) /** Compare Int with Money Case **/ /** Greater Than **/ int testInt = 8; - assert(objDataCompare(1,&testInt,7,&test) == 1); + assert(objDataCompare(DATA_T_INTEGER, &testInt, DATA_T_MONEY, &test) == 1); /** Less Than **/ testInt = 6; - assert(objDataCompare(1,&testInt,7,&test) == -1); + assert(objDataCompare(DATA_T_INTEGER, &testInt, DATA_T_MONEY, &test) == -1); /** Equal To **/ testInt = 7; - assert(objDataCompare(1,&testInt,7,&test) == 0); + assert(objDataCompare(DATA_T_INTEGER, &testInt, DATA_T_MONEY, &test) == 0); + /** Int multiplied to be > INT_MAX **/ + testInt = 2147483647; + assert(objDataCompare(DATA_T_INTEGER, &testInt, DATA_T_MONEY, &test) == 1); /** Compare Double with Money Case **/ /** Greater Than **/ double testDouble = 7.5; - assert(objDataCompare(3,&testDouble,7,&test) == 1); + assert(objDataCompare(DATA_T_DOUBLE, &testDouble, DATA_T_MONEY, &test) == 1); /** Less Than **/ testDouble = 5.5; - assert(objDataCompare(3,&testDouble,7,&test) == -1); + assert(objDataCompare(DATA_T_DOUBLE, &testDouble, DATA_T_MONEY, &test) == -1); /** Equal To **/ testDouble = 7.0; - assert(objDataCompare(3,&testDouble,7,&test) == 0); + assert(objDataCompare(DATA_T_DOUBLE, &testDouble, DATA_T_MONEY, &test) == 0); /** Compare String with Money Case **/ /** Greater Than **/ char data_ptr[] = "$8.50"; - assert(objDataCompare(2,data_ptr,7,&test) == 1); + assert(objDataCompare(DATA_T_STRING, data_ptr, DATA_T_MONEY, &test) == 1); /** Less Than **/ char data_ptr2[] = "$4.50"; - assert(objDataCompare(2,data_ptr2,7,&test) == -1); + assert(objDataCompare(DATA_T_STRING, data_ptr2, DATA_T_MONEY, &test) == -1); /** Equal To **/ char data_ptr3[] = "$7.00"; - assert(objDataCompare(2,data_ptr3,7,&test) == 0); + assert(objDataCompare(DATA_T_STRING, data_ptr3, DATA_T_MONEY, &test) == 0); /** Compare Money with Money Case **/ /** Greater Than **/ MoneyType testMoney = {80500}; - assert(objDataCompare(7,&testMoney,7,&test) == 1); + assert(objDataCompare(DATA_T_MONEY, &testMoney, DATA_T_MONEY, &test) == 1); /** Less Than **/ testMoney.Value = 50000; - assert(objDataCompare(7,&testMoney,7,&test) == -1); + assert(objDataCompare(DATA_T_MONEY, &testMoney, DATA_T_MONEY, &test) == -1); /** Equal To **/ testMoney.Value = 70000; - assert(objDataCompare(7,&testMoney,7,&test) == 0); + assert(objDataCompare(DATA_T_MONEY, &testMoney, DATA_T_MONEY, &test) == 0); /** Compare DateTime with Money Case **/ DateTime testDate = {0}; - assert(objDataCompare(4,&testDate,7,&test) == -2); + assert(objDataCompare(DATA_T_DATETIME, &testDate, DATA_T_MONEY, &test) == -2); /** Compare IntV with Money Case **/ /** IntV fails with any value other than 2 **/ IntVec testIV = {0}; - assert(objDataCompare(5,&testIV,7,&test) == -2); + assert(objDataCompare(DATA_T_INTVEC, &testIV, DATA_T_MONEY, &test) == -2); int* argArray[2]; IntVec validTestIV = {0}; @@ -68,19 +71,19 @@ test(char** name) validTestIV.Integers = argArray; validTestIV.Integers[0] = 9; validTestIV.Integers[1] = 20; - assert(objDataCompare(5,&validTestIV,7,&test) == 1); + assert(objDataCompare(DATA_T_INTVEC, &validTestIV, DATA_T_MONEY, &test) == 1); validTestIV.Integers[0] = 4; validTestIV.Integers[1] = 35; - assert(objDataCompare(5,&validTestIV,7,&test) == -1); + assert(objDataCompare(DATA_T_INTVEC, &validTestIV, DATA_T_MONEY, &test) == -1); validTestIV.Integers[0] = 7; validTestIV.Integers[1] = 0; - assert(objDataCompare(5,&validTestIV,7,&test) == 0); + assert(objDataCompare(DATA_T_INTVEC, &validTestIV, DATA_T_MONEY, &test) == 0); /** Compare StrV with Money Case **/ StringVec testSV = {0}; - assert(objDataCompare(6,&testSV,7,&test) == -2); + assert(objDataCompare(DATA_T_STRINGVEC, &testSV, DATA_T_MONEY, &test) == -2); return 0; } From c87236072341073b6b7f91e33c82f750d1b54175 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 19 Jul 2021 15:09:05 -0600 Subject: [PATCH 128/129] Fix + test int overflow in objDataToWords for money > INT_MAX --- centrallix/objectsystem/obj_datatypes.c | 5 +++-- .../tests/test_moneytype_objDataToWords_00.c | 14 ++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 5850e97f7..2f65ea898 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -1872,8 +1872,9 @@ objDataToWords(int data_type, void* data_ptr) static char* teens[9] = { "Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen" }; static char* tens[9] = { "Ten","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety" }; static char* multiples[] = { "", "Thousand","Million","Billion","Trillion","Quadrillion" }; - unsigned long integer_part, fraction_part = 0; - int multiple_cnt, n, i; + unsigned long long integer_part, fraction_part = 0; + long long n; + int multiple_cnt, i; pMoneyType m; char nbuf[16]; diff --git a/centrallix/tests/test_moneytype_objDataToWords_00.c b/centrallix/tests/test_moneytype_objDataToWords_00.c index 9722b6ec1..b18e78b0a 100644 --- a/centrallix/tests/test_moneytype_objDataToWords_00.c +++ b/centrallix/tests/test_moneytype_objDataToWords_00.c @@ -12,26 +12,32 @@ test(char** name) /** Positive Case **/ char* data_ptr = "Seven And 05/100 "; - char* returnStr = objDataToWords(7,&test); + char* returnStr = objDataToWords(DATA_T_MONEY, &test); assert(strcmp(data_ptr, returnStr) == 0); /** Negative Case **/ test.Value = -70500; data_ptr = "Negative Seven And 05/100 "; - returnStr = objDataToWords(7,&test); + returnStr = objDataToWords(DATA_T_MONEY, &test); + assert(strcmp(data_ptr, returnStr) == 0); + + /** Money > INT_MAX **/ + test.Value = 18888888888888888; + data_ptr = "One Trillion Eight Hundred Eighty-Eight Billion, Eight Hundred Eighty-Eight Million, Eight Hundred Eighty-Eight Thousand, Eight Hundred Eighty-Eight And 88/100 "; + returnStr = objDataToWords(DATA_T_MONEY, &test); assert(strcmp(data_ptr, returnStr) == 0); /**objDataToWords Truncates fractional cent values past 100ths**/ /** Fractional Case **/ test.Value = -70525; data_ptr = "Negative Seven And 05/100 "; - returnStr = objDataToWords(7,&test); + returnStr = objDataToWords(DATA_T_MONEY, &test); assert(strcmp(data_ptr, returnStr) == 0); /** Fractional Case **/ test.Value = -70575; data_ptr = "Negative Seven And 05/100 "; - returnStr = objDataToWords(7,&test); + returnStr = objDataToWords(DATA_T_MONEY, &test); assert(strcmp(data_ptr, returnStr) == 0); return 0; From 8e73edf4df181775e73be24b219912d3ff7c4e55 Mon Sep 17 00:00:00 2001 From: sheesania Date: Mon, 14 Feb 2022 11:43:08 -0700 Subject: [PATCH 129/129] Clarify comment --- centrallix/objectsystem/obj_datatypes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/centrallix/objectsystem/obj_datatypes.c b/centrallix/objectsystem/obj_datatypes.c index 2f65ea898..ddd310222 100644 --- a/centrallix/objectsystem/obj_datatypes.c +++ b/centrallix/objectsystem/obj_datatypes.c @@ -2489,7 +2489,7 @@ objGetOldRepresentationOfMoney(MoneyType money, long long* wholePart, unsigned s { /** Add negative 1 then truncate fraction. (essentially floor() )**/ *wholePart = (money.Value - 10000)/10000ll; - /** Since fraction always counts away from zero, it is inverted**/ + /** Since fraction always counts in a positive direction, it is inverted**/ *fractionPart = 10000ll - abs(money.Value%10000); } else @@ -2497,4 +2497,4 @@ objGetOldRepresentationOfMoney(MoneyType money, long long* wholePart, unsigned s *wholePart = money.Value / 10000ll; *fractionPart = money.Value % 10000ll; } -} \ No newline at end of file +}