txtwin: mark previous position with '
[cnoor.git] / quran.c
blob0c8cdb3ccd2a36d80b65a38fb83818bc18e9462b
1 #include <fcntl.h>
2 #include <stdio.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 "quran.h"
10 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
11 #define MIN(a, b) ((a) < (b) ? (a) : (b))
12 #define MAX(a, b) ((a) > (b) ? (a) : (b))
14 static char abuf[1 << 16];
15 static int apos = -1;
16 static int acur;
17 static int aaya;
19 static int aya_offset(int fd, int aya)
21 char *s;
22 if (aaya > aya || apos == -1) {
23 acur = 0;
24 aaya = 0;
25 apos = 0;
26 lseek(fd, apos, 0);
27 read(fd, abuf, sizeof(abuf));
29 while (aaya < aya) {
30 while (!(s = memchr(abuf + acur, '\n', sizeof(abuf) - acur))) {
31 acur = 0;
32 apos += sizeof(abuf);
33 lseek(fd, apos, 0);
34 read(fd, abuf, sizeof(abuf));
36 acur = s - abuf + 1;
37 aaya++;
39 return apos + acur;
42 static void *xmalloc(size_t size)
44 void *value = malloc(size);
45 if (!value) {
46 fprintf(stderr, "Out of memory!\n");
47 exit(1);
49 return value;
52 static void *xerror(char *errmsg)
54 perror(errmsg);
55 exit(1);
58 struct quran *quran_alloc(char *path)
60 struct quran *quran = xmalloc(sizeof(struct quran));
61 int i;
62 memset(quran, 0, sizeof(*quran));
63 quran->fd = open(path, O_RDONLY);
64 if (quran->fd == -1)
65 xerror(path);
66 for (i = 0; i < NAYA + 1; i++)
67 quran->ayas[i] = aya_offset(quran->fd, i);
68 return quran;
71 void quran_aya(struct quran *quran, char *buf, int len, int aya)
73 int n;
74 if (quran->ayas[aya] + len > quran->ayas[aya + 1])
75 len = quran->ayas[aya + 1] - quran->ayas[aya] - 1;
76 lseek(quran->fd, quran->ayas[aya], 0);
77 n = read(quran->fd, buf, len);
78 while (n > 0 && (buf[n - 1] == '\r' || buf[n - 1] == '\n'))
79 n--;
80 buf[n] = '\0';
83 void quran_free(struct quran *quran)
85 close(quran->fd);
86 free(quran);
89 static struct suras {
90 char *name;
91 int ayas;
92 } suras[] = {
93 {"Al-Faatiha", 7}, {"Al-Baqara", 286}, {"Aal-i-Imraan", 200},
94 {"An-Nisaa", 176}, {"Al-Maaida", 120}, {"Al-An'aam", 165},
95 {"Al-A'raaf", 206}, {"Al-Anfaal", 75}, {"At-Tawba", 129},
96 {"Yunus", 109}, {"Hud", 123}, {"Yusuf", 111},
97 {"Ar-Ra'd", 43}, {"Ibrahim", 52}, {"Al-Hijr", 99},
98 {"An-Nahl", 128}, {"Al-Israa", 111}, {"Al-Kahf", 110},
99 {"Maryam", 98}, {"Taa-Haa", 135}, {"Al-Anbiyaa", 112},
100 {"Al-Hajj", 78}, {"Al-Muminoon", 118}, {"An-Noor", 64},
101 {"Al-Furqaan", 77}, {"Ash-Shu'araa", 227}, {"An-Naml", 93},
102 {"Al-Qasas", 88}, {"Al-Ankaboot", 69}, {"Ar-Room", 60},
103 {"Luqman", 34}, {"As-Sajda", 30}, {"Al-Ahzaab", 73},
104 {"Saba", 54}, {"Faatir", 45}, {"Yaseen", 83},
105 {"As-Saaffaat", 182}, {"Saad", 88}, {"Az-Zumar", 75},
106 {"Al-Ghaafir", 85}, {"Fussilat", 54}, {"Ash-Shura", 53},
107 {"Az-Zukhruf", 89}, {"Ad-Dukhaan", 59}, {"Al-Jaathiya", 37},
108 {"Al-Ahqaf", 35}, {"Muhammad", 38}, {"Al-Fath", 29},
109 {"Al-Hujuraat", 18}, {"Qaaf", 45}, {"Adh-Dhaariyat", 60},
110 {"At-Tur", 49}, {"An-Najm", 62}, {"Al-Qamar", 55},
111 {"Ar-Rahmaan", 78}, {"Al-Waaqia", 96}, {"Al-Hadid", 29},
112 {"Al-Mujaadila", 22}, {"Al-Hashr", 24}, {"Al-Mumtahana", 13},
113 {"As-Saff", 14}, {"Al-Jumu'a", 11}, {"Al-Munaafiqoon", 11},
114 {"At-Taghaabun", 18}, {"At-Talaaq", 12}, {"At-Tahrim", 12},
115 {"Al-Mulk", 30}, {"Al-Qalam", 52}, {"Al-Haaqqa", 52},
116 {"Al-Ma'aarij", 44}, {"Nooh", 28}, {"Al-Jinn", 28},
117 {"Al-Muzzammil", 20}, {"Al-Muddaththir", 56}, {"Al-Qiyaama", 40},
118 {"Al-Insaan", 31}, {"Al-Mursalaat", 50}, {"An-Naba", 40},
119 {"An-Naazi'aat", 46}, {"Abasa", 42}, {"At-Takwir", 29},
120 {"Al-Infitaar", 19}, {"Al-Mutaffifin", 36}, {"Al-Inshiqaaq", 25},
121 {"Al-Burooj", 22}, {"At-Taariq", 17}, {"Al-A'laa", 19},
122 {"Al-Ghaashiya", 26}, {"Al-Fajr", 30}, {"Al-Balad", 20},
123 {"Ash-Shams", 15}, {"Al-Lail", 21}, {"Ad-Dhuhaa", 11},
124 {"Ash-Sharh", 8}, {"At-Tin", 8}, {"Al-Alaq", 19},
125 {"Al-Qadr", 5}, {"Al-Bayyina", 8}, {"Az-Zalzala", 8},
126 {"Al-Aadiyaat", 11}, {"Al-Qaari'a", 11}, {"At-Takaathur", 8},
127 {"Al-Asr", 3}, {"Al-Humaza", 9}, {"Al-Fil", 5},
128 {"Quraish", 4}, {"Al-Maa'un", 7}, {"Al-Kawthar", 3},
129 {"Al-Kaafiroon", 6}, {"An-Nasr", 3}, {"Al-Masad", 5},
130 {"Al-Ikhlaas", 4}, {"Al-Falaq", 5}, {"An-Naas", 6}
133 int sura_ayas(int sura)
135 return suras[sura - 1].ayas;
138 char *sura_name(int sura)
140 return suras[sura - 1].name;
143 int sura_start(int sura)
145 int i;
146 int n = 0;
147 for (i = 0; i < sura - 1; i++)
148 n += suras[i].ayas;
149 return n;
152 int aya_num(int sura, int aya)
154 return sura_start(sura) + aya;
157 #define AYAHASH(sura, aya) (((sura) << 10) | (aya))
159 int juz_start(int sura, int aya)
161 switch (AYAHASH(sura, aya)) {
162 case AYAHASH(1, 1):
163 return 1;
164 case AYAHASH(2, 142):
165 return 2;
166 case AYAHASH(2, 253):
167 return 3;
168 case AYAHASH(3, 93):
169 return 4;
170 case AYAHASH(4, 24):
171 return 5;
172 case AYAHASH(4, 148):
173 return 6;
174 case AYAHASH(5, 82):
175 return 7;
176 case AYAHASH(6, 111):
177 return 8;
178 case AYAHASH(7, 88):
179 return 9;
180 case AYAHASH(8, 41):
181 return 10;
182 case AYAHASH(9, 93):
183 return 11;
184 case AYAHASH(11, 6):
185 return 12;
186 case AYAHASH(12, 53):
187 return 13;
188 case AYAHASH(15, 1):
189 return 14;
190 case AYAHASH(17, 1):
191 return 15;
192 case AYAHASH(18, 75):
193 return 16;
194 case AYAHASH(21, 1):
195 return 16;
196 case AYAHASH(23, 1):
197 return 18;
198 case AYAHASH(25, 21):
199 return 19;
200 case AYAHASH(27, 56):
201 return 20;
202 case AYAHASH(29, 46):
203 return 21;
204 case AYAHASH(33, 31):
205 return 22;
206 case AYAHASH(36, 28):
207 return 23;
208 case AYAHASH(39, 32):
209 return 24;
210 case AYAHASH(41, 47):
211 return 25;
212 case AYAHASH(46, 1):
213 return 26;
214 case AYAHASH(51, 31):
215 return 27;
216 case AYAHASH(58, 1):
217 return 28;
218 case AYAHASH(67, 1):
219 return 29;
220 case AYAHASH(78, 1):
221 return 30;
223 return 0;
226 int sajda_kind(int sura, int aya)
228 switch (AYAHASH(sura, aya)) {
229 case AYAHASH(7, 206):
230 return SAJDA_RECOM;
231 case AYAHASH(13, 15):
232 return SAJDA_RECOM;
233 case AYAHASH(16, 50):
234 return SAJDA_RECOM;
235 case AYAHASH(17, 109):
236 return SAJDA_RECOM;
237 case AYAHASH(19, 58):
238 return SAJDA_RECOM;
239 case AYAHASH(22, 18):
240 return SAJDA_RECOM;
241 case AYAHASH(22, 77):
242 return SAJDA_RECOM;
243 case AYAHASH(25, 60):
244 return SAJDA_RECOM;
245 case AYAHASH(27, 26):
246 return SAJDA_RECOM;
247 case AYAHASH(32, 15):
248 return SAJDA_OBLIG;
249 case AYAHASH(38, 24):
250 return SAJDA_RECOM;
251 case AYAHASH(41, 38):
252 return SAJDA_OBLIG;
253 case AYAHASH(53, 62):
254 return SAJDA_OBLIG;
255 case AYAHASH(84, 21):
256 return SAJDA_RECOM;
257 case AYAHASH(96, 19):
258 return SAJDA_OBLIG;
259 default:
260 return SAJDA_NONE;