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; }
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; }