static char * put_filter(port *p, string text, int length) { string input; string output; if (p->status & INPUT_CLOSED) return(NULL); input = convert_nulls_to_newlines(text, length); output = (*(p->data.filter.filter))(input); free(input); string_stack_push(p->data.filter.waiting_packets, output); return(NULL); }
int user_input_word(int grp_max_generators, int grp_max_word_len, char **word) { /****************************************************************************/ /* Local variables. */ /****************************************************************************/ char subword[grp_max_word_len]; int subword_index = 0; char *popped_word; int ii; int jj; int input_ret_code; int exponent; char exponent_string[grp_max_word_len]; int exp_string_index = 0; char *user_input; int ret_code = WORD_INPUT_OK; bool parsing_exponent = false; bool hat_found = false; bool valid_exp = false; STRING_STACK_ELEMENT *top = NULL; int nest_depth = 0; /****************************************************************************/ /* Check input parameters. */ /****************************************************************************/ assert(grp_max_word_len < MAX_WORD_LEN); assert(grp_max_generators < MAX_GENERATORS); /****************************************************************************/ /* Ask the user for input and flush the output buffer to make sure the user */ /* sees the request. */ /****************************************************************************/ printf("Enter a word for the group loaded.\n"); fflush(stdout); /****************************************************************************/ /* Call the input_string method to retrieve a string containing the word. */ /****************************************************************************/ input_ret_code = input_string(MAX_WORD_LEN, &user_input); if (input_ret_code != STRING_INPUT_OK) { ret_code = WORD_INPUT_INVALID; goto EXIT_LABEL; } /****************************************************************************/ /* If the input string is longer than the maximum word size then return. */ /****************************************************************************/ if (strlen(user_input) > grp_max_word_len) { printf("The word inputted is too long.\n"); free(user_input); ret_code = WORD_INPUT_TOO_LONG; goto EXIT_LABEL; } /****************************************************************************/ /* Set the first character in the subword to be NULL to start. This means */ /* that even if there are no characters in the user input subword contains */ /* a well defined string. */ /****************************************************************************/ subword[0] = '\0'; /****************************************************************************/ /* Go through the word one character at a time parsing it. */ /****************************************************************************/ for (ii = 0; ii < strlen(user_input); ii++) { if (parsing_exponent) { if (((int) user_input[ii]) == (int) '^') { /**********************************************************************/ /* The first time that ^ is found after a bracket we can start */ /* looking for digits. */ /**********************************************************************/ hat_found = true; } else if ((((int) user_input[ii]) >= (int) '0') && (((int) user_input[ii]) <= (int) '9')) { /**********************************************************************/ /* Exponents must be of the form ^x where x is a digit. If the ^ is */ /* not found then it is not a valid exponent and the word fails. */ /**********************************************************************/ if (!hat_found) { printf("The word was invalid as a close brack was not followed by ^.\n"); ret_code = WORD_INPUT_INVALID; empty_string_stack(top); free(user_input); goto EXIT_LABEL; } /**********************************************************************/ /* As soon as a digit is found after a ^ we have a valid exponent. */ /**********************************************************************/ valid_exp = true; /**********************************************************************/ /* We generate a substring which contains the exponent. */ /**********************************************************************/ exponent_string[exp_string_index] = user_input[ii]; exp_string_index++; } else if ((((int) user_input[ii]) >= (int)'a' && ((int) user_input[ii]) <= (int)'a' + grp_max_generators - 1) || (((int) user_input[ii]) == (int) '(') || (((int) user_input[ii]) == (int) ')')) { /**********************************************************************/ /* It is only valid that a non-exponent valid character was found if */ /* the exponent found so far is valid. If not then the word fails. */ /**********************************************************************/ if (!valid_exp) { printf("A valid exponent was not found because there were no digits after a ^ character.\n"); ret_code = WORD_INPUT_INVALID; empty_string_stack(top); free(user_input); goto EXIT_LABEL; } /**********************************************************************/ /* At this point we know we have a valid exponent so we turn it into */ /* a number. */ /**********************************************************************/ exponent_string[exp_string_index] = '\0'; exponent = atoi(exponent_string); popped_word = string_stack_pop(&top); /**********************************************************************/ /* Add exponent many copies of the current subword to the word popped */ /* off the stack. */ /* The result is the new subword. */ /**********************************************************************/ for (jj = 0; jj < exponent; jj++) { strncat(popped_word, subword, strlen(subword)); } strncpy(subword, popped_word, strlen(popped_word)); subword[strlen(popped_word)] = '\0'; free(popped_word); /**********************************************************************/ /* Return to parsing the word normally. */ /**********************************************************************/ parsing_exponent = false; hat_found = false; valid_exp = false; exp_string_index = 0; subword_index = strlen(subword); } else { printf("An invalid character was found (%c) whilst parsing exponent.\n", user_input[ii]); } } if (!parsing_exponent) { if (((int) user_input[ii]) >= (int)'a' && ((int) user_input[ii]) <= (int)'a' + grp_max_generators - 1) { subword[subword_index] = user_input[ii]; subword_index++; /**********************************************************************/ /* The next character in the current subword should always be set to */ /* a null character in case there are no more brackets. */ /**********************************************************************/ subword[subword_index] = '\0'; } else if (((int) user_input[ii]) == (int) '(') { /**********************************************************************/ /* When we hit an open bracket we put the current string onto the */ /* stack and start again with an empty string. */ /**********************************************************************/ string_stack_push(subword, &top); subword_index = 0; /**********************************************************************/ /* To keep a track of the number of brackets opened we increment a */ /* depth counter. */ /**********************************************************************/ nest_depth++; } else if (((int) user_input[ii]) == (int) ')') { /**********************************************************************/ /* If the nest depth counter is not greater than 0 then there are no */ /* brackets to be closed and the word is not valid. */ /**********************************************************************/ if (nest_depth <= 0) { printf("A bracket was closed without being opened.\n"); ret_code = WORD_INPUT_INVALID; empty_string_stack(top); free(user_input); goto EXIT_LABEL; } /**********************************************************************/ /* When a close bracket is hit we insist that the next few characters */ /* are in a particular form. To force this we set a boolean which */ /* tells the program that it is parsing an exponent until it stops. */ /**********************************************************************/ parsing_exponent = true; subword_index = 0; nest_depth--; } else { printf("There is an invalid character (%c) in the word.\n", user_input[ii]); ret_code = WORD_INPUT_INVALID; empty_string_stack(top); free(user_input); goto EXIT_LABEL; } } } /****************************************************************************/ /* After the end of the word has been found the nest depth should be zero */ /* indicating that all brackets have been closed. */ /****************************************************************************/ if (nest_depth != 0) { printf("More brackets were opened than were closed in the word.\n"); ret_code = WORD_INPUT_INVALID; empty_string_stack(top); free(user_input); goto EXIT_LABEL; } /****************************************************************************/ /* If the string ends whilst still parsing the exponent but without having */ /* finished then the exponent is not valid and therefore the word isn't. */ /* e.g. w = abd(ca)^ is not a valid word and will hit this branch. */ /****************************************************************************/ if (parsing_exponent && !valid_exp) { printf("The word ended without a complete exponent.\n"); ret_code = WORD_INPUT_INVALID; empty_string_stack(top); free(user_input); goto EXIT_LABEL; } /****************************************************************************/ /* If the last character in the user input string was an exponent then we */ /* deal with it by popping the last string off the stack and adding the */ /* current subword as usual. */ /****************************************************************************/ if (valid_exp) { exponent_string[exp_string_index] = '\0'; exponent = atoi(exponent_string); popped_word = string_stack_pop(&top); /**************************************************************************/ /* Add exponent many copies of the current subword to the word popped off */ /* the stack. */ /* The result is the new subword. */ /**************************************************************************/ for (jj = 0; jj < exponent; jj++) { strncat(popped_word, subword, strlen(subword)); } strncpy(subword, popped_word, strlen(popped_word) + 1); free(popped_word); } /****************************************************************************/ /* Allocate the required amount of memory for the returned word. Then put */ /* the parsed word in to the new memory and return it. */ /****************************************************************************/ (*word) = (char *) malloc(sizeof(char) * strlen(subword) + 1); if (word == NULL) { printf("Memory allocation error creating word."); ret_code = WORD_INPUT_MEM_FAIL; goto EXIT_LABEL; } strncpy(*word, subword, strlen(subword) + 1); free(user_input); EXIT_LABEL: return(ret_code); }