Without a code block around my "default" clause of my switch statement the compiler can't parse the following instructions. I'm including the text of a file which, when compiled, will run without a bug (you will need to delete some of the local dependencies and references to global variables). If you remove the curly braces around the switch statement's default clause you'll find the compiler can't parse the file. The next declaration after the default clause introduction ("default:") is "char *myArgv[64];" and the compiler will tell you there's an error: syntax error before "char" on that line. (I messed with this for about 30 minutes before I figured out that it was a curly brace thing.) System/package info: gcc --version: gcc (GCC) 3.3.5 (Debian 1:3.3.5-8ubuntu2.1)
here's the code: /******************************************************************* Author: William P. Henry Jr. Name: mysh.c Class: CS 360 Assignment: lab2 Purpose: Simulate the UNIX command prompt and command processing. For purpose of understanding how Unix sh works by using fork() and exec(...), also string operations. *******************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> //contains static global variable for operations //including a string table for commands #include "commandGlobals.h" #include "commandProcessing.h" #define DIRECTORY_LOCAL #include "directoryGlobals.h" #define PATH_LOCAL #include "pathGlobals.h" #include "pathProcessing.h" //initialize array of recognized commands (global from //the commandGlobals.h file change the size there if you //make any additions or removals here */ const char *cmd[] = {"mkdir", "rmdir", "ls", "cd", "pwd", "creat", "rm", "quit", "help", "?", "menu", "reload", "echo", "exit", 0}; enum commandEnums {MKDIR = 0, RMDIR, LS, CD, PWD, CREAT, RM, QUIT, HELP, QUESTION, MENU, RELOAD, ECHO, EXIT }; int main( int argc, char **argv, char **env ) { printf("\n*************BEGIN MYSH.C MAIN****************\n"); initEnvironInfo(env); printf("Home string is: %s\n", homeBuf); printf("Path variables (in pathPointers[0-n]) are: \n"); int m = 0; while( 0 != pathPointers[m] ) { printf("\t%s\n", pathPointers[m++]); }//end while more path variables, print variables printf("PWD is: %s\n", getenv("PWD")); int ID = 0; char *fullInputString = malloc(256*(sizeof(char))); char *command = malloc(256*(sizeof(char))); char *arguments = malloc(256*(sizeof(char))); char localBuf[256]; //used in child process char *fullCmd = malloc(256*(sizeof(char))); int pid = 0; int retval = 0; int status = 0; while(1) { printf("wphix $: "); fgets(inputLine, 256, stdin); //copy the full input string for use passing into //other functions, overwrite the final '\n' //leftover from user hitting "enter" // fullInputString[0] = '\0'; strcpy(fullInputString, inputLine); fullInputString[strlen(fullInputString)-1] = '\0'; inputLine[strlen(inputLine)-1] = '\0'; command = strtok(inputLine, " "); //copy all arguments after the initial command arguments = strtok( 0, "\n"); //returns values as enumerated above ID = findCmd(command); switch(ID) { case(CD): //printf("found %s at index %d\n", cmd[ID], ID); if( 0 == arguments ) { //printf("no argument given for cd\n"); chdir(homeBuf); localBuf[0]='\0'; if( 0 == getcwd(localBuf, 256) ) { printf("getcwd(localBuf, 256) failed\n"); }//end if else { printf("PWD is: %s\n", localBuf); }//end else (so getcwd worked) }//end if no arguments are passed else if( 0 == chdir( arguments ) ) { //printf("was given %s to change to\n", arguments); localBuf[0]='\0'; if( 0 == getcwd(localBuf, 256) ) { printf("getcwd(localBuf, 256) failed\n"); }//end if else { printf("PWD is: %s\n", localBuf); }//end else (so getcwd worked) }//end if worked, print blah else { printf("%s isn't a recognized directory\n", arguments); }//else failed to chdir break; case(QUIT): printf("quitting\n"); //using goto to handle freeing of malloc'ed stuff goto quitCleanUp; break; case(ECHO): if( 0 == arguments ) { printf("\n"); }//end if null else { printf("%s\n", arguments); }//end else print args break; case(EXIT): printf("exiting\n"); free(fullInputString); free(command); free(arguments); free(fullCmd); exit(0); break; default: { //I HATE THAT THIS HAS TO BE HERE...BUT THE CODE WON'T //COMPILE WITHOUT THIS //arguments to pass in to new function //pointers will point to memory in parent that //will not be modified during child's execution char *myArgv[64]; char buf[64]; //using fullInputString, tokenized, as the argv's to pass in int counter = 0; myArgv[counter] = (char*)strtok( fullInputString, " " ); do { //strtok returns null on last call, so the //index past the last valid path will hold zero myArgv[++counter] = (char*)strtok( NULL , " " ); }//end while return not null while( 0 != myArgv[counter] ); //************FORK*********************// printf("parent mysh with PID:%d forks child\n", getpid()); pid = fork(); if(0 == pid) { //CHILD printf("in child\n"); //if path is absolute, pass it as argument //if path is relative, rebuild path from cwd if( isAbsolute(command) ) { if( -1 == execve(command, myArgv, env) ) { //printf("attempt to run \"%s\" failed\n", command); exit(2); }//end if }//end if is absolute path else { int num = 0; do { fullCmd[0]='\0'; strcpy(fullCmd,pathPointers[num]); strcat(fullCmd,"/"); strcat(fullCmd, command); //printf("trying %s, ", fullCmd); execve(fullCmd, myArgv, env); ++num; }//end do while( 0 != pathPointers[num] ); printf("\n"); }//end else is relative exit(3); }//end if zero is pid, so in child else { //PARENT retval = waitpid(pid, &status, 0); printf("in parent\n"); if( WIFEXITED(status) ) { printf("child pid:%d exited normally\n", pid); printf("with exit status:%d\n", WEXITSTATUS(status)); if( retval != pid ) { printf("and waitpid's retval:%d\n", retval); }//end if inequal retval and pid }//end if exited normally }//end else break; //I HATE THAT THIS HAS TO BE HERE, AND I HAVE NO IDEA WHY, //BUT AFTER I DOWNLOADED A NEW COMPILER VERSION IT GAVE //ME THE STRANGEST ERROR ON CODE THAT HAD BEEN WORKING //SO I MESSED WITH IT AND FINALLY FOUND THE PROBLEM BY //PUTTING CURLY BRACES AROUND THE CODE BLOCK }//end default block }//end switch }//end while loop quitCleanUp: free(fullInputString); free(command); free(arguments); free(fullCmd); printf("**************END MYSH.C MAIN*****************\n\n"); return 0; }//end main -- Summary: force code block in default clause of switch statement Product: gcc Version: 3.3.5 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: william dot p dot henry dot jr at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26742