/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant, * *variant and *language_variant will always be NULL). * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them. * NOTE: Keep that one always available, you never know, may become useful even in no-WITH_INTERNATIONAL context... */ void BLT_lang_locale_explode( const char *locale, char **language, char **country, char **variant, char **language_country, char **language_variant) { char *m1, *m2, *_t = NULL; m1 = strchr(locale, '_'); m2 = strchr(locale, '@'); if (language || language_variant) { if (m1 || m2) { _t = m1 ? BLI_strdupn(locale, m1 - locale) : BLI_strdupn(locale, m2 - locale); if (language) *language = _t; } else if (language) { *language = BLI_strdup(locale); } } if (country) { if (m1) *country = m2 ? BLI_strdupn(m1 + 1, m2 - (m1 + 1)) : BLI_strdup(m1 + 1); else *country = NULL; } if (variant) { if (m2) *variant = BLI_strdup(m2 + 1); else *variant = NULL; } if (language_country) { if (m1) *language_country = m2 ? BLI_strdupn(locale, m2 - locale) : BLI_strdup(locale); else *language_country = NULL; } if (language_variant) { if (m2) *language_variant = m1 ? BLI_strdupcat(_t, m2) : BLI_strdup(locale); else *language_variant = NULL; } if (_t && !language) { MEM_freeN(_t); } }
static void bli_builddir(const char *dirname, const char *relname) { struct dirent *fname; struct dirlink *dlink; int rellen, newnum = 0; char buf[256]; DIR *dir; BLI_strncpy(buf, relname, sizeof(buf)); rellen=strlen(relname); if (rellen) { buf[rellen]='/'; rellen++; } #ifndef WIN32 if (chdir(dirname) == -1) { perror(dirname); return; } #else UTF16_ENCODE(dirname); if (!SetCurrentDirectoryW(dirname_16)) { perror(dirname); free(dirname_16); return; } UTF16_UN_ENCODE(dirname); #endif if ((dir = (DIR *)opendir("."))) { while ((fname = (struct dirent*) readdir(dir)) != NULL) { dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); if (dlink) { BLI_strncpy(buf + rellen, fname->d_name, sizeof(buf) - rellen); dlink->name = BLI_strdup(buf); BLI_addhead(dirbase, dlink); newnum++; } } if (newnum) { if (files) { void *tmp = realloc(files, (totnum+newnum) * sizeof(struct direntry)); if (tmp) { files = (struct direntry *)tmp; } else { /* realloc fail */ free(files); files = NULL; } } if (files==NULL) files=(struct direntry *)malloc(newnum * sizeof(struct direntry)); if (files) { dlink = (struct dirlink *) dirbase->first; while (dlink) { memset(&files[actnum], 0, sizeof(struct direntry)); files[actnum].relname = dlink->name; files[actnum].path = BLI_strdupcat(dirname, dlink->name); // use 64 bit file size, only needed for WIN32 and WIN64. // Excluding other than current MSVC compiler until able to test #ifdef WIN32 {wchar_t * name_16 = alloc_utf16_from_8(dlink->name, 0); #if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500) _wstat64(name_16, &files[actnum].s); #elif defined(__MINGW32__) _stati64(dlink->name, &files[actnum].s); #endif free(name_16);}; #else stat(dlink->name, &files[actnum].s); #endif files[actnum].type=files[actnum].s.st_mode; files[actnum].flags = 0; totnum++; actnum++; dlink = dlink->next; } } else { printf("Couldn't get memory for dir\n"); exit(1); } BLI_freelist(dirbase); if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void*))bli_compare); } else { printf("%s empty directory\n", dirname); } closedir(dir); } else { printf("%s non-existant directory\n", dirname); } }
/** * Gets the temp directory when blender first runs. * If the default path is not found, use try $TEMP * * Also make sure the temp dir has a trailing slash * * \param fullname The full path to the temporary temp directory * \param basename The full path to the persistent temp directory (may be NULL) * \param maxlen The size of the fullname buffer * \param userdir Directory specified in user preferences */ static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) { /* Clear existing temp dir, if needed. */ BKE_tempdir_session_purge(); fullname[0] = '\0'; if (basename) { basename[0] = '\0'; } if (userdir && BLI_is_dir(userdir)) { BLI_strncpy(fullname, userdir, maxlen); } #ifdef WIN32 if (fullname[0] == '\0') { const char *tmp = getenv("TEMP"); /* Windows */ if (tmp && BLI_is_dir(tmp)) { BLI_strncpy(fullname, tmp, maxlen); } } #else /* Other OS's - Try TMP and TMPDIR */ if (fullname[0] == '\0') { const char *tmp = getenv("TMP"); if (tmp && BLI_is_dir(tmp)) { BLI_strncpy(fullname, tmp, maxlen); } } if (fullname[0] == '\0') { const char *tmp = getenv("TMPDIR"); if (tmp && BLI_is_dir(tmp)) { BLI_strncpy(fullname, tmp, maxlen); } } #endif if (fullname[0] == '\0') { BLI_strncpy(fullname, "/tmp/", maxlen); } else { /* add a trailing slash if needed */ BLI_add_slash(fullname); #ifdef WIN32 if (userdir && userdir != fullname) { BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */ } #endif } /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ if (basename) { /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); const size_t ln = strlen(tmp_name) + 1; if (ln <= maxlen) { #ifdef WIN32 if (_mktemp_s(tmp_name, ln) == 0) { BLI_dir_create_recursive(tmp_name); } #else mkdtemp(tmp_name); #endif } if (BLI_is_dir(tmp_name)) { BLI_strncpy(basename, fullname, maxlen); BLI_strncpy(fullname, tmp_name, maxlen); BLI_add_slash(fullname); } else { printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname); } MEM_freeN(tmp_name); } }
/** * Scans the directory named *dirname and appends entries for its contents to files. */ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) { struct ListBase dirbase = {NULL, NULL}; int newnum = 0; DIR *dir; if ((dir = opendir(dirname)) != NULL) { const struct dirent *fname; while ((fname = readdir(dir)) != NULL) { struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); if (dlink != NULL) { dlink->name = BLI_strdup(fname->d_name); BLI_addhead(&dirbase, dlink); newnum++; } } if (newnum) { if (dir_ctx->files) { void * const tmp = realloc(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry)); if (tmp) { dir_ctx->files = (struct direntry *)tmp; } else { /* realloc fail */ free(dir_ctx->files); dir_ctx->files = NULL; } } if (dir_ctx->files == NULL) dir_ctx->files = (struct direntry *)malloc(newnum * sizeof(struct direntry)); if (dir_ctx->files) { struct dirlink * dlink = (struct dirlink *) dirbase.first; struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles]; while (dlink) { char fullname[PATH_MAX]; memset(file, 0, sizeof(struct direntry)); file->relname = dlink->name; file->path = BLI_strdupcat(dirname, dlink->name); BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name); // use 64 bit file size, only needed for WIN32 and WIN64. // Excluding other than current MSVC compiler until able to test #ifdef WIN32 { wchar_t *name_16 = alloc_utf16_from_8(fullname, 0); #if defined(_MSC_VER) && (_MSC_VER >= 1500) _wstat64(name_16, &file->s); #elif defined(__MINGW32__) _stati64(fullname, &file->s); #endif free(name_16); } #else stat(fullname, &file->s); #endif file->type = file->s.st_mode; file->flags = 0; dir_ctx->nrfiles++; file++; dlink = dlink->next; } } else { printf("Couldn't get memory for dir\n"); exit(1); } BLI_freelist(&dirbase); if (dir_ctx->files) { qsort(dir_ctx->files, dir_ctx->nrfiles, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare); } } else { printf("%s empty directory\n", dirname); } closedir(dir); } else { printf("%s non-existant directory\n", dirname); } }
/** * Scans the directory named *dirname and appends entries for its contents to files. */ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) { struct ListBase dirbase = {NULL, NULL}; int newnum = 0; DIR *dir; if ((dir = opendir(dirname)) != NULL) { const struct dirent *fname; while ((fname = readdir(dir)) != NULL) { struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); if (dlink != NULL) { dlink->name = BLI_strdup(fname->d_name); BLI_addhead(&dirbase, dlink); newnum++; } } if (newnum) { if (dir_ctx->files) { void * const tmp = MEM_reallocN(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry)); if (tmp) { dir_ctx->files = (struct direntry *)tmp; } else { /* realloc fail */ MEM_freeN(dir_ctx->files); dir_ctx->files = NULL; } } if (dir_ctx->files == NULL) dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry), __func__); if (dir_ctx->files) { struct dirlink * dlink = (struct dirlink *) dirbase.first; struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles]; while (dlink) { char fullname[PATH_MAX]; memset(file, 0, sizeof(struct direntry)); file->relname = dlink->name; file->path = BLI_strdupcat(dirname, dlink->name); BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name); if (BLI_stat(fullname, &file->s) != -1) { file->type = file->s.st_mode; } file->flags = 0; dir_ctx->nrfiles++; file++; dlink = dlink->next; } } else { printf("Couldn't get memory for dir\n"); exit(1); } BLI_freelist(&dirbase); if (dir_ctx->files) { qsort(dir_ctx->files, dir_ctx->nrfiles, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare); } } else { printf("%s empty directory\n", dirname); } closedir(dir); } else { printf("%s non-existent directory\n", dirname); } }