home *** CD-ROM | disk | FTP | other *** search
- /*
- From the C'ing Clearly column in Micro Cornucopia Magazine Issue #46
-
- Program: FXREF (File Cross-Reference)
-
- Version: 1.10
- Date: 21-Sep-1988
-
- Language: ANSI C
-
- Reads a file from standard input, and sorts and organizes each
- token (word) found using a binary tree, keeping track of the number
- of occurences of each token and their location by line and column.
- It then prints a report to stdout.
-
- Released into the public domain for "educational" purposes.
- */
-
- #include "stdio.h"
- #include "string.h"
- #include "ctype.h"
- #include "stdlib.h"
-
- /* type definitions */
- typedef unsigned short line_no;
-
- typedef struct loc_s
- {
- line_no line;
- struct loc_s * next;
- }
- location;
-
- typedef struct tok_s
- {
- struct tok_s * less, * more;
- char * text;
- struct loc_s *loc, *last;
- }
- token;
-
- token * root;
-
- char * err_msg[] = {
- "token table root",
- "token text",
- "location references",
- "token record"
- };
-
- /* function prototypes */
- int main(void);
- void parse_tokens(char *, line_no);
- void add_tree(char *, line_no);
- token * find_tree(char *);
- void show_tree(token *);
- void error(short);
-
- int main()
- {
- char buf[256];
- line_no line=0;
-
- if (NULL == (root = ( token *)malloc(sizeof( token))))
- error(0);
-
- root->less = NULL;
- root->more = NULL;
- root->text = NULL;
- root->loc = NULL;
-
- while (NULL != (fgets(buf,256,stdin)))
- {
- ++line;
- printf("%5u: %s",line,buf);
- parse_tokens(buf,line);
- }
-
- printf("\x0C\n");
-
- show_tree(root);
-
- return 0;
- }
-
- void parse_tokens(char * buf, line_no line)
- {
- char tok[256];
- line_no pos;
-
- while (1)
- {
- while ((!isalpha(*buf)) && (*buf != 0))
- ++buf;
- if (*buf == 0)
- return;
- pos = 0;
- while (isalpha(*buf))
- tok[pos++] = *buf++;
- tok[pos] = 0;
- add_tree(tok,line);
- }
- }
-
- void add_tree(char * tok, line_no line)
- {
- token *temp_tok, *new_tok;
- location *temp_loc;
- short comp;
-
- if (root->text == NULL)
- {
- if (NULL == (root->text = (char *)malloc((unsigned)strlen(tok)+1)))
- error(1);
- strcpy(root->text,tok);
- if (NULL == (root->loc = ( location *)malloc(sizeof( location))))
- error(2);
- root->loc->line = line;
- root->loc->next = NULL;
- root->last = root->loc;
- return;
- }
-
- temp_tok = find_tree(tok);
-
- if (comp = strcmp(tok,temp_tok->text))
- /* comp is true (non-zero) if they don't match */
- {
- if (NULL == (new_tok = ( token *)malloc(sizeof( token))))
- error(3);
- if (NULL == (new_tok->text = (char *)malloc((unsigned)strlen(tok)+1)))
- error(1);
- new_tok->less = NULL;
- new_tok->more = NULL;
- strcpy(new_tok->text,tok);
- if (NULL == (new_tok->loc = ( location *)malloc(sizeof( location))))
- error(2);
- new_tok->loc->line = line;
- new_tok->loc->next = NULL;
- new_tok->last = new_tok->loc;
- if (comp < 0)
- temp_tok->less = new_tok;
- else
- temp_tok->more = new_tok;
- }
- else
- /* if comp is false (0), the tokens match */
- {
- if (NULL == (temp_loc = ( location *)malloc(sizeof( location))))
- error(2);
- temp_loc->line = line;
- temp_loc->next = NULL;
- temp_tok->last->next = temp_loc;
- temp_tok->last = temp_loc;
- }
- }
-
- token *find_tree(char * tok)
- {
- short comp;
- token *node;
-
- node = root;
-
- while (1)
- {
- if (0 == (comp = strcmp(tok,node->text)))
- return node;
- if (comp < 0)
- if (node->less == NULL)
- return node;
- else
- node = node->less;
- else
- if (node->more == NULL)
- return node;
- else
- node = node->more;
- }
- }
-
- void show_tree(node)
- token *node;
- {
- location *lloc;
- short pos;
-
- if (NULL == node) return;
-
- show_tree(node->less);
- printf("%-32s: ",node->text);
- pos = -1;
- lloc = node->loc;
- while (lloc != NULL)
- {
- if (++pos == 7)
- {
- pos = 0;
- printf("\n%32s: "," ");
- }
- printf("%5d ",lloc->line);
- lloc = lloc->next;
- }
- printf("\n");
- show_tree(node->more);
- }
-
- void error(short err_no)
- {
- printf("\nFXREF ERROR: Cannot allocate space for %s\n",err_msg[err_no]);
- exit(err_no+1);
- }