Skip to content

Commit 2a934d5

Browse files
committed
MLC: Add basic file & stream operations.
Add the livecode.io.file module. Initially, only support the following syntax, for getting or setting the contents of a file. On write, replaces any pre-existing file at the same path. put the contents of file tPath into tVar put tData into the contents of file tPath Also add the livecode.io.stream module. Initially you can only write to a stream -- not even open one! This is to enable basic output on standard out. write tData to stream tStream
1 parent 46b068b commit 2a934d5

File tree

8 files changed

+136
-98
lines changed

8 files changed

+136
-98
lines changed

libscript/Makefile.libscript

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ SOURCES += \
2020
module-math.cpp \
2121
module-math_foundation.cpp \
2222
module-sort.cpp \
23+
module-stream.cpp \
2324
module-string.cpp \
2425
module-type_convert.cpp \
2526
module-type.cpp \

libscript/libstdscript-modules.list

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ binary.mlc
66
bitwise.mlc
77
byte.mlc
88
char.mlc
9+
file.mlc
910
list.mlc
1011
logic.mlc
1112
math-foundation.mlc
1213
math.mlc
1314
sort.mlc
15+
stream.mlc
1416
string.mlc
1517
type.mlc
1618
type-convert.mlc

libscript/src/file.mlc

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,34 @@
1-
/*
1+
/*
22
This module specifies the syntax definitions and bindings for file i/o operations in modular LiveCode.
33
*/
44

55
module com.livecode.file
66

7-
public foreign type Stream binds to "kMCStreamTypeInfo"
7+
--
88

9-
public foreign handler MCFileExecOpenFileForRead(in File as string) as optional Stream binds to "<builtin>"
10-
public foreign handler MCFileExecOpenFileForWrite(in Create as bool, in File as string) as optional Stream binds to "<builtin>"
11-
public foreign handler MCFileExecOpenFileForUpdate(in Create as bool, in File as string) as optional Stream binds to "<builtin>"
9+
public foreign handler MCFileExecGetContents(in File as string, out Contents as data) as undefined binds to "<builtin>"
10+
public foreign handler MCFileExecSetContents(in Contents as data, in File as string) as undefined binds to "<builtin>"
1211

13-
public foreign handler MCFileExecReadFromStream(in Amount as uint, in Source as Stream) as data binds to "<builtin>"
12+
/*
13+
Summary: The data stored in a file.
1414

15-
--
15+
File: An expression that evaluates to a filename.
1616

17-
syntax OpenFileForRead is statement
18-
"open" "read" "only" "stream" "for" "file" <File: Expression>
19-
begin
20-
MCFileExecOpenFileForRead(File)
21-
end syntax
17+
Description:
18+
The raw data stored in a file.
2219

23-
syntax OpenFileForWrite is statement
24-
"open" "write" "only" "stream" "for" ("new" <Create=true> | <Create=false>) "file" <File: Expression>
25-
begin
26-
MCFileExecOpenFileForWrite(Create, File)
27-
end syntax
20+
>*Note:* Setting the contents of a file will replace the file with a
21+
>newly-created file with the new contents.
2822

29-
syntax OpenFileForUpdate is statement
30-
"open" "read" "write" "stream" "for" ("new" <Create=true> | <Create=false>) "file" <File: Expression>
23+
Tags: IO
24+
*/
25+
syntax FileContents is prefix operator with precedence 2
26+
"the" "contents" "of" "file" <File: Expression>
3127
begin
32-
MCFileExecOpenFileForUpdate(Create, File)
28+
MCFileExecGetContents(File, output)
29+
MCFileExecSetContents(input, File)
3330
end syntax
3431

3532
--
3633

37-
syntax ReadFromStream is statement
38-
"read" <Amount: Expression> "from" "stream" <Source: Expression>
39-
begin
40-
MCFileExecReadFromStream(Amount, Source)
41-
end syntax
42-
43-
end module
34+
end module

libscript/src/module-file.cpp

Lines changed: 22 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
/* Copyright (C) 2003-2013 Runtime Revolution Ltd.
2-
3-
This file is part of LiveCode.
4-
5-
LiveCode is free software; you can redistribute it and/or modify it under
6-
the terms of the GNU General Public License v3 as published by the Free
7-
Software Foundation.
8-
9-
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
10-
WARRANTY; without even the implied warranty of MERCHANTABILITY or
11-
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12-
for more details.
13-
14-
You should have received a copy of the GNU General Public License
15-
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1+
/* -*-c++-*-
2+
Copyright (C) 2015 Runtime Revolution Ltd.
3+
4+
This file is part of LiveCode.
5+
6+
LiveCode is free software; you can redistribute it and/or modify it under
7+
the terms of the GNU General Public License v3 as published by the Free
8+
Software Foundation.
9+
10+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
11+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1617

1718
#include <foundation.h>
1819
#include <foundation-auto.h>
@@ -21,54 +22,14 @@
2122

2223
////////////////////////////////////////////////////////////////////////////////
2324

24-
extern "C" MC_DLLEXPORT MCStreamRef MCFileExecOpenFileForRead(MCStringRef p_filename)
25-
{
26-
MCStreamRef t_stream;
27-
if (!MCFileCreateStreamForFile(p_filename, kMCOpenFileModeRead, t_stream))
28-
return nil;
29-
30-
return t_stream;
31-
}
32-
33-
extern "C" MC_DLLEXPORT MCStreamRef MCFileExecOpenFileForWrite(bool p_create, MCStringRef p_filename, MCStreamRef& r_stream)
34-
{
35-
MCStreamRef t_stream;
36-
if (!MCFileCreateStreamForFile(p_filename, p_create ? kMCOpenFileModeCreate : kMCOpenFileModeWrite, t_stream))
37-
return nil;
38-
39-
return t_stream;
40-
}
41-
42-
extern "C" MC_DLLEXPORT MCStreamRef MCFileExecOpenFileForUpdate(bool p_create, MCStringRef p_filename, MCStreamRef& r_stream)
25+
extern "C" MC_DLLEXPORT void
26+
MCFileExecGetContents (MCStringRef p_path, MCDataRef & r_data)
4327
{
44-
MCStreamRef t_stream;
45-
if (!MCFileCreateStreamForFile(p_filename, p_create ? kMCOpenFileModeCreate : kMCOpenFileModeUpdate, t_stream))
46-
return nil;
47-
48-
return t_stream;
28+
/* UNCHECKED */ MCFileGetContents (p_path, r_data);
4929
}
5030

51-
extern "C" MC_DLLEXPORT MCDataRef MCFileExecReadFromStream(uindex_t p_amount, MCStreamRef p_stream)
31+
extern "C" MC_DLLEXPORT void
32+
MCFileExecSetContents (MCDataRef p_contents, MCStringRef p_path)
5233
{
53-
if (!MCStreamIsReadable(p_stream))
54-
{
55-
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("stream is not readable"), nil);
56-
return MCValueRetain(kMCEmptyData);
57-
}
58-
59-
byte_t t_buffer[p_amount];
60-
61-
if (!MCStreamRead(p_stream, t_buffer, p_amount))
62-
{
63-
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("could not read from stream"), nil);
64-
return MCValueRetain(kMCEmptyData);
65-
}
66-
67-
MCDataRef t_data;
68-
if (!MCDataCreateWithBytes(t_buffer, p_amount, t_data))
69-
return MCValueRetain(kMCEmptyData);
70-
71-
return t_data;
34+
/* UNCHECKED */ MCFileSetContents (p_path, p_contents);
7235
}
73-
74-

libscript/src/module-stream.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* -*-c++-*-
2+
Copyright (C) 2015 Runtime Revolution Ltd.
3+
4+
This file is part of LiveCode.
5+
6+
LiveCode is free software; you can redistribute it and/or modify it under
7+
the terms of the GNU General Public License v3 as published by the Free
8+
Software Foundation.
9+
10+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
11+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
17+
18+
#include <foundation.h>
19+
20+
////////////////////////////////////////////////////////////////////////////////
21+
22+
extern "C" MC_DLLEXPORT void
23+
MCStreamExecWriteToStream(MCDataRef p_data,
24+
MCStreamRef p_stream)
25+
{
26+
/* FIXME This check should be handled by MCStreamWrite */
27+
if (!MCStreamIsWritable (p_stream))
28+
{
29+
MCErrorCreateAndThrow (kMCGenericErrorTypeInfo, "reason", MCSTR("stream is not writable"), NULL);
30+
return;
31+
}
32+
33+
if (!MCStreamWrite (p_stream,
34+
MCDataGetBytePtr (p_data), MCDataGetLength (p_data)))
35+
{
36+
return; /* Error should already have been set */
37+
}
38+
}

libscript/src/stream.mlc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
This module specifies the syntax definitions and bindings for
3+
stream input and output operations in modular LiveCode.
4+
*/
5+
6+
module com.livecode.stream
7+
8+
public foreign type Stream binds to "kMCStreamTypeInfo"
9+
10+
--
11+
12+
public foreign handler MCStreamExecWriteToStream(in Buffer as data, in Destination as Stream) as undefined binds to "<builtin>"
13+
14+
/*
15+
Summary: Write data to a stream.
16+
17+
Buffer: An expression that evaluates to binary data.
18+
Stream: An expression that evaluates to a stream.
19+
20+
Description:
21+
Write some data to a stream. If not all of the data can be written,
22+
fails with an error.
23+
24+
>*Warning:* If the stream is able to accept only part of the data,
25+
>some streams will write that part of the data and discard the rest.
26+
>This may cause loss of data.
27+
28+
29+
Tags: IO
30+
*/
31+
syntax WriteToStream is statement
32+
"write" <Buffer: Expression> "to" "stream" <Destination: Expression>
33+
begin
34+
MCStreamExecWriteToStream(Buffer, Destination)
35+
end syntax
36+
37+
--
38+
39+
end module

toolchain/lc-compile/src/module-helper.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern builtin_module_descriptor __com_livecode_math_module_info;
4040
extern builtin_module_descriptor __com_livecode_mathfoundation_module_info;
4141
extern builtin_module_descriptor __com_livecode_segmentchunk_module_info;
4242
extern builtin_module_descriptor __com_livecode_sort_module_info;
43+
extern builtin_module_descriptor __com_livecode_stream_module_info;
4344
extern builtin_module_descriptor __com_livecode_string_module_info;
4445
extern builtin_module_descriptor __com_livecode_type_module_info;
4546
extern builtin_module_descriptor __com_livecode_typeconvert_module_info;
@@ -62,6 +63,7 @@ builtin_module_descriptor* g_builtin_modules[] =
6263
&__com_livecode_mathfoundation_module_info,
6364
//&__com_livecode_segmentchunk_module_info,
6465
&__com_livecode_sort_module_info,
66+
&__com_livecode_stream_module_info,
6567
&__com_livecode_string_module_info,
6668
&__com_livecode_type_module_info,
6769
&__com_livecode_typeconvert_module_info
@@ -75,12 +77,13 @@ extern void (*MCBinaryEvalConcatenateBytes)();
7577
extern void (*MCBitwiseEvalBitwiseAnd)();
7678
extern void (*MCByteEvalNumberOfBytesIn)();
7779
extern void (*MCCharEvalNumberOfCharsIn)();
78-
extern void (*MCFileExecOpenFileForRead)();
80+
extern void (*MCFileExecGetContents)();
7981
extern void (*MCListEvalHeadOf)();
8082
extern void (*MCLogicEvalNot)();
8183
extern void (*MCMathEvalRealToPowerOfReal)();
8284
extern void (*MCMathFoundationExecRoundRealToNearest)();
8385
extern void (*MCSortExecSortListAscendingText)();
86+
extern void (*MCStreamExecWriteToStream)();
8487
extern void (*MCStringEvalConcatenate)();
8588
extern void (*MCTypeEvalIsEmpty)();
8689
extern void (*MCTypeConvertExecSplitStringByDelimiter)();
@@ -94,12 +97,13 @@ void *g_builtin_ptrs[] =
9497
&MCBitwiseEvalBitwiseAnd,
9598
&MCByteEvalNumberOfBytesIn,
9699
&MCCharEvalNumberOfCharsIn,
97-
&MCFileExecOpenFileForRead,
100+
&MCFileExecGetContents,
98101
&MCListEvalHeadOf,
99102
&MCLogicEvalNot,
100103
&MCMathEvalRealToPowerOfReal,
101104
&MCMathFoundationExecRoundRealToNearest,
102105
&MCSortExecSortListAscendingText,
106+
&MCStreamExecWriteToStream,
103107
&MCStringEvalConcatenate,
104108
&MCTypeEvalIsEmpty,
105109
&MCTypeConvertExecSplitStringByDelimiter

toolchain/lc-compile/test.mlc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module test
22

33
use com.livecode.file
4+
use com.livecode.stream
45

56
public handler test()
67
variable tResults as list
@@ -61,6 +62,9 @@ public handler test()
6162

6263
--com.livecode.file
6364
testFile(tResults)
65+
66+
--com.livecode.stream
67+
testStream(tResults)
6468

6569
--com.livecode.binary
6670
--com.livecode.byte
@@ -846,15 +850,13 @@ public handler testData(inout xResults as list)
846850
end handler
847851

848852
public handler testFile(inout xResults as list)
849-
variable tStream as Stream
850-
open read only stream for file "/Users/alilloyd/Desktop/log.txt"
851-
put the result into tStream
852-
853853
variable tData as data
854-
read 7 from stream tStream
855-
put the result into tData
856-
857-
--testLog("File", "ReadFromStream", tText is "Warning", xResults)
854+
put the contents of file "/dev/null" into tData
855+
testLog("File", "GetEmptyContents", tData is empty, xResults)
856+
end handler
857+
858+
public handler testStream(inout xResults as list)
859+
858860
end handler
859861

860862

0 commit comments

Comments
 (0)