PDA

View Full Version : separing commands


mile1982
09-13-2004, 01:45 AM
hey there

well i have a small problem with my code. when for example :

" /bin/sleep 10 & ls -l mila > xyz " is entered, the program is supposed to separate the two commands 1) /bin/sleep 10 & and 2) ls -l mila > xyz. im not sure of how to achieve this. my current program stores both commands as one, eg: the same command is entered as above:

Command[0]:
com_pathname=/bin/sleep
argc=5
argv[0]=/bin/sleep
argv[1]=10
argv[2]=ls
argv[3]=-lt
argv[4]=mila
#######
redirect_in=NULL
redirect_out=pero
com_suffix=

the correct version would be:
Command[0]:
com_pathname=/bin/sleep
argc=2
argv[0]=/bin/sleep
argv[1]=10
#######
redirect_in=NULL
redirect_out=pero
com_suffix= &

Command[1]:
com_pathname=ls
argc=3
argv[0]=ls
argv[1]=-lt
argv[2]=mila
#######
redirect_in=NULL
redirect_out=pero
com_suffix=

---

when only one command is entered, the program stores correctly.
here's the code so if anyone could help, would appreciate it:


//---------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*function prototypes*/
void student_details();
void option_exit();
void printComStruct(struct command *com);

//---------------------------------------------------------------------------------------------------

struct command {

char *com_pathname; // what is the path name of the command

int argc; // the number of arguments to the command
// including the command itself

char *argv[40]; // pointers to strings, each string
// is an argument for the command, including
// argument "0". The last pointer should
// be set to NULL.

char *redirect_in; // if this is not NULL, then the standard input
// is redirected to the given file name

char *redirect_out; // if this is not NULL, then the standard output
// is redirected to the given file name

char *com_suffix; // ' ' - no command suffix (last command);
// '&' - the command is followed by '&'
// ';' - the command is followed by ';';
// '|' - the command is followed by '|'.
};

//---------------------------------------------------------------------------------------------------

int main() {

/*declaration*/
char *guess = "exit";
char line[256];
char *break_set = "\n\f\v\\\"~!@#$%^*()_=+'' [] {}:?,";

int nCommands = 0; // number of commands in a command line
int state = 0; // if a file has been redirected either way
// this changes to 1
int i = 0;
int c;

struct command com[10]; // storage for each command

com->argc = 0;

student_details(); /*present information about the user*/

/*introduction of what the program is supposed to do*/
printf(" Hello and welcome to my program\n");
printf("\n");
printf(" This program will repeatedly take one line of input \n");
printf(" from the console until the input line is 'exit'. For \n");
printf(" each input line, break it down into tokens. The input \n");
printf(" line should result in a 'dump' of the raw contents of \n");
printf(" several structures, depending on how many commands \n");
printf(" were given.\n");
printf("\n");

printf(" Mila's Shell> ");

// increment number of commands by 1 because
// it is start of the program
nCommands++;

while (gets (line)) {

char *tokp;
char *sp = line;

while ((tokp = strtok(sp,break_set)) != NULL) {


if (strlen(tokp)==1) { /* if the length of the character is 1 */

switch (*tokp) { /* switch on the first char */


case '>': /* output is redirected */

state = 1;
break;

case '<': /* output is redirected */

state = 2;
break;

case '|': /* directs the standard output of one Unix command into the
standard input of another Unix command. */

com[nCommands-1].com_suffix = tokp;
break;

case '&': /* a command shall run in the background */

// save in suffix
com[nCommands-1].com_suffix = tokp;
break;

case ';': /* end of command */

// save in suffix
com[nCommands-1].com_suffix = tokp;
break;

} // end switch

} // end if

// ---------------------

else {

if (state == 1) {

com[nCommands-1].redirect_out = tokp;
}

if (state == 2) {

com[nCommands-1].redirect_in = tokp;
}

else if (state == 0) {

// save token as argument for command
// argv = arguments for commands
// argc = number of arguments to the command;
com->argc++;
com->argv[com->argc -1] = tokp;

/*
* everytime the program is started the first argument of
* the input line is stored as the first command
*/

if (com->argc == 1) {

com[0].com_pathname = tokp;
}

// -------------------------

com[nCommands-1].redirect_in = NULL;
com[nCommands-1].redirect_out = NULL;
com[nCommands-1].com_suffix = NULL;

// ---------------------------

sp = NULL; // continue in this string
} // end else if

} // end else

} // end while

/*
* checks if the input line equals 'exit'. if it does
* the function option_exit is called and the
* program terminated. if it does not, another
* prompt is displayed to allow the user to enter
* more commands
*/

if(strcmp(line,guess) == 0) {

option_exit();
}

else {

com->argv[com->argc] = NULL;

// print command structures
printf("\n");
fprintf(stderr, "*** ICT310 construct dump begin ***\n");

for (i = 0; i < nCommands; ++i) {

fprintf(stderr, " Command[%d]: \n", i);
printComStruct(&com[i]);

for (c = 0; c < com->argc; c++) {

com->argv[c] = NULL;
}

com->argc = 0;
nCommands = 0;
state = 0;

}

fprintf(stderr, "*** ICT310 construct dump end ***\n");

for (c = 0; c < com->argc; c++) {

com->argv[c] = NULL;
}

com->argc = 0;
nCommands = 0;
state = 0;

printf("\n");
printf("\n Mila's Shell> ");
nCommands++;

// everytime a user is presented the prompt, increment
// the number of comamnds by 1;
} // end else

} // end while

return 0;

} // end function main()

//---------------------------------------------------------------------------------------------------

void student_details() { /*function definition*/

/*student's details*/
printf("\n");
printf("\n");
printf(" Student's Name: Milos Zdravic\n");
printf("\n");

} /*end of function*/

//---------------------------------------------------------------------------------------------------

void option_exit() { /* exit option*/

printf("\n");
printf("\n");
printf(" Thanks for using my program. Wasn't too bad I hope!!!");
fflush(stdin);
printf("\n");
exit(0);

} /*end of function*/

//---------------------------------------------------------------------------------------------------

void printComStruct(struct command *com) { /* print function */

int i;

fprintf(stderr,"com_pathname=%s\n", com->com_pathname);
fprintf(stderr,"argc=%d\n", com->argc);

for(i=0; com->argv[i] != NULL; i++) {

fprintf(stderr,"argv[%d]=%s\n", i, com->argv[i]);
}

fprintf(stderr,"#######\n");

if (com->redirect_in == NULL)
fprintf(stderr,"redirect_in=NULL\n");

else
fprintf(stderr,"redirect_in=%s\n", com->redirect_in);

if (com->redirect_out == NULL)
fprintf(stderr,"redirect_out=NULL\n");

else
fprintf(stderr,"redirect_out=%s\n", com->redirect_out);

fprintf(stderr,"com_suffix=%c\n\n", com->com_suffix);

} /*end of function*/

//---------------------------------------------------------------------------------------------------

Nope
09-13-2004, 08:32 AM
Well, what's the definition for command end?

You see, all languages/parsers that allow to combine several commands in one line also define a line or command end character. So you could use the & as one of those as it has to be given at the end of the command (if at all) anyway, but without that you are lost.

mile1982
09-13-2004, 09:58 AM
thanks for ur reply mate but i finally got the whole program l working so its OK. took a little more time than usual to figure it out but its done now. thanks anyway