From 3203afca76573ea6563e5246230bc6a2c39725a6 Mon Sep 17 00:00:00 2001 From: MiranDMC Date: Mon, 2 Dec 2024 15:59:25 +0100 Subject: [PATCH] INI opcode updates. More unit tests. (#225) --- cleo_plugins/IniFiles/IniFiles.cpp | 91 +++++++++++++++++++++++++----- tests/cleo_tests/IniFiles/0AF0.txt | 73 ++++++++++++++++++++---- tests/cleo_tests/IniFiles/0AF1.txt | 2 +- tests/cleo_tests/IniFiles/0AF2.txt | 75 ++++++++++++++++++++---- tests/cleo_tests/IniFiles/0AF3.txt | 2 +- tests/cleo_tests/IniFiles/0AF4.txt | 37 +++++++++--- tests/cleo_tests/IniFiles/0AF5.txt | 2 +- 7 files changed, 235 insertions(+), 47 deletions(-) diff --git a/cleo_plugins/IniFiles/IniFiles.cpp b/cleo_plugins/IniFiles/IniFiles.cpp index 054c27f3..4841c66f 100644 --- a/cleo_plugins/IniFiles/IniFiles.cpp +++ b/cleo_plugins/IniFiles/IniFiles.cpp @@ -39,10 +39,44 @@ class IniFiles OPCODE_READ_PARAM_STRING(section); OPCODE_READ_PARAM_STRING(key); - auto result = GetPrivateProfileInt(section, key, 0x80000000, path); + char buff[32]; + if (GetPrivateProfileString(section, key, NULL, buff, sizeof(buff), path)) + { + char* str; + int base; + if (StringStartsWith(buff, "0x", false)) // hex int + { + str = buff + 2; + base = 16; + } + else // decimal int + { + str = buff; + base = 10; + } + + // parse + char* end; + int value = strtol(str, &end, base); + if (end != str) // at least one number character consumed + { + OPCODE_WRITE_PARAM_INT(value); + OPCODE_CONDITION_RESULT(true); + return OR_CONTINUE; + } + } - OPCODE_WRITE_PARAM_INT(result); - OPCODE_CONDITION_RESULT(result != 0x80000000); + // failed + if (IsLegacyScript(thread)) + { + OPCODE_WRITE_PARAM_INT(0x80000000); // CLEO4 behavior + } + else + { + OPCODE_SKIP_PARAMS(1); + } + + OPCODE_CONDITION_RESULT(false); return OR_CONTINUE; } @@ -60,6 +94,11 @@ class IniFiles char strValue[32]; _itoa(value, strValue, 10); auto result = WritePrivateProfileString(section, key, strValue, path); + + if (GetLastError() == ERROR_FILE_NOT_FOUND) // path points directory + { + result = false; + } OPCODE_CONDITION_RESULT(result); return OR_CONTINUE; @@ -75,19 +114,33 @@ class IniFiles OPCODE_READ_PARAM_STRING(section); OPCODE_READ_PARAM_STRING(key); - auto value = 0.0f; - char strValue[32]; - auto result = GetPrivateProfileString(section, key, NULL, strValue, sizeof(strValue), path); - if (result) - { - value = (float)atof(strValue); - OPCODE_WRITE_PARAM_FLOAT(value); - } - else + char buff[32]; + if (GetPrivateProfileString(section, key, NULL, buff, sizeof(buff), path)) { - OPCODE_SKIP_PARAMS(1); + char *str, *end; + float value; + if (StringStartsWith(buff, "0x", false)) // hex int + { + str = buff + 2; + value = (float)strtol(str, &end, 16); + } + else // float + { + str = buff; + value = strtof(str, &end); + } + + if (end != str) // at least one number character consumed + { + OPCODE_WRITE_PARAM_FLOAT(value); + OPCODE_CONDITION_RESULT(true); + return OR_CONTINUE; + } } - OPCODE_CONDITION_RESULT(result); + + // failed + OPCODE_SKIP_PARAMS(1); + OPCODE_CONDITION_RESULT(false); return OR_CONTINUE; } @@ -105,6 +158,11 @@ class IniFiles char strValue[32]; sprintf(strValue, "%g", value); auto result = WritePrivateProfileString(section, key, strValue, path); + + if (GetLastError() == ERROR_FILE_NOT_FOUND) // path points directory + { + result = false; + } OPCODE_CONDITION_RESULT(result); return OR_CONTINUE; @@ -147,6 +205,11 @@ class IniFiles auto result = WritePrivateProfileString(section, key, strValue, path); + if (GetLastError() == ERROR_FILE_NOT_FOUND) // path points directory + { + result = false; + } + OPCODE_CONDITION_RESULT(result); return OR_CONTINUE; } diff --git a/tests/cleo_tests/IniFiles/0AF0.txt b/tests/cleo_tests/IniFiles/0AF0.txt index ca3a9521..de16b4fa 100644 --- a/tests/cleo_tests/IniFiles/0AF0.txt +++ b/tests/cleo_tests/IniFiles/0AF0.txt @@ -15,16 +15,25 @@ function tests it("should fail on not-existing file", test1) it("should fail on invalid file", test2) it("should fail on not existing value", test3) - it("should fail on invalid type", test4) - it("should read value", test5) + it("should fail on invalid data", test4) + it("should read int from int data", test5) + it("should read int from negative int data", test6) + it("should read int from hex int data", test7) + it("should read int from float data", test8) + it("should read int from negative float data", test9) + it("should read int from mixed data", test10) return :setup delete_file {path} Test_Path - write_int_to_ini_file {value} 42 {path} Test_Path {section} "test" {key} "test_int" - write_float_to_ini_file {value} 50.0 {path} Test_Path {section} "test" {key} "test_float" - write_string_to_ini_file {value} "value_one" {path} Test_Path {section} "test" {key} "test_string" + write_int_to_ini_file {value} 42 {path} Test_Path {section} "test" {key} "test_int" + write_int_to_ini_file {value} -42 {path} Test_Path {section} "test" {key} "test_int_neg" + write_string_to_ini_file {value} "0x42" {path} Test_Path {section} "test" {key} "test_int_hex" + write_float_to_ini_file {value} 50.0 {path} Test_Path {section} "test" {key} "test_float" + write_float_to_ini_file {value} -50.0 {path} Test_Path {section} "test" {key} "test_float_neg" + write_string_to_ini_file {value} "value_one" {path} Test_Path {section} "test" {key} "test_string" + write_string_to_ini_file {value} " 12.3four " {path} Test_Path {section} "test" {key} "test_mixed" return :cleanup @@ -32,28 +41,72 @@ function tests return function test1 - int value = read_int_from_ini_file {path} "not_a_file.ini" {section} "test" {key} "test_int" + int value = 555 + value = read_int_from_ini_file {path} "not_a_file.ini" {section} "test" {key} "test_float" assert_result_false() + assert_eq(value, 555) end function test2 - int value = read_int_from_ini_file {path} "cleo.asi" {section} "test" {key} "test_int" + int value = 555 + value = read_int_from_ini_file {path} "cleo.asi" {section} "test" {key} "test_int" assert_result_false() + assert_eq(value, 555) end function test3 - int value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "invalid_key" + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "invalid_key" assert_result_false() + assert_eq(value, 555) end function test4 - int value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_string" + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_string" assert_result_false() + assert_eq(value, 555) end function test5 - int value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_int" + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_int" assert_result_true() assert_eq(value, 42) end + + function test6 + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_int_neg" + assert_result_true() + assert_eq(value, -42) + end + + function test7 + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_int_hex" + assert_result_true() + assert_eq(value, 0x42) + end + + function test8 + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_float" + assert_result_true() + assert_eq(value, 50) + end + + function test9 + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_float_neg" + assert_result_true() + assert_eq(value, -50) + end + + function test10 + int value = 555 + value = read_int_from_ini_file {path} Test_Path {section} "test" {key} "test_mixed" + assert_result_true() + assert_eq(value, 12) + end end diff --git a/tests/cleo_tests/IniFiles/0AF1.txt b/tests/cleo_tests/IniFiles/0AF1.txt index 73bb5933..04fd2886 100644 --- a/tests/cleo_tests/IniFiles/0AF1.txt +++ b/tests/cleo_tests/IniFiles/0AF1.txt @@ -15,7 +15,7 @@ function tests it("should fail to overwrite file", test1) it("should fail to overwrite directory", test2) it("should create new file", test3) - it("should append to existing file", test4) + it("should add to existing file", test4) it("should overwrite value", test5) return diff --git a/tests/cleo_tests/IniFiles/0AF2.txt b/tests/cleo_tests/IniFiles/0AF2.txt index e4f88840..534d8752 100644 --- a/tests/cleo_tests/IniFiles/0AF2.txt +++ b/tests/cleo_tests/IniFiles/0AF2.txt @@ -15,16 +15,25 @@ function tests it("should fail on not-existing file", test1) it("should fail on invalid file", test2) it("should fail on not existing value", test3) - it("should fail on invalid type", test4) - it("should read value", test5) + it("should fail on invalid data", test4) + it("should read float from int data", test5) + it("should read float from negative int data", test6) + it("should read float from hex int data", test7) + it("should read float from float data", test8) + it("should read float from negative float data", test9) + it("should read float from mixed data", test10) return :setup delete_file {path} Test_Path - write_int_to_ini_file {value} 42 {path} Test_Path {section} "test" {key} "test_int" - write_float_to_ini_file {value} 50.0 {path} Test_Path {section} "test" {key} "test_float" - write_string_to_ini_file {value} "value_one" {path} Test_Path {section} "test" {key} "test_string" + write_int_to_ini_file {value} 42 {path} Test_Path {section} "test" {key} "test_int" + write_int_to_ini_file {value} -42 {path} Test_Path {section} "test" {key} "test_int_neg" + write_string_to_ini_file {value} "0x42" {path} Test_Path {section} "test" {key} "test_int_hex" + write_float_to_ini_file {value} 50.0 {path} Test_Path {section} "test" {key} "test_float" + write_float_to_ini_file {value} -50.0 {path} Test_Path {section} "test" {key} "test_float_neg" + write_string_to_ini_file {value} "value_one" {path} Test_Path {section} "test" {key} "test_string" + write_string_to_ini_file {value} " 12.3four " {path} Test_Path {section} "test" {key} "test_mixed" return :cleanup @@ -32,28 +41,72 @@ function tests return function test1 - float value = read_float_from_ini_file {path} "not_a_file.ini" {section} "test" {key} "test_float" + float value = 555.0 + value = read_float_from_ini_file {path} "not_a_file.ini" {section} "test" {key} "test_float" assert_result_false() + assert_eq(value, 555.0) end function test2 - float value = read_float_from_ini_file {path} "cleo.asi" {section} "test" {key} "test_float" + float value = 555.0 + value = read_float_from_ini_file {path} "cleo.asi" {section} "test" {key} "test_int" assert_result_false() + assert_eq(value, 555.0) end function test3 - float value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "invalid_key" + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "invalid_key" assert_result_false() + assert_eq(value, 555.0) end function test4 - float value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_string" + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_string" assert_result_false() + assert_eq(value, 555.0) end function test5 - float value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_float" + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_int" assert_result_true() - assert_eqf(value, 50.0) + assert_eq(value, 42.0) + end + + function test6 + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_int_neg" + assert_result_true() + assert_eq(value, -42.0) + end + + function test7 + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_int_hex" + assert_result_true() + assert_eq(value, 66.0) // 0x42 + end + + function test8 + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_float" + assert_result_true() + assert_eq(value, 50.0) + end + + function test9 + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_float_neg" + assert_result_true() + assert_eq(value, -50.0) + end + + function test10 + float value = 555.0 + value = read_float_from_ini_file {path} Test_Path {section} "test" {key} "test_mixed" + assert_result_true() + assert_eq(value, 12.3) end end diff --git a/tests/cleo_tests/IniFiles/0AF3.txt b/tests/cleo_tests/IniFiles/0AF3.txt index a6b09555..eba16e92 100644 --- a/tests/cleo_tests/IniFiles/0AF3.txt +++ b/tests/cleo_tests/IniFiles/0AF3.txt @@ -15,7 +15,7 @@ function tests it("should fail to overwrite file", test1) it("should fail to overwrite directory", test2) it("should create new file", test3) - it("should append to existing file", test4) + it("should add to existing file", test4) it("should overwrite value", test5) return diff --git a/tests/cleo_tests/IniFiles/0AF4.txt b/tests/cleo_tests/IniFiles/0AF4.txt index 60fa091a..48c8a0a8 100644 --- a/tests/cleo_tests/IniFiles/0AF4.txt +++ b/tests/cleo_tests/IniFiles/0AF4.txt @@ -15,15 +15,20 @@ function tests it("should fail on not-existing file", test1) it("should fail on invalid file", test2) it("should fail on not existing value", test3) - it("should read value", test4) + it("should read string value", test4) + it("should trim whitespaces", test5) return :setup delete_file {path} Test_Path - write_int_to_ini_file {value} 42 {path} Test_Path {section} "test" {key} "test_int" - write_float_to_ini_file {value} 50.0 {path} Test_Path {section} "test" {key} "test_float" - write_string_to_ini_file {value} "value_one" {path} Test_Path {section} "test" {key} "test_string" + write_int_to_ini_file {value} 42 {path} Test_Path {section} "test" {key} "test_int" + write_int_to_ini_file {value} -42 {path} Test_Path {section} "test" {key} "test_int_neg" + write_string_to_ini_file {value} "0x42" {path} Test_Path {section} "test" {key} "test_int_hex" + write_float_to_ini_file {value} 50.0 {path} Test_Path {section} "test" {key} "test_float" + write_float_to_ini_file {value} -50.0 {path} Test_Path {section} "test" {key} "test_float_neg" + write_string_to_ini_file {value} "value_one" {path} Test_Path {section} "test" {key} "test_string" + write_string_to_ini_file {value} " 12.3four " {path} Test_Path {section} "test" {key} "test_mixed" return :cleanup @@ -31,23 +36,37 @@ function tests return function test1 - longstring value = read_string_from_ini_file {path} "not_a_file.ini" {section} "test" {key} "test_string" + longstring value = "initial" + value = read_string_from_ini_file {path} "not_a_file.ini" {section} "test" {key} "test_string" assert_result_false() + assert_eqs(value, "initial") end function test2 - longstring value = read_string_from_ini_file {path} "cleo.asi" {section} "test" {key} "test_string" + longstring value = "initial" + value = read_string_from_ini_file {path} "cleo.asi" {section} "test" {key} "test_string" assert_result_false() + assert_eqs(value, "initial") end function test3 - longstring value = read_string_from_ini_file {path} Test_Path {section} "test" {key} "invalid_key" + longstring value = "initial" + value = read_string_from_ini_file {path} Test_Path {section} "test" {key} "invalid_key" assert_result_false() + assert_eqs(value, "initial") end function test4 - longstring value = read_string_from_ini_file {path} Test_Path {section} "test" {key} "test_string" + longstring value = "initial" + value = read_string_from_ini_file {path} Test_Path {section} "test" {key} "test_string" assert_result_true() assert_eqs(value, "value_one") - end + end + + function test5 + longstring value = "initial" + value = read_string_from_ini_file {path} Test_Path {section} "test" {key} "test_mixed" + assert_result_true() + assert_eqs(value, "12.3four") + end end diff --git a/tests/cleo_tests/IniFiles/0AF5.txt b/tests/cleo_tests/IniFiles/0AF5.txt index 15eaf3dd..671dc652 100644 --- a/tests/cleo_tests/IniFiles/0AF5.txt +++ b/tests/cleo_tests/IniFiles/0AF5.txt @@ -15,7 +15,7 @@ function tests it("should fail to overwrite file", test1) it("should fail to overwrite directory", test2) it("should create new file", test3) - it("should append to existing file", test4) + it("should add to existing file", test4) it("should overwrite value", test5) return