1/*
2*******************************************************************************
3*
4*   Copyright (C) 2005-2008, 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
27U_CAPI FILE * U_EXPORT2
28usrc_create(const char *path, const char *filename) {
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(
59            f,
60            "/*\n"
61            " * Copyright (C) 1999-%s, International Business Machines\n"
62            " * Corporation and others.  All Rights Reserved.\n"
63            " *\n"
64            " * file name: %s\n"
65            " *\n"
66            " * machine-generated on: %s\n"
67            " */\n\n",
68            year,
69            filename,
70            buffer);
71    } else {
72        fprintf(
73            stderr,
74            "usrc_create(%s, %s): unable to create file\n",
75            path!=NULL ? path : "", filename);
76    }
77    return f;
78}
79
80U_CAPI void U_EXPORT2
81usrc_writeArray(FILE *f,
82                const char *prefix,
83                const void *p, int32_t width, int32_t length,
84                const char *postfix) {
85    const uint8_t *p8;
86    const uint16_t *p16;
87    const uint32_t *p32;
88    uint32_t value;
89    int32_t i, col;
90
91    p8=NULL;
92    p16=NULL;
93    p32=NULL;
94    switch(width) {
95    case 8:
96        p8=(const uint8_t *)p;
97        break;
98    case 16:
99        p16=(const uint16_t *)p;
100        break;
101    case 32:
102        p32=(const uint32_t *)p;
103        break;
104    default:
105        fprintf(stderr, "usrc_writeArray(width=%ld) unrecognized width\n", (long)width);
106        return;
107    }
108    if(prefix!=NULL) {
109        fprintf(f, prefix, (long)length);
110    }
111    for(i=col=0; i<length; ++i, ++col) {
112        if(i>0) {
113            if(col<16) {
114                fputc(',', f);
115            } else {
116                fputs(",\n", f);
117                col=0;
118            }
119        }
120        switch(width) {
121        case 8:
122            value=p8[i];
123            break;
124        case 16:
125            value=p16[i];
126            break;
127        case 32:
128            value=p32[i];
129            break;
130        default:
131            value=0; /* unreachable */
132            break;
133        }
134        fprintf(f, value<=9 ? "%lu" : "0x%lx", (unsigned long)value);
135    }
136    if(postfix!=NULL) {
137        fputs(postfix, f);
138    }
139}
140
141U_CAPI void U_EXPORT2
142usrc_writeUTrie2Arrays(FILE *f,
143                       const char *indexPrefix, const char *data32Prefix,
144                       const UTrie2 *pTrie,
145                       const char *postfix) {
146    if(pTrie->data32==NULL) {
147        /* 16-bit trie */
148        usrc_writeArray(f, indexPrefix, pTrie->index, 16, pTrie->indexLength+pTrie->dataLength, postfix);
149    } else {
150        /* 32-bit trie */
151        usrc_writeArray(f, indexPrefix, pTrie->index, 16, pTrie->indexLength, postfix);
152        usrc_writeArray(f, data32Prefix, pTrie->data32, 32, pTrie->dataLength, postfix);
153    }
154}
155
156U_CAPI void U_EXPORT2
157usrc_writeUTrie2Struct(FILE *f,
158                       const char *prefix,
159                       const UTrie2 *pTrie,
160                       const char *indexName, const char *data32Name,
161                       const char *postfix) {
162    if(prefix!=NULL) {
163        fputs(prefix, f);
164    }
165    if(pTrie->data32==NULL) {
166        /* 16-bit trie */
167        fprintf(
168            f,
169            "    %s,\n"         /* index */
170            "    %s+%ld,\n"     /* data16 */
171            "    NULL,\n",      /* data32 */
172            indexName,
173            indexName,
174            (long)pTrie->indexLength);
175    } else {
176        /* 32-bit trie */
177        fprintf(
178            f,
179            "    %s,\n"         /* index */
180            "    NULL,\n"       /* data16 */
181            "    %s,\n",        /* data32 */
182            indexName,
183            data32Name);
184    }
185    fprintf(
186        f,
187        "    %ld,\n"            /* indexLength */
188        "    %ld,\n"            /* dataLength */
189        "    0x%hx,\n"          /* index2NullOffset */
190        "    0x%hx,\n"          /* dataNullOffset */
191        "    0x%lx,\n"          /* initialValue */
192        "    0x%lx,\n"          /* errorValue */
193        "    0x%lx,\n"          /* highStart */
194        "    0x%lx,\n"          /* highValueIndex */
195        "    NULL, 0, FALSE, FALSE, 0, NULL\n",
196        (long)pTrie->indexLength, (long)pTrie->dataLength,
197        (short)pTrie->index2NullOffset, (short)pTrie->dataNullOffset,
198        (long)pTrie->initialValue, (long)pTrie->errorValue,
199        (long)pTrie->highStart, (long)pTrie->highValueIndex);
200    if(postfix!=NULL) {
201        fputs(postfix, f);
202    }
203}
204