Mail Archives: djgpp/2013/03/23/06:15:20
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-bounces using -f
|
X-Received: | by 10.224.185.79 with SMTP id cn15mr2026319qab.4.1364032694846;
|
| Sat, 23 Mar 2013 02:58:14 -0700 (PDT)
|
X-Received: | by 10.49.84.35 with SMTP id v3mr323767qey.16.1364032694818; Sat,
|
| 23 Mar 2013 02:58:14 -0700 (PDT)
|
Newsgroups: | comp.os.msdos.djgpp
|
Date: | Sat, 23 Mar 2013 02:58:14 -0700 (PDT)
|
Complaints-To: | groups-abuse AT google DOT com
|
Injection-Info: | glegroupsg2000goo.googlegroups.com; posting-host=2.173.27.66; posting-account=v5xbdQoAAAAOGc9Ccc-kLZyobvPlN3Qr
|
NNTP-Posting-Host: | 2.173.27.66
|
User-Agent: | G2/1.0
|
MIME-Version: | 1.0
|
Message-ID: | <261476b1-c137-495d-95df-a92075cd9960@googlegroups.com>
|
Subject: | DJGPP scandir and alphasort example code
|
From: | Georg Potthast <dosusb AT googlemail DOT com>
|
Injection-Date: | Sat, 23 Mar 2013 09:58:14 +0000
|
Bytes: | 6238
|
Lines: | 199
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Reply-To: | djgpp AT delorie DOT com
|
- DJGPP scandir and alphasort example code -
I was converting a program from Linux to DOS and this frequently used the scandir command. AFAIK this is not available with djgpp and so I wrote that function myself with help of examples I found via Google.
Since I assume this command may be of interest to other programmers too I post it here. HTH
1. First the libscandir.a library:
Compile with:
gcc -g -s -c libscandir.c
ar rcs libscandir.a libscandir.o
#include <stdio.h>
#include <string.h>
#include <glob.h>
#include <sys/types.h>
#include <stdlib.h>
#include <malloc.h>
#include <dirent.h>
#include <limits.h>
/* Alphabetic order comparison routine */
int alphasort(const void *d1, const void *d2)
{
return(strcmp((*(struct dirent **)d1)->d_name,
(*(struct dirent **)d2)->d_name));
}
/*
arg1 = directory name
arg2 = unallocated array of pointers to dirent(direct) strctures
arg3 = pointer to function to specify which files to include
arg4 = pointer to sorting function to qsort, e.g. alphasort
*/
int scandir(char *dirname, struct dirent *(*namelist[]),
int (*sd_select)(const struct dirent *), int (*dcomp)(const void *, const void *))
{
DIR *dirptr;
struct dirent *dir_entry;
int tdirsize = sizeof(struct dirent);
register int i=0;
int si=0;
size_t cnt;
glob_t glob_results;
char *wildcard;
char *wildcardpos;
wildcard=calloc(_POSIX_PATH_MAX,sizeof(char));
if ((dirptr = opendir(dirname)) == NULL)
return -1;
//read number of entries in directory
strcpy(wildcard,dirname);
//remove trailing slash
wildcardpos=strrchr(wildcard,'\\');
if (strlen(wildcardpos)==strlen(wildcard)) wildcard[strlen(wildcard)-1]='\0';
//add * for all entries
strcat(wildcard,"\\*");
if(glob(wildcard, GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_NOSORT, NULL, &glob_results) == 0)
cnt = glob_results.gl_pathc +2; //add two for . and ..
globfree(&glob_results);
free(wildcard);
//dynamic tdir array allocation
static struct dirent *tdir;
tdir = (struct dirent*) calloc(cnt,sizeof(struct dirent));
if ((*namelist = (struct dirent **) calloc(cnt, sizeof(struct dirent *)))
== NULL)
return -1;
if ((dir_entry = (struct dirent *) malloc(tdirsize + _POSIX_PATH_MAX)) == NULL)
return -1;
while (dir_entry = readdir(dirptr)) {
if (sd_select == NULL){
si=1; //no select routine specified, return all
} else {
si = sd_select(dir_entry);
}
if (si) {
if (((*namelist)[i] = (struct dirent *)
malloc(tdirsize + _POSIX_PATH_MAX)) == NULL)
return -1;
memcpy((*namelist)[i], dir_entry, sizeof(dir_entry)+_POSIX_PATH_MAX);
i++;
}
}
if (dcomp != NULL)
qsort((char *) &((*namelist)[0]), i, sizeof(struct dirent *), dcomp);
return i;
}
2. the header file for this library:
#ifndef scandir_h
#define scandir_h
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <stdlib.h>
#include <malloc.h>
#include <dirent.h>
#include <limits.h>
/* example select routine */
#if 0
int sd_select(struct dirent *entry)
//remove . and .. from directory list
{ if ((strcmp(entry->d_name,".") == 0) ||
(strcmp(entry->d_name,"..") == 0))
{
return (0);
} else {
return (1);
}
}
#endif
/* Alphabetic order comparison routine */
int alphasort(const void *d1, const void *d2);
/*
* rewrite of BSD scandir.
* arg1 = directory name
* arg2 = unallocated array of pointers to dirent(direct) strctures
* arg3 = specifier for which objects to pick (pointer to function)
* arg4 = sorting function pointer to pass to qsort
*/
int scandir(char *dirname, struct dirent *(*namelist[]),
int (*sd_select)(const struct dirent *), int (*dcomp)(const void *, const void *));
#ifdef __cplusplus
}
#endif
#endif //!scandir_h
3. a test program for this libary:
if all files are in one directory compile with:
gcc -g scandirtest.c -o scandirtest.exe libscandir.a
or copy libscandir.a into djgpp\lib and scandir.h into djgpp\include:
gcc -g scandirtest.c -o scandirtest.exe -lscandir
(you then would use #include <scandir.h> below instead)
#include <stdio.h>
#include <string.h>
#include "scandir.h"
/* select routine */
int sd_select(const struct dirent *entry)
//remove . and .. from directory list
{ if ((strcmp(entry->d_name,".") == 0) ||
(strcmp(entry->d_name,"..") == 0))
{
return (0);
} else {
return (1);
}
}
int main(void)
{
struct dirent **namelist;
int n,i;
/* all entries in current directory unsorted */
//n = scandir((char*)".", &namelist, 0, 0);
/* all entries in current directory sorted */
//n = scandir((char*)".", &namelist, 0, alphasort);
/* all entries in root sorted with "." and ".." entries removed*/
n = scandir((char*)"/", &namelist, sd_select, alphasort);
if (n < 0)
perror("scandir");
else {
for(i = 0; i < n; i++) {
printf("%02d: %s\n", i+1, namelist[i]->d_name);
}
//release memory allocated
while (n--) {
free(namelist[n]);
}
free(namelist);
}
}
- Raw text -