michael@0: /* michael@0: ******************************************************************************* michael@0: * michael@0: * Copyright (C) 2005-2012, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: * michael@0: ******************************************************************************* michael@0: * file name: writesrc.c michael@0: * encoding: US-ASCII michael@0: * tab size: 8 (not used) michael@0: * indentation:4 michael@0: * michael@0: * created on: 2005apr23 michael@0: * created by: Markus W. Scherer michael@0: * michael@0: * Helper functions for writing source code for data. michael@0: */ michael@0: michael@0: #include michael@0: #include michael@0: #include "unicode/utypes.h" michael@0: #include "unicode/putil.h" michael@0: #include "utrie2.h" michael@0: #include "cstring.h" michael@0: #include "writesrc.h" michael@0: michael@0: static FILE * michael@0: usrc_createWithHeader(const char *path, const char *filename, michael@0: const char *generator, const char *header) { michael@0: char buffer[1024]; michael@0: const char *p; michael@0: char *q; michael@0: FILE *f; michael@0: char c; michael@0: michael@0: if(path==NULL) { michael@0: p=filename; michael@0: } else { michael@0: /* concatenate path and filename, with U_FILE_SEP_CHAR in between if necessary */ michael@0: uprv_strcpy(buffer, path); michael@0: q=buffer+uprv_strlen(buffer); michael@0: if(q>buffer && (c=*(q-1))!=U_FILE_SEP_CHAR && c!=U_FILE_ALT_SEP_CHAR) { michael@0: *q++=U_FILE_SEP_CHAR; michael@0: } michael@0: uprv_strcpy(q, filename); michael@0: p=buffer; michael@0: } michael@0: michael@0: f=fopen(p, "w"); michael@0: if(f!=NULL) { michael@0: char year[8]; michael@0: const struct tm *lt; michael@0: time_t t; michael@0: michael@0: time(&t); michael@0: lt=localtime(&t); michael@0: strftime(year, sizeof(year), "%Y", lt); michael@0: if(generator==NULL) { michael@0: strftime(buffer, sizeof(buffer), "%Y-%m-%d", lt); michael@0: fprintf(f, header, year, filename, buffer); michael@0: } else { michael@0: fprintf(f, header, year, filename, generator); michael@0: } michael@0: } else { michael@0: fprintf( michael@0: stderr, michael@0: "usrc_create(%s, %s): unable to create file\n", michael@0: path!=NULL ? path : "", filename); michael@0: } michael@0: return f; michael@0: } michael@0: michael@0: U_CAPI FILE * U_EXPORT2 michael@0: usrc_create(const char *path, const char *filename, const char *generator) { michael@0: static const char *header= michael@0: "/*\n" michael@0: " * Copyright (C) 1999-%s, International Business Machines\n" michael@0: " * Corporation and others. All Rights Reserved.\n" michael@0: " *\n" michael@0: " * file name: %s\n" michael@0: " *\n" michael@0: " * machine-generated by: %s\n" michael@0: " */\n\n"; michael@0: return usrc_createWithHeader(path, filename, generator, header); michael@0: } michael@0: michael@0: U_CAPI FILE * U_EXPORT2 michael@0: usrc_createTextData(const char *path, const char *filename, const char *generator) { michael@0: static const char *header= michael@0: "# Copyright (C) 1999-%s, International Business Machines\n" michael@0: "# Corporation and others. All Rights Reserved.\n" michael@0: "#\n" michael@0: "# file name: %s\n" michael@0: "#\n" michael@0: "# machine-generated by: %s\n" michael@0: "#\n\n"; michael@0: return usrc_createWithHeader(path, filename, generator, header); michael@0: } michael@0: michael@0: U_CAPI void U_EXPORT2 michael@0: usrc_writeArray(FILE *f, michael@0: const char *prefix, michael@0: const void *p, int32_t width, int32_t length, michael@0: const char *postfix) { michael@0: const uint8_t *p8; michael@0: const uint16_t *p16; michael@0: const uint32_t *p32; michael@0: uint32_t value; michael@0: int32_t i, col; michael@0: michael@0: p8=NULL; michael@0: p16=NULL; michael@0: p32=NULL; michael@0: switch(width) { michael@0: case 8: michael@0: p8=(const uint8_t *)p; michael@0: break; michael@0: case 16: michael@0: p16=(const uint16_t *)p; michael@0: break; michael@0: case 32: michael@0: p32=(const uint32_t *)p; michael@0: break; michael@0: default: michael@0: fprintf(stderr, "usrc_writeArray(width=%ld) unrecognized width\n", (long)width); michael@0: return; michael@0: } michael@0: if(prefix!=NULL) { michael@0: fprintf(f, prefix, (long)length); michael@0: } michael@0: for(i=col=0; i0) { michael@0: if(col<16) { michael@0: fputc(',', f); michael@0: } else { michael@0: fputs(",\n", f); michael@0: col=0; michael@0: } michael@0: } michael@0: switch(width) { michael@0: case 8: michael@0: value=p8[i]; michael@0: break; michael@0: case 16: michael@0: value=p16[i]; michael@0: break; michael@0: case 32: michael@0: value=p32[i]; michael@0: break; michael@0: default: michael@0: value=0; /* unreachable */ michael@0: break; michael@0: } michael@0: fprintf(f, value<=9 ? "%lu" : "0x%lx", (unsigned long)value); michael@0: } michael@0: if(postfix!=NULL) { michael@0: fputs(postfix, f); michael@0: } michael@0: } michael@0: michael@0: U_CAPI void U_EXPORT2 michael@0: usrc_writeUTrie2Arrays(FILE *f, michael@0: const char *indexPrefix, const char *data32Prefix, michael@0: const UTrie2 *pTrie, michael@0: const char *postfix) { michael@0: if(pTrie->data32==NULL) { michael@0: /* 16-bit trie */ michael@0: usrc_writeArray(f, indexPrefix, pTrie->index, 16, pTrie->indexLength+pTrie->dataLength, postfix); michael@0: } else { michael@0: /* 32-bit trie */ michael@0: usrc_writeArray(f, indexPrefix, pTrie->index, 16, pTrie->indexLength, postfix); michael@0: usrc_writeArray(f, data32Prefix, pTrie->data32, 32, pTrie->dataLength, postfix); michael@0: } michael@0: } michael@0: michael@0: U_CAPI void U_EXPORT2 michael@0: usrc_writeUTrie2Struct(FILE *f, michael@0: const char *prefix, michael@0: const UTrie2 *pTrie, michael@0: const char *indexName, const char *data32Name, michael@0: const char *postfix) { michael@0: if(prefix!=NULL) { michael@0: fputs(prefix, f); michael@0: } michael@0: if(pTrie->data32==NULL) { michael@0: /* 16-bit trie */ michael@0: fprintf( michael@0: f, michael@0: " %s,\n" /* index */ michael@0: " %s+%ld,\n" /* data16 */ michael@0: " NULL,\n", /* data32 */ michael@0: indexName, michael@0: indexName, michael@0: (long)pTrie->indexLength); michael@0: } else { michael@0: /* 32-bit trie */ michael@0: fprintf( michael@0: f, michael@0: " %s,\n" /* index */ michael@0: " NULL,\n" /* data16 */ michael@0: " %s,\n", /* data32 */ michael@0: indexName, michael@0: data32Name); michael@0: } michael@0: fprintf( michael@0: f, michael@0: " %ld,\n" /* indexLength */ michael@0: " %ld,\n" /* dataLength */ michael@0: " 0x%hx,\n" /* index2NullOffset */ michael@0: " 0x%hx,\n" /* dataNullOffset */ michael@0: " 0x%lx,\n" /* initialValue */ michael@0: " 0x%lx,\n" /* errorValue */ michael@0: " 0x%lx,\n" /* highStart */ michael@0: " 0x%lx,\n" /* highValueIndex */ michael@0: " NULL, 0, FALSE, FALSE, 0, NULL\n", michael@0: (long)pTrie->indexLength, (long)pTrie->dataLength, michael@0: (short)pTrie->index2NullOffset, (short)pTrie->dataNullOffset, michael@0: (long)pTrie->initialValue, (long)pTrie->errorValue, michael@0: (long)pTrie->highStart, (long)pTrie->highValueIndex); michael@0: if(postfix!=NULL) { michael@0: fputs(postfix, f); michael@0: } michael@0: } michael@0: michael@0: U_CAPI void U_EXPORT2 michael@0: usrc_writeArrayOfMostlyInvChars(FILE *f, michael@0: const char *prefix, michael@0: const char *p, int32_t length, michael@0: const char *postfix) { michael@0: int32_t i, col; michael@0: int prev2, prev, c; michael@0: michael@0: if(prefix!=NULL) { michael@0: fprintf(f, prefix, (long)length); michael@0: } michael@0: prev2=prev=-1; michael@0: for(i=col=0; i0) { michael@0: /* Break long lines. Try to break at interesting places, to minimize revision diffs. */ michael@0: if( michael@0: /* Very long line. */ michael@0: col>=32 || michael@0: /* Long line, break after terminating NUL. */ michael@0: (col>=24 && prev2>=0x20 && prev==0) || michael@0: /* Medium-long line, break before non-NUL, non-character byte. */ michael@0: (col>=16 && (prev==0 || prev>=0x20) && 0