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