int main(int argc, char **argv) { char buffer[1024]; int continueloop = 0; char** commands; int state = 0; // 0 = sequential, 1 = parallel, 2 = exit while(continueloop == 0){ if (state == 0) printf("\nOperating in sequential mode\n"); else if (state == 1) printf("\nOperating in parallel mode\n"); printf("Type away>> "); fgets(buffer, 1024, stdin); removeComments(buffer); commands = tokenify(buffer, ";"); if (state == 0){ state = seqParse(&commands); } else if (state == 1){ state = parParse(&commands); } if (state == 2){ printf("Goodbye\n"); freeTokens(commands); return 0; } freeTokens(commands); } return 0; }
//Parses commands sequentially int seqParse(char*** commands){ const char* whitespace = " \t\n"; char** arguments; bool is_built_in = true; int* status = 0; pid_t pid; int state = 0; for (int i = 0; (*commands)[i] != NULL; i++){ arguments = tokenify((*commands)[i], whitespace); is_built_in = built_in(arguments, &state); if (!is_built_in){ pid = fork(); if (pid == 0){ //child process execv(arguments[0], arguments);//execv the command freeTokens(arguments); printf("Command not valid\n"); //if execv returns, command was invalid exit(0); } else{ //parent process waitpid(pid, status, 0); // wait for child process to end } } freeTokens(arguments); } return state; }
//Parse in parallel int parParse(char*** commands){ const char* whitespace = " \t\n"; char** arguments; bool is_built_in = true; pid_t pid; int i; int state = 1; pid_t waitArr[arrLen(*commands)]; memset(waitArr, 0, (arrLen(*commands)+1)*sizeof(pid_t)); for (i = 0; (*commands)[i] != NULL; i++){ arguments = tokenify((*commands)[i], whitespace); is_built_in = built_in(arguments, &state); //check if built in if (!is_built_in){ pid = fork(); //create child process if (pid == 0){ execv(arguments[0], arguments); freeTokens(arguments); printf("Command not valid\n"); exit(0); } else{ waitArr[i] = pid; } } freeTokens(arguments); } waitParallel(waitArr); return state; }
//sees if a string is empty bool is_empty(char* input){ char* temp = strdup(input); char** tokens = tokenify(temp, " \n\t"); if (tokens[0] == NULL){ free(temp); freeTokens(tokens); return true; } free(temp); freeTokens(tokens); return false; }
void freeTokens(Value* tokens) { Value* current = tokens; if (current == NULL) { return; } if(current->type == 8) { freeTokens(current->uni.cons->car); freeTokens(current->uni.cons->cdr); } free(current); }
TEST(VolumeMapTestGroup, VolumeMapTokenize) { char *input = strdup("abcd:efgh"); char **tokens = _tokenizeVolumeMapInput(input); size_t ntokens = 0; for ( ; tokens && tokens[ntokens]; ntokens++) { } CHECK(tokens != NULL && ntokens == 2); CHECK(strcmp(tokens[0], "abcd") == 0); CHECK(strcmp(tokens[1], "efgh") == 0); freeTokens(tokens); free(input); input = strdup("abcd:efgh:flag"); tokens = _tokenizeVolumeMapInput(input); for (ntokens = 0 ; tokens && tokens[ntokens]; ntokens++) { } CHECK(tokens != NULL && ntokens == 3); CHECK(strcmp(tokens[0], "abcd") == 0); CHECK(strcmp(tokens[1], "efgh") == 0); CHECK(strcmp(tokens[2], "flag") == 0); freeTokens(tokens); free(input); input = strdup("abcd:efgh:flag:extra"); tokens = _tokenizeVolumeMapInput(input); for (ntokens = 0 ; tokens && tokens[ntokens]; ntokens++) { } CHECK(tokens != NULL && ntokens == 4); CHECK(strcmp(tokens[0], "abcd") == 0); CHECK(strcmp(tokens[1], "efgh") == 0); CHECK(strcmp(tokens[2], "flag") == 0); CHECK(strcmp(tokens[3], "extra") == 0); freeTokens(tokens); free(input); input = strdup("no delim test"); tokens = _tokenizeVolumeMapInput(input); for (ntokens = 0 ; tokens && tokens[ntokens]; ntokens++) { } //fprintf(stderr," got %lu tokens\n0: %s\n1: %s\n2: %s\n", ntokens, tokens[0], tokens[1], tokens[2]); CHECK(tokens != NULL && ntokens == 1); CHECK(strcmp(tokens[0], "no delim test") == 0); freeTokens(tokens); free(input); }
int main(int argc, char *argv[]) { char *pcLine; DynArray_T oTokens; pcPgmName = argv[0]; printf("%s \n", pcPgmName); printf("------------------------------------\n"); while ((pcLine = readLine(stdin)) != NULL) { printf("Line: %s\n", pcLine); fflush(stdout); oTokens = lexLine(pcLine); if (oTokens != NULL) { writeTokens(oTokens); freeTokens(oTokens); DynArray_free(oTokens); } printf("------------------------------------\n"); free(pcLine); } return 0; }
void rewindToken( TokenContext *tc ){ Token *t = tc->last; if (tc->root == tc->last){ /* Only one token exists */ freeTokens(t); tc->root = NULL; tc->last = NULL; } else { /* Multiple tokens exist */ tc->last = t->prev; freeTokens(t); } }
/*****************************************************************************\ | Tokenization Code | \*****************************************************************************/ Token *tokenizeStream( FILE *fin ){ TokenContext tc; int c; initializeTokenContext(&tc); while ((c=fgetc(fin)) != EOF){ /* Get current tokenization state */ TokenState *nextState = tc.state->nextState(c, &tc); if (!nextState){ /* Error encountered */ fprintf(stderr, "Invalid token encountered\n"); if (tc.root){ freeTokens(tc.root); } return NULL; } if (nextState != tc.state){ /* Entering new tokenization state */ if (tc.state->exit){ tc.state->exit(&tc); } if (nextState->enter){ nextState->enter(&tc); } tc.state = nextState; } /* Process input */ if (tc.state->readChar){ tc.state->readChar(c, &tc); } } return tc.root; }
static DynArray_T lexLine(const char *pcLine) { /* lexLine() uses a DFA approach. It "reads" its characters from pcLine. The DFA has these three states: */ enum LexState {STATE_START, STATE_IN_NUMBER, STATE_IN_WORD}; /* The current state of the DFA. */ enum LexState eState = STATE_START; /* An index into pcLine. */ int iLineIndex = 0; /* Pointer to a buffer in which the characters comprising each token are accumulated. */ char *pcBuffer; /* An index into the buffer. */ int iBufferIndex = 0; char c; struct Token *psToken; DynArray_T oTokens; int iSuccessful; assert(pcLine != NULL); /* Create an empty token DynArray object. */ oTokens = DynArray_new(0); if (oTokens == NULL) {perror(pcPgmName); exit(EXIT_FAILURE);} /* Allocate memory for a buffer that is large enough to store the largest token that might appear within pcLine. */ pcBuffer = (char*)malloc(strlen(pcLine) + 1); if (pcBuffer == NULL) {perror(pcPgmName); exit(EXIT_FAILURE);} for (;;) { /* "Read" the next character from pcLine. */ c = pcLine[iLineIndex++]; switch (eState) { /* Handle the START state. */ case STATE_START: if (c == '\0') { free(pcBuffer); return oTokens; } else if (isdigit(c)) { pcBuffer[iBufferIndex++] = c; eState = STATE_IN_NUMBER; } else if (isalpha(c)) { pcBuffer[iBufferIndex++] = c; eState = STATE_IN_WORD; } else if (isspace(c)) eState = STATE_START; else { fprintf(stderr, "Invalid line\n"); free(pcBuffer); freeTokens(oTokens); DynArray_free(oTokens); return NULL; } break; /* Handle the IN_NUMBER state. */ case STATE_IN_NUMBER: if (c == '\0') { /* Create a NUMBER token. */ pcBuffer[iBufferIndex] = '\0'; psToken = newToken(TOKEN_NUMBER, pcBuffer); iSuccessful = DynArray_add(oTokens, psToken); if (! iSuccessful) {perror(pcPgmName); exit(EXIT_FAILURE);} iBufferIndex = 0; free(pcBuffer); return oTokens; } else if (isdigit(c)) { pcBuffer[iBufferIndex++] = c; eState = STATE_IN_NUMBER; } else if (isspace(c)) { /* Create a NUMBER token. */ pcBuffer[iBufferIndex] = '\0'; psToken = newToken(TOKEN_NUMBER, pcBuffer); iSuccessful = DynArray_add(oTokens, psToken); if (! iSuccessful) {perror(pcPgmName); exit(EXIT_FAILURE);} iBufferIndex = 0; eState = STATE_START; } else { fprintf(stderr, "Invalid line\n"); free(pcBuffer); freeTokens(oTokens); DynArray_free(oTokens); return NULL; } break; /* Handle the IN_WORD state. */ case STATE_IN_WORD: if (c == '\0') { /* Create a WORD token. */ pcBuffer[iBufferIndex] = '\0'; psToken = newToken(TOKEN_WORD, pcBuffer); iSuccessful = DynArray_add(oTokens, psToken); if (! iSuccessful) {perror(pcPgmName); exit(EXIT_FAILURE);} iBufferIndex = 0; free(pcBuffer); return oTokens; } else if (isalpha(c)) { pcBuffer[iBufferIndex++] = c; eState = STATE_IN_WORD; } else if (isspace(c)) { /* Create a WORD token. */ pcBuffer[iBufferIndex] = '\0'; psToken = newToken(TOKEN_WORD, pcBuffer); iSuccessful = DynArray_add(oTokens, psToken); if (! iSuccessful) {perror(pcPgmName); exit(EXIT_FAILURE);} iBufferIndex = 0; eState = STATE_START; } else { fprintf(stderr, "Invalid line\n"); free(pcBuffer); freeTokens(oTokens); DynArray_free(oTokens); return NULL; } break; default: assert(0); } } }
void freeTokens(struct token* t) { if(t == NULL) return; freeTokens(t->next); freeToken(t); }
void freeTokenList(struct token** head) { struct token* curr = *head; freeTokens(curr); free(head); }
int main( int argc, char *argv[] ) { /* for parsing args */ extern char *optarg; extern int optind; int ch; /* vars */ int i,j; int listenfd; /* select vars */ fd_set read_set; int fdmax; /* client arr */ Arraylist clientList; /* channel arr */ Arraylist channelList; /* servername */ char servername[MAX_SERVERNAME+1]; while ((ch = getopt(argc, argv, "hD:")) != -1) switch (ch) { case 'D': if (set_debug(optarg)) { exit(0); } break; case 'h': default: /* FALLTHROUGH */ usage(); } argc -= optind; argv += optind; if (argc < 2) { usage(); } signal(SIGPIPE, SIG_IGN); init_node(argv[0], argv[1]); printf( "I am node %lu and I listen on port %d for new users\n", curr_nodeID, curr_node_config_entry->irc_port ); /* Start your engines here! */ if (gethostname(servername,MAX_SERVERNAME) < 0){ perror("gethostname"); return EXIT_FAILURE; } servername[MAX_SERVERNAME] = '\0'; /* delegate all function calling to setupListenSocket. It should print out relevant err messages. */ listenfd = setupListenSocket(curr_node_config_entry->irc_port); if (listenfd < 0){ return EXIT_FAILURE; } /* initialize client array */ clientList = arraylist_create(); /* initialize channel array */ channelList = arraylist_create(); /* prepare for select */ fdmax = listenfd; FD_ZERO(&master_set); FD_ZERO(&write_set); FD_SET(listenfd,&master_set); /* FD_ZERO(&write_set); initially no data to write */ /* main loop!! */ for (;;){ int retval; read_set = master_set; /* wait until any sockets become available */ retval = select(fdmax+1,&read_set,&write_set,NULL,NULL); if (retval <= 0){ if (retval < 0) DEBUG_PERROR("select"); continue; /* handle errors gracefully and wait again if timed out (it shouldn't)*/ } /* at least one socket ready*/ for (i = 0; i <= fdmax; i++){ if (FD_ISSET(i, &write_set)) { int listIndex = findClientIndexBySockFD(clientList,i); client_t *thisClient = (client_t *) CLIENT_GET(clientList,listIndex); /*client data ready to be written */ int nbytes; /* iterate through item to be sent, until it will block */ Arraylist outbuf = thisClient->outbuf; while (!arraylist_is_empty(outbuf)) { /* write */ char *dataToSend = (char *) (arraylist_get(outbuf,0)) + thisClient->outbuf_offset; size_t sizeToSend = strlen(dataToSend); nbytes = send(thisClient->sock, dataToSend, sizeToSend, 0); if (nbytes <0){ /* error */ if (errno == EPIPE || errno == ECONNRESET){ /* connection lost or closed by the peer */ DPRINTF(DEBUG_SOCKETS,"send: client %d hungup\n",i); remove_client(clientList,listIndex); continue; } } else if (nbytes == sizeToSend){ /* current line completely sent */ char *toRemove = (char *) (arraylist_get(outbuf,0)); arraylist_removeIndex(outbuf,0); free(toRemove); } else{ /* partial send */ thisClient->outbuf_offset += nbytes; break; } } if (arraylist_is_empty(outbuf)) FD_CLR(i, &write_set); } if (FD_ISSET(i, &read_set)) { if (i == listenfd){ /* incoming connection */ int newindex = handle_incoming_conn(clientList,servername,listenfd); if (newindex < 0){ continue; } client_t *newClient = CLIENT_GET(clientList,newindex); int newfd = newClient->sock; FD_SET(newfd,&master_set); if (newfd > fdmax){ fdmax = newfd; } } else{ /* client data ready */ char *tempPtr; int listIndex = findClientIndexBySockFD(clientList,i); /* for split function */ char** tokenArr; int numToken; int lastTokenTerminated; if (listIndex < 0){ close(i); FD_CLR(i,&master_set); continue; } int nbytes = recv(i, CLIENT_GET(clientList,listIndex)->inbuf + CLIENT_GET(clientList,listIndex)->inbuf_size, MAX_MSG_LEN - CLIENT_GET(clientList,listIndex)->inbuf_size, 0); /* recv failed. Either client left or error */ if (nbytes <= 0){ if (nbytes == 0){ DPRINTF(DEBUG_SOCKETS,"recv: client %d hungup\n",i); remove_client(clientList, listIndex); } else if (errno == ECONNRESET || errno == EPIPE){ DPRINTF(DEBUG_SOCKETS,"recv: client %d connection reset \n",i); remove_client(clientList, listIndex); } else{ perror("recv"); } continue; } /* NULL terminate to use strpbrk */ CLIENT_GET(clientList,listIndex)->inbuf_size += nbytes; CLIENT_GET(clientList,listIndex)->inbuf[CLIENT_GET(clientList,listIndex)->inbuf_size] = '\0'; tempPtr = strpbrk(CLIENT_GET(clientList,listIndex)->inbuf,"\r\n"); if (!tempPtr){ if (CLIENT_GET(clientList,listIndex)->inbuf_size == MAX_MSG_LEN){ /* Message too long. Dump the content */ DPRINTF(DEBUG_INPUT,"recv: message longer than MAX_MESSAGE detected. The message will be discarded\n"); CLIENT_GET(clientList,listIndex)->inbuf_size = 0; } continue; } tokenArr = splitByDelimStr(CLIENT_GET(clientList,listIndex)->inbuf,"\r\n",&numToken,&lastTokenTerminated); /* since we have checked if there's delimeter beforehand, there should be at least one terminated token available*/ if (!tokenArr){ DPRINTF(DEBUG_INPUT,"splitByDelimStr: failed to split inputToken\n"); CLIENT_GET(clientList,listIndex)->inbuf_size = 0; continue; } if (!lastTokenTerminated){ CLIENT_GET(clientList,listIndex)->inbuf_size = strlen(tokenArr[numToken-1]); memcpy(CLIENT_GET(clientList,listIndex)->inbuf,tokenArr[numToken-1],CLIENT_GET(clientList,listIndex)->inbuf_size); numToken--; } for (j=0;j<numToken;j++){ handle_line(clientList,listIndex,channelList,servername,tokenArr[j]); } for (j = 0; j < arraylist_size(clientList); j++){ client_t *client = CLIENT_GET(clientList,j); if (arraylist_size(client->outbuf)){ FD_SET(client->sock,&write_set); } } freeTokens(&tokenArr,numToken); } } } } return 0; }