HelenOS sources
This source file includes following definitions.
- bi_textfile_declare
- bi_textfile_bind
- bi_textfile_openread
- bi_textfile_openwrite
- bi_textfile_close
- bi_textfile_readline
- bi_textfile_writeline
- bi_textfile_is_eof
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "../bigint.h"
#include "../builtin.h"
#include "../debug.h"
#include "../mytypes.h"
#include "../os/os.h"
#include "../rdata.h"
#include "../run.h"
#include "../strtab.h"
#include "bi_textfile.h"
#define LINE_BUF_SIZE 256
static char line_buf[LINE_BUF_SIZE];
static void bi_textfile_openread(run_t *run);
static void bi_textfile_openwrite(run_t *run);
static void bi_textfile_close(run_t *run);
static void bi_textfile_readline(run_t *run);
static void bi_textfile_writeline(run_t *run);
static void bi_textfile_is_eof(run_t *run);
void bi_textfile_declare(builtin_t *bi)
{
builtin_code_snippet(bi,
"class TextFile is\n"
" var f : resource;\n"
"\n"
" fun OpenRead(fname : string), builtin;\n"
" fun OpenWrite(fname : string), builtin;\n"
" fun Close(), builtin;\n"
" fun ReadLine() : string, builtin;\n"
" fun WriteLine(line : string), builtin;\n"
"\n"
" prop EOF : bool is\n"
" get is\n"
" return is_eof();\n"
" end\n"
" end\n"
"\n"
" fun is_eof() : bool, builtin;\n"
"end\n");
}
void bi_textfile_bind(builtin_t *bi)
{
builtin_fun_bind(bi, "TextFile", "OpenRead", bi_textfile_openread);
builtin_fun_bind(bi, "TextFile", "OpenWrite", bi_textfile_openwrite);
builtin_fun_bind(bi, "TextFile", "Close", bi_textfile_close);
builtin_fun_bind(bi, "TextFile", "ReadLine", bi_textfile_readline);
builtin_fun_bind(bi, "TextFile", "WriteLine", bi_textfile_writeline);
builtin_fun_bind(bi, "TextFile", "is_eof", bi_textfile_is_eof);
}
static void bi_textfile_openread(run_t *run)
{
rdata_var_t *fname_var;
const char *fname;
FILE *file;
rdata_resource_t *resource;
rdata_var_t *res_var;
rdata_value_t *res_val;
rdata_var_t *self_f_var;
#ifdef DEBUG_RUN_TRACE
printf("Called TextFile.OpenRead()\n");
#endif
fname_var = run_local_vars_lookup(run, strtab_get_sid("fname"));
assert(fname_var);
assert(fname_var->vc == vc_string);
fname = fname_var->u.string_v->value;
file = fopen(fname, "rt");
if (file == NULL) {
printf("Error: Failed opening file '%s' for reading.\n",
fname);
exit(1);
}
resource = rdata_resource_new();
resource->data = (void *) file;
res_var = rdata_var_new(vc_resource);
res_var->u.resource_v = resource;
res_val = rdata_value_new();
res_val->var = res_var;
self_f_var = builtin_get_self_mbr_var(run, "f");
rdata_var_write(self_f_var, res_val);
}
static void bi_textfile_openwrite(run_t *run)
{
rdata_var_t *fname_var;
const char *fname;
FILE *file;
rdata_resource_t *resource;
rdata_var_t *res_var;
rdata_value_t *res_val;
rdata_var_t *self_f_var;
#ifdef DEBUG_RUN_TRACE
printf("Called TextFile.OpenWrite()\n");
#endif
fname_var = run_local_vars_lookup(run, strtab_get_sid("fname"));
assert(fname_var);
assert(fname_var->vc == vc_string);
fname = fname_var->u.string_v->value;
file = fopen(fname, "wt");
if (file == NULL) {
printf("Error: Failed opening file '%s' for writing.\n",
fname);
exit(1);
}
resource = rdata_resource_new();
resource->data = (void *) file;
res_var = rdata_var_new(vc_resource);
res_var->u.resource_v = resource;
res_val = rdata_value_new();
res_val->var = res_var;
self_f_var = builtin_get_self_mbr_var(run, "f");
rdata_var_write(self_f_var, res_val);
}
static void bi_textfile_close(run_t *run)
{
FILE *file;
rdata_var_t *self_f_var;
run_proc_ar_t *proc_ar;
self_f_var = builtin_get_self_mbr_var(run, "f");
assert(self_f_var->vc == vc_resource);
file = (FILE *) self_f_var->u.resource_v->data;
if (file == NULL) {
printf("Error: TextFile not valid for Close.\n");
exit(1);
}
#ifdef DEBUG_RUN_TRACE
printf("Close text file.\n");
#endif
if (fclose(file) != 0) {
printf("Error: I/O error while closing file.\n");
exit(1);
}
self_f_var->u.resource_v->data = NULL;
proc_ar = run_get_current_proc_ar(run);
proc_ar->retval = NULL;
}
static void bi_textfile_readline(run_t *run)
{
FILE *file;
rdata_var_t *self_f_var;
rdata_string_t *str;
rdata_var_t *str_var;
rdata_value_t *str_val;
rdata_item_t *str_item;
run_proc_ar_t *proc_ar;
char *cp;
self_f_var = builtin_get_self_mbr_var(run, "f");
assert(self_f_var->vc == vc_resource);
file = (FILE *) self_f_var->u.resource_v->data;
if (file == NULL) {
printf("Error: TextFile not valid for ReadLine.\n");
exit(1);
}
if (feof(file)) {
printf("Error: Reading beyond end of file.\n");
exit(1);
}
if (fgets(line_buf, LINE_BUF_SIZE, file) == NULL)
line_buf[0] = '\0';
if (ferror(file)) {
printf("Error: I/O error while reading file.\n");
exit(1);
}
cp = line_buf;
while (*cp != '\0')
++cp;
if (cp != line_buf && cp[-1] == '\n')
cp[-1] = '\0';
#ifdef DEBUG_RUN_TRACE
printf("Read '%s' from file.\n", line_buf);
#endif
str = rdata_string_new();
str->value = os_str_dup(line_buf);
str_var = rdata_var_new(vc_string);
str_var->u.string_v = str;
str_val = rdata_value_new();
str_val->var = str_var;
str_item = rdata_item_new(ic_value);
str_item->u.value = str_val;
proc_ar = run_get_current_proc_ar(run);
proc_ar->retval = str_item;
}
static void bi_textfile_writeline(run_t *run)
{
FILE *file;
rdata_var_t *self_f_var;
rdata_var_t *line_var;
const char *line;
run_proc_ar_t *proc_ar;
line_var = run_local_vars_lookup(run, strtab_get_sid("line"));
assert(line_var);
assert(line_var->vc == vc_string);
line = line_var->u.string_v->value;
self_f_var = builtin_get_self_mbr_var(run, "f");
assert(self_f_var->vc == vc_resource);
file = (FILE *) self_f_var->u.resource_v->data;
if (file == NULL) {
printf("Error: TextFile not valid for WriteLine.\n");
exit(1);
}
#ifdef DEBUG_RUN_TRACE
printf("Write '%s' to file.\n", line);
#endif
if (fprintf(file, "%s\n", line) < 0) {
printf("Error: I/O error while writing file.\n");
exit(1);
}
proc_ar = run_get_current_proc_ar(run);
proc_ar->retval = NULL;
}
static void bi_textfile_is_eof(run_t *run)
{
FILE *file;
rdata_var_t *self_f_var;
bool_t eof_flag;
rdata_bool_t *eof_bool;
rdata_var_t *eof_var;
rdata_value_t *eof_val;
rdata_item_t *eof_item;
run_proc_ar_t *proc_ar;
self_f_var = builtin_get_self_mbr_var(run, "f");
assert(self_f_var->vc == vc_resource);
file = (FILE *) self_f_var->u.resource_v->data;
if (file == NULL) {
printf("Error: TextFile not valid for EOF check.\n");
exit(1);
}
eof_flag = feof(file) ? b_true : b_false;
#ifdef DEBUG_RUN_TRACE
printf("Read EOF flag '%s'.\n", eof_flag ? "true" : "false");
#endif
eof_bool = rdata_bool_new();
eof_bool->value = eof_flag;
eof_var = rdata_var_new(vc_bool);
eof_var->u.bool_v = eof_bool;
eof_val = rdata_value_new();
eof_val->var = eof_var;
eof_item = rdata_item_new(ic_value);
eof_item->u.value = eof_val;
proc_ar = run_get_current_proc_ar(run);
proc_ar->retval = eof_item;
}
HelenOS homepage, sources at GitHub