On Monday 17 December 2001 14:37, Edwin Groothuis wrote:
> On Mon, Dec 17, 2001 at 01:22:09PM -0600, Mark Roberts wrote:
> > Ummm.. since I have time today, I'm just wondering how you folks thing
> > that a commmand interpreter should work.
>
> Well, look at interp.c on how a command interpreter can be implemented :-)
>
> Your message doesn't make much sense as in "this is my problem" or
> as in "look what I've made, you can use it too". Please clarify.
>
> Edwin
Sorry. It wasn't a problem. And it wasn't a "Look what I've made". It was a
discussion on THEORY. How should a command interpreter be made. So, since we
require a "this is what I've made"... (And since I wanted to post it when I
finished it anyway.... *eg*) Ummm... here goes. It's attached, it's a .c
file... interp.c.
It contains my attempt at a command interpreter. It's not very well
documented, so I'll stab at how it works.
Also, I'd like comments on my IS_SET macro... Basically, if it's included in
the file, feel free to comment on it. I'd REALLY appreciate it. I mean, how
am I to learn if I don't get feedback on the stupid things I do. Since, there
WILL be something stupid in there... just finding it... ;)
The ideas are mostly mine, but I did borrow and test on CVagrant...
Imagine: trying to redo the command interpreter in ROM... with a random idea
of how it might be made!!!!
Ummm.... if you see ANYTHING in the file that you'd like to comment on...
please do. Keep the flames to my personal email only.. and constructive
criticism to open channels. Merry Christmas, and God bless you!
Mark
#include <stdio.h>
#include <stdlib.h>
/*******************
* Defined Macros *
*******************/
/*
Unlimited bits, it operates based on the bit number... bit 0, bit 1, etc...
on to bit 31 in the 1st long.
There are an infinite number of longs... well, as many as you malloc'ated.
There's no error checking, but... there's really no need.
Just don't make a mistake. ;)
*/
#define ISSET(a, b) (*((a)+((b)/32))&(1<<((b)%32)))
#define SETBIT(a, b) (*((a)+((b)/32))|=(1<<((b)%32)))
#define NOTBIT(a, b) (*((a)+((b)/32))&=(~(1<<((b)%32))))
#define XORBIT(a, b) (*((a)+((b)/32))^=(1<<((b)%32)))
/*
My feeble attempt at a upper and lower macro...
obviously for use on a character.
Someone told me there's a __LOWER__ macro or something...
I never found it. I made my own.
*/
#define LOWER(a) (((a) > 64 && (a) < 97)?((a)+32) : (a))
#define UPPER(a) (((a) > 96 && (a) < 123)?((a)-32) : (a))
typedef struct ch_type
{
char name[12]; /* ch's name */
long * cmds; /* commands allowed. Nochannel, turn off their communication commands*/
}CH_DATA;
typedef struct command_type
{
char name[20]; /* Command name */
int requires, expects, active;
/* It REQUIRES this to run the command,
It EXPECTS this many arguments.
And is the command an active command...
Yes, this means you can turn off a whole command in mid game...
Imagine...
">Say Hi Joe!"
"Huh?"
;)
*/
void (*funp)(CH_DATA *ch, char **args); /* function pointer.. nothing special */
}cmd_type;
int strpre(const char *s, const char *t);
void command_interp(CH_DATA *ch, char *input);
void c_halt(CH_DATA *, char **);
const cmd_type player_commands[] = {
{ "halt", 0, 0, 1, c_halt },
{ "", 0, 0, 0, 0 }
};
int main(int argc, char ** argv){
CH_DATA *ch;
strcpy(ch->name, "Mark");
ch->cmds=(long *)malloc(sizeof(long)*1);
*ch->cmds=-1; /* Set all bits to on */
command_interp(ch, *(argv+1));
free(ch->cmds);
return 0;
}
void c_halt(CH_DATA *ch, char ** input){
printf("YOU HALTED ME!!!\n");
}
void command_interp(CH_DATA *ch, char *input){
const cmd_type * command=player_commands; /*command pointer, at the command table */
char ** cmd;
while (*input == ' ') /*eliminate white space before malloc'ating your stuff */
++input;
cmd=(char **)malloc(sizeof(char *)*strlen(input));
*cmd=input;
for (; *input != ' ' && *input != 0; ++input); /* find the 1st space */
*input++=0; /*turn space to null */
for (; !strpre(*cmd, command->name) && *command->name && command->active; ++command);
/*I used the positive &&'s because && shortcircuts... more efficient, I think */
if (*(command->name) && ISSET(ch->cmds, command->requires)){
switch(command->expects){ /*determine what command requires*/
case 0:
command->funp(ch, 0);
break;
case 1:
*(cmd+1)=input;
command->funp(ch, cmd);
break;
case 2:
*(cmd+1)=input;
for(; *input != ' ' && *input; ++input); /* Remember, for is a pre-test*/
*(cmd+2)=input;
command->funp(ch, cmd);
case -1:
default:
{
int num=1;
*(cmd+1)=input;
for(; *input; ++input)
if (*input == ' '){
while(*input == ' ')
++input;
*(cmd+num)=(++input);
++num;
}
*(cmd+num)=0;
}
break;
}
}
else{
printf("Invalid Command '%s'.\n\r", *cmd);
return;
}
free(cmd);
}
/*
I'd like some feedback on how I made my
strpre function...
I more or less edited the one in CVagrant...
except that he released a faulty strpre...
(By his own admission).
It hardly resembles his anymore.
Conceptually... but.
Hmmm....
*/
int strpre(const char *s, const char *t){
if (!s || !t || !*s || !*t)
return 0;
while (LOWER(*s) == LOWER(*t)){
if (!*(++s))
return 1;
if (!*(++t))
return 0;
}
return 0;
}
/[EMAIL PROTECTED]
Send your comments, questions, and ideas here.
I'd appreciate feedback on how you think
a command interpreter should be made.
I'd appreciate your feedback on ANYTHING in this file
And whether or not I forgot something.
:) Please?
Mark Robrts
*/