1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
#ifndef LINT
/* @(#) makelist.c 2.3 88/01/24 12:46:44 */
static char sccsid[]="@(#) makelist.c 2.3 88/01/24 12:46:44";
#endif /* LINT */
/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
(C) Copyright 1988 Rahul Dhesi -- All rights reserved
*/
#include "options.h"
#include "portable.h"
#include "errors.i"
#include "zoo.h"
#include "zooio.h"
#include "various.h"
#include "zoofns.h"
#include "assert.h"
#include "debug.h"
char *nameptr PARMS((char *));
void modpath PARMS((char *));
int isadir PARMS((ZOOFILE));
int isfdir PARMS((char *));
/*******************/
/*
makelist() gets all pathnames corresponding to a set of filespecs and
adds them to a list. Not more than "flistsize" pathnames are added.
Into `longest' it returns the length of the longest name added, or
zero if none added.
Files ignore1, ignore2, and ignore3 are not added to the list.
A file that is a device/directory is also not added to the list.
However, if ignore1 is NULL, both these tests are skipped and all files
will be added to the list.
*/
void makelist (argc, argv, flist, flistsize, ignore1, ignore2, ignore3, longest)
int argc; /* number of filespec supplied */
char *argv[]; /* array of pointers to supplied filespecs */
register char *flist[]; /* array of pointers to filenames we will add */
int flistsize; /* home many names we can use */
char *ignore1, *ignore2, *ignore3; /* files to exclude from list */
int *longest; /* length of longest name in list */
{
char *this_path; /* current pathname */
int fptr; /* pointer to within flist */
register int i, j; /* loop counters */
#ifdef WILDCARD
char *pat_name; /* filename part of pattern */
#endif
int gap; /* for Shell sort */
flistsize--; /* allow for one terminating NULL entry */
fptr = *longest = 0;
assert(argc > 0);
#define WCLEN 4 /* length needed for wildcard, and a little extra */
while (argc > 0) {
#ifdef WILDCARD
int argok = 0; /* arg not matched yet */
#endif
char *this_arg;
this_arg = emalloc (strlen (*argv) + WCLEN);
strcpy (this_arg, *argv);
/* Initialize fileset 0. Select all files -- we will later
filter out the ones wanted */
#ifdef FOLD
str_lwr (this_arg);
#endif
#ifdef WILDCARD
pat_name = str_dup (nameptr (this_arg)); /* pattern without path */
#ifdef VER_CH /* trailing version field */
{
static char version_field[] = " *";
char *p;
p = strrchr (pat_name, VER_CH);
if (p == NULL) {
*version_field = VER_CH;
pat_name = newcat (pat_name, version_field); /* adds trailing ";*" */
}
}
#endif
/*
replace filename by wildcard; however, if argument ends in slash,
then simply append wildcard so we get all files in that directory
*/
#ifdef FORCESLASH
fixslash (this_arg); /* convert backslashes to slashes */
#endif
if (*lastptr(this_arg) == *(char *) PATH_CH) {
strcat (this_arg, WILDCARD);
pat_name = "*"; /* and select all files */
} else
#ifdef SPEC_WILD
spec_wild (this_arg);
#else
strcpy (nameptr (this_arg), WILDCARD);
#endif /* SPEC_WILD */
#endif /* WILDCARD */
nextfile (0, this_arg, 0);
while (fptr < flistsize &&
(this_path = nextfile(1, (char *) NULL, 0)) != NULL) {
char *this_name = nameptr (this_path);
modpath (this_path); /* do any needed changes to path */
#ifdef IGNORECASE
#define COMPARE str_icmp
#else
#define COMPARE strcmp
#endif
if (ignore1 != NULL) {
if (samefile (this_name,ignore1) || /* exclude ignored files */
samefile (this_name,ignore2) ||
samefile (this_name,ignore3))
continue;
#ifdef CHEKUDIR
if (isuadir(this_path))
continue;
#else /* CHEKUDIR */
# ifdef CHEKDIR
if (isfdir(this_path))
continue;
# endif /* CHEKDIR */
#endif /* CHEKUDIR */
} /* end if ignore1 ! = NULL */
/*
If WILDCARD is defined (e.g. AmigaDOS, MS-DOS, VAX/VMS), then nextfile()
returns all filenames and we must now select the ones we need by pattern
matching. If WILDCARD is not defined (e.g. **IX), filenames have already been
selected by the shell and need not be tested again.
*/
#ifdef WILDCARD
if (match_half (this_name,pat_name) ||
match_half (pat_name, "?-?") && /* character range */
*this_name >= *pat_name && *this_name <= pat_name[2])
#endif
{
#ifdef WILDCARD
argok = 1; /* remember arg matched */
#endif
flist[fptr++] = str_dup (this_path);
if (*longest < strlen(this_path))
*longest = strlen(this_path);
}
} /* end while */
#ifdef WILDCARD
if (argok == 0) { /* no match for argument */
prterror ('e', "Could not open %s\n", *argv);
}
#endif
argc--;
argv++;
}
/* fptr is now 1 + index of last item in array */
if (this_path != NULL && fptr >= flistsize)
prterror ('w', too_many_files, flistsize);
#ifndef DONT_SORT
/* Shell sort -- K&R p. 58 */
for (gap = fptr/2; gap > 0; gap /= 2)
for (i = gap; i < fptr; i++)
for (j = i - gap; j >= 0 &&
strcmp(flist[j],flist[j+gap]) > 0; j -= gap) {
char *t = flist[j]; flist[j] = flist[j+gap]; flist[j+gap] = t;
}
#endif /* DONT_SORT */
fptr--; /* fptr is now index of last item in array */
/* Remove duplicates */
for (i = 0; i < fptr; i++) {
while (i<fptr && COMPARE(flist[i],flist[i+1]) == 0) {
for (j = i; j < fptr; j++)
flist[j] = flist[j+1];
fptr--;
}
}
flist[++fptr] = NULL; /* NULL entry terminates list */
}
/*******
modpath() makes any changes needed before pathname is stored;
currently these could involve folding it to lower case and
converting backslashes to forward slashes
*/
/*ARGSUSED*/
void modpath (path)
char *path;
{
#ifdef FOLD
str_lwr (path);
#endif
#ifdef FORCESLASH
fixslash (path); /* convert backslashes to slashes */
#endif
}
#ifdef CHEKDIR
/* Function isfdir returns 1 if pathname is a directory else 0 */
int isfdir (this_path)
char *this_path;
{
int dir;
ZOOFILE f;
f = zooopen (this_path, Z_READ);
if (f == NOFILE)
return 0;
else {
dir = isadir(f); zooclose(f);
}
return (dir);
}
#endif
|