This is DirMgr.c in view mode; [Download] [Up]
/****************************************************************************
DirMgr.c
This file contains the C code to implement the DirectoryMgr system.
This system is intended to manage filtered and sorted directory
lists.
****************************************************************************/
/*
* Author:
* Brian Totty
* Department of Computer Science
* University Of Illinois at Urbana-Champaign
* 1304 West Springfield Avenue
* Urbana, IL 61801
*
* totty@cs.uiuc.edu
*
* (Sep 5, 1995: bugfix by Bert Bos <bert@let.rug.nl>, search for [BB])
* (Apr 7, 1997: changed NO_REGEXP into !HAVE_REGEXP_H and autoconf.h added
* by Ettore Perazzoli <ettore@comm2000.it>)
* (Apr 7, 1997: fixed behavior when regexp.h is not available by Ettore
* Perazzoli <ettore@comm2000.it>, search for [EP])
* (May 4, 1997: miscellaneous fixes by Ettore Perazzoli <ettore@comm2000.it>,
* search for [EP])
* (Mar 19, 1998: disabled usage of regexp.h on {Free,Net}BSD. Ettore
* Perazzoli <ettore@comm2000.it>, search for [EP])
*/
#include "config.h"
#include <stdlib.h> /* [EP] 05/04/97 */
#include "DirMgr.h"
#include "RegExp.h"
/*---------------------------------------------------------------------------*
S I M P L E I N T E R F A C E
*---------------------------------------------------------------------------*/
DirectoryMgr *DirectoryMgrSimpleOpen(path,sort_type,pattern)
char *path;
int sort_type;
char *pattern;
{
DirectoryMgr *dm;
PFI f_func,s_func;
fwf_regex_t f_data;
if (pattern == NULL) pattern = "*";
if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func, &f_data))
{
return(NULL);
}
if (!DirectoryMgrSimpleSortingFunc(sort_type,&s_func))
{
RegExpFree(&f_data);
return(NULL);
}
dm = DirectoryMgrOpen(path,s_func,f_func,&f_data,TRUE);
return(dm);
} /* End DirectoryMgrSimpleOpen */
int DirectoryMgrSimpleRefilter(dm,pattern)
DirectoryMgr *dm;
char *pattern;
{
PFI f_func;
fwf_regex_t f_data;
if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
{
return(FALSE);
}
DirectoryMgrRefilter(dm,f_func, &f_data,TRUE);
return(TRUE);
} /* End DirectoryMgrSimpleRefilter */
int DirectoryMgrSimpleResort(dm,sort_type)
DirectoryMgr *dm;
int sort_type;
{
PFI c_func;
if (!DirectoryMgrSimpleSortingFunc(sort_type,&c_func))
{
return(FALSE);
}
DirectoryMgrResort(dm,c_func);
return(TRUE);
} /* End DirectoryMgrSimpleResort */
/*---------------------------------------------------------------------------*
N O R M A L I N T E R F A C E
*---------------------------------------------------------------------------*/
int DirectoryMgrCanOpen(path)
char *path;
{
int status;
Directory dir;
status = DirectoryOpen(path,&dir);
if (status == TRUE) DirectoryClose(&dir);
return(status);
} /* End DirectoryMgrCanOpen */
DirectoryMgr *DirectoryMgrOpen(path,c_func,f_func,f_data,free_data)
char *path;
PFI c_func,f_func;
fwf_regex_t *f_data;
int free_data;
{
DirectoryMgr *dm;
dm = (DirectoryMgr *)calloc(1,sizeof(DirectoryMgr));
if (dm == NULL)
{
fprintf(stderr,"DirectoryMgrOpen: out of memory\n");
if (free_data)
RegExpFree(f_data);
return(NULL);
}
if (DirectoryOpen(path,DirectoryMgrDir(dm)) == FALSE)
{
fprintf(stderr,"DirectoryMgrOpen: can't open dir '%s'\n",
DirectoryMgrDir(dm)->path); /* [EP] 05/04/97 */
free(dm);
RegExpFree(f_data);
return(NULL);
}
DirectoryMgrCompFunc(dm) = c_func;
DirectoryMgrRefilter(dm,f_func,f_data,free_data);
return(dm);
} /* End DirectoryMgrOpen */
void DirectoryMgrClose(dm)
DirectoryMgr *dm;
{
free(DirectoryMgrData(dm));
free(DirectoryMgrSortedPtrs(dm));
if (DirectoryMgrFreeFilterData(dm))
{
RegExpFree(&DirectoryMgrFilterData(dm));
}
DirectoryClose(DirectoryMgrDir(dm));
free(dm);
} /* End DirectoryMgrClose */
int DirectoryMgrRefilter(dm,f_func,f_data,f_free)
DirectoryMgr *dm;
PFI f_func;
fwf_regex_t *f_data;
int f_free;
{
if (DirectoryMgrFreeFilterData(dm))
{
RegExpFree(&DirectoryMgrFilterData(dm));
}
DirectoryMgrFilterFunc(dm) = f_func;
DirectoryMgrFilterData(dm) = *f_data;
DirectoryMgrFreeFilterData(dm) = f_free;
DirectoryMgrRefresh(dm);
return 0; /* [EP] 05/04/97 */
} /* End DirectoryMgrRefilter */
int DirectoryMgrRefresh(dm)
DirectoryMgr *dm;
{
int err,data_size,ptrs_size,i;
DirEntryCons *head,*tail,*cons;
DirEntry *dm_data,**dm_ptrs;
PFI f_func;
fwf_regex_t *f_data;
tail = NULL; /* make compiler happy [EP] 05/04/97 */
DirectoryMgrTotalCount(dm) = 0;
DirectoryMgrFilteredCount(dm) = 0;
DirectoryRestart(DirectoryMgrDir(dm));
if (DirectoryMgrData(dm)) free(DirectoryMgrData(dm));
if (DirectoryMgrSortedPtrs(dm)) free(DirectoryMgrSortedPtrs(dm));
head = NULL;
f_func = DirectoryMgrFilterFunc(dm);
f_data = &DirectoryMgrFilterData(dm);
while (1)
{
cons = (DirEntryCons *)malloc(sizeof(DirEntryCons));
if (cons == NULL)
{
fprintf(stderr,
"DirectoryMgrRefresh: Can't Alloc Cons\n");
exit(-1);
}
err = DirectoryReadNextEntry(DirectoryMgrDir(dm),
&(cons->dir_entry));
if (err == FALSE)
{
free(cons);
break;
}
++ DirectoryMgrTotalCount(dm);
if ((f_func == NULL) ||
/* the next line make directories always
appear, even if pattern is applied, AF 23jun98 */
(DirEntryType(&cons->dir_entry) == F_TYPE_DIR) ||
(f_func && f_func(&(cons->dir_entry),f_data)))
{
cons->next = NULL;
if (head == NULL)
head = cons;
else
tail->next = cons;
tail = cons;
++ DirectoryMgrFilteredCount(dm);
}
else /* Filter Failed */
{
free(cons);
}
}
data_size = sizeof(DirEntry) * DirectoryMgrFilteredCount(dm);
ptrs_size = sizeof(DirEntry *) * DirectoryMgrFilteredCount(dm);
dm_data = (DirEntry *)malloc(data_size);
dm_ptrs = (DirEntry **)malloc(ptrs_size);
/*
* BUGFIX: Next line changed from:
* if ((dm_data == NULL) || (dm_ptrs == NULL))
* after a bug report by Andrew Robinson, Feb 13, '95 [BB]
*/
if (((dm_data == NULL) && (data_size > 0))
|| ((dm_ptrs == NULL) && (ptrs_size > 0)))
{
fprintf(stderr,"DirectoryMgrRefresh: Out of memory\n");
exit(1);
}
DirectoryMgrData(dm) = dm_data;
DirectoryMgrSortedPtrs(dm) = dm_ptrs;
for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
{
DirectoryMgrData(dm)[i] = head->dir_entry;
DirectoryMgrSortedPtrs(dm)[i] = &(DirectoryMgrData(dm)[i]);
cons = head->next;
free(head);
head = cons;
}
DirectoryMgrResort(dm,DirectoryMgrCompFunc(dm));
DirectoryMgrRestart(dm);
return(TRUE);
} /* End DirectoryMgrRefresh */
void DirectoryMgrResort(dm,c_func)
DirectoryMgr *dm;
PFI c_func;
{
DirectoryMgrCompFunc(dm) = c_func;
if (c_func != NULL)
{
qsort(DirectoryMgrSortedPtrs(dm),DirectoryMgrFilteredCount(dm),
sizeof(DirEntry *),DirectoryMgrCompFunc(dm));
}
DirectoryMgrRestart(dm);
} /* End DirectoryMgrResort */
/*---------------------------------------------------------------------------*
I T E R A T I O N C O M M A N D S
*---------------------------------------------------------------------------*/
int DirectoryMgrGotoItem(dm,i)
DirectoryMgr *dm;
int i;
{
if (i < 0 || i >= DirectoryMgrFilteredCount(dm)) return(FALSE);
DirectoryMgrCurrentIndex(dm) = i;
return(TRUE);
} /* End DirectoryMgrGotoItem */
int DirectoryMgrGotoNamedItem(dm,name)
DirectoryMgr *dm;
char *name;
{
int i;
DirEntry *entry;
for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
{
entry = DirectoryMgrSortedPtrs(dm)[i];
if (strcmp(DirEntryFileName(entry),name) == 0)
{
DirectoryMgrCurrentIndex(dm) = i;
return(TRUE);
}
}
return(FALSE);
} /* End DirectoryMgrGotoNamedItem */
void DirectoryMgrRestart(dm)
DirectoryMgr *dm;
{
DirectoryMgrCurrentIndex(dm) = 0;
} /* End DirectoryMgrRestart */
DirEntry *DirectoryMgrCurrentEntry(dm)
DirectoryMgr *dm;
{
int index;
index = DirectoryMgrCurrentIndex(dm);
if (index < 0 || index >= DirectoryMgrFilteredCount(dm)) return(NULL);
return(DirectoryMgrSortedPtrs(dm)[index]);
} /* End DirectoryMgrCurrentEntry */
DirEntry *DirectoryMgrNextEntry(dm)
DirectoryMgr *dm;
{
int index;
index = DirectoryMgrCurrentIndex(dm);
if (index >= DirectoryMgrFilteredCount(dm)) return(NULL);
++ DirectoryMgrCurrentIndex(dm);
return(DirectoryMgrSortedPtrs(dm)[index]);
} /* End DirectoryMgrNextEntry */
DirEntry *DirectoryMgrPrevEntry(dm)
DirectoryMgr *dm;
{
int index;
index = DirectoryMgrCurrentIndex(dm) - 1;
if (index < 0) return(NULL);
-- DirectoryMgrCurrentIndex(dm);
return(DirectoryMgrSortedPtrs(dm)[index]);
} /* End DirectoryMgrPrevEntry */
/*---------------------------------------------------------------------------*
U T I L I T Y F U N C T I O N S
*---------------------------------------------------------------------------*/
int DirectoryMgrSimpleFilterFunc(pattern,ff_ptr,fd_ptr)
char *pattern;
PFI *ff_ptr;
fwf_regex_t *fd_ptr;
{
char regexp[2048];
*ff_ptr = DirectoryMgrFilterName;
RegExpInit(fd_ptr);
RegExpPatternToRegExp(pattern, regexp);
RegExpCompile(regexp, fd_ptr);
return(TRUE);
} /* End DirectoryMgrSimpleFilterFunc */
int DirectoryMgrSimpleSortingFunc(sort_type,sf_ptr)
int sort_type;
PFI *sf_ptr;
{
*sf_ptr = NULL;
switch (sort_type)
{
case DIR_MGR_SORT_NONE:
break;
case DIR_MGR_SORT_NAME:
*sf_ptr = DirectoryMgrCompareName;
break;
case DIR_MGR_SORT_SIZE_ASCENDING:
*sf_ptr = DirectoryMgrCompareSizeAscending;
break;
case DIR_MGR_SORT_SIZE_DESCENDING:
*sf_ptr = DirectoryMgrCompareSizeDescending;
break;
case DIR_MGR_SORT_NAME_DIRS_FIRST:
*sf_ptr = DirectoryMgrCompareNameDirsFirst;
break;
case DIR_MGR_SORT_ACCESS_ASCENDING:
*sf_ptr = DirectoryMgrCompareLastAccessAscending;
break;
case DIR_MGR_SORT_ACCESS_DESCENDING:
*sf_ptr = DirectoryMgrCompareLastAccessDescending;
break;
default:
fprintf(stderr,"Bad sort type %d\n",sort_type);
return(FALSE);
}
return(TRUE);
} /* End DirectoryMgrSimpleSortingFunc */
/*---------------------------------------------------------------------------*
S O R T I N G R O U T I N E S
*---------------------------------------------------------------------------*/
int DirectoryMgrCompareName(e1p,e2p)
DirEntry **e1p,**e2p;
{
return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
} /* End DirectoryMgrCompareName */
int DirectoryMgrCompareNameDirsFirst(e1p,e2p)
DirEntry **e1p,**e2p;
{
if (DirEntryLeadsToDir(*e1p))
{
if (!DirEntryLeadsToDir(*e2p)) return(-1);
}
else if (DirEntryLeadsToDir(*e2p))
{
return(1);
}
return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
} /* End DirectoryMgrCompareNameDirsFirst */
int DirectoryMgrCompareSizeAscending(e1p,e2p)
DirEntry **e1p,**e2p;
{
if (DirEntryFileSize(*e1p) < DirEntryFileSize(*e2p))
return (-1);
else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
return (0);
else
return (1);
} /* End DirectoryMgrCompareSizeAscending */
int DirectoryMgrCompareSizeDescending(e1p,e2p)
DirEntry **e1p,**e2p;
{
if (DirEntryFileSize(*e1p) > DirEntryFileSize(*e2p))
return (-1);
else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
return (0);
else
return (1);
} /* End DirectoryMgrCompareSizeDescending */
int DirectoryMgrCompareLastAccessAscending(e1p,e2p)
DirEntry **e1p,**e2p;
{
return((long)DirEntryLastAccess(*e1p) >
(long)DirEntryLastAccess(*e2p));
} /* End DirectoryMgrCompareLastAccessAscending */
int DirectoryMgrCompareLastAccessDescending(e1p,e2p)
DirEntry **e1p,**e2p;
{
return((long)DirEntryLastAccess(*e1p) <
(long)DirEntryLastAccess(*e2p));
} /* End DirectoryMgrCompareLastAccessDescending */
/*---------------------------------------------------------------------------*
F I L T E R R O U T I N E S
*---------------------------------------------------------------------------*/
int DirectoryMgrFilterName(de,fsm)
DirEntry *de;
fwf_regex_t *fsm;
{
return(RegExpMatch(DirEntryFileName(de), fsm));
} /* End DirectoryMgrFilterName */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.