Example #1
0
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;
}
Example #2
0
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;
}