示例#1
0
文件: icupkg.cpp 项目: 119120119/node
extern int
main(int argc, char *argv[]) {
    const char *pname, *sourcePath, *destPath, *inFilename, *outFilename, *outComment;
    char outType;
    UBool isHelp, isModified, isPackage;
    int result = 0;

    Package *pkg, *listPkg, *addListPkg;

    U_MAIN_INIT_ARGS(argc, argv);

    /* get the program basename */
    pname=findBasename(argv[0]);

    argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
    isHelp=options[OPT_HELP_H].doesOccur || options[OPT_HELP_QUESTION_MARK].doesOccur;
    if(isHelp) {
        printUsage(pname, TRUE);
        return U_ZERO_ERROR;
    }

    pkg=new Package;
    if(pkg==NULL) {
        fprintf(stderr, "icupkg: not enough memory\n");
        return U_MEMORY_ALLOCATION_ERROR;
    }
    isModified=FALSE;

    int autoPrefix=0;
    if(options[OPT_AUTO_TOC_PREFIX].doesOccur) {
        pkg->setAutoPrefix();
        ++autoPrefix;
    }
    if(options[OPT_AUTO_TOC_PREFIX_WITH_TYPE].doesOccur) {
        if(options[OPT_TOC_PREFIX].doesOccur) {
            fprintf(stderr, "icupkg: --auto_toc_prefix_with_type and also --toc_prefix\n");
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
        pkg->setAutoPrefixWithType();
        ++autoPrefix;
    }
    if(argc<2 || 3<argc || autoPrefix>1) {
        printUsage(pname, FALSE);
        return U_ILLEGAL_ARGUMENT_ERROR;
    }

    if(options[OPT_SOURCEDIR].doesOccur) {
        sourcePath=options[OPT_SOURCEDIR].value;
    } else {
        // work relative to the current working directory
        sourcePath=NULL;
    }
    if(options[OPT_DESTDIR].doesOccur) {
        destPath=options[OPT_DESTDIR].value;
    } else {
        // work relative to the current working directory
        destPath=NULL;
    }

    if(0==strcmp(argv[1], "new")) {
        if(autoPrefix) {
            fprintf(stderr, "icupkg: --auto_toc_prefix[_with_type] but no input package\n");
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
        inFilename=NULL;
        isPackage=TRUE;
    } else {
        inFilename=argv[1];
        if(isPackageName(inFilename)) {
            pkg->readPackage(inFilename);
            isPackage=TRUE;
        } else {
            /* swap a single file (icuswap replacement) rather than work on a package */
            pkg->addFile(sourcePath, inFilename);
            isPackage=FALSE;
        }
    }

    if(argc>=3) {
        outFilename=argv[2];
        if(0!=strcmp(argv[1], argv[2])) {
            isModified=TRUE;
        }
    } else if(isPackage) {
        outFilename=NULL;
    } else /* !isPackage */ {
        outFilename=inFilename;
        isModified=(UBool)(sourcePath!=destPath);
    }

    /* parse the output type option */
    if(options[OPT_OUT_TYPE].doesOccur) {
        const char *type=options[OPT_OUT_TYPE].value;
        if(type[0]==0 || type[1]!=0) {
            /* the type must be exactly one letter */
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
        outType=type[0];
        switch(outType) {
        case 'l':
        case 'b':
        case 'e':
            break;
        default:
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }

        /*
         * Set the isModified flag if the output type differs from the
         * input package type.
         * If we swap a single file, just assume that we are modifying it.
         * The Package class does not give us access to the item and its type.
         */
        isModified|=(UBool)(!isPackage || outType!=pkg->getInType());
    } else if(isPackage) {
        outType=pkg->getInType(); // default to input type
    } else /* !isPackage: swap single file */ {
        outType=0; /* tells extractItem() to not swap */
    }

    if(options[OPT_WRITEPKG].doesOccur) {
        isModified=TRUE;
    }

    if(!isPackage) {
        /*
         * icuswap tool replacement: Only swap a single file.
         * Check that irrelevant options are not set.
         */
        if( options[OPT_COMMENT].doesOccur ||
            options[OPT_COPYRIGHT].doesOccur ||
            options[OPT_MATCHMODE].doesOccur ||
            options[OPT_REMOVE_LIST].doesOccur ||
            options[OPT_ADD_LIST].doesOccur ||
            options[OPT_EXTRACT_LIST].doesOccur ||
            options[OPT_LIST_ITEMS].doesOccur
        ) {
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
        if(isModified) {
            pkg->extractItem(destPath, outFilename, 0, outType);
        }

        delete pkg;
        return result;
    }

    /* Work with a package. */

    if(options[OPT_COMMENT].doesOccur) {
        outComment=options[OPT_COMMENT].value;
    } else if(options[OPT_COPYRIGHT].doesOccur) {
        outComment=U_COPYRIGHT_STRING;
    } else {
        outComment=NULL;
    }

    if(options[OPT_MATCHMODE].doesOccur) {
        if(0==strcmp(options[OPT_MATCHMODE].value, "noslash")) {
            pkg->setMatchMode(Package::MATCH_NOSLASH);
        } else {
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
    }

    /* remove items */
    if(options[OPT_REMOVE_LIST].doesOccur) {
        listPkg=new Package();
        if(listPkg==NULL) {
            fprintf(stderr, "icupkg: not enough memory\n");
            exit(U_MEMORY_ALLOCATION_ERROR);
        }
        if(readList(NULL, options[OPT_REMOVE_LIST].value, FALSE, listPkg)) {
            pkg->removeItems(*listPkg);
            delete listPkg;
            isModified=TRUE;
        } else {
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
    }

    /*
     * add items
     * use a separate Package so that its memory and items stay around
     * as long as the main Package
     */
    addListPkg=NULL;
    if(options[OPT_ADD_LIST].doesOccur) {
        addListPkg=new Package();
        if(addListPkg==NULL) {
            fprintf(stderr, "icupkg: not enough memory\n");
            exit(U_MEMORY_ALLOCATION_ERROR);
        }
        if(readList(sourcePath, options[OPT_ADD_LIST].value, TRUE, addListPkg)) {
            pkg->addItems(*addListPkg);
            // delete addListPkg; deferred until after writePackage()
            isModified=TRUE;
        } else {
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
    }

    /* extract items */
    if(options[OPT_EXTRACT_LIST].doesOccur) {
        listPkg=new Package();
        if(listPkg==NULL) {
            fprintf(stderr, "icupkg: not enough memory\n");
            exit(U_MEMORY_ALLOCATION_ERROR);
        }
        if(readList(NULL, options[OPT_EXTRACT_LIST].value, FALSE, listPkg)) {
            pkg->extractItems(destPath, *listPkg, outType);
            delete listPkg;
        } else {
            printUsage(pname, FALSE);
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
    }

    /* list items */
    if(options[OPT_LIST_ITEMS].doesOccur) {
        int32_t i;
        if (options[OPT_LIST_FILE].doesOccur) {
            FileStream *out;
            out = T_FileStream_open(options[OPT_LIST_FILE].value, "w");
            if (out != NULL) {
                for(i=0; i<pkg->getItemCount(); ++i) {
                    T_FileStream_writeLine(out, pkg->getItem(i)->name);
                    T_FileStream_writeLine(out, "\n");
                }
                T_FileStream_close(out);
            } else {
                return U_ILLEGAL_ARGUMENT_ERROR;
            }
        } else {
            for(i=0; i<pkg->getItemCount(); ++i) {
                fprintf(stdout, "%s\n", pkg->getItem(i)->name);
            }
        }
    }

    /* check dependencies between items */
    if(!pkg->checkDependencies()) {
        /* some dependencies are not fulfilled */
        return U_MISSING_RESOURCE_ERROR;
    }

    /* write the output .dat package if there are any modifications */
    if(isModified) {
        char outFilenameBuffer[1024]; // for auto-generated output filename, if necessary

        if(outFilename==NULL || outFilename[0]==0) {
            if(inFilename==NULL || inFilename[0]==0) {
                fprintf(stderr, "icupkg: unable to auto-generate an output filename if there is no input filename\n");
                exit(U_ILLEGAL_ARGUMENT_ERROR);
            }

            /*
             * auto-generate a filename:
             * copy the inFilename,
             * and if the last basename character matches the input file's type,
             * then replace it with the output file's type
             */
            char suffix[6]="?.dat";
            char *s;

            suffix[0]=pkg->getInType();
            strcpy(outFilenameBuffer, inFilename);
            s=strchr(outFilenameBuffer, 0);
            if((s-outFilenameBuffer)>5 && 0==memcmp(s-5, suffix, 5)) {
                *(s-5)=outType;
            }
            outFilename=outFilenameBuffer;
        }
        if(options[OPT_TOC_PREFIX].doesOccur) {
            pkg->setPrefix(options[OPT_TOC_PREFIX].value);
        }
        result = writePackageDatFile(outFilename, outComment, NULL, NULL, pkg, outType);
    }

    delete addListPkg;
    delete pkg;
    return result;
}
示例#2
0
static int32_t pkg_executeOptions(UPKGOptions *o) {
    UErrorCode status = U_ZERO_ERROR;
    int32_t result = 0;
//    char cmd[SMALL_BUFFER_MAX_SIZE] = "";
    const char mode = o->mode[0];
    char targetDir[SMALL_BUFFER_MAX_SIZE] = "";
    char tmpDir[SMALL_BUFFER_MAX_SIZE] = "";
    char datFileName[SMALL_BUFFER_MAX_SIZE] = "";
    char datFileNamePath[LARGE_BUFFER_MAX_SIZE] = "";
    char checkLibFile[LARGE_BUFFER_MAX_SIZE] = "";

    /* Initialize pkgdataFlags */
    pkgDataFlags = (char**)uprv_malloc(sizeof(char*) * PKGDATA_FLAGS_SIZE);
    if (pkgDataFlags != NULL) {
        for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) {
            pkgDataFlags[i] = (char*)uprv_malloc(sizeof(char) * SMALL_BUFFER_MAX_SIZE);
            if (pkgDataFlags[i] != NULL) {
                pkgDataFlags[i][0] = 0;
            } else {
                fprintf(stderr,"Error allocating memory for pkgDataFlags.\n");
                return -1;
            }
        }
    } else {
        fprintf(stderr,"Error allocating memory for pkgDataFlags.\n");
        return -1;
    }
#ifndef WINDOWS_WITH_MSVC
    /* Read in options file. */
    parseFlagsFile(o->options, pkgDataFlags, SMALL_BUFFER_MAX_SIZE, (int32_t)PKGDATA_FLAGS_SIZE, &status);
    if (U_FAILURE(status)) {
        fprintf(stderr,"Unable to open or read \"%s\" option file.\n", o->options);
        return -1;
    }
#endif
    if (mode == MODE_FILES) {
        /* Copy the raw data to the installation directory. */
        if (o->install != NULL) {
            uprv_strcpy(targetDir, o->install);
            if (o->shortName != NULL) {
                uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING);
                uprv_strcat(targetDir, o->shortName);
            }
            result = pkg_installFileMode(targetDir, o->srcDir, o->fileListFiles->str);
        }
        return result;
    } else /* if (mode == MODE_COMMON || mode == MODE_STATIC || mode == MODE_DLL) */ {
        uprv_strcpy(targetDir, o->targetDir);
        uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING);

        uprv_strcpy(tmpDir, o->tmpDir);
        uprv_strcat(tmpDir, PKGDATA_FILE_SEP_STRING);

        uprv_strcpy(datFileNamePath, tmpDir);

        uprv_strcpy(datFileName, o->shortName);
        uprv_strcat(datFileName, UDATA_CMN_SUFFIX);

        uprv_strcat(datFileNamePath, datFileName);

        result = writePackageDatFile(datFileNamePath, o->comment, o->srcDir, o->fileListFiles->str, NULL, U_IS_BIG_ENDIAN ? 'b' : 'l');
        if (result != 0) {
            fprintf(stderr,"Error writing package dat file.\n");
            return result;
        }

        if (mode == MODE_COMMON) {
            char targetFileNamePath[LARGE_BUFFER_MAX_SIZE] = "";

            uprv_strcpy(targetFileNamePath, targetDir);
            uprv_strcat(targetFileNamePath, datFileName);

            if (T_FileStream_file_exists(targetFileNamePath)) {
                if ((result = remove(targetFileNamePath)) != 0) {
                    fprintf(stderr, "Unable to remove old dat file: %s\n", targetFileNamePath);
                    return result;
                }
            }

            /* Move the dat file created to the target directory. */
            result = rename(datFileNamePath, targetFileNamePath);
            if (result != 0) {
                fprintf(stderr, "Unable to move dat file (%s) to target location (%s).\n", datFileNamePath, targetFileNamePath);
            }

            return result;
        } else /* if (mode[0] == MODE_STATIC || mode[0] == MODE_DLL) */ {
            char gencFilePath[SMALL_BUFFER_MAX_SIZE] = "";
            char version_major[10] = "";
            UBool reverseExt = FALSE;

#ifndef WINDOWS_WITH_MSVC
            /* Get the version major number. */
            if (o->version != NULL) {
                for (uint32_t i = 0;i < sizeof(version_major);i++) {
                    if (o->version[i] == '.') {
                        version_major[i] = 0;
                        break;
                    }
                    version_major[i] = o->version[i];
                }
            }

#ifndef OS400
            /* Certain platforms have different library extension ordering. (e.g. libicudata.##.so vs libicudata.so.##)
             * reverseExt is FALSE if the suffix should be the version number.
             */
            if (pkgDataFlags[LIB_EXT_ORDER][uprv_strlen(pkgDataFlags[LIB_EXT_ORDER])-1] == pkgDataFlags[SO_EXT][uprv_strlen(pkgDataFlags[SO_EXT])-1]) {
                reverseExt = TRUE;
            }
#endif
            /* Using the base libName and version number, generate the library file names. */
            createFileNames(version_major, o->version, o->libName, reverseExt);

            if (o->version != 0 && o->rebuild == FALSE) {
                /* Check to see if a previous built data library file exists and check if it is the latest. */
                sprintf(checkLibFile, "%s%s", targetDir, libFileNames[LIB_FILE_VERSION_TMP]);
                if (T_FileStream_file_exists(checkLibFile)) {
                    if (isFileModTimeLater(checkLibFile, o->srcDir, TRUE) && isFileModTimeLater(checkLibFile, o->options)) {
                        if (o->install != NULL) {
                            uprv_strcpy(libFileNames[LIB_FILE_VERSION], libFileNames[LIB_FILE_VERSION_TMP]);
                            result = pkg_installLibrary(o->install, targetDir);
                        }
                        return result;
                    }
                }
            }

            pkg_checkFlag(o);
#endif

            if (pkgDataFlags[GENCCODE_ASSEMBLY_TYPE][0] != 0) {
                const char* genccodeAssembly = pkgDataFlags[GENCCODE_ASSEMBLY_TYPE];

                /* Offset genccodeAssembly by 3 because "-a " */
                if (checkAssemblyHeaderName(genccodeAssembly+3)) {
                    writeAssemblyCode(datFileNamePath, o->tmpDir, o->entryName, NULL, gencFilePath);

                    result = pkg_createWithAssemblyCode(targetDir, mode, gencFilePath);
                    if (result != 0) {
                        fprintf(stderr, "Error generating assembly code for data.\n");
                        return result;
                    } else if (mode == MODE_STATIC) {
                        return result;
                    }
                } else {
                    fprintf(stderr,"Assembly type \"%s\" is unknown.\n", genccodeAssembly);
                    return -1;
                }
            } else {
#ifdef CAN_WRITE_OBJ_CODE
                writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, NULL, NULL, gencFilePath);
#ifdef U_LINUX
                result = pkg_generateLibraryFile(targetDir, mode, gencFilePath);
#elif defined(WINDOWS_WITH_MSVC)
                return pkg_createWindowsDLL(mode, gencFilePath, o);
#endif
#elif defined(BUILD_DATA_WITHOUT_ASSEMBLY)
                result = pkg_createWithoutAssemblyCode(o, targetDir, mode);
#endif
                if (result != 0) {
                    fprintf(stderr, "Error generating package data.\n");
                    return result;
                }
            }
#ifndef U_WINDOWS
            /* Certain platforms uses archive library. (e.g. AIX) */
            result = pkg_archiveLibrary(targetDir, o->version, reverseExt);
            if (result != 0) {
                fprintf(stderr, "Error creating data archive library file.\n");
               return result;
            }
#ifndef OS400
            /* Create symbolic links for the final library file. */
            result = pkg_createSymLinks(targetDir);
            if (result != 0) {
                fprintf(stderr, "Error creating symbolic links of the data library file.\n");
                return result;
            }
#endif
            /* Install the libraries if option was set. */
            if (o->install != NULL) {
                result = pkg_installLibrary(o->install, targetDir);
                if (result != 0) {
                    fprintf(stderr, "Error installing the data library.\n");
                    return result;
                }
            }
#endif
        }
    }
    return result;
}