]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/pkgdata/pkgdata.c
ICU-8.11.1.tar.gz
[apple/icu.git] / icuSources / tools / pkgdata / pkgdata.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2000-2006, 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 #include "putilimp.h"
29
30 #if U_HAVE_POPEN
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
38 # include <unistd.h>
39 #endif
40 #include <stdio.h>
41 #include <stdlib.h>
42
43 U_CDECL_BEGIN
44 #include "pkgtypes.h"
45 #include "makefile.h"
46 U_CDECL_END
47
48 static int executeMakefile(const UPKGOptions *o);
49 static void loadLists(UPKGOptions *o, UErrorCode *status);
50
51 /* always have this fcn, just might not do anything */
52 static void fillInMakefileFromICUConfig(UOption *option);
53
54 /* This sets the modes that are available */
55 static 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." },
63 #ifdef U_MAKE_IS_NMAKE
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 }
67 #else /*#ifdef U_MAKE_IS_NMAKE*/
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 }
73 #endif /*#ifdef U_MAKE_IS_NMAKE*/
74 };
75
76 enum {
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
100 static 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),
118 /*17*/ UOPTION_DEF( "makearg", 'M', UOPT_REQUIRES_ARG),
119 /*18*/ UOPTION_DEF( "force-prefix", 'f', UOPT_NO_ARG),
120 /*19*/ UOPTION_DEF( "libname", 'L', UOPT_REQUIRES_ARG),
121 /*20*/ UOPTION_DEF( "quiet", 'q', UOPT_NO_ARG)
122 };
123
124 const char options_help[][320]={
125 "Set the data name",
126 #ifdef U_MAKE_IS_NMAKE
127 "The directory where the ICU is located (e.g. <ICUROOT> which contains the bin directory)",
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)",
147 "Add package to all file names if not present",
148 "Library name to build (if different than package name)",
149 "Quite mode. (e.g. Do not output a readme file for static libraries)"
150 };
151
152 const char *progname = "PKGDATA";
153
154 int
155 main(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
168 options[MODE].value = "common";
169 options[MAKEARG].value = "";
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
178 if(options[HELP].doesOccur || options[HELP_QUESTION_MARK].doesOccur) {
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
191 if(!options[BLDOPT].doesOccur) {
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");
200 }
201 #endif
202
203 if(!options[BLDOPT].doesOccur) {
204 fprintf(stderr, " required parameter is missing: -O is required \n");
205 fprintf(stderr, "Run '%s --help' for help.\n", progname);
206 return 1;
207 }
208
209 if(!options[NAME].doesOccur) /* -O we already have - don't report it. */
210 {
211 fprintf(stderr, " required parameter -p is missing \n");
212 fprintf(stderr, "Run '%s --help' for help.\n", progname);
213 return 1;
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",
235 (i<1?"[REQ]":""),
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
258 o.mode = options[MODE].value;
259 o.version = options[REVISION].doesOccur ? options[REVISION].value : 0;
260 o.makeArgs = options[MAKEARG].value;
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;
281 {
282 int32_t len = (int32_t)uprv_strlen(o.shortName);
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
298 if(options[LIBNAME].doesOccur) { /* get libname from shortname, or explicit -L parameter */
299 o.libName = options[LIBNAME].value;
300 } else {
301 o.libName = o.shortName;
302 }
303
304 if(options[QUIET].doesOccur) {
305 o.quiet = TRUE;
306 } else {
307 o.quiet = FALSE;
308 }
309
310 o.verbose = options[VERBOSE].doesOccur;
311 #ifdef U_MAKE_IS_NMAKE /* format is R:pathtoICU or D:pathtoICU */
312 {
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';
316 }
317 if(*pathstuff == PKGDATA_DERIVED_PATH || *pathstuff == 'R' || *pathstuff == 'D') {
318 o.options = pathstuff;
319 pathstuff++;
320 if(*pathstuff == ':') {
321 *pathstuff = '\0';
322 pathstuff++;
323 }
324 else {
325 fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n");
326 return 1;
327 }
328 } else {
329 fprintf(stderr, "Error: invalid windows build mode, should be R (release) or D (debug).\n");
330 return 1;
331 }
332 o.icuroot = pathstuff;
333 if (o.verbose) {
334 fprintf(stdout, "# ICUROOT is %s\n", o.icuroot);
335 }
336 }
337 #else /* on UNIX, we'll just include the file... */
338 o.options = options[BLDOPT].value;
339 #endif
340 if(options[COPYRIGHT].doesOccur) {
341 o.comment = U_COPYRIGHT_STRING;
342 } else if (options[COMMENT].doesOccur) {
343 o.comment = options[COMMENT].value;
344 }
345
346 if( options[DESTDIR].doesOccur ) {
347 o.targetDir = options[DESTDIR].value;
348 } else {
349 o.targetDir = "."; /* cwd */
350 }
351
352 o.clean = options[CLEAN].doesOccur;
353 o.nooutput = options[NOOUTPUT].doesOccur;
354 o.rebuild = options[REBUILD].doesOccur;
355
356 if( options[TEMPDIR].doesOccur ) {
357 o.tmpDir = options[TEMPDIR].value;
358 } else {
359 o.tmpDir = o.targetDir;
360 }
361
362 if( options[INSTALL].doesOccur ) {
363 o.install = options[INSTALL].value;
364 }
365
366 if( options[SOURCEDIR].doesOccur ) {
367 o.srcDir = options[SOURCEDIR].value;
368 } else {
369 o.srcDir = ".";
370 }
371
372 if( options[ENTRYPOINT].doesOccur ) {
373 o.entryName = options[ENTRYPOINT].value;
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);
403 #ifdef U_MAKE_IS_NMAKE
404 uprv_strcat(tmp, U_FILE_SEP_STRING);
405 #else
406 uprv_strcat(tmp, U_FILE_ALT_SEP_STRING);
407 #endif
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 */
440 static 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);*/
454 #ifdef U_WINDOWS
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);
464 #elif defined(OS400)
465 sprintf(cmd, "CALL GNU/GMAKE PARM(%s%s%s '-f' '%s' %s %s %s %s%s%s)",
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'" : "",
473 o->makeArgs && *o->makeArgs ? "'" : "",
474 o->makeArgs && *o->makeArgs ? o->makeArgs : "",
475 o->makeArgs && *o->makeArgs ? "'" : "");
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
501 static 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;
508 char tmp[1024];
509 char *s;
510 int32_t ln=0; /* line number */
511
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 */
517 in = T_FileStream_open(l->str, "r"); /* open files list */
518
519 if(!in) {
520 fprintf(stderr, "Error opening <%s>.\n", l->str);
521 *status = U_FILE_ACCESS_ERROR;
522 return;
523 }
524
525 while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) { /* for each line */
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);
530 }
531 /* remove spaces at the beginning */
532 linePtr = line;
533 while(isspace(*linePtr)) {
534 linePtr++;
535 }
536 s=linePtr;
537 /* remove trailing newline characters */
538 while(*s!=0) {
539 if(*s=='\r' || *s=='\n') {
540 *s=0;
541 break;
542 }
543 ++s;
544 }
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 }
576 } else {
577 lineNext = uprv_strchr(linePtr, ' ');
578 if(lineNext) {
579 *lineNext = 0; /* terminate at space */
580 lineNext++;
581 }
582 }
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 }
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);
595 uprv_strcat(tmp, s);
596 o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp));
597 linePtr = lineNext;
598 } /* for each entry on line */
599 } /* for each line */
600 T_FileStream_close(in);
601 } /* for each file list file */
602 }
603
604 /* Try calling icu-config directly to get information */
605 static void fillInMakefileFromICUConfig(UOption *option)
606 {
607 #if U_HAVE_POPEN
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;
655 #else /* ! U_HAVE_POPEN */
656
657 #ifdef U_WINDOWS
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.. */
702
703 #endif
704 }