*

advertisement
/***********************************************************************
*
diff Output
April 20, 1997
This is the output of the current "diff" UNIX utility
on the test file sets.
* File
........ Date
Description
*
*
***********************************************************************/
3d2
extern int optind;
<
5c4,5
int aflg=O;
<
int x = 0;
int aflg=2;
>
>
7d6
<
9,10d7
<
<
lla9
int nread;
int *fd;
int badfiles=O;
int *fd;
>
13cll,12
<
char buffer [BUFSIZ]
>
>
char buffer [BUFSIZ+l] ;
int badfiles=l;
15c14
while((c=getopt(argc+l,argv, "ai")) !=EOF)
<
while((c=getopt(argc+2,argv,"ai")) !=EOF)
23,24c22,23
<
case '?':
(void)fprintf(stderr,"usage: cmd [-al-i]
>
>
case'!' :
(void*)fprintf(stderr,"usage: cmd [-al-i]
<
filel
filel
32a32
fd=(int)malloc((argc-optind+l)*sizeof(int));
>
34,35c34
<
<
fd=(int*)malloc((argc-optind+l)*sizeof(int));
for (n=l;optind<argc;optind++)
>
for(n=l;optind<argc;optind--)
37d35
{
<
39,40c37
perror(argv[optind]) ;
<
}
<
perror (argv [optind] );
>
43c40
n++;
<
n--·,
.:46
<
perror(": Could not write to file\n");
>
(void)perror(": Could not write to file\n")
54c51
i
[
<
return badfilesi
>
return ++badfilesi
~c58
int argc;char *argv[]
>
i
int argci char *argv[] i
63c60
<
register int ii
>
register int i=Oi
69d65
<
usage()
i
usage()
i
70a67
>
74c71
<
sprintf(buf,"%s ",argv[i])
i
>
sprintf(buf,"%d ",argv[i])
i
89c86
<
char ch,ch_buf[MAXLAME]
>
char ch,ch_buf[MAXLAME+l]
i
i
93d89
<
{
95,98c91,97
<
<
<
>
>
>
>
>
>
>
if (ch==EOF)
return(-l) i
strncat(ch buf,&ch,l)
if (ch==' \n/)
if (ch==EOF)
return(-l) i
strncat(ch buf,&ch,l)
if(ch=='\n/ )
i
i
{
lamerize(ch buf) i
for (i=Oii<strlen(ch_buf) ii++)
100,104c99,100
lamerize(ch buf) i
for(i=Oii<strlen(ch buf) ii++)
<
<
{
<
<
-
ch_buf[i]=NULLi
<
}
>
printf ("garbage\n")
ch_buf[i]=NULLi
>
i
125c121
<
if(buf[j]=='y'&&buf[j+l]=='o'&&buf[j+2]=='u')
>
if(buf[j]=='y'&&buf[j+l]=='o')
131d126
<
{
137c132
else
else
>
139d133
<
143d136
}
j+=2;
<
144a138
>
j+=2;
J,.A3c143
else if(buf[j]=='l'&&(rand()%3==l))
>
154d147
<
else if(buf[j]=='l'&&(rand()%3==l))
{
157d149
<
}
163c155
<
out[count++]=toupper(buf[j]) ;
>
out [count--] =toupper(buf[j] );
169c161
<
return(l) ;
>
return(O) ;
180d171
<
printf("***
Starting LAME with no arguments will put it in continuous
printf("***
Starting LAME with no arguments will put it in continuous
181a173
>
191a184
>
printf("\n") ;
193d185
<
.-
return(l) ;
Th..: r>::mainckr of tht pJckd \.:,m~i,;t" cd'11k' SOll1\.:.:: (:<)(k for the: program and the
testing drivers used to run Ih.: prugy:l11l. rh:.'~aus<;; Ill.: a~..:ompanying tools that cnabk the
program tf' ,york fully an:: ]Jet y:t ayaiLlbk. the: program cannot mn indcpcnd~ntly of test
dri\·crs. \rirh some hand manirulation of the input files hmvc\cr. the tool "a~ abk to he
set to work analyzmg the tiles.
1***************************************************** ******************
*
* File
--t... Developer
Date
* Description
*
header.h
James Pollard
April 20, 1997
Definitions of global constants and flags used
throughout project.
*
****************************************************** *****************1
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
DF
DF
DF
DF
DF
DF
DF DF
DF
DF
DF
DF
DF
DF
DF
DF
FALSE
TRUE
YES
NO
UNKNOWN
STATIC
EXTERN
IDENTICAL
LESSTHAN
GREATERTHAN
SCOPE
FILE
NAME
ALL
SUCCESS
FAILURE
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1* Statement types *1
-~fine
_2fine
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
1.
--
DF
DF
DF
DF
DF
DF
DF
DF
DF
DF
DF
DF
DF
DF
FOR
WHILE
DO
IF
ELSE
SWITCH
CASE
BEGIN
END
PARAMS
POUND
DECL
ASSIGN
FUNCT
16
17
18
19
20
21
22
23
24
25
26
27
28
29
II
II
II
II
II
II
II
II
II
II
II
II
II
II
for(
while (
repeat
if (
)
else
switch(
case ... :
f
first line of function until {
#statement# second # is artificial
keyword
until
name [+=-\*] or ++name or --name
anything not matching other types until { or
1***************************************************** ******************
*
* File
-*' Developer
Date
* Description
*
*
Differ.cc
James Pollard
April 20, 1997
Main module of Differ system. Manages activities of
all subordinate classes.
****************************************************** *****************1
#include <stdio.h>
#include <fstream.h>
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include " .. /header.h"
#include " .. /List.h"
#include " .. /SortedList.h"
#include " .. /StateList.h"
#include " .. /FunctList.h"
#include " .. /Node.h"
#include " .. /StateNode.h"
#include " .. /FunctNode.h"
int main(int argc, char** argv)
{
II
int Cj
II flag indicating option encountered in search
extern int optindj
II index into arguments set to first file argument
extern int opterrj
II turns off error message
extern char* optargj II argument to option found
int of lag
0;
II location of 0 (separator) flag
int nflag = 0;
II location of n (separator) flag
int sflag = OJ
II location of s (separator) flag
char* oldindexfile
NULLj
char* newindexfile = NULLj
char** oldfilesj
char** newfiles;
FILE* userfile;
FILE* indexfile;
char buffer [BUFSIZ]
int readlength;
opterr = 0;
Ilparse the command line for -s -n -0 flags
while ((c = getopt (argc, argv, "o:n:s")) != EOF)
switch (c) {
case '0':
oldindexfile = optarg;
of lag = optind-1;
break;
case 'n':
newindexfile = optarg;
n-Fl::>rr
=
r'I,...,!-inr'l_1.
[NewSourceFiles -s OldSourceFiles]]
exi t (1);
[SourceFiles]
II
\n",argv);
}
,'ead contents of user's directory file into differ new tablefile
if (newindexfile != NULL) {
cout « "New Index File is " « newindexfile « endl;
indexfile = fopen("newfiles.tab" r "wt");
indexfile = fopen("commandlinenewfiles.tab"r"wt");
userfile = fopen(newindexfiler"r");
while (!feof(userfile)) {
readlength = fread(&buffer,lrBUFSIZ,userfile);
fwrite(&buffer,l,readlengthrindexfile) ;
}
fclose(indexfile) ;
fclose(userfile) ;
Ilmove
II
Ilmove
II
else if (sflag == 0) {
all names of files except oldindexfile into differ new tablefile
newfiles = new char*[argc-optind-l];
indexfile = fopen("newfiles.tab"r"wt");
indexfile = fopen("commandlinenewfiles.tab"r"wt");
for (int x = optind; x < argc; x++) {
newfiles[x-optind] = argv[x];
cout « "New File is II « newfiles[x-optind] « endl;
fwrite (argv [x] rstrlen(argv[x]) ,sizeof(char) rindexfile);
fwrite("\n",lrsizeof(char) ,indexfile);
}
fclose(indexfile) ;
}
else {
all names of files before -s option into differ new tablefile
newfiles = new char*[sflag-optind] i
indexfile = fopen("newfiles.tab"r"wt");
indexfile = fopen("commandlinenewfiles.tab"r"wt");
for (int x = optind; x < sflag+l; x++) {
newfiles[x-optind] = argv[x];
cout « "New File is " « newfiles[x-optind] « endl;
fwrite(argv[x] ,sizeof(char) rstrlen(argv[x]) ,indexfile);
fwrite("\n",sizeof(char) r1rindexfile);
}
fclose(indexfile) ;
}
Ilread
II
-
contents of user's directory file into differ old tablefile
if (oldindexfile != NULL) {
cout « "Old Index File is " « oldindexfile « endl;
indexfile = fopen("oldfiles.tab"r"wt");
indexfile = fopen("commandlineoldfiles.tab"r"wt");
userfile = fopen(oldindexfiler"r");
while (! feof (userfile)) {
readlength = fread(&buffer,l,BUFSIZ,userfile);
fwrite(&buffer,lrreadlength,indexfile) ;
}
fclose(indexfile) ;
fclose(userfile) ;
}
Ilmove
else if (sflag == 0) {
all names of files except newindexfile into differ old tablefile
oldfiles = new char*[argc-optind-l];
indexfile = fopen("oldfiles.tab","wt");
indexfile = fopen("commandlineoldfiles.tab","wt");
for (int x = optind; x < argc; x++) {
oldfiles[x-optind] = argv[x];
cout « "Old File is " « oldfiles[x-optind] « endl;
fwrite(argv[x] ,sizeof(char) ,strlen(argv[x]) ,indexfile);
fwrite("\n",sizeof(char) ,l,indexfile);
II
-
}
fclose(indexfile) ;
}
Ilmove
II
else {
all names of files after -s flag into differ old tablefile
oldfiles = new char*[argc-sflag-2];
indexfile = fopen("oldfiles.tab","wt");
indexfile = fopen("commandlineoldfiles.tab","wt");
for (int x = sflag+l; x < argc; x++) {
oldfiles[x-sflag-l] = argv[x];
cout « "Old File is II « oldfiles[x-sflag-l] « endl;
fwrite(argv[x] ,strlen(argv[x]) ,sizeof(char) ,indexfile);
fwrite("\n",l,sizeof(char) ,indexfile);
}
fclose(indexfile) ;
}
~
cout « endl « endl;
call to parsing utility would go here and then file would be read below *1
FunctList* oldfilelist = new FunctList;
FunctList* newfilelist = new FunctList;
StateList* oldlist = new StateList();
StateList* newlist = new StateList();
StateList* deletedlist
new StateList();
StateList* addedlist = new StateList();
StateNode* node;
FunctNode* oldnode;
FunctNode* newnode;
int result;
long length;
char* newbuffer;
char* oldbuffer;
int nummatches;
int* matches;
int* repeats;
int oldextern;
int newextern;
long newlength;
long oldlength;
newfilelist->FeedList("newfiles.tab") ;
oldfilelist->FeedList("oldfiles.tab") ;
newlength
newfilelist->MaxLength();
newbuffer = new char [newlength] ;
-
oldlength = oldfilelist->MaxLength() i
oldbuffer = new char [oldlength] ;
oldfilelist->Reset() i
for (int x = 0; x < oldfilelist->GetLength() i x++) {
oldfilelist->SetLocation(x) i
oldnode = (FunctNode*) oldfilelist->Peekltem() i
if (oldnode->IsMatched() == NULL) {
if (oldfilelist->MatchAll(oldnode, newfilelist)
DF_FAILURE) {
delete []newbufferi
delete []oldbufferi
delete newlist;
delete oldlisti
delete addedlisti
delete deletedlisti
delete newfilelisti
delete oldfilelist;
return(l) i
}
}
}
.-
oldfilelist->Process(oldbuffer,newbuffer,oldlength,newlength,
oldlist,newlist,deletedlist,addedlist)
oldfilelist->Reset() i
cout « endl « endl «
IIFunction Summaryll « endli
cout «
1I0ld Funct Name /Old Location
/II
?1I « endl;
«
IINew
Funct Name +New
Location
cout «
11 _______________
____________________
+11 Diff
«
11 _______________ + ____________________ + ______ " « endli
oldfilelist->Print() i
newfilelist->Reset() i
for (int X=Oi x < newfilelist->GetLength(); x++) {
newfilelist->SetLocation(x) i
newnode = (FunctNode*)newfilelist->Peekltem()
if (newnode->IsMatched() == NULL) {
newnode->PrintNew() i
}
}
delete
delete
delete
delete
delete
delete
delete
delete
-
[]newbufferi
[]oldbuffer;
newlisti
oldlist;
addedlisti
deletedlisti
newfilelisti
oldfilelisti
i
i
/***********************************************************************
*
* File
Developer
Date
* Description
A
*
*
*
*
Node.cc
James Pollard
April 20, 1997
Coded methods for class Node.
This class holds the
information for one item in a list.
This class
is not intended to be be used directly in the
Differ project.
***********************************************************************/
#include "Node.h"
/***********************************************************************
*
* Function
* Description
*
*
Constructor
Sets pointers to NULL and other attributes to generic
values
***********************************************************************/
Node: : Node ()
{
Start = -1;
End = -1;
Next = NULL;
Previous = NULL;
--**********************************************************************
* Function
* Description
Destructor
Sets pointers to NULL
*
***********************************************************************/
Node: : -Node ( )
{
Next = NULL;
Previous = NULL;
/***********************************************************************
*
* Function
* Description
*
*
Compare
Compares only values held in node, intended to be
overridden
***********************************************************************/
int Node: : Compare (Node* item)
{
//Return whether comparison of Node lengths
if ((End - Start + 1) -- (item->End - item->Start + 1))
return DF IDENTICAL;
else if ((End - Start + 1) < (item->End - item->Start + 1))
return DF_LESSTHAN;
else
return DF_GREATERTHAN;
-
/***********************************************************************
*
~
Function
Description
*
*
Set
Initializes fields of node because nodes will not be
destroyed and recreated to save memory
***********************************************************************/
int Node: :Set(long start
{
l
long end)
Start = start;
End = end;
/***********************************************************************
*
* Function
* Description
*
*
Lead
Makes this node lead target node ln the list
First--->this--->target
************************************************************************/
Node* Node::Lead(Node* target)
{
Node* oldNext = Next;
Next = target;
return (oldNext) ;
/***********************************************************************
*
* Function
* Description
*
*
Follow
Makes this node follow target node in the list
First--->target--->this
*
***********************************************************************/
Node* Node: :Follow(Node* target)
{
Node* oldPrev = Previous;
Previous = target;
return (oldPrev) ;
}
/***********************************************************************
*
* Function
* Description
GetNext
Returns pointer to next item
*
***********************************************************************/
"f\T('lde* Node:: GetNext ()
return (Next) ;
}
/***********************************************************************
*
GetPrevious
Returns pointer to previous item
* Function
* Description
:*********************************************************************/
Node* Node: :GetPrevious()
{
return (Previous) ;
}
/***********************************************************************
*
GetLength
Returns length of current item's highlighted area
* Function
* Description
*
***********************************************************************/
long Node: :GetLength{)
{
return{End-Start +1)
/***********************************************************************
*
Print
Prints values of current item's highlight indices,
intended to be overridden
* Function
* Description
*
*
******************************************~*********** ****************/
int Node: : Print ()
{
cout «
}
-
Start «
"
" «
End;
/***********************************************************************
*
* File
~ Developer
Date
* Description
*
*
FunctNode.cc
James Pollard
April 20, 1997
Coded methods for class FunctNode.
This child class
of Node holds all the information for and body of
one function in a file set.
*
***********************************************************************/
II FunctNode . h 11
# inc 1 ude
/***********************************************************************
*
* Function
* Description
Constructor
Initializes all class attributes to given values.
*
***********************************************************************/
FunctNode: : FunctNode (char* name, char* file, int scope,
long start, long end, char* tablefile)
{
Set (start,end)
Name = name;
File = file;
Scope = scope;
TableFile = tablefile;
Changed = DF_FALSEi
Match = NULL;
/***********************************************************************
*
* Function
* Description
Destructor
deletes all strings and sets pointer to null
*
***********************************************************************/
FunctNode: :-FunctNode()
{
if (Name) delete Namei
if (File) delete File;
//TableFile is global, so don't remove
Match = NULL;
}
/***********************************************************************
*
* Function
* Description
Compare
Compares name of this function to target function
*
***********************************************************************/
int FunctNode: : Compare (FunctNode* target)
J-
return CompareAll(target);
/***********************************************************************
*
* Function
* Description
CompareName
Compares name of this function to target function
*
~**********************************************************************/
int FunctNode: :CompareName(FunctNode* target)
{
int compareval = strcmp (Name , target->Name)
if (compareval == 0)
return DF IDENTICAL;
else if (compareval < 0)
return DF_LESSTHAN;
else
return DF_GREATERTHAN;
}
/***********************************************************************
*
* Function
* Description
*
*
CompareFile
Compares name of file this function was found in to
name of file target function was found in.
***********************************************************************/
int FunctNode: :CompareFile(FunctNode* target)
{
//Find the location of the last occurence of '/' in the filenames
char* charLoc = rindex(File
char* tarcharLoc = rindex(target->File,'/'};
~if there was no '/' use the start of File, otherwise use after '/'
if (charLoc == NULL)
charLoc = File;
else
charLoc++;
if (tarcharLoc == NULL)
tarcharLoc = target->File;
else
tarcharLoc++;
//return results of string comparison on filenames
int compareval = strcmp(charLoc, tarcharLoc}
if (compareval == O)
return DF IDENTICAL;
else if (compareval < O)
return DF_LESSTHAN;
else
return DF_GREATERTHAN;
l
l
/
'
);
}
/***********************************************************************
*
* Function
* Description
*
CompareAll
Compares this function/s name, filename , and scope to
those of the target function.
*
~**********************************************************************/
int FunctNode: :CompareAll(FunctNode* target}
{
int result;
//compare all fields with Name,File,Scope as sort key order
if ((result = CompareName(target)) != DF_IDENTICAL)
return result;
-
if ((result = CompareFile(target))
return result;
!= DF_IDENTICAL)
if (Scope == target->Scope)
return DF IDENTICAL;
else if (Scope ==-DF_EXTERN)
return DF_LESSTHANi
else
return DF GREATERTHAN;
/***********************************************************************
*
* Function
* Description
*
*
*
Matchup
Sets match attribute of this function to point to
target function, and sets match attribute of
target function to point to this function.
***********************************************************************/
int FunctNode: : Matchup (FunctNode* target)
{
if (target ! = NULL)
//point two objects at each other
{
Match = target;
target->Match = this;
}
else {
//clearing Match pointer
if (Match != NULL)
//clear previously matched node
Match->Match = NULL;
Match = NULLi
return DF_SUCCESS;
}
/***********************************************************************
*
* Function
* Description
IsExtern
Returns state of Scope attribute
*
***********************************************************************/
int FunctNode: :IsExtern()
{
if (Scope == DF_EXTERN)
return DF_TRUE;
else
return DF_FALSE;
}
/***********************************************************************
:
.. Function
* Description
*
IsMatched
Returns state of Match pointer attribute
***********************************************************************/
FunctNode* FunctNode: : IsMatched()
{
return Match;
/***********************************************************************
*
* Function
* Description
*
*
MarkChanged
Alters Changed attribute to indicate this function
was changed between file sets.
***********************************************************************/
int FunctNode: :MarkChanged()
{
Changed = DF_TRUE;
return DF_SUCCESS;
}
/***********************************************************************
*
* Function
* Description
IsChanged
Returns state of Changed attribute
*
***********************************************************************/
int FunctNode: : IsChanged()
L
return Changed;
/***********************************************************************
*
* Function
* Description
ReadBody
Reads body of function into buffer
*
***********************************************************************/
int FunctNode: : ReadBody (char* buffer)
{
FILE* file;
int endlist;
long error;
int numread;
//open tablefile
file = fopen(TableFile,l1r l1 )
if (file == NULL) {
cout «
I1Could not open
return DF_FAILURE;
11
«
TableFile «
11
to compare\nl1;
}
//seek to the start of the function body in the tablefile
-if ((error = fseek(file,Start,SEEK_SET)) == -1) {
cout «
I1Could not seek to 11 « Start «
11
in
« TableFile « endl;
return DF_FAILURE;
11
//read the function body from the tablefile
if ((numread = fread(buffer,sizeof(char) ,GetLength() ,file)) <
GetLength()) {
cout « nCould only read n « numread « n characters, not n
« GetLength() «
characters from n « TableFile « endl;
return DF_FAILURE;
-
II
}
fclose(file)
}
/***********************************************************************
*
* Function
* Description
*
Print
Prints line of table for this function
***********************************************************************/
int FunctNode: :Print()
{
//print node's info
cout « setiosflags(ios: :left) « setw (15) « Name « n In
« setw (20) « File;
//if matched, print matches info
if (Match != NULL) {
cout « nln « setw (15) « Match->Name « n In « setw (20)
« Match->File;
cout « nln;
//if changed, print * in last column
if (Changed == DF_TRUE)
cout « n *n;
,-
}
}
/***********************************************************************
*
* Function
* Description
PrintNew
Prints line of table for new function
*
***********************************************************************/
int FunctNode: :PrintNew()
{
//print empty columns where old filename and function name would go
cout « n
I
In;
cout « setiosflags(ios: :left) « setw (15) « Name « n In
setw (20) « File;
«
/***********************************************************************
*
* Function
* Description
*
PrintName
Prints this node's name
~**********************************************************************/
int FunctNode: :PrintName()
{
cout «
}
Name;
/***********************************************************************
*
~
Function
Description
PrintFile
Prints this node's File
*
***********************************************************************/
int FunctNode: :PrintFile()
{
cout « Filej
}
/***********************************************************************
*
* Function
* Description
Printltem
Prints the information for a changed line
*
***********************************************************************/
int FunctNode: :Printltem(char* action, char* file, char* name, StateNode* item)
{
-x
breakjll
//print one line of differ output, i.e. lI>file.c
cout « action « setw (20) « setiosflags(ios: :left) « file «
«
setw (15) « setiosflags (ios: : left) « name « I I
11 j
item->Print() j
cout « endlj
}
--**********************************************************************
* Function
* Description
*
*
*
*
Process
Does the comparison of bodies of this function and
target function.
Debugging code was left in this
function, because this will be the most likely
function to require modification for maintenance
and enhancement.
*
***********************************************************************/
int FunctNode: :Process(char* oldbuffer, char* newbuffer,
StateList* oldlist, StateList* newlist,
StateList* oldsupplist, StateList* newsupplist)
{
#ifdef DEBUG
cout «
IIReached FunctNode: :Process\nllj
#endif
int endlistj
int olddistancej
int newdistancej
int backdistancej
int errorj
StateNode* newnodej
StateNode* oldnodej
StateNode* blanknode
new StateNode j
Changed = DF_FALSEj
//read the bodies of the two functions
if (ReadBody(oldbuffer)
DF_FAILURE)
{
11
11
delete blanknodei
return DF_FAILUREi
-
}
:def DEBUG
cout « "Read first body\n"
#endif
i
if (Match->ReadBody(newbuffer)
delete blanknodei
return DF_FAILUREi
DF_FAILURE)
{
}
#ifdef DEBUG
cout «
"Read second body\n"i
#endif
Ilload function bodies into statement lists
oldlist->FeedList(oldbuffer,GetLength()) ;
#ifdef DEBUG
cout « "Fed first list\n"i
#endif
newlist->FeedList(newbuffer,Match->GetLength()) i
#ifdef DEBUG
cout « "Fed second list\n"i
#endif
-
oldlist->Reset() ;
newlist->Reset() ;
#ifdef DEBUG
cout «
"Both lists reset\n"i
oldlist->Print() i
newlist->Print() ;
cout « "Both lists Printed\n";
#endif
endlist = 0;
while (endlist == 0) {
oldnode
(StateNode*)oldlist->PeekItem() i
newnode = (StateNode*)newlist->PeekItem();
#ifdef DEBUG
cout «
"Check l\n Comparing ... ";
newnode->Print() ;
cout «
" . . . to ... ";
oldnode->Print() i
cout « endli
#endif
II if both items match each other
if (oldnode->Compare(newnode)
#lfdef DEBUG
cout «
"Check 2 (items match)\n"i
#endif
-- DF_IDENTICAL)
{
II if old function body has completed, set marker
if ((oldlist->Advance() == DF_FAILURE)
II
(blanknode->Compare((StateNode*)oldlist->PeekItem()) -) {
DF IDENTICAL)
Edef DEBUG
cout «
"Check 3 (items match and end of oldfile)\n";
#endif
endlist = 1;
-
II if new function body has completed, set marker
if ((newlist->Advance() == DF FAILURE)
(blanknode->Compare((StateNode*)oldlist->PeekItem())
-- DF_IDENTICAL)
) {
#ifdef DEBUG
cout « "Check 4 (items match and end of newfile)\n";
#endif
endlist+=2;
}
else {
II Else the new items did not match each other
#ifdef DEBUG
cout «
"Check 5 (items do not match)\n";
#endif
Changed = DF TRUE;
olddistance
oldlist->FindDistance(newnode);
newdistance = newlist->FindDistance(oldnode);
new item was not found in old list
if (olddistance == -1) {
#ifdef DEBUG
cout « "Check 6 (new item not found in old list)\n";
#endif
oldsupplist->EndSet() ;
if ((backdistance = oldsupplist->FindBackDistance(newnode))
#ifdef DEBUG
cout « "Check 7 (new item not found in deleted list)\n";
#endif
#ifdef DEBUGSUPPLISTS
cout « "Deleted List is : \n" ;oldsupplist->Print (); cout « endl;
#endif
II print item, this item was a added to the file
PrintItem("+",Match->File,Match->Name,newnode) ;
newlist->Advance() ;
}
else {
#ifdef DEBUG
cout « "Check 8 (new item found in deleted list) ... tranferring ";
newnode->Print() icout « endli
#endif
#ifdef DEBUGSUPPLISTS
cout « "Deleted List is : \n";oldsupplist->Print(); cout « endl;
ie.ndif
skip this item, print message, and remove match from deleted list,
II
because match was found
PrintItem(">",File,Name,newnode) ;
oldsupplist->SetLocation(
oldsupplist->GetLocation()-backdistance) ;
-1)
{
-
newnode = (StateNode*) oldsupplist->Getltem() ;
newnode->Set(-l,-l,DF UNKNOWN, NULL) ;
oldlist->AddLast(newnode) ;
newlist->Advance() ;
}
}
II
old item was not found in new list
if (newdistance == -1) {
#ifdef DEBUG
cout « "Check 9 (old item not found in new list)\n";
#endif
newsupplist->EndSet() ;
#ifdef DEBUG
cout « Illength of added list is " « newsupplist->GetLength() « endl;
#endif
if ((backdistance
newsupplist->FindBackDistance(oldnode)) -- -1)
#ifdef DEBUG
cout « "Check 10 (old item not found in added list)\n Added list is \n";
newsupplist->Print() ;
#endif
#ifdef DEBUGSUPPLISTS
cout « "Added List is
\n";newsupplist->Print(); cout « endl;
#endif
II print item, this item was a removed from the file
Printltem("-",File,Name,oldnode) ;
oldlist->Advance() ;
}
else {
"'-'-fdef DEBUG
J.t « "Check 11 (old item found in added list) ... transferring II;
oldnode->Print(); cout « endl;
#endif
#ifdef DEBUGSUPPLISTS
cout « IIAdded List is
\nll;newsupplist->Print(); cout « endl;
#endif
II skip this item, print message, and remove match from added list,
because match was found
II
Printltem(II>II,File,Name,oldnode) ;
newsupplist->SetLocation(
newsupplist->GetLocation()-backdistance) ;
oldnode = (StateNode*)newsupplist->Getltem();
oldnode->Set(-l,-l,DF UNKNOWN, NULL) ;
newlist->AddLast(oldnode) ;
oldlist->Advance() ;
}
}
Ilboth items were found in other function bodies
if ((newdistance ! = -1) && (olddistance ! = -1)) {
#ifdef DEBUG
cout « "Check 12 (both items were found in lists)\n";
#endif
if (olddistance < newdistance) {
:ji,.,lfdef DEBUG
It « IICheck 13 (new item is closer in old list) ... olddistance is II
«olddistance«
11 • • • transferring
lI;newnode->Print();cout« endl;
#endif
II if the code from the new version was found closer in the old version
for(int x = 0; x < olddistance; x++) {
{
II
II
oldnode = (StateNode*) oldlist->Peekltem() ;
newdistance = newlist->FindDistance(oldnode);
newsupplist->EndSet() ;
backdistance = newsupplist->FindBackDistance(oldnode);
if (backdistance ! = -1) {
This item is already in the added list, so remove matching item and
print moved message
newsupplist->SetLocation(
newsupplist->GetLocation()-backdistance) ;
Printltem(">",File,Name,oldnode) ;
newnode = (StateNode*)newsupplist->Getltem();
newnode->Set(-l,-l,DF UNKNOWN, NULL) ;
newlist->AddLast(newnode) ;
oldlist->Advance() ;
}
II
else if (newdistance == -1) {
This item is not in either list so print that it was removed
Printltem(II-II,File,Name,oldnode) ;
oldlist->Advance() ;
}
II
II
else {
This item is not in added list, but it is later in file, so add it
to deleted list
oldsupplist->AddLast(oldlist->Getltem()) ;
}
}
}
-
else {
#ifdef DEBUG
"Check 14 (old i tern is closer or as close in newlist) ... transferring
It «
tr",ndif
II Else old item is closer or as close in the newlist than new item
is in old list
II
for(int x = 0; x < newdistance; x++) {
IIProcess all items between old item and item matching new item
newnode = (StateNode*)newlist->Peekltem();
olddistance = oldlist->FindDistance(newnode);
oldsupplist->EndSet() ;
backdistance = oldsupplist->FindBackDistance(newnode);
if (backdistance ! = -1) {
II This item is already in the deleted list, so remove matching item
II
and print moved message
oldsupplist->SetLocation(
oldsupplist->GetLocation()-backdistance) ;
Printltem(">",File,Name,newnode) ;
oldnode = (StateNode*)oldsupplist->Getltem();
oldnode->Set(-l,-l,DF UNKNOWN, NULL) ;
oldlist->AddLast(oldnode) ;
newlist->Advance() ;
}
else if (olddistance == -1) {
II This item is not in either list so print that it was added
Printltem("+",File,Name,newnode) ;
newlist->Advance() ;
II
II
}
else {
This item is not in deleted list, but it is later in file, so add it
to added list
newsupplist->AddLast(newlist->Getltem()) ;
}
II;
}
-
}
}
}
}
II
Process the rest of the newlist, since oldlist is finished
if (endlist -- 1) {
#ifdef DEBUG
cout «
"Check 15 (processing remaining newlist)\n";
#endif
Changed = DF TRUE;
newnode = (StateNode*)newlist->Peekltem();
while ((newnode != NULL) &&
(blanknode->Compare(newnode) != DF_IDENTICAL)) {
II Process all items between old item and item matching new item
olddistance = oldlist->FindDistance(newnode);
oldsupplist->EndSet() ;
backdistance = oldsupplist->FindBackDistance(newnode);
if (backdistance ! = -1) {
II This item is already in the deleted list, so remove matching item
II
and print moved message
oldsupplist->SetLocation(oldsupplist->GetLocation()-backdistance);
Printltem(">",File,Name,newnode) ;
oldnode = (StateNode*)oldsupplist->Getltem();
oldnode->Set(-l,-l,DF UNKNOWN,NULL) i
oldlist->AddLast(oldnode) ;
newlist->Advance() i
/
I
}
else if (olddistance == -1) {
This item is not in either list so print that it was added
Printltem("+",File,Name,newnode) ;
newlist->Advance() ;
}
II
II
else {
This item is not in deleted list, but it is later in file,
so add it to added list
newsupplist->AddLast(newlist->Getltem()) ;
}
newnode
=
(StateNode*)newlist->Peekltem();
}
II
Process the rest of the oldlist, since newlist is finished
if (endlist -- 2) {
#ifdef DEBUG
cout « "Check 17 (processing remaining oldlist\n";
#endif
Changed = DF TRUE;
oldnode = (StateNode*)oldlist->Peekltem();
while((oldnode != NULL) && (blanknode->Compare(oldnode) != DF_IDENTICAL)) {
newdistance = newlist->FindDistance(oldnode);
newsupplist->EndSet() ;
backdistance = newsupplist->FindBackDistance(oldnode);
-
II
II
if (backdistance != -1) {
This item is already in the added list, so remove matching item
and print moved message
newsupplist->SetLocation (newsupplist->GetLocation () -backdistance) .
.
.
'
Prlntltem(">",Flle,Name,oldnode)
i
newnode = (StateNode*)newsupplist->Getltem()
newnode->Set(-l,-l,DF UNKNOWN, NULL) j
newlist->AddLast(newnode) j
oldlist->Advance() i
j
}
II
II
II
else if (newdistance == -1) {
This item is not in either list so print that it was removed
Printltem("-",File,Name,oldnode) i
oldlist->Advance() ;
else {
This item is not in added list, but it is later in file, so add
it to deleted list
oldsupplist->AddLast(oldlist->Getltem()) j
}
oldnode = (StateNode*)oldlist->Peekltem()
j
}
}
II
Clear out remaining oldsupplist ("Deleted List")
oldsupplist->Reset() j
while ((oldnode = (StateNode*) oldsupplist- >Getltem ()) ! = NULL)
#ifdef DEBUG
cout « "Check 19 (processing remaining deleted list)\n"i
#endif
Printltem("-",File,Name,oldnode) i
oldnode->Set(-l,-l,DF UNKNOWN, NULL) j
oldlist->AddLast(oldnode) i
{
}
II
Clear out remaining newsupplist ("Added List")
newsupplist->Reset() ;
while ((newnode = (StateNode*)newsupplist->Getltem())
#ifdef DEBUG
cout «
"Check 20 (processing remaining added list)\n"j
#endif
Printltem("+",Match->File,Match->Name,newnode) j
newnode->Set(-l,-l,DF UNKNOWN, NULL) i
newlist->AddLast(newnode) j
}
#ifdef DEBUG
cout « "Check 21 (finished processing)\n"i
#endif
delete blanknode;
return DF_SUCCESSj
-
!=
NULL)
{
/***********************************************************************
*
* File
...... Developer
Date
* Description
*
*
*
*
*
*
StateNode.cc
James Pollard
April 20, 1997
Coded methods for class StateNode.
This child class of
class Node holds pointers into a buffer that
highlight a single statement in the body of a
function being compared.
This node can be in a
Statelist for a function body or a Added/Deleted
lines list.
***********************************************************************/
#include IIStateNode.hll
/***********************************************************************
*
* Function
* Description
Constructor
Initializes variables to starting states
*
***********************************************************************/
StateNode: :StateNode()
{
StateType = DF_UNKNOWN;
Code = NULL;
}
/***********************************************************************
.Function
* Description
*
Destructor
Sets Code pointer to NULL, buffer is destroyed by its
creator to save memory allocations.
*
***********************************************************************/
StateNode: :-StateNode()
{
Code = NULL;
/***********************************************************************
*
*
Function
* Description
*
Set
Overloads Node: :Set to allow setting of attributes
without destroying and recreating
*
***********************************************************************/
int StateNode: :Set(long start, long end, int type, char* buffer)
{
Node: :Set(start,end)
StateType = type;
Code = buffer;
return DF_SUCCESS;
-
/***********************************************************************
*
* Function
: Compare
* Description
*
*
Compares this node to target node, starting with
StateType and string length to quickly
eliminate mismatches
~
,*********************************************************************/
int StateNode: : Compare (StateNode* target)
{
if (StateType != target->StateType)
return DF_LESSTHAN;
{
}
else if ((End-Start) != (target->End-target->Start))
return DF_LESSTHAN;
{
}
else if (strncmp (Code+Start, target->Code+target->Start,End-Sta rt))
return DF_LESSTHAN;
}
else {
return DF IDENTICAL;
}
/***********************************************************************
*
* Function
* Description
*
TakeNextState
Finds boundaries of enxt statement and sets pointers
to highlight them
*
***********************************************************************/
_~ng
{
StateNode: : TakeNextState (char* buffer, long endprevious, long length)
int numdoublequotes = 0;
int numparens = 0;
long startval = endprevious+1;
long endval = endprevious+1;
/* Eat white space at beginning of statement */
while (buffer [startval] -')
startval++;
/* Set known values */
Code = buffer;
Start = startval;
/* This statement is the function header */
if (startval == 0)
return(TakeParams(length)) ;
/* Find boundary where function type can be determined */
if ((endval = GetIndicator(length)) == -1)
return -1;
/* React for individual statement types */
switch (buffer [endval] ) {
case '{':
End = endval;
StateType = DF BEGIN;
return (endval);
case '}':
~-
-
End = endval;
StateType = DF_END;
return (endval) ;
case ' +' :
, ,
case - :
case 1=' :
case ' I' :
case ' *, :
endval = GetVisibleChar(endval, length-l,
if (endval > 0) {
End = endval;
StateType = DF_ASSIGN;
, ;');
}
return (endval) ;
case ' ':
if (strncmp(buffer+startval,lIdo 11,3) -- 0)
End = endval-l;
StateType = DF DO;
return (endval-l) ;
{
}
else if (strncmp (buffer+startval, lIelse 11,5)
End = endval-l;
StateType = DF ELSE;
return (endval-l) ;
0)
{
}
.-
else if (strncmp (buffer+startval, IIcase 11,5)
endval = GetVisibleChar(endval, length-l,
if (endval > 0) {
End = endval;
StateType = DF_CASE;
}
return (endval) ;
0) {
, :');
==
}
else if (IsType(startval,endval) == DF TRUE)
endval = GetVisibleChar(endval, length-l,
if (endval > 0) {
End = endval;
StateType = DF_DECL;
{
, ;');
}
return (endval) ;
}
else {
endval = GetVisibleChar(endval, length-l,
if (endval > 0) {
End = endval;
StateType = DF_FUNCT;
, ;');
}
return (endval) ;
}
case ' #' :
Ilpound statements and macros will have artificial # placed at end of body
endval = GetVisibleChar(endval, length-l, , #' ) ;
if (endval > 0) {
End = endval;
StateType = DF_POUND;
}
return (endval) ;
case ' \ " :
if (strncmp(buffer+startval, IIcase\' 11,5) == 0) {
endval = GetVisibleChar(endval, length-l, , :');
-
if (endval > 0) {
End = endval;
StateType = DF_CASE;
-
}
return (endval) ;
}
FALL THROUGH
case ' ( , :
if (strncmp (buffer+startval, II for ( 11,4) == 0) {
endval = GetMatchingParen(endval, length);
if (endval > 0) {
End = endval;
StateType = DF_FOR;
II
}
return (endval) ;
}
else if (strncmp(buffer+startval,lIwhile(II,6)
endval = GetMatchingParen(endval, length);
if (endval > 0) {
End = endval;
StateType = DF_WHILE;
0)
{
}
return (endval)
i
}
else if (strncmp (buffer+startval, II if (11,3) == 0)
endval = GetMatchingParen(endval, length);
if (endval > 0) {
End = endvali
StateType = DF_IF;
-
{
}
return (endval) ;
}
else if (strncmp(buffer+startval,lIswitch(",7)
endval = GetMatchingParen(endval, length);
if (endval > 0) {
End = endvali
StateType = DF_SWITCHi
0)
{
}
return (endval) ;
}
II
FALL THROUGH TO GENERIC STATEMENT TYPE
default:
endval = GetVisibleChar(endval,length, ' i ' ) ;
if (endval > 0) {
End = endvali
StateType = DF_FUNCT;
}
return (endval) i
}
}
1***************************************************** ******************
*
* Function
~
*
*
*
Description
Get Indicator
Finds position in string of character that will
indicate which statement type this is. Searches
in Code buffer from Start position.
length
should be the index of the last character to check
****************************************************** *****************1
long StateNode: :Getlndicator(long length)
{
_
long curr = Start;
lhile indicator character is not found, get next character
, ) &&
"case o·. " , "do ..
II examples
while ( (Code [curr]
"case'
a' :"
examples
,
\")
&&
(Code [curr]
II
,
('
)
"printf(
... ", "fo
examples
&&
(Code [curr]
II
, } , ) &&
examples
11
}
"
(Code [curr]
II
, { , ) &&
(Code [curr]
II examples
" {"
i
"returni"
&&
(Code [curr]
II examples
, =' ) &&
"X= ... "
(Code [curr]
II examples
"++Xi
II,
examples
"X++i" , "
(Code [curr] != ' +' ) &&
II
examples
"x- -; " , "
"-x;
"
,
(Code [curr] != ' - , ) &&
II
examples
"X*=Yi"
(Code [curr] != ' * ' ) &&
II
(Code [curr] != ' I' ) &&
"x/=Yi"
II examples
examples
(Code [curr] != ' < ' ) &&
II
(Code [curr] != ' >' ) &&
II examples
examples
:
"#include ... " , "#define ..
(Code [curr] != ' #' )
II
I
I
)
curr++i
if (curr
>
length) return -Ii
}
return (curr)
i
}
1***************************************************** ******************
*
* Function
....... Description
*
*
*
*
IsType
Returns true if the string highlighted is a variable
type or an indicator of a variable declaration.
char at end is assumed to be " ", and since start
should be start of statement, letter before start
cannot be part of same word.
****************************************************** *****************1
int StateNode: : IsType (long start, long end)
{
long length=end-start+l;
Ilcheck for variable type declarations
switch (length) {
case 4:
if (strncmp(Code+start,"int ",length) -- 0)
return DF_TRUEi
break;
case 5:
-
if ((strncmp(Code+start,"char
(strncmp(Code+start,"long
(strncmp(Code+start, "auto
(strncmp(Code+start,"enum
(strncmp(Code+start,"void
return DF- TRUEi
",length) -- 0)
",length) -- 0)
" , length) -- 0)
",length)
0)
" ,length) -- 0)
breaki
case 6 :
if ((strncmp(Code+start,"float ",length)
0)
(strncmp(Code+start,"short " ,length) -- 0)
return DF- TRUEi
breaki
"
case 7 :
if ((strncmp(Code+start, "double
(strncmp(Code+start,"extern
(strncmp(Code+start,"static
(strncmp(Code+start,"signed
(strncmp(Code+start, "struct
return DF_TRUE;
break;
-
0)
",length)
0)
",length)
0)
",length)
",length) -- 0)
" ,length) -- 0)
case 8:
if (strncmp(Code+start, "typedef ", length) -- 0)
return DF_TRUE;
break;
case 9:
if ((strncmp (Code+start, "unsigned", length)
(strncmp(Code+start, "register ",length)
return DF_TRUE;
break;
0)
0)
return DF_FALSE;
}
/***********************************************************************
*
* Function
* Description
GetVisibleChar
Returns the index of the next char in Code buffer that
matches target and is not between single or
double quotes or a pair of parenthesis
*
*
*
~**********************************************************************/
long StateNode: :GetVisibleChar(long start, long end, char target)
{
int numdoublequotes
o·,
int numsinglequotes
o·,
int numparens = 0;
int forwardslashes = 0;
long current = start;
//get next character until unquoted or parenthesized target is found
while ((Code[current] 1= target) I I
(numdoublequotes)
(numsinglequotes)
(numparens)
{
//if not in quotes now, check this character for parenthesis
if ((lnumdoublequotes) && (lnumsinglequotes)) {
if (Code [current] == ' ( ' ) {
numparens++;
II
}
,) ,)
if (Code [current]
numparens - - ;
{
}
-
}
forward slash state resets if last one was a slash or this one isn't
if (Code [current] == '\\') {
forwards lashes = (forwardslashes+l) %2;
}
else {
II
forwardslashes
OJ
}
J...4.don't count \" or double quotes in single quotes
if ((Code[current] == '\"') &&
(!forwardslashes)
&&
(!numsinglequotes)
) {
numdoublequotes
(numdoublequotes+l)%2j
}
//don't count \, or single quotes in double quotes
else if ((Code[current] == '\") &&
(!forwardslashes)
&&
(!numdoublequotes)
{
numsinglequotes
(numsinglequotes+l)%2j
}
current++j
if (current> end) return -lj
}
return (current)
j
}
/***********************************************************************
*
* Function
* Description
*
*
-
TakeParams
Fills this node with the function header and
parameters from the Code buffer.
***********************************************************************/
~~ng
StateNode: : TakeParams (long length)
{
long currj
//find { which will be after params in K&R and ANSI style
curr = GetVisibleChar(Start, length-I, , { , ) j
if (curr > 0) {
curr--j
StateType
DF_PARAMSj
End = currj
}
ret urn (curr) i
}
/***********************************************************************
*
* Function
* Description
*
GetMatchingParen
Returns the index of the end parenthesis that matches
the start parenthesis at the start char in Code.
*
***********************************************************************/
long StateNode: : GetMatchingParen (long start, long end)
{
-
int numparens=lj
long current = start+lj
//find the next ')' not between parens and not in quotes
return (GetVisibleChar(start+l,end,') ')) j
}
/***********************************************************************
*
* Function
.-t Description
Print
Prints contents of this node
***********************************************************************/
int StateNode: :Print()
{
char* type;
//DEBUG CODE
/*
if (StateType -- DF FOR)
type = " FOR
" ,.
else if (StateType -- DF_WHILE)
type = " WHILE
" ,.
else if (StateType -- DF- DO)
type = " DO
" ,.
else if (StateType -- DF- IF)
type = " IF
" ,.
else if (StateType -- DF ELSE)
type = " ELSE
" ,.
else if (StateType -- DF- SWITCH)
type = " SWITCH
" ,.
else if (StateType -- DF- CASE)
type = " CASE
" ,.
else if (StateType -- DF- BEGIN)
type = " BEGIN
" ,.
else if (StateType - - DF- END)
type = " END
" ,.
else if (StateType - - DF PARAMS)
type = " PARAMS
" ,.
else if (StateType -- DF- POUND)
type = " POUND
" ,.
else if (StateType -- DF- DECL)
11 •
type = 11 DECL
,
else if (StateType == DF_ASSIGN)
11 •
type = " ASSIGN
,
else if (StateType -- DF- FUNCT)
type = " FUNCT
" ,.
else if (StateType -- DF UNKNOWN)
return DF- FAILURE;
-
{
}
cout « Start «
" 11 « End « type; */
for (long x = Start; x <= End; x++)
cout « Code [x] ;
-
/***********************************************************************
*
* File
"""" Developer
Date
* Description
*
*
*
List.cc
James Pollard
April 20, 1997
Coded methods for class List. This class
holds a list of items and allows certain actions
on those item. This class is not intended to be
be used directly in the Differ project.
*
***********************************************************************/
#include "List.h"
/***********************************************************************
*
* Function
* Description
*
*
Constructor
Sets all pointers to null and other attributes to
values indicating no list items
***********************************************************************/
List: : List ()
{
First = NULL;
Last = NULL;
Current = NULL;
CurrentLocation
Length = 0;
-1;
L
k***************************************************** ****************
*
* Function
* Description
Destructor
Removes all items
*
***********************************************************************/
List: : -List ()
{
while (Remove () == DF SUCCESS)
/* NULL BODY */;
First = NULL;
Last = NULL;
Current = NULL;
}
/***********************************************************************
*
* Function
* Description
Add
Adds item after Current node or as only node in list
*
***********************************************************************/
int List: :Add(Node* item)
1if (Length == 0) { //only item in list
First = item;
Last = item;
}
else if (Current
==
Last)
{ / /last in list
---
item->Follow(Current)
Current->Lead(item)
Last = item;
}
else {
item->Lead(Current->GetNext()) ;
item->Follow(Current) ;
Current->GetNext()->Follow(item)
Current->Lead(item)
}
Current = itemj
CurrentLocation++j
Length++;
return DF SUCCESSj
}
1***************************************************** ******************
*
* Function
* Description
AddLast
Adds item after Last node in list
*
****************************************************** *****************1
int List: :AddLast(Node* item)
{
if (Length == 0) II if this is only node, simply add it
return Add(item)
item->Lead(NULL) ;
item->Follow(Last)
Last->Lead(item)
Last = itemj
Length++j
,}
1***************************************************** ******************
*
* Function
* Description
Remove
Removes Current item and set pointer to next item
*
****************************************************** *****************1
int List: :Remove()
{
Node* item;
if ((item = Getltem()) == NULL)
return DF_FAILURE;
else {
delete item;
return DF_SUCCESS;
}
Ilget current item from list
Iithere was no item
Iidelete item
}
1***************************************************** ******************
*
.....i..
Function
Description
Getltem
Returns pointer to and removes Current item
*
****************************************************** *****************1
Node* List: :Getltem()
Node* Item;
if (Length == 0) return NULL;
fino items in list
Node* before = Current->GetPrevious(); //point to surrounding items
Node* after = Current->GetNext();
if (Length == 1) {
//only item in list
Length = 0;
CurrentLocation
-1;
Item = Current;
Last = NULL;
First = NULL;
Current = NULL;
//first item in list
} else if (before == NULL) {
after->Follow(NULL)
First = after;
Item = Current;
Current = after;
Length--;
//last item in list
} else if (after == NULL) {
before->Lead(NULL)
Last = before;
Item = Current;
Current = before;
CurrentLocation--j
Length--j
//not first or last, normal remove
} else {
before->Lead(after) j
after->Follow(before)
Item = Currentj
Current = afterj
Length--;
}
Item->Lead(NULL) ;
Item->Follow(NULL)
return Item;
//reset pointers for safety
j
/***********************************************************************
*
* Function
* Description
PeekItem
Returns pointer to current item for viewing
*
***********************************************************************/
Node* List: : PeekItem ()
{
return Currentj //this should probably become some sort of constant
}
/***********************************************************************
*
* Function
* Description
*
FindNext
Returns index of next node that matches item,
starting at and including Current
r*********************************************************************/
int List: : FindNext (Node* item)
{
if (Length == 0) return -1;
fino items in list
int templocation = CurrentLocation;
Node* temp = Current;
//start from current
//if this doesn't match
~
while ((temp != NULL) &&
(temp->Compare(item) != DF_IDENTICAL)) {
temp = temp->GetNext()
//look at next one
templocation++;
// there were no matches so return an invalid index
if (temp == NULL)
return -1;
temp = NULL;
return templocation; //return index of found item
/***********************************************************************
*
FindLast
Returns index of last node that matches item, searching
back from Current
* Function
* Description
*
*
***********************************************************************/
int List: : FindLast (Node* item)
{
if (Length == 0) return -1;
int templocation = CurrentLocation;
Node* temp = Current;
do {
temp = temp->GetPrevious()
//backup one node
templocation--;
} while ((temp != NULL) &&
(temp->Compare(item) != DF_IDENTICAL))
//stop if it matches
if (temp == NULL)
return -1; //there was no item
temp = NULL;
return templocation; //return index of found item
/***********************************************************************
*
SetLocation
Sets Current pointer to itemno'th item
* Function
* Description
*
***********************************************************************/
int List: :SetLocation(int itemno)
{
//make sure request is in bounds
if ((itemno >= 0) && (itemno < Length)) {
//requested location was backwards
if (itemno < CurrentLocation) {
do {
Backup() ;
//backup until there
} while (CurrentLocation != itemno)
}
else if (itemno > CurrentLocation)
//requested location was forwards
do
Advance() ;
{
//advance until there
while (CurrentLocation
,-
!=
itemno)
}
return DF SUCCESS;
}
else
return DF FAILURE;
/***********************************************************************
*
* Function
* Description
*
Advance
Moves Current pointer ahead one if possible
***********************************************************************/
int List: :Advance()
{
if (Current != Last) { j/if this isn't the last node move forward
Current = Current->GetNext()
CurrentLocation++;
return DF_SUCCESS;
}
else
//already at end of list
return DF_FAILURE;
/***********************************************************************
*
* Function
-
Description
Backup
Moves Current pointer back one if possible
***********************************************************************/
int List: :Backup()
{
if (Current != First) { //if this isn't the first node move backwards
Current = Current->GetPrevious()
CurrentLocation--;
return DF_SUCCESS;
}
jjalready at start of list
else
return DF_FAILURE;
/***********************************************************************
*
* Function
* Description
Reset
Moves Current pointer to head of list
*
***********************************************************************/
int List: :Reset()
{
Current = First;
//set pointer to first (may be NULL)
if (Length > 0) {
CurrentLocation = 0; //if there is at least one item set index
return DF_SUCCESS;
else {
return DF_FAILURE;
}
/***********************************************************************
,.....:t
Function
* Description
EndSet
Moves Current pointer to end of list
*
***********************************************************************/
int List: :EndSet()
{
Current = Last;
CurrentLocation
Length-I;
//set pointer, empty list works
//set index
}
/***********************************************************************
*
* Function
* Description
GetLocation
Returns index of Current pointer
*
***********************************************************************/
int List: :GetLocation()
{
return CurrentLocation;
}
/***********************************************************************
-
*
Function
Description
GetLength
Returns length of list
*
***********************************************************************/
int List: :GetLength()
{
return Length;
/***********************************************************************
*
* Function
* Description
Print
Prints all nodes in list starting at Current node
*
***********************************************************************/
int List: :Print()
{
if (Length
0) return DF_FAILURE;
int counter
0;
Node* start = Current;
-
Current->Print()
cout « endl;
while (Advance() != DF FAILURE)
Current->Print()
cout « endl;
//there are no nodes
//start at Current
//print Current
{
//if it can move ahead
//print this node
}
Reset ()
//while haven't reached starting point
//restart at beginning
}
-
-
while (Current != start) {
Current->Print() ;
cout « endl;
Advance() ;
}
NULL;
start
return DF- SUCCESS;
//print this node
//go to next node
/***********************************************************************
*
* File
..-c. Developer
Date
* Description
*
*
*
*
SortedList.cc
James Pollard
April 20, 1997
Coded methods for class SortedList.
This class holds
a list of sorted elements.
This class is not
intended to be used directly in the Differ
project.
***********************************************************************/
#include "SortedList.h"
/***********************************************************************
*
* Function
* Description
Constructor
Only a placeholder at this time
*
***********************************************************************/
SortedList: :SortedList()
~
/***********************************************************************
*
* Function
* Description
Destructor
Only a placeholder at this time
*
,-**********************************************************************/
SortedList: :-SortedList()
~
/***********************************************************************
*
* Function
* Description
*
*
Add
Adds item in appropriate place in list, after nodes
less than or equal to item
***********************************************************************/
int SortedList: : Add (Node* item)
{
if (Length == 0)
//there were no items in list
return(List::Add(item)) i
//if Current <= item search forward until greater item or end of list
if (Current->Compare(item) != DF_GREATERTHAN) {
while ((Advance() != DF FAILURE) &&
(Current->Compare(item) != DF GREATERTHAN))
/*NULL BODY*/i
//if Current < item, add item before greater node or after end of list
if none greater
//
if (Current->Compare(item) -- DF_GREATERTHAN)
Backup() i
List: : Add (item)
}
else {
//else Current> item
//backup until start or Current <= item
-
while ((Backup() !~ DF FAILURE) &&
(Current->Compare(item) == DF_GREATERTHAN))
/*NULL BODY*/;
k,(if founc Current <= item, add after, else add to start of list
if (Current->Compare(item) != DF GREATERTHAN) {
List: :Add(item);
-
}
else {
Current->Follow(item) ;
item->Lead(Current) ;
Current = item;
First = item;
Length++;
}
return DF SUCCESS;
}
-
-
/***********************************************************************
*
* File
,"""" Developer
Date
* Description
*
*
FunctList.cc
James Pollard
April 20, 1997
Coded methods for class FunctList. This child class
of SortedList holds a list of FunctNode's for one
file set.
*
***********************************************************************/
#include II FunctList . h"
/***********************************************************************
*
* Function
* Description
Constructor
Place holder for now
*
***********************************************************************/
FunctList: :FunctList()
~
/***********************************************************************
*
* Function
* Description
Destructor
Placeholder because parent class cleans out list
*
-
***********************************************************************/
L~nctList:
:-FunctList()
~
/***********************************************************************
*
* Function
* Description
FindAll
Returns number of nodes in list that match item
*
***********************************************************************/
int FunctList: : FindAll (FunctNode* item)
{
if (Length == 0) return 0; //if list is empty, return 0
int counter = 0;
FunctNode* start
(FunctNode*) Current;
//Check items to end of file, increment counter if it matches
while (Advance() != DF FAILURE)
if (item->CompareName((FunctNode*)PeekItem())
DF_IDENTICAL)
counter++;
//Return to start of list
Reset() ;
if (item->CompareName((FunctNode*)PeekItem())
DF_IDENTICAL)
counter++;
~Check items until back to starting point
while (Current != start) {
Advance() ;
if (item->CompareName((FunctNode*)PeekItem())
DF_IDENTICAL)
counter++;
}
start= NULLi
return (counter)
-
k***************************************************** ****************
*
FindNext
Returns index of next node that matches item
* Function
* Description
*
****************************************************** *****************1
int FunctList::FindNext(FunctNode* item)
{
Ilif
list empty, return invalid value
if (Length == 0) return -Ii
int templocation = CurrentLocationi
FunctNode* temp = (FunctNode*)Currenti
Ilmove forward until find match or reach end
while ((temp != NULL) &&
(temp->CompareName(item) != DF_IDENTICAL))
temp = (FunctNode*)temp->GetNext()
templocation++i
II if
{
went past end of list, return invalid value
if (temp == NULL)
return -Ii
temp = NULLi
return templocationi
-} **********************************************************************
*
Process
Executes comparison on Current node and its match
* Function
* Description
*
****************************************************** *****************1
int FunctList: :Process(char* oldbuffer, char* newbuffer,
long oldlength, long newlength,
StateList* oldlist, StateList* newlist,
StateList* oldsupplist, StateList* newsupplist)
{
Ilif
-
FunctNode* thisitemi
if (Length == 0)
Ilif no items, return failure
return DF_FAILUREi
Reset () i
Iistart at head of list
do {
Current item has a match, clear buffers and process items
thisitem = (FunctNode*)Currenti
if (thisitem- >IsMatched () ! = NULL) {
memset(newbuffer, '\0' ,newlength)
memset(oldbuffer,'\O' ,oldlength)
thisitem->Process(oldbuffer, newbuffer, oldlist,
newlist,oldsupplist,newsupplist)
}
} while (Advance () != DF_FAILURE)
return DF_SUCCESSi
Ilgo
to next item
1***************************************************** ******************
*
* Function
* Description
MaxLength
Returns length of longest function in list
....-t-
k***************************************************** ****************/
long FunctList: :MaxLength()
{
if (Length == 0) return 0;
long max = 0;
long thislength = 0;
FunctNode* thisitem;
Node* start = Current;
fino items in list, return 0 length
//Check items to end of list and compare length against current maximum
while (Advance() != DF FAILURE)
{
thisitem = (FunctNode*)PeekItem();
if ((thislength = thisitem->GetLength())
max = thislength;
> max)
}
//Return to start of list, and check first item
Reset() ;
thisitem = (FunctNode*)PeekItem();
if ((thislength = thisitem->GetLength()) > max)
max = thislength;
//check items until back to starting point
while (Current != start) {
Advance() ;
thisitem = (FunctNode*)PeekItem();
if ((thislength = thisitem->GetLength())
max = thislength;
.-
> max)
}
start= NULL;
return (max) ;
/***********************************************************************
*
* Function
* Description
* Note
*
*
*
FeedList
Fills this function list from the tablefile passed in
A possible revision for this module would be to
perform i/o in larger steps in order to
optimize scan time.
***********************************************************************/
int FunctList: :FeedList(char* filename)
{
FunctNode* newnode;
char buffer;
ifstream infile(filename);
char* file;
char* name;
~
char scopechar;
int scope;
long start;
long end;
while (! infile. eof ())
{
//get characters until 11:11
start = infile.tellg();
infile.get(buffer) ;
while ((buffer != ' :') && (!infile.eof()))
infile.get(buffer) ;
//check for eof to guard against blank or incomplete lines
if (infile.eof())
break;
end = infile.tellg();
name = new char [end-start] ;
//go back to recorded start and read in function name
infile.seekg(start) ;
infile.read(name,end-start-l) ;
name [end-start-l] = '\0';
//reset file pointer after last 11:11
infile.seekg(end) ;
start=infile.tellg() ;
infile.get(buffer) ;
//get characters until 11:11
while ((buffer != ':') && (!infile.eof()))
infile.get(buffer) ;
//check for eof to guard against blank or incomplete lines
if (infile.eof())
break;
end = infile.tellg();
file = new char [end-start] ;
//go back to recorded start and read in file name
infile.seekg(start) ;
infile.read(file,end-start-l) ;
file [end-start-l] ~ '\0' i
I,get function scope which is of known length immediately after file name
infile.seekg(end) ;
infile.get(scopechar) i
infile.seekg(end+2) ;
//record start of function body
start = infile.tellg() i
infile.get(buffer) i
//get characters until end of line
while ((buffer != '\n') && (!infile.eof()))
infile.get(buffer) i
end = infile.tellg()-2;
if (scopechar == 'e')
scope
DF_EXTERN;
else
scope
DF STATIC;
//make new node, fill it with read-in values, and add to list
newnode = new FunctNode (name, file,scope,start,end,filename)
Add (newnode) i
-
}
infile. close ()
i
}
/***********************************************************************
*
....... Function
MatchAll
Description
Matches this function and all functions with same name
to their counterparts in the new file set.
*
* Note
This function may not react well if there are more
than 26 functions of the same name that cannot
*
be matched by file name or extern scope.
This
*
i
would be an unbelievably bad worst case, so it
is safe to have this limitation.
*
*
*
~***************************************************** *****************1
int FunctList: :MatchAll(FunctNode* item,FunctList* newfilelist)
{
FunctNode* blanknode;
int headermode = 0;
int numoldmatches;
int numnewmatches;
int numnewmatchesleft;
int numoldmatchesleft;
FunctNode** newmatches;
FunctNode** oldmatches;
int oldextern = -1;
int newextern = -1;
FunctNode* oldnode;
FunctNode* newnode;
char oldprompt; Ilprompt in front of old file name to identify
char newprompt; Ilprompt in front of new file name to identify
int X;
int y;
char answer[5]
Ilmake
II
II
a node that will pass a name compare against a header node (the contents
of a file outside all functions), because those nodes will only be
matched based on filename
blanknode = new FunctNode("","example.c",'s' ,0,0,"nofile");
if (blanknode->CompareName(item)
DF IDENTICAL)
headermode = 1;
Ilfind
all nodes in newfilelist that match this item
newfilelist->Reset() ;
if (numnewmatches = newfilelist->FindAll(item) > 0) {
Ilif there is at least one match, make an array to hold pointers to them
newmatches = new FunctNode*[numnewmatches]
for (y = 0; y < numnewmatches; y++) {
Ilput next matching node in array
newfilelist->SetLocation(newfilelist->FindNext(item)) ;
newmatches[y] = (FunctNode*)newfilelist->PeekItem();
Ilif this function is extern and there already was an external copy of this,
then this file set cannot be valid, else set the flag that extern
II
was found
II
if (newmatches[y] ->IsExtern() == DF TRUE) {
if (newextern >= 0) {
cout «
"There are too many external versions of function ";
newmatches[y] ->PrintName();
cout «
" in new fileset.
This fileset is not valid.\n";
delete []newmatches;
return (DF FAILURE);
}
else {
newextern = newfilelist->GetLocation();
-
}
newfilelist->Advance() ;
}
}
}
Ilfind all nodes in oldfilelist that match this item
Reset() j
if (numoldmatches
FindAll(item) > 0) {
Ilif there is at least one match, make an array to hold pointers to them
__
oldmatches = new FunctNode*[numoldmatches] j
for (y = OJ Y < numoldmatches; y++) {
Ilput next matching node in array
SetLocation(FindNext(item)) j
oldmatches[y] = (FunctNode*)Currentj
II if this function is extern and there already was an external copy of this,
then this file set cannot be valid, else set the flag that extern
II
was
found
II
if (oldmatches[y] ->IsExtern() == DF TRUE) {
if (oldextern >= 0) {
cout «
"There are too many external versions of function "j
oldmatches[y] ->PrintName() j
cout «
" in old fileset.
This fileset is not valid.\n"j
delete []newmatchesj
delete []oldmatchesj
return (DF_FAILURE) j
}
else {
oldextern
}
}
Advance()
CurrentLocationj
j
}
Ilrecord
number of matches left so know when done matching
numnewmatchesleft = numnewmatchesj
numoldmatchesleft = numoldmatchesj
for (x = 0; x < numoldmatches; x++) {
II if this array entry hasn't been matched search for match by filename
II
in the other array
if (oldmatches[x] ->IsMatched() == NULL) {
for (y = OJ Y < numnewmatches; y++) {
Ilif this item is not matched either, compare scopes
if (newmatches[y] ->IsMatched() == NULL) {
if (oldmatches[x]->IsExtern() == DF TRUE) {
Ilif both are extern, match them
if (newmatches[y]->IsExtern() == DF TRUE) {
oldmatches[x]->Matchup(newmatches[y]) ;
numnewmatchesleft--;
numoldmatchesleft--;
~
} }
else if (newmatches[y]->IsExtern() == DF FALSE) {
Ilif neither is extern, but same file name, match them up
if (oldmatches[x] ->CompareFile(newmatches[y])
{
}
}
}
}
oldmatches[x]->Matchup(newmatches[y]) ;
numnewmatchesleft--j
numoldmatchesleft--;
DF_IDENTICAL)
lido not continue if this item is a header of a file
if (headermode)
numnewmatchesleft = 0;
.~hile there is still at least one unmatched item in both arrays
while ((numnewmatchesleft > 0) && (numoldmatchesleft > 0)) {
newprompt = 'A';
oldprompt = 'a';
cout « "Function: ";
item->PrintName() ;
cout « " has copies that need to be manually matched" « endl;
cout « "oldfileset" « endl;
//print filenames of all matches in old file set
for (x = 0; x < numoldmatches; x++) {
if (oldmatches[x]->IsMatched() == DF FALSE) {
cout « "\t(" « oldprompt « ")\1:"";
oldmatches[x]->PrintFile() ;
cout « endl;
oldprompt++;
}
cout « endl « endl « "newfileset" « endl;
//print filenames of all matches in new file set
for (y = 0; y < numnewmatches; y++) {
if (newmatches[y] ->IsMatched() == DF FALSE)
cout « "\t(" « newprompt « ")\t";
newmatches[y] ->PrintFile();
cout « endl;
newprompt++;
-
{
}
}
for and read user's manual matching
cout « endl « "Type in oldfile index and newfile index "
«
"(i.e.\"a A\" to match\n"
«
"or \"Quit\" to leave the rest unmatched" « endli
cin.read(&answer,5) ;
answer [4] = '\0';
if (strcmp(answer,"Quit")
0) {
delete []newmatches;
delete []oldmatches;
return DF_SUCCESSi
I,~rompt
}
//search through old array for match to input given
oldprompt = 'a'i
newprompt = 'A' i
for (x = 0; x < numoldmatches; x++) {
if (oldmatches[x]->IsMatched() == DF_FALSE) {
if (oldprompt == answer[O)) {
//search through new array for match to that input
for (y = 0; y < numnewmatches; y++) {
if (newmatches[y]->IsMatched() == DF FALSE) {
if (newprompt == answer[2]) {
//match items selected and decrement count of remaining copies
oldmatches[x]-> Matchup(newmatches[y]) i
numnewmatchesleft--i
numoldmatchesleft--;
-
}
newprompt++;
}
}
}
oldprompt++i
}
}
-}
delete []newmatchesi
delete []oldmatchesi
return DF_SUCCESSi
-
.-
/***********************************************************************
*
StateList.cc
James Pollard
April 20, 1997
Coded methods for class StateList.
This class holds
a list of statements that represents either the
body of a function or a Added/Deleted lines list
* File
A Developer
Date
* Description
*
*
*
***********************************************************************/
#include lStateList.h"
/***********************************************************************
*
Constructor
Only a placeholder at this time
* Function
* Description
*
***********************************************************************/
StateList: :StateList()
~
/***********************************************************************
*
Destructor
Only a placeholder at this time
* Function
* Description
*
-
***********************************************************************/
dteList: :-StateList()
/***********************************************************************
*
* Function
* Description
FindDistance
Finds difference in location between Current node and
next node that matches item
*
*
***********************************************************************/
int StateList: : FindDistance (StateNode* item)
{
int temp = CurrentLocation;
int distance = 0;
//if list is empty return invalid value
if (Length == 0)
return (-1) ;
//move to end of list, comparing as you go
while (DF_IDENTICAL != item->Compare((StateNode*)Current))
if (DF_FAILURE == Advance()) {
SetLocation(temp)
return -1;
-
}
else
distance++;
}
//reset list pointer and return distance found
{
SetLocation(temp)
return (distance) i
-
i
,*********************************************************************
*
FindBackDistance
Finds difference in location between Current node and
last node that matches item ... i.e. searches
for target backwards from Current.
* Function
* Description
*
*
*
***********************************************************************/
int StateList: : FindBackDistance (StateNode* item)
{
int temp = CurrentLocation;
int distance = Oi
//if list is empty return invalid value
if (Length == 0)
return (-1) i
//move to start of list, comparing as you go
while (DF IDENTICAL != item->Compare((StateNode*)Current))
if (DF FAILURE == Backup()) {
SetLocation(temp)
return -Ii
{
}
else
distance++i
}
~~eset
list pointer and return distance found
SetLocation(temp) i
return (distance) i
/***********************************************************************
*
* Function
* Description
*
*
FeedList
Fills existing or new nodes with statements from code
found in buffer
***********************************************************************/
int StateList: :FeedList(char* buffer, long length)
{
int endstatei
StateNode* thisnodei
int statetypei
//Start at first node and make node if necessary
if (Reset() == DF_FAILURE) {
thisnode = new StateNode()
Add (thisnode) ;
thisnode = NULL;
,-
\sk nodes to take each next statement and add nodes as needed
endstate = -1;
while (endstate < length-I) {
thisnode = (StateNode*)PeekItem();
endstate = thisnode->TakeNextState(buffer,endstate,length)
if (endstate < 0) {
//Found end of function prematurely, reset partially init'd node
thisnode = (StateNode*)Peekltem();
thisnode->Set(-l,-l,DF_UNKNOWN,NULL) ;
return DF_FAILURE;
}
thisnode = NULL;
if (Advance() == DF_FAILURE) {
thisnode = new StateNode();
Add (thisnode) ;
thisnode = NULL;
}
}
//Set all remaining nodes to blank
do {
thisnode = (StateNode*)Peekltem();
thisnode->Set(-l,-l,DF UNKNOWN, NULL) ;
} while (Advance() == DF_SUCCESS);
}
-
-
/***********************************************************************
*
* File
,---. Developer
Date
* Description
DriveNode.cc
James Pollard
April 20, 1997
Testing driver for the Node class.
uses the Node class.
*
*
This driver
***********************************************************************/
#include <iostream.h>
#include " .. /header.h"
#include " .. /Node.h"
int main ()
{
Node node [3]
int result;
node [0] .Set(l,l);
node [1] . Set (1,2) ;
node [2] . Set (1,1) ;
for
-,
for
(int x =
cout
node
cout
0; x < 3; x++)
«
"Node[" « x «
[x] . Print () ;
«
endl;
II]
II ,.
(int y = 0; y < 2; y++)
for (int x = y+l; x < 3; x++) {
if ((result = node[y] .Compare(node+x)) -- DF_IDENTICAL)
II ]
II Node [II « y «
cout «
Node [II « x «
II] \n" ;
if (result -- DF LESSTHAN)
II ] <
cout « "Node [II « y «
Node [II « x «
II] \n" ;
if (result -- DF GREATERTHAN)
cout « "Node[" « y «
"] >
Node [II « X «
"] \n" ;
}
node
node
node
node
for
-
}
for
[2] .Follow(node+l);
[1] .Lead(node+2);
[1] .Follow(node+O);
[0] .Lead(node+l);
(int y = 0; Y < 2; y++) {
if ((result = node[y] .Compare(node[y] .GetNext()))
DF IDENTICAL)
cout «
"Node [" « y «
II]
next node \n " ;
if (result == DF LESSTHAN)
cout « "Node [II « y «
II] < next node \n" ;
if (result == DF GREATERTHAN)
cout « "Node [II « y «
II] > next node \n" ;
(int y
if
if
2; Y > 0; y- -) {
((result = node[y] . Compare (node [y] .GetPrevious())) ==
DF IDENTICAL)
cout «
"Node[II « y «
"]
previo~s node\n";
(result == DF_LESSTHAN)
cout «
"Node[" « y «
II] < previous node\n";
=
if
}
-'
-
-
for
(result == DF GREATERTHAN)
cout « "Node [II « y «
II]
>
previous node\n"j
(int y = OJ Y < 3; y++)
cout «
"Length of node[II « y « II] is II
«
node[y] .GetLength() « endlj
/***********************************************************************
*
* File
Developer
Date
* Description
,.,..c.
*
*
*
DriveFunctNode.cc
James Pollard
April 20, 1997
Testing driver for the FunctNode class.
This driver
uses FunctNode and all of the classes on which it
depends.
***********************************************************************/
#include <iostream.h>
#include " .. /header.h"
#include " .. /Node.h"
#include " .. /List.h"
#include " .. /StateNode.h"
#include " .. /StateList.h"
#include " .. /FunctNode.h"
int main ()
{
FunctNode* newnode
FunctNode*
-.
new FunctNode("y","notexample.c",DF_EXTERN,
1 7 , 900, "newfiles. tab")
oldnode
new FunctNode ("x", "example. c", DF_STATIC,
14,887, "oldfiles. tab")
oldlist
new StateList();
newlist
new StateList();
deletedlist
new StateList();
addedlist = new StateList();
node;
StateList*
StateList*
StateList*
StateList*
StateNode*
int result;
long length;
char* newbuffer;
char* oldbuffer;
cout « "New node is ";
result = newnode->Compare(oldnode)
if (result == DF_IDENTICAL)
cout «
"IDENTICAL";
if (result == DF_LESSTHAN)
cout «
"LESSTHAN";
if (result == DF_GREATERTHAN)
cout «
"GREATERTHAN";
cout «
" Old node\n";
cout « "New node name is ";
result = newnode->CompareName(oldnode)
if (result == DF_IDENTICAL)
cout « "IDENTICAL";
if (result == DF_LESSTHAN)
cout «
"LESSTHAN";
if (result == DF_GREATERTHAN)
cout «
"GREATERTHAN";
cout «
" Old node\n";
-
cout «
"New node file is ";
result = newnode->CompareFile(oldnode)
if (result == DF_IDENTICAL)
cout «
"IDENTICAL";
if (result == DF_LESSTHAN)
cout «
"LESSTHAN";
if (result == DF GREATERTHAN)
cout « "GREATERTHAN";
cout « " Old node\n";
cout « "New node is ";
result = newnode->CompareAll(oldnode);
if (result == DF_IDENTICAL)
cout «
"IDENTICAL";
if (result == DF_LESSTHAN)
cout « "LESSTHAN";
if (result == DF_GREATERTHAN)
cout «
"GREATERTHAN";
cout « " Old node\n";
oldnode->Matchup(newnode) ;
cout « "New node is ";
if (newnode->IsMatched()
cout «
"not ";
cout « "matched\n";
cout « "Old node is ";
if (oldnode->IsMatched()
cout «
"not I I ;
cout « "matched\n";
--
/*
}
-
cout « "New Node is ";
if (newnode->IsExtern()
cout « "not ";
cout « "external\n";
cout «
"Old Node is ";
if (oldnode->IsExtern()
cout « "not ";
cout « "external\n";
DF FALSE)
DF FALSE)
DF FALSE)
DF FALSE)
length = newnode->GetLength();
newbuffer = new char [length] ;
length = oldnode->GetLength();
oldbuffer = new char [length] ;
newnode->ReadBody(newbuffer) ;
oldnode->ReadBody(oldbuffer) ;
cout « newbuffer « endl « oldbuffer « endl; */
oldnode->Process(oldbuffer,newbuffer,oldlist,newlist,
deletedlist,addedlist) ;
delete [] newbuffer;
delete [] oldbuffer;
/***********************************************************************
*
* File
,....... Developer
Date
* Description
*
*
DriveStateNode.cc
James Pollard
April 20, 1997
Testing driver for the StateNode class.
This driver
uses StateNode and all of the classes on which it
depends.
*
***********************************************************************/
#include <iostream.h>
#include " .. /header.h"
#include " .. /Node. h"
#include " .. /StateNode.h"
int main ()
{
StateNode node[100]
int resultj
int numnodes = OJ
char* buffer = "int x(int argc,char**argv) {extern int optindj\
extern int opterrjint aflg=Ojint iflg=ljint nreadjint flagsjint *fdj\
int badfiles=Ojint njint indexjchar buffer [BUFSIZ] jopterr=Oj\
while( (c=getopt(argc+1,argv,\"ai\")) !=EOF)switch(c) {case 'a' :aflg++jbreakj\
case ' i ' :iflg++jcase '?':\
(void)fprintf(stderr,\"usage: cmd [-al-i] file1 [ ... ] \\n\") jexit(2) j}\
if(aflg==l)flags=O_APPENDlo_CREATlo_WRONLYjelse flags=O_TRUNClo_CREATlo_WRONLYj\
if (iflg==l) signal (SIGINT,SIG IGN) jfd[O]=lj\
fd=(int*)malloc( (argc-optind+1)*sizeof(int)) jfor(n=ljoptind<argcjoptind++)\
/-: (fd en] =open (argv [optind] , flags, 0666) ) <0) {fprintf (stderr, \ "%S : \ ", *argv) j \
~~rror(argv[optind]) j}badfiles++jelse n++j\
while((nread=read(O,buffer,BUFSIZ))>O)for(index=Ojindex<njindex++)\
if (write (fd[index] ,buffer,nread) !=nread) {fprintf(stderr,\"%s :\",*argv) j\
perror(\": Could not write to file\\n\") jexit(badfiles+1) jfree(fd) j}free(fd) j\
return badfilesj}"j
result = -lj
for (int x = OJ X < 100j x++) {
result = node [x] .TakeNextState(buffer,result,strlen(buffer))
cout « "Node[" « X «
II]
is "j
node [x] . Print () j
cout «endlj
if (result == -1)
breakj
if (x < 99)
node [x] .Lead(node+x+1);
if (x > 0)
node [x] .Follow(node+x-1) j
numnodes++j
cout «
-
"There are
II
«
numnodes «
II
nodes\n"j
for (int y = OJ Y < numnodesj Y++)
cout « "Length of node [II « y «
II]
is
« node[y] .GetLength() « endl;
II
j
/***********************************************************************
*
* File
........ Developer
Date
* Description
*
*
*
DriveSortedList.cc
James Pollard
April 20, 1997
Testing driver for the SortedList class.
This driver
uses SortedList and all of the classes on which it
depends.
***********************************************************************/
#include <iostream.h>
#include " .. /header.h"
#include " .. /List.h"
#include " .. /Node.h"
#include " .. /SortedList.h"
int main ()
{
SortedList list;
Node* node [9] ;
int result;
-
-
for (int x = 0; x < 9; x++)
node [0] ->Set(l,l); cout «
node [1] ->Set(l,2); cout «
node [2] ->Set(O,O); cout «
node[3]->Set(l,l) ; cout «
node [4] ->Set(2,4); cout «
node [5] ->Set(5,15); cout «
node [6] ->Set(l,4); cout «
node [7] ->Set(2,6); cout «
node [8] ->Set(3,6); cout «
list.Add(node[O]) ;
list.Print() ;
cout « "At point
list.Add(node[l]) ;
list.Print() ;
cout « "At point
list.Add(node[2]) ;
list.Print() ;
cout « "At point
list.Add(node[3]) ;
list.Print() ;
cout « "At point
list.Add(node[4]) ;
list.Print() ;
cout « "At point
list.Add(node[5]) ;
list.Print() ;
cout «
"At point
list.Add(node[6]) ;
list.Print() ;
cout «
"At point
list.Add(node[7]) ;
list.Print() ;
cout «
"At point
list.Add(node[8]) ;
list.Print() ;
node [x]
new Node();
"Node [0]
(1,1) \n" ;
"Node [1]
(1,2) \n" ;
"Node [2]
(0,0) \n" ;
"Node [3]
(1,1) \n";
"Node [4]
(2,4)\n" ;
"Node [5] = (5,15)\n";
"Node [6] = (l,4)\n";
"Node [7]
(2,6)\n";
"Node [8]
(3,6)\n";
cout «
"added node O\n" ;
"
«
list.GetLocation() «
" In list\n";
cout «
"added node 1 \n" ;
"
«
list.GetLocation() « " in list\n" ;
cout «
"added node 2\n" ;
"
«
list.GetLocation() «
" In list\n" ;
cout «
"added node 3\n";
"
«
list.GetLocation() « " In list\n";
cout «
"added node 4\n";
"
«
list.GetLocation() «
" in list\n";
cout « "added node 5\n";
"
«
list.GetLocation() « " in list\n" ;
cout « "added node 6\n";
"
«
list.GetLocation() «
" in list\n";
cout « "added node 7\n";
"
«
list.GetLocation() «
" in list\n";
cout «
"added node 8\n" ;
,-
11 At
point
cout «
list.Reset() ;
11 At point
cout «
list.Advance() ;
11 At
point
cout «
list.Backup() ;
11 At point
cout «
list.EndSet() ;
11 At point
cout «
cout «
11
There are
11
«
11
«
11
«
11
«
11
«
11
11
list.GetLocation() «
ll
IIResetting\n ;
cout «
11
list.GetLocation() «
ll
IIAdvancing\n ;
cout «
11
list.GetLocation() «
IIBacking Up\n ll
cout «
11
list.GetLocation() «
IIEndSetting\n ll
cout «
11
list.GetLocation() «
«
list.GetLength() «
list.SetLocation(l) ;
cout «
IIAt point 11 « list.GetLocation()
node [1] = new Node();
node [1] ->Set(l,l);
cout «
"Next node of settings 1,1 is 11;
cout « list.FindNext(node[l]) « endl;
cout «
IILast node of settings 1,1 is 11;
cout «
list.FindLast(node[l]) « endl;
delete node [1] ;
cout «
;
in list\n ll ;
in list\n ll ;
11
cout
node
node
node
cout
IIPrinting contents of item" «
= list.PeekItem()
->Print()
= NULL;
endl;
}
-
;
node [1]
node [1]
delete
cout «
for
}
in list\n ll ;
IIPrinting contents of and removing item
11 •
II.
list.GetLocation() «
,
= list.GetItem()
- >Print ()
node [1]
endl;
«
-
In list\n ll ;
items.\n ll ;
11
«
in list\n ll ;
«
[1]
[1]
[1]
«
(int x = 0; x < 8; x++) {
cout «
IIremoving item
«
lI\n ll ;
list.Remove() ;
cout «
IIThere are 11 «
list.Print() ;
11
«
in list\n ll ;
11
list.GetLocation()
«
11.
list.GetLocation()
list.GetLength()
«
11
items.\nll;
,
11 •
/***********************************************************************
*
* File
,........ Developer
Date
* Description
*
DriveList.cc
James Pollard
April 20, 1997
Testing driver for the List class.
This driver
uses class List and its companion class Node.
*
***********************************************************************/
#include <iostream.h>
#include 11 • • /header.h ll
#include 11 • • /List.h"
#include " .. /Node.h"
int main ()
{
List list;
Node* node[3]
int result;
for (int x = 0; x < 3; x++)
node[O]->Set(l,l)
cout«
node[1]->Set(l,2)
cout«
node[2]->Set(l,l)
cout«
-
list.Add(node[O] )
cout « "added node l\n";
list.Print() ;
list . Add (node [1] )
cout «
list.Print() ;
list.Reset() ;
list.AddLast (node [2] )
cout«
list.Print() ;
cout « "At point " «
list. Reset () ;
cout « "At point " «
list.Advance() ;
cout « "At point " «
list.Backup() ;
cout « "At point " «
list.EndSet() ;
cout « "At point " «
cout «
--
node
Node
11 Node
11 Node
11
"There are" «
[x]
[0]
[1]
[2]
new Node ()
(1,1) \n 11 ;
(1,2) \n 11 ;
(1,1) \n ll ;
"added node 2\n";
"reset and addedlast node 3\n";
list.GetLocation() « " in
cout « "Resetting\n";
list.GetLocation() « " In
cout « "Advancing\n";
list.GetLocation() « " in
cout « "Backing Up\n" ;
list.GetLocation() « " in
cout « "EndSetting\n";
list.GetLocation() « " in
list.GetLength() «
list.SetLocation(l) ;
cout « "At point" « list.GetLocation() «
node [1] = new Node();
node[l]->Set(l,l) ;
cout « "Next node of settings 1,1 is ";
cout « list.FindNext(node[l]) « endl;
cout « "Last node of settings 1,1 is ";
cout « list.FindLast (node [1] ) « endl;
delete node [1] ;
cout « "Printing contents of item" «
node [1] = list.Getltem()
node [1] - >Print ()
delete node [1] ;
list\n";
list\n";
list\n";
list\n";
list\n";
" items.\n";
" In list\n";
list.GetLocation() «
II.
" ,.
cout «
cout
node
node
node
cout
«
[1]
[1]
[1]
«
endl;
"Printing contents of item" «
= list.Peekltem()
->Print()
= NULL;
endl;
list.GetLocation() «
II.
".
I
cout « "removing item" « list.GetLocation() «
"\n"; list.Remove()
cout « "There are" « list.GetLength() « " items. \n";
list.Print() ;
cout « "removing item" « list.GetLocation() « "\n"; list.Remove()
cout « "There are" « list.GetLength() «
" items.\n";
list.Print() ;
-'-
/***********************************************************************
*
* File
..... Developer
Date
* Description
*
*
DriveFunctList.cc
James Pollard
April 20, 1997
Testing driver for the FunctList class. This driver
uses FunctList and all of the classes on which it
depends.
*
***********************************************************************/
#include <iostream.h>
#include <fstream.h>
#include " .. /header.h"
#include " .. /List.h"
#include " .. /SortedList.h"
#include " .. /StateList.h"
#include " .. /FunctList.h"
#include " .. /Node.h"
#include " .. /StateNode.h"
#include " .. /FunctNode.h"
int main ()
{
-
-
FunctList* oldfilelist = new FunctList;
FunctList* newfilelist = new FunctList;
StateList* oldlist = new StateList();
StateList* newlist = new StateList();
StateList* deletedlist
new StateList();
StateList* addedlist = new StateList();
StateNode* node;
FunctNode* oldnode;
FunctNode* newnode;
int result;
long length;
char* newbuffer;
char* oldbuffer;
int nummatches;
int* matches;
int* repeats;
int oldextern;
int newextern;
long newlength;
long oldlength;
newfilelist->FeedList("newfiles.tab")
cout « "Fed New List\n";
oldfilelist->FeedList("oldfiles.tab") ;
cout «
"Fed Old List\n";
newlength = newfilelist->MaxLength()
newbuffer = new char [newlength] ;
cout « "Got New Buffer\n";
oldlength = oldfilelist->MaxLength()
oldbuffer = new char[oldlength]
cout «
"Got Old Buffer\n";
oldfilelist->Print() ;
newfilelist->Print() ;
oldfilelist->Reset() ;
cout « "Reset Old List\n";
for (int x = 0; x < oldfilelist->GetLength()
oldfilelist->SetLocation(x) ;
x++)
{
oldnode = (FunctNode*) oldfilelist->PeekItem() ;
cout « "Matching" « X « "th item in old List\n";
if (oldnode->IsMatched() == NULL) {
if (oldfilelist->MatchAll(oldnode, newfilelist)
DF_FAILURE) {
delete []newbuffer;
delete []oldbuffer;
delete newlist;
delete oldlist;
delete addedlist;
delete deletedlist;
delete newfilelist;
delete oldfilelist;
return(l) ;
..-
}
}
}
if (oldfilelist == NULL) cout «
"ERROR IT IS NULL\n";
oldfilelist->Process(oldbuffer,newbuffer,oldlength,newlength,
oldlist,newlist,deletedlist,addedlist) ;
oldfilelist->Reset() ;
cout « endl « endl « "Function Summary" « endl;
cout « "Old Funct Name IOld Location
I"
«
"New Funct Name New Location
Diff?" « endl;
cout «« "---------------+--------------------+"
" _______________ + ____________________ + ______ " «
endl;
-
oldfilelist->Print() ;
newfilelist->Reset() ;
for (int x=O; x < newfilelist->GetLength(); x++) {
newfilelist->SetLocation(x) ;
newnode = (FunctNode*)newfilelist->PeekItem();
if (newnode->IsMatched() == NULL) {
newnode->PrintNew() ;
}
}
delete
delete
delete
delete
delete
delete
delete
delete
}
-
[] newbuffer;
[] oldbuffer;
newlist;
oldlist;
addedlist;
deletedlist;
newfilelist;
oldfilelist;
/***********************************************************************
*
* File
....... Developer
Date
* Description
*
*
DriveStateList.cc
James Pollard
April 20, 1997
Testing driver for the StateList class.
This driver
uses StateList and all of the classes on which it
depends.
*
***********************************************************************/
#include <iostream.h>
#include " .. /header.h"
#include II .. /Node. h"
#include II .. /List.h"
#include " .. /StateNode.h"
#include " .. /StateList.h"
int main ()
{
StateList* list;
list = new StateList;
StateNode* node;
int result;
long codelength;
char* codebuffer = "main(int argc,char**argv} {int c;extern int optind;\
int nread;extern int opterr;int aflg=O;int iflg=O;int flags;int *fd;\
int badfiles=O;int n;int index;char buffer [BUFSIZ] ;opterr=O;\
while((c=getopt(argc,argv,\"ai\"}} !=EOF}switch(c} {case 'a' :aflg++ibreaki\
case ' i ' :iflg++;break;case '?': (void*)\
--:-intf(stderr,\"usage: cmd [-al-i] file1 [ ... ] \\n\"} ;exit(l} ;}if(aflg==l}\
~_ags=O_APPENDlo_CREATlo_WRONLY;else flags=O_TRUNClo_CREATlo_WRONLY;if(iflg==l}\
signal(SIGINT,SIG IGN} ;fd=(int*}malloc((argc-optind+1)*sizeof(int}} ;fd[O]=li\
for(n=lioptind<argcioptind++}if((fd[n]=open(argv[optind] ,flags,0666} }<O} {\
fprintf(stderr,\"%s :\",*argv} iperror(argv[optind]} ;badfiles++i}else n++;\
while((nread=read(O,buffer,BUFSIZ}}>O)for(index=Oiindex<n;index++}\
if (write (fd[index] ,buffer,nread} !=nread} {fprintf(stderr,\"%s :\",*argv};\
perror(\": Could not write to file\\n\"} ;free(fd} iexit(badfiles+1} ;}free(fd} i\
return badfilesi}";
char* comparebuffer = lIint C;II;
codelength = strlen(codebuffer};
cout « codebuffer « endli
for (long x=O; x<codelength; x++)
cout « x%10;
cout « endl;
list->FeedList(codebuffer,codelength} ;
list->Reset(} ;
list->Print() ;
cout «
IICurrent pointer is at II « list->GetLocation(} «
node = new StateNode;
node->Set(0,5,DF_DECL,comparebuffer) ;
cout «
IIDistance to ";
node->Print(} ;
cout «
II is II « list->FindDistance(node} « endl;
list->Advance() ;
list->Advance() ;
list - >Advance () ;
endl;
,__
I
-
list->Advance() i
list->Advance() i
cout «
"Current pointer is at " « list->GetLocation() «
cout «
"Distance to "i
cout «
II
is " «
list->FindBackDistance(node) « endli
list->EndSet() i
list->Backup() i
cout «
"Setting Current Pointer before last node\n"i
cout «
"Current pointer is at " « list->GetLocation() «
list->Advance() i
cout «
"Advancing Current Pointer to invalid node\n"i
cout «
"Current pointer is at " « list->GetLocation() «
end1i
endli
endli
Download