X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..6de34a005df0e4a02d88750703b950237b77d9c8:/icuSources/tools/pkgdata/pkgdata.c diff --git a/icuSources/tools/pkgdata/pkgdata.c b/icuSources/tools/pkgdata/pkgdata.c index 2427c4fc..041ebdbf 100644 --- a/icuSources/tools/pkgdata/pkgdata.c +++ b/icuSources/tools/pkgdata/pkgdata.c @@ -1,6 +1,6 @@ /****************************************************************************** * -* Copyright (C) 2000-2003, International Business Machines +* Copyright (C) 2000-2004, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -16,20 +16,28 @@ * (DLL, common data, etc.) */ -#include -#include #include "unicode/utypes.h" #include "unicode/putil.h" #include "cmemory.h" #include "cstring.h" #include "filestrm.h" #include "toolutil.h" +#include "unicode/uclean.h" #include "unewdata.h" #include "uoptions.h" #if U_HAVE_POPEN +/* + We define __USE_POSIX2 so that we can get popen and pclose when + --enable-strict is used +*/ +# ifndef __USE_POSIX2 +# define __USE_POSIX2 1 +# endif # include #endif +#include +#include U_CDECL_BEGIN #include "pkgtypes.h" @@ -51,17 +59,17 @@ static struct } modes[] = { { "files", 0, pkg_mode_files, "Uses raw data files (no effect). Installation copies all files to the target location." }, -#ifdef WIN32 +#ifdef U_MAKE_IS_NMAKE { "dll", "library", pkg_mode_windows, "Generates one common data file and one shared library, .dll"}, { "common", "archive", pkg_mode_windows, "Generates just the common file, .dat"}, { "static", "static", pkg_mode_windows, "Generates one statically linked library, " LIB_PREFIX "" UDATA_LIB_SUFFIX } -#else /*#ifdef WIN32*/ +#else /*#ifdef U_MAKE_IS_NMAKE*/ #ifdef UDATA_SO_SUFFIX { "dll", "library", pkg_mode_dll, "Generates one shared library, " UDATA_SO_SUFFIX }, #endif { "common", "archive", pkg_mode_common, "Generates one common data file, .dat" }, { "static", "static", pkg_mode_static, "Generates one statically linked library, " LIB_PREFIX "" UDATA_LIB_SUFFIX } -#endif /*#ifdef WIN32*/ +#endif /*#ifdef U_MAKE_IS_NMAKE*/ }; static UOption options[]={ @@ -83,13 +91,17 @@ static UOption options[]={ /*15*/ UOPTION_DEF( "entrypoint", 'e', UOPT_REQUIRES_ARG), /*16*/ UOPTION_DEF( "revision", 'r', UOPT_REQUIRES_ARG), /*17*/ UOPTION_DEF( 0, 'M', UOPT_REQUIRES_ARG), - /*18*/ UOPTION_DEF( "force-prefix", 'f', UOPT_NO_ARG) + /*18*/ UOPTION_DEF( "force-prefix", 'f', UOPT_NO_ARG), + /*19*/ UOPTION_DEF( "numerictmp", 'N', UOPT_NO_ARG), + /*20*/ UOPTION_DEF( "embed", 'E', UOPT_NO_ARG), + /*21*/ UOPTION_DEF( "libname", 'L', UOPT_REQUIRES_ARG), + /*22*/ UOPTION_DEF( "quiet", 'q', UOPT_NO_ARG) }; -const char options_help[][160]={ +const char options_help[][320]={ "Set the data name", -#ifdef WIN32 - "R:icupath for release version or D:icupath for debug version, where icupath is the directory where ICU is located", +#ifdef U_MAKE_IS_NMAKE + "The directory where the ICU is located (e.g. which contains the bin directory)", #else "Specify options for the builder. (Autdetected if icu-config is available)", #endif @@ -109,7 +121,11 @@ const char options_help[][160]={ "Specify a custom entrypoint name (default: short name)", "Specify a version when packaging in DLL or static mode", "Pass the next argument to make(1)", - "Add package to all file names if not present" + "Add package to all file names if not present", + "Use short numeric temporary file names such as t1234.c", + "Use Embedded paths (such as 'mypackage_') - for compatibility.", + "Library name to build (if different than package name)", + "Quite mode. (e.g. Do not output a readme file for static libraries)" }; const char *progname = "PKGDATA"; @@ -152,21 +168,28 @@ main(int argc, char* argv[]) { } if(!options[1].doesOccur) { - /* Try to fill in from icu-config or equivalent */ - fillInMakefileFromICUConfig(&options[1]); + /* Try to fill in from icu-config or equivalent */ + fillInMakefileFromICUConfig(&options[1]); + } +#ifdef U_MAKE_IS_NMAKE + else { + fprintf(stderr, "Warning: You are using the deprecated -O option\n" + "\tYou can fix this warning by installing pkgdata, gencmn and genccode\n" + "\tinto the same directory and not specifying the -O option to pkgdata.\n"); } +#endif if(!options[1].doesOccur) { - fprintf(stderr, " required parameter is missing: -O is required \n"); - fprintf(stderr, "Run '%s --help' for help.\n", progname); - return 1; + fprintf(stderr, " required parameter is missing: -O is required \n"); + fprintf(stderr, "Run '%s --help' for help.\n", progname); + return 1; } - + if(!options[0].doesOccur) /* -O we already have - don't report it. */ { - fprintf(stderr, " required parameter -p is missing \n"); - fprintf(stderr, "Run '%s --help' for help.\n", progname); - return 1; + fprintf(stderr, " required parameter -p is missing \n"); + fprintf(stderr, "Run '%s --help' for help.\n", progname); + return 1; } if(argc == 1) { @@ -188,7 +211,7 @@ main(int argc, char* argv[]) { fprintf(stderr, "\n options:\n"); for(i=0;i<(sizeof(options)/sizeof(options[0]));i++) { fprintf(stderr, "%-5s -%c %s%-10s %s\n", - (i<2?"[REQ]":""), + (i<1?"[REQ]":""), options[i].shortName, options[i].longName ? "or --" : " ", options[i].longName ? options[i].longName : "", @@ -234,8 +257,8 @@ main(int argc, char* argv[]) { } o.shortName = options[0].value; - /**/ { - int len = uprv_strlen(o.shortName); + { + int32_t len = (int32_t)uprv_strlen(o.shortName); char *csname, *cp; const char *sp; @@ -251,32 +274,48 @@ main(int argc, char* argv[]) { o.cShortName = csname; } -#ifdef WIN32 /* format is R:pathtoICU or D:pathtoICU */ + if(options[21].doesOccur) { /* get libname from shortname, or explicit -L parameter */ + o.libName = options[21].value; + } else { + o.libName = o.shortName; + } + + if(options[22].doesOccur) { + o.quiet = TRUE; + } else { + o.quiet = FALSE; + } + + o.verbose = options[5].doesOccur; +#ifdef U_MAKE_IS_NMAKE /* format is R:pathtoICU or D:pathtoICU */ { char *pathstuff = (char *)options[1].value; if(options[1].value[uprv_strlen(options[1].value)-1] == '\\') { pathstuff[uprv_strlen(options[1].value)-1] = '\0'; } - if(*pathstuff == 'R' || *pathstuff == 'D') { + if(*pathstuff == PKGDATA_DERIVED_PATH || *pathstuff == 'R' || *pathstuff == 'D') { o.options = pathstuff; pathstuff++; if(*pathstuff == ':') { *pathstuff = '\0'; pathstuff++; - } else { - fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n", o.mode, progname); + } + else { + fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n"); return 1; } } else { - fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n", o.mode, progname); + fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n"); return 1; } o.icuroot = pathstuff; + if (o.verbose) { + fprintf(stdout, "# ICUROOT is %s\n", o.icuroot); + } } #else /* on UNIX, we'll just include the file... */ o.options = options[1].value; #endif - o.verbose = options[5].doesOccur; if(options[6].doesOccur) { o.comment = U_COPYRIGHT_STRING; } else if (options[7].doesOccur) { @@ -292,6 +331,12 @@ main(int argc, char* argv[]) { o.clean = options[9].doesOccur; o.nooutput = options[10].doesOccur; o.rebuild = options[11].doesOccur; + o.numeric = options[19].doesOccur; + if(o.numeric) { + o.rebuild = TRUE; /* force rebuild if numeric */ + } + + o.embed = options[20].doesOccur; if( options[12].doesOccur ) { o.tmpDir = options[12].value; @@ -439,12 +484,12 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) char line[16384]; char *linePtr, *lineNext; const uint32_t lineMax = 16300; - char tmp[1024], tmp2[1024]; + char tmp[1024]; char pkgPrefix[1024]; int32_t pkgPrefixLen; const char *baseName; char *s; - int32_t ln; + int32_t ln=0; /* line number */ UBool fixPrefix; @@ -452,187 +497,218 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) strcpy(pkgPrefix, o->shortName); strcat(pkgPrefix, "_"); - pkgPrefixLen=uprv_strlen(pkgPrefix); + pkgPrefixLen=(int32_t)uprv_strlen(pkgPrefix); for(l = o->fileListFiles; l; l = l->next) { if(o->verbose) { fprintf(stdout, "# Reading %s..\n", l->str); } /* TODO: stdin */ - in = T_FileStream_open(l->str, "r"); + in = T_FileStream_open(l->str, "r"); /* open files list */ if(!in) { fprintf(stderr, "Error opening <%s>.\n", l->str); *status = U_FILE_ACCESS_ERROR; return; } - - ln = 0; - - while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) { - ln++; - if(uprv_strlen(line)>lineMax) { - fprintf(stderr, "%s:%d - line too long (over %d chars)\n", l->str, ln, lineMax); - exit(1); + + while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) { /* for each line */ + if((ln == 0) && (!o->embed)) { + /* determine if we need to run in 'embed' (compatibility) mode */ + if(!strncmp(findBasename(line), pkgPrefix, pkgPrefixLen)) { + fprintf(stderr, "Warning: Found path '%s' in file name. Assuming compatibility (-E) mode.\n", pkgPrefix); + o->embed = 1; } - /* remove spaces at the beginning */ - linePtr = line; - while(isspace(*linePtr)) { - linePtr++; + } + ln++; + if(uprv_strlen(line)>lineMax) { + fprintf(stderr, "%s:%d - line too long (over %d chars)\n", l->str, (int)ln, (int)lineMax); + exit(1); + } + /* remove spaces at the beginning */ + linePtr = line; + while(isspace(*linePtr)) { + linePtr++; + } + s=linePtr; + /* remove trailing newline characters */ + while(*s!=0) { + if(*s=='\r' || *s=='\n') { + *s=0; + break; } - s=linePtr; - /* remove trailing newline characters */ - while(*s!=0) { - if(*s=='\r' || *s=='\n') { - *s=0; - break; - } ++s; + } + if((*linePtr == 0) || (*linePtr == '#')) { + continue; /* comment or empty line */ + } + + /* Now, process the line */ + lineNext = NULL; + + while(linePtr && *linePtr) { /* process space-separated items */ + while(*linePtr == ' ') { + linePtr++; } - if((*linePtr == 0) || (*linePtr == '#')) { - continue; /* comment or empty line */ - } - - /* Now, process the line */ - lineNext = NULL; - - while(linePtr && *linePtr) { - while(*linePtr == ' ') { - linePtr++; - } - /* Find the next */ - if(linePtr[0] == '"') - { - lineNext = uprv_strchr(linePtr+1, '"'); - if(lineNext == NULL) { - fprintf(stderr, "%s:%d - missing trailing double quote (\")\n", - l->str, ln); - exit(1); - } else { - lineNext++; - if(*lineNext) { - if(*lineNext != ' ') { - fprintf(stderr, "%s:%d - malformed quoted line at position %d, expected ' ' got '%c'\n", - l->str, ln, lineNext-line, (*lineNext)?*lineNext:'0'); - exit(1); - } - *lineNext = 0; - lineNext++; - } - } + /* Find the next quote */ + if(linePtr[0] == '"') + { + lineNext = uprv_strchr(linePtr+1, '"'); + if(lineNext == NULL) { + fprintf(stderr, "%s:%d - missing trailing double quote (\")\n", + l->str, (int)ln); + exit(1); } else { - lineNext = uprv_strchr(linePtr, ' '); - if(lineNext) { - *lineNext = 0; /* terminate at space */ - lineNext++; - } - } - - /* add the file */ - s = (char*)getLongPathname(linePtr); - - baseName = findBasename(s); - - if(s != baseName) { - /* s was something 'long' with a path */ - if(fixPrefix && uprv_strncmp(pkgPrefix, baseName, pkgPrefixLen)) { - /* path don't have the prefix, add package prefix to short and longname */ - uprv_strcpy(tmp, pkgPrefix); - uprv_strcpy(tmp+pkgPrefixLen, baseName); - - uprv_strncpy(tmp2, s, uprv_strlen(s)-uprv_strlen(baseName)); /* should be: dirpath only, ending in sep */ - tmp2[uprv_strlen(s)-uprv_strlen(baseName)]=0; - uprv_strcat(tmp2, pkgPrefix); - uprv_strcat(tmp2, baseName); - - o->files = pkg_appendToList(o->files, &tail, uprv_strdup(tmp)); - o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp2)); - } else { - /* paths already have the prefix */ - o->files = pkg_appendToList(o->files, &tail, uprv_strdup(baseName)); - o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(s)); - } - - } else { /* s was just a basename, we want to prepend source dir*/ - /* check for prefix of package */ - uprv_strcpy(tmp, o->srcDir); - uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1]==U_FILE_SEP_CHAR?"":U_FILE_SEP_STRING); - - if(fixPrefix && strncmp(pkgPrefix,s, pkgPrefixLen)) { - /* didn't have the prefix - add it */ - uprv_strcat(tmp, pkgPrefix); - /* make up a new basename */ - uprv_strcpy(tmp2, pkgPrefix); - uprv_strcat(tmp2, s); - o->files = pkg_appendToList(o->files, &tail, uprv_strdup(tmp2)); - } else { - o->files = pkg_appendToList(o->files, &tail, uprv_strdup(baseName)); + lineNext++; + if(*lineNext) { + if(*lineNext != ' ') { + fprintf(stderr, "%s:%d - malformed quoted line at position %d, expected ' ' got '%c'\n", + l->str, (int)ln, lineNext-line, (*lineNext)?*lineNext:'0'); + exit(1); } - uprv_strcat(tmp, s); - o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp)); + *lineNext = 0; + lineNext++; + } } - linePtr = lineNext; + } else { + lineNext = uprv_strchr(linePtr, ' '); + if(lineNext) { + *lineNext = 0; /* terminate at space */ + lineNext++; + } } - } + + /* add the file */ + s = (char*)getLongPathname(linePtr); + + if(o->embed == 0) { + /* normal mode.. o->files is just the bare list without package names */ + o->files = pkg_appendToList(o->files, &tail, uprv_strdup(linePtr)); + uprv_strcpy(tmp, o->srcDir); + uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1]==U_FILE_SEP_CHAR?"":U_FILE_SEP_STRING); + uprv_strcat(tmp, s); + o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp)); + } else {/* embedded package_ mode */ + baseName = findBasename(s); + + if(s != baseName) { + /* s was something 'long' with a path */ + /* paths already have the prefix */ + o->files = pkg_appendToList(o->files, &tail, uprv_strdup(baseName)); + o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(s)); + } else { /* s was just a basename, we want to prepend source dir*/ + /* check for prefix of package */ + uprv_strcpy(tmp, o->srcDir); + uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1]==U_FILE_SEP_CHAR?"":U_FILE_SEP_STRING); + o->files = pkg_appendToList(o->files, &tail, uprv_strdup(baseName)); + uprv_strcat(tmp, s); + o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp)); + } + } /* end compatibility mode */ + linePtr = lineNext; + } /* for each entry on line */ + } /* for each line */ T_FileStream_close(in); - } + } /* for each file list file */ } /* Try calling icu-config directly to get information */ -void fillInMakefileFromICUConfig(UOption *option) +static void fillInMakefileFromICUConfig(UOption *option) { #if U_HAVE_POPEN - FILE *p; - size_t n; - static char buf[512] = ""; - static const char cmd[] = "icu-config --incfile"; - - if(options[5].doesOccur) - { - /* informational */ - fprintf(stderr, "%s: No -O option found, trying '%s'.\n", progname, cmd); - } - - p = popen(cmd, "r"); - - if(p == NULL) - { - fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname); - return; - } - - n = fread(buf, 1, 511, p); - - pclose(p); - - if(n<=0) - { - fprintf(stderr,"%s: icu-config: Could not read from icu-config. (fix PATH or use -O option)\n", progname); - return; - } - - if(buf[strlen(buf)-1]=='\n') - { - buf[strlen(buf)-1]=0; - } - - if(buf[0] == 0) - { - fprintf(stderr, "%s: icu-config: invalid response from icu-config (fix PATH or use -O option)\n", progname); - return; - } - - if(options[5].doesOccur) - { - /* informational */ - fprintf(stderr, "%s: icu-config: using '-O %s'\n", progname, buf); - } - option->value = buf; - option->doesOccur = TRUE; + FILE *p; + size_t n; + static char buf[512] = ""; + static const char cmd[] = "icu-config --incfile"; + + if(options[5].doesOccur) + { + /* informational */ + fprintf(stderr, "%s: No -O option found, trying '%s'.\n", progname, cmd); + } + + p = popen(cmd, "r"); + + if(p == NULL) + { + fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname); + return; + } + + n = fread(buf, 1, 511, p); + + pclose(p); + + if(n<=0) + { + fprintf(stderr,"%s: icu-config: Could not read from icu-config. (fix PATH or use -O option)\n", progname); + return; + } + + if(buf[strlen(buf)-1]=='\n') + { + buf[strlen(buf)-1]=0; + } + + if(buf[0] == 0) + { + fprintf(stderr, "%s: icu-config: invalid response from icu-config (fix PATH or use -O option)\n", progname); + return; + } + + if(options[5].doesOccur) + { + /* informational */ + fprintf(stderr, "%s: icu-config: using '-O %s'\n", progname, buf); + } + option->value = buf; + option->doesOccur = TRUE; #else /* ! U_HAVE_POPEN */ - /* no popen available */ - /* Put other OS specific ways to search for the Makefile.inc type - information or else fail.. */ +#ifdef WIN32 + char pathbuffer[_MAX_PATH] = {0}; + char *fullEXEpath = NULL; + char *pathstuff = NULL; + + if (strchr(progname, U_FILE_SEP_CHAR) != NULL || strchr(progname, U_FILE_ALT_SEP_CHAR) != NULL) { + /* pkgdata was executed with relative path */ + fullEXEpath = _fullpath(pathbuffer, progname, sizeof(pathbuffer)); + pathstuff = (char *)options[1].value; + + if (fullEXEpath) { + pathstuff = strrchr(fullEXEpath, U_FILE_SEP_CHAR); + if (pathstuff) { + pathstuff[1] = 0; + uprv_memmove(fullEXEpath + 2, fullEXEpath, uprv_strlen(fullEXEpath)+1); + fullEXEpath[0] = PKGDATA_DERIVED_PATH; + fullEXEpath[1] = ':'; + option->value = uprv_strdup(fullEXEpath); + option->doesOccur = TRUE; + } + } + } + else { + /* pkgdata was executed from the path */ + /* Search for file in PATH environment variable: */ + _searchenv("pkgdata.exe", "PATH", pathbuffer ); + if( *pathbuffer != '\0' ) { + fullEXEpath = pathbuffer; + pathstuff = strrchr(pathbuffer, U_FILE_SEP_CHAR); + if (pathstuff) { + pathstuff[1] = 0; + uprv_memmove(fullEXEpath + 2, fullEXEpath, uprv_strlen(fullEXEpath)+1); + fullEXEpath[0] = PKGDATA_DERIVED_PATH; + fullEXEpath[1] = ':'; + option->value = uprv_strdup(fullEXEpath); + option->doesOccur = TRUE; + } + } + } + /* else can't determine the path */ +#endif + + /* no popen available */ + /* Put other OS specific ways to search for the Makefile.inc type + information or else fail.. */ #endif }