Below is the working List abstraction design,List is a generic abstraction holding any type.Below is the code directory structure. Currently symbol table(ST) and file api fileIO is using List abstraction../Code$.:fileIO  list  ST tinyTale type.h frequencyCounter.c frequencyCounter.exe./fileIO:file.h  fileReading.c./list:arrayImpl.c   config.c virtualImplLayer.c linkedListImpl.c  list.h listHandler.h  listInterface.h  ./ST:implWithArray.c  ST.hBelow is the relevant code(for improvement),list.h#ifndef LIST_H /* Header guard */#define LIST_H#includetype.h  typedef struct List List; typedef int (*compareTo)(const void *, const void *); typedef bool (*isLess)(const void *, const void *); typedef bool (*isEqual)(const void *, const void *);#endiflistHandler.h/***********listHandler.h ***********/#ifndef LISTHANDLER_H#define LISTHANDLER_H#includelist/list.htypedef struct {         bool(*canHandle)(char*);        List*(*createList)(void);         void(*freeList)(List*);         void(*swim)(List*, int, isLess);         void(*sink)(List*, int, isLess);        void*(*listDeleteMaxElement)(List*, isLess);        void*(*sortedListDeleteMaxElement)(List*);          int(*listGetSize)(List*);  const void*(*listGetItem)(List*, const int);        List*(*sortedListInsertItem)(List*, void*, compareTo);         void(*listInsertItem)(List*, void*);        void*(*listDeleteItem)(List*, int);        void*(*listDeleteLastItem)(List*);        void*(*listDeleteFirstItem)(List*);         int(*linearSearch)(const void*, List*, size_t, compareTo);        void*(*binarySearch)(const void*, List*, size_t, compareTo);         void(*insertionSort)(List*, size_t, isLess);         void(*mergeSort)(List*, size_t, isLess);         void(*swap)(List*, int, int);}ListHandler;/*  config.c lookup below 2 global symbols created in impl handlers,   before linking time, so extern keyword*/extern ListHandler arrayImplHandler;extern ListHandler linkedListImplHandler;/*  viml.c lookup below global symbol created in config.c,   before linking time, so extern keyword*/extern ListHandler *listHandlers[];/* Prototypes for definitions in viml.c - start ********/        List* vCreateList(char *);         void vFreeList(List*, char *);         void vSwim(List*, int, isLess, char *);         void vSink(List*, int, isLess, char *);        void* vListDeleteMaxElement(List*, isLess, char *);        void* vSortedListDeleteMaxElement(List*, char *);          int vListGetSize(List*, char *);  const void* vListGetItem(List*, const int, char *);        List* vSortedListInsertItem(List*, void*, compareTo, char *);         void vListInsertItem(List*, void*, char *);        void* vListDeleteItem(List*, int, char *);        void* vListDeleteLastItem(List*, char *);        void* vListDeleteFirstItem(List*, char *);          int vLinearSearch(const void*, List*, size_t, compareTo, char *);        void* vBinarySearch(const void*, List*, size_t, compareTo, char *);         void vInsertionSort(List*, size_t, isLess, char *);         void vMergeSort(List*, size_t, isLess, char *);         void vSwap(List*, int, int, char *);/*****End ***********************************************/#endiflistInterface.h#includelist/listHandler.h#ifndef LISTINTERFACE_H#define LISTINTERFACE_H/*********** User Interface - start *****************/#define createList()                   vCreateList(argv[1])#define freeList(a)                    vFreeList(a, argv[1])#define swim(a, b, c)                  vSwim(a, b, c, argv[1])#define sink(a, b, c)                  vSink(a, b, c, argv[1])#define deleteMax(a, b)                vListDeleteMaxElement(a, b, argv[1])#define sortDeleteMax(a)               vSortedListDeleteMaxElement(a, argv[1])#define getSize(a)                     vListGetSize(a, argv[1])#define getItem(a, b)                  vListGetItem(a, b, argv[1])#define sortInsertItem(a, b, c)        vSortedListInsertItem(a, argv[1])#define insertItem(a, b)               vListInsertItem(a, b, argv[1])#define deleteItem(a, b)               vListDeleteItem(a, b, argv[1])#define deleteLastItem(a)              vListDeleteLastItem(a, argv[1])#define deleteFirstItem(a)             vListDeleteFirstItem(a, argv[1])#define lSearch(a, b, c, d)            vLinearSearch(a, b, c, d, argv[1])#define bSearch(a, b ,c, d)            vBinarySearch(a, b, c, d, argv[1])#define callInsertionSort(a, b, c)     vInsertionSort(a, b, c, argv[1])#define callMergeSort(a, b, c)         vMergeSort(a, b, c, argv[1])#define swap(a, b, c)                  vSwap(a, b, c, argv[1])/*********** User Interface - end *****************/#endifwhere, listInterface.h is an interface for a user of List abstraction.All api wth prefix(v) are defined in virtualImplLayer.c.But,1)listInterface.h is not a readable code for user, because it does not possess List typedef which is actually available in list.h and indirectly included via listHandler.h.2)listInterface.h is not easy to use because user(say fileReading.c) need to pass argv argument to List public api. Public api is given in listInterface.h. User has to run its application passing argv[1] as, $ ./userapp.exe ARRAY or$ ./userapp.exe LINKEDLISTQuestion:Can listInterface.h get more readable & easy to use?
Refactoring List abstraction - C
design;c;coding style;refactoring;interfaces
There are several ways to make listInterface.h easier to use. One of the easiest ways is to combine list.h and listInterface.h into one file and to move the declarations of the vXXX functions there as well.As a second refactoring, you should remove the implementation selector (ARRAY or LINKEDLIST string) from all interface functions. If you want to have run-time selection of the implementation, then you should either have a single function to select the implementation to use for the whole program, or you should specify it only on the createList function as an explicit argument.That way, users of the list abstraction can't accidentally create a linked list and then call the array implementation on it.Having the argument explicitly, and not implicitly as argv[1], makes it clear that there is a choice here and gives the possibility to base the choice on something else than the first program argument.