|
1 /****************************************************************************** |
|
2 * Copyright (C) 2008-2013, International Business Machines |
|
3 * Corporation and others. All Rights Reserved. |
|
4 ******************************************************************************* |
|
5 */ |
|
6 #include "unicode/utypes.h" |
|
7 #include "unicode/putil.h" |
|
8 #include "cstring.h" |
|
9 #include "toolutil.h" |
|
10 #include "uoptions.h" |
|
11 #include "uparse.h" |
|
12 #include "package.h" |
|
13 #include "pkg_icu.h" |
|
14 |
|
15 #include <stdio.h> |
|
16 #include <stdlib.h> |
|
17 #include <string.h> |
|
18 |
|
19 |
|
20 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) |
|
21 |
|
22 // read a file list -------------------------------------------------------- *** |
|
23 |
|
24 U_NAMESPACE_USE |
|
25 |
|
26 static const struct { |
|
27 const char *suffix; |
|
28 int32_t length; |
|
29 } listFileSuffixes[]={ |
|
30 { ".txt", 4 }, |
|
31 { ".lst", 4 }, |
|
32 { ".tmp", 4 } |
|
33 }; |
|
34 |
|
35 /* check for multiple text file suffixes to see if this list name is a text file name */ |
|
36 static UBool |
|
37 isListTextFile(const char *listname) { |
|
38 const char *listNameEnd=strchr(listname, 0); |
|
39 const char *suffix; |
|
40 int32_t i, length; |
|
41 for(i=0; i<LENGTHOF(listFileSuffixes); ++i) { |
|
42 suffix=listFileSuffixes[i].suffix; |
|
43 length=listFileSuffixes[i].length; |
|
44 if((listNameEnd-listname)>length && 0==memcmp(listNameEnd-length, suffix, length)) { |
|
45 return TRUE; |
|
46 } |
|
47 } |
|
48 return FALSE; |
|
49 } |
|
50 |
|
51 /* |
|
52 * Read a file list. |
|
53 * If the listname ends with ".txt", then read the list file |
|
54 * (in the system/ invariant charset). |
|
55 * If the listname ends with ".dat", then read the ICU .dat package file. |
|
56 * Otherwise, read the file itself as a single-item list. |
|
57 */ |
|
58 U_CAPI Package * U_EXPORT2 |
|
59 readList(const char *filesPath, const char *listname, UBool readContents, Package *listPkgIn) { |
|
60 Package *listPkg = listPkgIn; |
|
61 FILE *file; |
|
62 const char *listNameEnd; |
|
63 |
|
64 if(listname==NULL || listname[0]==0) { |
|
65 fprintf(stderr, "missing list file\n"); |
|
66 return NULL; |
|
67 } |
|
68 |
|
69 if (listPkg == NULL) { |
|
70 listPkg=new Package(); |
|
71 if(listPkg==NULL) { |
|
72 fprintf(stderr, "icupkg: not enough memory\n"); |
|
73 exit(U_MEMORY_ALLOCATION_ERROR); |
|
74 } |
|
75 } |
|
76 |
|
77 listNameEnd=strchr(listname, 0); |
|
78 if(isListTextFile(listname)) { |
|
79 // read the list file |
|
80 char line[1024]; |
|
81 char *end; |
|
82 const char *start; |
|
83 |
|
84 file=fopen(listname, "r"); |
|
85 if(file==NULL) { |
|
86 fprintf(stderr, "icupkg: unable to open list file \"%s\"\n", listname); |
|
87 delete listPkg; |
|
88 exit(U_FILE_ACCESS_ERROR); |
|
89 } |
|
90 |
|
91 while(fgets(line, sizeof(line), file)) { |
|
92 // remove comments |
|
93 end=strchr(line, '#'); |
|
94 if(end!=NULL) { |
|
95 *end=0; |
|
96 } else { |
|
97 // remove trailing CR LF |
|
98 end=strchr(line, 0); |
|
99 while(line<end && (*(end-1)=='\r' || *(end-1)=='\n')) { |
|
100 *--end=0; |
|
101 } |
|
102 } |
|
103 |
|
104 // check first non-whitespace character and |
|
105 // skip empty lines and |
|
106 // skip lines starting with reserved characters |
|
107 start=u_skipWhitespace(line); |
|
108 if(*start==0 || NULL!=strchr(U_PKG_RESERVED_CHARS, *start)) { |
|
109 continue; |
|
110 } |
|
111 |
|
112 // take whitespace-separated items from the line |
|
113 for(;;) { |
|
114 // find whitespace after the item or the end of the line |
|
115 for(end=(char *)start; *end!=0 && *end!=' ' && *end!='\t'; ++end) {} |
|
116 if(*end==0) { |
|
117 // this item is the last one on the line |
|
118 end=NULL; |
|
119 } else { |
|
120 // the item is terminated by whitespace, terminate it with NUL |
|
121 *end=0; |
|
122 } |
|
123 if(readContents) { |
|
124 listPkg->addFile(filesPath, start); |
|
125 } else { |
|
126 listPkg->addItem(start); |
|
127 } |
|
128 |
|
129 // find the start of the next item or exit the loop |
|
130 if(end==NULL || *(start=u_skipWhitespace(end+1))==0) { |
|
131 break; |
|
132 } |
|
133 } |
|
134 } |
|
135 fclose(file); |
|
136 } else if((listNameEnd-listname)>4 && 0==memcmp(listNameEnd-4, ".dat", 4)) { |
|
137 // read the ICU .dat package |
|
138 // Accept a .dat file whose name differs from the ToC prefixes. |
|
139 listPkg->setAutoPrefix(); |
|
140 listPkg->readPackage(listname); |
|
141 } else { |
|
142 // list the single file itself |
|
143 if(readContents) { |
|
144 listPkg->addFile(filesPath, listname); |
|
145 } else { |
|
146 listPkg->addItem(listname); |
|
147 } |
|
148 } |
|
149 |
|
150 return listPkg; |
|
151 } |
|
152 |
|
153 U_CAPI int U_EXPORT2 |
|
154 writePackageDatFile(const char *outFilename, const char *outComment, const char *sourcePath, const char *addList, Package *pkg, char outType) { |
|
155 Package *addListPkg = NULL; |
|
156 UBool pkgDelete = FALSE; |
|
157 |
|
158 if (pkg == NULL) { |
|
159 pkg = new Package; |
|
160 if(pkg == NULL) { |
|
161 fprintf(stderr, "icupkg: not enough memory\n"); |
|
162 return U_MEMORY_ALLOCATION_ERROR; |
|
163 } |
|
164 |
|
165 addListPkg = readList(sourcePath, addList, TRUE, NULL); |
|
166 if(addListPkg != NULL) { |
|
167 pkg->addItems(*addListPkg); |
|
168 } else { |
|
169 return U_ILLEGAL_ARGUMENT_ERROR; |
|
170 } |
|
171 |
|
172 pkgDelete = TRUE; |
|
173 } |
|
174 |
|
175 pkg->writePackage(outFilename, outType, outComment); |
|
176 |
|
177 if (pkgDelete) { |
|
178 delete pkg; |
|
179 delete addListPkg; |
|
180 } |
|
181 |
|
182 return 0; |
|
183 } |
|
184 |