1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/tools/pkgdata/pkgdata.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2041 @@ 1.4 +/****************************************************************************** 1.5 + * Copyright (C) 2000-2013, International Business Machines 1.6 + * Corporation and others. All Rights Reserved. 1.7 + ******************************************************************************* 1.8 + * file name: pkgdata.cpp 1.9 + * encoding: ANSI X3.4 (1968) 1.10 + * tab size: 8 (not used) 1.11 + * indentation:4 1.12 + * 1.13 + * created on: 2000may15 1.14 + * created by: Steven \u24C7 Loomis 1.15 + * 1.16 + * This program packages the ICU data into different forms 1.17 + * (DLL, common data, etc.) 1.18 + */ 1.19 + 1.20 +// Defines _XOPEN_SOURCE for access to POSIX functions. 1.21 +// Must be before any other #includes. 1.22 +#include "uposixdefs.h" 1.23 + 1.24 +#include "unicode/utypes.h" 1.25 + 1.26 +#include "unicode/putil.h" 1.27 +#include "putilimp.h" 1.28 + 1.29 +#if U_HAVE_POPEN 1.30 +#if (U_PF_MINGW <= U_PLATFORM || U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__) 1.31 +/* popen/pclose aren't defined in strict ANSI on Cygwin and MinGW */ 1.32 +#undef __STRICT_ANSI__ 1.33 +#endif 1.34 +#endif 1.35 + 1.36 +#include "cmemory.h" 1.37 +#include "cstring.h" 1.38 +#include "filestrm.h" 1.39 +#include "toolutil.h" 1.40 +#include "unicode/uclean.h" 1.41 +#include "unewdata.h" 1.42 +#include "uoptions.h" 1.43 +#include "package.h" 1.44 +#include "pkg_icu.h" 1.45 +#include "pkg_genc.h" 1.46 +#include "pkg_gencmn.h" 1.47 +#include "flagparser.h" 1.48 +#include "filetools.h" 1.49 + 1.50 +#if U_HAVE_POPEN 1.51 +# include <unistd.h> 1.52 +#endif 1.53 + 1.54 +#include <stdio.h> 1.55 +#include <stdlib.h> 1.56 + 1.57 +U_CDECL_BEGIN 1.58 +#include "pkgtypes.h" 1.59 +U_CDECL_END 1.60 + 1.61 + 1.62 +static void loadLists(UPKGOptions *o, UErrorCode *status); 1.63 + 1.64 +static int32_t pkg_executeOptions(UPKGOptions *o); 1.65 + 1.66 +#ifdef WINDOWS_WITH_MSVC 1.67 +static int32_t pkg_createWindowsDLL(const char mode, const char *gencFilePath, UPKGOptions *o); 1.68 +#endif 1.69 +static int32_t pkg_createSymLinks(const char *targetDir, UBool specialHandling=FALSE); 1.70 +static int32_t pkg_installLibrary(const char *installDir, const char *dir, UBool noVersion); 1.71 +static int32_t pkg_installFileMode(const char *installDir, const char *srcDir, const char *fileListName); 1.72 +static int32_t pkg_installCommonMode(const char *installDir, const char *fileName); 1.73 + 1.74 +#ifdef BUILD_DATA_WITHOUT_ASSEMBLY 1.75 +static int32_t pkg_createWithoutAssemblyCode(UPKGOptions *o, const char *targetDir, const char mode); 1.76 +#endif 1.77 + 1.78 +static int32_t pkg_createWithAssemblyCode(const char *targetDir, const char mode, const char *gencFilePath); 1.79 +static int32_t pkg_generateLibraryFile(const char *targetDir, const char mode, const char *objectFile, char *command = NULL); 1.80 +static int32_t pkg_archiveLibrary(const char *targetDir, const char *version, UBool reverseExt); 1.81 +static void createFileNames(UPKGOptions *o, const char mode, const char *version_major, const char *version, const char *libName, const UBool reverseExt, UBool noVersion); 1.82 +static int32_t initializePkgDataFlags(UPKGOptions *o); 1.83 + 1.84 +static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option); 1.85 +static int runCommand(const char* command, UBool specialHandling=FALSE); 1.86 + 1.87 +#define IN_COMMON_MODE(mode) (mode == 'a' || mode == 'c') 1.88 +#define IN_DLL_MODE(mode) (mode == 'd' || mode == 'l') 1.89 +#define IN_STATIC_MODE(mode) (mode == 's') 1.90 +#define IN_FILES_MODE(mode) (mode == 'f') 1.91 + 1.92 +enum { 1.93 + NAME, 1.94 + BLDOPT, 1.95 + MODE, 1.96 + HELP, 1.97 + HELP_QUESTION_MARK, 1.98 + VERBOSE, 1.99 + COPYRIGHT, 1.100 + COMMENT, 1.101 + DESTDIR, 1.102 + REBUILD, 1.103 + TEMPDIR, 1.104 + INSTALL, 1.105 + SOURCEDIR, 1.106 + ENTRYPOINT, 1.107 + REVISION, 1.108 + FORCE_PREFIX, 1.109 + LIBNAME, 1.110 + QUIET, 1.111 + WITHOUT_ASSEMBLY, 1.112 + PDS_BUILD 1.113 +}; 1.114 + 1.115 +/* This sets the modes that are available */ 1.116 +static struct { 1.117 + const char *name, *alt_name; 1.118 + const char *desc; 1.119 +} modes[] = { 1.120 + { "files", 0, "Uses raw data files (no effect). Installation copies all files to the target location." }, 1.121 +#if U_PLATFORM_HAS_WIN32_API 1.122 + { "dll", "library", "Generates one common data file and one shared library, <package>.dll"}, 1.123 + { "common", "archive", "Generates just the common file, <package>.dat"}, 1.124 + { "static", "static", "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX } 1.125 +#else 1.126 +#ifdef UDATA_SO_SUFFIX 1.127 + { "dll", "library", "Generates one shared library, <package>" UDATA_SO_SUFFIX }, 1.128 +#endif 1.129 + { "common", "archive", "Generates one common data file, <package>.dat" }, 1.130 + { "static", "static", "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX } 1.131 +#endif 1.132 +}; 1.133 + 1.134 +static UOption options[]={ 1.135 + /*00*/ UOPTION_DEF( "name", 'p', UOPT_REQUIRES_ARG), 1.136 + /*01*/ UOPTION_DEF( "bldopt", 'O', UOPT_REQUIRES_ARG), /* on Win32 it is release or debug */ 1.137 + /*02*/ UOPTION_DEF( "mode", 'm', UOPT_REQUIRES_ARG), 1.138 + /*03*/ UOPTION_HELP_H, /* -h */ 1.139 + /*04*/ UOPTION_HELP_QUESTION_MARK, /* -? */ 1.140 + /*05*/ UOPTION_VERBOSE, /* -v */ 1.141 + /*06*/ UOPTION_COPYRIGHT, /* -c */ 1.142 + /*07*/ UOPTION_DEF( "comment", 'C', UOPT_REQUIRES_ARG), 1.143 + /*08*/ UOPTION_DESTDIR, /* -d */ 1.144 + /*11*/ UOPTION_DEF( "rebuild", 'F', UOPT_NO_ARG), 1.145 + /*12*/ UOPTION_DEF( "tempdir", 'T', UOPT_REQUIRES_ARG), 1.146 + /*13*/ UOPTION_DEF( "install", 'I', UOPT_REQUIRES_ARG), 1.147 + /*14*/ UOPTION_SOURCEDIR , 1.148 + /*15*/ UOPTION_DEF( "entrypoint", 'e', UOPT_REQUIRES_ARG), 1.149 + /*16*/ UOPTION_DEF( "revision", 'r', UOPT_REQUIRES_ARG), 1.150 + /*17*/ UOPTION_DEF( "force-prefix", 'f', UOPT_NO_ARG), 1.151 + /*18*/ UOPTION_DEF( "libname", 'L', UOPT_REQUIRES_ARG), 1.152 + /*19*/ UOPTION_DEF( "quiet", 'q', UOPT_NO_ARG), 1.153 + /*20*/ UOPTION_DEF( "without-assembly", 'w', UOPT_NO_ARG), 1.154 + /*21*/ UOPTION_DEF( "zos-pds-build", 'z', UOPT_NO_ARG) 1.155 +}; 1.156 + 1.157 +/* This enum and the following char array should be kept in sync. */ 1.158 +enum { 1.159 + GENCCODE_ASSEMBLY_TYPE, 1.160 + SO_EXT, 1.161 + SOBJ_EXT, 1.162 + A_EXT, 1.163 + LIBPREFIX, 1.164 + LIB_EXT_ORDER, 1.165 + COMPILER, 1.166 + LIBFLAGS, 1.167 + GENLIB, 1.168 + LDICUDTFLAGS, 1.169 + LD_SONAME, 1.170 + RPATH_FLAGS, 1.171 + BIR_FLAGS, 1.172 + AR, 1.173 + ARFLAGS, 1.174 + RANLIB, 1.175 + INSTALL_CMD, 1.176 + PKGDATA_FLAGS_SIZE 1.177 +}; 1.178 +static const char* FLAG_NAMES[PKGDATA_FLAGS_SIZE] = { 1.179 + "GENCCODE_ASSEMBLY_TYPE", 1.180 + "SO", 1.181 + "SOBJ", 1.182 + "A", 1.183 + "LIBPREFIX", 1.184 + "LIB_EXT_ORDER", 1.185 + "COMPILE", 1.186 + "LIBFLAGS", 1.187 + "GENLIB", 1.188 + "LDICUDTFLAGS", 1.189 + "LD_SONAME", 1.190 + "RPATH_FLAGS", 1.191 + "BIR_LDFLAGS", 1.192 + "AR", 1.193 + "ARFLAGS", 1.194 + "RANLIB", 1.195 + "INSTALL_CMD" 1.196 +}; 1.197 +static char **pkgDataFlags = NULL; 1.198 + 1.199 +enum { 1.200 + LIB_FILE, 1.201 + LIB_FILE_VERSION_MAJOR, 1.202 + LIB_FILE_VERSION, 1.203 + LIB_FILE_VERSION_TMP, 1.204 +#if U_PLATFORM == U_PF_CYGWIN 1.205 + LIB_FILE_CYGWIN, 1.206 + LIB_FILE_CYGWIN_VERSION, 1.207 +#elif U_PLATFORM == U_PF_MINGW 1.208 + LIB_FILE_MINGW, 1.209 +#endif 1.210 + LIB_FILENAMES_SIZE 1.211 +}; 1.212 +static char libFileNames[LIB_FILENAMES_SIZE][256]; 1.213 + 1.214 +static UPKGOptions *pkg_checkFlag(UPKGOptions *o); 1.215 + 1.216 +const char options_help[][320]={ 1.217 + "Set the data name", 1.218 +#ifdef U_MAKE_IS_NMAKE 1.219 + "The directory where the ICU is located (e.g. <ICUROOT> which contains the bin directory)", 1.220 +#else 1.221 + "Specify options for the builder.", 1.222 +#endif 1.223 + "Specify the mode of building (see below; default: common)", 1.224 + "This usage text", 1.225 + "This usage text", 1.226 + "Make the output verbose", 1.227 + "Use the standard ICU copyright", 1.228 + "Use a custom comment (instead of the copyright)", 1.229 + "Specify the destination directory for files", 1.230 + "Force rebuilding of all data", 1.231 + "Specify temporary dir (default: output dir)", 1.232 + "Install the data (specify target)", 1.233 + "Specify a custom source directory", 1.234 + "Specify a custom entrypoint name (default: short name)", 1.235 + "Specify a version when packaging in dll or static mode", 1.236 + "Add package to all file names if not present", 1.237 + "Library name to build (if different than package name)", 1.238 + "Quite mode. (e.g. Do not output a readme file for static libraries)", 1.239 + "Build the data without assembly code" 1.240 +}; 1.241 + 1.242 +const char *progname = "PKGDATA"; 1.243 + 1.244 +int 1.245 +main(int argc, char* argv[]) { 1.246 + int result = 0; 1.247 + /* FileStream *out; */ 1.248 + UPKGOptions o; 1.249 + CharList *tail; 1.250 + UBool needsHelp = FALSE; 1.251 + UErrorCode status = U_ZERO_ERROR; 1.252 + /* char tmp[1024]; */ 1.253 + uint32_t i; 1.254 + int32_t n; 1.255 + 1.256 + U_MAIN_INIT_ARGS(argc, argv); 1.257 + 1.258 + progname = argv[0]; 1.259 + 1.260 + options[MODE].value = "common"; 1.261 + 1.262 + /* read command line options */ 1.263 + argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); 1.264 + 1.265 + /* error handling, printing usage message */ 1.266 + /* I've decided to simply print an error and quit. This tool has too 1.267 + many options to just display them all of the time. */ 1.268 + 1.269 + if(options[HELP].doesOccur || options[HELP_QUESTION_MARK].doesOccur) { 1.270 + needsHelp = TRUE; 1.271 + } 1.272 + else { 1.273 + if(!needsHelp && argc<0) { 1.274 + fprintf(stderr, 1.275 + "%s: error in command line argument \"%s\"\n", 1.276 + progname, 1.277 + argv[-argc]); 1.278 + fprintf(stderr, "Run '%s --help' for help.\n", progname); 1.279 + return 1; 1.280 + } 1.281 + 1.282 + 1.283 +#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) 1.284 + if(!options[BLDOPT].doesOccur && uprv_strcmp(options[MODE].value, "common") != 0) { 1.285 + if (pkg_getOptionsFromICUConfig(options[VERBOSE].doesOccur, &options[BLDOPT]) != 0) { 1.286 + fprintf(stderr, " required parameter is missing: -O is required for static and shared builds.\n"); 1.287 + fprintf(stderr, "Run '%s --help' for help.\n", progname); 1.288 + return 1; 1.289 + } 1.290 + } 1.291 +#else 1.292 + if(options[BLDOPT].doesOccur) { 1.293 + fprintf(stdout, "Warning: You are using the -O option which is not needed for MSVC build on Windows.\n"); 1.294 + } 1.295 +#endif 1.296 + 1.297 + if(!options[NAME].doesOccur) /* -O we already have - don't report it. */ 1.298 + { 1.299 + fprintf(stderr, " required parameter -p is missing \n"); 1.300 + fprintf(stderr, "Run '%s --help' for help.\n", progname); 1.301 + return 1; 1.302 + } 1.303 + 1.304 + if(argc == 1) { 1.305 + fprintf(stderr, 1.306 + "No input files specified.\n" 1.307 + "Run '%s --help' for help.\n", progname); 1.308 + return 1; 1.309 + } 1.310 + } /* end !needsHelp */ 1.311 + 1.312 + if(argc<0 || needsHelp ) { 1.313 + fprintf(stderr, 1.314 + "usage: %s [-options] [-] [packageFile] \n" 1.315 + "\tProduce packaged ICU data from the given list(s) of files.\n" 1.316 + "\t'-' by itself means to read from stdin.\n" 1.317 + "\tpackageFile is a text file containing the list of files to package.\n", 1.318 + progname); 1.319 + 1.320 + fprintf(stderr, "\n options:\n"); 1.321 + for(i=0;i<(sizeof(options)/sizeof(options[0]));i++) { 1.322 + fprintf(stderr, "%-5s -%c %s%-10s %s\n", 1.323 + (i<1?"[REQ]":""), 1.324 + options[i].shortName, 1.325 + options[i].longName ? "or --" : " ", 1.326 + options[i].longName ? options[i].longName : "", 1.327 + options_help[i]); 1.328 + } 1.329 + 1.330 + fprintf(stderr, "modes: (-m option)\n"); 1.331 + for(i=0;i<(sizeof(modes)/sizeof(modes[0]));i++) { 1.332 + fprintf(stderr, " %-9s ", modes[i].name); 1.333 + if (modes[i].alt_name) { 1.334 + fprintf(stderr, "/ %-9s", modes[i].alt_name); 1.335 + } else { 1.336 + fprintf(stderr, " "); 1.337 + } 1.338 + fprintf(stderr, " %s\n", modes[i].desc); 1.339 + } 1.340 + return 1; 1.341 + } 1.342 + 1.343 + /* OK, fill in the options struct */ 1.344 + uprv_memset(&o, 0, sizeof(o)); 1.345 + 1.346 + o.mode = options[MODE].value; 1.347 + o.version = options[REVISION].doesOccur ? options[REVISION].value : 0; 1.348 + 1.349 + o.shortName = options[NAME].value; 1.350 + { 1.351 + int32_t len = (int32_t)uprv_strlen(o.shortName); 1.352 + char *csname, *cp; 1.353 + const char *sp; 1.354 + 1.355 + cp = csname = (char *) uprv_malloc((len + 1 + 1) * sizeof(*o.cShortName)); 1.356 + if (*(sp = o.shortName)) { 1.357 + *cp++ = isalpha(*sp) ? * sp : '_'; 1.358 + for (++sp; *sp; ++sp) { 1.359 + *cp++ = isalnum(*sp) ? *sp : '_'; 1.360 + } 1.361 + } 1.362 + *cp = 0; 1.363 + 1.364 + o.cShortName = csname; 1.365 + } 1.366 + 1.367 + if(options[LIBNAME].doesOccur) { /* get libname from shortname, or explicit -L parameter */ 1.368 + o.libName = options[LIBNAME].value; 1.369 + } else { 1.370 + o.libName = o.shortName; 1.371 + } 1.372 + 1.373 + if(options[QUIET].doesOccur) { 1.374 + o.quiet = TRUE; 1.375 + } else { 1.376 + o.quiet = FALSE; 1.377 + } 1.378 + 1.379 + if(options[PDS_BUILD].doesOccur) { 1.380 + o.pdsbuild = TRUE; 1.381 + } else { 1.382 + o.pdsbuild = FALSE; 1.383 + } 1.384 + 1.385 + o.verbose = options[VERBOSE].doesOccur; 1.386 + 1.387 + 1.388 +#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) /* on UNIX, we'll just include the file... */ 1.389 + if (options[BLDOPT].doesOccur) { 1.390 + o.options = options[BLDOPT].value; 1.391 + } else { 1.392 + o.options = NULL; 1.393 + } 1.394 +#endif 1.395 + if(options[COPYRIGHT].doesOccur) { 1.396 + o.comment = U_COPYRIGHT_STRING; 1.397 + } else if (options[COMMENT].doesOccur) { 1.398 + o.comment = options[COMMENT].value; 1.399 + } 1.400 + 1.401 + if( options[DESTDIR].doesOccur ) { 1.402 + o.targetDir = options[DESTDIR].value; 1.403 + } else { 1.404 + o.targetDir = "."; /* cwd */ 1.405 + } 1.406 + 1.407 + o.rebuild = options[REBUILD].doesOccur; 1.408 + 1.409 + if( options[TEMPDIR].doesOccur ) { 1.410 + o.tmpDir = options[TEMPDIR].value; 1.411 + } else { 1.412 + o.tmpDir = o.targetDir; 1.413 + } 1.414 + 1.415 + if( options[INSTALL].doesOccur ) { 1.416 + o.install = options[INSTALL].value; 1.417 + } else { 1.418 + o.install = NULL; 1.419 + } 1.420 + 1.421 + if( options[SOURCEDIR].doesOccur ) { 1.422 + o.srcDir = options[SOURCEDIR].value; 1.423 + } else { 1.424 + o.srcDir = "."; 1.425 + } 1.426 + 1.427 + if( options[ENTRYPOINT].doesOccur ) { 1.428 + o.entryName = options[ENTRYPOINT].value; 1.429 + } else { 1.430 + o.entryName = o.cShortName; 1.431 + } 1.432 + 1.433 + o.withoutAssembly = FALSE; 1.434 + if (options[WITHOUT_ASSEMBLY].doesOccur) { 1.435 +#ifndef BUILD_DATA_WITHOUT_ASSEMBLY 1.436 + fprintf(stdout, "Warning: You are using the option to build without assembly code which is not supported on this platform.\n"); 1.437 + fprintf(stdout, "Warning: This option will be ignored.\n"); 1.438 +#else 1.439 + o.withoutAssembly = TRUE; 1.440 +#endif 1.441 + } 1.442 + 1.443 + /* OK options are set up. Now the file lists. */ 1.444 + tail = NULL; 1.445 + for( n=1; n<argc; n++) { 1.446 + o.fileListFiles = pkg_appendToList(o.fileListFiles, &tail, uprv_strdup(argv[n])); 1.447 + } 1.448 + 1.449 + /* load the files */ 1.450 + loadLists(&o, &status); 1.451 + if( U_FAILURE(status) ) { 1.452 + fprintf(stderr, "error loading input file lists: %s\n", u_errorName(status)); 1.453 + return 2; 1.454 + } 1.455 + 1.456 + result = pkg_executeOptions(&o); 1.457 + 1.458 + if (pkgDataFlags != NULL) { 1.459 + for (n = 0; n < PKGDATA_FLAGS_SIZE; n++) { 1.460 + if (pkgDataFlags[n] != NULL) { 1.461 + uprv_free(pkgDataFlags[n]); 1.462 + } 1.463 + } 1.464 + uprv_free(pkgDataFlags); 1.465 + } 1.466 + 1.467 + if (o.cShortName != NULL) { 1.468 + uprv_free((char *)o.cShortName); 1.469 + } 1.470 + if (o.fileListFiles != NULL) { 1.471 + pkg_deleteList(o.fileListFiles); 1.472 + } 1.473 + if (o.filePaths != NULL) { 1.474 + pkg_deleteList(o.filePaths); 1.475 + } 1.476 + if (o.files != NULL) { 1.477 + pkg_deleteList(o.files); 1.478 + } 1.479 + 1.480 + return result; 1.481 +} 1.482 + 1.483 +static int runCommand(const char* command, UBool specialHandling) { 1.484 + char *cmd = NULL; 1.485 + char cmdBuffer[SMALL_BUFFER_MAX_SIZE]; 1.486 + int32_t len = strlen(command); 1.487 + 1.488 + if (len == 0) { 1.489 + return 0; 1.490 + } 1.491 + 1.492 + if (!specialHandling) { 1.493 +#if defined(USING_CYGWIN) || U_PLATFORM == U_PF_MINGW || U_PLATFORM == U_PF_OS400 1.494 + if ((len + BUFFER_PADDING_SIZE) >= SMALL_BUFFER_MAX_SIZE) { 1.495 + cmd = (char *)uprv_malloc(len + BUFFER_PADDING_SIZE); 1.496 + } else { 1.497 + cmd = cmdBuffer; 1.498 + } 1.499 +#if defined(USING_CYGWIN) || U_PLATFORM == U_PF_MINGW 1.500 + sprintf(cmd, "bash -c \"%s\"", command); 1.501 + 1.502 +#elif U_PLATFORM == U_PF_OS400 1.503 + sprintf(cmd, "QSH CMD('%s')", command); 1.504 +#endif 1.505 +#else 1.506 + goto normal_command_mode; 1.507 +#endif 1.508 + } else { 1.509 +#if !(defined(USING_CYGWIN) || U_PLATFORM == U_PF_MINGW || U_PLATFORM == U_PF_OS400) 1.510 +normal_command_mode: 1.511 +#endif 1.512 + cmd = (char *)command; 1.513 + } 1.514 + 1.515 + printf("pkgdata: %s\n", cmd); 1.516 + int result = system(cmd); 1.517 + if (result != 0) { 1.518 + fprintf(stderr, "-- return status = %d\n", result); 1.519 + } 1.520 + 1.521 + if (cmd != cmdBuffer && cmd != command) { 1.522 + uprv_free(cmd); 1.523 + } 1.524 + 1.525 + return result; 1.526 +} 1.527 + 1.528 +#define LN_CMD "ln -s" 1.529 +#define RM_CMD "rm -f" 1.530 + 1.531 +static int32_t pkg_executeOptions(UPKGOptions *o) { 1.532 + int32_t result = 0; 1.533 + 1.534 + const char mode = o->mode[0]; 1.535 + char targetDir[SMALL_BUFFER_MAX_SIZE] = ""; 1.536 + char tmpDir[SMALL_BUFFER_MAX_SIZE] = ""; 1.537 + char datFileName[SMALL_BUFFER_MAX_SIZE] = ""; 1.538 + char datFileNamePath[LARGE_BUFFER_MAX_SIZE] = ""; 1.539 + char checkLibFile[LARGE_BUFFER_MAX_SIZE] = ""; 1.540 + 1.541 + initializePkgDataFlags(o); 1.542 + 1.543 + if (IN_FILES_MODE(mode)) { 1.544 + /* Copy the raw data to the installation directory. */ 1.545 + if (o->install != NULL) { 1.546 + uprv_strcpy(targetDir, o->install); 1.547 + if (o->shortName != NULL) { 1.548 + uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING); 1.549 + uprv_strcat(targetDir, o->shortName); 1.550 + } 1.551 + 1.552 + if(o->verbose) { 1.553 + fprintf(stdout, "# Install: Files mode, copying files to %s..\n", targetDir); 1.554 + } 1.555 + result = pkg_installFileMode(targetDir, o->srcDir, o->fileListFiles->str); 1.556 + } 1.557 + return result; 1.558 + } else /* if (IN_COMMON_MODE(mode) || IN_DLL_MODE(mode) || IN_STATIC_MODE(mode)) */ { 1.559 + UBool noVersion = FALSE; 1.560 + 1.561 + uprv_strcpy(targetDir, o->targetDir); 1.562 + uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING); 1.563 + 1.564 + uprv_strcpy(tmpDir, o->tmpDir); 1.565 + uprv_strcat(tmpDir, PKGDATA_FILE_SEP_STRING); 1.566 + 1.567 + uprv_strcpy(datFileNamePath, tmpDir); 1.568 + 1.569 + uprv_strcpy(datFileName, o->shortName); 1.570 + uprv_strcat(datFileName, UDATA_CMN_SUFFIX); 1.571 + 1.572 + uprv_strcat(datFileNamePath, datFileName); 1.573 + 1.574 + if(o->verbose) { 1.575 + fprintf(stdout, "# Writing package file %s ..\n", datFileNamePath); 1.576 + } 1.577 + result = writePackageDatFile(datFileNamePath, o->comment, o->srcDir, o->fileListFiles->str, NULL, U_CHARSET_FAMILY ? 'e' : U_IS_BIG_ENDIAN ? 'b' : 'l'); 1.578 + if (result != 0) { 1.579 + fprintf(stderr,"Error writing package dat file.\n"); 1.580 + return result; 1.581 + } 1.582 + 1.583 + if (IN_COMMON_MODE(mode)) { 1.584 + char targetFileNamePath[LARGE_BUFFER_MAX_SIZE] = ""; 1.585 + 1.586 + uprv_strcpy(targetFileNamePath, targetDir); 1.587 + uprv_strcat(targetFileNamePath, datFileName); 1.588 + 1.589 + /* Move the dat file created to the target directory. */ 1.590 + if (uprv_strcmp(datFileNamePath, targetFileNamePath) != 0) { 1.591 + if (T_FileStream_file_exists(targetFileNamePath)) { 1.592 + if ((result = remove(targetFileNamePath)) != 0) { 1.593 + fprintf(stderr, "Unable to remove old dat file: %s\n", 1.594 + targetFileNamePath); 1.595 + return result; 1.596 + } 1.597 + } 1.598 + 1.599 + result = rename(datFileNamePath, targetFileNamePath); 1.600 + 1.601 + if (o->verbose) { 1.602 + fprintf(stdout, "# Moving package file to %s ..\n", 1.603 + targetFileNamePath); 1.604 + } 1.605 + if (result != 0) { 1.606 + fprintf( 1.607 + stderr, 1.608 + "Unable to move dat file (%s) to target location (%s).\n", 1.609 + datFileNamePath, targetFileNamePath); 1.610 + return result; 1.611 + } 1.612 + } 1.613 + 1.614 + if (o->install != NULL) { 1.615 + result = pkg_installCommonMode(o->install, targetFileNamePath); 1.616 + } 1.617 + 1.618 + return result; 1.619 + } else /* if (IN_STATIC_MODE(mode) || IN_DLL_MODE(mode)) */ { 1.620 + char gencFilePath[SMALL_BUFFER_MAX_SIZE] = ""; 1.621 + char version_major[10] = ""; 1.622 + UBool reverseExt = FALSE; 1.623 + 1.624 +#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) 1.625 + /* Get the version major number. */ 1.626 + if (o->version != NULL) { 1.627 + for (uint32_t i = 0;i < sizeof(version_major);i++) { 1.628 + if (o->version[i] == '.') { 1.629 + version_major[i] = 0; 1.630 + break; 1.631 + } 1.632 + version_major[i] = o->version[i]; 1.633 + } 1.634 + } else { 1.635 + noVersion = TRUE; 1.636 + if (IN_DLL_MODE(mode)) { 1.637 + fprintf(stdout, "Warning: Providing a revision number with the -r option is recommended when packaging data in the current mode.\n"); 1.638 + } 1.639 + } 1.640 + 1.641 +#if U_PLATFORM != U_PF_OS400 1.642 + /* Certain platforms have different library extension ordering. (e.g. libicudata.##.so vs libicudata.so.##) 1.643 + * reverseExt is FALSE if the suffix should be the version number. 1.644 + */ 1.645 + if (pkgDataFlags[LIB_EXT_ORDER][uprv_strlen(pkgDataFlags[LIB_EXT_ORDER])-1] == pkgDataFlags[SO_EXT][uprv_strlen(pkgDataFlags[SO_EXT])-1]) { 1.646 + reverseExt = TRUE; 1.647 + } 1.648 +#endif 1.649 + /* Using the base libName and version number, generate the library file names. */ 1.650 + createFileNames(o, mode, version_major, o->version == NULL ? "" : o->version, o->libName, reverseExt, noVersion); 1.651 + 1.652 + if ((o->version!=NULL || IN_STATIC_MODE(mode)) && o->rebuild == FALSE) { 1.653 + /* Check to see if a previous built data library file exists and check if it is the latest. */ 1.654 + sprintf(checkLibFile, "%s%s", targetDir, libFileNames[LIB_FILE_VERSION]); 1.655 + if (T_FileStream_file_exists(checkLibFile)) { 1.656 + if (isFileModTimeLater(checkLibFile, o->srcDir, TRUE) && isFileModTimeLater(checkLibFile, o->options)) { 1.657 + if (o->install != NULL) { 1.658 + if(o->verbose) { 1.659 + fprintf(stdout, "# Installing already-built library into %s\n", o->install); 1.660 + } 1.661 + result = pkg_installLibrary(o->install, targetDir, noVersion); 1.662 + } else { 1.663 + if(o->verbose) { 1.664 + printf("# Not rebuilding %s - up to date.\n", checkLibFile); 1.665 + } 1.666 + } 1.667 + return result; 1.668 + } else if (o->verbose && (o->install!=NULL)) { 1.669 + fprintf(stdout, "# Not installing up-to-date library %s into %s\n", checkLibFile, o->install); 1.670 + } 1.671 + } else if(o->verbose && (o->install!=NULL)) { 1.672 + fprintf(stdout, "# Not installing missing %s into %s\n", checkLibFile, o->install); 1.673 + } 1.674 + } 1.675 + 1.676 + if (pkg_checkFlag(o) == NULL) { 1.677 + /* Error occurred. */ 1.678 + return result; 1.679 + } 1.680 +#endif 1.681 + 1.682 + if (!o->withoutAssembly && pkgDataFlags[GENCCODE_ASSEMBLY_TYPE][0] != 0) { 1.683 + const char* genccodeAssembly = pkgDataFlags[GENCCODE_ASSEMBLY_TYPE]; 1.684 + 1.685 + if(o->verbose) { 1.686 + fprintf(stdout, "# Generating assembly code %s of type %s ..\n", gencFilePath, genccodeAssembly); 1.687 + } 1.688 + 1.689 + /* Offset genccodeAssembly by 3 because "-a " */ 1.690 + if (genccodeAssembly && 1.691 + (uprv_strlen(genccodeAssembly)>3) && 1.692 + checkAssemblyHeaderName(genccodeAssembly+3)) { 1.693 + writeAssemblyCode(datFileNamePath, o->tmpDir, o->entryName, NULL, gencFilePath); 1.694 + 1.695 + result = pkg_createWithAssemblyCode(targetDir, mode, gencFilePath); 1.696 + if (result != 0) { 1.697 + fprintf(stderr, "Error generating assembly code for data.\n"); 1.698 + return result; 1.699 + } else if (IN_STATIC_MODE(mode)) { 1.700 + if(o->install != NULL) { 1.701 + if(o->verbose) { 1.702 + fprintf(stdout, "# Installing static library into %s\n", o->install); 1.703 + } 1.704 + result = pkg_installLibrary(o->install, targetDir, noVersion); 1.705 + } 1.706 + return result; 1.707 + } 1.708 + } else { 1.709 + fprintf(stderr,"Assembly type \"%s\" is unknown.\n", genccodeAssembly); 1.710 + return -1; 1.711 + } 1.712 + } else { 1.713 + if(o->verbose) { 1.714 + fprintf(stdout, "# Writing object code to %s ..\n", gencFilePath); 1.715 + } 1.716 + if (o->withoutAssembly) { 1.717 +#ifdef BUILD_DATA_WITHOUT_ASSEMBLY 1.718 + result = pkg_createWithoutAssemblyCode(o, targetDir, mode); 1.719 +#else 1.720 + /* This error should not occur. */ 1.721 + fprintf(stderr, "Error- BUILD_DATA_WITHOUT_ASSEMBLY is not defined. Internal error.\n"); 1.722 +#endif 1.723 + } else { 1.724 +#ifdef CAN_WRITE_OBJ_CODE 1.725 + writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, NULL, NULL, gencFilePath); 1.726 +#if U_PLATFORM_IS_LINUX_BASED 1.727 + result = pkg_generateLibraryFile(targetDir, mode, gencFilePath); 1.728 +#elif defined(WINDOWS_WITH_MSVC) 1.729 + result = pkg_createWindowsDLL(mode, gencFilePath, o); 1.730 +#endif 1.731 +#elif defined(BUILD_DATA_WITHOUT_ASSEMBLY) 1.732 + result = pkg_createWithoutAssemblyCode(o, targetDir, mode); 1.733 +#else 1.734 + fprintf(stderr, "Error- neither CAN_WRITE_OBJ_CODE nor BUILD_DATA_WITHOUT_ASSEMBLY are defined. Internal error.\n"); 1.735 + return 1; 1.736 +#endif 1.737 + } 1.738 + 1.739 + if (result != 0) { 1.740 + fprintf(stderr, "Error generating package data.\n"); 1.741 + return result; 1.742 + } 1.743 + } 1.744 +#if !U_PLATFORM_USES_ONLY_WIN32_API 1.745 + if(!IN_STATIC_MODE(mode)) { 1.746 + /* Certain platforms uses archive library. (e.g. AIX) */ 1.747 + if(o->verbose) { 1.748 + fprintf(stdout, "# Creating data archive library file ..\n"); 1.749 + } 1.750 + result = pkg_archiveLibrary(targetDir, o->version, reverseExt); 1.751 + if (result != 0) { 1.752 + fprintf(stderr, "Error creating data archive library file.\n"); 1.753 + return result; 1.754 + } 1.755 +#if U_PLATFORM != U_PF_OS400 1.756 + if (!noVersion) { 1.757 + /* Create symbolic links for the final library file. */ 1.758 +#if U_PLATFORM == U_PF_OS390 1.759 + if (!o->pdsbuild) { 1.760 + result = pkg_createSymLinks(targetDir, noVersion); 1.761 + } 1.762 +#else 1.763 + result = pkg_createSymLinks(targetDir, noVersion); 1.764 +#endif 1.765 + if (result != 0) { 1.766 + fprintf(stderr, "Error creating symbolic links of the data library file.\n"); 1.767 + return result; 1.768 + } 1.769 + } 1.770 +#endif 1.771 + } /* !IN_STATIC_MODE */ 1.772 +#endif 1.773 + 1.774 +#if !U_PLATFORM_USES_ONLY_WIN32_API 1.775 + /* Install the libraries if option was set. */ 1.776 + if (o->install != NULL) { 1.777 + if(o->verbose) { 1.778 + fprintf(stdout, "# Installing library file to %s ..\n", o->install); 1.779 + } 1.780 + result = pkg_installLibrary(o->install, targetDir, noVersion); 1.781 + if (result != 0) { 1.782 + fprintf(stderr, "Error installing the data library.\n"); 1.783 + return result; 1.784 + } 1.785 + } 1.786 +#endif 1.787 + } 1.788 + } 1.789 + return result; 1.790 +} 1.791 + 1.792 +/* Initialize the pkgDataFlags with the option file given. */ 1.793 +static int32_t initializePkgDataFlags(UPKGOptions *o) { 1.794 + UErrorCode status = U_ZERO_ERROR; 1.795 + int32_t result = 0; 1.796 + int32_t currentBufferSize = SMALL_BUFFER_MAX_SIZE; 1.797 + int32_t tmpResult = 0; 1.798 + 1.799 + /* Initialize pkgdataFlags */ 1.800 + pkgDataFlags = (char**)uprv_malloc(sizeof(char*) * PKGDATA_FLAGS_SIZE); 1.801 + 1.802 + /* If we run out of space, allocate more */ 1.803 +#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) 1.804 + do { 1.805 +#endif 1.806 + if (pkgDataFlags != NULL) { 1.807 + for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { 1.808 + pkgDataFlags[i] = (char*)uprv_malloc(sizeof(char) * currentBufferSize); 1.809 + if (pkgDataFlags[i] != NULL) { 1.810 + pkgDataFlags[i][0] = 0; 1.811 + } else { 1.812 + fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); 1.813 + return -1; 1.814 + } 1.815 + } 1.816 + } else { 1.817 + fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); 1.818 + return -1; 1.819 + } 1.820 + 1.821 + if (o->options == NULL) { 1.822 + return result; 1.823 + } 1.824 + 1.825 +#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) 1.826 + /* Read in options file. */ 1.827 + if(o->verbose) { 1.828 + fprintf(stdout, "# Reading options file %s\n", o->options); 1.829 + } 1.830 + status = U_ZERO_ERROR; 1.831 + tmpResult = parseFlagsFile(o->options, pkgDataFlags, currentBufferSize, FLAG_NAMES, (int32_t)PKGDATA_FLAGS_SIZE, &status); 1.832 + if (status == U_BUFFER_OVERFLOW_ERROR) { 1.833 + for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { 1.834 + uprv_free(pkgDataFlags[i]); 1.835 + } 1.836 + currentBufferSize = tmpResult; 1.837 + } else if (U_FAILURE(status)) { 1.838 + fprintf(stderr,"Unable to open or read \"%s\" option file. status = %s\n", o->options, u_errorName(status)); 1.839 + return -1; 1.840 + } 1.841 +#endif 1.842 + if(o->verbose) { 1.843 + fprintf(stdout, "# pkgDataFlags=\n"); 1.844 + for(int32_t i=0;i<PKGDATA_FLAGS_SIZE;i++) { 1.845 + fprintf(stdout, " [%d] %s: %s\n", i, FLAG_NAMES[i], pkgDataFlags[i]); 1.846 + } 1.847 + fprintf(stdout, "\n"); 1.848 + } 1.849 +#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) 1.850 + } while (status == U_BUFFER_OVERFLOW_ERROR); 1.851 +#endif 1.852 + 1.853 + return result; 1.854 +} 1.855 + 1.856 + 1.857 +/* 1.858 + * Given the base libName and version numbers, generate the libary file names and store it in libFileNames. 1.859 + * Depending on the configuration, the library name may either end with version number or shared object suffix. 1.860 + */ 1.861 +static void createFileNames(UPKGOptions *o, const char mode, const char *version_major, const char *version, const char *libName, UBool reverseExt, UBool noVersion) { 1.862 +#if U_PLATFORM == U_PF_MINGW 1.863 + /* MinGW does not need the library prefix when building in dll mode. */ 1.864 + if (IN_DLL_MODE(mode)) { 1.865 + sprintf(libFileNames[LIB_FILE], "%s", libName); 1.866 + } else { 1.867 + sprintf(libFileNames[LIB_FILE], "%s%s", 1.868 + pkgDataFlags[LIBPREFIX], 1.869 + libName); 1.870 + } 1.871 +#else 1.872 + sprintf(libFileNames[LIB_FILE], "%s%s", 1.873 + pkgDataFlags[LIBPREFIX], 1.874 + libName); 1.875 +#endif 1.876 + 1.877 + if(o->verbose) { 1.878 + fprintf(stdout, "# libFileName[LIB_FILE] = %s\n", libFileNames[LIB_FILE]); 1.879 + } 1.880 + 1.881 +#if U_PLATFORM == U_PF_MINGW 1.882 + sprintf(libFileNames[LIB_FILE_MINGW], "%s%s.lib", pkgDataFlags[LIBPREFIX], libName); 1.883 +#elif U_PLATFORM == U_PF_CYGWIN 1.884 + sprintf(libFileNames[LIB_FILE_CYGWIN], "cyg%s.%s", 1.885 + libName, 1.886 + pkgDataFlags[SO_EXT]); 1.887 + sprintf(libFileNames[LIB_FILE_CYGWIN_VERSION], "cyg%s%s.%s", 1.888 + libName, 1.889 + version_major, 1.890 + pkgDataFlags[SO_EXT]); 1.891 + 1.892 + uprv_strcat(pkgDataFlags[SO_EXT], "."); 1.893 + uprv_strcat(pkgDataFlags[SO_EXT], pkgDataFlags[A_EXT]); 1.894 +#elif U_PLATFORM == U_PF_OS400 || defined(_AIX) 1.895 + sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s.%s", 1.896 + libFileNames[LIB_FILE], 1.897 + pkgDataFlags[SOBJ_EXT]); 1.898 +#elif U_PLATFROM == U_PF_OS390 1.899 + if (o->pdsbuild) { 1.900 + sprintf(libFileNames[LIB_FILE], "%s", 1.901 + libName); 1.902 + sprintf(libFileNames[LIB_FILE_VERSION_TMP], "\"%s\"", 1.903 + libFileNames[LIB_FILE]); 1.904 + } else { 1.905 + sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s%s%s.%s", 1.906 + libFileNames[LIB_FILE], 1.907 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.908 + reverseExt ? version : pkgDataFlags[SOBJ_EXT], 1.909 + reverseExt ? pkgDataFlags[SOBJ_EXT] : version); 1.910 + } 1.911 +#else 1.912 + if (noVersion && !reverseExt) { 1.913 + sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s%s%s", 1.914 + libFileNames[LIB_FILE], 1.915 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.916 + pkgDataFlags[SOBJ_EXT]); 1.917 + } else { 1.918 + sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s%s%s.%s", 1.919 + libFileNames[LIB_FILE], 1.920 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.921 + reverseExt ? version : pkgDataFlags[SOBJ_EXT], 1.922 + reverseExt ? pkgDataFlags[SOBJ_EXT] : version); 1.923 + } 1.924 +#endif 1.925 + if (noVersion && !reverseExt) { 1.926 + sprintf(libFileNames[LIB_FILE_VERSION_MAJOR], "%s%s%s", 1.927 + libFileNames[LIB_FILE], 1.928 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.929 + pkgDataFlags[SO_EXT]); 1.930 + 1.931 + sprintf(libFileNames[LIB_FILE_VERSION], "%s%s%s", 1.932 + libFileNames[LIB_FILE], 1.933 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.934 + pkgDataFlags[SO_EXT]); 1.935 + } else { 1.936 + sprintf(libFileNames[LIB_FILE_VERSION_MAJOR], "%s%s%s.%s", 1.937 + libFileNames[LIB_FILE], 1.938 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.939 + reverseExt ? version_major : pkgDataFlags[SO_EXT], 1.940 + reverseExt ? pkgDataFlags[SO_EXT] : version_major); 1.941 + 1.942 + sprintf(libFileNames[LIB_FILE_VERSION], "%s%s%s.%s", 1.943 + libFileNames[LIB_FILE], 1.944 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.945 + reverseExt ? version : pkgDataFlags[SO_EXT], 1.946 + reverseExt ? pkgDataFlags[SO_EXT] : version); 1.947 + } 1.948 + 1.949 + if(o->verbose) { 1.950 + fprintf(stdout, "# libFileName[LIB_FILE_VERSION] = %s\n", libFileNames[LIB_FILE_VERSION]); 1.951 + } 1.952 + 1.953 +#if U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 1.954 + /* Cygwin and MinGW only deals with the version major number. */ 1.955 + uprv_strcpy(libFileNames[LIB_FILE_VERSION_TMP], libFileNames[LIB_FILE_VERSION_MAJOR]); 1.956 +#endif 1.957 + 1.958 + if(IN_STATIC_MODE(mode)) { 1.959 + sprintf(libFileNames[LIB_FILE_VERSION], "%s.%s", libFileNames[LIB_FILE], pkgDataFlags[A_EXT]); 1.960 + libFileNames[LIB_FILE_VERSION_MAJOR][0]=0; 1.961 + if(o->verbose) { 1.962 + fprintf(stdout, "# libFileName[LIB_FILE_VERSION] = %s (static)\n", libFileNames[LIB_FILE_VERSION]); 1.963 + } 1.964 + } 1.965 +} 1.966 + 1.967 +/* Create the symbolic links for the final library file. */ 1.968 +static int32_t pkg_createSymLinks(const char *targetDir, UBool specialHandling) { 1.969 + int32_t result = 0; 1.970 + char cmd[LARGE_BUFFER_MAX_SIZE]; 1.971 + char name1[SMALL_BUFFER_MAX_SIZE]; /* symlink file name */ 1.972 + char name2[SMALL_BUFFER_MAX_SIZE]; /* file name to symlink */ 1.973 + 1.974 +#if !defined(USING_CYGWIN) && U_PLATFORM != U_PF_MINGW 1.975 + /* No symbolic link to make. */ 1.976 + if (uprv_strlen(libFileNames[LIB_FILE_VERSION]) == 0 || uprv_strlen(libFileNames[LIB_FILE_VERSION_MAJOR]) == 0 || 1.977 + uprv_strcmp(libFileNames[LIB_FILE_VERSION], libFileNames[LIB_FILE_VERSION_MAJOR]) == 0) { 1.978 + return result; 1.979 + } 1.980 + 1.981 + sprintf(cmd, "cd %s && %s %s && %s %s %s", 1.982 + targetDir, 1.983 + RM_CMD, 1.984 + libFileNames[LIB_FILE_VERSION_MAJOR], 1.985 + LN_CMD, 1.986 + libFileNames[LIB_FILE_VERSION], 1.987 + libFileNames[LIB_FILE_VERSION_MAJOR]); 1.988 + result = runCommand(cmd); 1.989 + if (result != 0) { 1.990 + fprintf(stderr, "Error creating symbolic links. Failed command: %s\n", cmd); 1.991 + return result; 1.992 + } 1.993 +#endif 1.994 + 1.995 + if (specialHandling) { 1.996 +#if U_PLATFORM == U_PF_CYGWIN 1.997 + sprintf(name1, "%s", libFileNames[LIB_FILE_CYGWIN]); 1.998 + sprintf(name2, "%s", libFileNames[LIB_FILE_CYGWIN_VERSION]); 1.999 +#else 1.1000 + goto normal_symlink_mode; 1.1001 +#endif 1.1002 + } else { 1.1003 +#if U_PLATFORM != U_PF_CYGWIN 1.1004 +normal_symlink_mode: 1.1005 +#endif 1.1006 + sprintf(name1, "%s.%s", libFileNames[LIB_FILE], pkgDataFlags[SO_EXT]); 1.1007 + sprintf(name2, "%s", libFileNames[LIB_FILE_VERSION]); 1.1008 + } 1.1009 + 1.1010 + sprintf(cmd, "cd %s && %s %s && %s %s %s", 1.1011 + targetDir, 1.1012 + RM_CMD, 1.1013 + name1, 1.1014 + LN_CMD, 1.1015 + name2, 1.1016 + name1); 1.1017 + 1.1018 + result = runCommand(cmd); 1.1019 + 1.1020 + return result; 1.1021 +} 1.1022 + 1.1023 +static int32_t pkg_installLibrary(const char *installDir, const char *targetDir, UBool noVersion) { 1.1024 + int32_t result = 0; 1.1025 + char cmd[SMALL_BUFFER_MAX_SIZE]; 1.1026 + 1.1027 + sprintf(cmd, "cd %s && %s %s %s%s%s", 1.1028 + targetDir, 1.1029 + pkgDataFlags[INSTALL_CMD], 1.1030 + libFileNames[LIB_FILE_VERSION], 1.1031 + installDir, PKGDATA_FILE_SEP_STRING, libFileNames[LIB_FILE_VERSION] 1.1032 + ); 1.1033 + 1.1034 + result = runCommand(cmd); 1.1035 + 1.1036 + if (result != 0) { 1.1037 + fprintf(stderr, "Error installing library. Failed command: %s\n", cmd); 1.1038 + return result; 1.1039 + } 1.1040 + 1.1041 +#ifdef CYGWINMSVC 1.1042 + sprintf(cmd, "cd %s && %s %s.lib %s", 1.1043 + targetDir, 1.1044 + pkgDataFlags[INSTALL_CMD], 1.1045 + libFileNames[LIB_FILE], 1.1046 + installDir 1.1047 + ); 1.1048 + result = runCommand(cmd); 1.1049 + 1.1050 + if (result != 0) { 1.1051 + fprintf(stderr, "Error installing library. Failed command: %s\n", cmd); 1.1052 + return result; 1.1053 + } 1.1054 +#elif U_PLATFORM == U_PF_CYGWIN 1.1055 + sprintf(cmd, "cd %s && %s %s %s", 1.1056 + targetDir, 1.1057 + pkgDataFlags[INSTALL_CMD], 1.1058 + libFileNames[LIB_FILE_CYGWIN_VERSION], 1.1059 + installDir 1.1060 + ); 1.1061 + result = runCommand(cmd); 1.1062 + 1.1063 + if (result != 0) { 1.1064 + fprintf(stderr, "Error installing library. Failed command: %s\n", cmd); 1.1065 + return result; 1.1066 + } 1.1067 +#endif 1.1068 + 1.1069 + if (noVersion) { 1.1070 + return result; 1.1071 + } else { 1.1072 + return pkg_createSymLinks(installDir, TRUE); 1.1073 + } 1.1074 +} 1.1075 + 1.1076 +static int32_t pkg_installCommonMode(const char *installDir, const char *fileName) { 1.1077 + int32_t result = 0; 1.1078 + char cmd[SMALL_BUFFER_MAX_SIZE] = ""; 1.1079 + 1.1080 + if (!T_FileStream_file_exists(installDir)) { 1.1081 + UErrorCode status = U_ZERO_ERROR; 1.1082 + 1.1083 + uprv_mkdir(installDir, &status); 1.1084 + if (U_FAILURE(status)) { 1.1085 + fprintf(stderr, "Error creating installation directory: %s\n", installDir); 1.1086 + return -1; 1.1087 + } 1.1088 + } 1.1089 +#ifndef U_WINDOWS_WITH_MSVC 1.1090 + sprintf(cmd, "%s %s %s", pkgDataFlags[INSTALL_CMD], fileName, installDir); 1.1091 +#else 1.1092 + sprintf(cmd, "%s %s %s %s", WIN_INSTALL_CMD, fileName, installDir, WIN_INSTALL_CMD_FLAGS); 1.1093 +#endif 1.1094 + 1.1095 + result = runCommand(cmd); 1.1096 + if (result != 0) { 1.1097 + fprintf(stderr, "Failed to install data file with command: %s\n", cmd); 1.1098 + } 1.1099 + 1.1100 + return result; 1.1101 +} 1.1102 + 1.1103 +#ifdef U_WINDOWS_MSVC 1.1104 +/* Copy commands for installing the raw data files on Windows. */ 1.1105 +#define WIN_INSTALL_CMD "xcopy" 1.1106 +#define WIN_INSTALL_CMD_FLAGS "/E /Y /K" 1.1107 +#endif 1.1108 +static int32_t pkg_installFileMode(const char *installDir, const char *srcDir, const char *fileListName) { 1.1109 + int32_t result = 0; 1.1110 + char cmd[SMALL_BUFFER_MAX_SIZE] = ""; 1.1111 + 1.1112 + if (!T_FileStream_file_exists(installDir)) { 1.1113 + UErrorCode status = U_ZERO_ERROR; 1.1114 + 1.1115 + uprv_mkdir(installDir, &status); 1.1116 + if (U_FAILURE(status)) { 1.1117 + fprintf(stderr, "Error creating installation directory: %s\n", installDir); 1.1118 + return -1; 1.1119 + } 1.1120 + } 1.1121 +#ifndef U_WINDOWS_WITH_MSVC 1.1122 + char buffer[SMALL_BUFFER_MAX_SIZE] = ""; 1.1123 + int32_t bufferLength = 0; 1.1124 + 1.1125 + FileStream *f = T_FileStream_open(fileListName, "r"); 1.1126 + if (f != NULL) { 1.1127 + for(;;) { 1.1128 + if (T_FileStream_readLine(f, buffer, SMALL_BUFFER_MAX_SIZE) != NULL) { 1.1129 + bufferLength = uprv_strlen(buffer); 1.1130 + /* Remove new line character. */ 1.1131 + if (bufferLength > 0) { 1.1132 + buffer[bufferLength-1] = 0; 1.1133 + } 1.1134 + 1.1135 + sprintf(cmd, "%s %s%s%s %s%s%s", 1.1136 + pkgDataFlags[INSTALL_CMD], 1.1137 + srcDir, PKGDATA_FILE_SEP_STRING, buffer, 1.1138 + installDir, PKGDATA_FILE_SEP_STRING, buffer); 1.1139 + 1.1140 + result = runCommand(cmd); 1.1141 + if (result != 0) { 1.1142 + fprintf(stderr, "Failed to install data file with command: %s\n", cmd); 1.1143 + break; 1.1144 + } 1.1145 + } else { 1.1146 + if (!T_FileStream_eof(f)) { 1.1147 + fprintf(stderr, "Failed to read line from file: %s\n", fileListName); 1.1148 + result = -1; 1.1149 + } 1.1150 + break; 1.1151 + } 1.1152 + } 1.1153 + T_FileStream_close(f); 1.1154 + } else { 1.1155 + result = -1; 1.1156 + fprintf(stderr, "Unable to open list file: %s\n", fileListName); 1.1157 + } 1.1158 +#else 1.1159 + sprintf(cmd, "%s %s %s %s", WIN_INSTALL_CMD, srcDir, installDir, WIN_INSTALL_CMD_FLAGS); 1.1160 + result = runCommand(cmd); 1.1161 + if (result != 0) { 1.1162 + fprintf(stderr, "Failed to install data file with command: %s\n", cmd); 1.1163 + } 1.1164 +#endif 1.1165 + 1.1166 + return result; 1.1167 +} 1.1168 + 1.1169 +/* Archiving of the library file may be needed depending on the platform and options given. 1.1170 + * If archiving is not needed, copy over the library file name. 1.1171 + */ 1.1172 +static int32_t pkg_archiveLibrary(const char *targetDir, const char *version, UBool reverseExt) { 1.1173 + int32_t result = 0; 1.1174 + char cmd[LARGE_BUFFER_MAX_SIZE]; 1.1175 + 1.1176 + /* If the shared object suffix and the final object suffix is different and the final object suffix and the 1.1177 + * archive file suffix is the same, then the final library needs to be archived. 1.1178 + */ 1.1179 + if (uprv_strcmp(pkgDataFlags[SOBJ_EXT], pkgDataFlags[SO_EXT]) != 0 && uprv_strcmp(pkgDataFlags[A_EXT], pkgDataFlags[SO_EXT]) == 0) { 1.1180 + sprintf(libFileNames[LIB_FILE_VERSION], "%s%s%s.%s", 1.1181 + libFileNames[LIB_FILE], 1.1182 + pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "", 1.1183 + reverseExt ? version : pkgDataFlags[SO_EXT], 1.1184 + reverseExt ? pkgDataFlags[SO_EXT] : version); 1.1185 + 1.1186 + sprintf(cmd, "%s %s %s%s %s%s", 1.1187 + pkgDataFlags[AR], 1.1188 + pkgDataFlags[ARFLAGS], 1.1189 + targetDir, 1.1190 + libFileNames[LIB_FILE_VERSION], 1.1191 + targetDir, 1.1192 + libFileNames[LIB_FILE_VERSION_TMP]); 1.1193 + 1.1194 + result = runCommand(cmd); 1.1195 + if (result != 0) { 1.1196 + fprintf(stderr, "Error creating archive library. Failed command: %s\n", cmd); 1.1197 + return result; 1.1198 + } 1.1199 + 1.1200 + sprintf(cmd, "%s %s%s", 1.1201 + pkgDataFlags[RANLIB], 1.1202 + targetDir, 1.1203 + libFileNames[LIB_FILE_VERSION]); 1.1204 + 1.1205 + result = runCommand(cmd); 1.1206 + if (result != 0) { 1.1207 + fprintf(stderr, "Error creating archive library. Failed command: %s\n", cmd); 1.1208 + return result; 1.1209 + } 1.1210 + 1.1211 + /* Remove unneeded library file. */ 1.1212 + sprintf(cmd, "%s %s%s", 1.1213 + RM_CMD, 1.1214 + targetDir, 1.1215 + libFileNames[LIB_FILE_VERSION_TMP]); 1.1216 + 1.1217 + result = runCommand(cmd); 1.1218 + if (result != 0) { 1.1219 + fprintf(stderr, "Error creating archive library. Failed command: %s\n", cmd); 1.1220 + return result; 1.1221 + } 1.1222 + 1.1223 + } else { 1.1224 + uprv_strcpy(libFileNames[LIB_FILE_VERSION], libFileNames[LIB_FILE_VERSION_TMP]); 1.1225 + } 1.1226 + 1.1227 + return result; 1.1228 +} 1.1229 + 1.1230 +/* 1.1231 + * Using the compiler information from the configuration file set by -O option, generate the library file. 1.1232 + * command may be given to allow for a larger buffer for cmd. 1.1233 + */ 1.1234 +static int32_t pkg_generateLibraryFile(const char *targetDir, const char mode, const char *objectFile, char *command) { 1.1235 + int32_t result = 0; 1.1236 + char *cmd = NULL; 1.1237 + UBool freeCmd = FALSE; 1.1238 + int32_t length = 0; 1.1239 + 1.1240 + /* This is necessary because if packaging is done without assembly code, objectFile might be extremely large 1.1241 + * containing many object files and so the calling function should supply a command buffer that is large 1.1242 + * enough to handle this. Otherwise, use the default size. 1.1243 + */ 1.1244 + if (command != NULL) { 1.1245 + cmd = command; 1.1246 + } 1.1247 + 1.1248 + if (IN_STATIC_MODE(mode)) { 1.1249 + if (cmd == NULL) { 1.1250 + length = uprv_strlen(pkgDataFlags[AR]) + uprv_strlen(pkgDataFlags[ARFLAGS]) + uprv_strlen(targetDir) + 1.1251 + uprv_strlen(libFileNames[LIB_FILE_VERSION]) + uprv_strlen(objectFile) + uprv_strlen(pkgDataFlags[RANLIB]) + BUFFER_PADDING_SIZE; 1.1252 + if ((cmd = (char *)uprv_malloc(sizeof(char) * length)) == NULL) { 1.1253 + fprintf(stderr, "Unable to allocate memory for command.\n"); 1.1254 + return -1; 1.1255 + } 1.1256 + freeCmd = TRUE; 1.1257 + } 1.1258 + sprintf(cmd, "%s %s %s%s %s", 1.1259 + pkgDataFlags[AR], 1.1260 + pkgDataFlags[ARFLAGS], 1.1261 + targetDir, 1.1262 + libFileNames[LIB_FILE_VERSION], 1.1263 + objectFile); 1.1264 + 1.1265 + result = runCommand(cmd); 1.1266 + if (result == 0) { 1.1267 + sprintf(cmd, "%s %s%s", 1.1268 + pkgDataFlags[RANLIB], 1.1269 + targetDir, 1.1270 + libFileNames[LIB_FILE_VERSION]); 1.1271 + 1.1272 + result = runCommand(cmd); 1.1273 + } 1.1274 + } else /* if (IN_DLL_MODE(mode)) */ { 1.1275 + if (cmd == NULL) { 1.1276 + length = uprv_strlen(pkgDataFlags[GENLIB]) + uprv_strlen(pkgDataFlags[LDICUDTFLAGS]) + 1.1277 + ((uprv_strlen(targetDir) + uprv_strlen(libFileNames[LIB_FILE_VERSION_TMP])) * 2) + 1.1278 + uprv_strlen(objectFile) + uprv_strlen(pkgDataFlags[LD_SONAME]) + 1.1279 + uprv_strlen(pkgDataFlags[LD_SONAME][0] == 0 ? "" : libFileNames[LIB_FILE_VERSION_MAJOR]) + 1.1280 + uprv_strlen(pkgDataFlags[RPATH_FLAGS]) + uprv_strlen(pkgDataFlags[BIR_FLAGS]) + BUFFER_PADDING_SIZE; 1.1281 +#if U_PLATFORM == U_PF_CYGWIN 1.1282 + length += uprv_strlen(targetDir) + uprv_strlen(libFileNames[LIB_FILE_CYGWIN_VERSION]); 1.1283 +#elif U_PLATFORM == U_PF_MINGW 1.1284 + length += uprv_strlen(targetDir) + uprv_strlen(libFileNames[LIB_FILE_MINGW]); 1.1285 +#endif 1.1286 + if ((cmd = (char *)uprv_malloc(sizeof(char) * length)) == NULL) { 1.1287 + fprintf(stderr, "Unable to allocate memory for command.\n"); 1.1288 + return -1; 1.1289 + } 1.1290 + freeCmd = TRUE; 1.1291 + } 1.1292 +#if U_PLATFORM == U_PF_MINGW 1.1293 + sprintf(cmd, "%s%s%s %s -o %s%s %s %s%s %s %s", 1.1294 + pkgDataFlags[GENLIB], 1.1295 + targetDir, 1.1296 + libFileNames[LIB_FILE_MINGW], 1.1297 + pkgDataFlags[LDICUDTFLAGS], 1.1298 + targetDir, 1.1299 + libFileNames[LIB_FILE_VERSION_TMP], 1.1300 +#elif U_PLATFORM == U_PF_CYGWIN 1.1301 + sprintf(cmd, "%s%s%s %s -o %s%s %s %s%s %s %s", 1.1302 + pkgDataFlags[GENLIB], 1.1303 + targetDir, 1.1304 + libFileNames[LIB_FILE_VERSION_TMP], 1.1305 + pkgDataFlags[LDICUDTFLAGS], 1.1306 + targetDir, 1.1307 + libFileNames[LIB_FILE_CYGWIN_VERSION], 1.1308 +#elif U_PLATFORM == U_PF_AIX 1.1309 + sprintf(cmd, "%s %s%s;%s %s -o %s%s %s %s%s %s %s", 1.1310 + RM_CMD, 1.1311 + targetDir, 1.1312 + libFileNames[LIB_FILE_VERSION_TMP], 1.1313 + pkgDataFlags[GENLIB], 1.1314 + pkgDataFlags[LDICUDTFLAGS], 1.1315 + targetDir, 1.1316 + libFileNames[LIB_FILE_VERSION_TMP], 1.1317 +#else 1.1318 + sprintf(cmd, "%s %s -o %s%s %s %s%s %s %s", 1.1319 + pkgDataFlags[GENLIB], 1.1320 + pkgDataFlags[LDICUDTFLAGS], 1.1321 + targetDir, 1.1322 + libFileNames[LIB_FILE_VERSION_TMP], 1.1323 +#endif 1.1324 + objectFile, 1.1325 + pkgDataFlags[LD_SONAME], 1.1326 + pkgDataFlags[LD_SONAME][0] == 0 ? "" : libFileNames[LIB_FILE_VERSION_MAJOR], 1.1327 + pkgDataFlags[RPATH_FLAGS], 1.1328 + pkgDataFlags[BIR_FLAGS]); 1.1329 + 1.1330 + /* Generate the library file. */ 1.1331 + result = runCommand(cmd); 1.1332 + 1.1333 +#if U_PLATFORM == U_PF_OS390 && defined(OS390BATCH) 1.1334 + char PDS_LibName[512]; 1.1335 + if (uprv_strcmp(libFileNames[LIB_FILE],"libicudata") == 0) { 1.1336 + sprintf(PDS_LibName,"%s%s%s", 1.1337 + "\"//'", 1.1338 + getenv("LOADMOD"), 1.1339 + "(IXMI" U_ICU_VERSION_SHORT "DA)'\""); 1.1340 + } else if (uprv_strcmp(libFileNames[LIB_FILE],"libicudata_stub") == 0) { 1.1341 + sprintf(PDS_LibName,"%s%s%s", 1.1342 + "\"//'", 1.1343 + getenv("LOADMOD"), 1.1344 + "(IXMI" U_ICU_VERSION_SHORT "D1)'\""); 1.1345 + sprintf(cmd, "%s %s -o %s %s %s%s %s %s", 1.1346 + pkgDataFlags[GENLIB], 1.1347 + pkgDataFlags[LDICUDTFLAGS], 1.1348 + PDS_LibName, 1.1349 + objectFile, 1.1350 + pkgDataFlags[LD_SONAME], 1.1351 + pkgDataFlags[LD_SONAME][0] == 0 ? "" : libFileNames[LIB_FILE_VERSION_MAJOR], 1.1352 + pkgDataFlags[RPATH_FLAGS], 1.1353 + pkgDataFlags[BIR_FLAGS]); 1.1354 + } 1.1355 + result = runCommand(cmd); 1.1356 +#endif 1.1357 + } 1.1358 + 1.1359 + if (result != 0) { 1.1360 + fprintf(stderr, "Error generating library file. Failed command: %s\n", cmd); 1.1361 + } 1.1362 + 1.1363 + if (freeCmd) { 1.1364 + uprv_free(cmd); 1.1365 + } 1.1366 + 1.1367 + return result; 1.1368 +} 1.1369 + 1.1370 +static int32_t pkg_createWithAssemblyCode(const char *targetDir, const char mode, const char *gencFilePath) { 1.1371 + char tempObjectFile[SMALL_BUFFER_MAX_SIZE] = ""; 1.1372 + char *cmd; 1.1373 + int32_t result = 0; 1.1374 + 1.1375 + int32_t length = 0; 1.1376 + 1.1377 + /* Remove the ending .s and replace it with .o for the new object file. */ 1.1378 + uprv_strcpy(tempObjectFile, gencFilePath); 1.1379 + tempObjectFile[uprv_strlen(tempObjectFile)-1] = 'o'; 1.1380 + 1.1381 + length = uprv_strlen(pkgDataFlags[COMPILER]) + uprv_strlen(pkgDataFlags[LIBFLAGS]) 1.1382 + + uprv_strlen(tempObjectFile) + uprv_strlen(gencFilePath) + BUFFER_PADDING_SIZE; 1.1383 + 1.1384 + cmd = (char *)uprv_malloc(sizeof(char) * length); 1.1385 + if (cmd == NULL) { 1.1386 + return -1; 1.1387 + } 1.1388 + 1.1389 + /* Generate the object file. */ 1.1390 + sprintf(cmd, "%s %s -o %s %s", 1.1391 + pkgDataFlags[COMPILER], 1.1392 + pkgDataFlags[LIBFLAGS], 1.1393 + tempObjectFile, 1.1394 + gencFilePath); 1.1395 + 1.1396 + result = runCommand(cmd); 1.1397 + uprv_free(cmd); 1.1398 + if (result != 0) { 1.1399 + fprintf(stderr, "Error creating with assembly code. Failed command: %s\n", cmd); 1.1400 + return result; 1.1401 + } 1.1402 + 1.1403 + return pkg_generateLibraryFile(targetDir, mode, tempObjectFile); 1.1404 +} 1.1405 + 1.1406 +#ifdef BUILD_DATA_WITHOUT_ASSEMBLY 1.1407 +/* 1.1408 + * Generation of the data library without assembly code needs to compile each data file 1.1409 + * individually and then link it all together. 1.1410 + * Note: Any update to the directory structure of the data needs to be reflected here. 1.1411 + */ 1.1412 +enum { 1.1413 + DATA_PREFIX_BRKITR, 1.1414 + DATA_PREFIX_COLL, 1.1415 + DATA_PREFIX_CURR, 1.1416 + DATA_PREFIX_LANG, 1.1417 + DATA_PREFIX_RBNF, 1.1418 + DATA_PREFIX_REGION, 1.1419 + DATA_PREFIX_TRANSLIT, 1.1420 + DATA_PREFIX_ZONE, 1.1421 + DATA_PREFIX_LENGTH 1.1422 +}; 1.1423 + 1.1424 +const static char DATA_PREFIX[DATA_PREFIX_LENGTH][10] = { 1.1425 + "brkitr", 1.1426 + "coll", 1.1427 + "curr", 1.1428 + "lang", 1.1429 + "rbnf", 1.1430 + "region", 1.1431 + "translit", 1.1432 + "zone" 1.1433 +}; 1.1434 + 1.1435 +static int32_t pkg_createWithoutAssemblyCode(UPKGOptions *o, const char *targetDir, const char mode) { 1.1436 + int32_t result = 0; 1.1437 + CharList *list = o->filePaths; 1.1438 + CharList *listNames = o->files; 1.1439 + int32_t listSize = pkg_countCharList(list); 1.1440 + char *buffer; 1.1441 + char *cmd; 1.1442 + char gencmnFile[SMALL_BUFFER_MAX_SIZE] = ""; 1.1443 + char tempObjectFile[SMALL_BUFFER_MAX_SIZE] = ""; 1.1444 +#ifdef USE_SINGLE_CCODE_FILE 1.1445 + char icudtAll[SMALL_BUFFER_MAX_SIZE] = ""; 1.1446 + FileStream *icudtAllFile = NULL; 1.1447 + 1.1448 + sprintf(icudtAll, "%s%s%sall.c", 1.1449 + o->tmpDir, 1.1450 + PKGDATA_FILE_SEP_STRING, 1.1451 + libFileNames[LIB_FILE]); 1.1452 + /* Remove previous icudtall.c file. */ 1.1453 + if (T_FileStream_file_exists(icudtAll) && (result = remove(icudtAll)) != 0) { 1.1454 + fprintf(stderr, "Unable to remove old icudtall file: %s\n", icudtAll); 1.1455 + return result; 1.1456 + } 1.1457 + 1.1458 + if((icudtAllFile = T_FileStream_open(icudtAll, "w"))==NULL) { 1.1459 + fprintf(stderr, "Unable to write to icudtall file: %s\n", icudtAll); 1.1460 + return result; 1.1461 + } 1.1462 +#endif 1.1463 + 1.1464 + if (list == NULL || listNames == NULL) { 1.1465 + /* list and listNames should never be NULL since we are looping through the CharList with 1.1466 + * the given size. 1.1467 + */ 1.1468 + return -1; 1.1469 + } 1.1470 + 1.1471 + if ((cmd = (char *)uprv_malloc((listSize + 2) * SMALL_BUFFER_MAX_SIZE)) == NULL) { 1.1472 + fprintf(stderr, "Unable to allocate memory for cmd.\n"); 1.1473 + return -1; 1.1474 + } else if ((buffer = (char *)uprv_malloc((listSize + 1) * SMALL_BUFFER_MAX_SIZE)) == NULL) { 1.1475 + fprintf(stderr, "Unable to allocate memory for buffer.\n"); 1.1476 + uprv_free(cmd); 1.1477 + return -1; 1.1478 + } 1.1479 + 1.1480 + for (int32_t i = 0; i < (listSize + 1); i++) { 1.1481 + const char *file ; 1.1482 + const char *name; 1.1483 + 1.1484 + if (i == 0) { 1.1485 + /* The first iteration calls the gencmn function and initailizes the buffer. */ 1.1486 + createCommonDataFile(o->tmpDir, o->shortName, o->entryName, NULL, o->srcDir, o->comment, o->fileListFiles->str, 0, TRUE, o->verbose, gencmnFile); 1.1487 + buffer[0] = 0; 1.1488 +#ifdef USE_SINGLE_CCODE_FILE 1.1489 + uprv_strcpy(tempObjectFile, gencmnFile); 1.1490 + tempObjectFile[uprv_strlen(tempObjectFile) - 1] = 'o'; 1.1491 + 1.1492 + sprintf(cmd, "%s %s -o %s %s", 1.1493 + pkgDataFlags[COMPILER], 1.1494 + pkgDataFlags[LIBFLAGS], 1.1495 + tempObjectFile, 1.1496 + gencmnFile); 1.1497 + 1.1498 + result = runCommand(cmd); 1.1499 + if (result != 0) { 1.1500 + break; 1.1501 + } 1.1502 + 1.1503 + sprintf(buffer, "%s",tempObjectFile); 1.1504 +#endif 1.1505 + } else { 1.1506 + char newName[SMALL_BUFFER_MAX_SIZE]; 1.1507 + char dataName[SMALL_BUFFER_MAX_SIZE]; 1.1508 + char dataDirName[SMALL_BUFFER_MAX_SIZE]; 1.1509 + const char *pSubstring; 1.1510 + file = list->str; 1.1511 + name = listNames->str; 1.1512 + 1.1513 + newName[0] = dataName[0] = 0; 1.1514 + for (int32_t n = 0; n < DATA_PREFIX_LENGTH; n++) { 1.1515 + dataDirName[0] = 0; 1.1516 + sprintf(dataDirName, "%s%s", DATA_PREFIX[n], PKGDATA_FILE_SEP_STRING); 1.1517 + /* If the name contains a prefix (indicating directory), alter the new name accordingly. */ 1.1518 + pSubstring = uprv_strstr(name, dataDirName); 1.1519 + if (pSubstring != NULL) { 1.1520 + char newNameTmp[SMALL_BUFFER_MAX_SIZE] = ""; 1.1521 + const char *p = name + uprv_strlen(dataDirName); 1.1522 + for (int32_t i = 0;;i++) { 1.1523 + if (p[i] == '.') { 1.1524 + newNameTmp[i] = '_'; 1.1525 + continue; 1.1526 + } 1.1527 + newNameTmp[i] = p[i]; 1.1528 + if (p[i] == 0) { 1.1529 + break; 1.1530 + } 1.1531 + } 1.1532 + sprintf(newName, "%s_%s", 1.1533 + DATA_PREFIX[n], 1.1534 + newNameTmp); 1.1535 + sprintf(dataName, "%s_%s", 1.1536 + o->shortName, 1.1537 + DATA_PREFIX[n]); 1.1538 + } 1.1539 + if (newName[0] != 0) { 1.1540 + break; 1.1541 + } 1.1542 + } 1.1543 + 1.1544 + if(o->verbose) { 1.1545 + printf("# Generating %s \n", gencmnFile); 1.1546 + } 1.1547 + 1.1548 + writeCCode(file, o->tmpDir, dataName[0] != 0 ? dataName : o->shortName, newName[0] != 0 ? newName : NULL, gencmnFile); 1.1549 + 1.1550 +#ifdef USE_SINGLE_CCODE_FILE 1.1551 + sprintf(cmd, "#include \"%s\"\n", gencmnFile); 1.1552 + T_FileStream_writeLine(icudtAllFile, cmd); 1.1553 + /* don't delete the file */ 1.1554 +#endif 1.1555 + } 1.1556 + 1.1557 +#ifndef USE_SINGLE_CCODE_FILE 1.1558 + uprv_strcpy(tempObjectFile, gencmnFile); 1.1559 + tempObjectFile[uprv_strlen(tempObjectFile) - 1] = 'o'; 1.1560 + 1.1561 + sprintf(cmd, "%s %s -o %s %s", 1.1562 + pkgDataFlags[COMPILER], 1.1563 + pkgDataFlags[LIBFLAGS], 1.1564 + tempObjectFile, 1.1565 + gencmnFile); 1.1566 + result = runCommand(cmd); 1.1567 + if (result != 0) { 1.1568 + fprintf(stderr, "Error creating library without assembly code. Failed command: %s\n", cmd); 1.1569 + break; 1.1570 + } 1.1571 + 1.1572 + uprv_strcat(buffer, " "); 1.1573 + uprv_strcat(buffer, tempObjectFile); 1.1574 + 1.1575 +#endif 1.1576 + 1.1577 + if (i > 0) { 1.1578 + list = list->next; 1.1579 + listNames = listNames->next; 1.1580 + } 1.1581 + } 1.1582 + 1.1583 +#ifdef USE_SINGLE_CCODE_FILE 1.1584 + T_FileStream_close(icudtAllFile); 1.1585 + uprv_strcpy(tempObjectFile, icudtAll); 1.1586 + tempObjectFile[uprv_strlen(tempObjectFile) - 1] = 'o'; 1.1587 + 1.1588 + sprintf(cmd, "%s %s -I. -o %s %s", 1.1589 + pkgDataFlags[COMPILER], 1.1590 + pkgDataFlags[LIBFLAGS], 1.1591 + tempObjectFile, 1.1592 + icudtAll); 1.1593 + 1.1594 + result = runCommand(cmd); 1.1595 + if (result == 0) { 1.1596 + uprv_strcat(buffer, " "); 1.1597 + uprv_strcat(buffer, tempObjectFile); 1.1598 + } else { 1.1599 + fprintf(stderr, "Error creating library without assembly code. Failed command: %s\n", cmd); 1.1600 + } 1.1601 +#endif 1.1602 + 1.1603 + if (result == 0) { 1.1604 + /* Generate the library file. */ 1.1605 +#if U_PLATFORM == U_PF_OS390 1.1606 + if (o->pdsbuild && IN_DLL_MODE(mode)) { 1.1607 + result = pkg_generateLibraryFile("",mode, buffer, cmd); 1.1608 + } else { 1.1609 + result = pkg_generateLibraryFile(targetDir,mode, buffer, cmd); 1.1610 + } 1.1611 +#else 1.1612 + result = pkg_generateLibraryFile(targetDir,mode, buffer, cmd); 1.1613 +#endif 1.1614 + } 1.1615 + 1.1616 + uprv_free(buffer); 1.1617 + uprv_free(cmd); 1.1618 + 1.1619 + return result; 1.1620 +} 1.1621 +#endif 1.1622 + 1.1623 +#ifdef WINDOWS_WITH_MSVC 1.1624 +#define LINK_CMD "link.exe /nologo /release /out:" 1.1625 +#define LINK_FLAGS "/DLL /NOENTRY /MANIFEST:NO /base:0x4ad00000 /implib:" 1.1626 +#define LIB_CMD "LIB.exe /nologo /out:" 1.1627 +#define LIB_FILE "icudt.lib" 1.1628 +#define LIB_EXT UDATA_LIB_SUFFIX 1.1629 +#define DLL_EXT UDATA_SO_SUFFIX 1.1630 + 1.1631 +static int32_t pkg_createWindowsDLL(const char mode, const char *gencFilePath, UPKGOptions *o) { 1.1632 + int32_t result = 0; 1.1633 + char cmd[LARGE_BUFFER_MAX_SIZE]; 1.1634 + if (IN_STATIC_MODE(mode)) { 1.1635 + char staticLibFilePath[SMALL_BUFFER_MAX_SIZE] = ""; 1.1636 + 1.1637 +#ifdef CYGWINMSVC 1.1638 + sprintf(staticLibFilePath, "%s%s%s%s%s", 1.1639 + o->targetDir, 1.1640 + PKGDATA_FILE_SEP_STRING, 1.1641 + pkgDataFlags[LIBPREFIX], 1.1642 + o->libName, 1.1643 + LIB_EXT); 1.1644 +#else 1.1645 + sprintf(staticLibFilePath, "%s%s%s%s%s", 1.1646 + o->targetDir, 1.1647 + PKGDATA_FILE_SEP_STRING, 1.1648 + (strstr(o->libName, "icudt") ? "s" : ""), 1.1649 + o->libName, 1.1650 + LIB_EXT); 1.1651 +#endif 1.1652 + 1.1653 + sprintf(cmd, "%s\"%s\" \"%s\"", 1.1654 + LIB_CMD, 1.1655 + staticLibFilePath, 1.1656 + gencFilePath); 1.1657 + } else if (IN_DLL_MODE(mode)) { 1.1658 + char dllFilePath[SMALL_BUFFER_MAX_SIZE] = ""; 1.1659 + char libFilePath[SMALL_BUFFER_MAX_SIZE] = ""; 1.1660 + char resFilePath[SMALL_BUFFER_MAX_SIZE] = ""; 1.1661 + char tmpResFilePath[SMALL_BUFFER_MAX_SIZE] = ""; 1.1662 + 1.1663 +#ifdef CYGWINMSVC 1.1664 + uprv_strcpy(dllFilePath, o->targetDir); 1.1665 +#else 1.1666 + uprv_strcpy(dllFilePath, o->srcDir); 1.1667 +#endif 1.1668 + uprv_strcat(dllFilePath, PKGDATA_FILE_SEP_STRING); 1.1669 + uprv_strcpy(libFilePath, dllFilePath); 1.1670 + 1.1671 +#ifdef CYGWINMSVC 1.1672 + uprv_strcat(libFilePath, o->libName); 1.1673 + uprv_strcat(libFilePath, ".lib"); 1.1674 + 1.1675 + uprv_strcat(dllFilePath, o->libName); 1.1676 + uprv_strcat(dllFilePath, o->version); 1.1677 +#else 1.1678 + if (strstr(o->libName, "icudt")) { 1.1679 + uprv_strcat(libFilePath, LIB_FILE); 1.1680 + } else { 1.1681 + uprv_strcat(libFilePath, o->libName); 1.1682 + uprv_strcat(libFilePath, ".lib"); 1.1683 + } 1.1684 + uprv_strcat(dllFilePath, o->entryName); 1.1685 +#endif 1.1686 + uprv_strcat(dllFilePath, DLL_EXT); 1.1687 + 1.1688 + uprv_strcpy(tmpResFilePath, o->tmpDir); 1.1689 + uprv_strcat(tmpResFilePath, PKGDATA_FILE_SEP_STRING); 1.1690 + uprv_strcat(tmpResFilePath, ICUDATA_RES_FILE); 1.1691 + 1.1692 + if (T_FileStream_file_exists(tmpResFilePath)) { 1.1693 + sprintf(resFilePath, "\"%s\"", tmpResFilePath); 1.1694 + } 1.1695 + 1.1696 + /* Check if dll file and lib file exists and that it is not newer than genc file. */ 1.1697 + if (!o->rebuild && (T_FileStream_file_exists(dllFilePath) && isFileModTimeLater(dllFilePath, gencFilePath)) && 1.1698 + (T_FileStream_file_exists(libFilePath) && isFileModTimeLater(libFilePath, gencFilePath))) { 1.1699 + if(o->verbose) { 1.1700 + printf("# Not rebuilding %s - up to date.\n", gencFilePath); 1.1701 + } 1.1702 + return 0; 1.1703 + } 1.1704 + 1.1705 + sprintf(cmd, "%s\"%s\" %s\"%s\" \"%s\" %s", 1.1706 + LINK_CMD, 1.1707 + dllFilePath, 1.1708 + LINK_FLAGS, 1.1709 + libFilePath, 1.1710 + gencFilePath, 1.1711 + resFilePath 1.1712 + ); 1.1713 + } 1.1714 + 1.1715 + result = runCommand(cmd, TRUE); 1.1716 + if (result != 0) { 1.1717 + fprintf(stderr, "Error creating Windows DLL library. Failed command: %s\n", cmd); 1.1718 + } 1.1719 + 1.1720 + return result; 1.1721 +} 1.1722 +#endif 1.1723 + 1.1724 +static UPKGOptions *pkg_checkFlag(UPKGOptions *o) { 1.1725 +#if U_PLATFORM == U_PF_AIX 1.1726 + /* AIX needs a map file. */ 1.1727 + char *flag = NULL; 1.1728 + int32_t length = 0; 1.1729 + char tmpbuffer[SMALL_BUFFER_MAX_SIZE]; 1.1730 + const char MAP_FILE_EXT[] = ".map"; 1.1731 + FileStream *f = NULL; 1.1732 + char mapFile[SMALL_BUFFER_MAX_SIZE] = ""; 1.1733 + int32_t start = -1; 1.1734 + uint32_t count = 0; 1.1735 + const char rm_cmd[] = "rm -f all ;"; 1.1736 + 1.1737 + flag = pkgDataFlags[GENLIB]; 1.1738 + 1.1739 + /* This portion of the code removes 'rm -f all' in the GENLIB. 1.1740 + * Only occurs in AIX. 1.1741 + */ 1.1742 + if (uprv_strstr(flag, rm_cmd) != NULL) { 1.1743 + char *tmpGenlibFlagBuffer = NULL; 1.1744 + int32_t i, offset; 1.1745 + 1.1746 + length = uprv_strlen(flag) + 1; 1.1747 + tmpGenlibFlagBuffer = (char *)uprv_malloc(length); 1.1748 + if (tmpGenlibFlagBuffer == NULL) { 1.1749 + /* Memory allocation error */ 1.1750 + fprintf(stderr,"Unable to allocate buffer of size: %d.\n", length); 1.1751 + return NULL; 1.1752 + } 1.1753 + 1.1754 + uprv_strcpy(tmpGenlibFlagBuffer, flag); 1.1755 + 1.1756 + offset = uprv_strlen(rm_cmd); 1.1757 + 1.1758 + for (i = 0; i < (length - offset); i++) { 1.1759 + flag[i] = tmpGenlibFlagBuffer[offset + i]; 1.1760 + } 1.1761 + 1.1762 + /* Zero terminate the string */ 1.1763 + flag[i] = 0; 1.1764 + 1.1765 + uprv_free(tmpGenlibFlagBuffer); 1.1766 + } 1.1767 + 1.1768 + flag = pkgDataFlags[BIR_FLAGS]; 1.1769 + length = uprv_strlen(pkgDataFlags[BIR_FLAGS]); 1.1770 + 1.1771 + for (int32_t i = 0; i < length; i++) { 1.1772 + if (flag[i] == MAP_FILE_EXT[count]) { 1.1773 + if (count == 0) { 1.1774 + start = i; 1.1775 + } 1.1776 + count++; 1.1777 + } else { 1.1778 + count = 0; 1.1779 + } 1.1780 + 1.1781 + if (count == uprv_strlen(MAP_FILE_EXT)) { 1.1782 + break; 1.1783 + } 1.1784 + } 1.1785 + 1.1786 + if (start >= 0) { 1.1787 + int32_t index = 0; 1.1788 + for (int32_t i = 0;;i++) { 1.1789 + if (i == start) { 1.1790 + for (int32_t n = 0;;n++) { 1.1791 + if (o->shortName[n] == 0) { 1.1792 + break; 1.1793 + } 1.1794 + tmpbuffer[index++] = o->shortName[n]; 1.1795 + } 1.1796 + } 1.1797 + 1.1798 + tmpbuffer[index++] = flag[i]; 1.1799 + 1.1800 + if (flag[i] == 0) { 1.1801 + break; 1.1802 + } 1.1803 + } 1.1804 + 1.1805 + uprv_memset(flag, 0, length); 1.1806 + uprv_strcpy(flag, tmpbuffer); 1.1807 + 1.1808 + uprv_strcpy(mapFile, o->shortName); 1.1809 + uprv_strcat(mapFile, MAP_FILE_EXT); 1.1810 + 1.1811 + f = T_FileStream_open(mapFile, "w"); 1.1812 + if (f == NULL) { 1.1813 + fprintf(stderr,"Unable to create map file: %s.\n", mapFile); 1.1814 + return NULL; 1.1815 + } else { 1.1816 + sprintf(tmpbuffer, "%s%s ", o->entryName, UDATA_CMN_INTERMEDIATE_SUFFIX); 1.1817 + 1.1818 + T_FileStream_writeLine(f, tmpbuffer); 1.1819 + 1.1820 + T_FileStream_close(f); 1.1821 + } 1.1822 + } 1.1823 +#elif U_PLATFORM == U_PF_CYGWIN || U_PLATFORM == U_PF_MINGW 1.1824 + /* Cygwin needs to change flag options. */ 1.1825 + char *flag = NULL; 1.1826 + int32_t length = 0; 1.1827 + 1.1828 + flag = pkgDataFlags[GENLIB]; 1.1829 + length = uprv_strlen(pkgDataFlags[GENLIB]); 1.1830 + 1.1831 + int32_t position = length - 1; 1.1832 + 1.1833 + for(;position >= 0;position--) { 1.1834 + if (flag[position] == '=') { 1.1835 + position++; 1.1836 + break; 1.1837 + } 1.1838 + } 1.1839 + 1.1840 + uprv_memset(flag + position, 0, length - position); 1.1841 +#elif U_PLATFORM == U_PF_OS400 1.1842 + /* OS/400 needs to fix the ld options (swap single quote with double quote) */ 1.1843 + char *flag = NULL; 1.1844 + int32_t length = 0; 1.1845 + 1.1846 + flag = pkgDataFlags[GENLIB]; 1.1847 + length = uprv_strlen(pkgDataFlags[GENLIB]); 1.1848 + 1.1849 + int32_t position = length - 1; 1.1850 + 1.1851 + for(int32_t i = 0; i < length; i++) { 1.1852 + if (flag[i] == '\'') { 1.1853 + flag[i] = '\"'; 1.1854 + } 1.1855 + } 1.1856 +#endif 1.1857 + // Don't really need a return value, just need to stop compiler warnings about 1.1858 + // the unused parameter 'o' on platforms where it is not otherwise used. 1.1859 + return o; 1.1860 +} 1.1861 + 1.1862 +static void loadLists(UPKGOptions *o, UErrorCode *status) 1.1863 +{ 1.1864 + CharList *l, *tail = NULL, *tail2 = NULL; 1.1865 + FileStream *in; 1.1866 + char line[16384]; 1.1867 + char *linePtr, *lineNext; 1.1868 + const uint32_t lineMax = 16300; 1.1869 + char *tmp; 1.1870 + int32_t tmpLength = 0; 1.1871 + char *s; 1.1872 + int32_t ln=0; /* line number */ 1.1873 + 1.1874 + for(l = o->fileListFiles; l; l = l->next) { 1.1875 + if(o->verbose) { 1.1876 + fprintf(stdout, "# pkgdata: Reading %s..\n", l->str); 1.1877 + } 1.1878 + /* TODO: stdin */ 1.1879 + in = T_FileStream_open(l->str, "r"); /* open files list */ 1.1880 + 1.1881 + if(!in) { 1.1882 + fprintf(stderr, "Error opening <%s>.\n", l->str); 1.1883 + *status = U_FILE_ACCESS_ERROR; 1.1884 + return; 1.1885 + } 1.1886 + 1.1887 + while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) { /* for each line */ 1.1888 + ln++; 1.1889 + if(uprv_strlen(line)>lineMax) { 1.1890 + fprintf(stderr, "%s:%d - line too long (over %d chars)\n", l->str, (int)ln, (int)lineMax); 1.1891 + exit(1); 1.1892 + } 1.1893 + /* remove spaces at the beginning */ 1.1894 + linePtr = line; 1.1895 + /* On z/OS, disable call to isspace (#9996). Investigate using uprv_isspace instead (#9999) */ 1.1896 +#if U_PLATFORM != U_PF_OS390 1.1897 + while(isspace(*linePtr)) { 1.1898 + linePtr++; 1.1899 + } 1.1900 +#endif 1.1901 + s=linePtr; 1.1902 + /* remove trailing newline characters */ 1.1903 + while(*s!=0) { 1.1904 + if(*s=='\r' || *s=='\n') { 1.1905 + *s=0; 1.1906 + break; 1.1907 + } 1.1908 + ++s; 1.1909 + } 1.1910 + if((*linePtr == 0) || (*linePtr == '#')) { 1.1911 + continue; /* comment or empty line */ 1.1912 + } 1.1913 + 1.1914 + /* Now, process the line */ 1.1915 + lineNext = NULL; 1.1916 + 1.1917 + while(linePtr && *linePtr) { /* process space-separated items */ 1.1918 + while(*linePtr == ' ') { 1.1919 + linePtr++; 1.1920 + } 1.1921 + /* Find the next quote */ 1.1922 + if(linePtr[0] == '"') 1.1923 + { 1.1924 + lineNext = uprv_strchr(linePtr+1, '"'); 1.1925 + if(lineNext == NULL) { 1.1926 + fprintf(stderr, "%s:%d - missing trailing double quote (\")\n", 1.1927 + l->str, (int)ln); 1.1928 + exit(1); 1.1929 + } else { 1.1930 + lineNext++; 1.1931 + if(*lineNext) { 1.1932 + if(*lineNext != ' ') { 1.1933 + fprintf(stderr, "%s:%d - malformed quoted line at position %d, expected ' ' got '%c'\n", 1.1934 + l->str, (int)ln, (int)(lineNext-line), (*lineNext)?*lineNext:'0'); 1.1935 + exit(1); 1.1936 + } 1.1937 + *lineNext = 0; 1.1938 + lineNext++; 1.1939 + } 1.1940 + } 1.1941 + } else { 1.1942 + lineNext = uprv_strchr(linePtr, ' '); 1.1943 + if(lineNext) { 1.1944 + *lineNext = 0; /* terminate at space */ 1.1945 + lineNext++; 1.1946 + } 1.1947 + } 1.1948 + 1.1949 + /* add the file */ 1.1950 + s = (char*)getLongPathname(linePtr); 1.1951 + 1.1952 + /* normal mode.. o->files is just the bare list without package names */ 1.1953 + o->files = pkg_appendToList(o->files, &tail, uprv_strdup(linePtr)); 1.1954 + if(uprv_pathIsAbsolute(s) || s[0] == '.') { 1.1955 + fprintf(stderr, "pkgdata: 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, s); 1.1956 + exit(U_ILLEGAL_ARGUMENT_ERROR); 1.1957 + } 1.1958 + tmpLength = uprv_strlen(o->srcDir) + 1.1959 + uprv_strlen(s) + 5; /* 5 is to add a little extra space for, among other things, PKGDATA_FILE_SEP_STRING */ 1.1960 + if((tmp = (char *)uprv_malloc(tmpLength)) == NULL) { 1.1961 + fprintf(stderr, "pkgdata: Error: Unable to allocate tmp buffer size: %d\n", tmpLength); 1.1962 + exit(U_MEMORY_ALLOCATION_ERROR); 1.1963 + } 1.1964 + uprv_strcpy(tmp, o->srcDir); 1.1965 + uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1] == U_FILE_SEP_CHAR ? "" : PKGDATA_FILE_SEP_STRING); 1.1966 + uprv_strcat(tmp, s); 1.1967 + o->filePaths = pkg_appendToList(o->filePaths, &tail2, tmp); 1.1968 + linePtr = lineNext; 1.1969 + } /* for each entry on line */ 1.1970 + } /* for each line */ 1.1971 + T_FileStream_close(in); 1.1972 + } /* for each file list file */ 1.1973 +} 1.1974 + 1.1975 +/* Try calling icu-config directly to get the option file. */ 1.1976 + static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option) { 1.1977 +#if U_HAVE_POPEN 1.1978 + FILE *p = NULL; 1.1979 + size_t n; 1.1980 + static char buf[512] = ""; 1.1981 + char cmdBuf[1024]; 1.1982 + UErrorCode status = U_ZERO_ERROR; 1.1983 + const char cmd[] = "icu-config --incpkgdatafile"; 1.1984 + 1.1985 + /* #1 try the same path where pkgdata was called from. */ 1.1986 + findDirname(progname, cmdBuf, 1024, &status); 1.1987 + if(U_SUCCESS(status)) { 1.1988 + if (cmdBuf[0] != 0) { 1.1989 + uprv_strncat(cmdBuf, U_FILE_SEP_STRING, 1024); 1.1990 + } 1.1991 + uprv_strncat(cmdBuf, cmd, 1024); 1.1992 + 1.1993 + if(verbose) { 1.1994 + fprintf(stdout, "# Calling icu-config: %s\n", cmdBuf); 1.1995 + } 1.1996 + p = popen(cmdBuf, "r"); 1.1997 + } 1.1998 + 1.1999 + if(p == NULL || (n = fread(buf, 1, 511, p)) <= 0) { 1.2000 + if(verbose) { 1.2001 + fprintf(stdout, "# Calling icu-config: %s\n", cmd); 1.2002 + } 1.2003 + pclose(p); 1.2004 + 1.2005 + p = popen(cmd, "r"); 1.2006 + if(p == NULL || (n = fread(buf, 1, 511, p)) <= 0) { 1.2007 + fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname); 1.2008 + return -1; 1.2009 + } 1.2010 + } 1.2011 + 1.2012 + pclose(p); 1.2013 + 1.2014 + for (int32_t length = strlen(buf) - 1; length >= 0; length--) { 1.2015 + if (buf[length] == '\n' || buf[length] == ' ') { 1.2016 + buf[length] = 0; 1.2017 + } else { 1.2018 + break; 1.2019 + } 1.2020 + } 1.2021 + 1.2022 + if(buf[strlen(buf)-1]=='\n') 1.2023 + { 1.2024 + buf[strlen(buf)-1]=0; 1.2025 + } 1.2026 + 1.2027 + if(buf[0] == 0) 1.2028 + { 1.2029 + fprintf(stderr, "%s: icu-config: invalid response from icu-config (fix PATH or use -O option)\n", progname); 1.2030 + return -1; 1.2031 + } 1.2032 + 1.2033 + if(verbose) { 1.2034 + fprintf(stdout, "# icu-config said: %s\n", buf); 1.2035 + } 1.2036 + 1.2037 + option->value = buf; 1.2038 + option->doesOccur = TRUE; 1.2039 + 1.2040 + return 0; 1.2041 +#else 1.2042 + return -1; 1.2043 +#endif 1.2044 +}