home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / flower.zip / updtlist.c < prev    next >
Text File  |  1997-06-23  |  13KB  |  402 lines

  1.  
  2. /* Copyright (c) 1996, 1997 Craig Schneiderwent */
  3. /*
  4. Program: flower
  5. File:    updtlist.c
  6. Author:  Craig Schneiderwent
  7.          74631.165@compuserve.com
  8. Date:    04-Dec-1996
  9.  
  10. These are helper functions for flower.  They
  11. update the linked lists which hold the
  12. function information for the files flower
  13. has been asked to analyze.
  14.  
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21. #include <limits.h>
  22. #include "mydebug.h"
  23. #include "structs.h"
  24. #include "mniplist.h"
  25. #include "memfunc.h"
  26. #include "updtlist.h"
  27.  
  28. void updateNotCalledFuncList( struct fileInfo *psFileInfo
  29.                             , struct isCalledByFuncInfo *psCalledByList )
  30. {
  31.     struct fileInfo           *nextFile = NULL;
  32.     struct funcInfo           *nextFunc = NULL;
  33.     struct isCalledByFuncInfo *isCalledBy = NULL;
  34.  
  35.     nextFile = startOfFileList( psFileInfo );
  36.     nextFunc = nextFile->funcListStart;
  37.  
  38.     while ( nextFile != NULL ) {
  39.         while ( nextFunc != NULL ) {
  40.             isCalledBy = funcInCalledByFuncList( nextFunc->funcNm
  41.                                                , psCalledByList );
  42.             if ( isCalledBy != NULL ) {
  43.                 nextFunc->isCalled = 1;
  44.             } /* endif */
  45.             nextFunc = nextFunc->next;
  46.         } /* endwhile */
  47.         nextFile = nextFile->next;
  48.         if ( nextFile != NULL ) {
  49.             nextFunc = nextFile->funcListStart;
  50.         } /* endif */
  51.     } /* endwhile */
  52.  
  53.     return;
  54. }
  55.  
  56. void updateAllCalledFuncFileNm( struct fileInfo *psFileInfo )
  57. {
  58.     struct fileInfo *nextFile = NULL;
  59.     struct funcInfo *nextFunc = NULL;
  60.     char            fileNm [ MAXFILENAMESIZE ];
  61.     char            funcNm [ MAXFUNCNAMESIZE ];
  62.  
  63.     nextFile = startOfFileList( psFileInfo );
  64.     nextFunc = nextFile->funcListStart;
  65.  
  66.     while ( nextFile != NULL ) {
  67.         strncpy( fileNm, nextFile->fileNm, MAXFILENAMESIZE );
  68.         while ( nextFunc != NULL ) {
  69.             strncpy( funcNm, nextFunc->funcNm, MAXFUNCNAMESIZE );
  70.             updateOneCalledFuncFileNm( nextFile, funcNm, fileNm );
  71.             nextFunc = nextFunc->next;
  72.         } /* endwhile */
  73.         nextFile = nextFile->next;
  74.         if ( nextFile != NULL ) {
  75.             nextFunc = nextFile->funcListStart;
  76.         } /* endif */
  77.     } /* endwhile */
  78.  
  79.     return;
  80. }
  81.  
  82. void updateOneCalledFuncFileNm( struct fileInfo *psFileInfo
  83.                               , char *funcNm
  84.                               , char *fileNm )
  85. {
  86.     struct fileInfo *nextFile = NULL;
  87.     struct funcInfo *nextFunc = NULL;
  88.     struct funcInfo *nextCalledFunc = NULL;
  89.     int             thisIsIt = 0;
  90.  
  91.     nextFile = startOfFileList( psFileInfo );
  92.  
  93.     while ( nextFile != NULL ) {
  94.         nextFunc = nextFile->funcListStart;
  95.         while ( nextFunc != NULL ) {
  96.             nextCalledFunc = nextFunc->calledFuncListStart;
  97.             while ( nextCalledFunc != NULL ) {
  98.                 thisIsIt = strncmp( nextCalledFunc->funcNm
  99.                                   , funcNm
  100.                                   , MAXFUNCNAMESIZE );
  101.                 if ( thisIsIt == 0 ) {
  102.                       strncpy( nextCalledFunc->fileNm
  103.                              , fileNm
  104.                              , MAXFILENAMESIZE );
  105.                 } /* endif */
  106.                 nextCalledFunc = nextCalledFunc->next;
  107.             } /* endwhile */
  108.             nextFunc = nextFunc->next;
  109.         } /* endwhile */
  110.         nextFile = nextFile->next;
  111.     } /* endwhile */
  112.  
  113.     return;
  114. }
  115.  
  116. void updateCalledFuncBase( struct fileInfo *pFileStart )
  117. {
  118.     struct fileInfo *nextFile = NULL;
  119.     struct funcInfo *nextFunc = NULL;
  120.     struct funcInfo *nextCalledFunc = NULL;
  121.  
  122.     nextFile = pFileStart;
  123.  
  124.     while ( nextFile != NULL ) {
  125.         nextFunc = nextFile->funcListStart;
  126.         while ( nextFunc != NULL ) {
  127.             nextCalledFunc = nextFunc->calledFuncListStart;
  128.             while ( nextCalledFunc != NULL ) {
  129.                 nextCalledFunc->calledFuncBase = 
  130.                        funcInFileList( nextCalledFunc->funcNm
  131.                                      , pFileStart );
  132.                 nextCalledFunc = nextCalledFunc->next;
  133.             } /* endwhile */
  134.             nextFunc = nextFunc->next;
  135.         } /* endwhile */
  136.         nextFile = nextFile->next;
  137.     } /* endwhile */
  138.  
  139.     return;
  140. }
  141.  
  142. void updateCircularReferences( struct fileInfo *pFileStart )
  143. {
  144.     #ifdef MY_DEBUG
  145.     char            *thisFuncNm = "updateCircularReferences\0";
  146.     char            debug_msg[ MY_DEBUG_MSG_SZ ];
  147.     #endif
  148.     struct fileInfo *nextFile = NULL;
  149.     struct funcInfo *nextFunc = NULL;
  150.     struct funcInfo *calledBase = NULL;
  151.     struct funcInfo *nextCalled = NULL;
  152.     struct funcInfo *nextSubCalled = NULL;
  153.     struct funcInfo *upTree = NULL;
  154.  
  155.     #ifdef MY_DEBUG
  156.     TRACE_ENTRY( thisFuncNm );
  157.     #endif
  158.  
  159.     nextFile = pFileStart;
  160.  
  161.     while ( nextFile != NULL ) {
  162.         #ifdef MY_DEBUG
  163.         sprintf( debug_msg, "\tFILE: %s", nextFile->fileNm );
  164.         TRACE_MSG( thisFuncNm, debug_msg );
  165.         #endif
  166.         nextFunc = nextFile->funcListStart;
  167.         while ( nextFunc != NULL ) {
  168.             #ifdef MY_DEBUG
  169.             sprintf( debug_msg, "\t\tFUNC: %s", nextFunc->funcNm );
  170.             TRACE_MSG( thisFuncNm, debug_msg );
  171.             #endif
  172.             nextCalled = nextFunc->calledFuncListStart;
  173.             while ( nextCalled != NULL ) {
  174.                 #ifdef MY_DEBUG
  175.                 sprintf( debug_msg, "\t\t\tCALLED FUNC: %s"
  176.                        , nextCalled->funcNm );
  177.                 TRACE_MSG( thisFuncNm, debug_msg );
  178.                 #endif
  179.                 calledBase = nextCalled->calledFuncBase;
  180.                 if ( calledBase == NULL ) {
  181.                     nextCalled = nextCalled->next;
  182.                     continue;
  183.                 } /* endif */
  184.                 nextSubCalled = calledBase->calledFuncListStart;
  185.                 doTheCircularReferenceUpdate( nextFunc
  186.                                             , nextCalled
  187.                                             , nextSubCalled
  188.                                             , upTree );
  189.                 freeUpTreeList( upTree );
  190.                 upTree = NULL;
  191.                 nextCalled = nextCalled->next;
  192.             } /* endwhile */
  193.             nextFunc = nextFunc->next;
  194.         } /* endwhile */
  195.         nextFile = nextFile->next;
  196.     } /* endwhile */
  197.  
  198.     #ifdef MY_DEBUG
  199.     TRACE_EXIT( thisFuncNm );
  200.     #endif
  201.  
  202.     return;
  203. }
  204.  
  205. void doTheCircularReferenceUpdate( struct funcInfo *baseFunc
  206.                                  , struct funcInfo *calledFunc
  207.                                  , struct funcInfo *subCalledFunc
  208.                                  , struct funcInfo *upTree )
  209. {
  210.     #ifdef MY_DEBUG
  211.     char            *thisFuncNm = "doTheCircularReferenceUpdate\0";
  212.     char            debug_msg[ MY_DEBUG_MSG_SZ ];
  213.     #endif
  214.     struct funcInfo *nextSubCalled = NULL;
  215.     struct funcInfo *subCalledBase = NULL;
  216.     struct funcInfo *nextUpTree = NULL;
  217.  
  218.     #ifdef MY_DEBUG
  219.     TRACE_ENTRY( thisFuncNm );
  220.     #endif
  221.  
  222.     if ( subCalledFunc == NULL || baseFunc == NULL || calledFunc == NULL ) {
  223.         #ifdef MY_DEBUG
  224.         if ( baseFunc == NULL ) {
  225.             sprintf( debug_msg, "             baseFunc = NULL" );
  226.         } else {
  227.             sprintf( debug_msg, "     baseFunc->funcNm = %s", baseFunc->funcNm );
  228.         } /* endif */
  229.         TRACE_MSG( thisFuncNm, debug_msg );
  230.         if ( calledFunc == NULL ) {
  231.             sprintf( debug_msg, "           calledFunc = NULL" );
  232.         } else {
  233.             sprintf( debug_msg, "   calledFunc->funcNm = %s", calledFunc->funcNm );
  234.         } /* endif */
  235.         TRACE_MSG( thisFuncNm, debug_msg );
  236.         if ( subCalledFunc == NULL ) {
  237.             sprintf( debug_msg, "        subCalledFunc = NULL" );
  238.         } else {
  239.             sprintf( debug_msg, "subCalledFunc->funcNm = %s", subCalledFunc->funcNm );
  240.         } /* endif */
  241.         TRACE_MSG( thisFuncNm, debug_msg );
  242.         TRACE_EXIT( thisFuncNm );
  243.         #endif
  244.         return;
  245.     } /* endif */
  246.  
  247.     #ifdef MY_DEBUG
  248.     sprintf( debug_msg, "     baseFunc->funcNm = %s [%p]", baseFunc->funcNm, baseFunc );
  249.     TRACE_MSG( thisFuncNm, debug_msg );
  250.     sprintf( debug_msg, "   calledFunc->funcNm = %s [%p]", calledFunc->funcNm, calledFunc );
  251.     TRACE_MSG( thisFuncNm, debug_msg );
  252.     #endif
  253.     nextSubCalled = subCalledFunc;
  254.  
  255.     while ( nextSubCalled != NULL ) {
  256.         subCalledBase = nextSubCalled->calledFuncBase;
  257.         #ifdef MY_DEBUG
  258.         sprintf( debug_msg, "nextSubCalled->funcNm = %s", nextSubCalled->funcNm );
  259.         TRACE_MSG( thisFuncNm, debug_msg );
  260.         sprintf( debug_msg, "subCalledBase = %p", subCalledBase );
  261.         TRACE_MSG( thisFuncNm, debug_msg );
  262.         #endif
  263.         if ( subCalledBase == baseFunc ) {
  264.             nextSubCalled->isCircularReference = 1;
  265.             #ifdef MY_DEBUG
  266.             sprintf( debug_msg, "%s subCalledBase == baseFunc [%s]"
  267.                    , subCalledBase->funcNm
  268.                    , baseFunc->funcNm );
  269.             TRACE_MSG( thisFuncNm, debug_msg );
  270.             #endif
  271.             nextSubCalled = nextSubCalled->next;
  272.             continue;
  273.         } /* endif */
  274.         if ( funcIsInUpTreeList( upTree, subCalledBase ) ) {
  275.             nextSubCalled->isCircularReference = 1;
  276.             #ifdef MY_DEBUG
  277.             sprintf( debug_msg, "%s is in upTree list"
  278.                    , nextSubCalled->funcNm );
  279.             TRACE_MSG( thisFuncNm, debug_msg );
  280.             #endif
  281.             nextSubCalled = nextSubCalled->next;
  282.             continue;
  283.         } /* endif */
  284.         if ( subCalledBase != NULL ) {
  285.             nextUpTree = funcInfoMalloc( );
  286.             if ( nextUpTree == NULL ) {
  287.                 return; /* punt, sorry */
  288.             } /* endif */
  289.             copyFuncInfo( subCalledBase, nextUpTree );
  290.             if ( upTree != NULL ) {
  291.                 upTree->next = nextUpTree;
  292.                 nextUpTree->prev = upTree;
  293.             } /* endif */
  294.             doTheCircularReferenceUpdate( baseFunc
  295.                                     , calledFunc
  296.                                     , subCalledBase->calledFuncListStart
  297.                                     , nextUpTree );
  298.             if ( nextUpTree != NULL ) {
  299.                 if ( nextUpTree->prev != NULL ) {
  300.                     nextUpTree->prev->next = NULL;
  301.                 } /* endif */
  302.                 free( nextUpTree );
  303.             } /* endif */
  304.             #ifdef MY_DEBUG
  305.             sprintf( debug_msg, "RESUMING:" );
  306.             TRACE_MSG( thisFuncNm, debug_msg );
  307.             sprintf( debug_msg, "     baseFunc->funcNm = %s [%p]"
  308.                    , baseFunc->funcNm, baseFunc );
  309.             TRACE_MSG( thisFuncNm, debug_msg );
  310.             sprintf( debug_msg, "   calledFunc->funcNm = %s [%p]"
  311.                    , calledFunc->funcNm, calledFunc );
  312.             TRACE_MSG( thisFuncNm, debug_msg );
  313.             #endif
  314.         } /* endif */
  315.         nextSubCalled = nextSubCalled->next;
  316.     } /* endwhile */
  317.  
  318.     #ifdef MY_DEBUG
  319.     sprintf( debug_msg, "RETURNING: subCalledFunc->funcNm = %s"
  320.            , subCalledFunc->funcNm );
  321.     TRACE_MSG( thisFuncNm, debug_msg );
  322.     TRACE_EXIT( thisFuncNm );
  323.     #endif
  324.  
  325.     return;
  326. }
  327.  
  328. int funcIsInUpTreeList( struct funcInfo *pTail
  329.                       , struct funcInfo *pFunc )
  330. {
  331.     #ifdef MY_DEBUG
  332.     char            *thisFuncNm = "funcIsInUpTreeList\0";
  333.     char            debug_msg[ MY_DEBUG_MSG_SZ ];
  334.     #endif
  335.     struct funcInfo *prevFunc = NULL;
  336.     int             rc = 0;
  337.  
  338.     #ifdef MY_DEBUG
  339.     TRACE_ENTRY( thisFuncNm );
  340.     #endif
  341.  
  342.     if ( pFunc == NULL ) {
  343.         #ifdef MY_DEBUG
  344.         sprintf( debug_msg, "pFunc == NULL" );
  345.         TRACE_MSG( thisFuncNm, debug_msg );
  346.         TRACE_EXIT( thisFuncNm );
  347.         #endif
  348.         return( rc );
  349.     } /* endif */
  350.  
  351.     if ( pTail == NULL ) {
  352.         #ifdef MY_DEBUG
  353.         sprintf( debug_msg, "pTail == NULL" );
  354.         TRACE_MSG( thisFuncNm, debug_msg );
  355.         TRACE_EXIT( thisFuncNm );
  356.         #endif
  357.         return( rc );
  358.     } /* endif */
  359.  
  360.     prevFunc = pTail->prev;
  361.  
  362.     while ( prevFunc != NULL ) {
  363.         #ifdef MY_DEBUG
  364.         sprintf( debug_msg, "strcmp( %s, %s)"
  365.                , pFunc->funcNm, prevFunc->funcNm );
  366.         TRACE_MSG( thisFuncNm, debug_msg );
  367.         #endif
  368.         rc = strcmp( pFunc->funcNm, prevFunc->funcNm );
  369.         if ( rc == 0 ) {
  370.             rc = 1;
  371.             break;
  372.         } /* endif */
  373.         prevFunc = prevFunc->prev;
  374.         rc = 0;
  375.     } /* endwhile */
  376.  
  377.     #ifdef MY_DEBUG
  378.     sprintf( debug_msg, "rc = %d", rc );
  379.     TRACE_MSG( thisFuncNm, debug_msg );
  380.     TRACE_EXIT( thisFuncNm );
  381.     #endif
  382.  
  383.     return( rc );
  384. }
  385.  
  386. void freeUpTreeList( struct funcInfo *pHead )
  387. {
  388.     struct funcInfo *thisFunc = NULL;
  389.     struct funcInfo *nextFunc = NULL;
  390.  
  391.     thisFunc = pHead;
  392.  
  393.     while ( thisFunc != NULL ) {
  394.         nextFunc = thisFunc->next;
  395.         free( thisFunc );
  396.         thisFunc = nextFunc;
  397.     } /* endwhile */
  398.  
  399.     return;
  400. }
  401.  
  402.