int main(int argc, char *argv[]) { int quiet = 0; char input[BUFSIZ]; int r = 0; // Check for '-q' option: be quiet -- print no prompts if (argc > 1 && strcmp(argv[1], "-q") == 0) quiet = 1; signal(SIGCHLD,signal_handler); while (!feof(stdin)) { parsestate_t parsestate; command_t *cmdlist; // Print the prompt if (!quiet) { printf("prog1$ "); fflush(stdout); } // Read a string, checking for error or EOF if (fgets(input, BUFSIZ, stdin) == NULL) { if (ferror(stdin)) // This function prints a description of the // error, preceded by 'cs111_fall07: '. perror("prog1"); break; } // TODO: invoke some function(s) in cmdline.c for parsing the read string. parse_init(&parsestate,input); cmdlist=command_line_parse(&parsestate,0); if (!cmdlist) { printf("Syntax error\n"); continue; } // print the command list if (!quiet) { // TODO: invoke some function(s) in cmdline.c for printing out the command for debugging. command_print(cmdlist,1); // why do we need to do this? fflush(stdout); } // and run it! int not_impotant=0; waitpid(-1,¬_impotant,WNOHANG);//kill zombies if (cmdlist) command_line_exec(cmdlist); if (cmdlist) command_free(cmdlist); } return 0; }
int main(int argc, char *argv[]) { struct RfidTagReader *tag_reader; struct TagDatabase *database; struct NetworkServer *server; struct BeerVolumeReader *volume_reader; GMainLoop *loop; struct CmdOptions options; int i; command_line_parse(&options, argc, argv); config_load("beerd.conf"); database = tag_database_new(config.sqlite_file); if(!options.disable_tagreader) { for(i=0;i < config.num_rfid_readers; i++) { tag_reader = rfid_tag_reader_new(config.rfid_serial_port[i]); if(tag_reader) rfid_tag_reader_set_callback(tag_reader, tag_read, database); else fprintf(stderr,"Error opening serial device for tagreader\n"); } } volume_reader = beer_volume_reader_new(config.beer_volume_reader); if(volume_reader) { beer_volume_reader_set_callback(volume_reader, volume_read, database); tag_reader->beer_volume_reader = volume_reader; beer_volume_reader_control_valve(volume_reader, VALVE_CLOSE); } else { fprintf(stderr,"could not connect to valve reader\n"); return -1; } server = network_server_new(database); pthread_create(&led_thread,NULL,(void*)&ledMatrixThread,NULL); // tag_database_update_liters(database); g_timeout_add_seconds(30, (GSourceFunc)tag_database_update_liters, database); loop = g_main_loop_new(NULL,FALSE); // g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, logfunc, NULL); g_main_loop_run(loop); return 0; }
command_t * command_parse(parsestate_t *parsestate) { int i = 0; command_t *cmd = command_alloc(); if (!cmd) { printf("cmd alloc error\n"); return NULL; } while (1) { // EXERCISE: Read the next token from 'parsestate'. // Normal tokens go in the cmd->argv[] array. // Redirection file names go into cmd->redirect_filename[]. // Open parenthesis tokens indicate a subshell command. // Other tokens complete the current command // and are not actually part of it; // use parse_ungettoken() to save those tokens for later. // There are a couple errors you should check. // First, be careful about overflow on normal tokens. // Each command_t only has space for MAXTOKENS tokens in // 'argv'. If there are too many tokens, reject the whole // command. // Second, redirection tokens (<, >, 2>) must be followed by // TOK_NORMAL tokens containing file names. // Third, a parenthesized subcommand can't be part of the // same command as other normal tokens. For example, // "echo ( echo foo )" and "( echo foo ) echo" are both errors. // (You should figure out exactly how to check for this kind // of error. Try interacting with the actual 'bash' shell // for some ideas.) // 'goto error' when you encounter one of these errors, // which frees the current command and returns NULL. // Hint: An open parenthesis should recursively call // command_line_parse(). The command_t structure has a slot // you can use for parens; figure out how to use it! if (i > MAXTOKENS) goto error; token_t token; parse_gettoken(parsestate, &token); switch (token.type) { case TOK_NORMAL: //printf("%s len: %d", token.buffer, strlen(token.buffer)); if (cmd->subshell != NULL) { parse_ungettoken(parsestate); goto done; } if (strlen(token.buffer) != 0) { cmd->argv[i] = strdup(token.buffer); i++; } break; case TOK_LESS_THAN: //printf("input red\n"); parse_gettoken(parsestate, &token); if (token.type != TOK_NORMAL) goto error; cmd->redirect_filename[0] = strdup(token.buffer); break; case TOK_GREATER_THAN: //printf("output red\n"); parse_gettoken(parsestate, &token); if (token.type != TOK_NORMAL) goto error; cmd->redirect_filename[1] = strdup(token.buffer); break; case TOK_2_GREATER_THAN: //printf("stderr red\n"); parse_gettoken(parsestate, &token); if (token.type != TOK_NORMAL) goto error; cmd->redirect_filename[2] = strdup(token.buffer); break; case TOK_OPEN_PAREN: cmd->subshell = command_line_parse(parsestate, PARENS_IN); //goto done; break; case TOK_CLOSE_PAREN: default: parse_ungettoken(parsestate); goto done; } } done: // NULL-terminate the argv list cmd->argv[i] = 0; // EXERCISE: Make sure you return the right return value! if (i == 0 && cmd->subshell == NULL) { /* Empty command */ command_free(cmd); return NULL; } else return cmd; error: command_free(cmd); return NULL; }
/********************************************************************** * MAIN **********************************************************************/ int main(int argc, char *argv[]) { FILE *stimfp = NULL, *datafp = NULL, *dsumfp = NULL; char *stimfname = NULL; char *stimfroot, *pcm_name, *entseq=NULL, tmpExemplar[1024]; const char delimiters[] = " .,;:!-"; char datafname[1024], hour[16], min[16], month[16],day[16], year[16], dsumfname[1024], stimftemp[1024],outsf[1024]; char buf[1024], stimexm[1024],fstim[1024], timebuff[64], tod[256], date_out[256], buffer[30],temphour[16],tempmin[16]; int stim_class, resp_sel, resp_acc, subjectid, period, foo; int played, resp_wind=0,trial_num, session_num, i,j, correction, loop, stim_number; int dosunrise=0,dosunset=0,starttime,stoptime,currtime, tmpClass=0, mindx=0,cindx=0; long unsigned int tmpDur=0; float timeout_val=0.0, resp_rxt=0.0, tmpHit=0.0; int respwin_sec, respwin_usec, resp_sec, resp_usec; /* debugging variables */ int nstims=0, nclasses=0; int motmax =1, motmin=1, prbrate=0, CRf=0, XRf=0, prbRf=0, prbTO=0; int ret, do_prb, nprbclasses=0; float latitude = 32.82, longitude = 117.14; time_t curr_tt, rise_tt, set_tt; struct timeval stimoff,stimon, resp_window, resp_lag, resp_rt, stim_dur; struct tm *loctime; Failures f = {0,0,0,0}; int left = 0, right= 0, center = 0, fed = 0; int reinfor_sum = 0, reinfor = 0; sigset_t trial_mask; Seqstim seqstims[MAXCLASS], *pseqstims; struct resp{ int left; int right; int no; int count; float p_left; float p_right; }classRses[MAXCLASS], classRtot[MAXCLASS]; srand (time (0) ); /* set up termination handler*/ if (signal(SIGPIPE, sig_pipe) == SIG_ERR){ perror("error installing signal handler for SIG_PIPE"); exit (-1); } sigemptyset (&trial_mask); sigaddset (&trial_mask, SIGINT); sigaddset (&trial_mask, SIGTERM); signal(SIGTERM, termination_handler); signal(SIGINT, termination_handler); /* Parse the command line */ command_line_parse(argc,argv,&box_id,&subjectid,&starthour,&stophour,&startmin,&stopmin, &resp_wind,&timeout_val,&stimfname, &prbrate,&CRf,&XRf,&prbRf,&prbTO); if(DEBUG){ fprintf(stderr, "command_line_parse(): box_id=%d, subjectid=%d, startH=%d, stopH=%d, startM=%d, stopM=%d, xresp=%d, resp_wind=%d, do_rand_start=%d, timeout_val=%f flash=%d stimfile:%s, prbrate=%d, CRf=%d, XRf=%d, prbRf=%d, prbTO=%d, motmax=%d, motmin=%d\n", box_id, subjectid, starthour, stophour, startmin, stopmin, xresp, resp_wind, do_rand_start, timeout_val, flash, stimfname, prbrate, CRf, XRf, prbRf, prbTO, motmax, motmin); } sprintf(pcm_name, "dac%i", box_id); if(DEBUG){fprintf(stderr,"dac: %s\n",pcm_name);} if(DEBUG){fprintf(stderr,"commandline done, now checking for errors\n");} /* watch for terminal errors*/ if( (stophour!=99) && (starthour !=99) ){ if ((stophour <= starthour) && (stopmin<=startmin)){ fprintf(stderr, "\tTERMINAL ERROR: exp start-time must be greater than stop-time\n"); exit(-1); } } if (box_id <= 0){ fprintf(stderr, "\tYou must enter a box ID!\n"); fprintf(stderr, "\tERROR: try '2ac_entropy -help' for available options\n"); exit(-1); } if( (prbRf<0) || (prbTO<0) || (CRf<=0) || (XRf<=0) ){ fprintf(stderr, "\tYou must specify the reinforcemnt rate for all baseline and probe stimuli on the command line!\n"); fprintf(stderr, "\tERROR: try '2ac_entropy -help' for available options\n"); snd_pcm_close(handle); exit(-1); } else if ((prbRf+prbTO)>100){ fprintf(stderr, "\tFATAL ERROR: The sum of the probe feed (prbRf) and timeout (prbTO) rates can't be greater than 100!\n"); snd_pcm_close(handle); exit(-1); } if(motmax > MAXMOTSPERSEQ ){ fprintf(stderr, "\tyou can't have more than %d motifs in each sequence\n", MAXMOTSPERSEQ); fprintf(stderr, "\tERROR: try '2ac_entropy -help'\n"); snd_pcm_close(handle); exit(-1); } /*set some variables as needed*/ if (resp_wind>0) respoff.tv_sec = resp_wind; fprintf(stderr, "response window duration set to %d secs\n", (int) respoff.tv_sec); if(timeout_val>0.0) timeout_duration = (int) (timeout_val*1000000); fprintf(stderr, "timeout duration set to %d microsecs\n", (int) timeout_duration); if(DEBUG){fprintf(stderr, "starthour: %d\tstartmin: %d\tstophour: %d\tstopmin: %d\n", starthour,startmin,stophour,stopmin);} curr_tt = time(NULL); loctime = localtime (&curr_tt); strftime (year, 16, "%Y", loctime); strftime(month, 16, "%m", loctime); strftime(day, 16,"%d", loctime); if(starthour==99){ dosunrise=1; rise_tt = sunrise(atoi(year), atoi(month), atoi(day), latitude, longitude); strftime(temphour, 16, "%H", localtime(&rise_tt)); strftime(tempmin, 16, "%M", localtime(&rise_tt)); starthour=atoi(temphour); startmin=atoi(tempmin); strftime(buffer,30,"%m-%d-%Y %H:%M:%S",localtime(&rise_tt)); printf("Sessions start at sunrise (Today: '%s')\n",buffer); } if(stophour==99){ dosunset=1; set_tt = sunset(atoi(year), atoi(month), atoi(day), latitude, longitude); strftime(temphour, 16, "%H", localtime(&set_tt)); strftime(tempmin, 16, "%M", localtime(&set_tt)); stophour=atoi(temphour); stopmin=atoi(tempmin); strftime(buffer,30,"%m-%d-%Y %T",localtime(&set_tt)); printf("Sessions stop at sunset (Today: '%s')\n",buffer); } starttime=(starthour*60)+startmin; stoptime=(stophour*60)+stopmin; if(DEBUG){fprintf(stderr, "starthour: %d\tstartmin: %d\tstophour: %d\tstopmin: %d\n", starthour,startmin,stophour,stopmin);} /* Initialize box */ if(DEBUG){ printf("Initializing box %d ...\n", box_id); printf("trying to execute setup(%s)\n", pcm_name); } if((period= setup_pcmdev(pcm_name))<0){ fprintf(stderr,"FAILED to set up the pcm device %s\n", pcm_name); exit (-1);} if (operant_open()!=0){ fprintf(stderr, "Problem opening IO interface\n"); snd_pcm_close(handle); exit (-1); } operant_clear(box_id); if(DEBUG){printf("done\n");} /* give user some feedback*/ fprintf(stderr, "Loading stimuli from file '%s' for session in box '%d' \n", stimfname, box_id); fprintf(stderr, "Subject ID number: %i\n", subjectid); if(flash){fprintf(stderr, "!!WARNING: Flashing keylights during response window!!\n");} if(xresp){fprintf(stderr, "!!WARNING: Enabling correction trials for 'No' responses !!\n");} /* Read in the list of exmplars */ if ((stimfp = fopen(stimfname, "r")) != NULL){ while (fgets(buf, sizeof(buf), stimfp)) nstims++; fprintf(stderr, "Found %d stimulus exemplars in '%s'\n", nstims, stimfname); rewind(stimfp); for (i = 0; i < nstims; i++){ fgets(buf, 128, stimfp); tmpDur=0.0; mindx =0; cindx=0; if((ret=sscanf(buf, "%d\%s\%g", &tmpClass, tmpExemplar, &tmpHit)) != 3){ printf("ERROR: bad line in '.stim' file (read in '%s'\n", buf); snd_pcm_close(handle); exit(-1); } if(DEBUG){fprintf(stderr, "\n%d %s\n", tmpClass, tmpExemplar);} /* count total stim and probe classes*/ /*NOTE: these counters only work if classes are numbered consecutively in the .stim file w/o any skips */ if (nclasses<tmpClass){ nclasses=tmpClass; if (DEBUG){printf("total number of stimlus classes set to: %d\n", nclasses);} } if((tmpClass>=3) && (nprbclasses<tmpClass-2)){ /*count the number of probe classes*/ nprbclasses=tmpClass-2; if (DEBUG){fprintf(stderr,"number of probe classes set to %d\n", nprbclasses);} } /*verify soundfile*/ sprintf(fstim,"%s%s", STIMPATH, tmpExemplar); if((tmpDur = verify_soundfile(fstim))<1){ fprintf(stderr, "Unable to verify %s!\n",fstim ); snd_pcm_close(handle); exit(0); } if(DEBUG){printf("soundfile %s verified, duration: %lu \tclass: %d\n", tmpExemplar, tmpDur, tmpClass);} /*now load up the seqstims struct*/ cindx = tmpClass-1; seqstims[cindx].count++; mindx = seqstims[cindx].count-1; seqstims[cindx].exemplar[mindx] = (malloc(sizeof (tmpExemplar))); memcpy(seqstims[cindx].exemplar[mindx], tmpExemplar, sizeof(tmpExemplar)); seqstims[cindx].hit[mindx]=tmpHit; if(DEBUG){fprintf(stderr,"seqstims[%d].exemplar[%d]: %s ", cindx, mindx, seqstims[cindx].exemplar[mindx]);} if (DEBUG){printf("occurs at sequence postion '%d' in %g%% of all sequences in class %d\n", mindx+1, seqstims[cindx].hit[mindx], cindx+1);} } }
/********************************************************************** MAIN **********************************************************************/ int main(int argc, char *argv[]){ if(DEBUG){fprintf(stderr, "start songchoice");} FILE *stimfp = NULL, *datafp = NULL, *dsumfp = NULL; char *stimfname = NULL; char *stimfroot, *tmpstr; const char delimiters[] = " .,;:!-"; const char stereopcm [] = "doubledac"; char datafname[128], hour[16], min[16], month[16],day[16], year[16], dsumfname[128], stimftemp[128], pcm_name[128]; char buf[256],distexm[128],targetloc[128],stimexm[128],fstim[256], fdist [256],timebuff[64],buffer[30],*bplist= NULL, temphour[16],tempmin[16],tod[256], date_out[256]; int nclasses, nstims, stim_class, stim_reinf, stim_punish, stim_nbps, resp_sel, resp_acc, subjectid, period, tot_trial_num, played, resp_wind=0,trial_num, session_num, i,j,k, correction, playval, distval, loop,stim_number,targloc, nbps,minlength, *playlist=NULL, totnstims=0,dosunrise=0,dosunset=0,starttime,stoptime,currtime,doprobes,dist_number,breakval; float timeout_val=0.0, resp_rxt=0.0, breakpoint = 0.0, cueint = 0.0, targlength = 0.0; int stimoff_sec, stimoff_usec, respwin_sec, respwin_usec, resp_sec, resp_usec; /* debugging variables */ float latitude = 32.82, longitude = 117.14; time_t curr_tt, rise_tt, set_tt; struct timeval stimoff, resp_window, resp_lag, resp_rt; struct tm *loctime; Failures f = {0,0,0,0}; int left = 0, right= 0, center = 0, fed = 0; int reinfor_sum = 0, reinfor = 0; float probeCO=68.0; SNDFILE *sf; SF_INFO *sfinfo; struct stim { char exemplar[128]; float breakpt[MAXBP]; int reinf; int punish; int freq; int nbps; unsigned long int dur; int num; }stimulus[MAXSTIM]; struct resp{ int C; int X; int no; int CbyBP[MAXBP]; int XbyBP[MAXBP]; int nobyBP[MAXBP]; int countbyBP[MAXBP]; int left; int center; int right; int count; }Rstim[MAXSTIM], Tstim[MAXSTIM]; sigset_t trial_mask; srand (time (0) ); if(DEBUG){fprintf(stderr, "start songchoice");} /* set up termination handler*/ if (signal(SIGPIPE, sig_pipe) == SIG_ERR){ perror("error installing signal handler for SIG_PIPE"); exit (-1); } sigemptyset (&trial_mask); sigaddset (&trial_mask, SIGINT); sigaddset (&trial_mask, SIGTERM); signal(SIGTERM, termination_handler); signal(SIGINT, termination_handler); /* Parse the command line */ command_line_parse(argc, argv, &box_id, &subjectid, &starthour, &stophour, &startmin, &stopmin, &resp_wind, &timeout_val, &targlength, &cueint, &stimfname); if(DEBUG){ fprintf(stderr, "command_line_parse(): box_id=%d, subjectid=%d, startH=%d, stopH=%d, startM=%d, stopM=%d, resp_wind=%d, timeout_val=%f, targlength=%f, cueint=%f, stimfile:%s", box_id, subjectid, starthour, stophour, startmin, stopmin, resp_wind, timeout_val, targlength, cueint, stimfname); } sprintf(pcm_name, "%s", stereopcm); if(DEBUG){fprintf(stderr,"dac: %s\n",pcm_name);} if(DEBUG){fprintf(stderr,"commandline done, now checking for errors\n");} /* watch for terminal errors*/ if( (stophour!=99) && (starthour !=99) ){ if ((stophour <= starthour) && (stopmin<=startmin)){ fprintf(stderr, "\tTERMINAL ERROR: exp start-time must be greater than stop-time\n"); exit(-1); } } if (box_id <= 0){ fprintf(stderr, "\tYou must enter a box ID!\n"); fprintf(stderr, "\tERROR: try 'SONGCHOICE -help' for available options\n"); exit(-1); } /* set some variables as needed*/ if (resp_wind>0) respoff.tv_sec = resp_wind; fprintf(stderr, "response window duration set to %d secs\n", (int) respoff.tv_sec); if(timeout_val>0.0) timeout_duration = (int) (timeout_val*1000000); fprintf(stderr, "timeout duration set to %d microsecs\n", (int) timeout_duration); if(targlength>0.0) target_duration = (int) (targlength*1000000); fprintf(stderr, "timeout duration set to %d microsecs\n", (int) target_duration); if(cueint>0.0) cue_stim_interval = cueint; fprintf(stderr, "timeout duration set to %f seconds\n", cue_stim_interval); if(DEBUG){fprintf(stderr, "starthour: %d\tstartmin: %d\tstophour: %d\tstopmin: %d\n", starthour,startmin,stophour,stopmin);} curr_tt = time(NULL); loctime = localtime (&curr_tt); strftime (year, 16, "%Y", loctime); strftime(month, 16, "%m", loctime); strftime(day, 16,"%d", loctime); if(starthour==99){ dosunrise=1; rise_tt = sunrise(atoi(year), atoi(month), atoi(day), latitude, longitude); strftime(temphour, 16, "%H", localtime(&rise_tt)); strftime(tempmin, 16, "%M", localtime(&rise_tt)); starthour=atoi(temphour); startmin=atoi(tempmin); strftime(buffer,30,"%m-%d-%Y %H:%M:%S",localtime(&rise_tt)); printf("Sessions start at sunrise (Today: '%s')\n",buffer); } if(stophour==99){ dosunset=1; set_tt = sunset(atoi(year), atoi(month), atoi(day), latitude, longitude); strftime(temphour, 16, "%H", localtime(&set_tt)); strftime(tempmin, 16, "%M", localtime(&set_tt)); stophour=atoi(temphour); stopmin=atoi(tempmin); strftime(buffer,30,"%m-%d-%Y %T",localtime(&set_tt)); printf("Sessions stop at sunset (Today: '%s')\n",buffer); } starttime=(starthour*60)+startmin; stoptime=(stophour*60)+stopmin; if(DEBUG){fprintf(stderr, "starthour: %d\tstartmin: %d\tstophour: %d\tstopmin: %d\n", starthour,startmin,stophour,stopmin);} /* Initialize box */ if(DEBUG){ printf("Initializing box %d ...\n", box_id); printf("trying to execute setup(%s)\n", pcm_name); } if((period= setup_pcmdev(pcm_name))<0){ fprintf(stderr,"FAILED to set up the pcm device %s\n", pcm_name); exit (-1);} if (operant_open()!=0){ fprintf(stderr, "Problem opening IO interface\n"); snd_pcm_close(handle); exit (-1); } operant_clear(box_id); if(DEBUG){printf("done\n");} /* give user some feedback*/ fprintf(stderr, "Loading stimuli from file '%s' for session in box '%d' \n", stimfname, box_id); fprintf(stderr, "Subject ID number: %i\n", subjectid); if(flash){fprintf(stderr, "!!WARNING: Flashing keylights during response window!!\n");} if(xresp){fprintf(stderr, "!!WARNING: Enabling correction trials for 'No' responses !!\n");} /* Read in the list of exemplars */ nstims = 0; if ((stimfp = fopen(stimfname, "r")) != NULL){ while (fgets(buf, sizeof(buf), stimfp)) nstims++; fprintf(stderr, "Found %d stimulus exemplars in '%s'\n", nstims, stimfname); rewind(stimfp); for (i = 0; i < nstims; i++){ fgets(buf, 128, stimfp); stimulus[i].freq = stimulus[i].reinf=0; sscanf(buf, "%s\%d\%d\%d", stimulus[i].exemplar, &stimulus[i].freq, &stimulus[i].reinf, &stimulus[i].punish); bplist = strstr(buf, "0.00"); /* Parse break points */ if (bplist == NULL){ fprintf(stderr,"ERROR: cannot read breakpoints. Try 'SONGCHOICE -help'\n");} else{ tmpstr = strtok (bplist," "); j=0; nbps = 0; while (tmpstr != NULL) { tmpstr = strtok (NULL, " "); if (tmpstr != NULL) { if(DEBUG){fprintf(stderr,"%s", tmpstr);} sscanf(tmpstr, "%f\t", &stimulus[i].breakpt[j]); if(DEBUG){fprintf(stderr,"%1.2f",stimulus[i].breakpt[j]);} j++; nbps++; } } if(DEBUG){fprintf(stderr," %i", nbps);} stimulus[i].nbps = nbps; } if((stimulus[i].freq==0) || (stimulus[i].reinf==0)|| (stimulus[i].punish==0)){ fprintf(stderr,"%i, %i, %i\n", stimulus[i].freq, stimulus[i].reinf, stimulus[i].punish); fprintf(stderr,"ERROR: insufficient data or bad format in '.stim' file. Try 'SONGCHOICE -help'\n"); exit(0);} totnstims += stimulus[i].freq; if(DEBUG){fprintf(stderr,"totnstims: %d\n", totnstims);} /*check the reinforcement rates */ fprintf(stderr, "Reinforcement rate for %s is set to %d%% for correct responses\n", stimulus[i].exemplar, stimulus[i].reinf); fprintf(stderr, "Punishment rate for %s is set to %d%% for incorrect responses\n", stimulus[i].exemplar, stimulus[i].punish); } } else{ fprintf(stderr,"Error opening stimulus input file! Try 'SONGCHOICE -help' for proper file formatting.\n"); snd_pcm_close(handle); exit(0); } fclose(stimfp); if(DEBUG){printf("Done reading in stims; %d stims found\n", nstims);} /* Check stim files and determine min song length - must allow sufficient time for targets and distractors */ minlength = MAXFILESIZE; for (i = 0; i<nstims; i++){ strcpy (stimexm, stimulus[i].exemplar); /* get exemplar filename */ sprintf(fstim,"%s%s", STIMPATH, stimexm); /* memory for SF_INFO structures */ sfinfo = (SF_INFO *) malloc(sizeof(SF_INFO)); /* open input files*/ if(!(sf = sf_open(fstim,SFM_READ,sfinfo))){ fprintf(stderr,"error opening input file %s\n", stimexm); return -1; } if (DEBUG){ /* print out some info about the file one */ fprintf(stderr,"\n ---------- Stimulus parameters from playwav ------------ \n"); fprintf (stderr, " Samples: %d\n", (int)sfinfo->frames) ; fprintf (stderr, "Sample Rate: %d\n", sfinfo->samplerate) ; fprintf (stderr, " Channels: %d\n", sfinfo->channels) ; } /* check that some assumptions are met */ if (sfinfo->frames > MAXFILESIZE){ fprintf(stderr,"%s is too large!\n", stimexm); sf_close(sf); return -1; } else if (sfinfo->frames < minlength) minlength = sfinfo->frames; if (sfinfo->samplerate != 44100){ fprintf(stderr, "Sample rate for %s is not equal to 44.1 KHz!\n", stimexm); sf_close(sf); return -1; } if (sfinfo->channels != 1){ fprintf(stderr, "Sound file %s is not mono!\n", stimexm); sf_close(sf); return -1; } if ((sfinfo->format & SF_FORMAT_TYPEMASK) != SF_FORMAT_WAV ){ fprintf(stderr, "Sound file %s is not in wav format!\n", stimexm); sf_close(sf); return -1; } sf_close(sf); free(sfinfo); } /* check probe times */ /* Don't allow correction trials when probe stimuli are presented */ if(xresp==1 && doprobes==1){ fprintf(stderr, "ERROR!: You cannot use correction trials and probe stimuli in the same session.\n Exiting now\n"); snd_pcm_close(handle); exit(-1); } /* build the stimulus playlist */ if(DEBUG){printf("flag: making the playlist\n");} free(playlist); playlist = malloc( (totnstims+1)*sizeof(int) ); i=j=0; for (i=0;i<nstims; i++){ k=0; for(k=0;k<stimulus[i].freq;k++){ playlist[j]=i; if(DEBUG){printf("value for playlist entry '%d' is '%d'\n", j, i);} j++; } } if(DEBUG){printf("there are %d stims in the playlist\n", totnstims);} /* Open & setup data logging files */ curr_tt = time (NULL); loctime = localtime (&curr_tt); strftime (timebuff, 64, "%d%b%y", loctime); sprintf (stimftemp, "%s", stimfname); stimfroot = strtok (stimftemp, delimiters); sprintf(datafname, "%i_%s.SC_rDAT", subjectid, stimfroot); sprintf(dsumfname, "%i.SCsummaryDAT", subjectid); datafp = fopen(datafname, "a"); dsumfp = fopen(dsumfname, "w"); if ( (datafp==NULL) || (dsumfp==NULL) ){ fprintf(stderr, "ERROR!: problem opening data output file!: %s\n", datafname); snd_pcm_close(handle); fclose(datafp); fclose(dsumfp); exit(-1); } /* Write data file header info */ fprintf (stderr,"Data output to '%s'\n", datafname); fprintf (datafp, "File name: %s\n", datafname); fprintf (datafp, "Procedure source: %s\n", exp_name); fprintf (datafp, "Start time: %s", asctime(loctime)); fprintf (datafp, "Subject ID: %d\n", subjectid); fprintf (datafp, "Stimulus source: %s\n", stimfname); fprintf (datafp, "Sess#\tTrl#\tStimulus\t\t\tBreakPt\tCueSrc\tR_sel\tR_acc\tRT\tReinf\tTOD\tDate\n"); /******************************************** +++++++++++ Trial sequence ++++++++++++++ ********************************************/ session_num = 1; trial_num = 0; tot_trial_num = 0; correction = 1; /*zero out the response tallies */ for(i = 0; i<nstims;++i){ Rstim[i].C = Rstim[i].no = Rstim[i].X = Rstim[i].count = 0; Tstim[i].C = Tstim[i].no = Tstim[i].X = Tstim[i].count = 0; for(j = 0; j<stimulus[i].nbps; ++j){ Rstim[i].CbyBP[j] = Rstim[i].nobyBP[j] = Rstim[i].XbyBP[j] = Rstim[i].countbyBP[j] = 0; Tstim[i].CbyBP[j] = Tstim[i].nobyBP[j] = Tstim[i].XbyBP[j] = Tstim[i].countbyBP[j] = 0; } } curr_tt = time(NULL); loctime = localtime (&curr_tt); strftime (hour, 16, "%H", loctime); strftime(min, 16, "%M", loctime); if (DEBUG){printf("hour:min at loop start: %d:%d \n", atoi(hour),atoi(min));} currtime=(atoi(hour)*60)+atoi(min); operant_write (box_id, HOUSELT, 1); /* make sure houselight is on */ do{ /* start the main loop */ while ((currtime>=starttime) && (currtime<stoptime)){ /* start main trial loop */ if (DEBUG){printf("minutes since midnight at loop start: %d\t starttime: %d\tstoptime: %d\n",currtime,starttime,stoptime);} srand(time(0)); /* select stim exemplar at random */ playval = (int) ((totnstims+0.0)*rand()/(RAND_MAX+0.0)); if (DEBUG){printf(" %d\t", playval);} stim_number = playlist[playval]; stim_nbps = stimulus[stim_number].nbps; strcpy (stimexm, stimulus[stim_number].exemplar); /* get exemplar filename */ stim_reinf = stimulus[stim_number].reinf; stim_punish = stimulus[stim_number].punish; sprintf(fstim,"%s%s", STIMPATH, stimexm); /* add full path to file name */ /* select a break point from target */ breakval = (int) ((stim_nbps+0.0)*rand()/(RAND_MAX+0.0)); breakpoint = stimulus[stim_number].breakpt[breakval]; /* select stim distractor at random */ distval = playval; while (distval == playval) distval = (int) ((totnstims+0.0)*rand()/(RAND_MAX+0.0)); dist_number = playlist[distval]; strcpy(distexm, stimulus[dist_number].exemplar); sprintf(fdist,"%s%s", STIMPATH, distexm); /* add full path to file name */ /* select a target source at random */ targloc = 1+(int) (2*rand()/(RAND_MAX+1.0)); if (targloc == 1){ /* target source is right */ sprintf(targetloc, "right");} else if (targloc == 2) { /* target source is left */ sprintf(targetloc, "left");} else{ printf("ERROR: incorrect cue choice\n"); exit(0);} if(DEBUG){fprintf(stderr, "target is on %s\n", targetloc);} do{ /* start correction trial loop */ left = right = center = 0; /* zero trial peckcounts */ resp_sel = resp_acc = resp_rxt = 0; /* zero trial variables */ ++trial_num;++tot_trial_num; /* Wait for center key press */ if (DEBUG){printf("\n\nWaiting for center key press\n");} operant_write (box_id, HOUSELT, 1); /* house light on */ right=left=center=0; do{ nanosleep(&rsi, NULL); center = operant_read(box_id, CENTERPECK); /*get value at center response port*/ }while (center==0); sigprocmask (SIG_BLOCK, &trial_mask, NULL); /* block termination signals*/ /* play the stimulus*/ if (DEBUG){fprintf(stderr,"start sound file\n");} if (DEBUG){fprintf(stderr, "tying to playstereo with target: %s, distractor : %s, cue length: %f, target location:'%s', cue-stim interval: %1.2f\n", stimexm, distexm, breakpoint, targetloc, cue_stim_interval ); } played = playstereo(fstim, fdist, breakpoint, targlength, targloc, cue_stim_interval, period); if (DEBUG){fprintf(stderr, "played: %d\n", played);} if(played != 1){ fprintf(stderr, "playwav failed on pcm:%s stimfile:%s. Program aborted %s\n", pcm_name, stimexm, asctime(localtime (&curr_tt)) ); fclose(datafp); fclose(dsumfp); exit(-1); } if (DEBUG){fprintf(stderr,"stop sound file\n");} gettimeofday(&stimoff, NULL); if (DEBUG){ stimoff_sec = stimoff.tv_sec; stimoff_usec = stimoff.tv_usec; fprintf(stderr,"stim_off sec: %d \t usec: %d\n", stimoff_sec, stimoff_usec);} /* Wait for response */ if (DEBUG){fprintf(stderr, "flag: waiting for right/left response\n");} timeradd (&stimoff, &respoff, &resp_window); if (DEBUG){respwin_sec = resp_window.tv_sec;} if (DEBUG){respwin_usec = resp_window.tv_usec;} if (DEBUG){fprintf(stderr,"resp window sec: %d \t usec: %d\n", respwin_sec, respwin_usec);} loop=left=right=center=0; do{ nanosleep(&rsi, NULL); left = operant_read(box_id, LEFTPECK); right = operant_read(box_id, RIGHTPECK ); center = operant_read(box_id, CENTERPECK); if((left==0) && (right==0) && (center==0) && flash){ ++loop; if(loop%80==0){ if(loop%160==0){ operant_write (box_id, LFTKEYLT, 1); operant_write (box_id, RGTKEYLT, 1); } else{ operant_write (box_id, LFTKEYLT, 0); operant_write (box_id, RGTKEYLT, 0); } } } gettimeofday(&resp_lag, NULL); if (DEBUG==2){printf("flag: value at right=%d, left=%d, center=%d\t", right, left, center);} }while ( (left==0) && (right==0) && (center==0) && (timercmp(&resp_lag, &resp_window, <)) ); operant_write (box_id, LFTKEYLT, 0); /*make sure the key lights are off after resp interval*/ operant_write (box_id, RGTKEYLT, 0); operant_write (box_id, CTRKEYLT, 0); /* Calculate response time */ curr_tt = time (NULL); loctime = localtime (&curr_tt); /* date and wall clock time of resp */ timersub (&resp_lag, &stimoff, &resp_rt); /* reaction time */ if (DEBUG){resp_sec = resp_rt.tv_sec;} if (DEBUG){ resp_usec = resp_rt.tv_usec;} if (DEBUG){printf("resp rt sec: %d \t usec: %d\n", resp_sec, resp_usec);} resp_rxt = (float) resp_rt.tv_sec + ( (float) resp_rt.tv_usec/1000000); /* format reaction time */ if (DEBUG){printf("flag: resp_rxt = %.4f\n", resp_rxt);} strftime (hour, 16, "%H", loctime); /* format wall clock times */ strftime (min, 16, "%M", loctime); strftime (month, 16, "%m", loctime); strftime (day, 16, "%d", loctime); /* Consequate responses */ if (DEBUG){printf("flag: stim_class = %d\n", stim_class);} if (DEBUG){printf("flag: exit value left = %d, right = %d\n", left, right);} if(targloc == 1){ /* go right */ if ((left==0 ) && (right==1) && (center==0)){ /* correct, went right */ resp_sel = 2; resp_acc = 1; ++Rstim[stim_number].C; ++Tstim[stim_number].C; ++Rstim[stim_number].CbyBP[breakval]; ++Tstim[stim_number].CbyBP[breakval]; ++Rstim[stim_number].right;++Tstim[stim_number].right; reinfor=feed(stim_reinf, &f); if (reinfor == 1) { ++fed;} if (DEBUG){ printf("flag: correct response to stimtype 2\n");} } else if (left == 1){ /* incorrect, went left */ resp_sel = 1; resp_acc = 0; ++Rstim[stim_number].X;++Tstim[stim_number].X; ++Rstim[stim_number].XbyBP[breakval]; ++Tstim[stim_number].XbyBP[breakval]; ++Rstim[stim_number].left;++Tstim[stim_number].left; reinfor = timeout(stim_punish); if (DEBUG){printf("flag: left response to right target, lights out\n");} } else if (center == 1){ /* incorrect, went center - NOTE: CURRENTLY NO PENALTY FOR CENTER RESPONSE*/ resp_sel = 0; resp_acc = 0; ++Rstim[stim_number].X;++Tstim[stim_number].X; ++Rstim[stim_number].XbyBP[breakval]; ++Tstim[stim_number].XbyBP[breakval]; ++Rstim[stim_number].center;++Tstim[stim_number].center; reinfor = 0; if (DEBUG){printf("flag: center response to right target, no punishment\n");} } else{ resp_sel = -1; resp_acc = 2; ++Rstim[stim_number].no;++Tstim[stim_number].no; ++Rstim[stim_number].nobyBP[breakval]; ++Tstim[stim_number].nobyBP[breakval]; reinfor = 0; if (DEBUG){printf("flag: no response to right target\n");} fprintf(datafp, "DEFAULT SWITCH for bit value:ERROR CODE REMOVED"); } } else if (targloc == 2){ if ((left==1 ) && (right== 0) && (center==0)){ /* correct, went left */ resp_sel = 1; resp_acc = 1; ++Rstim[stim_number].C; ++Tstim[stim_number].C; ++Rstim[stim_number].CbyBP[breakval]; ++Tstim[stim_number].CbyBP[breakval]; ++Rstim[stim_number].left;++Tstim[stim_number].left; reinfor=feed(stim_reinf, &f); if (reinfor == 1) { ++fed;} if (DEBUG){ printf("flag: correct response to left target\n");} } else if (right == 1){ /* incorrect, went right */ resp_sel = 2; resp_acc = 0; ++Rstim[stim_number].X;++Tstim[stim_number].X; ++Rstim[stim_number].XbyBP[breakval]; ++Tstim[stim_number].XbyBP[breakval]; ++Rstim[stim_number].right;++Tstim[stim_number].right; reinfor = timeout(stim_punish); if (DEBUG){printf("flag: right response to left target, lights out\n");} } else if (center == 1){ /* incorrect, went center - NOTE: CURRENTLY NO PENALTY FOR CENTER RESPONSE*/ resp_sel = 0; resp_acc = 0; ++Rstim[stim_number].X;++Tstim[stim_number].X; ++Rstim[stim_number].XbyBP[breakval]; ++Tstim[stim_number].XbyBP[breakval]; ++Rstim[stim_number].center;++Tstim[stim_number].center; reinfor = 0; if (DEBUG){printf("flag: center response to left target, no punishment\n");} } else{ resp_sel = -1; resp_acc = 2; ++Rstim[stim_number].no;++Tstim[stim_number].no; ++Rstim[stim_number].nobyBP[breakval]; ++Tstim[stim_number].nobyBP[breakval]; reinfor = 0; if (DEBUG){printf("flag: no response to left target\n");} fprintf(datafp, "DEFAULT SWITCH for bit value:ERROR CODE REMOVED"); } } else{ fprintf(stderr, "Unrecognized stimulus class: Fatal Error"); fclose(datafp); fclose(dsumfp); exit(-1); } /* Pause for ITI */ reinfor_sum = reinfor + reinfor_sum; operant_write(box_id, HOUSELT, 1); /* make sure the houselight is on */ nanosleep(&iti, NULL); /* wait intertrial interval */ if (DEBUG){printf("flag: ITI passed\n");} /* Write trial data to output file */ strftime (tod, 256, "%H%M", loctime); strftime (date_out, 256, "%m%d", loctime); fprintf(datafp, "%d\t%d\t%d\t%s\t\t%s\t%d\t%d\t%d\t%.4f\t%d\t%s\t%s\n", session_num, trial_num, correction, stimexm, distexm, stim_class, resp_sel, resp_acc, resp_rxt, reinfor, tod, date_out ); fflush (datafp); if (DEBUG){printf("flag: trial data written\n");} /*generate some output numbers*/ for (i = 0; i<nstims; i++){ Rstim[i].count = Rstim[i].X + Rstim[i].C + Rstim[i].no; Tstim[i].count = Tstim[i].X + Tstim[i].C + Tstim[i].no; for (j = 0; j<stimulus[j].nbps; j++){ Rstim[i].countbyBP[j] = Rstim[i].XbyBP[j] + Rstim[i].CbyBP[j] + Rstim[i].nobyBP[j]; Tstim[i].countbyBP[j] = Tstim[i].XbyBP[j] + Tstim[i].CbyBP[j] + Tstim[i].nobyBP[j]; } } /* Update summary data */ if(freopen(dsumfname,"w",dsumfp)!= NULL){ fprintf (dsumfp, " SUMMARY DATA FOR st%d, %s\n", subjectid, exp_name); fprintf (dsumfp, "\tPERCENT CORRECT RESPONSES (by stim, including correction trials and no response trials)\n"); fprintf (dsumfp, "\tStim\t\tCount\tToday \t\tCount\tTotals\n"); for (i = 0; i<nstims;++i){ fprintf (dsumfp, "\t%s\t%d\t%1.4f \t\t%d\t%1.4f\n", stimulus[i].exemplar, Rstim[i].count, (float)Rstim[i].C/(float)Rstim[i].count, Tstim[i].count, (float)Tstim[i].C/(float)Tstim[i].count ); } fprintf(stderr, "nstims: %d ", nstims); for (i = 0; i<nstims; ++i){ fprintf (dsumfp, "\tTrials by Probe Time for %s\n", stimulus[i].exemplar ); fprintf (dsumfp, "\tProbe Time\t\tCount\tToday \tProbe Time\tCount\tTotals\n"); for (j = 0; j<stimulus[i].nbps; ++j){ fprintf (dsumfp, "\t%1.2f\t%d\t%1.4f \t\t%d\t%1.4f\n", stimulus[i].breakpt[j], Rstim[i].countbyBP[j], (float)Rstim[i].CbyBP[j]/(float)Rstim[i].countbyBP[j], Tstim[i].countbyBP[j], (float)Tstim[i].CbyBP[j]/(float)Tstim[i].countbyBP[j] ); } } fprintf (dsumfp, "Last trial run @: %s\n", asctime(loctime) ); fprintf (dsumfp, "Trials this session: %d\n",trial_num); fprintf (dsumfp, "Feeder ops today: %d\n", fed ); fprintf (dsumfp, "Hopper failures today: %d\n", f.hopper_failures); fprintf (dsumfp, "Hopper won't go down failures today: %d\n",f.hopper_wont_go_down_failures); fprintf (dsumfp, "Hopper already up failures today: %d\n",f.hopper_already_up_failures); fprintf (dsumfp, "Responses during feed: %d\n", f.response_failures); fprintf (dsumfp, "Rf'd responses: %d\n\n", reinfor_sum); fflush (dsumfp); } else fprintf(stderr, "ERROR!: problem re-opening summary output file!: %s\n", dsumfname); if (DEBUG){printf("flag: summaries updated\n");} /* End of trial chores */ sigprocmask (SIG_UNBLOCK, &trial_mask, NULL); /* unblock termination signals */ if (resp_acc == 0){ correction = 0;} else if (resp_acc == 0){ correction = 0;} else correction = 1; /* set correction trial var */ if ((xresp==1)&&(resp_acc == 2)){ correction = 0;} /* set correction trial var for no-resp */ fprintf(stderr, "probeCO=%f, correction=%i\n", probeCO, correction); curr_tt = time(NULL); loctime = localtime (&curr_tt); strftime (hour, 16, "%H", loctime); strftime(min, 16, "%M", loctime); currtime=(atoi(hour)*60)+atoi(min); if (DEBUG){printf("minutes since midnight at trial end: %d\t starttime: %d\tstoptime: %d\n",currtime,starttime,stoptime);} }while ((correction==0)&&(trial_num<=trial_max)&&(currtime>=starttime)&&(currtime<stoptime)); /* correction trial loop */ stim_number = -1; /* reset the stim number for correct trial*/ } /* trial loop */ /* You'll end up here if its night time or if you skip a day The latter only happens if the night window elapses between the time a stimulus is chosen and the time its actually played--i.e. if the subject doesn't initiates a cued trial during the night window, which is rare */ /* Loop while lights out */ if (DEBUG){printf("minutes since midnight: %d\t starttime: %d\tstoptime: %d\n",currtime,starttime,stoptime);} while( (currtime<starttime) || (currtime>=stoptime) ){ operant_write(box_id, HOUSELT, 0); operant_write(box_id, FEEDER, 0); operant_write(box_id, LFTKEYLT, 0); operant_write(box_id, CTRKEYLT, 0); operant_write(box_id, RGTKEYLT, 0); operant_write(box_id, GREENLT, 0); operant_write(box_id, BLUELT, 0); operant_write(box_id, REDLT, 0); sleep (sleep_interval); curr_tt = time(NULL); loctime = localtime (&curr_tt); strftime (hour, 16, "%H", loctime); strftime (min, 16, "%M", loctime); currtime=(atoi(hour)*60)+atoi(min); if (DEBUG){printf("minutes since midnight: %d\t starttime: %d\tstoptime: %d\n",currtime,starttime,stoptime);} } operant_write(box_id, HOUSELT, 1); /*reset some vars for the new day */ ++session_num; trial_num = 0; for(i = 0; i<nstims;++i){ Rstim[i].C = Rstim[i].X = Rstim[i].count = Rstim[i].left = Rstim[i].center = Rstim[i].right = 0; } f.hopper_wont_go_down_failures = f.hopper_already_up_failures = f.hopper_failures =f.response_failures = fed = reinfor_sum = 0; /*figure new sunrise/set times*/ curr_tt = time(NULL); loctime = localtime (&curr_tt); strftime (year, 16, "%Y", loctime); strftime(month, 16, "%m", loctime); strftime(day, 16,"%d", loctime); if(dosunrise){ rise_tt = sunrise(atoi(year), atoi(month), atoi(day), latitude, longitude); strftime(temphour, 16, "%H", localtime(&rise_tt)); strftime(tempmin, 16, "%M", localtime(&rise_tt)); starthour=atoi(temphour); startmin=atoi(tempmin); strftime(buffer,30,"%m-%d-%Y %H:%M:%S",localtime(&rise_tt)); if(DEBUG){fprintf(stderr,"Sessions start at sunrise(Today: '%s')\n",buffer);} } if(dosunset){ set_tt = sunset(atoi(year), atoi(month), atoi(day), latitude, longitude); strftime(temphour, 16, "%H", localtime(&set_tt)); strftime(tempmin, 16, "%M", localtime(&set_tt)); stophour=atoi(temphour); stopmin=atoi(tempmin); strftime(buffer,30,"%m-%d-%Y %T",localtime(&set_tt)); if(DEBUG){fprintf(stderr,"Session stop at sunset(Today: '%s')\n",buffer);} } if(DEBUG){fprintf(stderr, "starthour: %d\tstartmin: %d\tstophour: %d\tstopmin: %d\n", starthour,startmin,stophour,stopmin);} }while (1);/*main trial loop*/ /* Cleanup */ fclose(datafp); fclose(dsumfp); free(playlist); return 1; }
command_t * command_parse(parsestate_t *parsestate) { int i = 0; command_t *cmd = command_alloc(); if (!cmd) return NULL; int flag_in=0; int flag_out=0; int flag_err=0; while (1) { // EXERCISE: Read the next token from 'parsestate'. // Normal tokens go in the cmd->argv[] array. // Redirection file names go into cmd->redirect_filename[]. // Open parenthesis tokens indicate a subshell command. // Other tokens complete the current command // and are not actually part of it; // use parse_ungettoken() to save those tokens for later. // There are a couple errors you should check. // First, be careful about overflow on normal tokens. // Each command_t only has space for MAXTOKENS tokens in // 'argv'. If there are too many tokens, reject the whole // command. // Second, redirection tokens (<, >, 2>) must be followed by // TOK_NORMAL tokens containing file names. // Third, a parenthesized subcommand can't be part of the // same command as other normal tokens. For example, // "echo ( echo foo )" and "( echo foo ) echo" are both errors. // (You should figure out exactly how to check for this kind // of error. Try interacting with the actual 'bash' shell // for some ideas.) // 'goto error' when you encounter one of these errors, // which frees the current command and returns NULL. // Hint: An open parenthesis should recursively call // command_line_parse(). The command_t structure has a slot // you can use for parens; figure out how to use it! token_t token; memset(&token, 0, sizeof(token)); parse_gettoken(parsestate, &token); switch (token.type) { case TOK_NORMAL: if(flag_out){ flag_out=0; cmd->redirect_filename[1]=strdup(token.buffer); break; } else if(flag_in){ flag_in=0; cmd->redirect_filename[0]=strdup(token.buffer); break; } else if(flag_err){ flag_err=0; cmd->redirect_filename[2]=strdup(token.buffer); break; } if(i==MAXTOKENS) goto error; cmd->argv[i] = strdup(token.buffer); i++; break; case TOK_PIPE: cmd->controlop=CMD_PIPE; parse_ungettoken(parsestate); goto done; case TOK_DOUBLEPIPE: cmd->controlop=CMD_OR; parse_ungettoken(parsestate); goto done; case TOK_AMPERSAND: cmd->controlop=CMD_BACKGROUND; parse_ungettoken(parsestate); goto done; case TOK_DOUBLEAMP: cmd->controlop=CMD_AND; parse_ungettoken(parsestate); goto done; case TOK_SEMICOLON: cmd->controlop=CMD_SEMICOLON; parse_ungettoken(parsestate); goto done; case TOK_OPEN_PAREN: cmd->subshell=command_line_parse(parsestate,1); break; case TOK_CLOSE_PAREN: parse_ungettoken(parsestate); goto done; case TOK_END: parse_ungettoken(parsestate); cmd->controlop=CMD_END; goto done; case TOK_ERROR: goto error; case TOK_GREATER_THAN: flag_out=1; break; case TOK_LESS_THAN: flag_in=1; break; case TOK_2_GREATER_THAN: flag_err=1; break; default: parse_ungettoken(parsestate); goto done; } } done: // NULL-terminate the argv list cmd->argv[i] = 0; // EXERCISE: Make sure you return the right return value! if (i == 0 && cmd->subshell==NULL) { /* Empty command */ command_free(cmd); return NULL; } else return cmd; error: command_free(cmd); return NULL; }