-
Notifications
You must be signed in to change notification settings - Fork 128
File module
Wang Renxin edited this page Apr 16, 2015
·
13 revisions
This is a demonstration about how to implement a file accessing module with MY-BASIC.
Add implementation functions:
static int _file_open(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
FILE* fp = 0;
char* fn = 0;
char* fm = 0;
mb_assert(s && l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_string(s, l, &fn));
mb_check(mb_pop_string(s, l, &fm));
mb_check(mb_attempt_close_bracket(s, l));
if(!fn)
return MB_FUNC_ERR;
fp = fopen(fn, fm);
if(!fp)
return MB_FUNC_ERR;
mb_check(mb_push_usertype(s, l, (void*)fp));
return result;
}
static int _file_close(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
FILE* fp = 0;
void* up = 0;
mb_assert(s && l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_usertype(s, l, &up));
mb_check(mb_attempt_close_bracket(s, l));
if(!up)
return MB_FUNC_ERR;
fp = (FILE*)up;
fclose(fp);
return result;
}
static int _file_peek(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
FILE* fp = 0;
void* up = 0;
long ft = 0;
mb_assert(s && l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_usertype(s, l, &up));
mb_check(mb_attempt_close_bracket(s, l));
if(!up)
return MB_FUNC_ERR;
fp = (FILE*)up;
ft = ftell(fp);
mb_check(mb_push_int(s, l, ft));
return result;
}
static int _file_poke(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
FILE* fp = 0;
void* up = 0;
int fo = 0;
mb_assert(s && l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_usertype(s, l, &up));
mb_check(mb_pop_int(s, l, &fo));
mb_check(mb_attempt_close_bracket(s, l));
if(!up)
return MB_FUNC_ERR;
fp = (FILE*)up;
fseek(fp, fo, SEEK_SET);
return result;
}
static int _file_read(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
FILE* fp = 0;
void* up = 0;
int ln = 0;
mb_assert(s && l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_usertype(s, l, &up));
if(mb_has_arg(s, l)) {
mb_check(mb_pop_int(s, l, &ln));
}
mb_check(mb_attempt_close_bracket(s, l));
if(!up)
return MB_FUNC_ERR;
fp = (FILE*)up;
if(ln) {
char* buf = (char*)malloc(ln + 1);
fgets(buf, ln + 1, fp);
buf[ln] = '\0';
mb_check(mb_push_string(s, l, mb_memdup(buf, ln + 1)));
free(buf);
} else {
int ret = fgetc(fp);
mb_check(mb_push_int(s, l, ret));
}
return result;
}
static int _file_write(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
FILE* fp = 0;
void* up = 0;
mb_value_t val;
mb_assert(s && l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_usertype(s, l, &up));
if(!up) {
result = MB_FUNC_ERR;
goto _exit;
}
fp = (FILE*)up;
if(mb_has_arg(s, l)) {
mb_check(mb_pop_value(s, l, &val));
switch(val.type) {
case MB_DT_INT:
fputc(val.value.integer, fp);
break;
case MB_DT_STRING:
fputs(val.value.string, fp);
break;
default:
result = MB_FUNC_ERR;
break;
}
}
_exit:
mb_check(mb_attempt_close_bracket(s, l));
return result;
}
Register them:
mb_register_func(bas, "FOPEN", _file_open);
mb_register_func(bas, "FCLOSE", _file_close);
mb_register_func(bas, "FPEEK", _file_peek);
mb_register_func(bas, "FPOKE", _file_poke);
mb_register_func(bas, "FREAD", _file_read);
mb_register_func(bas, "FWRITE", _file_write);
Script usage:
f = fopen("a.txt", "w+")
fwrite(f, "123") ' write a string
fwrite(f, 45) ' write a byte
print fpeek(f);
fpoke(f, 0)
s = fread(f, 3) ' read a string length 3
i = fread(f) ' read a byte
print fpeek(f);
print s, i;
fclose(f)
- Principles
- Coding
- Data types
- Standalone shell
- Integration
- Customization
- More scripting API
- FAQ