| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
xref.cpp
/*
** C/C++ cross-reference utility
**
** Usage: xref filename.ext { filename.ext } [ -filelist.ext ]
**
** By: Stephen R. Schmitt
*/
#include "stdafx.h" // generated by Visual C++ ver.6
#include <ctype.h>
#include <fstream.h>
#include <stdlib.h>
#include "symtab.h"
#include "scanner.h"
/*
** declarations for xref class
*/
class xref : public symtab, public scanner
{
public:
int file_count;
xref(){ file_count = 0; }
void files( char * );
private:
void get_file( char * );
void get_list_files( char * );
void build_table( char * );
void assemble( char *, int );
long file_length( ifstream * );
};
/*---------------------------------------------------------------------------*
** "put_message" displays a message on usage of this program
**
** returns: nothing
*/
void put_message( char *buf )
{
cout << endl;
cout << "C/C++ cross reference utility.\n\n";
cout << "Usage: xref [-]filename.ext { [-]filename.ext }\n\n";
cout << " - indicates file is a list of files\n";
cout << " output is file named \"xref.out\"\n" << endl;
cout << "file: ";
cin >> buf;
cout << endl;
}
/*---------------------------------------------------------------------------*
** "main" program entry point
**
** returns: nothing
*/
void main( int argc, // number of files + 1
char *argv[] ) // file names
{
int n; // counter
char buffer[_MAX_PATH]; // for file names
xref x; // cross refererence
if( argc < 2 ) // user dialog needed
{
put_message( buffer );
x.files( buffer ); // the truth is out there
}
else // get command line input
{
n = 1;
while( n < argc )
{
strcpy( buffer, argv[n++] );
x.files( buffer ); // trust no one
}
}
if( x.file_count ) // at least one file was read
x.output();
else
cout << "No files were processed " << endl;
}
/*
** definitions for xref class
*/
#define MAXLINE 256
/*---------------------------------------------------------------------------*
** "files" processes command line arguments.
**
** returns: nothing
*/
void xref::files( char *buffer ) // file name
{
ifstream is; // input stream
long length; // length of file to read
char *text; // of list file
if( buffer[0] == '-' ) // is a list of file names
{
is.open( &buffer[1], ios::binary | ios::nocreate );
if( ! is )
{
cout << "Can't open " << &buffer[1] << endl;
return;
}
length = file_length( &is ); // allocate memory for file
text = new char[length + 1];
if( ! text )
{
cout << "Out of memory" << endl;
is.close();
return;
}
is.read( text, length ); // read entire list of files
text[length] = 0;
is.close();
get_list_files( text ); // process files in list
delete text;
}
else // process a single file
get_file( buffer );
}
/*---------------------------------------------------------------------------*
** "get_list_files" processes files from a list.
**
** returns: nothing
*/
void xref::get_list_files( char *list ) // names of file to process
{
long i, j; // counters
char filename[_MAX_PATH]; // listed file
i = 0;
while( 1 ) // extract file names
{
while( isspace( list[i] ) )
i++;
if( ! list[i] ) // end of list file
break;
j = 0;
while( !isspace( list[i] ) ) // copy file name to buffer
filename[j++] = list[i++];
filename[j] = 0;
get_file( filename ); // process a file
}
}
/*---------------------------------------------------------------------------*
** "get_file" opens a file and starts the word counting process.
**
** returns: nothing
*/
void xref::get_file( char *srce_name ) // name of file to process
{
ifstream is; // input stream
long length; // length of file to read
char *text; // of file
is.open( srce_name, ios::binary | ios::nocreate );
if( ! is )
{
cout << "Can't open " << srce_name << endl;
return;
}
length = file_length( &is ); // allocate memory for file
text = new char[length + 1];
if( ! text )
{
cout << "Out of memory" << endl;
is.close();
return;
}
is.read( text, length ); // read entire file
text[length] = 0;
is.close();
start( text ); // do the processing
build_table( srce_name );
cout << "Processed " << srce_name << endl;
file_count++;
delete text; // free memory
}
/*---------------------------------------------------------------------------*
** "file_length" determines the length of a file in bytes
**
** returns: the length
*/
long xref::file_length( ifstream *in ) // the file
{
long beg, end; // file pointer indices
in->seekg( 0, ios::end ); // get ending value
end = in->tellg();
in->seekg( 0 ); // get beginning value
beg = in->tellg();
return end - beg; // result
}
/*---------------------------------------------------------------------------*
** "build_table" builds the cross reference table
**
** returns: nothing
*/
void xref::build_table( char *filename ) // of next file
{
node *idp; // identifiers
node *fp; // file names
char word[MAXLINE];
get_token();
while( code != END_OF_FILE )
{
if( code == ID_TOKEN )
{
assemble( word, MAXLINE );
// add word to table
idp = search( word, Symbol_root );
if( !idp )
idp = enter( word, &Symbol_root );
if( !idp )
return;
// add file name
fp = search( filename, idp->files );
if( !fp )
fp = enter( filename, &idp->files );
if( !fp )
return;
// add line number
add_instance( on_line, &fp->lines );
}
else
get_token();
}
}
/*---------------------------------------------------------------------------*
** "assemble" joins identifiers of structure elements into
** a single identifier.
**
** returns: nothing
*/
void xref::assemble( char *buffer, // for table entry
int n ) // length of buffer
{
memset( buffer, '\0', n );
while( code == ID_TOKEN )
{
strcat( buffer, lexeme );
get_token();
if( ( code == ARROW ) || ( code == PERIOD ) )
{
strcat( buffer, lexeme );
get_token();
}
else
break;
}
}
| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
Copyright © 2004, Stephen R. Schmitt