Skip to content

Commit

Permalink
TIVarFile: call getMinVersionFromData handler and add some tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
adriweb committed Jul 15, 2024
1 parent 195c76f commit e3a718e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/TIVarFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ namespace tivars
{
entry.data_length2 = entry.data_length = (uint16_t) entry.data.size();
this->header.entries_len += sizeof(var_entry_t::data_length) + sizeof(var_entry_t::data_length2) + entry.meta_length + entry.data_length;
// todo: update entry version field
entry.version = (this->calcModel.getFlags() & TIFeatureFlags::hasFlash) ? std::get<2>(entry._type.getHandlers())(entry.data) : 0;
}
this->computedChecksum = this->computeChecksumFromInstanceData();
}
Expand Down
52 changes: 50 additions & 2 deletions src/TypeHandlers/TH_Tokenized.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,56 @@ namespace tivars::TypeHandlers

uint8_t TH_Tokenized::getMinVersionFromData(const data_t& data)
{
(void)data;
return 0;
const size_t dataSize = data.size();
if (dataSize < 2)
{
throw std::invalid_argument("Invalid data array. Needs to contain at least 2 bytes (size fields)");
}

bool usesRTC = false;
int maxBB = -1;
int maxEF = -1;
uint16_t offset = 2;
while (offset < dataSize) {
const uint8_t firstByte = data[offset++];
if (is_in_vector(firstByteOfTwoByteTokens, firstByte)) {
if (offset >= dataSize) {
break;
}
uint8_t secondByte = data[offset++];
if (firstByte == 0xBB) {
if (secondByte > maxBB) maxBB = secondByte;
} else if (firstByte == 0xEF) {
if (secondByte <= 0x10) usesRTC = true;
if (secondByte > maxEF) maxEF = secondByte;
}
}
}
uint8_t version = usesRTC ? 0x20 : 0x00;
if (maxBB > 0xF5 || maxEF > 0xA6) {
version = 0xFF;
} else if (maxEF > 0x98) {
version |= 0x0C;
} else if (maxEF > 0x75) {
version |= 0x0B;
} else if (maxEF > 0x40) {
version |= 0x0A;
} else if (maxEF > 0x3E) {
version |= 0x07;
} else if (maxEF > 0x16) {
version |= 0x06;
} else if (maxEF > 0x12) {
version |= 0x05;
} else if (maxEF > -1) {
version |= 0x04;
} else if (maxBB > 0xDA) {
version |= 0x03;
} else if (maxBB > 0xCE) {
version |= 0x02;
} else if (maxBB > 0x67) {
version |= 0x01;
}
return version;
}

std::string TH_Tokenized::reindentCodeString(const std::string& str_orig, const options_t& options)
Expand Down
51 changes: 51 additions & 0 deletions tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,57 @@ int main(int argc, char** argv)
assert(trim(testPrgmStr1.getReadableContent({{"prettify", true}, {"reindent", true}})) == "\"42→Str1\nStr2\n123");
}

{
// See https://wikiti.brandonw.net/index.php?title=83Plus:OS:Variable_Versions
TIVarFile testPrgmStr1 = TIVarFile::createNew("Program", "asdf");
const auto& ver = testPrgmStr1.getVarEntries()[0].version;
assert(ver == 0x00);
testPrgmStr1.setContentFromString("Disp 41+1");
assert((ver & ~0x20) == 0x00);
testPrgmStr1.setContentFromString("Archive A");
assert((ver & ~0x20) == 0x01);
testPrgmStr1.setContentFromString("GarbageCollect");
assert((ver & ~0x20) == 0x01);
testPrgmStr1.setContentFromString("Disp 42%");
assert((ver & ~0x20) == 0x02);
testPrgmStr1.setContentFromString("~A");
assert((ver & ~0x20) == 0x02);
testPrgmStr1.setContentFromString("Disp \"\"");
assert((ver & ~0x20) == 0x03);
testPrgmStr1.setContentFromString("Disp \"\"");
assert((ver & ~0x20) == 0x03);
testPrgmStr1.setContentFromString("setDate(A,B,C)");
assert((ver & ~0x20) == 0x04);
testPrgmStr1.setContentFromString("ExecLib \"A\"");
assert((ver & ~0x20) == 0x04);
testPrgmStr1.setContentFromString("Manual-Fit ");
assert((ver & ~0x20) == 0x05);
testPrgmStr1.setContentFromString("ZQuadrant1");
assert((ver & ~0x20) == 0x06);
testPrgmStr1.setContentFromString("FRAC");
assert((ver & ~0x20) == 0x06);
testPrgmStr1.setContentFromString("STATWIZARD ON");
assert((ver & ~0x20) == 0x07);
testPrgmStr1.setContentFromString("STATWIZARD OFF");
assert((ver & ~0x20) == 0x07);
testPrgmStr1.setContentFromString("BLUE");
assert((ver & ~0x20) == 0x0A);
testPrgmStr1.setContentFromString("Dot-Thin");
assert((ver & ~0x20) == 0x0A);
testPrgmStr1.setContentFromString("TraceStep");
assert((ver & ~0x20) == 0x00); // 63** token ranges are not considered by a calculator when it generates the version.
testPrgmStr1.setContentFromString("Asm84CEPrgm:C9");
assert((ver & ~0x20) == 0x0B);
testPrgmStr1.setContentFromString("Disp eval(Str1");
assert((ver & ~0x20) == 0x0B); // 0Bh is used for all of TI-84 Plus CE OS 5.0 through 5.2, despite tokens being added between them.
testPrgmStr1.setContentFromString("Quartiles Setting…");
assert((ver & ~0x20) == 0x0B);
testPrgmStr1.setContentFromString("Execute Program");
assert((ver & ~0x20) == 0x0C);
testPrgmStr1.setContentFromString("piecewise(");
assert((ver & ~0x20) == 0x0C);
}

{
assert(TH_Tokenized::oneTokenBytesToString(0x00) == "");
assert(TH_Tokenized::oneTokenBytesToString(0xBB) == "");
Expand Down

0 comments on commit e3a718e

Please sign in to comment.