diff --git a/doc/helianthus-doc-ru.odt b/doc/helianthus-doc-ru.odt index eda0ced..c199e6d 100644 Binary files a/doc/helianthus-doc-ru.odt and b/doc/helianthus-doc-ru.odt differ diff --git a/src/common.c b/src/common.c index d6daf84..b20fbf7 100644 --- a/src/common.c +++ b/src/common.c @@ -11,6 +11,7 @@ HeliArray heliObjectsSet; struct _Directory { + size_t pathLen; HeliArray files; }; @@ -44,21 +45,68 @@ void rotateVector(double *x, double *y, double angle) { if (y) *y = xx*s + yy*c; } - -Directory openDirectory(const char *path) { +Directory openDirectoryEx( + const char *path, + const char *prefix, + const char *suffix, + int caseSensitive, + int showFiles, + int showDirectories ) +{ if (!heliInitialized) return NULL; + if (!path) return NULL; DIR *dir = opendir(path); if (!dir) return NULL; Directory d = calloc(1, sizeof(*d)); + d->pathLen = strlen(path); + size_t prefixLen = prefix ? strlen(prefix) : 0u; + size_t suffixLen = suffix ? strlen(suffix) : 0u; + + size_t bufLen = d->pathLen + 1024; + char *buf = calloc(1, bufLen); + strcpy(buf, path); + if (d->pathLen > 0 && buf[d->pathLen - 1] != '\\' && buf[d->pathLen - 1] != '/') { + char lastSlash = '/'; + for(const char *c = buf; *c; ++c) + if (*c == '\\' || *c == '/') lastSlash = *c; + buf[d->pathLen++] = lastSlash; + } + struct dirent *ent; while((ent = readdir(dir)) != NULL) { if ( !ent->d_name[0] || strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0 ) continue; - heliStringmapAdd(&d->files, ent->d_name, NULL, NULL); + + if (prefixLen) { + if ( caseSensitive ? strncmp(prefix, ent->d_name, prefixLen) + : heliStringCompareNCi(prefix, ent->d_name, prefixLen) ) + continue; + } + + size_t nameLen = strlen(ent->d_name); + + if (suffixLen) { + if (nameLen < suffixLen) continue; + const char *sub = ent->d_name + nameLen - suffixLen; + if ( caseSensitive ? strcmp(suffix, sub) + : heliStringCompareCi(suffix, sub) ) + continue; + } + + if (bufLen <= d->pathLen + nameLen) { + bufLen = d->pathLen + nameLen + 1024; + buf = realloc(buf, bufLen); + } + + strcpy(buf + d->pathLen, ent->d_name); + + if ( (showFiles && fileExists(buf)) + || (showDirectories && directoryExists(buf)) ) + heliStringmapAdd(&d->files, buf, NULL, NULL); } closedir(dir); @@ -66,6 +114,9 @@ Directory openDirectory(const char *path) { return d; } +Directory openDirectory(const char *path) + { return openDirectoryEx(path, NULL, NULL, TRUE, TRUE, TRUE); } + void closeDirectory(Directory directory) { if (!directory) return; heliObjectUnregister(directory); @@ -76,9 +127,13 @@ void closeDirectory(Directory directory) { int directoryGetCount(Directory directory) { return directory->files.count; } -const char* directoryGet(Directory directory, int i) +const char* directoryGetFull(Directory directory, int i) { return (const char*)heliArrayGetKey(&directory->files, i); } +const char* directoryGet(Directory directory, int i) { + const char *path = directoryGetFull(directory, i); + return path ? path + directory->pathLen : NULL; +} int fileExists(const char *path) { struct stat s = {}; @@ -126,22 +181,25 @@ char* heliStringConcat3(const char *a, const char *b, const char *c) { return s; } -int heliStringCompareCi(const char *a, const char *b) { +int heliStringCompareNCi(const char *a, const char *b, size_t n) { if (!a && !b) return 0; if (!a) return -1; if (!b) return 1; - while(*a || *b) { + while((*a || *b) && n) { if (!a) return -1; if (!b) return 1; char aa = tolower(*a); char bb = tolower(*b); if (aa < bb) return -1; if (bb < aa) return 1; - ++a, ++b; + ++a, ++b, --n; } return 0; } +int heliStringCompareCi(const char *a, const char *b) + { return heliStringCompareNCi(a, b, SIZE_MAX); } + int heliStringEndsWithLowcase(const char *s, const char *tail) { int ls = strlen(s); int lt = strlen(tail); diff --git a/src/common.h b/src/common.h index 49d9da8..c5662f1 100644 --- a/src/common.h +++ b/src/common.h @@ -25,9 +25,17 @@ void rotateVector(double *x, double *y, double angle); Directory openDirectory(const char *path); +Directory openDirectoryEx( + const char *path, + const char *prefix, + const char *suffix, + int caseSensitive, + int showFiles, + int showDirectories ); void closeDirectory(Directory directory); int directoryGetCount(Directory directory); const char* directoryGet(Directory directory, int i); +const char* directoryGetFull(Directory directory, int i); int fileExists(const char *path); int directoryExists(const char *path); diff --git a/src/private.h b/src/private.h index 4d818c6..7907119 100644 --- a/src/private.h +++ b/src/private.h @@ -43,6 +43,7 @@ char* heliStringCopyLower(const char *x); char* heliStringConcat(const char *a, const char *b); char* heliStringConcat3(const char *a, const char *b, const char *c); int heliStringCompareCi(const char *a, const char *b); +int heliStringCompareNCi(const char *a, const char *b, size_t n); int heliStringEndsWithLowcase(const char *s, const char *tail); void heliStringLower(char *x);