Home | History | Annotate | Download | only in toolutil
      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 *
     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
     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
     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
    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
    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
    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
    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