Skip to content

Commit 5ec4bb2

Browse files
committed
FEAT: allow char as an argument for writing to a file port
related to: Oldes/Rebol-issues#1894
1 parent f66b9a6 commit 5ec4bb2

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

make/tools/make-headers.reb

+1
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ context [
296296
acts: load root-dir/src/boot/actions.reb
297297

298298
foreach word [
299+
append
299300
copy
300301
find
301302
put

src/core/p-file.c

+20-8
Original file line numberDiff line numberDiff line change
@@ -329,15 +329,25 @@ REBINT Mode_Syms[] = {
329329
#endif
330330
len += n;
331331
}
332-
333-
// Auto convert string to UTF-8
334-
if (IS_STRING(data)) {
332+
333+
if (IS_BINARY(data)) {
334+
file->data = VAL_BIN_DATA(data);
335+
}
336+
else if (IS_STRING(data)) {
337+
// Auto convert string to UTF-8
335338
ser = Encode_UTF8_Value(data, len, ENCF_OS_CRLF);
336339
file->data = ser? BIN_HEAD(ser) : VAL_BIN_DATA(data); // No encoding may be needed
337340
len = SERIES_TAIL(ser);
338341
}
342+
else if (IS_CHAR(data)) {
343+
// Auto convert char to UTF-8
344+
REBYTE buf[8];
345+
len = Encode_UTF8_Char(buf, VAL_CHAR(data));
346+
file->data = &buf;
347+
}
339348
else {
340-
file->data = VAL_BIN_DATA(data);
349+
// it should be already handled
350+
//Trap1(PE_BAD_ARGUMENT, data);
341351
}
342352
file->length = len;
343353
OS_DO_DEVICE(file, RDC_WRITE);
@@ -464,14 +474,16 @@ REBINT Mode_Syms[] = {
464474
break;
465475

466476
case A_APPEND:
477+
args = Find_Refines(ds, AM_APPEND_DUP | AM_APPEND_ONLY );
478+
if (args > 0) Trap0(RE_BAD_REFINES); // should be used some new port related error!
467479
file->file.index = file->file.size;
468480
SET_FLAG(file->modes, RFM_RESEEK);
469481

470482
case A_WRITE:
471483
args = Find_Refines(ds, ALL_WRITE_REFS);
472-
spec = D_ARG(2); // data (binary, string, or block)
484+
spec = D_ARG(2); // data (binary, string, char or block)
473485

474-
if (!(IS_BINARY(spec) || IS_STRING(spec) || (IS_BLOCK(spec) && (args & AM_WRITE_LINES)))) {
486+
if (!(IS_BINARY(spec) || IS_STRING(spec) || IS_CHAR(spec) || (IS_BLOCK(spec) && (args & AM_WRITE_LINES)))) {
475487
//Trap1(RE_INVALID_ARG, spec);
476488
REB_MOLD mo = {0};
477489
Reset_Mold(&mo);
@@ -493,14 +505,14 @@ REBINT Mode_Syms[] = {
493505
}
494506

495507
// Setup for /append or /seek:
496-
if (args & AM_WRITE_APPEND) {
508+
if (args & AM_WRITE_APPEND || action == A_APPEND) {
497509
file->file.index = -1; // append
498510
SET_FLAG(file->modes, RFM_RESEEK);
499511
}
500512
if (args & AM_WRITE_SEEK) Set_Seek(file, D_ARG(ARG_WRITE_INDEX));
501513

514+
len = IS_CHAR(spec) ? 0 : VAL_LEN(spec);
502515
// Determine length. Clip /PART to size of string if needed.
503-
len = VAL_LEN(spec);
504516
if (args & AM_WRITE_PART) {
505517
REBCNT n = Int32s(D_ARG(ARG_WRITE_LENGTH), 0);
506518
if (n <= len) len = n;

src/tests/units/port-test.r3

+32
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,38 @@ if system/platform = 'Windows [
435435
; validate...
436436
--assert not exists? %issue-2447
437437

438+
--test-- "WRITE/APPEND file-port"
439+
--assert all [
440+
not error? try [
441+
p: open/new %issue-1894
442+
write/append p "Hello"
443+
write/append p newline
444+
close p
445+
p: open %issue-1894
446+
write/append p #{5265626F6C}
447+
close p
448+
]
449+
"Hello^/Rebol" = read/string %issue-1894
450+
]
451+
452+
--test-- "APPEND file-port"
453+
;@@ https://github.com/Oldes/Rebol-issues/issues/1894
454+
--assert all [
455+
not error? try [
456+
p: open/new %issue-1894
457+
append p "Hello"
458+
append p newline
459+
close p
460+
p: open %issue-1894
461+
append p #{5265626F6C}
462+
close p
463+
]
464+
"Hello^/Rebol" = read/string %issue-1894
465+
]
466+
--assert all [error? e: try [append/dup p LF 10] e/id = 'bad-refines]
467+
--assert all [error? e: try [append/only p "aa"] e/id = 'bad-refines]
468+
try [delete %issue-1894]
469+
438470
===end-group===
439471

440472
if system/platform = 'Windows [

0 commit comments

Comments
 (0)