/* Copyright Yann Weber This file is part of asmsh. asmsh is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. asmsh is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with asmsh. If not, see . */ #include "shell_cmds.h" const asmsh_cmd_t *asmsh_cmd_match(const char *text, int tlen) { for(const asmsh_cmd_t *cmd=asmsh_CMDS; cmd->str; cmd++) { const int clen = strlen(cmd->str); if(cmd->sm && tlen >= cmd->sm && tlen < clen) { if(!strncmp(cmd->str, text, tlen)) { return cmd; } continue; } else if(tlen != clen) { continue; } else { int cmp = strncmp(text, cmd->str, tlen); if(cmp < 0) { break; } else if(!cmp) { return cmd; } } } return NULL; } asmsh_cmd_args_t *asmsh_cmd_parse(const char *cmd) { asmsh_cmd_args_t *ret; int cmdlen, err, argno; const char *ptr, *arg; if(!cmd || !*cmd || *cmd != '.') { return NULL; } if(!(ret = malloc(sizeof(*ret)))) { asmsh_log_fatal("Unable to allocate command"); return NULL; } bzero(ret, sizeof(*ret)); cmdlen=0; for(ptr=cmd; *ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '\n'; ptr++) { cmdlen++; } if(cmdlen > ASMSH_CMD_MAXLEN) { asmsh_log_error("Invalid command"); //TODO printf command err=EINVAL; goto err; } strncpy(ret->cmd, cmd, cmdlen); ret->cmd[cmdlen] = '\0'; // lstrip white chars for(ptr; *ptr && (*ptr == ' ' || *ptr == '\t' || *ptr == '\n'); ptr++); if(!*ptr) { // end of command ret->args[0] = NULL; return ret; } arg = ptr; argno=0; do { int arglen = 0; for(ptr; *ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '\n'; ptr++) { arglen++; } ret->args[argno] = strndup(arg, arglen); if(!ret->args[argno]) { asmsh_log_error("strndup args failed"); err=errno; goto err; } argno++; if(argno >= ASMSH_CMD_MAXARG) { //too many arguments asmsh_log_error("too many arguments"); err=EINVAL; goto err; } // lstrip white chars for(ptr; *ptr && (*ptr == ' ' || *ptr == '\t' || *ptr == '\n'); ptr++); arg=ptr; }while(*ptr); ret->argc = argno; ret->args[argno] = NULL; return ret; err: for(char **p=ret->args; *p; p++) { free(*p); } errno = err; free(ret); return NULL; } int asmsh_cmd_bcode(asmsh_t *sh, char *argbuf, int bufsz, int argc, char **args) { asmsh_bytecode_t bcode; char _buf[256], *buf; const char *instr; int ret; if(!argbuf) { buf=_buf; bufsz=256; } else { buf=argbuf; } if(argc == 0) { if(sh->last_instr == NULL) { asmsh_log_error("No instruction compiled yet"); return -1; } bcode = sh->last_bcode; instr = sh->last_instr; } else { char **arg; char code[256]; int sz = 0; for(arg=args;*arg;arg++) { sz+=snprintf(code+sz, 255-sz, "%s", *arg); if(*(arg+1)) { code[sz] = ' '; sz++; } } code[sz]='\0'; dprintf(2, "INSTR='%s'\n", code); if(asmsh_asmc_compile(sh->cctx, code, &bcode) < 0) { return -1; } instr = code; } ret = snprintf(buf, bufsz, "%s = (%02db) ", instr, bcode.size); for(int i=0; i