a81fa53a61
X-SVN-Rev: 13150
678 lines
22 KiB
C
678 lines
22 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2000-2003, International Business Machines
|
|
* Corporation and others. All Rights Reserved.
|
|
*
|
|
*******************************************************************************
|
|
* file name: pkgdata.c
|
|
* encoding: ANSI X3.4 (1968)
|
|
* tab size: 8 (not used)
|
|
* indentation:4
|
|
*
|
|
* created on: 2000may15
|
|
* created by: Steven \u24C7 Loomis
|
|
*
|
|
* This program packages the ICU data into different forms
|
|
* (DLL, common data, etc.)
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#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
|
|
# include <unistd.h>
|
|
#endif
|
|
|
|
U_CDECL_BEGIN
|
|
#include "pkgtypes.h"
|
|
#include "makefile.h"
|
|
U_CDECL_END
|
|
|
|
static int executeMakefile(const UPKGOptions *o);
|
|
static void loadLists(UPKGOptions *o, UErrorCode *status);
|
|
|
|
/* always have this fcn, just might not do anything */
|
|
static void fillInMakefileFromICUConfig(UOption *option);
|
|
|
|
/* This sets the modes that are available */
|
|
static struct
|
|
{
|
|
const char *name, *alt_name;
|
|
UPKGMODE *fcn;
|
|
const char *desc;
|
|
} modes[] =
|
|
{
|
|
{ "files", 0, pkg_mode_files, "Uses raw data files (no effect). Installation copies all files to the target location." },
|
|
#ifdef WIN32
|
|
{ "dll", "library", pkg_mode_windows, "Generates one common data file and one shared library, <package>.dll"},
|
|
{ "common", "archive", pkg_mode_windows, "Generates just the common file, <package>.dat"},
|
|
{ "static", "static", pkg_mode_windows, "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX }
|
|
#else /*#ifdef WIN32*/
|
|
#ifdef UDATA_SO_SUFFIX
|
|
{ "dll", "library", pkg_mode_dll, "Generates one shared library, <package>" UDATA_SO_SUFFIX },
|
|
#endif
|
|
{ "common", "archive", pkg_mode_common, "Generates one common data file, <package>.dat" },
|
|
{ "static", "static", pkg_mode_static, "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX }
|
|
#endif /*#ifdef WIN32*/
|
|
};
|
|
|
|
static UOption options[]={
|
|
/*00*/ UOPTION_DEF( "name", 'p', UOPT_REQUIRES_ARG),
|
|
/*01*/ UOPTION_DEF( "bldopt", 'O', UOPT_REQUIRES_ARG), /* on Win32 it is release or debug */
|
|
/*02*/ UOPTION_DEF( "mode", 'm', UOPT_REQUIRES_ARG),
|
|
/*03*/ UOPTION_HELP_H, /* -h */
|
|
/*04*/ UOPTION_HELP_QUESTION_MARK, /* -? */
|
|
/*05*/ UOPTION_VERBOSE, /* -v */
|
|
/*06*/ UOPTION_COPYRIGHT, /* -c */
|
|
/*07*/ UOPTION_DEF( "comment", 'C', UOPT_REQUIRES_ARG),
|
|
/*08*/ UOPTION_DESTDIR, /* -d */
|
|
/*09*/ UOPTION_DEF( "clean", 'k', UOPT_NO_ARG),
|
|
/*10*/ UOPTION_DEF( "nooutput",'n', UOPT_NO_ARG),
|
|
/*11*/ UOPTION_DEF( "rebuild", 'F', UOPT_NO_ARG),
|
|
/*12*/ UOPTION_DEF( "tempdir", 'T', UOPT_REQUIRES_ARG),
|
|
/*13*/ UOPTION_DEF( "install", 'I', UOPT_REQUIRES_ARG),
|
|
/*14*/ UOPTION_SOURCEDIR ,
|
|
/*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),
|
|
/*19*/ UOPTION_DEF( "numerictmp", 'N', UOPT_NO_ARG)
|
|
};
|
|
|
|
const char options_help[][160]={
|
|
"Set the data name",
|
|
#ifdef WIN32
|
|
"The directory where the ICU is located (e.g. <ICUROOT> which contains the bin directory)",
|
|
#else
|
|
"Specify options for the builder. (Autdetected if icu-config is available)",
|
|
#endif
|
|
"Specify the mode of building (see below; default: common)",
|
|
"This usage text",
|
|
"This usage text",
|
|
"Make the output verbose",
|
|
"Use the standard ICU copyright",
|
|
"Use a custom comment (instead of the copyright)",
|
|
"Specify the destination directory for files",
|
|
"Clean out generated & temporary files",
|
|
"Suppress output of data, just list files to be created",
|
|
"Force rebuilding of all data",
|
|
"Specify temporary dir (default: output dir)",
|
|
"Install the data (specify target)",
|
|
"Specify a custom source directory",
|
|
"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",
|
|
"Use short numeric temporary file names such as t1234.c"
|
|
};
|
|
|
|
const char *progname = "PKGDATA";
|
|
|
|
int
|
|
main(int argc, char* argv[]) {
|
|
FileStream *out;
|
|
UPKGOptions o;
|
|
CharList *tail;
|
|
UBool needsHelp = FALSE;
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
char tmp[1024];
|
|
int32_t i;
|
|
|
|
U_MAIN_INIT_ARGS(argc, argv);
|
|
|
|
progname = argv[0];
|
|
|
|
options[2].value = "common";
|
|
options[17].value = "";
|
|
|
|
/* read command line options */
|
|
argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
|
|
|
|
/* error handling, printing usage message */
|
|
/* I've decided to simply print an error and quit. This tool has too
|
|
many options to just display them all of the time. */
|
|
|
|
if(options[3].doesOccur || options[4].doesOccur) {
|
|
needsHelp = TRUE;
|
|
}
|
|
else {
|
|
if(!needsHelp && argc<0) {
|
|
fprintf(stderr,
|
|
"%s: error in command line argument \"%s\"\n",
|
|
progname,
|
|
argv[-argc]);
|
|
fprintf(stderr, "Run '%s --help' for help.\n", progname);
|
|
return 1;
|
|
}
|
|
|
|
if(!options[1].doesOccur) {
|
|
/* Try to fill in from icu-config or equivalent */
|
|
fillInMakefileFromICUConfig(&options[1]);
|
|
}
|
|
#ifdef WIN32
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
if(argc == 1) {
|
|
fprintf(stderr,
|
|
"No input files specified.\n"
|
|
"Run '%s --help' for help.\n", progname);
|
|
return 1;
|
|
}
|
|
} /* end !needsHelp */
|
|
|
|
if(argc<0 || needsHelp ) {
|
|
fprintf(stderr,
|
|
"usage: %s [-options] [-] [packageFile] \n"
|
|
"\tProduce packaged ICU data from the given list(s) of files.\n"
|
|
"\t'-' by itself means to read from stdin.\n"
|
|
"\tpackageFile is a text file containing the list of files to package.\n",
|
|
progname);
|
|
|
|
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]":""),
|
|
options[i].shortName,
|
|
options[i].longName ? "or --" : " ",
|
|
options[i].longName ? options[i].longName : "",
|
|
options_help[i]);
|
|
}
|
|
|
|
fprintf(stderr, "modes: (-m option)\n");
|
|
for(i=0;i<(sizeof(modes)/sizeof(modes[0]));i++) {
|
|
fprintf(stderr, " %-9s ", modes[i].name);
|
|
if (modes[i].alt_name) {
|
|
fprintf(stderr, "/ %-9s", modes[i].alt_name);
|
|
} else {
|
|
fprintf(stderr, " ");
|
|
}
|
|
fprintf(stderr, " %s\n", modes[i].desc);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/* OK, fill in the options struct */
|
|
uprv_memset(&o, 0, sizeof(o));
|
|
|
|
o.mode = options[2].value;
|
|
o.version = options[16].doesOccur ? options[16].value : 0;
|
|
o.makeArgs = options[17].value;
|
|
|
|
o.fcn = NULL;
|
|
|
|
for(i=0;i<sizeof(modes)/sizeof(modes[0]);i++) {
|
|
if(!uprv_strcmp(modes[i].name, o.mode)) {
|
|
o.fcn = modes[i].fcn;
|
|
break;
|
|
} else if (modes[i].alt_name && !uprv_strcmp(modes[i].alt_name, o.mode)) {
|
|
o.mode = modes[i].name;
|
|
o.fcn = modes[i].fcn;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(o.fcn == NULL) {
|
|
fprintf(stderr, "Error: invalid mode '%s' specified. Run '%s --help' to list valid modes.\n", o.mode, progname);
|
|
return 1;
|
|
}
|
|
|
|
o.shortName = options[0].value;
|
|
/**/ {
|
|
int len = uprv_strlen(o.shortName);
|
|
char *csname, *cp;
|
|
const char *sp;
|
|
|
|
cp = csname = (char *) uprv_malloc((len + 1 + 1) * sizeof(*o.cShortName));
|
|
if (*(sp = o.shortName)) {
|
|
*cp++ = isalpha(*sp) ? * sp : '_';
|
|
for (++sp; *sp; ++sp) {
|
|
*cp++ = isalnum(*sp) ? *sp : '_';
|
|
}
|
|
}
|
|
*cp = 0;
|
|
|
|
o.cShortName = csname;
|
|
}
|
|
|
|
o.verbose = options[5].doesOccur;
|
|
#ifdef WIN32 /* 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 == 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");
|
|
return 1;
|
|
}
|
|
} else {
|
|
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
|
|
if(options[6].doesOccur) {
|
|
o.comment = U_COPYRIGHT_STRING;
|
|
} else if (options[7].doesOccur) {
|
|
o.comment = options[7].value;
|
|
}
|
|
|
|
if( options[8].doesOccur ) {
|
|
o.targetDir = options[8].value;
|
|
} else {
|
|
o.targetDir = "."; /* cwd */
|
|
}
|
|
|
|
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 */
|
|
}
|
|
|
|
|
|
if( options[12].doesOccur ) {
|
|
o.tmpDir = options[12].value;
|
|
} else {
|
|
o.tmpDir = o.targetDir;
|
|
}
|
|
|
|
if( options[13].doesOccur ) {
|
|
o.install = options[13].value;
|
|
}
|
|
|
|
if( options[14].doesOccur ) {
|
|
o.srcDir = options[14].value;
|
|
} else {
|
|
o.srcDir = ".";
|
|
}
|
|
|
|
if( options[15].doesOccur ) {
|
|
o.entryName = options[15].value;
|
|
} else {
|
|
o.entryName = o.cShortName;
|
|
}
|
|
|
|
/* OK options are set up. Now the file lists. */
|
|
tail = NULL;
|
|
for( i=1; i<argc; i++) {
|
|
if ( !uprv_strcmp(argv[i] , "-") ) {
|
|
/* stdin */
|
|
if( o.hadStdin == TRUE ) {
|
|
fprintf(stderr, "Error: can't specify '-' twice!\n"
|
|
"Run '%s --help' for help.\n", progname);
|
|
return 1;
|
|
}
|
|
o.hadStdin = TRUE;
|
|
}
|
|
|
|
o.fileListFiles = pkg_appendToList(o.fileListFiles, &tail, uprv_strdup(argv[i]));
|
|
}
|
|
|
|
/* load the files */
|
|
loadLists(&o, &status);
|
|
if( U_FAILURE(status) ) {
|
|
fprintf(stderr, "error loading input file lists: %s\n", u_errorName(status));
|
|
return 2;
|
|
}
|
|
|
|
/* Makefile pathname */
|
|
uprv_strcpy(tmp, o.tmpDir);
|
|
uprv_strcat(tmp, U_FILE_SEP_STRING);
|
|
uprv_strcat(tmp, o.shortName);
|
|
uprv_strcat(tmp, "_");
|
|
uprv_strcat(tmp, o.mode);
|
|
uprv_strcat(tmp, ".mak"); /* MAY NEED TO CHANGE PER PLATFORM */
|
|
|
|
o.makeFile = uprv_strdup(tmp);
|
|
|
|
out = T_FileStream_open(o.makeFile, "w");
|
|
if (out) {
|
|
pkg_mak_writeHeader(out, &o); /* need to take status */
|
|
o.fcn(&o, out, &status);
|
|
pkg_mak_writeFooter(out, &o);
|
|
T_FileStream_close(out);
|
|
} else {
|
|
fprintf(stderr, "warning: couldn't create %s, will use existing file if any\n", o.makeFile);
|
|
/*status = U_FILE_ACCESS_ERROR;*/
|
|
}
|
|
|
|
if(U_FAILURE(status)) {
|
|
fprintf(stderr, "Error creating makefile [%s]: %s\n", o.mode,
|
|
u_errorName(status));
|
|
return 1;
|
|
}
|
|
|
|
if(o.nooutput == TRUE) {
|
|
return 0; /* nothing to do. */
|
|
}
|
|
|
|
return executeMakefile(&o);
|
|
}
|
|
|
|
/* POSIX - execute makefile */
|
|
static int executeMakefile(const UPKGOptions *o)
|
|
{
|
|
char cmd[1024];
|
|
/*char pwd[1024];*/
|
|
const char *make;
|
|
int rc;
|
|
|
|
make = getenv("MAKE");
|
|
|
|
if(!make || !make[0]) {
|
|
make = U_MAKE;
|
|
}
|
|
|
|
/*getcwd(pwd, 1024);*/
|
|
#ifdef WIN32
|
|
sprintf(cmd, "%s %s%s -f \"%s\" %s %s %s %s",
|
|
make,
|
|
o->install ? "INSTALLTO=" : "",
|
|
o->install ? o->install : "",
|
|
o->makeFile,
|
|
o->clean ? "clean" : "",
|
|
o->rebuild ? "rebuild" : "",
|
|
o->install ? "install" : "",
|
|
o->makeArgs);
|
|
#elif OS400
|
|
sprintf(cmd, "CALL GNU/GMAKE PARM(%s%s%s '-f' '%s' %s %s %s %s)",
|
|
o->install ? "'INSTALLTO=" : "",
|
|
o->install ? o->install : "",
|
|
o->install ? "'" : "",
|
|
o->makeFile,
|
|
o->clean ? "'clean'" : "",
|
|
o->rebuild ? "'rebuild'" : "",
|
|
o->install ? "'install'" : "",
|
|
o->makeArgs);
|
|
#else
|
|
sprintf(cmd, "%s %s%s -f %s %s %s %s %s",
|
|
make,
|
|
o->install ? "INSTALLTO=" : "",
|
|
o->install ? o->install : "",
|
|
o->makeFile,
|
|
o->clean ? "clean" : "",
|
|
o->rebuild ? "rebuild" : "",
|
|
o->install ? "install" : "",
|
|
o->makeArgs);
|
|
#endif
|
|
if(o->verbose) {
|
|
puts(cmd);
|
|
}
|
|
|
|
rc = system(cmd);
|
|
|
|
if(rc < 0) {
|
|
fprintf(stderr, "# Failed, rc=%d\n", rc);
|
|
}
|
|
|
|
return rc < 128 ? rc : (rc >> 8);
|
|
}
|
|
|
|
|
|
static void loadLists(UPKGOptions *o, UErrorCode *status)
|
|
{
|
|
CharList *l, *tail = NULL, *tail2 = NULL;
|
|
FileStream *in;
|
|
char line[16384];
|
|
char *linePtr, *lineNext;
|
|
const uint32_t lineMax = 16300;
|
|
char tmp[1024], tmp2[1024];
|
|
char pkgPrefix[1024];
|
|
int32_t pkgPrefixLen;
|
|
const char *baseName;
|
|
char *s;
|
|
int32_t ln;
|
|
UBool fixPrefix;
|
|
|
|
|
|
fixPrefix = options[18].doesOccur;
|
|
|
|
strcpy(pkgPrefix, o->shortName);
|
|
strcat(pkgPrefix, "_");
|
|
pkgPrefixLen=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");
|
|
|
|
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);
|
|
}
|
|
/* 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;
|
|
}
|
|
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++;
|
|
}
|
|
}
|
|
} 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));
|
|
}
|
|
uprv_strcat(tmp, s);
|
|
o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp));
|
|
}
|
|
linePtr = lineNext;
|
|
}
|
|
}
|
|
T_FileStream_close(in);
|
|
}
|
|
}
|
|
|
|
/* Try calling icu-config directly to get information */
|
|
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;
|
|
#else /* ! U_HAVE_POPEN */
|
|
|
|
#ifdef WIN32
|
|
char tmp[1024];
|
|
char *fullEXEpath = _fullpath(tmp, progname, sizeof(tmp));
|
|
char *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 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
|
|
}
|