1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 2005-2012, International Business Machines
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"
23 #include "utrie2.h"
24 #include "cstring.h"
25 #include "writesrc.h"
26
27 static FILE *
usrc_createWithHeader(const char * path,const char * filename,const char * generator,const char * header)28 usrc_createWithHeader(const char *path, const char *filename,
29 const char *generator, const char *header) {
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);
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 }
64 } else {
65 fprintf(
66 stderr,
67 "usrc_create(%s, %s): unable to create file\n",
68 path!=NULL ? path : "", filename);
69 }
70 return f;
71 }
72
73 U_CAPI FILE * U_EXPORT2
usrc_create(const char * path,const char * filename,const char * generator)74 usrc_create(const char *path, const char *filename, const char *generator) {
75 static const char *header=
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"
82 " * machine-generated by: %s\n"
83 " */\n\n";
84 return usrc_createWithHeader(path, filename, generator, header);
85 }
86
87 U_CAPI FILE * U_EXPORT2
usrc_createTextData(const char * path,const char * filename,const char * generator)88 usrc_createTextData(const char *path, const char *filename, const char *generator) {
89 static const char *header=
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"
95 "# machine-generated by: %s\n"
96 "#\n\n";
97 return usrc_createWithHeader(path, filename, generator, header);
98 }
99
100 U_CAPI void U_EXPORT2
usrc_writeArray(FILE * f,const char * prefix,const void * p,int32_t width,int32_t length,const char * postfix)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
usrc_writeUTrie2Arrays(FILE * f,const char * indexPrefix,const char * data32Prefix,const UTrie2 * pTrie,const char * postfix)162 usrc_writeUTrie2Arrays(FILE *f,
163 const char *indexPrefix, const char *data32Prefix,
164 const UTrie2 *pTrie,
165 const char *postfix) {
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);
172 usrc_writeArray(f, data32Prefix, pTrie->data32, 32, pTrie->dataLength, postfix);
173 }
174 }
175
176 U_CAPI void U_EXPORT2
usrc_writeUTrie2Struct(FILE * f,const char * prefix,const UTrie2 * pTrie,const char * indexName,const char * data32Name,const char * postfix)177 usrc_writeUTrie2Struct(FILE *f,
178 const char *prefix,
179 const UTrie2 *pTrie,
180 const char *indexName, const char *data32Name,
181 const char *postfix) {
182 if(prefix!=NULL) {
183 fputs(prefix, f);
184 }
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);
204 }
205 fprintf(
206 f,
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",
216 (long)pTrie->indexLength, (long)pTrie->dataLength,
217 (short)pTrie->index2NullOffset, (short)pTrie->dataNullOffset,
218 (long)pTrie->initialValue, (long)pTrie->errorValue,
219 (long)pTrie->highStart, (long)pTrie->highValueIndex);
220 if(postfix!=NULL) {
221 fputs(postfix, f);
222 }
223 }
224
225 U_CAPI void U_EXPORT2
usrc_writeArrayOfMostlyInvChars(FILE * f,const char * prefix,const char * p,int32_t length,const char * postfix)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 }
263