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