+added extra importing directories support to shell.

This commit is contained in:
Wang Renxin 2016-01-16 16:30:34 +08:00
parent 74f6f054b4
commit d083dac2ad
2 changed files with 168 additions and 46 deletions

View File

@ -1,5 +1,6 @@
Jan. 16 2016 Jan. 16 2016
Added a range of integer syntax for the LIST statement, eg. LIST(m TO n) Added a range of integer syntax for the LIST statement, eg. LIST(m TO n)
Added extra importing directories support to shell
Jan. 15 2016 Jan. 15 2016
Added a REFLECT statement Added a REFLECT statement

View File

@ -356,7 +356,7 @@ typedef struct _code_line_t {
int size; int size;
} _code_line_t; } _code_line_t;
static _code_line_t* c = 0; static _code_line_t* code = 0;
static _code_line_t* _create_code(void) { static _code_line_t* _create_code(void) {
_code_line_t* result = (_code_line_t*)malloc(sizeof(_code_line_t)); _code_line_t* result = (_code_line_t*)malloc(sizeof(_code_line_t));
@ -364,10 +364,12 @@ static _code_line_t* _create_code(void) {
result->size = _LINE_INC_STEP; result->size = _LINE_INC_STEP;
result->lines = (char**)malloc(sizeof(char*) * result->size); result->lines = (char**)malloc(sizeof(char*) * result->size);
code = result;
return result; return result;
} }
static void _destroy_code(_code_line_t* code) { static void _destroy_code(void) {
int i = 0; int i = 0;
mb_assert(code); mb_assert(code);
@ -491,6 +493,104 @@ static int _save_file(const char* path, const char* txt) {
/* ========================================================} */ /* ========================================================} */
/*
** {========================================================
** Importing directories
*/
typedef struct _importing_dirs_t {
char** dirs;
int count;
int size;
} _importing_dirs_t;
static _importing_dirs_t* importing_dirs = 0;
static _importing_dirs_t* _set_importing_directories(char* dirs) {
if(dirs) {
char* end = dirs + strlen(dirs);
_importing_dirs_t* result = (_importing_dirs_t*)malloc(sizeof(_importing_dirs_t));
result->count = 0;
result->size = _LINE_INC_STEP;
result->dirs = (char**)malloc(sizeof(char*) * result->size);
while(dirs && dirs < end && *dirs) {
int l = 0;
char* buf = 0;
bool_t as = false;
strtok(dirs, ";");
if(!(*dirs)) continue;
if(*dirs == ';') { dirs++; continue; }
if(result->count + 1 == result->size) {
result->size += _LINE_INC_STEP;
result->dirs = (char**)realloc(result->dirs, sizeof(char*) * result->size);
}
l = (int)strlen(dirs);
as = dirs[l - 1] != '/' && dirs[l - 1] != '\\';
buf = (char*)malloc(l + as ? 2 : 1);
memcpy(buf, dirs, l);
if(as) {
buf[l] = '/';
buf[l + 1] = '\0';
} else {
buf[l] = '\0';
}
result->dirs[result->count++] = buf;
while(*buf) {
if(*buf == '\\') *buf = '/';
buf++;
}
dirs += l + 1;
}
importing_dirs = result;
return result;
}
return 0;
}
static void _destroy_importing_directories(void) {
int i = 0;
mb_assert(importing_dirs);
for(i = 0; i < importing_dirs->count; ++i) {
free(importing_dirs->dirs[i]);
}
free(importing_dirs->dirs);
free(importing_dirs);
}
static bool_t _try_import(struct mb_interpreter_t* s, const char* p) {
bool_t result = false;
int i = 0;
for(i = 0; i < importing_dirs->count; i++) {
char* t = 0;
char* d = importing_dirs->dirs[i];
int m = (int)strlen(d);
int n = (int)strlen(p);
char* buf = _pop_mem(m + n + 1);
memcpy(buf, d, m);
memcpy(buf + m, p, n);
buf[m + n] = '\0';
t = _load_file(buf);
if(t) {
if(mb_load_string(bas, t) == MB_FUNC_OK)
result = true;
free(t);
}
_push_mem(buf);
if(result)
break;
}
return result;
}
/* ========================================================} */
/* /*
** {======================================================== ** {========================================================
** Interactive commands ** Interactive commands
@ -505,7 +605,7 @@ static void _clear_screen(void) {
} }
static int _new_program(void) { static int _new_program(void) {
_clear_code(c); _clear_code(code);
return mb_reset(&bas, false); return mb_reset(&bas, false);
} }
@ -520,13 +620,13 @@ static void _list_program(const char* sn, const char* cn) {
lcn = atoi(cn); lcn = atoi(cn);
if(lsn == 0 && lcn == 0) { if(lsn == 0 && lcn == 0) {
long i = 0; long i = 0;
for(i = 0; i < c->count; ++i) { for(i = 0; i < code->count; ++i) {
_printf("%ld]%s", i + 1, c->lines[i]); _printf("%ld]%s", i + 1, code->lines[i]);
} }
} else { } else {
long i = 0; long i = 0;
long e = 0; long e = 0;
if(lsn < 1 || lsn > c->count) { if(lsn < 1 || lsn > code->count) {
_printf("Line number %ld out of bound.\n", lsn); _printf("Line number %ld out of bound.\n", lsn);
return; return;
@ -537,12 +637,12 @@ static void _list_program(const char* sn, const char* cn) {
return; return;
} }
--lsn; --lsn;
e = lcn ? lsn + lcn : c->count; e = lcn ? lsn + lcn : code->count;
for(i = lsn; i < e; ++i) { for(i = lsn; i < e; ++i) {
if(i >= c->count) if(i >= code->count)
break; break;
_printf("%ld]%s\n", i + 1, c->lines[i]); _printf("%ld]%s\n", i + 1, code->lines[i]);
} }
} }
} }
@ -555,7 +655,7 @@ static void _edit_program(const char* no) {
mb_assert(no); mb_assert(no);
lno = atoi(no); lno = atoi(no);
if(lno < 1 || lno > c->count) { if(lno < 1 || lno > code->count) {
_printf("Line number %ld out of bound.\n", lno); _printf("Line number %ld out of bound.\n", lno);
return; return;
@ -565,10 +665,10 @@ static void _edit_program(const char* no) {
_printf("%ld]", lno + 1); _printf("%ld]", lno + 1);
mb_gets(line, _MAX_LINE_LENGTH); mb_gets(line, _MAX_LINE_LENGTH);
l = (int)strlen(line); l = (int)strlen(line);
c->lines[lno] = (char*)realloc(c->lines[lno], l + 2); code->lines[lno] = (char*)realloc(code->lines[lno], l + 2);
strcpy(c->lines[lno], line); strcpy(code->lines[lno], line);
c->lines[lno][l] = '\n'; code->lines[lno][l] = '\n';
c->lines[lno][l + 1] = '\0'; code->lines[lno][l + 1] = '\0';
} }
static void _insert_program(const char* no) { static void _insert_program(const char* no) {
@ -580,7 +680,7 @@ static void _insert_program(const char* no) {
mb_assert(no); mb_assert(no);
lno = atoi(no); lno = atoi(no);
if(lno < 1 || lno > c->count) { if(lno < 1 || lno > code->count) {
_printf("Line number %ld out of bound.\n", lno); _printf("Line number %ld out of bound.\n", lno);
return; return;
@ -589,18 +689,18 @@ static void _insert_program(const char* no) {
memset(line, 0, _MAX_LINE_LENGTH); memset(line, 0, _MAX_LINE_LENGTH);
_printf("%ld]", lno + 1); _printf("%ld]", lno + 1);
mb_gets(line, _MAX_LINE_LENGTH); mb_gets(line, _MAX_LINE_LENGTH);
if(c->count + 1 == c->size) { if(code->count + 1 == code->size) {
c->size += _LINE_INC_STEP; code->size += _LINE_INC_STEP;
c->lines = (char**)realloc(c->lines, sizeof(char*) * c->size); code->lines = (char**)realloc(code->lines, sizeof(char*) * code->size);
} }
for(i = c->count; i > lno; i--) for(i = code->count; i > lno; i--)
c->lines[i] = c->lines[i - 1]; code->lines[i] = code->lines[i - 1];
l = (int)strlen(line); l = (int)strlen(line);
c->lines[lno] = (char*)realloc(0, l + 2); code->lines[lno] = (char*)realloc(0, l + 2);
strcpy(c->lines[lno], line); strcpy(code->lines[lno], line);
c->lines[lno][l] = '\n'; code->lines[lno][l] = '\n';
c->lines[lno][l + 1] = '\0'; code->lines[lno][l + 1] = '\0';
c->count++; code->count++;
} }
static void _alter_program(const char* no) { static void _alter_program(const char* no) {
@ -610,28 +710,28 @@ static void _alter_program(const char* no) {
mb_assert(no); mb_assert(no);
lno = atoi(no); lno = atoi(no);
if(lno < 1 || lno > c->count) { if(lno < 1 || lno > code->count) {
_printf("Line number %ld out of bound.\n", lno); _printf("Line number %ld out of bound.\n", lno);
return; return;
} }
--lno; --lno;
free(c->lines[lno]); free(code->lines[lno]);
for(i = lno; i < c->count - 1; i++) for(i = lno; i < code->count - 1; i++)
c->lines[i] = c->lines[i + 1]; code->lines[i] = code->lines[i + 1];
c->count--; code->count--;
} }
static void _load_program(const char* path) { static void _load_program(const char* path) {
char* txt = _load_file(path); char* txt = _load_file(path);
if(txt) { if(txt) {
_new_program(); _new_program();
_set_code(c, txt); _set_code(code, txt);
free(txt); free(txt);
if(c->count == 1) { if(code->count == 1) {
_printf("Load done. %d line loaded.\n", c->count); _printf("Load done. %d line loaded.\n", code->count);
} else { } else {
_printf("Load done. %d lines loaded.\n", c->count); _printf("Load done. %d lines loaded.\n", code->count);
} }
} else { } else {
_printf("Cannot load file \"%s\".\n", path); _printf("Cannot load file \"%s\".\n", path);
@ -639,14 +739,14 @@ static void _load_program(const char* path) {
} }
static void _save_program(const char* path) { static void _save_program(const char* path) {
char* txt = _get_code(c); char* txt = _get_code(code);
if(!_save_file(path, txt)) { if(!_save_file(path, txt)) {
_printf("Cannot save file \"%s\".\n", path); _printf("Cannot save file \"%s\".\n", path);
} else { } else {
if(c->count == 1) { if(code->count == 1) {
_printf("Save done. %d line saved.\n", c->count); _printf("Save done. %d line saved.\n", code->count);
} else { } else {
_printf("Save done. %d lines saved.\n", c->count); _printf("Save done. %d lines saved.\n", code->count);
} }
} }
free(txt); free(txt);
@ -686,7 +786,10 @@ static void _show_help(void) {
_printf(" %s -e \"expr\" - Evaluate an expression directly\n", _BIN_FILE_NAME); _printf(" %s -e \"expr\" - Evaluate an expression directly\n", _BIN_FILE_NAME);
_printf("\n"); _printf("\n");
_printf("Options:\n"); _printf("Options:\n");
_printf(" -p n - Set memory pool threashold size, n is size in bytes\n"); #if _USE_MEM_POOL
_printf(" -p n - Set memory pool threashold size, n is size in bytes\n");
#endif /* _USE_MEM_POOL */
_printf(" -f \"dirs\" - Set importing directories, separated by semicolon\n");
_printf("\n"); _printf("\n");
_printf("Interactive commands:\n"); _printf("Interactive commands:\n");
_printf(" HELP - View help information\n"); _printf(" HELP - View help information\n");
@ -734,13 +837,13 @@ static int _do_line(void) {
result = _new_program(); result = _new_program();
} else if(_str_eq(line, "RUN")) { } else if(_str_eq(line, "RUN")) {
int i = 0; int i = 0;
mb_assert(c); mb_assert(code);
result = mb_reset(&bas, false); result = mb_reset(&bas, false);
for(i = 0; i < c->count; ++i) { for(i = 0; i < code->count; ++i) {
if(result) if(result)
break; break;
result = mb_load_string(bas, c->lines[i]); result = mb_load_string(bas, code->lines[i]);
} }
if(result == MB_FUNC_OK) if(result == MB_FUNC_OK)
result = mb_run(bas); result = mb_run(bas);
@ -777,7 +880,7 @@ static int _do_line(void) {
char* path = line + strlen(line) + 1; char* path = line + strlen(line) + 1;
_list_directory(path); _list_directory(path);
} else { } else {
_append_line(c, dup); _append_line(code, dup);
} }
return result; return result;
@ -851,6 +954,7 @@ static bool_t _process_parameters(int argc, char* argv[]) {
char* prog = 0; char* prog = 0;
bool_t eval = false; bool_t eval = false;
char* memp = 0; char* memp = 0;
char* diri = 0;
while(i < argc) { while(i < argc) {
if(!memcmp(argv[i], "-", 1)) { if(!memcmp(argv[i], "-", 1)) {
@ -865,6 +969,9 @@ static bool_t _process_parameters(int argc, char* argv[]) {
if(argc > i + 1) if(argc > i + 1)
prog = argv[++i]; prog = argv[++i];
#endif /* _USE_MEM_POOL */ #endif /* _USE_MEM_POOL */
} else if(!memcmp(argv[i] + 1, "f", 1)) {
_CHECK_ARG(argc, i, "-f: Importing directories expected.\n");
diri = argv[++i];
} else { } else {
_printf("Unknown argument: %s.\n", argv[i]); _printf("Unknown argument: %s.\n", argv[i]);
} }
@ -881,6 +988,8 @@ static bool_t _process_parameters(int argc, char* argv[]) {
#else /* _USE_MEM_POOL */ #else /* _USE_MEM_POOL */
mb_unrefvar(memp); mb_unrefvar(memp);
#endif /* _USE_MEM_POOL */ #endif /* _USE_MEM_POOL */
if(diri)
importing_dirs = _set_importing_directories(diri);
if(eval) if(eval)
_evaluate_expression(prog); _evaluate_expression(prog);
else if(prog) else if(prog)
@ -967,6 +1076,16 @@ static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, char* f
} }
} }
static int _on_import(struct mb_interpreter_t* s, const char* p) {
if(!importing_dirs)
return MB_FUNC_ERR;
if(!_try_import(s, p))
return MB_FUNC_ERR;
return MB_FUNC_OK;
}
/* ========================================================} */ /* ========================================================} */
/* /*
@ -981,7 +1100,7 @@ static void _on_startup(void) {
mb_set_memory_manager(_pop_mem, _push_mem); mb_set_memory_manager(_pop_mem, _push_mem);
#endif /* _USE_MEM_POOL */ #endif /* _USE_MEM_POOL */
c = _create_code(); code = _create_code();
#ifdef _HAS_TICKS #ifdef _HAS_TICKS
srand((unsigned)_ticks()); srand((unsigned)_ticks());
@ -993,6 +1112,7 @@ static void _on_startup(void) {
mb_debug_set_stepped_handler(bas, _on_stepped); mb_debug_set_stepped_handler(bas, _on_stepped);
mb_set_error_handler(bas, _on_error); mb_set_error_handler(bas, _on_error);
mb_set_import_handler(bas, _on_import);
#ifdef _HAS_TICKS #ifdef _HAS_TICKS
mb_reg_fun(bas, ticks); mb_reg_fun(bas, ticks);
@ -1001,12 +1121,13 @@ static void _on_startup(void) {
} }
static void _on_exit(void) { static void _on_exit(void) {
_destroy_importing_directories();
mb_close(&bas); mb_close(&bas);
mb_dispose(); mb_dispose();
_destroy_code(c); _destroy_code();
c = 0;
#if _USE_MEM_POOL #if _USE_MEM_POOL
_close_mem_pool(); _close_mem_pool();