mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 23:08:40 +02:00
Compare commits
13 Commits
05.03.05-B
...
05.03.06
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce123d1b41 | ||
|
|
4ed8331369 | ||
|
|
44b920e080 | ||
|
|
dc75c8f49b | ||
|
|
cef6e6717c | ||
|
|
5ec78739cd | ||
|
|
79f45169c8 | ||
|
|
b9f09b9a2d | ||
|
|
f53a174d65 | ||
|
|
ed15b7deb5 | ||
|
|
caf5f81eb0 | ||
|
|
d48910eca9 | ||
|
|
c004944a59 |
3
Makefile
3
Makefile
@@ -43,8 +43,9 @@ test:
|
|||||||
@$(MAKE) -C src -s test
|
@$(MAKE) -C src -s test
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
-rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
-rm -f config.cache config.log config.status src/Makefile src/version.h src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
||||||
-rm -f man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind
|
-rm -f man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind
|
||||||
|
-rm -rf autom4te.cache rem2html/Makefile rem2html/rem2html.1
|
||||||
|
|
||||||
src/Makefile: src/Makefile.in
|
src/Makefile: src/Makefile.in
|
||||||
./configure
|
./configure
|
||||||
|
|||||||
18
configure
vendored
18
configure
vendored
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.71 for remind 05.03.05.
|
# Generated by GNU Autoconf 2.71 for remind 05.03.06.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
|
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
|
||||||
@@ -608,8 +608,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='remind'
|
PACKAGE_NAME='remind'
|
||||||
PACKAGE_TARNAME='remind'
|
PACKAGE_TARNAME='remind'
|
||||||
PACKAGE_VERSION='05.03.05'
|
PACKAGE_VERSION='05.03.06'
|
||||||
PACKAGE_STRING='remind 05.03.05'
|
PACKAGE_STRING='remind 05.03.06'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
|
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
|
||||||
|
|
||||||
@@ -1265,7 +1265,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures remind 05.03.05 to adapt to many kinds of systems.
|
\`configure' configures remind 05.03.06 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -1327,7 +1327,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of remind 05.03.05:";;
|
short | recursive ) echo "Configuration of remind 05.03.06:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1415,7 +1415,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
remind configure 05.03.05
|
remind configure 05.03.06
|
||||||
generated by GNU Autoconf 2.71
|
generated by GNU Autoconf 2.71
|
||||||
|
|
||||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
@@ -1865,7 +1865,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by remind $as_me 05.03.05, which was
|
It was created by remind $as_me 05.03.06, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
$ $0$ac_configure_args_raw
|
$ $0$ac_configure_args_raw
|
||||||
@@ -4710,7 +4710,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by remind $as_me 05.03.05, which was
|
This file was extended by remind $as_me 05.03.06, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -4775,7 +4775,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config='$ac_cs_config_escaped'
|
ac_cs_config='$ac_cs_config_escaped'
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
remind config.status 05.03.05
|
remind config.status 05.03.06
|
||||||
configured by $0, generated by GNU Autoconf 2.71,
|
configured by $0, generated by GNU Autoconf 2.71,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_INIT(remind, 05.03.05, , , https://dianne.skoll.ca/projects/remind/)
|
AC_INIT(remind, 05.03.06, , , https://dianne.skoll.ca/projects/remind/)
|
||||||
AC_CONFIG_SRCDIR([src/queue.c])
|
AC_CONFIG_SRCDIR([src/queue.c])
|
||||||
|
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
|
|||||||
@@ -166,21 +166,23 @@
|
|||||||
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||||
"baseyr" "char" "choose" "coerce" "columns" "current" "date"
|
"baseyr" "char" "choose" "coerce" "columns" "current" "date"
|
||||||
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
||||||
"dusk" "easterdate" "escape" "evaltrig" "filedate" "filedatetime" "filedir"
|
"dusk" "easterdate" "escape" "evaltrig" "filedate" "filedatetime"
|
||||||
"filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear" "hour"
|
"filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear"
|
||||||
"htmlescape" "htmlstriptags" "iif" "index" "isany" "isdst" "isleap"
|
"hour" "htmlescape" "htmlstriptags" "iif" "index" "isany" "isdst"
|
||||||
"isomitted" "language" "localtoutc" "lower" "max" "min" "minsfromutc"
|
"isleap" "isomitted" "language" "localtoutc" "lower" "max" "min"
|
||||||
"minute" "mon" "monnum" "moondate" "moondatetime" "moonphase"
|
"minsfromutc" "minute" "mon" "monnum" "moondate" "moondatetime"
|
||||||
"moontime" "multitrig" "ndawn" "ndusk" "nonomitted" "now" "ord"
|
"moonphase" "moonrise" "moonrisedir" "moonset" "moonsetdir" "moontime"
|
||||||
"orthodoxeaster" "ostype" "pad" "plural" "psmoon" "psshade"
|
"multitrig" "ndawn" "ndusk" "nonomitted" "now" "ord" "orthodoxeaster"
|
||||||
"realcurrent" "realnow" "realtoday" "rows" "sgn" "shell" "shellescape"
|
"ostype" "pad" "plural" "psmoon" "psshade" "realcurrent" "realnow"
|
||||||
"slide" "soleq" "stdout" "strlen" "substr" "sunrise" "sunset" "time"
|
"realtoday" "rows" "sgn" "shell" "shellescape" "slide" "soleq"
|
||||||
"timepart" "timezone" "today" "trig" "trigback" "trigdate"
|
"stdout" "strlen" "substr" "sunrise" "sunset" "time" "timepart"
|
||||||
"trigdatetime" "trigdelta" "trigduration" "trigeventduration"
|
"timezone" "today" "trig" "trigback" "trigdate" "trigdatetime"
|
||||||
"trigeventstart" "trigfrom" "trigger" "triginfo" "trigpriority" "trigrep"
|
"trigdelta" "trigduration" "trigeventduration" "trigeventstart"
|
||||||
|
"trigfrom" "trigger" "triginfo" "trigpriority" "trigrep"
|
||||||
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep"
|
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep"
|
||||||
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
||||||
"value" "version" "weekno" "wkday" "wkdaynum" "year")
|
"value" "version" "weekno" "wkday" "wkdaynum" "year"
|
||||||
|
)
|
||||||
#'(lambda (a b) (> (length a) (length b)))))
|
#'(lambda (a b) (> (length a) (length b)))))
|
||||||
|
|
||||||
;;; faces
|
;;; faces
|
||||||
|
|||||||
@@ -1,6 +1,21 @@
|
|||||||
CHANGES TO REMIND
|
CHANGES TO REMIND
|
||||||
|
|
||||||
* VERSION 5.3 Patch 5 - 2025-03-??
|
* VERSION 5.3 Patch 6 - 2025-04-25
|
||||||
|
|
||||||
|
- BUG FIX: remind: Make "remind -s" respect $DefaultColor. Bug found by
|
||||||
|
Tim Chase.
|
||||||
|
|
||||||
|
- DOCUMENTATION IMPROVEMENT: Make documentation of $SuppressLRM a bit more
|
||||||
|
prominent
|
||||||
|
|
||||||
|
- UPDATE: contrib/remind-conf-mode: Add new functions moonrise, moonset, etc.
|
||||||
|
to Emacs highlighting file
|
||||||
|
|
||||||
|
- MINOR IMPROVEMENT: examples/astro: Align output better
|
||||||
|
|
||||||
|
- MINOR FIX: src/moon.c: Change C++-style comments to C-style comments
|
||||||
|
|
||||||
|
* VERSION 5.3 Patch 5 - 2025-03-23
|
||||||
|
|
||||||
- NEW FEATURE: remind: Add moonrise, moonset, moonrisedir and moonsetdir
|
- NEW FEATURE: remind: Add moonrise, moonset, moonrisedir and moonsetdir
|
||||||
functions. The first two functions calculate the time of the next
|
functions. The first two functions calculate the time of the next
|
||||||
@@ -12,11 +27,14 @@ CHANGES TO REMIND
|
|||||||
|
|
||||||
- IMPROVEMENT: Add tests for the astronomical calculation functions.
|
- IMPROVEMENT: Add tests for the astronomical calculation functions.
|
||||||
|
|
||||||
|
- UPDATE: Update the included json.c and json.h files to the latest versions
|
||||||
|
from https://github.com/udp/json-parser
|
||||||
|
|
||||||
- BUG FIX: remind: The %2 and %@ sequences would print "0:34am" for the
|
- BUG FIX: remind: The %2 and %@ sequences would print "0:34am" for the
|
||||||
time 00:34, instead of the correct "12:34am". This has been fixed.
|
time 00:34, instead of the correct "12:34am". This has been fixed.
|
||||||
|
|
||||||
- BUG FIX: TkRemind: Fix bug that broke the ability to open a text editor
|
- BUG FIX: TkRemind: Fix bug that broke the ability to open a text editor
|
||||||
on a reminder from the Queue... listing.
|
on a reminder from the "Queue..." listing.
|
||||||
|
|
||||||
* VERSION 5.3 Patch 4 - 2025-03-09
|
* VERSION 5.3 Patch 4 - 2025-03-09
|
||||||
|
|
||||||
@@ -39,7 +57,7 @@ CHANGES TO REMIND
|
|||||||
- MINOR IMPROVEMENT: include/holidays/misc.rem: Add a few new holidays and
|
- MINOR IMPROVEMENT: include/holidays/misc.rem: Add a few new holidays and
|
||||||
URL INFO strings.
|
URL INFO strings.
|
||||||
|
|
||||||
- CHANGE: remind: Issue a warning if a time-related subsitution sequence
|
- CHANGE: remind: Issue a warning if a time-related substitution sequence
|
||||||
is used with a non-timed REM command.
|
is used with a non-timed REM command.
|
||||||
|
|
||||||
- BUG FIX: remind: Fix a memory leak.
|
- BUG FIX: remind: Fix a memory leak.
|
||||||
|
|||||||
@@ -92,19 +92,14 @@ set ms moonset()
|
|||||||
set mr_a moonrisedir()
|
set mr_a moonrisedir()
|
||||||
set ms_a moonsetdir()
|
set ms_a moonsetdir()
|
||||||
|
|
||||||
IF mr < ms
|
REM NOQUEUE [mr] MSG Moonrise: %*3 in the [angle_to_direction(mr_a)] ([mr_a] degrees)
|
||||||
REM NOQUEUE [mr] MSG The moon rises %3 in the [angle_to_direction(mr_a)] ([mr_a] degrees)
|
REM NOQUEUE [ms] MSG Moonset: %*3 in the [angle_to_direction(ms_a)] ([ms_a] degrees)
|
||||||
REM NOQUEUE [ms] MSG The moon sets %3 in the [angle_to_direction(ms_a)] ([ms_a] degrees)
|
|
||||||
ELSE
|
|
||||||
REM NOQUEUE [ms] MSG The moon sets %3 in the [angle_to_direction(ms_a)] ([ms_a] degrees)
|
|
||||||
REM NOQUEUE [mr] MSG The moon rises %3 in the [angle_to_direction(mr_a)] ([mr_a] degrees)
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
IF (datepart(mr) != today())
|
IF (datepart(mr) != today())
|
||||||
REM MSG There is no moonrise today
|
REM MSG Moonrise: No moonrise today
|
||||||
ENDIF
|
ENDIF
|
||||||
IF (datepart(ms) != today())
|
IF (datepart(ms) != today())
|
||||||
REM MSG There is no moonset today
|
REM MSG Moonset: No moonset today
|
||||||
ENDIF
|
ENDIF
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
@@ -84,8 +84,13 @@ causes \fBRemind\fR to use VT100 escape sequences to approximate
|
|||||||
SPECIAL COLOR reminders. Note that this flag is kept for
|
SPECIAL COLOR reminders. Note that this flag is kept for
|
||||||
backwards-compatibility; you should use the \fB\-@\fI[n][,m][,b]\fR
|
backwards-compatibility; you should use the \fB\-@\fI[n][,m][,b]\fR
|
||||||
command-line option instead.
|
command-line option instead.
|
||||||
|
.PP
|
||||||
|
In a UTF-8 locale, \fBRemind\fR will use "left-to-right marks" when
|
||||||
|
creating a calendar with the \fB\-c\fR option. Some terminals don't
|
||||||
|
handle this correctly and garble the rendering of the calendar; see
|
||||||
|
the documentation of \fB$SuppressLRM\fR in the section "SYSTEM
|
||||||
|
VARIABLES" for a workaround.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-@\fR[\fIn\fR][,\fIm\fR][,\fIb\fR]
|
.B \-@\fR[\fIn\fR][,\fIm\fR][,\fIb\fR]
|
||||||
Tells \fBRemind\fR to approximate SPECIAL COLOR and SHADE reminders
|
Tells \fBRemind\fR to approximate SPECIAL COLOR and SHADE reminders
|
||||||
|
|||||||
@@ -2055,7 +2055,7 @@ static int DoCalRem(ParsePtr p, int col)
|
|||||||
if (trig.typ == MSG_TYPE ||
|
if (trig.typ == MSG_TYPE ||
|
||||||
trig.typ == CAL_TYPE ||
|
trig.typ == CAL_TYPE ||
|
||||||
trig.typ == MSF_TYPE) {
|
trig.typ == MSF_TYPE) {
|
||||||
if (PsCal && is_color) {
|
if ((PsCal || DoSimpleCalendar) && is_color) {
|
||||||
char cbuf[24];
|
char cbuf[24];
|
||||||
snprintf(cbuf, sizeof(cbuf), "%d %d %d ", col_r, col_g, col_b);
|
snprintf(cbuf, sizeof(cbuf), "%d %d %d ", col_r, col_g, col_b);
|
||||||
DBufPuts(&pre_buf, cbuf);
|
DBufPuts(&pre_buf, cbuf);
|
||||||
|
|||||||
@@ -367,8 +367,8 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
PARSENUM(DefaultTDelta, arg);
|
PARSENUM(DefaultTDelta, arg);
|
||||||
if (DefaultTDelta < 0) {
|
if (DefaultTDelta < 0) {
|
||||||
DefaultTDelta = 0;
|
DefaultTDelta = 0;
|
||||||
} else if (DefaultTDelta > 1440) {
|
} else if (DefaultTDelta > MINUTES_PER_DAY) {
|
||||||
DefaultTDelta = 1440;
|
DefaultTDelta = MINUTES_PER_DAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!*arg) {
|
} else if (!*arg) {
|
||||||
|
|||||||
184
src/json.c
184
src/json.c
@@ -1,7 +1,7 @@
|
|||||||
/* vim: set et ts=3 sw=3 sts=3 ft=c:
|
/* vim: set et ts=3 sw=3 sts=3 ft=c:
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved.
|
* Copyright (C) 2012-2021 the json-parser authors All rights reserved.
|
||||||
* https://github.com/udp/json-parser
|
* https://github.com/json-parser/json-parser
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -29,36 +29,49 @@
|
|||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
|
|
||||||
#define UNUSED(x) ( (void) x )
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||||
|
/* C99 might give us uintptr_t and UINTPTR_MAX but they also might not be provided */
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const struct _json_value json_value_none;
|
#ifndef JSON_INT_T_OVERRIDDEN
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
/* https://docs.microsoft.com/en-us/cpp/cpp/data-type-ranges */
|
||||||
|
#define JSON_INT_MAX 9223372036854775807LL
|
||||||
|
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||||
|
/* C99 */
|
||||||
|
#define JSON_INT_MAX INT_FAST64_MAX
|
||||||
|
#else
|
||||||
|
/* C89 */
|
||||||
|
#include <limits.h>
|
||||||
|
#define JSON_INT_MAX LONG_MAX
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#ifndef JSON_INT_MAX
|
||||||
#include <string.h>
|
#define JSON_INT_MAX (json_int_t)(((unsigned json_int_t)(-1)) / (unsigned json_int_t)2);
|
||||||
#include <ctype.h>
|
#endif
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
typedef unsigned int json_uchar;
|
typedef unsigned int json_uchar;
|
||||||
|
|
||||||
/* There has to be a better way to do this */
|
const struct _json_value json_value_none;
|
||||||
static const json_int_t JSON_INT_MAX = sizeof(json_int_t) == 1
|
|
||||||
? INT8_MAX
|
|
||||||
: (sizeof(json_int_t) == 2
|
|
||||||
? INT16_MAX
|
|
||||||
: (sizeof(json_int_t) == 4
|
|
||||||
? INT32_MAX
|
|
||||||
: INT64_MAX));
|
|
||||||
|
|
||||||
static unsigned char hex_value (json_char c)
|
static unsigned char hex_value (json_char c)
|
||||||
{
|
{
|
||||||
if (isdigit(c))
|
if (isdigit((unsigned char)c))
|
||||||
return c - '0';
|
return c - '0';
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -79,10 +92,7 @@ static int would_overflow (json_int_t value, json_char b)
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned long used_memory;
|
size_t used_memory;
|
||||||
|
|
||||||
unsigned int uint_max;
|
|
||||||
unsigned long ulong_max;
|
|
||||||
|
|
||||||
json_settings settings;
|
json_settings settings;
|
||||||
int first_pass;
|
int first_pass;
|
||||||
@@ -94,19 +104,19 @@ typedef struct
|
|||||||
|
|
||||||
static void * default_alloc (size_t size, int zero, void * user_data)
|
static void * default_alloc (size_t size, int zero, void * user_data)
|
||||||
{
|
{
|
||||||
UNUSED(user_data);
|
(void)user_data; /* ignore unused-parameter warn */
|
||||||
return zero ? calloc (1, size) : malloc (size);
|
return zero ? calloc (1, size) : malloc (size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void default_free (void * ptr, void * user_data)
|
static void default_free (void * ptr, void * user_data)
|
||||||
{
|
{
|
||||||
UNUSED(user_data);
|
(void)user_data; /* ignore unused-parameter warn */
|
||||||
free (ptr);
|
free (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * json_alloc (json_state * state, unsigned long size, int zero)
|
static void * json_alloc (json_state * state, size_t size, int zero)
|
||||||
{
|
{
|
||||||
if ((state->ulong_max - state->used_memory) < size)
|
if ((ULONG_MAX - 8 - state->used_memory) < size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (state->settings.max_memory
|
if (state->settings.max_memory
|
||||||
@@ -123,7 +133,7 @@ static int new_value (json_state * state,
|
|||||||
json_type type)
|
json_type type)
|
||||||
{
|
{
|
||||||
json_value * value;
|
json_value * value;
|
||||||
int values_size;
|
size_t values_size;
|
||||||
|
|
||||||
if (!state->first_pass)
|
if (!state->first_pass)
|
||||||
{
|
{
|
||||||
@@ -157,14 +167,16 @@ static int new_value (json_state * state,
|
|||||||
values_size = sizeof (*value->u.object.values) * value->u.object.length;
|
values_size = sizeof (*value->u.object.values) * value->u.object.length;
|
||||||
|
|
||||||
if (! (value->u.object.values = (json_object_entry *) json_alloc
|
if (! (value->u.object.values = (json_object_entry *) json_alloc
|
||||||
(state, values_size + ((unsigned long) value->u.object.values), 0)) )
|
#ifdef UINTPTR_MAX
|
||||||
|
(state, values_size + ((uintptr_t) value->u.object.values), 0)) )
|
||||||
|
#else
|
||||||
|
(state, values_size + ((size_t) value->u.object.values), 0)) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *s = (char *) value->u.object.values;
|
value->_reserved.object_mem = (void *) (((char *) value->u.object.values) + values_size);
|
||||||
s += values_size;
|
|
||||||
value->_reserved.object_mem = s;
|
|
||||||
|
|
||||||
value->u.object.length = 0;
|
value->u.object.length = 0;
|
||||||
break;
|
break;
|
||||||
@@ -213,8 +225,8 @@ static int new_value (json_state * state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define whitespace \
|
#define whitespace \
|
||||||
case '\n': ++ state.cur_line; state.cur_col = 0; /* FALLTHRU */ \
|
case '\n': ++ state.cur_line; state.cur_col = 0; /* FALLTHRU */ \
|
||||||
case ' ': case '\t': case '\r'
|
case ' ': /* FALLTHRU */ case '\t': /* FALLTHRU */ case '\r'
|
||||||
|
|
||||||
#define string_add(b) \
|
#define string_add(b) \
|
||||||
do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
|
do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
|
||||||
@@ -245,13 +257,13 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
size_t length,
|
size_t length,
|
||||||
char * error_buf)
|
char * error_buf)
|
||||||
{
|
{
|
||||||
json_char error [json_error_max];
|
char error [json_error_max];
|
||||||
const json_char * end;
|
const json_char * end;
|
||||||
json_value * top, * root, * alloc = 0;
|
json_value * top, * root, * alloc = 0;
|
||||||
json_state state = { 0 };
|
json_state state = { 0 };
|
||||||
long flags;
|
long flags;
|
||||||
double num_digits = 0, num_e = 0;
|
int num_digits = 0;
|
||||||
double num_fraction = 0;
|
double num_e = 0, num_fraction = 0;
|
||||||
|
|
||||||
/* Skip UTF-8 BOM
|
/* Skip UTF-8 BOM
|
||||||
*/
|
*/
|
||||||
@@ -274,12 +286,6 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
if (!state.settings.mem_free)
|
if (!state.settings.mem_free)
|
||||||
state.settings.mem_free = default_free;
|
state.settings.mem_free = default_free;
|
||||||
|
|
||||||
memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
|
|
||||||
memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
|
|
||||||
|
|
||||||
state.uint_max -= 8; /* limit of how much can be added before next check */
|
|
||||||
state.ulong_max -= 8;
|
|
||||||
|
|
||||||
for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
|
for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
|
||||||
{
|
{
|
||||||
json_uchar uchar;
|
json_uchar uchar;
|
||||||
@@ -299,11 +305,11 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
if (flags & flag_string)
|
if (flags & flag_string)
|
||||||
{
|
{
|
||||||
if (!b)
|
if (!b)
|
||||||
{ snprintf (error, sizeof(error), "Unexpected EOF in string (at %u:%u)", line_and_col);
|
{ sprintf (error, "%u:%u: Unexpected EOF in string", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_length > state.uint_max)
|
if (string_length > UINT_MAX - 8)
|
||||||
goto e_overflow;
|
goto e_overflow;
|
||||||
|
|
||||||
if (flags & flag_escaped)
|
if (flags & flag_escaped)
|
||||||
@@ -325,7 +331,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
||||||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
||||||
{
|
{
|
||||||
snprintf (error, sizeof(error), "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
sprintf (error, "%u:%u: Invalid character value `%c`", line_and_col, b);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +348,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
||||||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
||||||
{
|
{
|
||||||
snprintf (error, sizeof(error), "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
sprintf (error, "%u:%u: Invalid character value `%c`", line_and_col, b);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,11 +432,12 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
case json_object:
|
case json_object:
|
||||||
|
|
||||||
if (state.first_pass) {
|
if (state.first_pass) {
|
||||||
char *s = (char *) top->u.object.values;
|
json_char **chars = (json_char **) &top->u.object.values;
|
||||||
s += string_length+1;
|
chars[0] += string_length + 1;
|
||||||
top->u.object.values = (void *) s;
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
top->u.object.values [top->u.object.length].name
|
top->u.object.values [top->u.object.length].name
|
||||||
= (json_char *) top->_reserved.object_mem;
|
= (json_char *) top->_reserved.object_mem;
|
||||||
|
|
||||||
@@ -472,7 +479,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
if (flags & flag_block_comment)
|
if (flags & flag_block_comment)
|
||||||
{
|
{
|
||||||
if (!b)
|
if (!b)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected EOF in block comment", line_and_col);
|
{ sprintf (error, "%u:%u: Unexpected EOF in block comment", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,12 +495,12 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
else if (b == '/')
|
else if (b == '/')
|
||||||
{
|
{
|
||||||
if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
|
if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Comment not allowed here", line_and_col);
|
{ sprintf (error, "%u:%u: Comment not allowed here", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++ state.ptr == end)
|
if (++ state.ptr == end)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: EOF unexpected", line_and_col);
|
{ sprintf (error, "%u:%u: EOF unexpected", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,7 +515,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf (error, sizeof(error), "%u:%u: Unexpected `%c` in comment opening sequence", line_and_col, b);
|
sprintf (error, "%u:%u: Unexpected `%c` in comment opening sequence", line_and_col, b);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -526,8 +533,8 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
snprintf (error, sizeof(error), "%u:%u: Trailing garbage: `%c`",
|
sprintf (error, "%u:%u: Trailing garbage: `%c`",
|
||||||
state.cur_line, state.cur_col, b);
|
line_and_col, b);
|
||||||
|
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
};
|
};
|
||||||
@@ -545,7 +552,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
if (top && top->type == json_array)
|
if (top && top->type == json_array)
|
||||||
flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
|
flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
|
||||||
else
|
else
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected ]", line_and_col);
|
{ sprintf (error, "%u:%u: Unexpected `]`", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,8 +568,8 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snprintf (error, sizeof(error), "%u:%u: Expected , before %c",
|
sprintf (error, "%u:%u: Expected `,` before `%c`",
|
||||||
state.cur_line, state.cur_col, b);
|
line_and_col, b);
|
||||||
|
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
@@ -576,8 +583,8 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snprintf (error, sizeof(error), "%u:%u: Expected : before %c",
|
sprintf (error, "%u:%u: Expected `:` before `%c`",
|
||||||
state.cur_line, state.cur_col, b);
|
line_and_col, b);
|
||||||
|
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
@@ -616,7 +623,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
|
|
||||||
if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' ||
|
if ((end - state.ptr) <= 3 || *(++ state.ptr) != 'r' ||
|
||||||
*(++ state.ptr) != 'u' || *(++ state.ptr) != 'e')
|
*(++ state.ptr) != 'u' || *(++ state.ptr) != 'e')
|
||||||
{
|
{
|
||||||
goto e_unknown_value;
|
goto e_unknown_value;
|
||||||
@@ -632,7 +639,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
|
|
||||||
if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' ||
|
if ((end - state.ptr) <= 4 || *(++ state.ptr) != 'a' ||
|
||||||
*(++ state.ptr) != 'l' || *(++ state.ptr) != 's' ||
|
*(++ state.ptr) != 'l' || *(++ state.ptr) != 's' ||
|
||||||
*(++ state.ptr) != 'e')
|
*(++ state.ptr) != 'e')
|
||||||
{
|
{
|
||||||
@@ -647,7 +654,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
|
|
||||||
if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' ||
|
if ((end - state.ptr) <= 3 || *(++ state.ptr) != 'u' ||
|
||||||
*(++ state.ptr) != 'l' || *(++ state.ptr) != 'l')
|
*(++ state.ptr) != 'l' || *(++ state.ptr) != 'l')
|
||||||
{
|
{
|
||||||
goto e_unknown_value;
|
goto e_unknown_value;
|
||||||
@@ -661,14 +668,14 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
if (isdigit (b) || b == '-')
|
if (isdigit ((unsigned char) b) || b == '-')
|
||||||
{
|
{
|
||||||
if (!new_value (&state, &top, &root, &alloc, json_integer))
|
if (!new_value (&state, &top, &root, &alloc, json_integer))
|
||||||
goto e_alloc_failure;
|
goto e_alloc_failure;
|
||||||
|
|
||||||
if (!state.first_pass)
|
if (!state.first_pass)
|
||||||
{
|
{
|
||||||
while (isdigit (b) || b == '+' || b == '-'
|
while (isdigit ((unsigned char) b) || b == '+' || b == '-'
|
||||||
|| b == 'e' || b == 'E' || b == '.')
|
|| b == 'e' || b == 'E' || b == '.')
|
||||||
{
|
{
|
||||||
if ( (++ state.ptr) == end)
|
if ( (++ state.ptr) == end)
|
||||||
@@ -702,7 +709,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected %c when seeking value", line_and_col, b);
|
{ sprintf (error, "%u:%u: Unexpected `%c` when seeking value", line_and_col, b);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -722,7 +729,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
case '"':
|
case '"':
|
||||||
|
|
||||||
if (flags & flag_need_comma)
|
if (flags & flag_need_comma)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Expected , before \"", line_and_col);
|
{ sprintf (error, "%u:%u: Expected `,` before `\"`", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,10 +751,10 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
{
|
{
|
||||||
flags &= ~ flag_need_comma;
|
flags &= ~ flag_need_comma;
|
||||||
break;
|
break;
|
||||||
}
|
} /* FALLTHRU */
|
||||||
/* FALLTHROUGH */
|
|
||||||
default:
|
default:
|
||||||
snprintf (error, sizeof(error), "%u:%u: Unexpected `%c` in object", line_and_col, b);
|
sprintf (error, "%u:%u: Unexpected `%c` in object", line_and_col, b);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -756,7 +763,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
case json_integer:
|
case json_integer:
|
||||||
case json_double:
|
case json_double:
|
||||||
|
|
||||||
if (isdigit (b))
|
if (isdigit ((unsigned char)b))
|
||||||
{
|
{
|
||||||
++ num_digits;
|
++ num_digits;
|
||||||
|
|
||||||
@@ -765,7 +772,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
if (! (flags & flag_num_e))
|
if (! (flags & flag_num_e))
|
||||||
{
|
{
|
||||||
if (flags & flag_num_zero)
|
if (flags & flag_num_zero)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected `0` before `%c`", line_and_col, b);
|
{ sprintf (error, "%u:%u: Unexpected `0` before `%c`", line_and_col, b);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,10 +787,12 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (would_overflow(top->u.integer, b))
|
if (would_overflow(top->u.integer, b))
|
||||||
{ -- num_digits;
|
{
|
||||||
|
json_int_t integer = top->u.integer;
|
||||||
|
-- num_digits;
|
||||||
-- state.ptr;
|
-- state.ptr;
|
||||||
top->type = json_double;
|
top->type = json_double;
|
||||||
top->u.dbl = (double)top->u.integer;
|
top->u.dbl = (double)integer;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,13 +822,15 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
}
|
}
|
||||||
else if (b == '.' && top->type == json_integer)
|
else if (b == '.' && top->type == json_integer)
|
||||||
{
|
{
|
||||||
|
json_int_t integer = top->u.integer;
|
||||||
|
|
||||||
if (!num_digits)
|
if (!num_digits)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Expected digit before `.`", line_and_col);
|
{ sprintf (error, "%u:%u: Expected digit before `.`", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
top->type = json_double;
|
top->type = json_double;
|
||||||
top->u.dbl = (double) top->u.integer;
|
top->u.dbl = (double) integer;
|
||||||
|
|
||||||
flags |= flag_num_got_decimal;
|
flags |= flag_num_got_decimal;
|
||||||
num_digits = 0;
|
num_digits = 0;
|
||||||
@@ -831,7 +842,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
if (top->type == json_double)
|
if (top->type == json_double)
|
||||||
{
|
{
|
||||||
if (!num_digits)
|
if (!num_digits)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Expected digit after `.`", line_and_col);
|
{ sprintf (error, "%u:%u: Expected digit after `.`", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,8 +855,9 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
if (top->type == json_integer)
|
if (top->type == json_integer)
|
||||||
{
|
{
|
||||||
|
json_int_t integer = top->u.integer;
|
||||||
top->type = json_double;
|
top->type = json_double;
|
||||||
top->u.dbl = (double) top->u.integer;
|
top->u.dbl = (double) integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_digits = 0;
|
num_digits = 0;
|
||||||
@@ -857,7 +869,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!num_digits)
|
if (!num_digits)
|
||||||
{ snprintf (error, sizeof(error), "%u:%u: Expected digit after `e`", line_and_col);
|
{ sprintf (error, "%u:%u: Expected digit after `e`", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -926,7 +938,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (++ top->parent->u.array.length) > state.uint_max)
|
if ( (++ top->parent->u.array.length) > UINT_MAX - 8)
|
||||||
goto e_overflow;
|
goto e_overflow;
|
||||||
|
|
||||||
top = top->parent;
|
top = top->parent;
|
||||||
@@ -942,7 +954,7 @@ json_value * json_parse_ex (json_settings * settings,
|
|||||||
|
|
||||||
e_unknown_value:
|
e_unknown_value:
|
||||||
|
|
||||||
snprintf (error, sizeof(error), "%u:%u: Unknown value", line_and_col);
|
sprintf (error, "%u:%u: Unknown value", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
|
|
||||||
e_alloc_failure:
|
e_alloc_failure:
|
||||||
@@ -952,7 +964,7 @@ e_alloc_failure:
|
|||||||
|
|
||||||
e_overflow:
|
e_overflow:
|
||||||
|
|
||||||
snprintf (error, sizeof(error), "%u:%u: Too long (caught overflow)", line_and_col);
|
sprintf (error, "%u:%u: Too long (caught overflow)", line_and_col);
|
||||||
goto e_failed;
|
goto e_failed;
|
||||||
|
|
||||||
e_failed:
|
e_failed:
|
||||||
|
|||||||
36
src/json.h
36
src/json.h
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
/* vim: set et ts=3 sw=3 sts=3 ft=c:
|
/* vim: set et ts=3 sw=3 sts=3 ft=c:
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved.
|
* Copyright (C) 2012-2021 the json-parser authors All rights reserved.
|
||||||
* https://github.com/udp/json-parser
|
* https://github.com/json-parser/json-parser
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -35,15 +36,22 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef json_int_t
|
#ifndef json_int_t
|
||||||
#ifndef _MSC_VER
|
#undef JSON_INT_T_OVERRIDDEN
|
||||||
#include <inttypes.h>
|
#if defined(_MSC_VER)
|
||||||
#define json_int_t int64_t
|
|
||||||
#else
|
|
||||||
#define json_int_t __int64
|
#define json_int_t __int64
|
||||||
|
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__cplusplus) && __cplusplus >= 201103L)
|
||||||
|
/* C99 and C++11 */
|
||||||
|
#include <stdint.h>
|
||||||
|
#define json_int_t int_fast64_t
|
||||||
|
#else
|
||||||
|
/* C89 */
|
||||||
|
#define json_int_t long
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#define JSON_INT_T_OVERRIDDEN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
@@ -56,7 +64,7 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned long max_memory;
|
unsigned long max_memory; /* should be size_t, but would modify the API */
|
||||||
int settings;
|
int settings;
|
||||||
|
|
||||||
/* Custom allocator support (leave null to use malloc/free)
|
/* Custom allocator support (leave null to use malloc/free)
|
||||||
@@ -122,11 +130,11 @@ typedef struct _json_value
|
|||||||
|
|
||||||
json_object_entry * values;
|
json_object_entry * values;
|
||||||
|
|
||||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
#if defined(__cplusplus)
|
||||||
decltype(values) begin () const
|
json_object_entry * begin () const
|
||||||
{ return values;
|
{ return values;
|
||||||
}
|
}
|
||||||
decltype(values) end () const
|
json_object_entry * end () const
|
||||||
{ return values + length;
|
{ return values + length;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -138,11 +146,11 @@ typedef struct _json_value
|
|||||||
unsigned int length;
|
unsigned int length;
|
||||||
struct _json_value ** values;
|
struct _json_value ** values;
|
||||||
|
|
||||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
#if defined(__cplusplus)
|
||||||
decltype(values) begin () const
|
_json_value ** begin () const
|
||||||
{ return values;
|
{ return values;
|
||||||
}
|
}
|
||||||
decltype(values) end () const
|
_json_value ** end () const
|
||||||
{ return values + length;
|
{ return values + length;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
65
src/moon.c
65
src/moon.c
@@ -649,7 +649,7 @@ static int datetime_from_time_t(time_t t)
|
|||||||
|
|
||||||
local = localtime(&t);
|
local = localtime(&t);
|
||||||
|
|
||||||
ans = DSE(local->tm_year + 1900, local->tm_mon, local->tm_mday) * 1440;
|
ans = DSE(local->tm_year + 1900, local->tm_mon, local->tm_mday) * MINUTES_PER_DAY;
|
||||||
ans += local->tm_hour * 60;
|
ans += local->tm_hour * 60;
|
||||||
ans += local->tm_min;
|
ans += local->tm_min;
|
||||||
return ans;
|
return ans;
|
||||||
@@ -720,17 +720,17 @@ void moon_position(double dayOffset, double *ra, double *declination, double *di
|
|||||||
|
|
||||||
double s;
|
double s;
|
||||||
s = w / sqrt(u - v*v);
|
s = w / sqrt(u - v*v);
|
||||||
*ra = l + atan(s / sqrt(1 - s*s)); // Right ascension
|
*ra = l + atan(s / sqrt(1 - s*s)); /* Right ascension */
|
||||||
|
|
||||||
s = v / sqrt(u);
|
s = v / sqrt(u);
|
||||||
*declination = atan(s / sqrt(1 - s*s)); // Declination
|
*declination = atan(s / sqrt(1 - s*s)); /* Declination */
|
||||||
*distance = 60.40974 * sqrt(u); // Distance
|
*distance = 60.40974 * sqrt(u); /* Distance */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search for moonrise / moonset events during an hour */
|
/* Search for moonrise / moonset events during an hour */
|
||||||
static void test_moon_event(int k, double offset_days, struct MoonInfo *moon_info,
|
static void test_moon_event(int k, double offset_days, struct MoonInfo *moon_info,
|
||||||
double latitude, double longitude,
|
double latitude, double longitude,
|
||||||
double ra[], double declination[], double distance[])
|
double const ra[], double declination[], double const distance[])
|
||||||
{
|
{
|
||||||
double ha[3], VHz[3];
|
double ha[3], VHz[3];
|
||||||
double lSideTime;
|
double lSideTime;
|
||||||
@@ -742,21 +742,21 @@ static void test_moon_event(int k, double offset_days, struct MoonInfo *moon_inf
|
|||||||
ha[0] = lSideTime - ra[0] + k*K1;
|
ha[0] = lSideTime - ra[0] + k*K1;
|
||||||
ha[2] = lSideTime - ra[2] + k*K1 + K1;
|
ha[2] = lSideTime - ra[2] + k*K1 + K1;
|
||||||
|
|
||||||
// Hour Angle and declination at half hour.
|
/* Hour Angle and declination at half hour. */
|
||||||
ha[1] = (ha[2] + ha[0])/2;
|
ha[1] = (ha[2] + ha[0])/2;
|
||||||
declination[1] = (declination[2] + declination[0])/2;
|
declination[1] = (declination[2] + declination[0])/2;
|
||||||
|
|
||||||
double s = sin((PI / 180) * latitude);
|
double s = sin((PI / 180) * latitude);
|
||||||
double c = cos((PI / 180) * latitude);
|
double c = cos((PI / 180) * latitude);
|
||||||
|
|
||||||
// refraction + semidiameter at horizon + distance correction
|
/* refraction + semidiameter at horizon + distance correction */
|
||||||
double z = cos((PI / 180) * (90.567 - 41.685 / distance[0]));
|
double z = cos((PI / 180) * (90.567 - 41.685 / distance[0]));
|
||||||
|
|
||||||
VHz[0] = s * sin(declination[0]) + c * cos(declination[0]) * cos(ha[0]) - z;
|
VHz[0] = s * sin(declination[0]) + c * cos(declination[0]) * cos(ha[0]) - z;
|
||||||
VHz[2] = s * sin(declination[2]) + c * cos(declination[2]) * cos(ha[2]) - z;
|
VHz[2] = s * sin(declination[2]) + c * cos(declination[2]) * cos(ha[2]) - z;
|
||||||
|
|
||||||
if (signbit(VHz[0]) == signbit(VHz[2]))
|
if (signbit(VHz[0]) == signbit(VHz[2]))
|
||||||
goto noevent; // No event this hour.
|
goto noevent; /* No event this hour. */
|
||||||
|
|
||||||
VHz[1] = s * sin(declination[1]) + c * cos(declination[1]) * cos(ha[1]) - z;
|
VHz[1] = s * sin(declination[1]) + c * cos(declination[1]) * cos(ha[1]) - z;
|
||||||
|
|
||||||
@@ -766,21 +766,23 @@ static void test_moon_event(int k, double offset_days, struct MoonInfo *moon_inf
|
|||||||
d = b * b - 4 * a * VHz[0];
|
d = b * b - 4 * a * VHz[0];
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
goto noevent; // No event this hour.
|
goto noevent; /* No event this hour. */
|
||||||
|
|
||||||
d = sqrt(d);
|
d = sqrt(d);
|
||||||
e = (-b + d) / (2 * a);
|
e = (-b + d) / (2 * a);
|
||||||
if ((e < 0) || (e > 1))
|
if ((e < 0) || (e > 1))
|
||||||
e = (-b - d) / (2 * a);
|
e = (-b - d) / (2 * a);
|
||||||
time = k + e + 1 / 120; // Time since k=0 of event (in hours).
|
time = k + e + 1 / 120; /* Time since k=0 of event (in hours). */
|
||||||
|
|
||||||
// The time we started searching + the time from the start of the search to the
|
|
||||||
// event is the time of the event. Add (time since k=0) - window/2 hours.
|
/* The time we started searching + the time from the start of the
|
||||||
|
search to the event is the time of the event. Add (time since
|
||||||
|
k=0) - window/2 hours. */
|
||||||
time_t eventTime;
|
time_t eventTime;
|
||||||
eventTime = moon_info->queryTime + (time - MR_WINDOW / 2) *60 *60;
|
eventTime = moon_info->queryTime + (time - MR_WINDOW / 2) *60 *60;
|
||||||
|
|
||||||
double hz, nz, dz, az;
|
double hz, nz, dz, az;
|
||||||
hz = ha[0] + e * (ha[2] - ha[0]); // Azimuth of the moon at the event.
|
hz = ha[0] + e * (ha[2] - ha[0]); /* Azimuth of the moon at the event. */
|
||||||
nz = -cos(declination[1]) * sin(hz);
|
nz = -cos(declination[1]) * sin(hz);
|
||||||
dz = c * sin(declination[1]) - s * cos(declination[1]) * cos(hz);
|
dz = c * sin(declination[1]) - s * cos(declination[1]) * cos(hz);
|
||||||
az = atan2(nz, dz) * (180 / PI);
|
az = atan2(nz, dz) * (180 / PI);
|
||||||
@@ -788,23 +790,24 @@ static void test_moon_event(int k, double offset_days, struct MoonInfo *moon_inf
|
|||||||
az += 360;
|
az += 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no previously recorded event of this type, save this event.
|
/* If there is no previously recorded event of this type, save this event.
|
||||||
//
|
|
||||||
// If this event is previous to queryTime, and is the nearest event to queryTime
|
If this event is previous to queryTime, and is the nearest event
|
||||||
// of events of its type previous to queryType, save this event, replacing the
|
to queryTime of events of its type previous to queryType, save
|
||||||
// previously recorded event of its type. Events subsequent to queryTime are
|
this event, replacing the previously recorded event of its type.
|
||||||
// treated similarly, although since events are tested in chronological order
|
Events subsequent to queryTime are treated similarly, although
|
||||||
// no replacements will occur as successive events will be further from
|
since events are tested in chronological order no replacements
|
||||||
// queryTime.
|
will occur as successive events will be further from queryTime.
|
||||||
//
|
|
||||||
// If this event is subsequent to queryTime and there is an event of its type
|
If this event is subsequent to queryTime and there is an event of
|
||||||
// previous to queryTime, then there is an event of the other type between the
|
its type previous to queryTime, then there is an event of the
|
||||||
// two events of this event's type. If the event of the other type is
|
other type between the two events of this event's type. If the
|
||||||
// previous to queryTime, then it is the nearest event to queryTime that is
|
event of the other type is previous to queryTime, then it is the
|
||||||
// previous to queryTime. In this case save the current event, replacing
|
nearest event to queryTime that is previous to queryTime. In
|
||||||
// the previously recorded event of its type. Otherwise discard the current
|
this case save the current event, replacing the previously
|
||||||
// event.
|
recorded event of its type. Otherwise discard the current
|
||||||
//
|
event. */
|
||||||
|
|
||||||
if ((VHz[0] < 0) && (VHz[2] > 0)) {
|
if ((VHz[0] < 0) && (VHz[2] > 0)) {
|
||||||
if (!moon_info->hasRise ||
|
if (!moon_info->hasRise ||
|
||||||
((moon_info->riseTime < moon_info->queryTime) == (eventTime < moon_info->queryTime) &&
|
((moon_info->riseTime < moon_info->queryTime) == (eventTime < moon_info->queryTime) &&
|
||||||
@@ -831,7 +834,7 @@ static void test_moon_event(int k, double offset_days, struct MoonInfo *moon_inf
|
|||||||
}
|
}
|
||||||
|
|
||||||
noevent:
|
noevent:
|
||||||
// There are obscure cases in the polar regions that require extra logic.
|
/* There are obscure cases in the polar regions that require extra logic. */
|
||||||
if (!moon_info->hasRise && !moon_info->hasSet)
|
if (!moon_info->hasRise && !moon_info->hasSet)
|
||||||
moon_info->isVisible = !signbit(VHz[2]);
|
moon_info->isVisible = !signbit(VHz[2]);
|
||||||
else if (moon_info->hasRise && !moon_info->hasSet)
|
else if (moon_info->hasRise && !moon_info->hasSet)
|
||||||
|
|||||||
@@ -862,7 +862,7 @@ static SysVar SysVarArr[] = {
|
|||||||
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 },
|
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 },
|
||||||
{"DefaultDelta", 1, INT_TYPE, &DefaultDelta, 0, 10000 },
|
{"DefaultDelta", 1, INT_TYPE, &DefaultDelta, 0, 10000 },
|
||||||
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 },
|
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 },
|
||||||
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440 },
|
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, MINUTES_PER_DAY },
|
||||||
{"DeltaOverride", 0, INT_TYPE, &DeltaOverride, 0, 0 },
|
{"DeltaOverride", 0, INT_TYPE, &DeltaOverride, 0, 0 },
|
||||||
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
|
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
|
||||||
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
|
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
|
||||||
@@ -898,7 +898,7 @@ static SysVar SysVarArr[] = {
|
|||||||
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0 },
|
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0 },
|
||||||
{"March", 1, TRANS_TYPE, "March", 0, 0 },
|
{"March", 1, TRANS_TYPE, "March", 0, 0 },
|
||||||
{"MaxFullOmits", 0, CONST_INT_TYPE, NULL, MAX_FULL_OMITS, 0},
|
{"MaxFullOmits", 0, CONST_INT_TYPE, NULL, MAX_FULL_OMITS, 0},
|
||||||
{"MaxLateMinutes", 1, INT_TYPE, &MaxLateMinutes, 0, 1440 },
|
{"MaxLateMinutes", 1, INT_TYPE, &MaxLateMinutes, 0, MINUTES_PER_DAY },
|
||||||
{"MaxPartialOmits",0, CONST_INT_TYPE, NULL, MAX_PARTIAL_OMITS, 0},
|
{"MaxPartialOmits",0, CONST_INT_TYPE, NULL, MAX_PARTIAL_OMITS, 0},
|
||||||
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
|
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
|
||||||
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY },
|
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY },
|
||||||
|
|||||||
@@ -709,6 +709,12 @@ for i in ../include/lang/??.rem ; do
|
|||||||
../src/remind -r -q "-ii=\"$i\"" ../tests/tstlang.rem 1 Feb 2024 13:34 >> ../tests/test.out 2>&1
|
../src/remind -r -q "-ii=\"$i\"" ../tests/tstlang.rem 1 Feb 2024 13:34 >> ../tests/test.out 2>&1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Fix for $DefaultColor bug with remind -s
|
||||||
|
../src/remind -s - 1 Feb 2024 >> ../tests/test.out 2>&1 <<'EOF'
|
||||||
|
SET $DefaultColor "255 0 0"
|
||||||
|
REM Wed MSG Wookie
|
||||||
|
EOF
|
||||||
|
|
||||||
# Make sure all the include files are ok
|
# Make sure all the include files are ok
|
||||||
find ../include -type f -name '*.rem' | while read x; do ../src/remind -n $x 1 Jan 2024 2>>../tests/test.out 1>/dev/null; done
|
find ../include -type f -name '*.rem' | while read x; do ../src/remind -n $x 1 Jan 2024 2>>../tests/test.out 1>/dev/null; done
|
||||||
cmp -s ../tests/test.out ../tests/test.cmp
|
cmp -s ../tests/test.out ../tests/test.cmp
|
||||||
|
|||||||
@@ -1047,7 +1047,7 @@ set a057 value("a05"+"6")
|
|||||||
"a05" + "6" => "a056"
|
"a05" + "6" => "a056"
|
||||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||||
set a058 version()
|
set a058 version()
|
||||||
version() => "05.03.05"
|
version() => "05.03.06"
|
||||||
set a059 wkday(today())
|
set a059 wkday(today())
|
||||||
today() => 1991-02-16
|
today() => 1991-02-16
|
||||||
wkday(1991-02-16) => "Saturday"
|
wkday(1991-02-16) => "Saturday"
|
||||||
@@ -2611,7 +2611,7 @@ a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
|||||||
a007 "1991-02-16"
|
a007 "1991-02-16"
|
||||||
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||||
a008 "11:44"
|
a008 "11:44"
|
||||||
a058 "05.03.05"
|
a058 "05.03.06"
|
||||||
a059 "Saturday"
|
a059 "Saturday"
|
||||||
a010 12
|
a010 12
|
||||||
a060 6
|
a060 6
|
||||||
@@ -5632,8 +5632,8 @@ REM SATISFY ""
|
|||||||
REM SATISFY [version() > "01.00.00"]
|
REM SATISFY [version() > "01.00.00"]
|
||||||
../tests/test.rem(1050): SATISFY: expression has no reference to trigdate() or $T...
|
../tests/test.rem(1050): SATISFY: expression has no reference to trigdate() or $T...
|
||||||
../tests/test.rem(1050): Trig = Saturday, 16 February, 1991
|
../tests/test.rem(1050): Trig = Saturday, 16 February, 1991
|
||||||
version() => "05.03.05"
|
version() => "05.03.06"
|
||||||
"05.03.05" > "01.00.00" => 1
|
"05.03.06" > "01.00.00" => 1
|
||||||
../tests/test.rem(1050): Trig(satisfied) = Saturday, 16 February, 1991
|
../tests/test.rem(1050): Trig(satisfied) = Saturday, 16 February, 1991
|
||||||
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
|
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
|
||||||
../tests/test.rem(1051): SATISFY: expression has no reference to trigdate() or $T...
|
../tests/test.rem(1051): SATISFY: expression has no reference to trigdate() or $T...
|
||||||
@@ -23201,7 +23201,7 @@ SECURITY: Won't read world-writable file or directory!
|
|||||||
Error reading include_dir/ww: Can't open file
|
Error reading include_dir/ww: Can't open file
|
||||||
SECURITY: Won't read world-writable file or directory!
|
SECURITY: Won't read world-writable file or directory!
|
||||||
Error reading include_dir/ww: No files matching *.rem
|
Error reading include_dir/ww: No files matching *.rem
|
||||||
05.03.05
|
05.03.06
|
||||||
Enabling test mode: This is meant for the acceptance test.
|
Enabling test mode: This is meant for the acceptance test.
|
||||||
Do not use --test in production.
|
Do not use --test in production.
|
||||||
In test mode, the system time is fixed at 2025-01-06@19:00
|
In test mode, the system time is fixed at 2025-01-06@19:00
|
||||||
@@ -38252,3 +38252,7 @@ $Thursday is Joi
|
|||||||
$Friday is Vineri
|
$Friday is Vineri
|
||||||
$Saturday is Sâmbătă
|
$Saturday is Sâmbătă
|
||||||
$Sunday is Duminică
|
$Sunday is Duminică
|
||||||
|
2024/02/07 COLOR * * * 255 0 0 Wookie
|
||||||
|
2024/02/14 COLOR * * * 255 0 0 Wookie
|
||||||
|
2024/02/21 COLOR * * * 255 0 0 Wookie
|
||||||
|
2024/02/28 COLOR * * * 255 0 0 Wookie
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
echo "Unconfiguring Remind..."
|
|
||||||
echo rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h www/Makefile rem2html/Makefile
|
|
||||||
rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h www/Makefile rem2html/Makefile
|
|
||||||
exit 0
|
|
||||||
Reference in New Issue
Block a user