]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/pkgdata/pkgdata.c
ICU-6.2.10.tar.gz
[apple/icu.git] / icuSources / tools / pkgdata / pkgdata.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2000-2004, International Business Machines
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
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"
25 #include "unicode/uclean.h"
26 #include "unewdata.h"
27 #include "uoptions.h"
28
29 #if U_HAVE_POPEN
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
37 # include <unistd.h>
38 #endif
39 #include <stdio.h>
40 #include <stdlib.h>
41
42 U_CDECL_BEGIN
43 #include "pkgtypes.h"
44 #include "makefile.h"
45 U_CDECL_END
46
47 static int executeMakefile(const UPKGOptions *o);
48 static void loadLists(UPKGOptions *o, UErrorCode *status);
49
50 /* always have this fcn, just might not do anything */
51 static void fillInMakefileFromICUConfig(UOption *option);
52
53 /* This sets the modes that are available */
54 static 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." },
62 #ifdef U_MAKE_IS_NMAKE
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 }
66 #else /*#ifdef U_MAKE_IS_NMAKE*/
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 }
72 #endif /*#ifdef U_MAKE_IS_NMAKE*/
73 };
74
75 static 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),
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)
99 };
100
101 const char options_help[][320]={
102 "Set the data name",
103 #ifdef U_MAKE_IS_NMAKE
104 "The directory where the ICU is located (e.g. <ICUROOT> which contains the bin directory)",
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)",
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)"
129 };
130
131 const char *progname = "PKGDATA";
132
133 int
134 main(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) {
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");
179 }
180 #endif
181
182 if(!options[1].doesOccur) {
183 fprintf(stderr, " required parameter is missing: -O is required \n");
184 fprintf(stderr, "Run '%s --help' for help.\n", progname);
185 return 1;
186 }
187
188 if(!options[0].doesOccur) /* -O we already have - don't report it. */
189 {
190 fprintf(stderr, " required parameter -p is missing \n");
191 fprintf(stderr, "Run '%s --help' for help.\n", progname);
192 return 1;
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",
214 (i<1?"[REQ]":""),
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;
260 {
261 int32_t len = (int32_t)uprv_strlen(o.shortName);
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
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 */
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 }
296 if(*pathstuff == PKGDATA_DERIVED_PATH || *pathstuff == 'R' || *pathstuff == 'D') {
297 o.options = pathstuff;
298 pathstuff++;
299 if(*pathstuff == ':') {
300 *pathstuff = '\0';
301 pathstuff++;
302 }
303 else {
304 fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n");
305 return 1;
306 }
307 } else {
308 fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n");
309 return 1;
310 }
311 o.icuroot = pathstuff;
312 if (o.verbose) {
313 fprintf(stdout, "# ICUROOT is %s\n", o.icuroot);
314 }
315 }
316 #else /* on UNIX, we'll just include the file... */
317 o.options = options[1].value;
318 #endif
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;
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;
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 */
421 static 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
480 static 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;
487 char tmp[1024];
488 char pkgPrefix[1024];
489 int32_t pkgPrefixLen;
490 const char *baseName;
491 char *s;
492 int32_t ln=0; /* line number */
493 UBool fixPrefix;
494
495
496 fixPrefix = options[18].doesOccur;
497
498 strcpy(pkgPrefix, o->shortName);
499 strcat(pkgPrefix, "_");
500 pkgPrefixLen=(int32_t)uprv_strlen(pkgPrefix);
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 */
506 in = T_FileStream_open(l->str, "r"); /* open files list */
507
508 if(!in) {
509 fprintf(stderr, "Error opening <%s>.\n", l->str);
510 *status = U_FILE_ACCESS_ERROR;
511 return;
512 }
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;
520 }
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;
538 }
539 ++s;
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++;
551 }
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);
560 } else {
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);
567 }
568 *lineNext = 0;
569 lineNext++;
570 }
571 }
572 } else {
573 lineNext = uprv_strchr(linePtr, ' ');
574 if(lineNext) {
575 *lineNext = 0; /* terminate at space */
576 lineNext++;
577 }
578 }
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 */
610 T_FileStream_close(in);
611 } /* for each file list file */
612 }
613
614 /* Try calling icu-config directly to get information */
615 static void fillInMakefileFromICUConfig(UOption *option)
616 {
617 #if U_HAVE_POPEN
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;
665 #else /* ! U_HAVE_POPEN */
666
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.. */
712
713 #endif
714 }