PDA

View Full Version : compiling under xp and linux


mile1982
09-13-2004, 08:25 PM
hey there

im kinda new to all this programming and therefore have a interesting question. under xp im using visual c++ 6.0. when i compile and link the program there are no errors nor warnings. the program runs ok apart from a few mistakes.

now when i switch to red hat linux 8.0 and try and compile the same file, i get several warnings and i cant run the file. can anyone help with this??

below is the code:


#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[60]; // 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\\\"~!@#$%^*()_=+'' [] {}:?,";
char *token[60];
int a, b, i;
int nCommands = 0;
int state = 0;
int d = 0;
int l = 0;
int w = 0;
int count = 0;
char result = 'x';

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

com[nCommands].argc = 0; // set number of arguments to zero
com[nCommands].redirect_in = NULL;
com[nCommands].redirect_out = NULL;
com[nCommands].com_suffix = NULL;

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");

a = 0;

printf(" Mila's Shell> ");

while (gets (line)) {

token[a++] = strtok(line," ");

while (token[a++] = strtok(NULL," "));

a--;

// seperate the input line into tokens
for (b = 0; b < a; b++) {

printf("%i: \'%s\'\n",b+1,token[b]);
}

for (count = 0; count < a; count++) {

// if the input equals 'exit', show a exit message before
// exiting the program
if(strcmp(line,guess) == 0) {

option_exit();
}

// everytime the program is started or a new prompt is
// displayed, the first argument is set as the pathname
// for the command
if (count == 0) {

com[nCommands].com_pathname = token[count];
com[nCommands].argc++;
com[nCommands].argv[d++] = token[count];
}

if (count > 0) {

if (strlen(token[count]) == 1) { // if the length of the character is 1

switch (*token[count]) { // 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.

state = 3;
break;

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

state = 3;
break;

case ';': // end of command

state = 3;
break;

} // end switch

} // end if

// if either '>' or '<' is encountered during the program
// execution, store the result in either com[nCommands].redirect_out
// or com[nCommands].redirect_in

if (state == 1) {

com[nCommands].redirect_out = token[count];
}

else if (state == 2) {

com[nCommands].redirect_in = token[count];
}

// if any of the following three commands are encountered
// '&', '|' or ';' during the program execution, store the
// command in the appropriate com_suffix and set the next
// argument in the line to NULL so that it indicates end
// of command

else if (state == 3) {

com[nCommands].com_suffix = token[count];
state = 4;
com->argv[d++] = NULL;
}

// if any of the following three commands are encountered
// '&', '|' or ';' during the program execution, it may mean
// that the next token is the beginning of a new command.
// for that reason, increase the number of commands by 1 and
// set the other appropriate command to zero so its starting
// from 'fresh';

else if (state == 4) {

nCommands++;
com[nCommands].com_pathname = token[count];
d = 0;
com[nCommands].argc = 0;
com[nCommands].argc++;
com[nCommands].argv[d++] = token[count];

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

state = 0;

}

// if no special characters were encountered during program
// execution, save the next token in the next available
// argv[position]

else if (state == 0) {

// save token as argument for command
// argv = arguments for commands
// argc = number of arguments to the command;

com[nCommands].argc++;
com[nCommands].argv[d++] = token[count];

} // end else if

} // end else if

} // end for

// after the user has finished with the commmand, print out
// the commands
fprintf(stderr, "*** construct dump begin *** \n");
for (i = 0; i < nCommands+1; ++i) {

com[nCommands].argv[d++] = NULL;

fprintf(stderr, "\n command[%d]: \n", i);
printComStruct(&com[i]);
}
fprintf(stderr, "*** construct dump end *** \n");

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

printf("\n");
printf("\n Mila's Shell> ");
nCommands = 0;
count = 0;
a = 0;
d = 0;

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

com[w].argc = 0;
}

} // end while

option_exit();
return 0;

} // end function main()

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

// this method is displayed right at the start of the program.
// it is a simple function that shows the students details
void student_details() {

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

} /*end of function*/

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

// this method is displayed right at the end of the program.
// it is a simple function that is shown when the program exits
void option_exit() {

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*/

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

// this method is displayed everytime the print function is
// called in order to properly display the results
void printComStruct(struct command *com) {

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*/

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



cheers

Nope
09-13-2004, 10:26 PM
Well, the warnings would help to find the problem....

VC++ is a C++ compiler, so there are even some basic things that might not work out. Then, between XP and Unix the included header files must not be nescessarily be equal. So check for missing include files. A thing you shouldn't do is using the "//" comments in C, they are C++, use "/* ... */" instead. Else I don't see anything out of the ordinary.

Check those things first. I won't help you anymore if I get the feeling you don't try to make your own (home)work...

RobSeace
09-14-2004, 01:15 PM
Well, since I'm a nice guy (hah! ;-)), I copied all that code to a local
file, and tried compiling with GCC and -Wall... It looks like the
major complaint that's choking compilation is the fact that you
define the prototype for printComStruct() prior to actualy defining
what "struct command" is... Then, when the actualy function is
defined later, "struct command" exists, and now the function def
conflicts with the old prototype, according to GCC's interpretation
of wacky ANSI rules, anyway... You can solve this one of two
ways: move the definition of "struct command" above your function
prototypes, OR pre-define the struct with a simple "struct command;"
statement prior to the prototypes, which will allow you to define it
fully later, and still have everything work ok... Doing either of those
should allow you to compile successfully, at least...

However, there are also several other less serious problems you
should correct, as well: those 2 prototypes with empty parameter
lists are simply wrong... That's old-style K&R type prototyping...
The correct ANSI prototype for functions with no arguments is
"void funcname (void);"... Also, the last fprintf() in printComStruct()
is incorrect: you use a "%c" format, but pass it com->com_suffix,
which is defined as a string (ie: a char*)... Also, the gets() function
is just horrible and should not be used by anyone for ANY reason
at all... (Except, possibly, for creating a demonstration program
with a deliberately exploitable security hole...) Use fgets()!!