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