Skip to content

Commit

Permalink
added and mapped noninteractive nqp::readlinefh
Browse files Browse the repository at this point in the history
  • Loading branch information
FROGGS committed Jul 13, 2013
1 parent 3f2908e commit 36e3254
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 2 deletions.
7 changes: 7 additions & 0 deletions lib/MAST/Ops.nqp
Expand Up @@ -3540,6 +3540,13 @@ class MAST::Ops {
$MVM_operand_read_reg +| $MVM_operand_obj
]
),
'readline_fh', nqp::hash(
'code', 50,
'operands', [
$MVM_operand_write_reg +| $MVM_operand_str,
$MVM_operand_read_reg +| $MVM_operand_obj
]
),
],
[
'getenv', nqp::hash(
Expand Down
2 changes: 1 addition & 1 deletion nqp-cc/src/QASTOperationsMAST.nqp
Expand Up @@ -1313,7 +1313,7 @@ QAST::MASTOperations.add_core_moarop_mapping('setencoding', 'setencoding');
QAST::MASTOperations.add_core_moarop_mapping('tellfh', 'tell_fh');
QAST::MASTOperations.add_core_moarop_mapping('printfh', 'write_fhs');
# QAST::MASTOperations.add_core_moarop_mapping('sayfh', ?);
# QAST::MASTOperations.add_core_moarop_mapping('readlinefh', ?);
QAST::MASTOperations.add_core_moarop_mapping('readlinefh', 'readline_fh');
# QAST::MASTOperations.add_core_moarop_mapping('readlineintfh', ?);
QAST::MASTOperations.add_core_moarop_mapping('readallfh', 'readall_fh');
QAST::MASTOperations.add_core_moarop_mapping('eoffh', 'eof');
Expand Down
4 changes: 4 additions & 0 deletions src/core/interp.c
Expand Up @@ -2740,6 +2740,10 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
MVM_file_close_fh(tc, GET_REG(cur_op, 0).o);
cur_op += 2;
break;
case MVM_OP_readline_fh:
GET_REG(cur_op, 0).s = MVM_file_readline_fh(tc, GET_REG(cur_op, 2).o);
cur_op += 4;
break;
case MVM_OP_read_fhs:
GET_REG(cur_op, 0).s = MVM_file_read_fhs(tc, GET_REG(cur_op, 2).o,
GET_REG(cur_op, 4).i64);
Expand Down
1 change: 1 addition & 0 deletions src/core/oplist
Expand Up @@ -471,6 +471,7 @@ BANK 5 io
0x2F readlall_fh w(str) r(obj)
0x30 tell_fh w(int64) r(obj)
0x31 eof w(int64) r(obj)
0x32 readline_fh w(str) r(obj)

BANK 6 processthread
0x00 getenv w(str) r(str)
Expand Down
8 changes: 7 additions & 1 deletion src/core/ops.c
Expand Up @@ -2789,6 +2789,12 @@ static MVMOpInfo MVM_op_info_io[] = {
2,
{ MVM_operand_write_reg | MVM_operand_int64, MVM_operand_read_reg | MVM_operand_obj }
},
{
MVM_OP_readline_fh,
"readline_fh",
2,
{ MVM_operand_write_reg | MVM_operand_str, MVM_operand_read_reg | MVM_operand_obj }
},
};
static MVMOpInfo MVM_op_info_processthread[] = {
{
Expand Down Expand Up @@ -3100,7 +3106,7 @@ static unsigned char MVM_opcounts_by_bank[] = {
52,
54,
132,
50,
51,
31,
17,
};
Expand Down
1 change: 1 addition & 0 deletions src/core/ops.h
Expand Up @@ -483,6 +483,7 @@
#define MVM_OP_readall_fh 47
#define MVM_OP_tell_fh 48
#define MVM_OP_eof 49
#define MVM_OP_readline_fh 50

/* Op name defines for bank processthread. */
#define MVM_OP_getenv 0
Expand Down
51 changes: 51 additions & 0 deletions src/io/fileops.c
Expand Up @@ -211,6 +211,57 @@ void MVM_file_close_fh(MVMThreadContext *tc, MVMObject *oshandle) {
}
}

/* reads a line from a filehandle. */
MVMString * MVM_file_readline_fh(MVMThreadContext *tc, MVMObject *oshandle) {
MVMString *result;
apr_status_t rv;
MVMOSHandle *handle;
char ch;
char *buf;
apr_off_t offset = 0;
apr_off_t fetched = 0;
apr_off_t bytes_read = 0;

verify_filehandle_type(tc, oshandle, &handle, "readline from filehandle");

if ((rv = apr_file_seek(handle->body.file_handle, APR_CUR, &offset)) != APR_SUCCESS) {
MVM_exception_throw_apr_error(tc, rv, "Failed to tell position of filehandle in readline(1): ");
}

while (apr_file_getc(&ch, handle->body.file_handle) == APR_SUCCESS && ch != 10 && ch != 13) {
bytes_read++;
}

/* have a look if it is a windows newline, and step back if not. */
if (ch == 13 && apr_file_getc(&ch, handle->body.file_handle) == APR_SUCCESS && ch != 10) {
fetched--;
}

if ((rv = apr_file_seek(handle->body.file_handle, APR_CUR, &fetched)) != APR_SUCCESS) {
MVM_exception_throw_apr_error(tc, rv, "Failed to tell position of filehandle in readline(2): ");
}

if ((rv = apr_file_seek(handle->body.file_handle, APR_SET, &offset)) != APR_SUCCESS) {
MVM_exception_throw_apr_error(tc, rv, "Failed to tell position of filehandle in readline(3)");
}

buf = malloc((int)(bytes_read + 1));

if ((rv = apr_file_read(handle->body.file_handle, buf, &bytes_read)) != APR_SUCCESS) {
free(buf);
MVM_exception_throw_apr_error(tc, rv, "readline from filehandle failed: ");
}

if ((rv = apr_file_seek(handle->body.file_handle, APR_SET, &fetched)) != APR_SUCCESS) {
MVM_exception_throw_apr_error(tc, rv, "Failed to tell position of filehandle in readline(4)");
}
/* XXX should this take a type object? */
result = MVM_decode_C_buffer_to_string(tc, tc->instance->VMString, buf, bytes_read, handle->body.encoding_type);
free(buf);

return result;
}

/* reads a string from a filehandle. */
MVMString * MVM_file_read_fhs(MVMThreadContext *tc, MVMObject *oshandle, MVMint64 length) {
MVMString *result;
Expand Down
1 change: 1 addition & 0 deletions src/io/fileops.h
Expand Up @@ -7,6 +7,7 @@ void MVM_file_chmod(MVMThreadContext *tc, MVMString *f, MVMint64 flag);
MVMint64 MVM_file_exists(MVMThreadContext *tc, MVMString *f);
MVMObject * MVM_file_open_fh(MVMThreadContext *tc, MVMObject *type_object, MVMString *filename, MVMint64 flag, MVMint64 encoding_flag);
void MVM_file_close_fh(MVMThreadContext *tc, MVMObject *oshandle);
MVMString * MVM_file_readline_fh(MVMThreadContext *tc, MVMObject *oshandle);
MVMString * MVM_file_read_fhs(MVMThreadContext *tc, MVMObject *oshandle, MVMint64 length);
MVMString * MVM_file_readall_fh(MVMThreadContext *tc, MVMObject *oshandle);
MVMString * MVM_file_slurp(MVMThreadContext *tc, MVMString *filename, MVMint64 encoding_flag);
Expand Down

0 comments on commit 36e3254

Please sign in to comment.