1 /* Copyright © Євгеній Мещеряков <eugen@debian.org>
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 #define _POSIX_C_SOURCE 200809L
17 #include "unicode_blocks.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
read_blocks(const char * file_name,int * n)22 struct unicode_block *read_blocks(const char *file_name, int *n)
23 {
24 int nalloc = 256;
25 struct unicode_block *blocks = calloc(nalloc, sizeof(struct unicode_block));
26 *n = 0;
27
28 FILE *input_file = fopen(file_name, "r");
29 if (!input_file) {
30 perror("fopen");
31 exit(7);
32 }
33
34 char *line = NULL;
35 size_t len = 0;
36 ssize_t nread;
37
38 while ((nread = getline(&line, &len, input_file)) != -1) {
39 unsigned long block_start, block_end;
40 char block_name[256];
41
42 if (nread >= (ssize_t)sizeof(block_name))
43 continue;
44
45 int matched = sscanf(line, "%lx..%lx; %[^\r\n]", &block_start, &block_end, block_name);
46 if (matched == 3) {
47 struct unicode_block *b = blocks + *n;
48 b->start = block_start;
49 b->end = block_end;
50 b->name = strdup(block_name);
51 if (b->name == NULL) {
52 perror("strdup");
53 exit(8);
54 }
55
56 *n += 1;
57 if (*n >= nalloc) {
58 int new_nalloc = nalloc + 256;
59 struct unicode_block *new_blocks = realloc(blocks,
60 new_nalloc * sizeof(struct unicode_block));
61 if (new_blocks == NULL) {
62 perror("realloc");
63 exit(9);
64 }
65 memset(new_blocks + nalloc, 0, (new_nalloc - nalloc) * sizeof(struct unicode_block));
66 nalloc = new_nalloc;
67 blocks = new_blocks;
68 }
69 }
70 }
71 free(line);
72
73 if (*n == 0) {
74 free(blocks);
75 return NULL;
76 } else if (*n < nalloc) {
77 blocks = realloc(blocks, *n * sizeof(struct unicode_block));
78 }
79
80 return blocks;
81 }
82