/* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2010 Index Data
+ * Copyright (C) Index Data
* See the file LICENSE for details.
*/
-/** \file
+/** \file
\brief File globbing (ala POSIX glob, but simpler)
*/
#if HAVE_CONFIG_H
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <assert.h>
#include <yaz/wrbuf.h>
#include <yaz/tpath.h>
#include <yaz/log.h>
-#include <dirent.h>
+#include <yaz/dirent.h>
#include <yaz/nmem.h>
#include <yaz/file_glob.h>
#include <yaz/match_glob.h>
struct glob_res {
NMEM nmem;
+ unsigned flags;
size_t number_of_entries;
struct res_entry **last_entry;
struct res_entry *entries;
};
+static void add_entry(yaz_glob_res_t res, const char *str)
+{
+ struct res_entry *ent =
+ nmem_malloc(res->nmem, sizeof(*ent));
+ ent->file = nmem_strdup(res->nmem, str);
+ ent->next = 0;
+ *res->last_entry = ent;
+ res->last_entry = &ent->next;
+ res->number_of_entries++;
+}
+
static void glob_r(yaz_glob_res_t res, const char *pattern, size_t off,
char *prefix)
{
is_pattern = 1;
i++;
}
-
+
if (!is_pattern && pattern[i]) /* no pattern and directory part */
{
i++; /* skip dir sep */
glob_r(res, pattern, i, prefix);
prefix[prefix_len] = '\0';
}
+ else if ((res->flags & YAZ_FILE_GLOB_FAIL_NOTEXIST) &&
+ !is_pattern && !pattern[i])
+ {
+ strcpy(prefix + prefix_len, pattern + off);
+ add_entry(res, prefix);
+ }
else
{
DIR * dir = opendir(*prefix ? prefix : "." );
}
else
{
- struct res_entry *ent =
- nmem_malloc(res->nmem, sizeof(*ent));
- ent->file = nmem_strdup(res->nmem, prefix);
- ent->next = 0;
- *res->last_entry = ent;
- res->last_entry = &ent->next;
- res->number_of_entries++;
+ add_entry(res, prefix);
}
prefix[prefix_len] = '\0';
}
}
}
+static int cmp_entry(const void *a, const void *b)
+{
+ struct res_entry *ent_a = *(struct res_entry **) a;
+ struct res_entry *ent_b = *(struct res_entry **) b;
+ return strcmp(ent_a->file, ent_b->file);
+}
+
+static void sort_them(yaz_glob_res_t res)
+{
+ size_t i;
+ struct res_entry **ent_p;
+ struct res_entry **ent = nmem_malloc(res->nmem, sizeof(*ent) * res->number_of_entries);
+ struct res_entry *ent_i = res->entries;
+ for (i = 0; i < res->number_of_entries; i++)
+ {
+ ent[i] = ent_i;
+ ent_i = ent_i->next;
+ }
+ qsort(ent, res->number_of_entries, sizeof(*ent), cmp_entry);
+ ent_p = &res->entries;
+ for (i = 0; i < res->number_of_entries; i++)
+ {
+ *ent_p = ent[i];
+ ent_p = &ent[i]->next;
+ }
+ *ent_p = 0;
+}
+
int yaz_file_glob(const char *pattern, yaz_glob_res_t *res)
{
+ return yaz_file_glob2(pattern, res, 0);
+}
+
+int yaz_file_glob2(const char *pattern, yaz_glob_res_t *res, unsigned flags)
+{
char prefix[FILENAME_MAX+1];
NMEM nmem = nmem_create();
*prefix = '\0';
*res = nmem_malloc(nmem, sizeof(**res));
+ (*res)->flags = flags;
(*res)->number_of_entries = 0;
(*res)->nmem = nmem;
(*res)->entries = 0;
(*res)->last_entry = &(*res)->entries;
glob_r(*res, pattern, 0, prefix);
+ sort_them(*res);
return 0;
}