#include "command.h" #include "argument.h" #include "console.h" #include "debugger.h" #include "math.h" COMMAND* cmdfind(COMMAND* command_list, const char* name, COMMAND** link) { COMMAND* cur=command_list; if(!cur->name) return 0; COMMAND* prev=0; while(cur) { if(arraycontains(cur->name, name)) { if(link) *link=prev; return cur; } prev=cur; cur=cur->next; } return 0; } COMMAND* cmdinit() { COMMAND* cmd=(COMMAND*)emalloc(sizeof(COMMAND), "cmdinit:cmd"); memset(cmd, 0, sizeof(COMMAND)); return cmd; } void cmdfree(COMMAND* cmd_list) { COMMAND* cur=cmd_list; while(cur) { efree(cur->name, "cmdfree:cur->name"); COMMAND* next=cur->next; efree(cur, "cmdfree:cur"); cur=next; } } bool cmdnew(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly) { if(!command_list or !cbCommand or !name or !*name or cmdfind(command_list, name, 0)) return false; COMMAND* cmd; bool nonext=false; if(!command_list->name) { cmd=command_list; nonext=true; } else cmd=(COMMAND*)emalloc(sizeof(COMMAND), "cmdnew:cmd"); memset(cmd, 0, sizeof(COMMAND)); cmd->name=(char*)emalloc(strlen(name)+1, "cmdnew:cmd->name"); strcpy(cmd->name, name); cmd->cbCommand=cbCommand; cmd->debugonly=debugonly; COMMAND* cur=command_list; if(!nonext) { while(cur->next) cur=cur->next; cur->next=cmd; } return true; } COMMAND* cmdget(COMMAND* command_list, const char* cmd) { char new_cmd[deflen]=""; strcpy(new_cmd, cmd); int len=strlen(new_cmd); int start=0; while(new_cmd[start]!=' ' and startcbCommand; found->cbCommand=cbCommand; found->debugonly=debugonly; return old; } bool cmddel(COMMAND* command_list, const char* name) { COMMAND* prev=0; COMMAND* found=cmdfind(command_list, name, &prev); if(!found) return false; efree(found->name, "cmddel:found->name"); if(found==command_list) { COMMAND* next=command_list->next; if(next) { memcpy(command_list, command_list->next, sizeof(COMMAND)); command_list->next=next->next; efree(next, "cmddel:next"); } else memset(command_list, 0, sizeof(COMMAND)); } else { prev->next=found->next; efree(found, "cmddel:found"); } return true; } /* command_list: command list cbUnknownCommand: function to execute when an unknown command was found cbCommandProvider: function that provides commands (fgets for example), does not return until a command was found cbCommandFinder: non-default command finder error_is_fatal: error return of a command callback stops the command processing */ CMDRESULT cmdloop(COMMAND* command_list, CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal) { if(!cbUnknownCommand or !cbCommandProvider) return STATUS_ERROR; char command[deflen]=""; bool bLoop=true; while(bLoop) { if(!cbCommandProvider(command, deflen)) break; if(strlen(command)) { argformat(command); //default formatting COMMAND* cmd; if(!cbCommandFinder) //'clean' command processing cmd=cmdget(command_list, command); else //'dirty' command processing cmd=cbCommandFinder(command_list, command); if(!cmd or !cmd->cbCommand) //unknown command { char* argv[1]; *argv=command; CMDRESULT res=cbUnknownCommand(1, argv); if((error_is_fatal and res==STATUS_ERROR) or res==STATUS_EXIT) bLoop=false; } else { if(cmd->debugonly and !DbgIsDebugging()) { dputs("this command is debug-only"); if(error_is_fatal) bLoop=false; } else { int argcount=arggetcount(command); char** argv=(char**)emalloc((argcount+1)*sizeof(char*), "cmdloop:argv"); argv[0]=command; for(int i=0; icbCommand(argcount+1, argv); for(int i=0; i2) //x*=3 -> x=x*3 { char op=*a; *a=0; sprintf(str, "mov %s,%s%c%s", string, string, op, found); } else sprintf(str, "mov %s,%s", string, found); strcpy(string, str); } else if((string[len-1]=='+' and string[len-2]=='+') or (string[len-1]=='-' and string[len-2]=='-')) //eax++/eax-- { string[len-2]=0; char op=string[len-1]; sprintf(str, "mov %s,%s%c1", string, string, op); strcpy(string, str); } efree(str, "specialformat:str"); } /* - 'default' command finder, with some custom rules */ COMMAND* cmdfindmain(COMMAND* cmd_list, char* command) { COMMAND* cmd=cmdfind(cmd_list, command, 0); if(!cmd) { specialformat(command); cmd=cmdget(cmd_list, command); } if(!cmd or !cmd->cbCommand) mathformat(command); return cmd; } CMDRESULT cmddirectexec(COMMAND* cmd_list, const char* cmd) { if(!cmd or !strlen(cmd)) return STATUS_ERROR; char command[deflen]=""; strcpy(command, cmd); argformat(command); COMMAND* found=cmdfindmain(cmd_list, command); if(!found or !found->cbCommand) return STATUS_ERROR; if(found->debugonly and !DbgIsDebugging()) return STATUS_ERROR; int argcount=arggetcount(command); char** argv=(char**)emalloc((argcount+1)*sizeof(char*), "cmddirectexec:argv"); argv[0]=command; for(int i=0; icbCommand(argcount+1, argv); for(int i=0; i