]>
Commit | Line | Data |
---|---|---|
73c04bcf A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
4388f060 | 4 | * Copyright (C) 2005-2012, International Business Machines |
73c04bcf A |
5 | * Corporation and others. All Rights Reserved. |
6 | * | |
7 | ******************************************************************************* | |
8 | * file name: writesrc.c | |
9 | * encoding: US-ASCII | |
10 | * tab size: 8 (not used) | |
11 | * indentation:4 | |
12 | * | |
13 | * created on: 2005apr23 | |
14 | * created by: Markus W. Scherer | |
15 | * | |
16 | * Helper functions for writing source code for data. | |
17 | */ | |
18 | ||
19 | #include <stdio.h> | |
20 | #include <time.h> | |
21 | #include "unicode/utypes.h" | |
22 | #include "unicode/putil.h" | |
729e4ab9 | 23 | #include "utrie2.h" |
73c04bcf A |
24 | #include "cstring.h" |
25 | #include "writesrc.h" | |
26 | ||
729e4ab9 | 27 | static FILE * |
4388f060 A |
28 | usrc_createWithHeader(const char *path, const char *filename, |
29 | const char *generator, const char *header) { | |
73c04bcf A |
30 | char buffer[1024]; |
31 | const char *p; | |
32 | char *q; | |
33 | FILE *f; | |
34 | char c; | |
35 | ||
36 | if(path==NULL) { | |
37 | p=filename; | |
38 | } else { | |
39 | /* concatenate path and filename, with U_FILE_SEP_CHAR in between if necessary */ | |
40 | uprv_strcpy(buffer, path); | |
41 | q=buffer+uprv_strlen(buffer); | |
42 | if(q>buffer && (c=*(q-1))!=U_FILE_SEP_CHAR && c!=U_FILE_ALT_SEP_CHAR) { | |
43 | *q++=U_FILE_SEP_CHAR; | |
44 | } | |
45 | uprv_strcpy(q, filename); | |
46 | p=buffer; | |
47 | } | |
48 | ||
49 | f=fopen(p, "w"); | |
50 | if(f!=NULL) { | |
51 | char year[8]; | |
52 | const struct tm *lt; | |
53 | time_t t; | |
54 | ||
55 | time(&t); | |
56 | lt=localtime(&t); | |
57 | strftime(year, sizeof(year), "%Y", lt); | |
4388f060 A |
58 | if(generator==NULL) { |
59 | strftime(buffer, sizeof(buffer), "%Y-%m-%d", lt); | |
60 | fprintf(f, header, year, filename, buffer); | |
61 | } else { | |
62 | fprintf(f, header, year, filename, generator); | |
63 | } | |
73c04bcf A |
64 | } else { |
65 | fprintf( | |
66 | stderr, | |
67 | "usrc_create(%s, %s): unable to create file\n", | |
46f4442e | 68 | path!=NULL ? path : "", filename); |
73c04bcf A |
69 | } |
70 | return f; | |
71 | } | |
72 | ||
729e4ab9 | 73 | U_CAPI FILE * U_EXPORT2 |
4388f060 A |
74 | usrc_create(const char *path, const char *filename, const char *generator) { |
75 | static const char *header= | |
729e4ab9 A |
76 | "/*\n" |
77 | " * Copyright (C) 1999-%s, International Business Machines\n" | |
78 | " * Corporation and others. All Rights Reserved.\n" | |
79 | " *\n" | |
80 | " * file name: %s\n" | |
81 | " *\n" | |
4388f060 | 82 | " * machine-generated by: %s\n" |
729e4ab9 | 83 | " */\n\n"; |
4388f060 | 84 | return usrc_createWithHeader(path, filename, generator, header); |
729e4ab9 A |
85 | } |
86 | ||
87 | U_CAPI FILE * U_EXPORT2 | |
4388f060 A |
88 | usrc_createTextData(const char *path, const char *filename, const char *generator) { |
89 | static const char *header= | |
729e4ab9 A |
90 | "# Copyright (C) 1999-%s, International Business Machines\n" |
91 | "# Corporation and others. All Rights Reserved.\n" | |
92 | "#\n" | |
93 | "# file name: %s\n" | |
94 | "#\n" | |
4388f060 | 95 | "# machine-generated by: %s\n" |
729e4ab9 | 96 | "#\n\n"; |
4388f060 | 97 | return usrc_createWithHeader(path, filename, generator, header); |
729e4ab9 A |
98 | } |
99 | ||
73c04bcf A |
100 | U_CAPI void U_EXPORT2 |
101 | usrc_writeArray(FILE *f, | |
102 | const char *prefix, | |
103 | const void *p, int32_t width, int32_t length, | |
104 | const char *postfix) { | |
105 | const uint8_t *p8; | |
106 | const uint16_t *p16; | |
107 | const uint32_t *p32; | |
108 | uint32_t value; | |
109 | int32_t i, col; | |
110 | ||
111 | p8=NULL; | |
112 | p16=NULL; | |
113 | p32=NULL; | |
114 | switch(width) { | |
115 | case 8: | |
116 | p8=(const uint8_t *)p; | |
117 | break; | |
118 | case 16: | |
119 | p16=(const uint16_t *)p; | |
120 | break; | |
121 | case 32: | |
122 | p32=(const uint32_t *)p; | |
123 | break; | |
124 | default: | |
125 | fprintf(stderr, "usrc_writeArray(width=%ld) unrecognized width\n", (long)width); | |
126 | return; | |
127 | } | |
128 | if(prefix!=NULL) { | |
129 | fprintf(f, prefix, (long)length); | |
130 | } | |
131 | for(i=col=0; i<length; ++i, ++col) { | |
132 | if(i>0) { | |
133 | if(col<16) { | |
134 | fputc(',', f); | |
135 | } else { | |
136 | fputs(",\n", f); | |
137 | col=0; | |
138 | } | |
139 | } | |
140 | switch(width) { | |
141 | case 8: | |
142 | value=p8[i]; | |
143 | break; | |
144 | case 16: | |
145 | value=p16[i]; | |
146 | break; | |
147 | case 32: | |
148 | value=p32[i]; | |
149 | break; | |
150 | default: | |
151 | value=0; /* unreachable */ | |
152 | break; | |
153 | } | |
154 | fprintf(f, value<=9 ? "%lu" : "0x%lx", (unsigned long)value); | |
155 | } | |
156 | if(postfix!=NULL) { | |
157 | fputs(postfix, f); | |
158 | } | |
159 | } | |
160 | ||
161 | U_CAPI void U_EXPORT2 | |
729e4ab9 A |
162 | usrc_writeUTrie2Arrays(FILE *f, |
163 | const char *indexPrefix, const char *data32Prefix, | |
164 | const UTrie2 *pTrie, | |
165 | const char *postfix) { | |
73c04bcf A |
166 | if(pTrie->data32==NULL) { |
167 | /* 16-bit trie */ | |
168 | usrc_writeArray(f, indexPrefix, pTrie->index, 16, pTrie->indexLength+pTrie->dataLength, postfix); | |
169 | } else { | |
170 | /* 32-bit trie */ | |
171 | usrc_writeArray(f, indexPrefix, pTrie->index, 16, pTrie->indexLength, postfix); | |
729e4ab9 | 172 | usrc_writeArray(f, data32Prefix, pTrie->data32, 32, pTrie->dataLength, postfix); |
73c04bcf A |
173 | } |
174 | } | |
175 | ||
176 | U_CAPI void U_EXPORT2 | |
729e4ab9 A |
177 | usrc_writeUTrie2Struct(FILE *f, |
178 | const char *prefix, | |
179 | const UTrie2 *pTrie, | |
180 | const char *indexName, const char *data32Name, | |
181 | const char *postfix) { | |
73c04bcf A |
182 | if(prefix!=NULL) { |
183 | fputs(prefix, f); | |
184 | } | |
729e4ab9 A |
185 | if(pTrie->data32==NULL) { |
186 | /* 16-bit trie */ | |
187 | fprintf( | |
188 | f, | |
189 | " %s,\n" /* index */ | |
190 | " %s+%ld,\n" /* data16 */ | |
191 | " NULL,\n", /* data32 */ | |
192 | indexName, | |
193 | indexName, | |
194 | (long)pTrie->indexLength); | |
195 | } else { | |
196 | /* 32-bit trie */ | |
197 | fprintf( | |
198 | f, | |
199 | " %s,\n" /* index */ | |
200 | " NULL,\n" /* data16 */ | |
201 | " %s,\n", /* data32 */ | |
202 | indexName, | |
203 | data32Name); | |
73c04bcf A |
204 | } |
205 | fprintf( | |
206 | f, | |
729e4ab9 A |
207 | " %ld,\n" /* indexLength */ |
208 | " %ld,\n" /* dataLength */ | |
209 | " 0x%hx,\n" /* index2NullOffset */ | |
210 | " 0x%hx,\n" /* dataNullOffset */ | |
211 | " 0x%lx,\n" /* initialValue */ | |
212 | " 0x%lx,\n" /* errorValue */ | |
213 | " 0x%lx,\n" /* highStart */ | |
214 | " 0x%lx,\n" /* highValueIndex */ | |
215 | " NULL, 0, FALSE, FALSE, 0, NULL\n", | |
73c04bcf | 216 | (long)pTrie->indexLength, (long)pTrie->dataLength, |
729e4ab9 A |
217 | (short)pTrie->index2NullOffset, (short)pTrie->dataNullOffset, |
218 | (long)pTrie->initialValue, (long)pTrie->errorValue, | |
219 | (long)pTrie->highStart, (long)pTrie->highValueIndex); | |
73c04bcf A |
220 | if(postfix!=NULL) { |
221 | fputs(postfix, f); | |
222 | } | |
223 | } | |
4388f060 A |
224 | |
225 | U_CAPI void U_EXPORT2 | |
226 | usrc_writeArrayOfMostlyInvChars(FILE *f, | |
227 | const char *prefix, | |
228 | const char *p, int32_t length, | |
229 | const char *postfix) { | |
230 | int32_t i, col; | |
231 | int prev2, prev, c; | |
232 | ||
233 | if(prefix!=NULL) { | |
234 | fprintf(f, prefix, (long)length); | |
235 | } | |
236 | prev2=prev=-1; | |
237 | for(i=col=0; i<length; ++i, ++col) { | |
238 | c=(uint8_t)p[i]; | |
239 | if(i>0) { | |
240 | /* Break long lines. Try to break at interesting places, to minimize revision diffs. */ | |
241 | if( | |
242 | /* Very long line. */ | |
243 | col>=32 || | |
244 | /* Long line, break after terminating NUL. */ | |
245 | (col>=24 && prev2>=0x20 && prev==0) || | |
246 | /* Medium-long line, break before non-NUL, non-character byte. */ | |
247 | (col>=16 && (prev==0 || prev>=0x20) && 0<c && c<0x20) | |
248 | ) { | |
249 | fputs(",\n", f); | |
250 | col=0; | |
251 | } else { | |
252 | fputc(',', f); | |
253 | } | |
254 | } | |
255 | fprintf(f, c<0x20 ? "%u" : "'%c'", c); | |
256 | prev2=prev; | |
257 | prev=c; | |
258 | } | |
259 | if(postfix!=NULL) { | |
260 | fputs(postfix, f); | |
261 | } | |
262 | } |