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