static CharList * pkg_appendFromStrings(CharList *l, CharList** end, const char *s, int32_t len) { CharList *endptr = NULL; const char *p; char *t; const char *targ; if(end == NULL) { end = &endptr; } if(len==-1) { len = uprv_strlen(s); } targ = s+len; while(*s && s<targ) { while(s<targ&&isspace(*s)) s++; for(p=s;s<targ&&!isspace(*p);p++); if(p!=s) { t = uprv_malloc(p-s+1); uprv_strncpy(t,s,p-s); t[p-s]=0; l=pkg_appendToList(l,end,t); fprintf(stderr, " P %s\n", t); } s=p; } return l; }
CharList *pkg_appendUniqueDirToList(CharList *l, CharList** end, const char *strAlias) { char aBuf[1024]; char *rPtr; rPtr = uprv_strrchr(strAlias, U_FILE_SEP_CHAR); #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) { char *aPtr = uprv_strrchr(strAlias, U_FILE_ALT_SEP_CHAR); if(!rPtr || /* regular char wasn't found or.. */ (aPtr && (aPtr > rPtr))) { /* alt ptr exists and is to the right of r ptr */ rPtr = aPtr; /* may copy NULL which is OK */ } } #endif if(!rPtr) { return l; /* no dir path */ } if((rPtr-strAlias) >= (sizeof(aBuf)/sizeof(aBuf[0]))) { fprintf(stderr, "## ERR: Path too long [%d chars]: %s\n", (int)sizeof(aBuf), strAlias); return l; } strncpy(aBuf, strAlias,(rPtr-strAlias)); aBuf[rPtr-strAlias]=0; /* no trailing slash */ convertToNativePathSeparators(aBuf); if(!pkg_listContains(l, aBuf)) { return pkg_appendToList(l, end, uprv_strdup(aBuf)); } else { return l; /* already found */ } }
void pkg_mode_common(UPKGOptions *o, FileStream *makefile, UErrorCode *status) { char tmp[1024]; CharList *tail = NULL; uprv_strcpy(tmp, UDATA_CMN_PREFIX); uprv_strcat(tmp, o->shortName); uprv_strcat(tmp, UDATA_CMN_SUFFIX); if(!uprv_strcmp(o->mode, "common")) { /* If we're not the main mode.. don't change the output file list */ /* We should be the only item. So we don't care about the order. */ o->outFiles = pkg_appendToList(o->outFiles, &tail, uprv_strdup(tmp)); if(o->nooutput || o->verbose) { fprintf(stdout, "# Output file: %s%s%s\n", o->targetDir, U_FILE_SEP_STRING, tmp); } if(o->nooutput) { *status = U_ZERO_ERROR; return; } sprintf(tmp, "# File to make:\nTARGET=%s%s%s\n\nTARGETNAME=%s\n", o->targetDir, U_FILE_SEP_STRING, o->outFiles->str, o->outFiles->str); T_FileStream_writeLine(makefile, tmp); } else { /* We're in another mode. but, set the target so they can find us.. */ T_FileStream_writeLine(makefile, "TARGET="); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "\n\n"); } /* end [check to make sure we are in mode 'common' ] */ sprintf(tmp, "# List file for gencmn:\n" "CMNLIST=%s%s%s_common.lst\n\n", o->tmpDir, U_FILE_SEP_STRING, o->shortName); T_FileStream_writeLine(makefile, tmp); sprintf(tmp, "all: $(TARGET)\n\n"); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "$(TARGET): $(CMNLIST) $(DATAFILEPATHS)\n" "\t$(INVOKE) $(GENCMN) -n $(CNAME) -c -s $(SRCDIR) -d $(TARGETDIR) 0 $(CMNLIST)\n\n"); if(o->hadStdin == FALSE) { /* shortcut */ T_FileStream_writeLine(makefile, "$(CMNLIST): $(LISTFILES)\n" "\tcat $(LISTFILES) > $(CMNLIST)\n\n"); } else { T_FileStream_writeLine(makefile, "$(CMNLIST): \n" "\t@echo \"generating $@ (list of data files)\"\n" "\t@-$(RMV) $@\n" "\t@for file in $(DATAFILEPATHS); do \\\n" "\t echo $$file >> $@; \\\n" "\tdone;\n\n"); } if(!uprv_strcmp(o->mode, "common")) { /* only install/clean in our own mode */ T_FileStream_writeLine(makefile, "CLEANFILES= $(CMNLIST) $(TARGET)\n\nclean:\n\t-$(RMV) $(CLEANFILES) $(MAKEFILE)"); T_FileStream_writeLine(makefile, "\n\n"); sprintf(tmp, "install: $(TARGET)\n" "\t$(INSTALL_DATA) $(TARGET) $(INSTALLTO)%s$(TARGETNAME)\n\n", U_FILE_SEP_STRING); T_FileStream_writeLine(makefile, tmp); } }
int main(int argc, char* argv[]) { int result = 0; /* FileStream *out; */ UPKGOptions o; CharList *tail; UBool needsHelp = FALSE; UErrorCode status = U_ZERO_ERROR; /* char tmp[1024]; */ uint32_t i; int32_t n; U_MAIN_INIT_ARGS(argc, argv); progname = argv[0]; options[MODE].value = "common"; /* read command line options */ argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); /* error handling, printing usage message */ /* I've decided to simply print an error and quit. This tool has too many options to just display them all of the time. */ if(options[HELP].doesOccur || options[HELP_QUESTION_MARK].doesOccur) { needsHelp = TRUE; } else { if(!needsHelp && argc<0) { fprintf(stderr, "%s: error in command line argument \"%s\"\n", progname, argv[-argc]); fprintf(stderr, "Run '%s --help' for help.\n", progname); return 1; } #ifndef WINDOWS_WITH_MSVC if(!options[BLDOPT].doesOccur) { if (pkg_getOptionsFromICUConfig(&options[BLDOPT]) != 0) { fprintf(stderr, " required parameter is missing: -O is required \n"); fprintf(stderr, "Run '%s --help' for help.\n", progname); return 1; } } #else if(options[BLDOPT].doesOccur) { fprintf(stdout, "Warning: You are using the -O option which is not needed for MSVC build on Windows.\n"); } #endif if(!options[NAME].doesOccur) /* -O we already have - don't report it. */ { fprintf(stderr, " required parameter -p is missing \n"); fprintf(stderr, "Run '%s --help' for help.\n", progname); return 1; } if(argc == 1) { fprintf(stderr, "No input files specified.\n" "Run '%s --help' for help.\n", progname); return 1; } } /* end !needsHelp */ if(argc<0 || needsHelp ) { fprintf(stderr, "usage: %s [-options] [-] [packageFile] \n" "\tProduce packaged ICU data from the given list(s) of files.\n" "\t'-' by itself means to read from stdin.\n" "\tpackageFile is a text file containing the list of files to package.\n", progname); fprintf(stderr, "\n options:\n"); for(i=0;i<(sizeof(options)/sizeof(options[0]));i++) { fprintf(stderr, "%-5s -%c %s%-10s %s\n", (i<1?"[REQ]":""), options[i].shortName, options[i].longName ? "or --" : " ", options[i].longName ? options[i].longName : "", options_help[i]); } fprintf(stderr, "modes: (-m option)\n"); for(i=0;i<(sizeof(modes)/sizeof(modes[0]));i++) { fprintf(stderr, " %-9s ", modes[i].name); if (modes[i].alt_name) { fprintf(stderr, "/ %-9s", modes[i].alt_name); } else { fprintf(stderr, " "); } fprintf(stderr, " %s\n", modes[i].desc); } return 1; } /* OK, fill in the options struct */ uprv_memset(&o, 0, sizeof(o)); o.mode = options[MODE].value; o.version = options[REVISION].doesOccur ? options[REVISION].value : 0; o.shortName = options[NAME].value; { int32_t len = (int32_t)uprv_strlen(o.shortName); char *csname, *cp; const char *sp; cp = csname = (char *) uprv_malloc((len + 1 + 1) * sizeof(*o.cShortName)); if (*(sp = o.shortName)) { *cp++ = isalpha(*sp) ? * sp : '_'; for (++sp; *sp; ++sp) { *cp++ = isalnum(*sp) ? *sp : '_'; } } *cp = 0; o.cShortName = csname; } if(options[LIBNAME].doesOccur) { /* get libname from shortname, or explicit -L parameter */ o.libName = options[LIBNAME].value; } else { o.libName = o.shortName; } if(options[QUIET].doesOccur) { o.quiet = TRUE; } else { o.quiet = FALSE; } o.verbose = options[VERBOSE].doesOccur; #ifndef WINDOWS_WITH_MSVC /* on UNIX, we'll just include the file... */ o.options = options[BLDOPT].value; #endif if(options[COPYRIGHT].doesOccur) { o.comment = U_COPYRIGHT_STRING; } else if (options[COMMENT].doesOccur) { o.comment = options[COMMENT].value; } if( options[DESTDIR].doesOccur ) { o.targetDir = options[DESTDIR].value; } else { o.targetDir = "."; /* cwd */ } o.rebuild = options[REBUILD].doesOccur; if( options[TEMPDIR].doesOccur ) { o.tmpDir = options[TEMPDIR].value; } else { o.tmpDir = o.targetDir; } if( options[INSTALL].doesOccur ) { o.install = options[INSTALL].value; } else { o.install = NULL; } if( options[SOURCEDIR].doesOccur ) { o.srcDir = options[SOURCEDIR].value; } else { o.srcDir = "."; } if( options[ENTRYPOINT].doesOccur ) { o.entryName = options[ENTRYPOINT].value; } else { o.entryName = o.cShortName; } /* OK options are set up. Now the file lists. */ tail = NULL; for( n=1; n<argc; n++) { o.fileListFiles = pkg_appendToList(o.fileListFiles, &tail, uprv_strdup(argv[n])); } /* load the files */ loadLists(&o, &status); if( U_FAILURE(status) ) { fprintf(stderr, "error loading input file lists: %s\n", u_errorName(status)); return 2; } result = pkg_executeOptions(&o); if (pkgDataFlags != NULL) { for (n = 0; n < PKGDATA_FLAGS_SIZE; n++) { if (pkgDataFlags[n] != NULL) { uprv_free(pkgDataFlags[n]); } } uprv_free(pkgDataFlags); } if (o.cShortName != NULL) { uprv_free((char *)o.cShortName); } if (o.fileListFiles != NULL) { pkg_deleteList(o.fileListFiles); } if (o.filePaths != NULL) { pkg_deleteList(o.filePaths); } if (o.files != NULL) { pkg_deleteList(o.files); } return result; }
void pkg_mode_static(UPKGOptions *o, FileStream *makefile, UErrorCode *status) { char tmp[1024]; CharList *tail = NULL; CharList *objects = NULL; if(U_FAILURE(*status)) { return; } uprv_strcpy(tmp, LIB_STATIC_PREFIX); uprv_strcat(tmp, o->libName); uprv_strcat(tmp, UDATA_LIB_SUFFIX); o->outFiles = pkg_appendToList(o->outFiles, &tail, uprv_strdup(tmp)); if (!o->quiet) { pkg_sttc_writeReadme(o, tmp, status); } if(U_FAILURE(*status)) { return; } if(o->nooutput || o->verbose) { fprintf(stdout, "# Output file: %s%s%s\n", o->targetDir, U_FILE_SEP_STRING, tmp); } if(o->nooutput) { *status = U_ZERO_ERROR; return; } /* begin writing makefile ========================= */ T_FileStream_writeLine(makefile, "# Version numbers:\nVERSIONED="); if (o->version) { sprintf(tmp, ".%s", o->version); if (!uprv_strchr(o->version, '.')) { uprv_strcat(tmp, ".0"); } T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "\nDLL_LDFLAGS=$(LD_SONAME) $(RPATH_LDFLAGS)\n"); } else { T_FileStream_writeLine(makefile, "\nDLL_LDFLAGS=$(BIR_LDFLAGS)\n"); } T_FileStream_writeLine(makefile, "\n"); sprintf(tmp, "# File to make:\nTARGET=%s\n\n", o->outFiles->str); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "LIB_TARGET=$(TARGET)\n"); uprv_strcpy(tmp, "all: $(TARG_PATH)$(LIB_TARGET)"); uprv_strcat(tmp, "\n\n"); T_FileStream_writeLine(makefile, tmp); #ifdef OS400 /* New for iSeries: All packaged data in one .c */ sprintf(tmp, "# Create a file which contains all .c data files/structures\n" "$(TEMP_DIR)/$(NAME)all.c: $(CMNLIST)\n\n"); T_FileStream_writeLine(makefile, tmp); #endif /* Write compile rules */ pkg_mak_writeObjRules(o, makefile, &objects, ".$(STATIC_O)"); /* use special .o suffix */ sprintf(tmp, "# List file for gencmn:\n" "CMNLIST=%s%s$(NAME)_static.lst\n\n", o->tmpDir, U_FILE_SEP_STRING); T_FileStream_writeLine(makefile, tmp); if(o->hadStdin == FALSE) { /* shortcut */ T_FileStream_writeLine(makefile, "$(CMNLIST): $(LISTFILES)\n" "\tcat $(LISTFILES) > $(CMNLIST)\n\n"); } else { T_FileStream_writeLine(makefile, "$(CMNLIST): \n" "\t@echo \"generating $@ (list of data files)\"\n" "\t@-$(RMV) $@\n" "\t@for file in $(DATAFILEPATHS); do \\\n" "\t echo $$file >> $@; \\\n" "\tdone;\n\n"); } pkg_mak_writeAssemblyHeader(makefile, o); sprintf(tmp,"$(TEMP_PATH)$(NAME)_dat.$(STATIC_O) : $(TEMP_PATH)$(NAME)_dat.c\n" "\t$(COMPILE.c) -o $@ $<\n\n"); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "# 'TOCOBJ' contains C Table of Contents objects [if any]\n"); if(!o->embed) { sprintf(tmp, "$(TEMP_PATH)$(NAME)_dat.c: $(CMNLIST)\n" "\t$(INVOKE) $(GENCMN) -e $(ENTRYPOINT) -n $(NAME) -S -s $(SRCDIR) -d $(TEMP_DIR) 0 $(CMNLIST)\n\n"); } else { sprintf(tmp, "$(TEMP_PATH)$(NAME)_dat.c: $(CMNLIST)\n" "\t$(INVOKE) $(GENCMN) -e $(ENTRYPOINT) -n $(NAME) -S -E -d $(TEMP_DIR) 0 $(CMNLIST)\n\n"); } T_FileStream_writeLine(makefile, tmp); sprintf(tmp, "TOCOBJ= $(NAME)_dat%s \n\n", OBJ_SUFFIX); T_FileStream_writeLine(makefile, tmp); #ifdef OS400 /* New for iSeries: All packaged data in one .c */ sprintf(tmp,"$(TEMP_PATH)$(NAME)all.$(STATIC_O) : $(TEMP_PATH)$(NAME)all.c\n" "\t$(COMPILE.c) -o $@ $<\n\n"); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "# 'ALLDATAOBJ' contains all .c data structures\n"); sprintf(tmp, "ALLDATAOBJ= $(NAME)all%s \n\n", OBJ_SUFFIX); T_FileStream_writeLine(makefile, tmp); #endif sprintf(tmp, "TOCSYM= $(ENTRYPOINT)_dat \n\n"); /* entrypoint not always shortname! */ T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "BASE_OBJECTS= $(TOCOBJ) "); #ifdef OS400 T_FileStream_writeLine(makefile, "$(ALLDATAOBJ) "); #else pkg_writeCharListWrap(makefile, objects, " ", " \\\n",0); #endif pkg_mak_writeAssemblyFooter(makefile, o); T_FileStream_writeLine(makefile, "\n\n"); T_FileStream_writeLine(makefile, "OBJECTS=$(BASE_OBJECTS:%=$(TEMP_PATH)%)\n\n"); T_FileStream_writeLine(makefile,"$(TEMP_PATH)%.$(STATIC_O): $(TEMP_PATH)%.c\n\t $(COMPILE.c) -o $@ $<\n\n"); #if NO_IMPLICIT_AR T_FileStream_writeLine(makefile, "$(TARG_PATH)$(LIB_TARGET):$(TARG_PATH)$(LIB_TARGET) $(OBJECTS) $(LISTFILES)\n" "\t$(AR) $(ARFLAGS) $(TARG_PATH)$(LIB_TARGET) $(OBJECTS)\n" "\t$(RANLIB) $@\n\n"); #else T_FileStream_writeLine(makefile, "$(TARG_PATH)$(LIB_TARGET):$(TARG_PATH)$(LIB_TARGET)($(OBJECTS)) $(LISTFILES)\n" "\t$(RANLIB) $@\n\n"); #endif T_FileStream_writeLine(makefile, "CLEANFILES= $(CMNLIST) $(OBJECTS) $(TARG_PATH)$(LIB_TARGET) $(TARG_PATH)$(MIDDLE_STATIC_LIB_TARGET) $(TARG_PATH)$(TARGET)\n\nclean:\n\t-$(RMV) $(CLEANFILES) $(MAKEFILE)"); T_FileStream_writeLine(makefile, "\n\n"); T_FileStream_writeLine(makefile, "# static mode shouldn't need to be installed, but we will install the header and static library for them.\n"); T_FileStream_writeLine(makefile, "install: $(TARG_PATH)$(LIB_TARGET)\n" "\t$(INSTALL-L) $(TARG_PATH)$(LIB_TARGET) $(INSTALLTO)/$(LIB_TARGET)\n"); T_FileStream_writeLine(makefile, "\t$(RANLIB) $(INSTALLTO)/$(LIB_TARGET)\n"); if (o->version) { T_FileStream_writeLine(makefile, "\tcd $(INSTALLTO) && $(RM) $(MIDDLE_STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(MIDDLE_STATIC_LIB_TARGET)\n\tcd $(INSTALLTO) && $(RM) $(STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(STATIC_LIB_TARGET)\n"); T_FileStream_writeLine(makefile, "\t$(RANLIB) $(INSTALLTO)/$(STATIC_LIB_TARGET)\n\n"); } *status = U_ZERO_ERROR; }