#include "argtable2.h"
#include <assert.h>

/* for memory leak debugging */
#ifdef DMALLOC
#include "dmalloc.h"
#endif


 /*
Here we verify that arg_freetable() works proprely, at least by nulling the argtable
array entries when finished.
*/
void test_freetable(void)
    {
    struct arg_lit  *list    = arg_lit0("lL",NULL,                      "list files");
    struct arg_lit  *recurse = arg_lit0("R",NULL,                       "recurse through subdirectories");
    struct arg_int  *repeat  = arg_int0("k","scalar",NULL,              "define scalar value k (default is 3)");
    struct arg_str  *defines = arg_strn("D","define","MACRO",0,20,      "macro definitions");
    struct arg_file *outfile = arg_file0("o",NULL,"<output>",           "output file (default is \"-\")");
    struct arg_lit  *verbose = arg_lit0("v","verbose,debug",            "verbose messages");
    struct arg_lit  *help    = arg_lit0(NULL,"help",                    "print this help and exit");
    struct arg_lit  *version = arg_lit0(NULL,"version",                 "print version information and exit");
    struct arg_file *infiles = arg_filen(NULL,NULL,NULL,1,20,           "input file(s)");
    struct arg_end  *end     = arg_end(20);
    void* argtable[]  = {list,recurse,repeat,defines,outfile,verbose,help,version,infiles,end};

    printf("testing arg_freetable()...\n");
    
    assert( argtable[0]!=NULL );
    assert( argtable[1]!=NULL );
    assert( argtable[2]!=NULL );
    assert( argtable[3]!=NULL );
    assert( argtable[4]!=NULL );
    assert( argtable[5]!=NULL );
    assert( argtable[6]!=NULL );
    assert( argtable[7]!=NULL );
    assert( argtable[8]!=NULL );
    assert( argtable[9]!=NULL );
    
    arg_freetable(argtable,sizeof(argtable)/sizeof(argtable[0]));
    
    assert( argtable[0]==NULL );
    assert( argtable[1]==NULL );
    assert( argtable[2]==NULL );
    assert( argtable[3]==NULL );
    assert( argtable[4]==NULL );
    assert( argtable[5]==NULL );
    assert( argtable[6]==NULL );
    assert( argtable[7]==NULL );
    assert( argtable[8]==NULL );
    assert( argtable[9]==NULL );
    
    printf("arg_freetable() OK\n");
    }

       
/*
Here we verify that arg_nullcheck() works properly at detecting NULL
entries in the argtable array.
In this test, we first build a normal argtable (taken from myprog.c)
and then a bunch of copycat argtable arrays that have NULL entries
dispersed within them. We test arg_nullcheck on each of these
argtable arrays to verify iots behaviour.
*/
void test_nullcheck(void)
    {
    struct arg_lit  *list    = arg_lit0("lL",NULL,                      "list files");
    struct arg_lit  *recurse = arg_lit0("R",NULL,                       "recurse through subdirectories");
    struct arg_int  *repeat  = arg_int0("k","scalar",NULL,              "define scalar value k (default is 3)");
    struct arg_str  *defines = arg_strn("D","define","MACRO",0,20,      "macro definitions");
    struct arg_file *outfile = arg_file0("o",NULL,"<output>",           "output file (default is \"-\")");
    struct arg_lit  *verbose = arg_lit0("v","verbose,debug",            "verbose messages");
    struct arg_lit  *help    = arg_lit0(NULL,"help",                    "print this help and exit");
    struct arg_lit  *version = arg_lit0(NULL,"version",                 "print version information and exit");
    struct arg_file *infiles = arg_filen(NULL,NULL,NULL,1,20,           "input file(s)");
    struct arg_end  *end     = arg_end(20);
    void* argtable[]  = {list,recurse,repeat,defines,outfile,verbose,help,version,infiles,end};
    void* argtable1[] = {list,recurse,repeat,defines,outfile,verbose,help,version,infiles,NULL};
    void* argtable2[] = {list,recurse,repeat,defines,outfile,verbose,help,version,NULL,   NULL};
    void* argtable3[] = {list,recurse,repeat,defines,outfile,verbose,help,NULL,   infiles,end};
    void* argtable4[] = {NULL,recurse,NULL,  NULL,   outfile,NULL,   help,version,infiles,NULL};

    printf("testing arg_nullcheck()...\n");
    assert(arg_nullcheck(argtable)  == 0);
    assert(arg_nullcheck(argtable1) == 1);
    assert(arg_nullcheck(argtable2) == 1);
    assert(arg_nullcheck(argtable3) == 1);
    assert(arg_nullcheck(argtable4) == 1);
    printf("arg_nullcheck() OK\n");
    
    arg_free(argtable);
    }


int main(int argc, char **argv)
    {
    test_freetable();
    test_nullcheck();
    
    /* close stdin and stdout to stop memcheck whining about their memory not being freed */
    fclose(stdin);
    fclose(stdout);
    
    return 0;
    }
