home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_46.arc / CING46.ARC / FXREF.C < prev    next >
Text File  |  1988-05-11  |  5KB  |  213 lines

  1. /*
  2.      From the C'ing Clearly column in Micro Cornucopia Magazine Issue #46
  3.  
  4.      Program:  FXREF (File Cross-Reference)
  5.      
  6.      Version:  1.10
  7.      Date:     21-Sep-1988
  8.      
  9.      Language: ANSI C
  10.      
  11.      Reads a file from standard input, and sorts and organizes each
  12.      token (word) found using a binary tree, keeping track of the number
  13.      of occurences of each token and their location by line and column.
  14.      It then prints a report to stdout.
  15.      
  16.      Released into the public domain for "educational" purposes.
  17. */
  18.  
  19. #include "stdio.h"
  20. #include "string.h"
  21. #include "ctype.h"
  22. #include "stdlib.h"
  23.  
  24. /* type definitions */
  25. typedef unsigned short line_no;
  26.  
  27. typedef struct loc_s
  28.      {
  29.      line_no line;
  30.      struct loc_s * next;
  31.      }
  32.      location;
  33.  
  34. typedef struct tok_s
  35.      {
  36.      struct tok_s * less, * more;
  37.      char * text;
  38.      struct loc_s *loc, *last;
  39.      }
  40.      token;
  41.  
  42. token * root;
  43.  
  44. char * err_msg[] = {
  45.                   "token table root",
  46.                   "token text",
  47.                   "location references",
  48.                   "token record"
  49.                   };
  50.  
  51. /* function prototypes */
  52. int main(void);
  53. void parse_tokens(char *, line_no);
  54. void add_tree(char *, line_no);
  55. token * find_tree(char *);
  56. void show_tree(token *);
  57. void error(short);
  58.  
  59. int main()
  60.      {
  61.      char buf[256];
  62.      line_no line=0;
  63.  
  64.      if (NULL == (root = ( token *)malloc(sizeof( token))))
  65.           error(0);
  66.  
  67.      root->less = NULL;
  68.      root->more = NULL;
  69.      root->text = NULL;
  70.      root->loc  = NULL;
  71.  
  72.      while (NULL != (fgets(buf,256,stdin)))
  73.           {
  74.           ++line;
  75.           printf("%5u: %s",line,buf);
  76.           parse_tokens(buf,line);
  77.           }
  78.           
  79.      printf("\x0C\n");
  80.  
  81.      show_tree(root);
  82.  
  83.      return 0;
  84.      }
  85.      
  86. void parse_tokens(char * buf, line_no line)
  87.      {
  88.      char tok[256];
  89.      line_no pos;
  90.      
  91.      while (1)
  92.           {
  93.           while ((!isalpha(*buf)) && (*buf != 0))
  94.                ++buf;
  95.           if (*buf == 0)
  96.                return;
  97.           pos = 0;
  98.           while (isalpha(*buf))
  99.                tok[pos++] = *buf++;
  100.           tok[pos] = 0;
  101.           add_tree(tok,line);
  102.           }
  103.      }
  104.  
  105. void add_tree(char * tok, line_no line)
  106.      {
  107.      token *temp_tok, *new_tok;
  108.      location *temp_loc;
  109.      short comp;
  110.      
  111.      if (root->text == NULL)
  112.           {
  113.           if (NULL == (root->text = (char *)malloc((unsigned)strlen(tok)+1)))
  114.                error(1);
  115.           strcpy(root->text,tok);
  116.           if (NULL == (root->loc = ( location *)malloc(sizeof( location))))
  117.                error(2);
  118.           root->loc->line = line;
  119.           root->loc->next = NULL;
  120.           root->last = root->loc;
  121.           return;
  122.           }
  123.           
  124.      temp_tok = find_tree(tok);
  125.      
  126.      if (comp = strcmp(tok,temp_tok->text))
  127.           /* comp is true (non-zero) if they don't match */
  128.           {
  129.           if (NULL == (new_tok = ( token *)malloc(sizeof( token))))
  130.                error(3);
  131.           if (NULL == (new_tok->text = (char *)malloc((unsigned)strlen(tok)+1)))
  132.                error(1);
  133.           new_tok->less = NULL;
  134.           new_tok->more = NULL;
  135.           strcpy(new_tok->text,tok);
  136.           if (NULL == (new_tok->loc = ( location *)malloc(sizeof( location))))
  137.                error(2);
  138.           new_tok->loc->line = line;
  139.           new_tok->loc->next = NULL;
  140.           new_tok->last = new_tok->loc;
  141.           if (comp < 0)
  142.                temp_tok->less = new_tok;
  143.             else
  144.                temp_tok->more = new_tok;
  145.           }
  146.        else
  147.           /* if comp is false (0), the tokens match */
  148.           {
  149.           if (NULL == (temp_loc = ( location *)malloc(sizeof( location))))
  150.                error(2);
  151.           temp_loc->line = line;
  152.           temp_loc->next = NULL;
  153.           temp_tok->last->next = temp_loc;
  154.           temp_tok->last = temp_loc;
  155.           }
  156.      }
  157.  
  158.  token *find_tree(char * tok)
  159.      {
  160.      short comp;
  161.      token *node;
  162.      
  163.      node = root;
  164.      
  165.      while (1)
  166.           {
  167.           if (0 == (comp = strcmp(tok,node->text)))
  168.                return node;
  169.           if (comp < 0)
  170.                if (node->less == NULL)
  171.                     return node;
  172.                  else
  173.                     node = node->less;
  174.             else
  175.                if (node->more == NULL)
  176.                     return node;
  177.                  else
  178.                     node = node->more;
  179.           }
  180.      }
  181.  
  182. void show_tree(node)
  183.  token *node;
  184.      {
  185.      location *lloc;
  186.      short pos;
  187.      
  188.      if (NULL == node) return;
  189.      
  190.      show_tree(node->less);
  191.      printf("%-32s: ",node->text);
  192.      pos = -1;
  193.      lloc = node->loc;
  194.      while (lloc != NULL)
  195.           {
  196.           if (++pos == 7)
  197.                {
  198.                pos = 0;
  199.                printf("\n%32s: "," ");
  200.                }
  201.           printf("%5d ",lloc->line);
  202.           lloc = lloc->next;
  203.           }
  204.      printf("\n");
  205.      show_tree(node->more);
  206.      }
  207.  
  208. void error(short err_no)
  209.      {
  210.      printf("\nFXREF ERROR: Cannot allocate space for %s\n",err_msg[err_no]);
  211.      exit(err_no+1);
  212.      }
  213.