X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Ffile_glob.c;h=a2e903105c2a5214a183596ba679b224c59b943f;hp=8b106642861b7b363743a07f56cb914bb649b404;hb=7fc72f3ae149e416a297ef1f55c09271056e98f1;hpb=de82e7fd43191fc2ae0d8eab9781c59c595c343a diff --git a/src/file_glob.c b/src/file_glob.c index 8b10664..a2e9031 100644 --- a/src/file_glob.c +++ b/src/file_glob.c @@ -1,9 +1,9 @@ /* 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 @@ -14,11 +14,12 @@ #include #include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -30,11 +31,23 @@ struct res_entry { 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) { @@ -47,7 +60,7 @@ static void glob_r(yaz_glob_res_t res, const char *pattern, size_t off, is_pattern = 1; i++; } - + if (!is_pattern && pattern[i]) /* no pattern and directory part */ { i++; /* skip dir sep */ @@ -56,6 +69,12 @@ static void glob_r(yaz_glob_res_t res, const char *pattern, size_t off, 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 : "." ); @@ -81,13 +100,7 @@ static void glob_r(yaz_glob_res_t res, const char *pattern, size_t off, } 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'; } @@ -97,18 +110,53 @@ static void glob_r(yaz_glob_res_t res, const char *pattern, size_t off, } } +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; }