From 68cb9d0fbfad43c647a3da22834c79cd55f581a7 Mon Sep 17 00:00:00 2001 From: Oldes Date: Fri, 8 Jul 2022 14:15:04 +0200 Subject: [PATCH] FEAT: implemented `indexz?`, `at` and `atz` actions on file port resolves: https://github.com/Oldes/Rebol-issues/issues/2506 --- src/core/p-file.c | 19 +++++++++++++++-- src/tests/units/port-test.r3 | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/core/p-file.c b/src/core/p-file.c index 3b6a31622e..7ff193aac6 100644 --- a/src/core/p-file.c +++ b/src/core/p-file.c @@ -636,6 +636,9 @@ REBINT Mode_Syms[] = { case A_INDEXQ: SET_INTEGER(D_RET, file->file.index + 1); break; + case A_INDEXZQ: + SET_INTEGER(D_RET, file->file.index); + break; case A_LENGTHQ: SET_INTEGER(D_RET, file->file.size - file->file.index); // !clip at zero @@ -654,13 +657,20 @@ REBINT Mode_Syms[] = { goto seeked; case A_BACK: - if (file->file.index > 0) file->file.index--; + file->file.index--; goto seeked; case A_SKIP: file->file.index += Get_Num_Arg(D_ARG(2)); goto seeked; + case A_AT: + file->file.index = Get_Num_Arg(D_ARG(2)) - 1; + goto seeked; + case A_ATZ: + file->file.index = Get_Num_Arg(D_ARG(2)); + goto seeked; + case A_HEADQ: DECIDE(file->file.index == 0); @@ -680,7 +690,6 @@ REBINT Mode_Syms[] = { break; /* Not yet implemented: - A_AT, // 38 A_PICK, // 41 A_PATH, // 42 A_PATH_SET, // 43 @@ -701,6 +710,12 @@ REBINT Mode_Syms[] = { return R_RET; seeked: + // fit index in available range... + if (file->file.index < 0) + file->file.index = 0; + else if (file->file.index > file->file.size) + file->file.index = file->file.size; + SET_FLAG(file->modes, RFM_RESEEK); return R_ARG1; diff --git a/src/tests/units/port-test.r3 b/src/tests/units/port-test.r3 index f0184f4bcf..5c616f5822 100644 --- a/src/tests/units/port-test.r3 +++ b/src/tests/units/port-test.r3 @@ -347,6 +347,46 @@ if system/platform = 'Windows [ port? close p not error? try [delete %12345] ] + --test-- "skip/at on file port" + write %12345 "12345" + p: open/read/seek %12345 + ;@@ https://github.com/Oldes/Rebol-issues/issues/2506 + --assert all [ + 1 = index? head p + 3 = index? skip p 2 + 5 = index? skip p 2 + 6 = index? tail p + 6 = index? skip p 20 + 1 = index? skip head p -10 + 1 = index? back head p + 1 = index? back back head p + ] + --assert all [ + 6 = index? tail p + 6 = index? at p 20 + 2 = index? at p 2 + 2 = index? at p 2 + 1 = index? at p 0 + 1 = index? at p -10 + ] + --assert all [ + 6 = index? tail p + 6 = index? atz p 20 + 3 = index? atz p 2 + 3 = index? atz p 2 + 1 = index? atz p 0 + 1 = index? atz p -10 + ] + --assert all [ + 5 = indexz? tail p + 5 = indexz? atz p 20 + 2 = indexz? atz p 2 + 2 = indexz? atz p 2 + 0 = indexz? atz p 0 + 0 = indexz? atz p -10 + ] + close p + delete %12345 --test-- "CLEAR file port" ;@@ https://github.com/Oldes/Rebol-issues/issues/812