commit 478a8a59456b8ccd6d6e0e548d35ec8177dacbed
parent c7de74fc1a3bbf3acf50408d327de7c3562b7ccc
Author: afify <hassan@afify.dev>
Date: Sat, 7 May 2022 07:50:31 +0300
[feat] print next prayer left duration
Diffstat:
A | .clang-format | | | 95 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | Makefile | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | cazan | | | 0 | |
A | cazan.c | | | 214 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | config.mk | | | 14 | ++++++++++++++ |
A | util.c | | | 44 | ++++++++++++++++++++++++++++++++++++++++++++ |
A | util.h | | | 17 | +++++++++++++++++ |
7 files changed, 436 insertions(+), 0 deletions(-)
diff --git a/.clang-format b/.clang-format
@@ -0,0 +1,95 @@
+---
+BasedOnStyle: WebKit
+---
+AccessModifierOffset: 8
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignConsecutiveMacros: false
+AlignEscapedNewlines: Left
+AlignOperands: false
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: InlineOnly
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: TopLevelDefinitions
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+BinPackArguments: true
+BinPackParameters: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: WebKit
+BreakBeforeTernaryOperators: false
+BreakStringLiterals: false
+ColumnLimit: 80
+CompactNamespaces: true
+UseTab: Always
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+DerivePointerAlignment: false
+DisableFormat: false
+IncludeBlocks: Regroup
+IndentCaseLabels: false
+IndentPPDirectives: None
+IndentWidth: 8
+KeepEmptyLinesAtTheStartOfBlocks: true
+Language: Cpp
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+PenaltyBreakBeforeFirstCallParameter: 1000
+PenaltyBreakComment: 10
+PointerAlignment: Right
+ReflowComments: false
+SortIncludes: true
+SpaceAfterCStyleCast: false
+TabWidth: 8
+
+IncludeCategories:
+ - Regex: '^\"opt_.*\.h\"'
+ Priority: 1
+ SortPriority: 10
+ - Regex: '^<sys/cdefs\.h>'
+ Priority: 2
+ SortPriority: 20
+ - Regex: '^<sys/types\.h>'
+ Priority: 2
+ SortPriority: 21
+ - Regex: '^<sys/param\.h>'
+ Priority: 2
+ SortPriority: 22
+ - Regex: '^<sys.*/'
+ Priority: 2
+ SortPriority: 23
+ - Regex: '^<vm/vm\.h>'
+ Priority: 3
+ SortPriority: 30
+ - Regex: '^<vm/'
+ Priority: 3
+ SortPriority: 31
+ - Regex: '^<machine/'
+ Priority: 4
+ SortPriority: 40
+ - Regex: '^<(x86|amd64|i386|xen)/'
+ Priority: 5
+ SortPriority: 50
+ - Regex: '^<dev/'
+ Priority: 6
+ SortPriority: 60
+ - Regex: '^<net.*/'
+ Priority: 7
+ SortPriority: 70
+ - Regex: '^<protocols/'
+ Priority: 7
+ SortPriority: 71
+ - Regex: '^<(fs|nfs(|client|server)|ufs)/'
+ Priority: 8
+ SortPriority: 80
+ - Regex: '^<[^/].*\.h'
+ Priority: 9
+ SortPriority: 90
+ - Regex: '^\".*\.h\"'
+ Priority: 10
+ SortPriority: 100
+...
diff --git a/Makefile b/Makefile
@@ -0,0 +1,52 @@
+# cazan - simple muslim prayers calculator
+# print next prayer left duration or today's all prayers.
+# See LICENSE file for copyright and license details.
+
+include config.mk
+
+SRC = cazan.c util.c
+OBJ = ${SRC:.c=.o}
+
+all: options cazan
+
+options:
+ @echo cazan build options:
+ @echo "CFLAGS = ${CFLAGS}"
+ @echo "LDFLAGS = ${LDFLAGS}"
+ @echo "CC = ${CC}"
+
+.c.o:
+ ${CC} -c ${CFLAGS} $<
+
+${OBJ}: config.h config.mk
+
+config.h:
+ cp config.def.h $@
+
+cazan: ${OBJ}
+ ${CC} ${LDFLAGS} -o $@ ${OBJ}
+
+clean:
+ rm -f cazan ${OBJ} cazan-${VERSION}.tar.gz
+
+dist: clean
+ mkdir -p cazan-${VERSION}
+ cp -R LICENSE Makefile README.md config.def.h config.mk\
+ cazan.1 cazan.png util.h ${SRC} cazan-${VERSION}
+ tar -cf cazan-${VERSION}.tar cazan-${VERSION}
+ gzip cazan-${VERSION}.tar
+ rm -rf cazan-${VERSION}
+
+install: cazan
+ mkdir -p ${DESTDIR}${PREFIX}/bin
+ cp -f cazan ${DESTDIR}${PREFIX}/bin
+ chmod 755 ${DESTDIR}${PREFIX}/bin/cazan
+ mkdir -p ${DESTDIR}${MANPREFIX}/man1
+ sed "s/VERSION/${VERSION}/g" < cazan.1 > ${DESTDIR}${MANPREFIX}/man1/cazan.1
+ chmod 644 ${DESTDIR}${MANPREFIX}/man1/cazan.1
+
+uninstall:
+ rm -f ${DESTDIR}${PREFIX}/bin/cazan\
+ ${DESTDIR}${MANPREFIX}/man1/cazan.1
+
+.PHONY: all options clean dist install uninstall
diff --git a/cazan b/cazan
Binary files differ.
diff --git a/cazan.c b/cazan.c
@@ -0,0 +1,214 @@
+/* See LICENSE file for copyright and license details. */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "config.h"
+#include "util.h"
+
+/* macros */
+#define PI 3.14159265358979323846
+#define JUL1970 2440587.5
+#define SEC_INDAY 86400.0
+#define SEC_INHOUR 3600.0
+#define OFFSET 2451545.0
+
+/* typedef */
+/* function declarations */
+
+/* global variables */
+static const long double p1 = 0.066666666666666666;
+static const long double to_rad = 0.017453292519943295;
+static const long double to_deg = 57.295779513082322865;
+static long double p2, p3;
+
+/* function implementations */
+static void
+usage(void)
+{
+ die("usage: cazan -[AaUuv] [-lo longitude] [-la latitude]\n\
+ [-al altitude] [-tz timezone] [-fa fajr_angle]\n\
+ [-ia isha_angle] [-am asr_mazhab] [-r ramadan]\n\
+options:\n \
+-A print all prayers time, 12-hour clock format.\n \
+-a print all prayers time.\n \
+-U print all prayers time, unix-time format.\n \
+-u print next prayer time, unix-time format.\n \
+-v print version.");
+}
+
+static void
+convert_sec_double_to_min_hour(double sec, int *hours, int *min)
+{
+ *hours = sec / SEC_INHOUR;
+ *min = (sec - (*hours * SEC_INHOUR)) / 60;
+}
+
+static long double
+T(long double t)
+{
+ long double p4, p5;
+ p4 = -1.0 * sin(to_rad * t);
+ p5 = to_deg * (acos((p4 - p3) / p2));
+ return p1 * p5;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int hours, min;
+ char pray_char;
+ time_t now, start_of_day;
+ long double duhr_t, asr_t, maghrib_t, isha_t;
+ long double julian, d, g, e, q, sing, sin2g, sine, cose, L, sinL, cosL;
+ long double RA, D, EqT, duhr, fajr, asr, maghrib, isha;
+ long double fajr_t, p4, p5, p6, p7, A;
+ long double next_prayer;
+
+
+ /*
+ if (argc == 1)
+ goto start;
+
+ if (argc == 2) {
+ if (strncmp("-v", argv[1], 2) == 0)
+ die("cazan-" VERSION);
+ if (strncmp("-a", argv[1], 2) == 0)
+ opt = 'a';
+ if (strncmp("-A", argv[1], 2) == 0)
+ opt = 'A';
+ if (strncmp("-U", argv[1], 2) == 0)
+ opt = 'U';
+ if (strncmp("-u", argv[1], 2) == 0)
+ opt = 'u';
+ else
+ usage();
+ goto start;
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-lo")) {
+ longitude = strtold(argv[++i], NULL);
+ } else if (!strcmp(argv[i], "-la")) {
+ latitude = strtold(argv[++i], NULL);
+ } else if (!strcmp(argv[i], "-al")) {
+ altitude = strtold(argv[++i], NULL);
+ } else if (!strcmp(argv[i], "-tz")) {
+ timezone = strtold(argv[++i], NULL);
+ } else if (!strcmp(argv[i], "-fa")) {
+ fajr_angle = strtold(argv[++i], NULL);
+ } else if (!strcmp(argv[i], "-ia")) {
+ isha_angle = strtold(argv[++i], NULL);
+ } else if (!strcmp(argv[i], "-am")) {
+ asr_mazhab = atoi(argv[++i]);
+ FAIL_IF((asr_mazhab > 2 || asr_mazhab < 1),
+ "asr_mazhab must be 1 or 2");
+ } else if (!strcmp(argv[i], "-r")) {
+ ramadan = atoi(argv[++i]);
+ } else {
+ usage();
+ }
+ }
+
+ */
+ if (argc == 1)
+ goto start;
+ else if (argc == 2 && strncmp("-v", argv[1], 2) == 0)
+ die("cazan-" VERSION);
+ else
+ usage();
+
+start:
+ time(&now);
+ start_of_day = now - (now % 86400);
+ julian = (now / SEC_INDAY) + JUL1970;
+ d = julian - OFFSET;
+ g = to_rad * ((d * 0.98560028) + 357.529);
+ e = to_rad * (23.439 - (d * 0.00000036));
+ q = (d * 0.98564736) + 280.459;
+ sing = 1.915 * sin(g);
+ sin2g = 0.020 * sin(2.0 * g);
+ sine = sin(e);
+ cose = cos(e);
+ L = to_rad * (q + sing + sin2g);
+ sinL = sin(L);
+ cosL = cos(L);
+ RA = to_deg * (atan2(cose * sinL, cosL) / 15.0);
+ D = to_deg * (asin(sine * sinL));
+ EqT = q / 15.0 - RA;
+ p2 = cos(to_rad * latitude) * cos(to_rad * D);
+ p3 = sin(to_rad * latitude) * sin(to_rad * D);
+
+ /* duhr */
+ duhr = 12.0 + timezone - EqT - (longitude / 15.0);
+ duhr = duhr - (24 * floor(duhr / 24));
+ duhr_t = start_of_day + (duhr * 3600);
+
+ /* fajr */
+ fajr_t = T(fajr_angle);
+ fajr = duhr - fajr_t;
+ fajr_t = start_of_day + (fajr * 3600);
+
+ /* asr */
+ p4 = tan(to_rad * ((latitude - D)));
+ p5 = atan2(1.0, p4 + asr_mazhab);
+ p6 = sin(p5);
+ p7 = to_deg * (acos((p6 - p3) / p2));
+ A = p1 * p7;
+ asr = duhr + A;
+ asr = asr - (24 * floor(asr / 24));
+ asr_t = start_of_day + (asr * 3600);
+
+ /* maghrib */
+ maghrib = duhr + T(0.8333 + 0.0347 * sqrt(altitude));
+ maghrib = maghrib - (24 * floor(maghrib / 24));
+ maghrib_t = start_of_day + (maghrib * 3600);
+
+ /* isha */
+ if (fajr_angle == 18.5) { /* Umm Al-Qura */
+ isha = maghrib + (90.0 * 0.016666666666666666);
+ if (ramadan == 1) /* Ramadan Umm Al-Qura */
+ isha = maghrib + (120.0 * 0.016666666666666666);
+ } else { /* Use isha_angle */
+ isha = duhr + T(isha_angle);
+ }
+ isha = isha - (24 * floor(isha / 24));
+ isha_t = start_of_day + (isha * 3600);
+
+ next_prayer = fajr_t - now;
+
+ if (fajr_t > now) {
+ pray_char = 'F';
+ } else if (duhr_t > now) {
+ pray_char = 'D';
+ next_prayer = duhr_t - now;
+ } else if (asr_t > now) {
+ pray_char = 'A';
+ next_prayer = asr_t - now;
+ } else if (maghrib_t > now) {
+ pray_char = 'M';
+ next_prayer = maghrib_t - now;
+ } else if (isha_t > now) {
+ pray_char = 'I';
+ next_prayer = isha_t - now;
+ } else {
+ pray_char = '?';
+ }
+
+ /*
+ printf("now\t\t%ld\n", now);
+ printf("fajr_t\t\t%.18Lf\n", fajr_t);
+ printf("duhr_t\t\t%.18Lf\n", duhr_t);
+ printf("asr_t\t\t%.18Lf\n", asr_t);
+ printf("maghrib_t\t%.18Lf\n", maghrib_t);
+ printf("isha_t\t\t%.18Lf\n", isha_t);
+ */
+
+ convert_sec_double_to_min_hour(next_prayer, &hours, &min);
+ printf("%c %.2d:%.2d\n", pray_char, hours, min);
+
+ return 0;
+}
diff --git a/config.mk b/config.mk
@@ -0,0 +1,14 @@
+# cazan version
+VERSION = 0.1
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = ${PREFIX}/share/man
+
+# flags
+CPPFLAGS = -DVERSION=\"${VERSION}\" -D_POSIX_C_SOURCE=200112L
+CFLAGS = -ansi -pedantic -Wextra -Wall -O0 ${CPPFLAGS}
+LDFLAGS = -s -lm
+
+# compiler and linker
+CC = cc
diff --git a/util.c b/util.c
@@ -0,0 +1,44 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+void *
+ecalloc(size_t nmemb, size_t size)
+{
+ void *p;
+ p = calloc(nmemb, size);
+ FAIL_IF(p == NULL, "calloc");
+ return p;
+}
+
+void *
+erealloc(void *p, size_t len)
+{
+ if ((p = realloc(p, len)) == NULL)
+ die("realloc: %s\n", strerror(errno));
+ return p;
+}
+
+void
+die(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') {
+ (void)fputc(' ', stderr);
+ perror(NULL);
+ } else {
+ (void)fputc('\n', stderr);
+ }
+
+ exit(EXIT_FAILURE);
+}
diff --git a/util.h b/util.h
@@ -0,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#define MAX(A, B) ((A) > (B) ? (A) : (B))
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
+#define LEN(A) (sizeof(A)/sizeof(A[0]))
+#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
+#define FAIL_IF(EXP, MSG) {if(EXP){fprintf(stderr, "[\033[31mFAILED %d\033[0m] %s\n", __LINE__, MSG);exit(EXIT_FAILURE);}}
+#define PERROR(EXP) {if(EXP){print_error(strerror(errno));}};
+
+void *ecalloc(size_t, size_t);
+void *erealloc(void*, size_t);
+void die(const char *fmt, ...);
+
+#endif /* UTIL_H */