]> git.saurik.com Git - apple/icu.git/blame - icuSources/tools/pkgdata/pkgdata.c
ICU-8.11.1.tar.gz
[apple/icu.git] / icuSources / tools / pkgdata / pkgdata.c
CommitLineData
b75a7d8f
A
1/******************************************************************************
2*
73c04bcf 3* Copyright (C) 2000-2006, International Business Machines
b75a7d8f
A
4* Corporation and others. All Rights Reserved.
5*
6*******************************************************************************
7* file name: pkgdata.c
8* encoding: ANSI X3.4 (1968)
9* tab size: 8 (not used)
10* indentation:4
11*
12* created on: 2000may15
13* created by: Steven \u24C7 Loomis
14*
15* This program packages the ICU data into different forms
16* (DLL, common data, etc.)
17*/
18
b75a7d8f
A
19#include "unicode/utypes.h"
20#include "unicode/putil.h"
21#include "cmemory.h"
22#include "cstring.h"
23#include "filestrm.h"
24#include "toolutil.h"
374ca955 25#include "unicode/uclean.h"
b75a7d8f
A
26#include "unewdata.h"
27#include "uoptions.h"
73c04bcf 28#include "putilimp.h"
b75a7d8f
A
29
30#if U_HAVE_POPEN
374ca955
A
31/*
32 We define __USE_POSIX2 so that we can get popen and pclose when
33 --enable-strict is used
34*/
35# ifndef __USE_POSIX2
36# define __USE_POSIX2 1
37# endif
b75a7d8f
A
38# include <unistd.h>
39#endif
374ca955
A
40#include <stdio.h>
41#include <stdlib.h>
b75a7d8f
A
42
43U_CDECL_BEGIN
44#include "pkgtypes.h"
45#include "makefile.h"
46U_CDECL_END
47
48static int executeMakefile(const UPKGOptions *o);
49static void loadLists(UPKGOptions *o, UErrorCode *status);
50
51/* always have this fcn, just might not do anything */
52static void fillInMakefileFromICUConfig(UOption *option);
53
54/* This sets the modes that are available */
55static struct
56{
57 const char *name, *alt_name;
58 UPKGMODE *fcn;
59 const char *desc;
60} modes[] =
61{
62 { "files", 0, pkg_mode_files, "Uses raw data files (no effect). Installation copies all files to the target location." },
374ca955 63#ifdef U_MAKE_IS_NMAKE
b75a7d8f
A
64 { "dll", "library", pkg_mode_windows, "Generates one common data file and one shared library, <package>.dll"},
65 { "common", "archive", pkg_mode_windows, "Generates just the common file, <package>.dat"},
66 { "static", "static", pkg_mode_windows, "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX }
374ca955 67#else /*#ifdef U_MAKE_IS_NMAKE*/
b75a7d8f
A
68#ifdef UDATA_SO_SUFFIX
69 { "dll", "library", pkg_mode_dll, "Generates one shared library, <package>" UDATA_SO_SUFFIX },
70#endif
71 { "common", "archive", pkg_mode_common, "Generates one common data file, <package>.dat" },
72 { "static", "static", pkg_mode_static, "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX }
374ca955 73#endif /*#ifdef U_MAKE_IS_NMAKE*/
b75a7d8f
A
74};
75
73c04bcf
A
76enum {
77 NAME,
78 BLDOPT,
79 MODE,
80 HELP,
81 HELP_QUESTION_MARK,
82 VERBOSE,
83 COPYRIGHT,
84 COMMENT,
85 DESTDIR,
86 CLEAN,
87 NOOUTPUT,
88 REBUILD,
89 TEMPDIR,
90 INSTALL,
91 SOURCEDIR,
92 ENTRYPOINT,
93 REVISION,
94 MAKEARG,
95 FORCE_PREFIX,
96 LIBNAME,
97 QUIET
98};
99
b75a7d8f
A
100static UOption options[]={
101 /*00*/ UOPTION_DEF( "name", 'p', UOPT_REQUIRES_ARG),
102 /*01*/ UOPTION_DEF( "bldopt", 'O', UOPT_REQUIRES_ARG), /* on Win32 it is release or debug */
103 /*02*/ UOPTION_DEF( "mode", 'm', UOPT_REQUIRES_ARG),
104 /*03*/ UOPTION_HELP_H, /* -h */
105 /*04*/ UOPTION_HELP_QUESTION_MARK, /* -? */
106 /*05*/ UOPTION_VERBOSE, /* -v */
107 /*06*/ UOPTION_COPYRIGHT, /* -c */
108 /*07*/ UOPTION_DEF( "comment", 'C', UOPT_REQUIRES_ARG),
109 /*08*/ UOPTION_DESTDIR, /* -d */
110 /*09*/ UOPTION_DEF( "clean", 'k', UOPT_NO_ARG),
111 /*10*/ UOPTION_DEF( "nooutput",'n', UOPT_NO_ARG),
112 /*11*/ UOPTION_DEF( "rebuild", 'F', UOPT_NO_ARG),
113 /*12*/ UOPTION_DEF( "tempdir", 'T', UOPT_REQUIRES_ARG),
114 /*13*/ UOPTION_DEF( "install", 'I', UOPT_REQUIRES_ARG),
115 /*14*/ UOPTION_SOURCEDIR ,
116 /*15*/ UOPTION_DEF( "entrypoint", 'e', UOPT_REQUIRES_ARG),
117 /*16*/ UOPTION_DEF( "revision", 'r', UOPT_REQUIRES_ARG),
73c04bcf 118 /*17*/ UOPTION_DEF( "makearg", 'M', UOPT_REQUIRES_ARG),
374ca955 119 /*18*/ UOPTION_DEF( "force-prefix", 'f', UOPT_NO_ARG),
73c04bcf
A
120 /*19*/ UOPTION_DEF( "libname", 'L', UOPT_REQUIRES_ARG),
121 /*20*/ UOPTION_DEF( "quiet", 'q', UOPT_NO_ARG)
b75a7d8f
A
122};
123
374ca955 124const char options_help[][320]={
b75a7d8f 125 "Set the data name",
374ca955
A
126#ifdef U_MAKE_IS_NMAKE
127 "The directory where the ICU is located (e.g. <ICUROOT> which contains the bin directory)",
b75a7d8f
A
128#else
129 "Specify options for the builder. (Autdetected if icu-config is available)",
130#endif
131 "Specify the mode of building (see below; default: common)",
132 "This usage text",
133 "This usage text",
134 "Make the output verbose",
135 "Use the standard ICU copyright",
136 "Use a custom comment (instead of the copyright)",
137 "Specify the destination directory for files",
138 "Clean out generated & temporary files",
139 "Suppress output of data, just list files to be created",
140 "Force rebuilding of all data",
141 "Specify temporary dir (default: output dir)",
142 "Install the data (specify target)",
143 "Specify a custom source directory",
144 "Specify a custom entrypoint name (default: short name)",
145 "Specify a version when packaging in DLL or static mode",
146 "Pass the next argument to make(1)",
374ca955 147 "Add package to all file names if not present",
374ca955
A
148 "Library name to build (if different than package name)",
149 "Quite mode. (e.g. Do not output a readme file for static libraries)"
b75a7d8f
A
150};
151
152const char *progname = "PKGDATA";
153
154int
155main(int argc, char* argv[]) {
156 FileStream *out;
157 UPKGOptions o;
158 CharList *tail;
159 UBool needsHelp = FALSE;
160 UErrorCode status = U_ZERO_ERROR;
161 char tmp[1024];
162 int32_t i;
163
164 U_MAIN_INIT_ARGS(argc, argv);
165
166 progname = argv[0];
167
73c04bcf
A
168 options[MODE].value = "common";
169 options[MAKEARG].value = "";
b75a7d8f
A
170
171 /* read command line options */
172 argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
173
174 /* error handling, printing usage message */
175 /* I've decided to simply print an error and quit. This tool has too
176 many options to just display them all of the time. */
177
73c04bcf 178 if(options[HELP].doesOccur || options[HELP_QUESTION_MARK].doesOccur) {
b75a7d8f
A
179 needsHelp = TRUE;
180 }
181 else {
182 if(!needsHelp && argc<0) {
183 fprintf(stderr,
184 "%s: error in command line argument \"%s\"\n",
185 progname,
186 argv[-argc]);
187 fprintf(stderr, "Run '%s --help' for help.\n", progname);
188 return 1;
189 }
190
73c04bcf 191 if(!options[BLDOPT].doesOccur) {
374ca955
A
192 /* Try to fill in from icu-config or equivalent */
193 fillInMakefileFromICUConfig(&options[1]);
194 }
195#ifdef U_MAKE_IS_NMAKE
196 else {
197 fprintf(stderr, "Warning: You are using the deprecated -O option\n"
198 "\tYou can fix this warning by installing pkgdata, gencmn and genccode\n"
199 "\tinto the same directory and not specifying the -O option to pkgdata.\n");
b75a7d8f 200 }
374ca955 201#endif
b75a7d8f 202
73c04bcf 203 if(!options[BLDOPT].doesOccur) {
374ca955
A
204 fprintf(stderr, " required parameter is missing: -O is required \n");
205 fprintf(stderr, "Run '%s --help' for help.\n", progname);
206 return 1;
b75a7d8f 207 }
374ca955 208
73c04bcf 209 if(!options[NAME].doesOccur) /* -O we already have - don't report it. */
b75a7d8f 210 {
374ca955
A
211 fprintf(stderr, " required parameter -p is missing \n");
212 fprintf(stderr, "Run '%s --help' for help.\n", progname);
213 return 1;
b75a7d8f
A
214 }
215
216 if(argc == 1) {
217 fprintf(stderr,
218 "No input files specified.\n"
219 "Run '%s --help' for help.\n", progname);
220 return 1;
221 }
222 } /* end !needsHelp */
223
224 if(argc<0 || needsHelp ) {
225 fprintf(stderr,
226 "usage: %s [-options] [-] [packageFile] \n"
227 "\tProduce packaged ICU data from the given list(s) of files.\n"
228 "\t'-' by itself means to read from stdin.\n"
229 "\tpackageFile is a text file containing the list of files to package.\n",
230 progname);
231
232 fprintf(stderr, "\n options:\n");
233 for(i=0;i<(sizeof(options)/sizeof(options[0]));i++) {
234 fprintf(stderr, "%-5s -%c %s%-10s %s\n",
374ca955 235 (i<1?"[REQ]":""),
b75a7d8f
A
236 options[i].shortName,
237 options[i].longName ? "or --" : " ",
238 options[i].longName ? options[i].longName : "",
239 options_help[i]);
240 }
241
242 fprintf(stderr, "modes: (-m option)\n");
243 for(i=0;i<(sizeof(modes)/sizeof(modes[0]));i++) {
244 fprintf(stderr, " %-9s ", modes[i].name);
245 if (modes[i].alt_name) {
246 fprintf(stderr, "/ %-9s", modes[i].alt_name);
247 } else {
248 fprintf(stderr, " ");
249 }
250 fprintf(stderr, " %s\n", modes[i].desc);
251 }
252 return 1;
253 }
254
255 /* OK, fill in the options struct */
256 uprv_memset(&o, 0, sizeof(o));
257
73c04bcf
A
258 o.mode = options[MODE].value;
259 o.version = options[REVISION].doesOccur ? options[REVISION].value : 0;
260 o.makeArgs = options[MAKEARG].value;
b75a7d8f
A
261
262 o.fcn = NULL;
263
264 for(i=0;i<sizeof(modes)/sizeof(modes[0]);i++) {
265 if(!uprv_strcmp(modes[i].name, o.mode)) {
266 o.fcn = modes[i].fcn;
267 break;
268 } else if (modes[i].alt_name && !uprv_strcmp(modes[i].alt_name, o.mode)) {
269 o.mode = modes[i].name;
270 o.fcn = modes[i].fcn;
271 break;
272 }
273 }
274
275 if(o.fcn == NULL) {
276 fprintf(stderr, "Error: invalid mode '%s' specified. Run '%s --help' to list valid modes.\n", o.mode, progname);
277 return 1;
278 }
279
280 o.shortName = options[0].value;
374ca955
A
281 {
282 int32_t len = (int32_t)uprv_strlen(o.shortName);
b75a7d8f
A
283 char *csname, *cp;
284 const char *sp;
285
286 cp = csname = (char *) uprv_malloc((len + 1 + 1) * sizeof(*o.cShortName));
287 if (*(sp = o.shortName)) {
288 *cp++ = isalpha(*sp) ? * sp : '_';
289 for (++sp; *sp; ++sp) {
290 *cp++ = isalnum(*sp) ? *sp : '_';
291 }
292 }
293 *cp = 0;
294
295 o.cShortName = csname;
296 }
297
73c04bcf
A
298 if(options[LIBNAME].doesOccur) { /* get libname from shortname, or explicit -L parameter */
299 o.libName = options[LIBNAME].value;
374ca955
A
300 } else {
301 o.libName = o.shortName;
302 }
303
73c04bcf 304 if(options[QUIET].doesOccur) {
374ca955
A
305 o.quiet = TRUE;
306 } else {
307 o.quiet = FALSE;
308 }
309
73c04bcf 310 o.verbose = options[VERBOSE].doesOccur;
374ca955 311#ifdef U_MAKE_IS_NMAKE /* format is R:pathtoICU or D:pathtoICU */
b75a7d8f 312 {
73c04bcf
A
313 char *pathstuff = (char *)options[BLDOPT].value;
314 if(options[1].value[uprv_strlen(options[BLDOPT].value)-1] == '\\') {
315 pathstuff[uprv_strlen(options[BLDOPT].value)-1] = '\0';
b75a7d8f 316 }
374ca955 317 if(*pathstuff == PKGDATA_DERIVED_PATH || *pathstuff == 'R' || *pathstuff == 'D') {
b75a7d8f
A
318 o.options = pathstuff;
319 pathstuff++;
320 if(*pathstuff == ':') {
321 *pathstuff = '\0';
322 pathstuff++;
374ca955
A
323 }
324 else {
325 fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n");
b75a7d8f
A
326 return 1;
327 }
328 } else {
374ca955 329 fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n");
b75a7d8f
A
330 return 1;
331 }
332 o.icuroot = pathstuff;
374ca955
A
333 if (o.verbose) {
334 fprintf(stdout, "# ICUROOT is %s\n", o.icuroot);
335 }
b75a7d8f
A
336 }
337#else /* on UNIX, we'll just include the file... */
73c04bcf 338 o.options = options[BLDOPT].value;
b75a7d8f 339#endif
73c04bcf 340 if(options[COPYRIGHT].doesOccur) {
b75a7d8f 341 o.comment = U_COPYRIGHT_STRING;
73c04bcf
A
342 } else if (options[COMMENT].doesOccur) {
343 o.comment = options[COMMENT].value;
b75a7d8f
A
344 }
345
73c04bcf
A
346 if( options[DESTDIR].doesOccur ) {
347 o.targetDir = options[DESTDIR].value;
b75a7d8f
A
348 } else {
349 o.targetDir = "."; /* cwd */
350 }
351
73c04bcf
A
352 o.clean = options[CLEAN].doesOccur;
353 o.nooutput = options[NOOUTPUT].doesOccur;
354 o.rebuild = options[REBUILD].doesOccur;
374ca955 355
73c04bcf
A
356 if( options[TEMPDIR].doesOccur ) {
357 o.tmpDir = options[TEMPDIR].value;
b75a7d8f
A
358 } else {
359 o.tmpDir = o.targetDir;
360 }
361
73c04bcf
A
362 if( options[INSTALL].doesOccur ) {
363 o.install = options[INSTALL].value;
b75a7d8f
A
364 }
365
73c04bcf
A
366 if( options[SOURCEDIR].doesOccur ) {
367 o.srcDir = options[SOURCEDIR].value;
b75a7d8f
A
368 } else {
369 o.srcDir = ".";
370 }
371
73c04bcf
A
372 if( options[ENTRYPOINT].doesOccur ) {
373 o.entryName = options[ENTRYPOINT].value;
b75a7d8f
A
374 } else {
375 o.entryName = o.cShortName;
376 }
377
378 /* OK options are set up. Now the file lists. */
379 tail = NULL;
380 for( i=1; i<argc; i++) {
381 if ( !uprv_strcmp(argv[i] , "-") ) {
382 /* stdin */
383 if( o.hadStdin == TRUE ) {
384 fprintf(stderr, "Error: can't specify '-' twice!\n"
385 "Run '%s --help' for help.\n", progname);
386 return 1;
387 }
388 o.hadStdin = TRUE;
389 }
390
391 o.fileListFiles = pkg_appendToList(o.fileListFiles, &tail, uprv_strdup(argv[i]));
392 }
393
394 /* load the files */
395 loadLists(&o, &status);
396 if( U_FAILURE(status) ) {
397 fprintf(stderr, "error loading input file lists: %s\n", u_errorName(status));
398 return 2;
399 }
400
401 /* Makefile pathname */
402 uprv_strcpy(tmp, o.tmpDir);
73c04bcf 403#ifdef U_MAKE_IS_NMAKE
b75a7d8f 404 uprv_strcat(tmp, U_FILE_SEP_STRING);
73c04bcf
A
405#else
406 uprv_strcat(tmp, U_FILE_ALT_SEP_STRING);
407#endif
b75a7d8f
A
408 uprv_strcat(tmp, o.shortName);
409 uprv_strcat(tmp, "_");
410 uprv_strcat(tmp, o.mode);
411 uprv_strcat(tmp, ".mak"); /* MAY NEED TO CHANGE PER PLATFORM */
412
413 o.makeFile = uprv_strdup(tmp);
414
415 out = T_FileStream_open(o.makeFile, "w");
416 if (out) {
417 pkg_mak_writeHeader(out, &o); /* need to take status */
418 o.fcn(&o, out, &status);
419 pkg_mak_writeFooter(out, &o);
420 T_FileStream_close(out);
421 } else {
422 fprintf(stderr, "warning: couldn't create %s, will use existing file if any\n", o.makeFile);
423 /*status = U_FILE_ACCESS_ERROR;*/
424 }
425
426 if(U_FAILURE(status)) {
427 fprintf(stderr, "Error creating makefile [%s]: %s\n", o.mode,
428 u_errorName(status));
429 return 1;
430 }
431
432 if(o.nooutput == TRUE) {
433 return 0; /* nothing to do. */
434 }
435
436 return executeMakefile(&o);
437}
438
439/* POSIX - execute makefile */
440static int executeMakefile(const UPKGOptions *o)
441{
442 char cmd[1024];
443 /*char pwd[1024];*/
444 const char *make;
445 int rc;
446
447 make = getenv("MAKE");
448
449 if(!make || !make[0]) {
450 make = U_MAKE;
451 }
452
453 /*getcwd(pwd, 1024);*/
73c04bcf 454#ifdef U_WINDOWS
b75a7d8f
A
455 sprintf(cmd, "%s %s%s -f \"%s\" %s %s %s %s",
456 make,
457 o->install ? "INSTALLTO=" : "",
458 o->install ? o->install : "",
459 o->makeFile,
460 o->clean ? "clean" : "",
461 o->rebuild ? "rebuild" : "",
462 o->install ? "install" : "",
463 o->makeArgs);
73c04bcf
A
464#elif defined(OS400)
465 sprintf(cmd, "CALL GNU/GMAKE PARM(%s%s%s '-f' '%s' %s %s %s %s%s%s)",
b75a7d8f
A
466 o->install ? "'INSTALLTO=" : "",
467 o->install ? o->install : "",
468 o->install ? "'" : "",
469 o->makeFile,
470 o->clean ? "'clean'" : "",
471 o->rebuild ? "'rebuild'" : "",
472 o->install ? "'install'" : "",
73c04bcf
A
473 o->makeArgs && *o->makeArgs ? "'" : "",
474 o->makeArgs && *o->makeArgs ? o->makeArgs : "",
475 o->makeArgs && *o->makeArgs ? "'" : "");
b75a7d8f
A
476#else
477 sprintf(cmd, "%s %s%s -f %s %s %s %s %s",
478 make,
479 o->install ? "INSTALLTO=" : "",
480 o->install ? o->install : "",
481 o->makeFile,
482 o->clean ? "clean" : "",
483 o->rebuild ? "rebuild" : "",
484 o->install ? "install" : "",
485 o->makeArgs);
486#endif
487 if(o->verbose) {
488 puts(cmd);
489 }
490
491 rc = system(cmd);
492
493 if(rc < 0) {
494 fprintf(stderr, "# Failed, rc=%d\n", rc);
495 }
496
497 return rc < 128 ? rc : (rc >> 8);
498}
499
500
501static void loadLists(UPKGOptions *o, UErrorCode *status)
502{
503 CharList *l, *tail = NULL, *tail2 = NULL;
504 FileStream *in;
505 char line[16384];
506 char *linePtr, *lineNext;
507 const uint32_t lineMax = 16300;
374ca955 508 char tmp[1024];
b75a7d8f 509 char *s;
374ca955 510 int32_t ln=0; /* line number */
b75a7d8f 511
b75a7d8f
A
512 for(l = o->fileListFiles; l; l = l->next) {
513 if(o->verbose) {
514 fprintf(stdout, "# Reading %s..\n", l->str);
515 }
516 /* TODO: stdin */
374ca955 517 in = T_FileStream_open(l->str, "r"); /* open files list */
b75a7d8f
A
518
519 if(!in) {
520 fprintf(stderr, "Error opening <%s>.\n", l->str);
521 *status = U_FILE_ACCESS_ERROR;
522 return;
523 }
374ca955
A
524
525 while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) { /* for each line */
73c04bcf
A
526 ln++;
527 if(uprv_strlen(line)>lineMax) {
528 fprintf(stderr, "%s:%d - line too long (over %d chars)\n", l->str, (int)ln, (int)lineMax);
529 exit(1);
b75a7d8f 530 }
73c04bcf
A
531 /* remove spaces at the beginning */
532 linePtr = line;
533 while(isspace(*linePtr)) {
534 linePtr++;
b75a7d8f 535 }
73c04bcf
A
536 s=linePtr;
537 /* remove trailing newline characters */
538 while(*s!=0) {
539 if(*s=='\r' || *s=='\n') {
540 *s=0;
541 break;
542 }
b75a7d8f
A
543 ++s;
544 }
73c04bcf
A
545 if((*linePtr == 0) || (*linePtr == '#')) {
546 continue; /* comment or empty line */
547 }
548
549 /* Now, process the line */
550 lineNext = NULL;
551
552 while(linePtr && *linePtr) { /* process space-separated items */
553 while(*linePtr == ' ') {
554 linePtr++;
555 }
556 /* Find the next quote */
557 if(linePtr[0] == '"')
558 {
559 lineNext = uprv_strchr(linePtr+1, '"');
560 if(lineNext == NULL) {
561 fprintf(stderr, "%s:%d - missing trailing double quote (\")\n",
562 l->str, (int)ln);
563 exit(1);
564 } else {
565 lineNext++;
566 if(*lineNext) {
567 if(*lineNext != ' ') {
568 fprintf(stderr, "%s:%d - malformed quoted line at position %d, expected ' ' got '%c'\n",
569 l->str, (int)ln, (int)(lineNext-line), (*lineNext)?*lineNext:'0');
570 exit(1);
571 }
572 *lineNext = 0;
573 lineNext++;
574 }
575 }
b75a7d8f 576 } else {
73c04bcf
A
577 lineNext = uprv_strchr(linePtr, ' ');
578 if(lineNext) {
579 *lineNext = 0; /* terminate at space */
580 lineNext++;
b75a7d8f 581 }
b75a7d8f 582 }
73c04bcf
A
583
584 /* add the file */
585 s = (char*)getLongPathname(linePtr);
586
587 /* normal mode.. o->files is just the bare list without package names */
588 o->files = pkg_appendToList(o->files, &tail, uprv_strdup(linePtr));
589 if(uprv_pathIsAbsolute(s)) {
590 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);
591 exit(U_ILLEGAL_ARGUMENT_ERROR);
592 }
374ca955
A
593 uprv_strcpy(tmp, o->srcDir);
594 uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1]==U_FILE_SEP_CHAR?"":U_FILE_SEP_STRING);
374ca955
A
595 uprv_strcat(tmp, s);
596 o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp));
73c04bcf
A
597 linePtr = lineNext;
598 } /* for each entry on line */
374ca955 599 } /* for each line */
b75a7d8f 600 T_FileStream_close(in);
374ca955 601 } /* for each file list file */
b75a7d8f
A
602}
603
604/* Try calling icu-config directly to get information */
374ca955 605static void fillInMakefileFromICUConfig(UOption *option)
b75a7d8f
A
606{
607#if U_HAVE_POPEN
374ca955
A
608 FILE *p;
609 size_t n;
610 static char buf[512] = "";
611 static const char cmd[] = "icu-config --incfile";
612
613 if(options[5].doesOccur)
614 {
615 /* informational */
616 fprintf(stderr, "%s: No -O option found, trying '%s'.\n", progname, cmd);
617 }
618
619 p = popen(cmd, "r");
620
621 if(p == NULL)
622 {
623 fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname);
624 return;
625 }
626
627 n = fread(buf, 1, 511, p);
628
629 pclose(p);
630
631 if(n<=0)
632 {
633 fprintf(stderr,"%s: icu-config: Could not read from icu-config. (fix PATH or use -O option)\n", progname);
634 return;
635 }
636
637 if(buf[strlen(buf)-1]=='\n')
638 {
639 buf[strlen(buf)-1]=0;
640 }
641
642 if(buf[0] == 0)
643 {
644 fprintf(stderr, "%s: icu-config: invalid response from icu-config (fix PATH or use -O option)\n", progname);
645 return;
646 }
647
648 if(options[5].doesOccur)
649 {
650 /* informational */
651 fprintf(stderr, "%s: icu-config: using '-O %s'\n", progname, buf);
652 }
653 option->value = buf;
654 option->doesOccur = TRUE;
b75a7d8f
A
655#else /* ! U_HAVE_POPEN */
656
73c04bcf 657#ifdef U_WINDOWS
374ca955
A
658 char pathbuffer[_MAX_PATH] = {0};
659 char *fullEXEpath = NULL;
660 char *pathstuff = NULL;
661
662 if (strchr(progname, U_FILE_SEP_CHAR) != NULL || strchr(progname, U_FILE_ALT_SEP_CHAR) != NULL) {
663 /* pkgdata was executed with relative path */
664 fullEXEpath = _fullpath(pathbuffer, progname, sizeof(pathbuffer));
665 pathstuff = (char *)options[1].value;
666
667 if (fullEXEpath) {
668 pathstuff = strrchr(fullEXEpath, U_FILE_SEP_CHAR);
669 if (pathstuff) {
670 pathstuff[1] = 0;
671 uprv_memmove(fullEXEpath + 2, fullEXEpath, uprv_strlen(fullEXEpath)+1);
672 fullEXEpath[0] = PKGDATA_DERIVED_PATH;
673 fullEXEpath[1] = ':';
674 option->value = uprv_strdup(fullEXEpath);
675 option->doesOccur = TRUE;
676 }
677 }
678 }
679 else {
680 /* pkgdata was executed from the path */
681 /* Search for file in PATH environment variable: */
682 _searchenv("pkgdata.exe", "PATH", pathbuffer );
683 if( *pathbuffer != '\0' ) {
684 fullEXEpath = pathbuffer;
685 pathstuff = strrchr(pathbuffer, U_FILE_SEP_CHAR);
686 if (pathstuff) {
687 pathstuff[1] = 0;
688 uprv_memmove(fullEXEpath + 2, fullEXEpath, uprv_strlen(fullEXEpath)+1);
689 fullEXEpath[0] = PKGDATA_DERIVED_PATH;
690 fullEXEpath[1] = ':';
691 option->value = uprv_strdup(fullEXEpath);
692 option->doesOccur = TRUE;
693 }
694 }
695 }
696 /* else can't determine the path */
697#endif
698
699 /* no popen available */
700 /* Put other OS specific ways to search for the Makefile.inc type
701 information or else fail.. */
b75a7d8f
A
702
703#endif
704}