Your assigned task is to write the code for the "insert_name_list(...)" subprogram, whose prototype is shown below and is defined in the name_list.h header file.
void insert_name_list(sNAME_LIST *name_list, // The linked list of names. sNODE *node ); // The node containing the name.
The purpose of the "insert_name_list(...)" subprogrm is to build a single-linked list of names, with the following provisions:
- A given name is inserted in the "name_list" ONLY if the name is not already present in the list.
- If a name is already present in the list, then the "insert_name_list(...)" routine simply discards the given node by freeing it's storage.
- A new node is always inserted at the end of the list, that is, it is appended to the list.
- Stop searching the list of names as soon as the target name is found to be present in the list.
- An appropriate error message is printed if the "name_list" does not exist, or is undefined.
Compile and execute the project to test your code. You MUST NOT alter any of the given code. Your list must be constructed so that it will work with the given source code.
. name_list.h #ifndef NAME_LIST_H_ #define NAME_LIST_H_ #define MAX_FIRST_NAME_LNG 41 #define MAX_LAST_NAME_LNG MAX_FIRST_NAME_LNG #define MAX_MIDDLE_NAME_LNG MAX_FIRST_NAME_LNG // Max. size of First Name field tend byte. // Max. size of Last Name field tend byte. // Max. size of Middle Name field +end byte. typedef struct { char first_name[MAX_FIRST_NAME_LNG]; char last_name [MAX_LAST_NAME_LNG ]; } SNAME; // Name Structure storing the First, Last, and Middle name of a person's name. // Stores the person's first name. // Stores the person's last name. // NAME is the name given to the person's name structure typedef struct node{ SNAME name; struct node *next; } SNODE; // List node structure. // Compound field storing the person's name. // Pointer to an SNODE node. // SNODE is the name given to the node structure. typedef struct { SNODE *front; SNODE *rear; int count; } SNAME_LIST; // Pointer to the FIRST nodeame of the SNAME_LIST. // Pointer to the LAST nodeame of the SNAME_LIST. // Count of number of nodesames are present in the SNAME_LIST. ========= //===== SUBPROGRAM PROTOTYPES ==== // Subprogram to initialize the "name_list". void initialize_name_list(SNAME_LIST *name_list); // Subprogram to free (i.e. Clean) all the nodes in the "name_list". int free_name_list(SNAME_LIST *name_list); // Subprogram to print the Data content of the "name_list". int output_name_list(SNAME_LIST *name_list); // Subprogram to insert a name in the list, but only if the name is NOT // already in the list. void insert_name_list(SNAME_LIST *name_list, SNODE *node ); #endif home_list. #include
#include #include #include Ninclude 'ru Library.h" #include "name-list.h" void initialize_name_list(SNAME_LIST narc_list) // The empty mane List has both, front and rear pointers get to NULL because the list does NOT contain any nodes, i.e. names. W of course, the count field is set to ZERO for the same reason. { static char pname[] = initialize_name_listo"; if (name List !- NULL) { // Check for under inedon-existent nameList". name_list-stront - NULL; nanc_list->rear = NULL; nane_list->count = 3.8; // set front of list pointer to NULL pointer, // set rear of list pointer to WILL pointer. // list has ZERO mares initially, Helse { sprintf(ng[A], 545", "In Function: ", prane); sprintring(1), **s"; "Internal Error: List not Initialized because it does not existi'); report_message(eg, MSG_ERROR); } return; 1 int free_name_list(SNAME_LIST Anane list) 1/ Given the single-Linked List nene list", this subprogram CLEANS the list. That is, it frees all of the nodes in the list, 1 including the header node. It returns a count of the number of nodes freed, including the list header node, { static char pname] = freename_List("; int freed; SMODE -pentti // Count of number of nodes "freed", including header nede. // Pointer to next "Mode-To-Free, or node to clean". n_freed = 3; it (name_list = NULL) { // Check for under indon-existent name_List". 1+ ((name_list-front !- NULL) 66 ( Chamc_list->rear NULL) 55 (name_list->count > 2 ) ) { 1/ Check for cepty list // ==> List is NOT empty! while (nale list-front fe none List->rear 1 l Traverse the nane_list from front to rear, and free every node encountered. Puntf = naze_list->front; // punt points to the next node to free. This is always the first nade in the list. nane list-sfront - p ntr->next; // "de-Link (1.e. drop/remove) the ntr node from the list. 1 The mode following the pantt node is now at the front of the list. free(p_ntt); n_freedte // free the de linked punti node, {update freed counter // update freed counter. n_freed++; } free( name_list->front); n_freed++; // Free the last remaining node in the list. Helse { sprintf(msg(e), "%s", "In Function: ", pname); sprintf(msg[1], "%s", "List is EMPTY! Only header node freed."); report_message(msg, MSG_INFO); } free(name_list); // Free header node. name_list = NULL; n_freed++; Helse { sprintf(msg[0], "%s%s", "In Function: ", pname); sprintf(msg[1], "%s", "Internal Error: List not freed because it does not exist!"); report_message(msg, MSG_ERROR); return (n_freed); } int output_name_list(SNAME_LIST *name_list) // Linked list of names. static char pname[] = "output_name_list()"; int n_printed; SNODE *p_scan; // Number of names output/printed. // Scan pointer used to traverse the "name_list". if ( name_list != NULL) { // Check for undefinedon-existent "name_list". if ( (name_list->front != NULL) &G (came_list->rear != NULL) && (name_list->count > 0 ) ) { // Check for empty list. printf(NL); printf("List of Names with duplicates REMOVED: "); // Always nice to label the output with a descriptive heading, printf("=======EEEEEEEEEE======== "); n_printed = 0; puscan = name_list->front; // Set p scan to point to the first node in the last. while (n_printed count) { // Traverse the name_list from beginning to end and output // the data content of each node. printf("%s %s ", puscan->name.first_name , p_scan->name.last_name); n-printed++; // Update the counter to keep track of the no. of names printed. puscan = puscan->next; // Update the scan pointer to point to the next node. } }else { sprintf(msg(e), "%%s", "In Function: ", pname); sprintf(msg[1], "%s", "List is EMPTY! Nothing to output/print."); report_message(msg, MSG_INFO); } Jelse { sprintf(msg[0], "%s%s", "In Function: ", pname); sprintf(msg[1], "ES", "Internal Error: List not printed because it does not exist!"); report_message(msg, MSG_ERROR); } return (n_printed); 7/rm.library.c Version 10-18-2020 #include #include #include #include #include "rm_library.h" #include "name_list.n" void report_message(char msg[MAX_MSG_NUM] [MAX_MSG_LNG), // Message butter enum msg_kind_type msg_kind ) // Message kind, i.e. kind of message: INFO, WARNING, or ERROR. { static char pname[] = "report_message"; // sub-program name. register int i; static char info_prefix[] = "::> MSG: "; static char warn_prefix[] = "**> WRN: char err_prefix[] = ">>> ERR: "; char end_prefix[] "E=> END "; static char indent[] static static printf(NL); // Print a blank line to separate the message from previous output. // Switch on "msg_kind" to determine which message prefix to output! switch (msg_kind) { case MSG_INFO: printf(info_prefix); break; // is part of the "Switch Syntax". case MSG_WARNING: printf(warn_prefix); // A "Switch" statement is the ONLY place where a "break" is allowed because it break; case MSG_ERROR: printf(err-prefix); break; case MSG_END: printf(end_prefix); break; default: // Always check for an "un-handled" msg_kind! printf(">>>>>>: INTERNAL Error in function: %s ", pname ); printf(">>>>>>: Invalid msg_kind [xd] ", msg_kind); break; msg[e][MAX_MSG_LNG -1) = (NUL; // Null last position of message, in case message is longer than butter, or printf("%s ", msg(e)); // Always print first message! for (int j=0; j 0) #define scE(S1, s2) (strcmp((51), (S2)) >= ) // Comparison of up to a maxinun of "n" characters of given strings. #define snEQ(81, 82, n) (!strncmp((1),(52), (n))) #define snNE(51, 52, n) ( strncmp((51), (52), (n)) #define snLT(51,52,n) ( strncmp((51), (52), (n)) 0) #define snGE(S1, S2, n) ( strncmp((51), (52), (n)) > 0) // Is a string EMPTY, BLANK, etc. ? #define sisempty(s) ((*) == NUL) #define SISNOTempty(s) (!(SISempty((s)))) #define SISblank(s) #define SISNOTblank (S) (strspn((s), (BLK)) == strlen((s))) (!(SISblank((s)))) #define sIszero(s) (strspn((s), "O") == strlen((s))) #define sHasValue(s) #define sHasNoValue(s) ((SISNOTempty((s))) && (SISNOTblank((s)))) (!(sHasValue((s)))) // ===== GLOBAL STATEMENT FUNCTION DEFINITIONS #define F_MIN(V1, V2) (((v1) (V2))? (v1):(V2)) #define ZF_MIN(V1, V2) (F_MAXCO, (F_MIN((v1), (v2))))) #define ZF (V) (F_MAXCO, (v))) #define F_NOT(V) (((v) == TRUE)? FALSE:TRUE) #define F_ABS(V) (((V) >= 0 )? (V):(-(v))) // Return the less of v1 and v2 // Return the greater of v1 and v2 // Like F_MIN, but lower bounds the result at ZERO // Lower bounds the value "V" at ZERO. // Logical Negation. // Absolute value ======= //===== GLOBAL CONSTANTS ========: #define MAX_MSG_NUM 10 #define MAX_MSG_LNG 81 // Number of message lines. // Length of a message string: Max of 132 chars +1 for terminating null byte. //===== PSEUDO-TYPES DEFINITIONS typedef unsigned bool; // Define "bool" to hold boolean values TRUE or FALSE //===== VARIABLES and STRUCTURE DEFINITIONS char msg[MAX_MSG_NUM] [MAX_MSG_LNG]; // Message buffer. Can hold MAX_MSG_NUM messages, each MAX_MSG_LNG chars long. enum msg_kind_type{MSG_INFO, MSG_WARNING, MSG_ERROR, MSG_END}; // MESSAGE type or kind of message. // Information. // Warning. // Error. // Program end. //===== SUBPROGRAM PROTOTYPES ======= // Report Message routine to output all of the generated various types of // output messages. Messages are output in a "standardized" fashion/format. void report_message(char msg[MAX_MSG_NUM] [MAX_MSG_LNG), // 20 Message Array/Buffer. enum msg_kind_type msg_kind ); // Type of message. #endif /* RM_LIBRARY_H_ */