Listing 2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "c_calls.h"

void build_graph(LIST *fcn_list, const char *filename)

/*
Build a graph which shows the calling relationships of all fcns in
a C program by parsing the program's assembly language file.
*/

{
FILE      *input_file;
LINE      line;
TOKENS    toks;
char      *tp;
NAME      caller_name, called_name;
int       i;
LIST      caller_ptr = NULL, called_ptr;

if ((input_file = fopen(filename, "r")) == NULL)
    error("cannot open input file");

while (!feof(input_file))
    {
    fgets(line, sizeof(line), input_file);
    line[strlen(line) - 1] = '\0';  /* Remove \n from end of line. */
    
    memset(toks, 0, sizeof(toks));
    
    /* Extract the fields from the current line. */
    tp = strtok(line, "\t ");  /* Token separator is a tab or space. */
    
    for (i = 0; (i < MAX_TOKENS) && (tp != NULL); i++)
        {
        strcpy(toks[i], tp);
        tp = strtok(NULL, "\t ");  /* Get next token. */
        }
    
    i-; /* i now points to last token on current line.  */
    
    /* If current line is the start of a fcn... */
    if (stricmp(toks[1], "proc") == O)
        {
        strcpy(caller_name, &toks[O] [1]);
        
        /* Insert fcn into fcn list.  */
        insert_cell (fcn_list, caller_name);
        
        /* Make the new fcn the calling fcn.  */
        caller_ptr = find_cell(*fcn_list, caller_name);
        
        }
    
    /* If current line is a user-defined fcn call...  */
    if ((stricmp(toks[0], "call") == 0) &&
       (toks[i][strlen(toks[i]) - 1] != '@') && (toks[i][1] != '_'))
        {
        strcpy (called_name, &toks  [1] );
        
        /* Insert called fcn into the fcn list.  */
        insert_cell (fcn_list, called_name);
        
        /* Record that the calling fcn is calling this fcn.  */
        insert_cell(&caller_ptr->calls, called_name);
        
        /* Record that this fcn is called by the calling fcn.  */
        called_ptr = find_cell (*fcn_list, called_name);
        insert_cell (&called_ptr->called_from, caller_name);
        }
    }

if (fclose(input_file) != 0)
    error("cannot close input file");
}
/* End of File */