OLD | NEW |
1 /****************************************************************************** | 1 /****************************************************************************** |
2 * Copyright (C) 2000-2014, International Business Machines | 2 * Copyright (C) 2000-2015, International Business Machines |
3 * Corporation and others. All Rights Reserved. | 3 * Corporation and others. All Rights Reserved. |
4 ******************************************************************************* | 4 ******************************************************************************* |
5 * file name: pkgdata.cpp | 5 * file name: pkgdata.cpp |
6 * encoding: ANSI X3.4 (1968) | 6 * encoding: ANSI X3.4 (1968) |
7 * tab size: 8 (not used) | 7 * tab size: 8 (not used) |
8 * indentation:4 | 8 * indentation:4 |
9 * | 9 * |
10 * created on: 2000may15 | 10 * created on: 2000may15 |
11 * created by: Steven \u24C7 Loomis | 11 * created by: Steven \u24C7 Loomis |
12 * | 12 * |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 # include <unistd.h> | 49 # include <unistd.h> |
50 #endif | 50 #endif |
51 | 51 |
52 #include <stdio.h> | 52 #include <stdio.h> |
53 #include <stdlib.h> | 53 #include <stdlib.h> |
54 | 54 |
55 U_CDECL_BEGIN | 55 U_CDECL_BEGIN |
56 #include "pkgtypes.h" | 56 #include "pkgtypes.h" |
57 U_CDECL_END | 57 U_CDECL_END |
58 | 58 |
| 59 #if U_HAVE_POPEN |
| 60 |
| 61 using icu::LocalPointerBase; |
| 62 |
| 63 U_DEFINE_LOCAL_OPEN_POINTER(LocalPipeFilePointer, FILE, pclose); |
| 64 |
| 65 #endif |
59 | 66 |
60 static void loadLists(UPKGOptions *o, UErrorCode *status); | 67 static void loadLists(UPKGOptions *o, UErrorCode *status); |
61 | 68 |
62 static int32_t pkg_executeOptions(UPKGOptions *o); | 69 static int32_t pkg_executeOptions(UPKGOptions *o); |
63 | 70 |
64 #ifdef WINDOWS_WITH_MSVC | 71 #ifdef WINDOWS_WITH_MSVC |
65 static int32_t pkg_createWindowsDLL(const char mode, const char *gencFilePath, U
PKGOptions *o); | 72 static int32_t pkg_createWindowsDLL(const char mode, const char *gencFilePath, U
PKGOptions *o); |
66 #endif | 73 #endif |
67 static int32_t pkg_createSymLinks(const char *targetDir, UBool specialHandling=F
ALSE); | 74 static int32_t pkg_createSymLinks(const char *targetDir, UBool specialHandling=F
ALSE); |
68 static int32_t pkg_installLibrary(const char *installDir, const char *dir, UBool
noVersion); | 75 static int32_t pkg_installLibrary(const char *installDir, const char *dir, UBool
noVersion); |
69 static int32_t pkg_installFileMode(const char *installDir, const char *srcDir, c
onst char *fileListName); | 76 static int32_t pkg_installFileMode(const char *installDir, const char *srcDir, c
onst char *fileListName); |
70 static int32_t pkg_installCommonMode(const char *installDir, const char *fileNam
e); | 77 static int32_t pkg_installCommonMode(const char *installDir, const char *fileNam
e); |
71 | 78 |
72 #ifdef BUILD_DATA_WITHOUT_ASSEMBLY | 79 #ifdef BUILD_DATA_WITHOUT_ASSEMBLY |
73 static int32_t pkg_createWithoutAssemblyCode(UPKGOptions *o, const char *targetD
ir, const char mode); | 80 static int32_t pkg_createWithoutAssemblyCode(UPKGOptions *o, const char *targetD
ir, const char mode); |
74 #endif | 81 #endif |
75 | 82 |
| 83 #ifdef CAN_WRITE_OBJ_CODE |
| 84 static void pkg_createOptMatchArch(char *optMatchArch); |
| 85 static void pkg_destroyOptMatchArch(char *optMatchArch); |
| 86 #endif |
| 87 |
76 static int32_t pkg_createWithAssemblyCode(const char *targetDir, const char mode
, const char *gencFilePath); | 88 static int32_t pkg_createWithAssemblyCode(const char *targetDir, const char mode
, const char *gencFilePath); |
77 static int32_t pkg_generateLibraryFile(const char *targetDir, const char mode, c
onst char *objectFile, char *command = NULL, UBool specialHandling=FALSE); | 89 static int32_t pkg_generateLibraryFile(const char *targetDir, const char mode, c
onst char *objectFile, char *command = NULL, UBool specialHandling=FALSE); |
78 static int32_t pkg_archiveLibrary(const char *targetDir, const char *version, UB
ool reverseExt); | 90 static int32_t pkg_archiveLibrary(const char *targetDir, const char *version, UB
ool reverseExt); |
79 static void createFileNames(UPKGOptions *o, const char mode, const char *version
_major, const char *version, const char *libName, const UBool reverseExt, UBool
noVersion); | 91 static void createFileNames(UPKGOptions *o, const char mode, const char *version
_major, const char *version, const char *libName, const UBool reverseExt, UBool
noVersion); |
80 static int32_t initializePkgDataFlags(UPKGOptions *o); | 92 static int32_t initializePkgDataFlags(UPKGOptions *o); |
81 | 93 |
82 static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option); | 94 static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option); |
83 static int runCommand(const char* command, UBool specialHandling=FALSE); | 95 static int runCommand(const char* command, UBool specialHandling=FALSE); |
84 | 96 |
85 #define IN_COMMON_MODE(mode) (mode == 'a' || mode == 'c') | 97 #define IN_COMMON_MODE(mode) (mode == 'a' || mode == 'c') |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 } | 735 } |
724 if (o->withoutAssembly) { | 736 if (o->withoutAssembly) { |
725 #ifdef BUILD_DATA_WITHOUT_ASSEMBLY | 737 #ifdef BUILD_DATA_WITHOUT_ASSEMBLY |
726 result = pkg_createWithoutAssemblyCode(o, targetDir, mode); | 738 result = pkg_createWithoutAssemblyCode(o, targetDir, mode); |
727 #else | 739 #else |
728 /* This error should not occur. */ | 740 /* This error should not occur. */ |
729 fprintf(stderr, "Error- BUILD_DATA_WITHOUT_ASSEMBLY is not d
efined. Internal error.\n"); | 741 fprintf(stderr, "Error- BUILD_DATA_WITHOUT_ASSEMBLY is not d
efined. Internal error.\n"); |
730 #endif | 742 #endif |
731 } else { | 743 } else { |
732 #ifdef CAN_WRITE_OBJ_CODE | 744 #ifdef CAN_WRITE_OBJ_CODE |
733 writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, NU
LL, NULL, gencFilePath); | 745 /* Try to detect the arch type, use NULL if unsuccessful */ |
| 746 char optMatchArch[10] = { 0 }; |
| 747 pkg_createOptMatchArch(optMatchArch); |
| 748 writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, (o
ptMatchArch[0] == 0 ? NULL : optMatchArch), NULL, gencFilePath); |
| 749 pkg_destroyOptMatchArch(optMatchArch); |
734 #if U_PLATFORM_IS_LINUX_BASED | 750 #if U_PLATFORM_IS_LINUX_BASED |
735 result = pkg_generateLibraryFile(targetDir, mode, gencFilePa
th); | 751 result = pkg_generateLibraryFile(targetDir, mode, gencFilePa
th); |
736 #elif defined(WINDOWS_WITH_MSVC) | 752 #elif defined(WINDOWS_WITH_MSVC) |
737 result = pkg_createWindowsDLL(mode, gencFilePath, o); | 753 result = pkg_createWindowsDLL(mode, gencFilePath, o); |
738 #endif | 754 #endif |
739 #elif defined(BUILD_DATA_WITHOUT_ASSEMBLY) | 755 #elif defined(BUILD_DATA_WITHOUT_ASSEMBLY) |
740 result = pkg_createWithoutAssemblyCode(o, targetDir, mode); | 756 result = pkg_createWithoutAssemblyCode(o, targetDir, mode); |
741 #else | 757 #else |
742 fprintf(stderr, "Error- neither CAN_WRITE_OBJ_CODE nor BUILD
_DATA_WITHOUT_ASSEMBLY are defined. Internal error.\n"); | 758 fprintf(stderr, "Error- neither CAN_WRITE_OBJ_CODE nor BUILD
_DATA_WITHOUT_ASSEMBLY are defined. Internal error.\n"); |
743 return 1; | 759 return 1; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) | 825 #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) |
810 do { | 826 do { |
811 #endif | 827 #endif |
812 if (pkgDataFlags != NULL) { | 828 if (pkgDataFlags != NULL) { |
813 for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { | 829 for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { |
814 pkgDataFlags[i] = (char*)uprv_malloc(sizeof(char) * currentBuffe
rSize); | 830 pkgDataFlags[i] = (char*)uprv_malloc(sizeof(char) * currentBuffe
rSize); |
815 if (pkgDataFlags[i] != NULL) { | 831 if (pkgDataFlags[i] != NULL) { |
816 pkgDataFlags[i][0] = 0; | 832 pkgDataFlags[i][0] = 0; |
817 } else { | 833 } else { |
818 fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"
); | 834 fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"
); |
| 835 /* If an error occurs, ensure that the rest of the array is
NULL */ |
| 836 for (int32_t n = i + 1; n < PKGDATA_FLAGS_SIZE; n++) { |
| 837 pkgDataFlags[n] = NULL; |
| 838 } |
819 return -1; | 839 return -1; |
820 } | 840 } |
821 } | 841 } |
822 } else { | 842 } else { |
823 fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); | 843 fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); |
824 return -1; | 844 return -1; |
825 } | 845 } |
826 | 846 |
827 if (o->options == NULL) { | 847 if (o->options == NULL) { |
828 return result; | 848 return result; |
829 } | 849 } |
830 | 850 |
831 #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) | 851 #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) |
832 /* Read in options file. */ | 852 /* Read in options file. */ |
833 if(o->verbose) { | 853 if(o->verbose) { |
834 fprintf(stdout, "# Reading options file %s\n", o->options); | 854 fprintf(stdout, "# Reading options file %s\n", o->options); |
835 } | 855 } |
836 status = U_ZERO_ERROR; | 856 status = U_ZERO_ERROR; |
837 tmpResult = parseFlagsFile(o->options, pkgDataFlags, currentBufferSize,
FLAG_NAMES, (int32_t)PKGDATA_FLAGS_SIZE, &status); | 857 tmpResult = parseFlagsFile(o->options, pkgDataFlags, currentBufferSize,
FLAG_NAMES, (int32_t)PKGDATA_FLAGS_SIZE, &status); |
838 if (status == U_BUFFER_OVERFLOW_ERROR) { | 858 if (status == U_BUFFER_OVERFLOW_ERROR) { |
839 for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { | 859 for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { |
840 uprv_free(pkgDataFlags[i]); | 860 if (pkgDataFlags[i]) { |
| 861 uprv_free(pkgDataFlags[i]); |
| 862 pkgDataFlags[i] = NULL; |
| 863 } |
841 } | 864 } |
842 currentBufferSize = tmpResult; | 865 currentBufferSize = tmpResult; |
843 } else if (U_FAILURE(status)) { | 866 } else if (U_FAILURE(status)) { |
844 fprintf(stderr,"Unable to open or read \"%s\" option file. status =
%s\n", o->options, u_errorName(status)); | 867 fprintf(stderr,"Unable to open or read \"%s\" option file. status =
%s\n", o->options, u_errorName(status)); |
845 return -1; | 868 return -1; |
846 } | 869 } |
847 #endif | 870 #endif |
848 if(o->verbose) { | 871 if(o->verbose) { |
849 fprintf(stdout, "# pkgDataFlags=\n"); | 872 fprintf(stdout, "# pkgDataFlags=\n"); |
850 for(int32_t i=0;i<PKGDATA_FLAGS_SIZE;i++) { | 873 for(int32_t i=0;i<PKGDATA_FLAGS_SIZE;i++) { |
(...skipping 30 matching lines...) Expand all Loading... |
881 sprintf(libFileNames[LIB_FILE], "%s%s", | 904 sprintf(libFileNames[LIB_FILE], "%s%s", |
882 pkgDataFlags[LIBPREFIX], | 905 pkgDataFlags[LIBPREFIX], |
883 libName); | 906 libName); |
884 #endif | 907 #endif |
885 | 908 |
886 if(o->verbose) { | 909 if(o->verbose) { |
887 fprintf(stdout, "# libFileName[LIB_FILE] = %s\n", libFileNames[LIB_FIL
E]); | 910 fprintf(stdout, "# libFileName[LIB_FILE] = %s\n", libFileNames[LIB_FIL
E]); |
888 } | 911 } |
889 | 912 |
890 #if U_PLATFORM == U_PF_MINGW | 913 #if U_PLATFORM == U_PF_MINGW |
891 sprintf(libFileNames[LIB_FILE_MINGW], "%s%s.lib", pkgDataFlags[LIBPREFIX
], libName); | 914 // Name the import library lib*.dll.a |
| 915 sprintf(libFileNames[LIB_FILE_MINGW], "lib%s.dll.a", libName); |
892 #elif U_PLATFORM == U_PF_CYGWIN | 916 #elif U_PLATFORM == U_PF_CYGWIN |
893 sprintf(libFileNames[LIB_FILE_CYGWIN], "cyg%s%s%s", | 917 sprintf(libFileNames[LIB_FILE_CYGWIN], "cyg%s%s%s", |
894 libName, | 918 libName, |
895 FILE_EXTENSION_SEP, | 919 FILE_EXTENSION_SEP, |
896 pkgDataFlags[SO_EXT]); | 920 pkgDataFlags[SO_EXT]); |
897 sprintf(libFileNames[LIB_FILE_CYGWIN_VERSION], "cyg%s%s%s%s", | 921 sprintf(libFileNames[LIB_FILE_CYGWIN_VERSION], "cyg%s%s%s%s", |
898 libName, | 922 libName, |
899 version_major, | 923 version_major, |
900 FILE_EXTENSION_SEP, | 924 FILE_EXTENSION_SEP, |
901 pkgDataFlags[SO_EXT]); | 925 pkgDataFlags[SO_EXT]); |
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2071 linePtr = lineNext; | 2095 linePtr = lineNext; |
2072 } /* for each entry on line */ | 2096 } /* for each entry on line */ |
2073 } /* for each line */ | 2097 } /* for each line */ |
2074 T_FileStream_close(in); | 2098 T_FileStream_close(in); |
2075 } /* for each file list file */ | 2099 } /* for each file list file */ |
2076 } | 2100 } |
2077 | 2101 |
2078 /* Try calling icu-config directly to get the option file. */ | 2102 /* Try calling icu-config directly to get the option file. */ |
2079 static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option) { | 2103 static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option) { |
2080 #if U_HAVE_POPEN | 2104 #if U_HAVE_POPEN |
2081 FILE *p = NULL; | 2105 LocalPipeFilePointer p; |
2082 size_t n; | 2106 size_t n; |
2083 static char buf[512] = ""; | 2107 static char buf[512] = ""; |
2084 icu::CharString cmdBuf; | 2108 icu::CharString cmdBuf; |
2085 UErrorCode status = U_ZERO_ERROR; | 2109 UErrorCode status = U_ZERO_ERROR; |
2086 const char cmd[] = "icu-config --incpkgdatafile"; | 2110 const char cmd[] = "icu-config --incpkgdatafile"; |
2087 char dirBuf[1024] = ""; | 2111 char dirBuf[1024] = ""; |
2088 /* #1 try the same path where pkgdata was called from. */ | 2112 /* #1 try the same path where pkgdata was called from. */ |
2089 findDirname(progname, dirBuf, UPRV_LENGTHOF(dirBuf), &status); | 2113 findDirname(progname, dirBuf, UPRV_LENGTHOF(dirBuf), &status); |
2090 if(U_SUCCESS(status)) { | 2114 if(U_SUCCESS(status)) { |
2091 cmdBuf.append(dirBuf, status); | 2115 cmdBuf.append(dirBuf, status); |
2092 if (cmdBuf[0] != 0) { | 2116 if (cmdBuf[0] != 0) { |
2093 cmdBuf.append( U_FILE_SEP_STRING, status ); | 2117 cmdBuf.append( U_FILE_SEP_STRING, status ); |
2094 } | 2118 } |
2095 cmdBuf.append( cmd, status ); | 2119 cmdBuf.append( cmd, status ); |
2096 | 2120 |
2097 if(verbose) { | 2121 if(verbose) { |
2098 fprintf(stdout, "# Calling icu-config: %s\n", cmdBuf.data()); | 2122 fprintf(stdout, "# Calling icu-config: %s\n", cmdBuf.data()); |
2099 } | 2123 } |
2100 p = popen(cmdBuf.data(), "r"); | 2124 p.adoptInstead(popen(cmdBuf.data(), "r")); |
2101 } | 2125 } |
2102 | 2126 |
2103 if(p == NULL || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p)) <= 0) { | 2127 if(p.isNull() || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p.getAlias())) <=
0) { |
2104 if(verbose) { | 2128 if(verbose) { |
2105 fprintf(stdout, "# Calling icu-config: %s\n", cmd); | 2129 fprintf(stdout, "# Calling icu-config: %s\n", cmd); |
2106 } | 2130 } |
2107 pclose(p); | |
2108 | 2131 |
2109 p = popen(cmd, "r"); | 2132 p.adoptInstead(popen(cmd, "r")); |
2110 if(p == NULL || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p)) <= 0) { | 2133 if(p.isNull() || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p.getAlias()))
<= 0) { |
2111 fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use
-O option)\n", progname); | 2134 fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or u
se -O option)\n", progname); |
2112 return -1; | 2135 return -1; |
2113 } | 2136 } |
2114 } | 2137 } |
2115 | 2138 |
2116 pclose(p); | |
2117 | |
2118 for (int32_t length = strlen(buf) - 1; length >= 0; length--) { | 2139 for (int32_t length = strlen(buf) - 1; length >= 0; length--) { |
2119 if (buf[length] == '\n' || buf[length] == ' ') { | 2140 if (buf[length] == '\n' || buf[length] == ' ') { |
2120 buf[length] = 0; | 2141 buf[length] = 0; |
2121 } else { | 2142 } else { |
2122 break; | 2143 break; |
2123 } | 2144 } |
2124 } | 2145 } |
2125 | 2146 |
2126 if(buf[strlen(buf)-1]=='\n') | 2147 if(buf[strlen(buf)-1]=='\n') |
2127 { | 2148 { |
(...skipping 11 matching lines...) Expand all Loading... |
2139 } | 2160 } |
2140 | 2161 |
2141 option->value = buf; | 2162 option->value = buf; |
2142 option->doesOccur = TRUE; | 2163 option->doesOccur = TRUE; |
2143 | 2164 |
2144 return 0; | 2165 return 0; |
2145 #else | 2166 #else |
2146 return -1; | 2167 return -1; |
2147 #endif | 2168 #endif |
2148 } | 2169 } |
| 2170 |
| 2171 #ifdef CAN_WRITE_OBJ_CODE |
| 2172 /* Create optMatchArch for genccode architecture detection */ |
| 2173 static void pkg_createOptMatchArch(char *optMatchArch) { |
| 2174 #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) |
| 2175 const char* code = "void oma(){}"; |
| 2176 const char* source = "oma.c"; |
| 2177 const char* obj = "oma.obj"; |
| 2178 FileStream* stream = NULL; |
| 2179 |
| 2180 stream = T_FileStream_open(source,"w"); |
| 2181 if (stream != NULL) { |
| 2182 T_FileStream_writeLine(stream, code); |
| 2183 T_FileStream_close(stream); |
| 2184 |
| 2185 char cmd[LARGE_BUFFER_MAX_SIZE]; |
| 2186 sprintf(cmd, "%s %s -o %s", |
| 2187 pkgDataFlags[COMPILER], |
| 2188 source, |
| 2189 obj); |
| 2190 |
| 2191 if (runCommand(cmd) == 0){ |
| 2192 sprintf(optMatchArch, "%s", obj); |
| 2193 } |
| 2194 else { |
| 2195 fprintf(stderr, "Failed to compile %s\n", source); |
| 2196 } |
| 2197 if(!T_FileStream_remove(source)){ |
| 2198 fprintf(stderr, "T_FileStream_remove failed to delete %s\n", source)
; |
| 2199 } |
| 2200 } |
| 2201 else { |
| 2202 fprintf(stderr, "T_FileStream_open failed to open %s for writing\n", sou
rce); |
| 2203 } |
| 2204 #endif |
| 2205 } |
| 2206 static void pkg_destroyOptMatchArch(char *optMatchArch) { |
| 2207 if(T_FileStream_file_exists(optMatchArch) && !T_FileStream_remove(optMatchAr
ch)){ |
| 2208 fprintf(stderr, "T_FileStream_remove failed to delete %s\n", optMatchArc
h); |
| 2209 } |
| 2210 } |
| 2211 #endif |
OLD | NEW |