/*********************************************************************** * 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