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