|
|
#include "compdir.h"
#define printtext( Text) fprintf( stdout, Text);
#define printstring( String) fprintf( stdout, "%s\n",String);
#define Next( List) ( List == NULL) ? NULL : &(*List).Next
#define CALCULATE_HEIGHT( Node) \
\ if ( (*Node).Left == NULL) \ if ( (*Node).Right == NULL) \ (*Node).Height = 1; \ else \ (*Node).Height = (*(*Node).Right).Height + 1; \ else \ if ( (*Node).Right == NULL) \ (*Node).Height = (*(*Node).Left).Height + 1; \ else \ (*Node).Height = ( (*(*Node).Right).Height > (*(*Node).Left).Height) ? \ (*(*Node).Right).Height + 1 : (*(*Node).Left).Height + 1;
#define ROTATELEFT( List) \
\ LinkedFileList TmpPtr; \ \ TmpPtr = (**List).Right; \ (**List).Right = (*TmpPtr).Left; \ (*TmpPtr).Left = (*List); \ *List = TmpPtr; \ \ if ( (*(**List).Left).Right != NULL) \ (*(**List).Left).Last = (*(*(**List).Left).Right).Last; \ else \ (*(**List).Left).Last = (**List).Left; \ (**List).First = (*(**List).Left).First; \ \ CALCULATE_HEIGHT( (**List).Left); \ \ CALCULATE_HEIGHT(*List);
#define ROTATERIGHT( List) \
\ LinkedFileList TmpPtr; \ \ TmpPtr = (**List).Left; \ (**List).Left = (*TmpPtr).Right; \ (*TmpPtr).Right = (*List); \ *List = TmpPtr; \ \ if ( (*(**List).Right).Left != NULL) \ (*(**List).Right).First = (*(*(**List).Right).Left).First; \ else \ (*(**List).Right).First = (**List).Right; \ (**List).Last = (*(**List).Right).Last; \ \ CALCULATE_HEIGHT( (**List).Right); \ \ CALCULATE_HEIGHT( *List);
#define ROTATEUPLEFT( List) \
\ LinkedFileList TmpPtr; \ \ TmpPtr = (*(**List).Right).Left; \ (*(**List).Right).Left = (*TmpPtr).Right; \ (*TmpPtr).Right = (**List).Right; \ (**List).Right = (*TmpPtr).Left; \ (*TmpPtr).Left = (*List); \ *List = TmpPtr; \ \ if ( (*(**List).Left).Right != NULL) \ (*(**List).Left).Last = (*(*(**List).Left).Right).Last; \ else \ (*(**List).Left).Last = (**List).Left; \ (**List).First = (*(**List).Left).First; \ \ if ( (*(**List).Right).Left != NULL) \ (*(**List).Right).First = (*(*(**List).Right).Left).First; \ else \ (*(**List).Right).First = (**List).Right; \ (**List).Last = (*(**List).Right).Last; \ \ CALCULATE_HEIGHT( (**List).Left); \ \ CALCULATE_HEIGHT( (**List).Right); \ \ CALCULATE_HEIGHT( *List);
#define ROTATEUPRIGHT( List) \
\ LinkedFileList TmpPtr; \ \ TmpPtr = (*(**List).Left).Right; \ (*(**List).Left).Right = (*TmpPtr).Left; \ (*TmpPtr).Left = (**List).Left; \ (**List).Left = (*TmpPtr).Right; \ (*TmpPtr).Right = (*List); \ *List = TmpPtr; \ \ if ( (*(**List).Right).Left != NULL) \ (*(**List).Right).First = (*(*(**List).Right).Left).First; \ else \ (*(**List).Right).First = (**List).Right; \ (**List).Last = (*(**List).Right).Last; \ \ if ( (*(**List).Left).Right != NULL) \ (*(**List).Left).Last = (*(*(**List).Left).Right).Last; \ else \ (*(**List).Left).Last = (**List).Left; \ (**List).First = (*(**List).Left).First; \ \ CALCULATE_HEIGHT( (**List).Right); \ \ CALCULATE_HEIGHT( (**List).Left); \ \ CALCULATE_HEIGHT( *List);
//
// Walk down list and add Nodes
//
BOOL AddToList( LinkedFileList Node, LinkedFileList *List) { int Result; BOOL Changed = FALSE; BOOL ChangedVal = FALSE;
//
// If Node is empty do nothing
//
if ( Node == NULL) { return Changed; } //
// If list is empty just point to Node
//
if ( *List == NULL) { *List = Node; Changed = TRUE;
//
// Otherwise go down the list and add
// in sorted order
//
} else { Result = _stricmp( (*Node).Name, (**List).Name);
if ( Result < 0) {
if ( (**List).Left == NULL) { (**List).Left = Node; (**List).First = (*Node).First; (*(*Node).Last).Next = *List; Changed = TRUE; CALCULATE_HEIGHT(*List);
} else { ChangedVal = AddToList( Node, &(**List).Left); if ( ChangedVal) { if ( (**List).First != (*(**List).Left).First) { Changed = TRUE; (**List).First = (*(**List).Left).First; } if ( (*(*(**List).Left).Last).Next != *List) { Changed = TRUE; (*(*(**List).Left).Last).Next = *List; } } Result = (**List).Height; CALCULATE_HEIGHT( *List); if ( (**List).Height != Result) { Changed = TRUE; } } if ( Changed) { if ( (**List).Right == NULL) { if ( (*(**List).Left).Height > 1 ) { if ( (*(**List).Left).Left == NULL ) { ROTATEUPRIGHT( List); Changed = TRUE;
} else { ROTATERIGHT( List); Changed = TRUE; } }
} else if ( ( (*(**List).Left).Height - (*(**List).Right).Height) > 1) { ROTATERIGHT( List); Changed = TRUE; } } } else if ( Result > 0) { if ( (**List).Right == NULL) {
(**List).Right = Node; (**List).Next = (*Node).First; (**List).Last = (*Node).Last; Changed = TRUE; CALCULATE_HEIGHT( *List);
} else { ChangedVal = AddToList( Node, &(**List).Right); if ( ChangedVal) { if ( (**List).Next != (*(**List).Right).First) { Changed = TRUE; (**List).Next = (*(**List).Right).First; } if ( (**List).Last != (*(**List).Right).Last) { Changed = TRUE; (**List).Last = (*(**List).Right).Last; } } Result = (**List).Height; CALCULATE_HEIGHT( *List); if ( (**List).Height != Result) { Changed = TRUE; } } if ( Changed) { if ( (**List).Left == NULL) { if ( (*(**List).Right).Height > 1 ) { if ( (*(**List).Right).Right == NULL ) { ROTATEUPLEFT( List); Changed = TRUE;
} else { ROTATELEFT( List); Changed = TRUE; } } } else if ( ( (*(**List).Right).Height - (*(**List).Left).Height) > 1) { ROTATELEFT( List); Changed = TRUE; } }
} else if ( Result == 0) { // Don't add if already here
}
}
return Changed;
} /* AddToList */
LPSTR CombineThreeStrings( char *FirstString, char *SecondString, char *ThirdString) { char *String;
String = malloc( strlen( FirstString) + strlen( SecondString) + strlen( ThirdString) + 1); if ( String == NULL) { OutOfMem(); }
strcpy( String, FirstString); strcpy( &(String[strlen( FirstString)]), SecondString); strcpy( &(String[strlen( FirstString) + strlen( SecondString)]), ThirdString);
return( String);
} /* CombineThreeStrings */
void CreateNode( LinkedFileList *Node, WIN32_FIND_DATA *Buff) { (*Node) = malloc( sizeof( struct NodeStruct)); if ( (*Node) == NULL) { OutOfMem(); } (**Node).Name = _strrev( _strdup( (*Buff).cFileName)); if ( (**Node).Name == NULL) { OutOfMem(); } if ( !fDontLowerCase) { _strlwr( (**Node).Name); } strcpy( (**Node).Flag, ""); (**Node).Attributes = (*Buff).dwFileAttributes; if ( (*Buff).dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { strcpy( (**Node).Flag, "DIR"); } (**Node).SizeHigh = (*Buff).nFileSizeHigh; (**Node).SizeLow = (*Buff).nFileSizeLow; (**Node).Time.dwLowDateTime = (*Buff).ftLastWriteTime.dwLowDateTime; (**Node).Time.dwHighDateTime = (*Buff).ftLastWriteTime.dwHighDateTime; (**Node).First = (*Node); (**Node).Last = (*Node); (**Node).Left = NULL; (**Node).Next = NULL; (**Node).Process = ProcessModeDefault; (**Node).Right = NULL; (**Node).DiffNode = NULL; (**Node).Height = 1;
} /* CreateNode */
void CreateNameNode( LinkedFileList *Node, char *Name) { (*Node) = malloc( sizeof( struct NodeStruct)); if ( (*Node) == NULL) { OutOfMem(); } (**Node).Name = _strdup( Name); if ( (**Node).Name == NULL) { OutOfMem(); } if ( !fDontLowerCase) { _strlwr( (**Node).Name); } strcpy( (**Node).Flag, ""); (**Node).Attributes = 0; (**Node).SizeHigh = 0; (**Node).SizeLow = 0; (**Node).Time.dwLowDateTime = 0; (**Node).Time.dwHighDateTime = 0; (**Node).First = (*Node); (**Node).Last = (*Node); (**Node).Left = NULL; (**Node).Next = NULL; (**Node).Process = TRUE; (**Node).Right = NULL; (**Node).DiffNode = NULL; (**Node).Height = 1;
} /* CreateNode */
void DuplicateNode( LinkedFileList FirstNode, LinkedFileList *SecondNode) { (*SecondNode) = malloc( sizeof( struct NodeStruct)); if ( (*SecondNode) == NULL) { OutOfMem(); } (**SecondNode).Name = _strdup( (*FirstNode).Name); if ( (**SecondNode).Name == NULL) { OutOfMem(); } if ( !fDontLowerCase) { _strlwr( (**SecondNode).Name); } strcpy( (**SecondNode).Flag, (*FirstNode).Flag); (**SecondNode).Attributes = (*FirstNode).Attributes; (**SecondNode).SizeHigh = (*FirstNode).SizeHigh; (**SecondNode).SizeLow = (*FirstNode).SizeLow; (**SecondNode).Time.dwLowDateTime = (*FirstNode).Time.dwLowDateTime; (**SecondNode).Time.dwHighDateTime = (*FirstNode).Time.dwHighDateTime; (**SecondNode).First = (*SecondNode); (**SecondNode).Last = (*SecondNode); (**SecondNode).Left = NULL; (**SecondNode).Next = NULL; (**SecondNode).Process = ProcessModeDefault; (**SecondNode).Right = NULL; (**SecondNode).DiffNode = NULL; (**SecondNode).Height = 0;
} // DuplicateNode
LinkedFileList *FindInList( char *Name, LinkedFileList *List) { int Result; LinkedFileList *tmpptr = List;
while ( *tmpptr != NULL) { Result = _stricmp( (**tmpptr).Name, Name); if ( Result == 0) { return tmpptr; } if ( Result > 0) { tmpptr = &(**tmpptr).Left; } if ( Result < 0) { tmpptr = &(**tmpptr).Right; } } return NULL;
} /* FindInList */
BOOL FindInMatchListTop( char *Name, LinkedFileList *List) { int Result; LinkedFileList *tmpptr = List;
while ( *tmpptr != NULL) { Result = _stricmp( (**tmpptr).Name, Name); if ( Result == 0) { return TRUE; } if ( strchr( (**tmpptr).Name, '*') != NULL) { if ( Match( (**tmpptr).Name, Name)) { return TRUE; } } if ( Result > 0) { tmpptr = &(**tmpptr).Left; } if ( Result < 0) { tmpptr = &(**tmpptr).Right; } } return FALSE;
} /* FindInList */
BOOL FindInMatchListFront( char *Name, LinkedFileList *List) { LinkedFileList *tmpptr = List;
if ( *tmpptr != NULL) { tmpptr = &(**tmpptr).First; }
while ( *tmpptr != NULL) { if ( Match( (**tmpptr).Name, Name)) { return TRUE; }
tmpptr = &(**tmpptr).Next; } return FALSE;
} /* FindInList */
//
// Walk down list and free each entry
//
void FreeList( LinkedFileList *List) { if ( (*List) != NULL) { FreeList( &(**List).Left); FreeList( &(**List).Right); FreeList( &(**List).DiffNode); free( (**List).Name); free( *List); }
} // FreeList
void PrintTree( LinkedFileList List, int Level) { int Counter = 0;
if ( List == NULL) { return; }
PrintTree( (*List).Right, Level + 1);
while ( Counter++ < Level) { fprintf( stdout, " "); }
fprintf( stdout, "%s %d\n", (*List).Name, (*List).Height);
PrintTree( (*List).Left, Level + 1);
} // Print Tree
//
// This function is is the same as strcat except
// that it does the memory allocation for the string
//
LPSTR MyStrCat( char *FirstString, char *SecondString) { char *String;
String = malloc( strlen( FirstString) + strlen( SecondString) + 1); if ( String == NULL) { OutOfMem(); }
strcpy( String, FirstString); strcpy( &(String[strlen( FirstString)]), SecondString);
return( String);
} /* MyStrCat */
BOOL Match( char *Pat, char* Text) { switch ( *Pat) { case '\0': return *Text == '\0'; case '?': return *Text != '\0' && Match( Pat + 1, Text + 1); case '*': do { if ( Match( Pat + 1, Text)) { return TRUE; } } while ( *Text++); return FALSE; default: return toupper( *Text) == toupper( *Pat) && Match( Pat + 1, Text + 1); }
} /* Match */
/*
LinkedFileList *Next( LinkedFileList List) { if ( List == NULL) { return NULL; }
return &(*List).Next;
} /* /* Next */
void OutOfMem( void) { fprintf( stderr, "-out of memory-\n"); exit(1);
} // OutOfMem
|