Subversion Repositories SvarDOS

Rev

Rev 1114 | Rev 1248 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1114 Rev 1247
1
/*
1
/*
2
 * Copyright (C) 2021-2022 Mateusz Viste
2
 * Copyright (C) 2021-2023 Mateusz Viste
3
 *
3
 *
4
 * usage: tlumacz en fr pl etc
4
 * usage: tlumacz en fr pl etc
5
 *
5
 *
6
 * computes an out.lng file that contains all language ressources.
6
 * computes an out.lng file that contains all language ressources.
7
 *
7
 *
8
 * DAT format:
8
 * DAT format:
9
 *
9
 *
10
 * 4-bytes signature:
10
 * 4-bytes signature:
11
 * "SvL\x1b"
11
 * "SvL\x1b"
12
 *
12
 *
13
 * Then "LANG BLOCKS" follow. Each LANG BLOCK is prefixed with 4 bytes:
13
 * Then "LANG BLOCKS" follow. Each LANG BLOCK is prefixed with 4 bytes:
14
 * II LL    - II is the LANG identifier ("EN", "PL", etc) and LL is the size
14
 * II LL    - II is the LANG identifier ("EN", "PL", etc) and LL is the size
15
 *            of the block (65535 bytes max).
15
 *            of the block (65535 bytes max).
16
 *
16
 *
17
 * Inside a LANG BLOCK is a set of strings:
17
 * Inside a LANG BLOCK is a set of strings:
18
 *
18
 *
19
 * II LL S  where II is the string's 16-bit identifier, LL is its length
19
 * II LL S  where II is the string's 16-bit identifier, LL is its length
20
 *          (1-65535) and S is the actual string. All strings are ASCIIZ (ie.
20
 *          (1-65535) and S is the actual string. All strings are ASCIIZ (ie.
21
 *          they end with a NULL terminator).
21
 *          they end with a NULL terminator).
22
 *
22
 *
23
 * The list of strings ends with a single 0-long string.
23
 * The list of strings ends with a single 0-long string.
24
 */
24
 */
25
 
25
 
26
 
26
 
27
#include <stdio.h>
27
#include <stdio.h>
28
#include <stdlib.h>
28
#include <stdlib.h>
29
#include <string.h>
29
#include <string.h>
30
 
30
 
-
 
31
#include "version.h"
31
 
32
 
32
 
33
 
33
struct bitmap {
34
struct bitmap {
34
  unsigned char bits[8192];
35
  unsigned char bits[8192];
35
};
36
};
36
 
37
 
37
static void bitmap_set(struct bitmap *b, unsigned short id) {
38
static void bitmap_set(struct bitmap *b, unsigned short id) {
38
  b->bits[id >> 3] |= 1 << (id & 7);
39
  b->bits[id >> 3] |= 1 << (id & 7);
39
}
40
}
40
 
41
 
41
static int bitmap_get(const struct bitmap *b, unsigned short id) {
42
static int bitmap_get(const struct bitmap *b, unsigned short id) {
42
  return(b->bits[id >> 3] & (1 << (id & 7)));
43
  return(b->bits[id >> 3] & (1 << (id & 7)));
43
}
44
}
44
 
45
 
45
static void bitmap_init(struct bitmap *b) {
46
static void bitmap_init(struct bitmap *b) {
46
  bzero(b, sizeof(struct bitmap));
47
  bzero(b, sizeof(struct bitmap));
47
}
48
}
48
 
49
 
49
 
50
 
50
 
51
 
51
/* read a single line from fd and fills it into dst, returns line length
52
/* read a single line from fd and fills it into dst, returns line length
52
 * ending CR/LF is trimmed, as well as any trailing spaces */
53
 * ending CR/LF is trimmed, as well as any trailing spaces */
53
static unsigned short readl(char *dst, size_t dstsz, FILE *fd) {
54
static unsigned short readl(char *dst, size_t dstsz, FILE *fd) {
54
  unsigned short l, lastnonspace = 0;
55
  unsigned short l, lastnonspace = 0;
55
 
56
 
56
  if (fgets(dst, dstsz, fd) == NULL) return(0xffff); /* EOF */
57
  if (fgets(dst, dstsz, fd) == NULL) return(0xffff); /* EOF */
57
  /* trim at first CR or LF and return len */
58
  /* trim at first CR or LF and return len */
58
  for (l = 0; (dst[l] != 0) && (dst[l] != '\r') && (dst[l] != '\n'); l++) {
59
  for (l = 0; (dst[l] != 0) && (dst[l] != '\r') && (dst[l] != '\n'); l++) {
59
    if (dst[l] != ' ') lastnonspace = l;
60
    if (dst[l] != ' ') lastnonspace = l;
60
  }
61
  }
61
 
62
 
62
  if (lastnonspace < l) l = lastnonspace + 1; /* rtrim */
63
  if (lastnonspace < l) l = lastnonspace + 1; /* rtrim */
63
  dst[l] = 0;
64
  dst[l] = 0;
64
 
65
 
65
  return(l);
66
  return(l);
66
}
67
}
67
 
68
 
68
 
69
 
69
/* parse a line in format "[?]1.50:somestring". fills id and returns a pointer to
70
/* parse a line in format "[?]1.50:somestring". fills id and returns a pointer to
70
 * the actual string part on success, or NULL on error */
71
 * the actual string part on success, or NULL on error */
71
static const char *parseline(unsigned short *id, const char *s) {
72
static const char *parseline(unsigned short *id, const char *s) {
72
  int i;
73
  int i;
73
  int dotpos = 0, colpos = 0, gotdigits = 0;
74
  int dotpos = 0, colpos = 0, gotdigits = 0;
74
 
75
 
75
  /* strings prefixed by '?' are flagged as "dirty": ignore this flag here */
76
  /* strings prefixed by '?' are flagged as "dirty": ignore this flag here */
76
  if (*s == '?') s++;
77
  if (*s == '?') s++;
77
 
78
 
78
  /* I must have a . and a : in the first 9 bytes */
79
  /* I must have a . and a : in the first 9 bytes */
79
  for (i = 0;; i++) {
80
  for (i = 0;; i++) {
80
    if (s[i] == '.') {
81
    if (s[i] == '.') {
81
      if ((dotpos != 0) || (gotdigits == 0)) break;
82
      if ((dotpos != 0) || (gotdigits == 0)) break;
82
      dotpos = i;
83
      dotpos = i;
83
      gotdigits = 0;
84
      gotdigits = 0;
84
    } else if (s[i] == ':') {
85
    } else if (s[i] == ':') {
85
      if (gotdigits != 0) colpos = i;
86
      if (gotdigits != 0) colpos = i;
86
      break;
87
      break;
87
    } else if ((s[i] < '0') || (s[i] > '9')) {
88
    } else if ((s[i] < '0') || (s[i] > '9')) {
88
      break;
89
      break;
89
    }
90
    }
90
    gotdigits++;
91
    gotdigits++;
91
  }
92
  }
92
  /* did I collect everything? */
93
  /* did I collect everything? */
93
  if ((dotpos == 0) || (colpos == 0)) return(NULL);
94
  if ((dotpos == 0) || (colpos == 0)) return(NULL);
94
  if (s[colpos + 1] == 0) return(NULL);
95
  if (s[colpos + 1] == 0) return(NULL);
95
 
96
 
96
  *id = atoi(s);
97
  *id = atoi(s);
97
  *id <<= 8;
98
  *id <<= 8;
98
  *id |= atoi(s + dotpos + 1);
99
  *id |= atoi(s + dotpos + 1);
99
 
100
 
100
  /* printf("parseline(): %04X = '%s'\r\n", *id, s + colpos + 1); */
101
  /* printf("parseline(): %04X = '%s'\r\n", *id, s + colpos + 1); */
101
 
102
 
102
  return(s + colpos + 1);
103
  return(s + colpos + 1);
103
}
104
}
104
 
105
 
105
 
106
 
106
/* converts escape sequences like "\n" or "\t" into actual bytes, returns
107
/* converts escape sequences like "\n" or "\t" into actual bytes, returns
107
 * the new length of the string. */
108
 * the new length of the string. */
108
static unsigned short unesc_string(char *linebuff) {
109
static unsigned short unesc_string(char *linebuff) {
109
  unsigned short i;
110
  unsigned short i;
110
  for (i = 0; linebuff[i] != 0; i++) {
111
  for (i = 0; linebuff[i] != 0; i++) {
111
    if (linebuff[i] != '\\') continue;
112
    if (linebuff[i] != '\\') continue;
112
    strcpy(linebuff + i, linebuff + i + 1);
113
    strcpy(linebuff + i, linebuff + i + 1);
113
    if (linebuff[i] == 0) break;
114
    if (linebuff[i] == 0) break;
114
    switch (linebuff[i]) {
115
    switch (linebuff[i]) {
115
      case 'n':
116
      case 'n':
116
        linebuff[i] = '\n';
117
        linebuff[i] = '\n';
117
        break;
118
        break;
118
      case 'r':
119
      case 'r':
119
        linebuff[i] = '\r';
120
        linebuff[i] = '\r';
120
        break;
121
        break;
121
      case 't':
122
      case 't':
122
        linebuff[i] = '\t';
123
        linebuff[i] = '\t';
123
        break;
124
        break;
124
    }
125
    }
125
  }
126
  }
126
  return(i);
127
  return(i);
127
}
128
}
128
 
129
 
129
 
130
 
130
/* opens a CATS-style file and compiles it into a ressources lang block
131
/* opens a CATS-style file and compiles it into a ressources lang block
131
 * returns 0 on error, or the size of the generated data block otherwise */
132
 * returns 0 on error, or the size of the generated data block otherwise */
132
static unsigned short gen_langstrings(unsigned char *buff, const char *langid, struct bitmap *b, const struct bitmap *refb, const unsigned char *refblock) {
133
static unsigned short gen_langstrings(unsigned char *buff, const char *langid, struct bitmap *b, const struct bitmap *refb, const unsigned char *refblock) {
133
  unsigned short len = 0, linelen;
134
  unsigned short len = 0, linelen;
134
  FILE *fd;
135
  FILE *fd;
135
  char fname[] = "XX.TXT";
136
  char fname[] = "XX.TXT";
136
  static char linebuf[8192];
137
  static char linebuf[8192];
137
  const char *ptr;
138
  const char *ptr;
138
  unsigned short id, linecount;
139
  unsigned short id, linecount;
139
 
140
 
140
  bitmap_init(b);
141
  bitmap_init(b);
141
 
142
 
142
  memcpy(fname + strlen(fname) - 6, langid, 2);
143
  memcpy(fname + strlen(fname) - 6, langid, 2);
143
 
144
 
144
  fd = fopen(fname, "rb");
145
  fd = fopen(fname, "rb");
145
  if (fd == NULL) {
146
  if (fd == NULL) {
146
    printf("ERROR: FAILED TO OPEN '%s'\r\n", fname);
147
    printf("ERROR: FAILED TO OPEN '%s'\r\n", fname);
147
    return(0);
148
    return(0);
148
  }
149
  }
149
 
150
 
150
  for (linecount = 1;; linecount++) {
151
  for (linecount = 1;; linecount++) {
151
 
152
 
152
    linelen = readl(linebuf, sizeof(linebuf), fd);
153
    linelen = readl(linebuf, sizeof(linebuf), fd);
153
    if (linelen == 0xffff) break; /* EOF */
154
    if (linelen == 0xffff) break; /* EOF */
154
    if ((linelen == 0) || (linebuf[0] == '#')) continue;
155
    if ((linelen == 0) || (linebuf[0] == '#')) continue;
155
 
156
 
156
    /* convert escaped chars to actual bytes (\n -> newline, etc) */
157
    /* convert escaped chars to actual bytes (\n -> newline, etc) */
157
    linelen = unesc_string(linebuf);
158
    linelen = unesc_string(linebuf);
158
 
159
 
159
    /* read id and get ptr to actual string ("1.15:string") */
160
    /* read id and get ptr to actual string ("1.15:string") */
160
    ptr = parseline(&id, linebuf);
161
    ptr = parseline(&id, linebuf);
161
    if (ptr == NULL) {
162
    if (ptr == NULL) {
162
      printf("ERROR: line #%u of %s is malformed (linelen = %u):\r\n", linecount, fname, linelen);
163
      printf("ERROR: line #%u of %s is malformed (linelen = %u):\r\n", linecount, fname, linelen);
163
      puts(linebuf);
164
      puts(linebuf);
164
      len = 0;
165
      len = 0;
165
      break;
166
      break;
166
    }
167
    }
167
 
168
 
168
    /* warn about dirty lines */
169
    /* warn about dirty lines */
169
    if (linebuf[0] == '?') {
170
    if (linebuf[0] == '?') {
170
      printf("WARNING: %s[#%u] string id %u.%u is flagged as 'dirty'\r\n", fname, linecount, id >> 8, id & 0xff);
171
      printf("WARNING: %s[#%u] string id %u.%u is flagged as 'dirty'\r\n", fname, linecount, id >> 8, id & 0xff);
171
    }
172
    }
172
 
173
 
173
    /* write string into block (II LL S) */
174
    /* write string into block (II LL S) */
174
    memcpy(buff + len, &id, 2);
175
    memcpy(buff + len, &id, 2);
175
    len += 2;
176
    len += 2;
176
    {
177
    {
177
      unsigned short slen = strlen(ptr) + 1;
178
      unsigned short slen = strlen(ptr) + 1;
178
      memcpy(buff + len, &slen, 2);
179
      memcpy(buff + len, &slen, 2);
179
      len += 2;
180
      len += 2;
180
      memcpy(buff + len, ptr, slen);
181
      memcpy(buff + len, ptr, slen);
181
      len += slen;
182
      len += slen;
182
    }
183
    }
183
 
184
 
184
    /* if reference bitmap provided: check that the id is valid */
185
    /* if reference bitmap provided: check that the id is valid */
185
    if ((refb != NULL) && (bitmap_get(refb, id) == 0)) {
186
    if ((refb != NULL) && (bitmap_get(refb, id) == 0)) {
186
      printf("WARNING: %s[#%u] has an invalid id (%u.%u not present in ref lang)\r\n", fname, linecount, id >> 8, id & 0xff);
187
      printf("WARNING: %s[#%u] has an invalid id (%u.%u not present in ref lang)\r\n", fname, linecount, id >> 8, id & 0xff);
187
    }
188
    }
188
 
189
 
189
    /* make sure this id is not already present */
190
    /* make sure this id is not already present */
190
    if (bitmap_get(b, id) == 0) {
191
    if (bitmap_get(b, id) == 0) {
191
      /* set bit in bitmap to remember I have this string */
192
      /* set bit in bitmap to remember I have this string */
192
      bitmap_set(b, id);
193
      bitmap_set(b, id);
193
    } else {
194
    } else {
194
      printf("WARNING: %s[#%u] has a duplicated id (%u.%u)\r\n", fname, linecount, id >> 8, id & 0xff);
195
      printf("WARNING: %s[#%u] has a duplicated id (%u.%u)\r\n", fname, linecount, id >> 8, id & 0xff);
195
    }
196
    }
196
  }
197
  }
197
 
198
 
198
  fclose(fd);
199
  fclose(fd);
199
 
200
 
200
  /* if refblock provided, pull missing strings from it */
201
  /* if refblock provided, pull missing strings from it */
201
  if (refblock != NULL) {
202
  if (refblock != NULL) {
202
    for (;;) {
203
    for (;;) {
203
      unsigned short slen;
204
      unsigned short slen;
204
      id = ((unsigned short *)refblock)[0];
205
      id = ((unsigned short *)refblock)[0];
205
      slen = ((unsigned short *)refblock)[1];
206
      slen = ((unsigned short *)refblock)[1];
206
      if ((id == 0) && (slen == 0)) break;
207
      if ((id == 0) && (slen == 0)) break;
207
      if (bitmap_get(b, id) == 0) {
208
      if (bitmap_get(b, id) == 0) {
208
        printf("WARNING: %s is missing string %u.%u (pulled from ref lang)\r\n", fname, id >> 8, id & 0xff);
209
        printf("WARNING: %s is missing string %u.%u (pulled from ref lang)\r\n", fname, id >> 8, id & 0xff);
209
        /* copy missing string from refblock */
210
        /* copy missing string from refblock */
210
        memcpy(buff + len, refblock, slen + 4);
211
        memcpy(buff + len, refblock, slen + 4);
211
        len += slen + 4;
212
        len += slen + 4;
212
      }
213
      }
213
      refblock += slen + 4;
214
      refblock += slen + 4;
214
    }
215
    }
215
  }
216
  }
216
 
217
 
217
  /* write the block terminator (0-long string) */
218
  /* write the block terminator (0-long string) */
218
  buff[len++] = 0; /* id */
219
  buff[len++] = 0; /* id */
219
  buff[len++] = 0; /* id */
220
  buff[len++] = 0; /* id */
220
  buff[len++] = 0; /* len */
221
  buff[len++] = 0; /* len */
221
  buff[len++] = 0; /* len */
222
  buff[len++] = 0; /* len */
222
  buff[len++] = 0; /* empty string */
223
  buff[len++] = 0; /* empty string */
223
 
224
 
224
  return(len);
225
  return(len);
225
}
226
}
226
 
227
 
227
 
228
 
228
#define MEMBLOCKSZ 65000
229
#define MEMBLOCKSZ 65000
229
 
230
 
230
int main(int argc, char **argv) {
231
int main(int argc, char **argv) {
231
  FILE *fd;
232
  FILE *fd;
232
  int ecode = 0;
233
  int ecode = 0;
233
  char *buff, *refblock;
234
  char *buff, *refblock;
234
  unsigned short refblocksz = 0;
235
  unsigned short refblocksz = 0;
235
  static struct bitmap bufbitmap;
236
  static struct bitmap bufbitmap;
236
  static struct bitmap refbitmap;
237
  static struct bitmap refbitmap;
237
  unsigned short i;
238
  unsigned short i;
238
  unsigned short biggest_langsz = 0;
239
  unsigned short biggest_langsz = 0;
239
 
240
 
240
  if (argc < 2) {
241
  if (argc < 2) {
-
 
242
    puts("tlumacz ver " SVARLANGVER " - this tool is part of the SvarLANG project.");
-
 
243
    puts("converts a set of CATS-style translations in files EN.TXT, PL.TXT, etc");
-
 
244
    puts("into a single resource file (OUT.LNG).");
-
 
245
    puts("");
241
    puts("usage: tlumacz en fr pl etc");
246
    puts("usage: tlumacz en fr pl ...");
242
    return(1);
247
    return(1);
243
  }
248
  }
244
 
249
 
245
  buff = malloc(MEMBLOCKSZ);
250
  buff = malloc(MEMBLOCKSZ);
246
  refblock = malloc(MEMBLOCKSZ);
251
  refblock = malloc(MEMBLOCKSZ);
247
  if ((buff == NULL) || (refblock == NULL)) {
252
  if ((buff == NULL) || (refblock == NULL)) {
248
    puts("out of memory");
253
    puts("out of memory");
249
    return(1);
254
    return(1);
250
  }
255
  }
251
 
256
 
252
  fd = fopen("out.lng", "wb");
257
  fd = fopen("out.lng", "wb");
253
  if (fd == NULL) {
258
  if (fd == NULL) {
254
    puts("ERR: failed to open or create SVARCOM.LNG");
259
    puts("ERR: failed to open or create SVARCOM.LNG");
255
    return(1);
260
    return(1);
256
  }
261
  }
257
 
262
 
258
  /* write sig */
263
  /* write sig */
259
  fwrite("SvL\x1b", 1, 4, fd);
264
  fwrite("SvL\x1b", 1, 4, fd);
260
 
265
 
261
  /* write lang blocks */
266
  /* write lang blocks */
262
  for (i = 1; i < argc; i++) {
267
  for (i = 1; i < argc; i++) {
263
    unsigned short sz;
268
    unsigned short sz;
264
    char id[3];
269
    char id[3];
265
 
270
 
266
    if (strlen(argv[i]) != 2) {
271
    if (strlen(argv[i]) != 2) {
267
      printf("INVALID LANG SPECIFIED: %s\r\n", argv[i]);
272
      printf("INVALID LANG SPECIFIED: %s\r\n", argv[i]);
268
      ecode = 1;
273
      ecode = 1;
269
      break;
274
      break;
270
    }
275
    }
271
 
276
 
272
    id[0] = argv[i][0];
277
    id[0] = argv[i][0];
273
    id[1] = argv[i][1];
278
    id[1] = argv[i][1];
274
    id[2] = 0;
279
    id[2] = 0;
275
    if (id[0] >= 'a') id[0] -= 'a' - 'A';
280
    if (id[0] >= 'a') id[0] -= 'a' - 'A';
276
    if (id[1] >= 'a') id[1] -= 'a' - 'A';
281
    if (id[1] >= 'a') id[1] -= 'a' - 'A';
277
 
282
 
278
    sz = gen_langstrings(buff, id, &bufbitmap, (i != 1)?&refbitmap:NULL, (i != 1)?refblock:NULL);
283
    sz = gen_langstrings(buff, id, &bufbitmap, (i != 1)?&refbitmap:NULL, (i != 1)?refblock:NULL);
279
    if (sz == 0) {
284
    if (sz == 0) {
280
      printf("ERROR COMPUTING LANG '%s'\r\n", id);
285
      printf("ERROR COMPUTING LANG '%s'\r\n", id);
281
      ecode = 1;
286
      ecode = 1;
282
      break;
287
      break;
283
    } else {
288
    } else {
284
      printf("computed %s lang block of %u bytes\r\n", id, sz);
289
      printf("computed %s lang block of %u bytes\r\n", id, sz);
285
      if (sz > biggest_langsz) biggest_langsz = sz;
290
      if (sz > biggest_langsz) biggest_langsz = sz;
286
    }
291
    }
287
    /* write lang ID to file, followed by block size and then the actual block */
292
    /* write lang ID to file, followed by block size and then the actual block */
288
    if ((fwrite(id, 1, 2, fd) != 2) ||
293
    if ((fwrite(id, 1, 2, fd) != 2) ||
289
        (fwrite(&sz, 1, 2, fd) != 2) ||
294
        (fwrite(&sz, 1, 2, fd) != 2) ||
290
        (fwrite(buff, 1, sz, fd) != sz)) {
295
        (fwrite(buff, 1, sz, fd) != sz)) {
291
      printf("ERROR WRITING TO OUTPUT FILE\r\n");
296
      printf("ERROR WRITING TO OUTPUT FILE\r\n");
292
      ecode = 1;
297
      ecode = 1;
293
      break;
298
      break;
294
    }
299
    }
295
    /* remember reference data for other languages */
300
    /* remember reference data for other languages */
296
    if (i == 1) {
301
    if (i == 1) {
297
      refblocksz = sz;
302
      refblocksz = sz;
298
      memcpy(refblock, buff, MEMBLOCKSZ);
303
      memcpy(refblock, buff, MEMBLOCKSZ);
299
      memcpy(&refbitmap, &bufbitmap, sizeof(struct bitmap));
304
      memcpy(&refbitmap, &bufbitmap, sizeof(struct bitmap));
300
    }
305
    }
301
  }
306
  }
302
 
307
 
303
  fclose(fd);
308
  fclose(fd);
304
 
309
 
305
  /* compute the deflang.c file containing a dump of the reference block */
310
  /* compute the deflang.c file containing a dump of the reference block */
306
  fd = fopen("DEFLANG.C", "wb");
311
  fd = fopen("DEFLANG.C", "wb");
307
  if (fd == NULL) {
312
  if (fd == NULL) {
308
    puts("ERROR: FAILED TO OPEN OR CREATE DEFLANG.C");
313
    puts("ERROR: FAILED TO OPEN OR CREATE DEFLANG.C");
309
    ecode = 1;
314
    ecode = 1;
310
  } else {
315
  } else {
311
    unsigned short allocsz = biggest_langsz + (biggest_langsz / 20);
316
    unsigned short allocsz = biggest_langsz + (biggest_langsz / 20);
312
    printf("biggest lang block is %u bytes -> allocating a %u bytes buffer\n", biggest_langsz, allocsz);
317
    printf("biggest lang block is %u bytes -> allocating a %u bytes buffe (5%% safety margin)r\n", biggest_langsz, allocsz);
313
    fprintf(fd, "/* THIS FILE HAS BEEN GENERATED BY TLUMACZ (PART OF THE SVARLANG LIBRARY) */\r\n");
318
    fprintf(fd, "/* THIS FILE HAS BEEN GENERATED BY TLUMACZ (PART OF THE SVARLANG LIBRARY) */\r\n");
314
    fprintf(fd, "const unsigned short svarlang_memsz = %uu;\r\n", allocsz);
319
    fprintf(fd, "const unsigned short svarlang_memsz = %uu;\r\n", allocsz);
315
    fprintf(fd, "char svarlang_mem[%u] = {\r\n", allocsz);
320
    fprintf(fd, "char svarlang_mem[%u] = {\r\n", allocsz);
316
    for (i = 0; i < refblocksz; i++) {
321
    for (i = 0; i < refblocksz; i++) {
317
      fprintf(fd, "%u", refblock[i]);
322
      fprintf(fd, "%u", refblock[i]);
318
      if (i + 1 < refblocksz) fprintf(fd, ",");
323
      if (i + 1 < refblocksz) fprintf(fd, ",");
319
      if ((i & 15) == 15) fprintf(fd, "\r\n");
324
      if ((i & 15) == 15) fprintf(fd, "\r\n");
320
    }
325
    }
321
    fprintf(fd, "};\r\n");
326
    fprintf(fd, "};\r\n");
322
    fclose(fd);
327
    fclose(fd);
323
  }
328
  }
324
 
329
 
325
  return(ecode);
330
  return(ecode);
326
}
331
}
327
 
332