root/native.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- FOPEN_ARGUMENT_TYPE_ERR
- FCLOSE_ARGUMENT_TYPE_ERR
- FGETS_ARGUMENT_TYPE_ERR
- FILE_ALREADY_CLOSED_ERR
- FPUTS_ARGUMENT_TYPE_ERR
- NEW_ARRAY_ARGUMENT_TYPE_ERR
- NEW_ARRAY_ARGUMENT_TOO_FEW_ERR
- NativeErrorCode
- file_finalizer
- crb_nv_print_proc
- check_file_pointer
- crb_nv_fopen_proc
- crb_nv_fclose_proc
- crb_nv_fgets_proc
- crb_nv_fputs_proc
- new_array_sub
- crb_nv_new_array_proc
- crb_nv_new_object_proc
#include <stdio.h>
#include <string.h>
#include "MEM.h"
#include "DBG.h"
#include "crowbar.h"
#include "CRB_dev.h"
#define LINE_BUF_SIZE (1024)
typedef enum {
FOPEN_ARGUMENT_TYPE_ERR = 0,
FCLOSE_ARGUMENT_TYPE_ERR,
FGETS_ARGUMENT_TYPE_ERR,
FILE_ALREADY_CLOSED_ERR,
FPUTS_ARGUMENT_TYPE_ERR,
NEW_ARRAY_ARGUMENT_TYPE_ERR,
NEW_ARRAY_ARGUMENT_TOO_FEW_ERR,
} NativeErrorCode;
extern CRB_MessageFormat crb_native_error_message_format[];
static CRB_NativeLibInfo st_lib_info = {
crb_native_error_message_format,
};
void file_finalizer(CRB_Interpreter *inter, CRB_Object *obj);
static CRB_NativePointerInfo st_file_type_info = {
"crowbar.lang.file",
file_finalizer
};
void
file_finalizer(CRB_Interpreter *inter, CRB_Object *obj)
{
FILE *fp;
fp = (FILE*)CRB_object_get_native_pointer(obj);
if (fp) {
fclose(fp);
}
}
CRB_Value
crb_nv_print_proc(CRB_Interpreter *interpreter,
CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args)
{
CRB_Value value;
char *str;
value.type = CRB_NULL_VALUE;
CRB_check_argument_count(interpreter, env, arg_count, 1);
str = CRB_value_to_string(&args[0]);
printf("%s", str);
MEM_free(str);
return value;
}
static void
check_file_pointer(CRB_Interpreter *inter, CRB_LocalEnvironment *env,
CRB_Object *obj)
{
FILE *fp;
fp = (FILE*)CRB_object_get_native_pointer(obj);
if (fp == NULL) {
CRB_error(inter, env, &st_lib_info, __LINE__,
(int)FILE_ALREADY_CLOSED_ERR,
CRB_MESSAGE_ARGUMENT_END);
}
}
CRB_Value
crb_nv_fopen_proc(CRB_Interpreter *interpreter,
CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
CRB_check_argument_count(interpreter, env, arg_count, 2);
if (args[0].type != CRB_STRING_VALUE
|| args[1].type != CRB_STRING_VALUE) {
CRB_error(interpreter, env, &st_lib_info, __LINE__,
(int)FOPEN_ARGUMENT_TYPE_ERR,
CRB_MESSAGE_ARGUMENT_END);
}
fp = fopen(CRB_object_get_string(args[0].u.object),
CRB_object_get_string(args[1].u.object));
if (fp == NULL) {
value.type = CRB_NULL_VALUE;
} else {
value.type = CRB_NATIVE_POINTER_VALUE;
value.u.object
= CRB_create_native_pointer(interpreter, fp, &st_file_type_info);
}
return value;
}
CRB_Value
crb_nv_fclose_proc(CRB_Interpreter *interpreter,
CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
CRB_check_argument_count(interpreter, env, arg_count, 1);
value.type = CRB_NULL_VALUE;
if (args[0].type != CRB_NATIVE_POINTER_VALUE
|| (!CRB_check_native_pointer_type(args[0].u.object,
&st_file_type_info))) {
CRB_error(interpreter, env, &st_lib_info, __LINE__,
(int)FCLOSE_ARGUMENT_TYPE_ERR,
CRB_MESSAGE_ARGUMENT_END);
}
check_file_pointer(interpreter,env, args[0].u.object);
fp = CRB_object_get_native_pointer(args[0].u.object);
fclose(fp);
CRB_object_set_native_pointer(args[0].u.object, NULL);
return value;
}
CRB_Value
crb_nv_fgets_proc(CRB_Interpreter *interpreter,
CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
char buf[LINE_BUF_SIZE];
char *ret_buf = NULL;
int ret_len = 0;
CRB_check_argument_count(interpreter, env, arg_count, 1);
if (args[0].type != CRB_NATIVE_POINTER_VALUE
|| (!CRB_check_native_pointer_type(args[0].u.object,
&st_file_type_info))) {
CRB_error(interpreter, env, &st_lib_info, __LINE__,
(int)FGETS_ARGUMENT_TYPE_ERR,
CRB_MESSAGE_ARGUMENT_END);
}
check_file_pointer(interpreter,env, args[0].u.object);
fp = CRB_object_get_native_pointer(args[0].u.object);
while (fgets(buf, LINE_BUF_SIZE, fp)) {
int new_len;
new_len = ret_len + strlen(buf);
ret_buf = MEM_realloc(ret_buf, new_len + 1);
if (ret_len == 0) {
strcpy(ret_buf, buf);
} else {
strcat(ret_buf, buf);
}
ret_len = new_len;
if (ret_buf[ret_len-1] == '\n')
break;
}
if (ret_len > 0) {
value.type = CRB_STRING_VALUE;
value.u.object = CRB_create_crowbar_string(interpreter, ret_buf);
} else {
value.type = CRB_NULL_VALUE;
}
return value;
}
CRB_Value
crb_nv_fputs_proc(CRB_Interpreter *interpreter,
CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
CRB_check_argument_count(interpreter, env, arg_count, 2);
value.type = CRB_NULL_VALUE;
if (args[0].type != CRB_STRING_VALUE
|| args[1].type != CRB_NATIVE_POINTER_VALUE
|| (!CRB_check_native_pointer_type(args[1].u.object,
&st_file_type_info))) {
CRB_error(interpreter, env, &st_lib_info, __LINE__,
(int)FPUTS_ARGUMENT_TYPE_ERR,
CRB_MESSAGE_ARGUMENT_END);
}
check_file_pointer(interpreter,env, args[1].u.object);
fp = CRB_object_get_native_pointer(args[1].u.object);
fputs(CRB_object_get_string(args[0].u.object), fp);
return value;
}
CRB_Value
new_array_sub(CRB_Interpreter *inter, CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args, int arg_idx)
{
CRB_Value ret;
CRB_Value value;
int size;
int i;
if (args[arg_idx].type != CRB_INT_VALUE) {
CRB_error(inter, env, &st_lib_info, __LINE__,
(int)NEW_ARRAY_ARGUMENT_TYPE_ERR,
CRB_MESSAGE_ARGUMENT_END);
}
size = args[arg_idx].u.int_value;
ret.type = CRB_ARRAY_VALUE;
ret.u.object = CRB_create_array(inter, size);
CRB_push_value(inter, &ret);
if (arg_idx == arg_count-1) {
value.type = CRB_NULL_VALUE;
for (i = 0; i < size; i++) {
CRB_array_set(inter, env, ret.u.object, i, &value);
}
} else {
for (i = 0; i < size; i++) {
value = new_array_sub(inter, env,
arg_count, args, arg_idx+1);
CRB_array_set(inter, env, ret.u.object, i, &value);
}
}
CRB_pop_value(inter);
return ret;
}
CRB_Value
crb_nv_new_array_proc(CRB_Interpreter *interpreter,
CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args)
{
CRB_Value value;
if (arg_count < 1) {
CRB_error(interpreter, env, &st_lib_info, __LINE__,
(int)NEW_ARRAY_ARGUMENT_TOO_FEW_ERR,
CRB_MESSAGE_ARGUMENT_END);
}
value = new_array_sub(interpreter, env, arg_count, args, 0);
return value;
}
CRB_Value
crb_nv_new_object_proc(CRB_Interpreter *interpreter,
CRB_LocalEnvironment *env,
int arg_count, CRB_Value *args)
{
CRB_Value value;
CRB_check_argument_count(interpreter, env, arg_count, 0);
value.type = CRB_ASSOC_VALUE;
value.u.object = CRB_create_assoc(interpreter);
return value;
}