static void addFile(const char *filename, const char *name, const char *source, UBool sourceTOC, UBool verbose) { char *s; uint32_t length; char *fullPath = NULL; if(fileCount==fileMax) { fileMax += CHUNK_FILE_COUNT; files = uprv_realloc(files, fileMax*sizeof(files[0])); /* note: never freed. */ if(files==NULL) { fprintf(stderr, "pkgdata/gencmn: Could not allocate %u bytes for %d files\n", (unsigned int)(fileMax*sizeof(files[0])), fileCount); exit(U_MEMORY_ALLOCATION_ERROR); } } if(!sourceTOC) { FileStream *file; if(uprv_pathIsAbsolute(filename)) { fprintf(stderr, "gencmn: Error: absolute path encountered. Old style paths are not supported. Use relative paths such as 'fur.res' or 'translit%cfur.res'.\n\tBad path: '%s'\n", U_FILE_SEP_CHAR, filename); exit(U_ILLEGAL_ARGUMENT_ERROR); } fullPath = pathToFullPath(filename, source); /* store the pathname */ length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1); s=allocString(length); uprv_strcpy(s, name); uprv_strcat(s, U_TREE_ENTRY_SEP_STRING); uprv_strcat(s, filename); /* get the basename */ fixDirToTreePath(s); files[fileCount].basename=s; files[fileCount].basenameLength=length; files[fileCount].pathname=fullPath; basenameTotal+=length; /* try to open the file */ file=T_FileStream_open(fullPath, "rb"); if(file==NULL) { fprintf(stderr, "gencmn: unable to open listed file %s\n", fullPath); exit(U_FILE_ACCESS_ERROR); } /* get the file length */ length=T_FileStream_size(file); if(T_FileStream_error(file) || length<=20) { fprintf(stderr, "gencmn: unable to get length of listed file %s\n", fullPath); exit(U_FILE_ACCESS_ERROR); } T_FileStream_close(file); /* do not add files that are longer than maxSize */ if(maxSize && length>maxSize) { if (verbose) { printf("%s ignored (size %ld > %ld)\n", fullPath, (long)length, (long)maxSize); } return; } files[fileCount].fileSize=length; } else { char *t; /* get and store the basename */ /* need to include the package name */ length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1); s=allocString(length); uprv_strcpy(s, name); uprv_strcat(s, U_TREE_ENTRY_SEP_STRING); uprv_strcat(s, filename); fixDirToTreePath(s); files[fileCount].basename=s; /* turn the basename into an entry point name and store in the pathname field */ t=files[fileCount].pathname=allocString(length); while(--length>0) { if(*s=='.' || *s=='-' || *s=='/') { *t='_'; } else { *t=*s; } ++s; ++t; } *t=0; } ++fileCount; }
static UDataMemory * doOpenChoice(const char *path, const char *type, const char *name, UDataMemoryIsAcceptable *isAcceptable, void *context, UErrorCode *pErrorCode) { UDataMemory *retVal = NULL; TinyString tocEntryName; /* entry name in tree format. ex: 'icudt28b/coll/ar.res' */ TinyString tocEntryPath; /* entry name in path format. ex: 'icudt28b\\coll\\ar.res' */ TinyString pkgName; TinyString treeName; #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) /* '/' vs '\' */ TinyString altSepPath; #endif const char *dataPath; int32_t tocEntrySuffixIndex; const char *tocEntryPathSuffix; UErrorCode subErrorCode=U_ZERO_ERROR; const char *treeChar; UBool isICUData = FALSE; /* Is this path ICU data? */ if(path == NULL || !strcmp(path, U_ICUDATA_ALIAS) || /* "ICUDATA" */ !uprv_strncmp(path, U_ICUDATA_NAME U_TREE_SEPARATOR_STRING, /* "icudt26e-" */ uprv_strlen(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING)) || !uprv_strncmp(path, U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING, /* "ICUDATA-" */ uprv_strlen(U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING))) { isICUData = TRUE; } #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) /* Windows: try "foo\bar" and "foo/bar" */ /* remap from alternate path char to the main one */ TinyString_init(&altSepPath); if(path) { char *p; if((p=uprv_strchr(path,U_FILE_ALT_SEP_CHAR))) { TinyString_append(&altSepPath, path); while((p=uprv_strchr(altSepPath.s,U_FILE_ALT_SEP_CHAR))) { *p = U_FILE_SEP_CHAR; } #if defined (UDATA_DEBUG) fprintf(stderr, "Changed path from [%s] to [%s]\n", path, altSepPath.s); #endif path = altSepPath.s; } } #endif TinyString_init(&tocEntryName); TinyString_init(&tocEntryPath); TinyString_init(&pkgName); TinyString_init(&treeName); /* ======= Set up strings */ if(path==NULL) { TinyString_append(&pkgName, U_ICUDATA_NAME); } else { const char *pkg; const char *first; pkg = uprv_strrchr(path, U_FILE_SEP_CHAR); first = uprv_strchr(path, U_FILE_SEP_CHAR); if(uprv_pathIsAbsolute(path) || (pkg != first)) { /* more than one slash in the path- not a tree name */ /* see if this is an /absolute/path/to/package path */ if(pkg) { TinyString_append(&pkgName, pkg+1); } else { TinyString_append(&pkgName, path); } } else { treeChar = uprv_strchr(path, U_TREE_SEPARATOR); if(treeChar) { TinyString_append(&treeName, treeChar+1); /* following '-' */ if(isICUData) { TinyString_append(&pkgName, U_ICUDATA_NAME); } else { TinyString_appendn(&pkgName, path, (int32_t)(treeChar-path)); if (first == NULL) { /* This user data has no path, but there is a tree name. Look up the correct path from the data cache later. */ path = pkgName.s; } } } else { if(isICUData) { TinyString_append(&pkgName, U_ICUDATA_NAME); } else { TinyString_append(&pkgName, path); } } } } #ifdef UDATA_DEBUG fprintf(stderr, " P=%s T=%s\n", pkgName.s, treeName.s); #endif /* setting up the entry name and file name * Make up a full name by appending the type to the supplied * name, assuming that a type was supplied. */ /* prepend the package */ TinyString_append(&tocEntryName, pkgName.s); TinyString_append(&tocEntryPath, pkgName.s); tocEntrySuffixIndex = tocEntryName.length; if(treeName.s[0]) { TinyString_append(&tocEntryName, U_TREE_ENTRY_SEP_STRING); TinyString_append(&tocEntryName, treeName.s); TinyString_append(&tocEntryPath, U_FILE_SEP_STRING); TinyString_append(&tocEntryPath, treeName.s); } TinyString_append(&tocEntryName, U_TREE_ENTRY_SEP_STRING); TinyString_append(&tocEntryPath, U_FILE_SEP_STRING); TinyString_append(&tocEntryName, name); TinyString_append(&tocEntryPath, name); if(type!=NULL && *type!=0) { TinyString_append(&tocEntryName, "."); TinyString_append(&tocEntryName, type); TinyString_append(&tocEntryPath, "."); TinyString_append(&tocEntryPath, type); } tocEntryPathSuffix = tocEntryPath.s+tocEntrySuffixIndex; /* suffix starts here */ #ifdef UDATA_DEBUG fprintf(stderr, " tocEntryName = %s\n", tocEntryName.s); fprintf(stderr, " tocEntryPath = %s\n", tocEntryName.s); #endif if(path == NULL) { path = COMMON_DATA_NAME; /* "icudt26e" */ } /************************ Begin loop looking for ind. files ***************/ #ifdef UDATA_DEBUG fprintf(stderr, "IND: inBasename = %s, pkg=%s\n", "(n/a)", packageNameFromPath(path)); #endif /* End of dealing with a null basename */ dataPath = u_getDataDirectory(); /**** COMMON PACKAGE - only if packages are first. */ if(gDataFileAccess == UDATA_PACKAGES_FIRST) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying packages (UDATA_PACKAGES_FIRST)\n"); #endif /* #2 */ retVal = doLoadFromCommonData(isICUData, pkgName.s, dataPath, tocEntryPathSuffix, tocEntryName.s, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } /**** INDIVIDUAL FILES */ if((gDataFileAccess==UDATA_PACKAGES_FIRST) || (gDataFileAccess==UDATA_FILES_FIRST)) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying individual files\n"); #endif /* Check to make sure that there is a dataPath to iterate over */ if ((dataPath && *dataPath) || !isICUData) { retVal = doLoadFromIndividualFiles(pkgName.s, dataPath, tocEntryPathSuffix, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } } /**** COMMON PACKAGE */ if((gDataFileAccess==UDATA_ONLY_PACKAGES) || (gDataFileAccess==UDATA_FILES_FIRST)) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying packages (UDATA_ONLY_PACKAGES || UDATA_FILES_FIRST)\n"); #endif retVal = doLoadFromCommonData(isICUData, pkgName.s, dataPath, tocEntryPathSuffix, tocEntryName.s, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } /* Load from DLL. If we haven't attempted package load, we also haven't had any chance to try a DLL (static or setCommonData/etc) load. If we ever have a "UDATA_ONLY_FILES", add it to the or list here. */ if(gDataFileAccess==UDATA_NO_FILES) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying common data (UDATA_NO_FILES)\n"); #endif retVal = doLoadFromCommonData(isICUData, pkgName.s, "", tocEntryPathSuffix, tocEntryName.s, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } /* data not found */ if(U_SUCCESS(*pErrorCode)) { if(U_SUCCESS(subErrorCode)) { /* file not found */ *pErrorCode=U_FILE_ACCESS_ERROR; } else { /* entry point not found or rejected */ *pErrorCode=subErrorCode; } } commonReturn: TinyString_dt(&tocEntryName); TinyString_dt(&tocEntryPath); TinyString_dt(&pkgName); TinyString_dt(&treeName); #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) TinyString_dt(&altSepPath); #endif return retVal; }