quran: report if open or mmap fails
[cnoor.git] / quran.c
blob361c57be6c7cf416994568972a728cce6a24e8f6
1 #include <fcntl.h>
2 #include <sys/mman.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 #include "util.h"
9 #include "quran.h"
11 static size_t file_size(int fd)
13 struct stat st;
14 if (!fstat(fd, &st))
15 return st.st_size;
16 return 0;
19 static int newlines(char *s)
21 int n;
22 for (n = 0; (s = strchr(s, '\n')); s++, n++);
23 return n;
26 struct quran *quran_alloc(char *path)
28 int i;
29 int nayas;
30 struct quran *quran = xmalloc(sizeof(struct quran));
31 memset(quran, 0, sizeof(quran));
32 quran->fd = open(path, O_RDONLY);
33 if (quran->fd == -1)
34 xerror("open: ");
35 quran->text = mmap(NULL, file_size(quran->fd), PROT_READ,
36 MAP_SHARED, quran->fd, 0);
37 if (quran->text == MAP_FAILED)
38 xerror("mmap: ");
39 nayas = newlines(quran->text);
40 quran->ayas = xmalloc(sizeof(quran->ayas) * nayas);
41 quran->ayas[0] = quran->text;
42 for (i = 1; i < nayas; i++)
43 quran->ayas[i] = strchr(quran->ayas[i - 1], '\n') + 1;
44 return quran;
47 void quran_aya(struct quran *quran, char *buf, size_t len, int aya)
49 char *s = quran->ayas[aya];
50 char *e = strchr(s, '\n');
51 size_t n = e - s;
52 if (n > len - 1)
53 n = len - 1;
54 memcpy(buf, s, n);
55 buf[buf[n - 1] == '\r' ? n - 1 : n] = '\0';
58 void quran_free(struct quran *quran)
60 munmap(quran->text, file_size(quran->fd));
61 close(quran->fd);
62 free(quran->ayas);
63 free(quran);
66 static int ayas[] = {
67 7, 286, 200, 176, 120, 165, 206, 75, 129, 109,
68 123, 111, 43, 52, 99, 128, 111, 110, 98, 135,
69 112, 78, 118, 64, 77, 227, 93, 88, 69, 60,
70 34, 30, 73, 54, 45, 83, 182, 88, 75, 85,
71 54, 53, 89, 59, 37, 35, 38, 29, 18, 45,
72 60, 49, 62, 55, 78, 96, 29, 22, 24, 13,
73 14, 11, 11, 18, 12, 12, 30, 52, 52, 44,
74 28, 28, 20, 56, 40, 31, 50, 40, 46, 42,
75 29, 19, 36, 25, 22, 17, 19, 26, 30, 20,
76 15, 21, 11, 8, 8, 19, 5, 8, 8, 11,
77 11, 8, 3, 9, 5, 4, 7, 3, 6,
78 3, 5, 4, 5, 6};
80 int sura_ayas(int sura)
82 return ayas[sura - 1];
85 int sura_start(int sura)
87 int i;
88 int n = 0;
89 for (i = 0; i < sura - 1; i++)
90 n += ayas[i];
91 return n;
94 int aya_num(int sura, int aya)
96 return sura_start(sura) + aya;
99 #define AYAHASH(sura, aya) (((sura) << 10) | (aya))
101 int juz_start(int sura, int aya)
103 switch (AYAHASH(sura, aya)) {
104 case AYAHASH(1, 1):
105 return 1;
106 case AYAHASH(2, 142):
107 return 2;
108 case AYAHASH(2, 253):
109 return 3;
110 case AYAHASH(3, 93):
111 return 4;
112 case AYAHASH(4, 24):
113 return 5;
114 case AYAHASH(4, 148):
115 return 6;
116 case AYAHASH(5, 82):
117 return 7;
118 case AYAHASH(6, 111):
119 return 8;
120 case AYAHASH(7, 88):
121 return 9;
122 case AYAHASH(8, 41):
123 return 10;
124 case AYAHASH(9, 93):
125 return 11;
126 case AYAHASH(11, 6):
127 return 12;
128 case AYAHASH(12, 53):
129 return 13;
130 case AYAHASH(15, 1):
131 return 14;
132 case AYAHASH(17, 1):
133 return 15;
134 case AYAHASH(18, 75):
135 return 16;
136 case AYAHASH(21, 1):
137 return 16;
138 case AYAHASH(23, 1):
139 return 18;
140 case AYAHASH(25, 21):
141 return 19;
142 case AYAHASH(27, 56):
143 return 20;
144 case AYAHASH(29, 46):
145 return 21;
146 case AYAHASH(33, 31):
147 return 22;
148 case AYAHASH(36, 28):
149 return 23;
150 case AYAHASH(39, 32):
151 return 24;
152 case AYAHASH(41, 47):
153 return 25;
154 case AYAHASH(46, 1):
155 return 26;
156 case AYAHASH(51, 31):
157 return 27;
158 case AYAHASH(58, 1):
159 return 28;
160 case AYAHASH(67, 1):
161 return 29;
162 case AYAHASH(78, 1):
163 return 30;
165 return 0;
168 enum sajda sajda_kind(int sura, int aya)
170 switch (AYAHASH(sura, aya)) {
171 case AYAHASH(7, 206):
172 return SAJDA_RECOM;
173 case AYAHASH(13, 15):
174 return SAJDA_RECOM;
175 case AYAHASH(16, 50):
176 return SAJDA_RECOM;
177 case AYAHASH(17, 109):
178 return SAJDA_RECOM;
179 case AYAHASH(19, 58):
180 return SAJDA_RECOM;
181 case AYAHASH(22, 18):
182 return SAJDA_RECOM;
183 case AYAHASH(22, 77):
184 return SAJDA_RECOM;
185 case AYAHASH(25, 60):
186 return SAJDA_RECOM;
187 case AYAHASH(27, 26):
188 return SAJDA_RECOM;
189 case AYAHASH(32, 15):
190 return SAJDA_OBLIG;
191 case AYAHASH(38, 24):
192 return SAJDA_RECOM;
193 case AYAHASH(41, 38):
194 return SAJDA_OBLIG;
195 case AYAHASH(53, 62):
196 return SAJDA_OBLIG;
197 case AYAHASH(84, 21):
198 return SAJDA_RECOM;
199 case AYAHASH(96, 19):
200 return SAJDA_OBLIG;
201 default:
202 return SAJDA_NONE;