home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / text_cla / mem_test.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-12  |  15.7 KB  |  676 lines

  1. /***************************************************************************
  2.  
  3.    Test out the Tree, List, Stack, and Queue Routines in MEMLIB.LIB
  4.  
  5.  
  6. ****************************************************************************/
  7.  
  8. #include <stdio.h>
  9.  
  10. #if C_UNIX
  11. #include <signal.h>
  12. #endif
  13.  
  14.  
  15. #include  <memlib.h>
  16.  
  17. #ifdef C_ANSI
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <conio.h>
  21. #endif
  22.  
  23.  
  24. #define MAX_STR_LEN  20     /* maximum length of any string */
  25.  
  26. #define TEST_MEMBERS   (250)  /* number of test elements/cases */
  27. #define TEST_MAX_RUNS  1600
  28.  
  29.  
  30. #define M_LIST  1      /* Link list */
  31. #define M_TREE  2      /* Binary tree */
  32. #define M_STACK 3      /* stack (LIFO) */
  33. #define M_QUEUE 4      /* queue (FIFO) */
  34. #define M_HEAP  5      /* heap (priority queue) */
  35. #define M_VMM   6      /* virtual memory */
  36. #define M_TEST_ALL 7
  37.  
  38. /*
  39. **  The TEST_S structure is used as an independant data store to verify
  40. **  the accuracy of the data store being tested.  It is the 'control'
  41. **  for these experiments
  42. */
  43.  
  44. struct TEST_S{
  45.       CHAR   szName[MAX_STR_LEN];   /* alpha form of id  = number */
  46.       SHORT  sId;                   /* numeric of id */        
  47.       SHORT  sMode;                  /* sMode, TRUE = in data store,
  48.                                              FALSE = not in data store */
  49. };
  50.  
  51. typedef struct TEST_S TEST_T;
  52. typedef TEST_T  * TEST_P;
  53. typedef TEST_T  ** TEST_PP;
  54.  
  55.  
  56. #define NAME_SIZE 3+1
  57.  
  58.  
  59.  
  60.  
  61. /*
  62. **  (ANSI) Prototypes for local functions 
  63. */
  64.  
  65. #ifdef C_ANSI
  66. SHORT
  67. CompareData(PVOID pvData1,PVOID pvData2);
  68. #else
  69. SHORT
  70. CompareData();
  71. #endif
  72.  
  73.  
  74.  
  75. #if C_UNIX
  76.  
  77. void set_signal();
  78. void KILL();
  79.  
  80. #endif
  81.  
  82.  
  83. int fKILL = 0;  /* set if UNIX stop */;
  84.  
  85.  
  86. /*
  87. **  Init Menu Selections for user
  88. */
  89.  
  90. CHAR szTestName[M_TEST_ALL][40] = { "Link List",
  91.                           "Binary Tree",
  92.                           "Stack",
  93.                           "Queue",
  94.                           "Heap",
  95.                           "Virtual Memory",
  96.                           "All" };
  97.  
  98. #define BACK_SPACE 8
  99. #define SPIN_SIZE  8 
  100.  
  101. CHAR  cSpin[SPIN_SIZE];
  102.  
  103.     
  104. LONG lHandle[TEST_MEMBERS];
  105.  
  106.  
  107. int main()
  108. {   
  109.  
  110.    TNODE_P psTreeRoot = NULL;    /*  tree root member, initialize to NULL */
  111.    TNODE_P psWorkNode;           /*  working/scratch nodes */
  112.  
  113.    LLIST_P psListHead = NULL;    /*  head used for list, stack, queue */
  114.    LLIST_P psListTail = NULL;    /*  tail used for queue */
  115.    LLIST_P psWorkMember;         /*  working member */
  116.  
  117.    HEAP_P  psHeap;               /*  heap control structure */
  118.    HEAP_DATA_P  psHeapData;      /*  heap data structure */
  119.  
  120.    SHORT   sPriority;            /*  priority for heap */
  121.    
  122.    PVOID   pvData;               /*  work variable */
  123.  
  124.    TEST_P  pstTest;              /*  working test type */
  125.  
  126.  
  127.    SHORT   sSel;                 /*  current test case */
  128.  
  129.    LONG    lTestErrors[M_TEST_ALL-1];       /*  counter for errors if any occur */
  130.  
  131.    int     sSelection;           /*  menu selection, test types */
  132.    BOOL    fInData;              /*  if test in data structures */
  133.    int     iCnt;
  134.    ULONG   ulTestIterations[M_TEST_ALL-1];
  135.    ULONG   ulMasterIterations[M_TEST_ALL-1];
  136.   
  137.    SHORT   sTestMode;
  138.  
  139.    static  TEST_T   stTest[TEST_MEMBERS + 1];    /* test cases */
  140.  
  141.    SHORT   sSpinner = 0;
  142.  
  143.    CHAR    * pcData;
  144.  
  145.  
  146. #if C_UNIX
  147.    set_signal();
  148. #endif
  149.  
  150.  
  151.  
  152.    for(sSelection = 0; sSelection < (M_TEST_ALL -1); sSelection++)
  153.    {
  154.        lTestErrors[sSelection] = 0;
  155.        ulTestIterations[sSelection] = 0;
  156.        ulMasterIterations[sSelection] = 0;
  157.    }
  158.  
  159.  
  160.    cSpin[0] = '|';
  161.    cSpin[1] = '/';
  162.    cSpin[2] = '-';
  163.    cSpin[3] = '\\';
  164.    cSpin[4] = cSpin[0];
  165.    cSpin[5] = cSpin[1];
  166.    cSpin[6] = cSpin[2];
  167.    cSpin[7] = cSpin[3];
  168.  
  169.    printf("\n\n");
  170.    printf("MEM C Algorithms v 2.0 - Test program\n\n");
  171.    printf("1  Link List\n");
  172.    printf("2  Binary Tree\n");
  173.    printf("3  Stack\n");
  174.    printf("4  Queue\n");
  175.    printf("5  Heap\n");
  176.    printf("6  Virtual Memory\n");
  177.    printf("7  Test All\n\n");
  178.  
  179.    scanf("%d",&sSelection);
  180.  
  181.  
  182.    /*
  183.    **  Make sure selection in range, else exit
  184.    */
  185.  
  186.    if(
  187.       (sSelection >= M_LIST) &&
  188.       (sSelection <= M_TEST_ALL)
  189.      )
  190.    {
  191.       ;
  192.    }
  193.    else
  194.       exit(1);
  195.  
  196.  
  197.    sTestMode = sSelection;  /* remember */
  198.  
  199.  
  200.    /*
  201.    **  Load up the test control data
  202.    */
  203.  
  204.    for(sSel = 1; sSel < TEST_MEMBERS; sSel++)
  205.    {
  206.        sprintf(stTest[sSel].szName,"%d",sSel);
  207.        stTest[sSel].sId = sSel;
  208.        stTest[sSel].sMode = C_FALSE;
  209.    }
  210.  
  211.  
  212.    /*
  213.    **  Heap is only data type requiring initialization beyond just
  214.    **  setting pointer to NULL.   The heap is implemented in an array
  215.    **  so the array must be alloc'd before use.
  216.    */
  217.  
  218.    if(sSelection >= M_HEAP)
  219.       MemHepInit(&psHeap, TEST_MEMBERS);
  220.  
  221.    if(sSelection >= M_VMM)
  222.    {
  223.       VmmInit(64,"swap.dat");
  224.       for(iCnt = 0; iCnt < TEST_MEMBERS; iCnt++)
  225.          lHandle[iCnt] = -1;
  226.    }
  227.  
  228.    if(sSelection > (M_TEST_ALL -1))
  229.       sSelection = M_LIST;
  230.  
  231.  
  232.  
  233.    printf("Errors will be printed if they occur......");
  234.  
  235. #ifdef C_ANSI
  236.    printf("\nHit any key to end test\n");
  237. #else
  238.    printf("\nHit Ctrl-C to end test\n");
  239. #endif
  240.  
  241.  
  242.    printf("\nTesting %s   ", szTestName[sSelection - 1]);
  243.  
  244.    while(!fKILL)
  245.    {
  246.  
  247.        /*
  248.        **  Select test member at random
  249.        */
  250.  
  251.        sSel = rand() % TEST_MEMBERS;
  252.  
  253. #ifdef DEBUG
  254. #else
  255.        SpinCheck(&sSpinner);
  256. #endif
  257.  
  258. #ifdef DEBUG
  259.        printf("%d",sSel);
  260. #endif
  261.  
  262.        /*
  263.        **  Process if control says should not be in data store
  264.        */
  265.  
  266.  
  267.        /*
  268.        **  Check everything
  269.        */
  270.  
  271.        for(iCnt = 0; iCnt < TEST_MEMBERS; iCnt++)
  272.        {
  273.            switch(sSelection)
  274.            {
  275.               case M_LIST:
  276.               case M_STACK:
  277.               case M_QUEUE:
  278.  
  279.                  MemLstFindMember(psListHead,(PCHAR) stTest[iCnt].szName,CompareData,&psWorkMember);
  280.                  fInData = (psWorkMember != NULL);
  281.                  break;
  282.  
  283.               case M_TREE:
  284.  
  285.                  MemTreFindNode(psTreeRoot,(PVOID) stTest[iCnt].szName,CompareData,&psWorkNode);
  286.  
  287.                  fInData = (psWorkNode != NULL);
  288.                  break;
  289.  
  290.               case M_HEAP:
  291.  
  292.                  MemHepSearch(psHeap,(PVOID) stTest[iCnt].szName,CompareData,&psHeapData); 
  293.                  fInData = (psHeapData != NULL);
  294.                  break;
  295.  
  296.               case M_VMM:
  297.                  if(lHandle[iCnt] != -1)
  298.                  {
  299.                      VmmPrep(lHandle[iCnt],&pcData);
  300.                      if(strcmp(pcData, stTest[iCnt].szName) == 0)
  301.                         fInData = 1;
  302.                      else
  303.                         fInData = 0;
  304.                  }
  305.                  else
  306.                     fInData = 0;
  307.                  
  308.            }
  309.  
  310.  
  311.            if(fInData != stTest[iCnt].sMode)
  312.            {
  313.               if(stTest[iCnt].sMode)    
  314.                   printf("\nDid not find %d - should have been in %s\n", iCnt, szTestName[sSelection - 1]);
  315.               else
  316.                   printf("\nFound %d - should not have been in %s\n", iCnt, szTestName[sSelection - 1]);
  317.                      
  318.               lTestErrors[sSelection -1]++;
  319.               printf("Total errors = %d\n",lTestErrors[sSelection - 1]);
  320.            }
  321.        }
  322.  
  323.  
  324.  
  325.        
  326.  
  327.        if(stTest[sSel].sMode == C_FALSE) 
  328.        {
  329. #ifdef DEBUG
  330.            printf("+"); 
  331. #endif
  332.            /*
  333.            **  Add to data store 
  334.            */
  335.  
  336.            switch(sSelection)
  337.            {
  338.              case M_LIST:
  339.  
  340.                 MemLstAllocMember(&psWorkMember);
  341.                 if(psWorkMember != NULL)
  342.                 {
  343.                     psWorkMember -> pvData = (PVOID) &stTest[sSel];
  344.                 }
  345.                 else
  346.                    printf("\nno member allocated\n");
  347.                 
  348.                 MemLstInsertMember(psListHead,psWorkMember,CompareData,&psListHead);
  349.                 break;
  350.  
  351.              case M_STACK:
  352.  
  353.                 MemStkPush(&psListHead, (PVOID) &stTest[sSel]);
  354.                 break;
  355.  
  356.              case M_QUEUE:
  357.  
  358.                 MemQueEnqMember(&psListHead, &psListTail, (PVOID) &stTest[sSel]);
  359.                 break;
  360.  
  361.              case M_TREE:
  362.  
  363.                 MemTreAllocNode(&psWorkNode);
  364.                 if(psWorkNode != NULL)
  365.                 {
  366.                        psWorkNode -> pvData = (PVOID) &stTest[sSel];
  367.                 }
  368.                 else
  369.                    printf("\nno member allocated\n");
  370.            
  371.                 MemTreInsertNode(psTreeRoot,psWorkNode,CompareData,&psTreeRoot);
  372.                 /* printf("I=%d, ",sSel); */
  373.  
  374.                 break;
  375.  
  376.               case M_HEAP:
  377.  
  378.                  MemHepEnque(psHeap,sSel,(PVOID) &stTest[sSel]);
  379.                  break;
  380.  
  381.               case M_VMM:
  382.  
  383.                  VmmAlloc(1,NAME_SIZE, &lHandle[sSel]);
  384.                  VmmPrep(lHandle[sSel],&pcData);
  385.                  memcpy(pcData,stTest[sSel].szName,NAME_SIZE);
  386.                  break;
  387.  
  388.            }
  389.  
  390.            /*
  391.            **  Mark control as being in data store
  392.            */
  393.  
  394.            stTest[sSel].sMode = C_TRUE;
  395.  
  396.        }
  397.        else if(stTest[sSel].sMode == C_TRUE) 
  398.        {
  399.  
  400.            /*
  401.            **  Process if control says should be in data store
  402.            */
  403.  
  404. #ifdef DEBUG
  405.            printf("-"); 
  406. #endif
  407.            /*
  408.            **  Remove from data store
  409.            */
  410.  
  411.            /*
  412.            **  Usage of Stacks, Queues, and Heaps requires that
  413.            **  the member removed is not selectable.
  414.            **
  415.            **    For stacks, it is the item on top.
  416.            **    For queues, it is the oldest item.
  417.            **    For heaps, it is the item with the highest priority
  418.            **
  419.            **  Because of this, stack, queue, and heap item removals
  420.            **  also reset the control number (sSel) to that of the
  421.            **  item which was removed
  422.            */
  423.  
  424.  
  425.            switch(sSelection)
  426.            {
  427.               case M_LIST:
  428.  
  429.                 MemLstFindMember(psListHead,(PCHAR) stTest[sSel].szName,CompareData,&psWorkMember);
  430.                 MemLstDeleteMember(psListHead,psWorkMember,&psListHead);
  431.  
  432.                 break;
  433.  
  434.               case M_STACK:
  435.  
  436.                 MemStkPop(&psListHead, &pvData);
  437.                 pstTest = (TEST_P) pvData;
  438.                 sSel = pstTest -> sId;
  439.  
  440.                 break;
  441.  
  442.               case M_QUEUE:
  443.          
  444.                 MemQueDeqMember(&psListHead, &psListTail, &pvData);
  445.                 pstTest = (TEST_P) pvData;
  446.                 sSel = pstTest -> sId;
  447.  
  448.                 break;
  449.  
  450.               case M_TREE:          
  451.  
  452.                 MemTreDeleteNode(psTreeRoot,(PVOID) stTest[sSel].szName,CompareData,&psTreeRoot);
  453.  
  454.                 break;
  455.  
  456.               case M_HEAP:
  457.  
  458.                 MemHepDeque(psHeap,&sPriority,&pvData);
  459.                 pstTest = (TEST_P) pvData;
  460.                 sSel = pstTest -> sId;
  461.                 break;
  462.  
  463.               case M_VMM:
  464.  
  465.                 VmmPrep(lHandle[sSel],&pcData);
  466.                 VmmFree(lHandle[sSel]);
  467.                 lHandle[sSel] = -1;
  468.                 break;
  469.  
  470.            }
  471. #ifdef DEBUG
  472.            printf("D ",sSel); 
  473. #endif                
  474.            stTest[sSel].sMode = C_FALSE;
  475.  
  476.        }                   
  477.  
  478. /*
  479. **  You will note that this program uses 'goto'.   After years of
  480. **  heartburn with goto's, there has developed in the programming
  481. **  community a phobia of using goto at all.   Even the SLC shows this.
  482. **  There have even been languages created which do not have a goto
  483. **  (Modula-2).   I feel there is a case for using goto only under
  484. **  1 condition,  there is only one label to 'goto' and the goto
  485. **  is always towards the bottom of the function or to exit
  486. **  the function.
  487. **
  488. **  Without using any goto's, you end up with extra levels of 'if'
  489. **  statements and code that is harder to read and has higher
  490. **  essential and cyclomatic complexities (cf. Software Metrics, McCabe).
  491. **
  492. **  If you are in a module and have encountered a condition that means
  493. **  there is nothing else you can do there, GET OUT!.  Don't keep
  494. **  setting return codes and checking return codes as you fall-through
  495. **  the module, just get out.  There should be only one entry point and
  496. **  exit point from the module so you should NOT have multiple return 
  497. **  statements.  You should goto the common exit label and return
  498. **  from there.  The goto itself should normally be masked with a 
  499. **  define (cf C_LEAVE() in MEMDEF.H).
  500. **
  501. */
  502.  
  503. LOOP_BOT:
  504.  
  505.      ulTestIterations[sSelection - 1]++;
  506.      ulMasterIterations[sSelection - 1]++;
  507.  
  508.  
  509.      if(sTestMode == M_TEST_ALL)
  510.      {
  511.         if(ulTestIterations[sSelection - 1] >= TEST_MAX_RUNS)
  512.         {
  513.            sSpinner = 0;
  514.      
  515.            switch(sSelection)
  516.            {
  517.  
  518. #ifdef DEBUG
  519.        printf("\nVACATE\n");
  520. #endif
  521.  
  522.               case M_LIST:
  523.  
  524.               case M_QUEUE:
  525.  
  526.                  MemLstVacateList(&psListHead, C_FALSE);
  527.                  break;
  528.  
  529.               case M_TREE:
  530.  
  531.                  MemTreVacateTree(&psTreeRoot, C_FALSE);
  532.                  break;
  533.  
  534.               case M_STACK:
  535.  
  536.                  MemStkVacateStack(&psListHead, C_FALSE);
  537.                  break;
  538.  
  539.               case M_HEAP:
  540.  
  541.                  MemHepVacateHeap(&psHeap, C_FALSE);
  542.                  MemHepInit(&psHeap, TEST_MEMBERS);
  543.                  break;
  544.  
  545.               case M_VMM:
  546.                  break;
  547.            }
  548.  
  549.            ulTestIterations[sSelection - 1] = 0;
  550.  
  551.            for(sSel = 0; sSel < TEST_MEMBERS; sSel++)
  552.            {
  553.               stTest[sSel].sMode = C_FALSE;
  554.            }
  555.  
  556.            sSelection++;
  557.            if(sSelection > (M_TEST_ALL-1))
  558.               sSelection = M_LIST;
  559.  
  560.            printf("\nTesting %s ", szTestName[sSelection - 1]);
  561.         }
  562.      }
  563.  
  564.  
  565. #ifdef C_ANSI
  566.      if(kbhit())
  567.         fKILL = 1;
  568. #endif
  569.  
  570.    }
  571.  
  572.    /* getch();  */ /* get the character at the keyboard */
  573.  
  574.    if(sTestMode >= M_HEAP)
  575.       MemHepVacateHeap(&psHeap,C_FALSE);
  576.  
  577.    if(sTestMode >= M_VMM)
  578.       VmmTerm();
  579.  
  580.    printf("\n");
  581.  
  582.    if(sTestMode <= (M_TEST_ALL -1))
  583.    {
  584.          printf("\n%s Test ", szTestName[sSelection-1]);
  585.          printf(" = %u iterations ", ulMasterIterations[sSelection-1]);
  586.          printf("with %d errors.\n",lTestErrors[sSelection-1]);
  587.    }
  588.    else
  589.    {
  590.       for(sSelection = 0; sSelection < (M_TEST_ALL-1); sSelection++)
  591.       {
  592.          printf("\n%s Test ", szTestName[sSelection]);
  593.          printf(" = %u iterations ", ulMasterIterations[sSelection]);
  594.          printf("with %d errors.\n",lTestErrors[sSelection]);
  595.       }
  596.    }
  597.  
  598. }
  599.  
  600.  
  601.  
  602. #ifdef C_ANSI
  603. SHORT
  604. CompareData(PVOID pvData1,PVOID pvData2)
  605. #else
  606. SHORT
  607. CompareData(pvData1,pvData2)
  608. PVOID pvData1;
  609. PVOID pvData2;
  610. #endif
  611. {
  612.    return(strcmp((PCHAR) pvData1,(PCHAR) pvData2));
  613. }
  614.  
  615.  
  616. #if C_UNIX
  617.  
  618. void set_signal()
  619. {
  620.    signal(SIGHUP, KILL);
  621.    signal(SIGINT, KILL);       /* this one works for cntl c */
  622.    signal(SIGQUIT, KILL);
  623.    signal(SIGILL, KILL);
  624.    signal(SIGTRAP, KILL);
  625.    signal(SIGABRT, KILL);
  626.    signal(SIGEMT, KILL);
  627.    signal(SIGFPE, KILL);
  628.    signal(SIGKILL, KILL);
  629.    signal(SIGBUS, KILL);
  630.    signal(SIGSYS, KILL);
  631.    signal(SIGPIPE, KILL);
  632.    signal(SIGALRM, KILL);
  633.    signal(SIGTERM, KILL);
  634. }
  635.  
  636. void KILL()
  637. {
  638.    fKILL  = 1;
  639. }
  640.  
  641.  
  642. #endif
  643.  
  644.  
  645.  
  646.  
  647. int
  648. SpinCheck(psSpinner)
  649. PSHORT psSpinner;
  650. {
  651.    static SHORT sCnt = 0;
  652.  
  653.    (*psSpinner)++;
  654.  
  655.    if((*psSpinner) > (SPIN_SIZE * 100))
  656.       *psSpinner = 0;
  657.  
  658.    if((*psSpinner) % 50)
  659.    {
  660.       sCnt++;
  661.       if(sCnt >= SPIN_SIZE)
  662.          sCnt = 0;
  663.  
  664.       printf("%c",BACK_SPACE);
  665.       printf("%c",cSpin[sCnt]);
  666.      
  667. #if C_UNIX
  668.       fflush(stdout);
  669. #endif
  670.  
  671.    }
  672. }
  673.  
  674.            
  675.            
  676.