123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- /* Copyright Yann Weber <asmsh@yannweb.net>
- 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 <https://www.gnu.org/licenses/>.
- */
- #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<sizeof(bcode.bytes); i++)
- {
- char repr[3] = "..";
- if(i<bcode.size)
- {
- snprintf(repr, 3, "%02x", bcode.bytes[i]);
- }
- repr[2]='\0';
- ret += snprintf(buf+ret, bufsz-ret, "%s%s%s",
- i&&(i%4==0)?" ":"",i==8?" ":"",
- repr);
- }
- buf[ret] = '\0';
- return 0;
- }
|