summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2015-06-17 23:14:26 -0500
committerNicolas Williams <nico@cryptonector.com>2015-06-17 23:14:26 -0500
commit164b877bfaa0531c0e3fe150d2a5018a769883d0 (patch)
treeaa8c5cd17c62fcf4a9c391012b90efb6b6ccd27d
parentb9c2a326bae085a27b5bd01ca15c3c42c7b726a3 (diff)
Add isnormal and related, rename *inf
-rw-r--r--builtin.c23
-rw-r--r--docs/content/3.manual/manual.yml26
2 files changed, 35 insertions, 14 deletions
diff --git a/builtin.c b/builtin.c
index 8fb04622..a845db60 100644
--- a/builtin.c
+++ b/builtin.c
@@ -832,7 +832,7 @@ static jv f_type(jq_state *jq, jv input) {
return out;
}
-static jv f_isinf(jq_state *jq, jv input) {
+static jv f_isinfinite(jq_state *jq, jv input) {
jv_kind k = jv_get_kind(input);
if (k != JV_KIND_NUMBER) {
jv_free(input);
@@ -854,7 +854,18 @@ static jv f_isnan(jq_state *jq, jv input) {
return isnan(n) ? jv_true() : jv_false();
}
-static jv f_inf(jq_state *jq, jv input) {
+static jv f_isnormal(jq_state *jq, jv input) {
+ jv_kind k = jv_get_kind(input);
+ if (k != JV_KIND_NUMBER) {
+ jv_free(input);
+ return jv_false();
+ }
+ double n = jv_number_value(input);
+ jv_free(input);
+ return isnormal(n) ? jv_true() : jv_false();
+}
+
+static jv f_infinite(jq_state *jq, jv input) {
jv_free(input);
return jv_number(INFINITY);
}
@@ -1216,9 +1227,10 @@ static const struct cfunction function_list[] = {
{(cfunction_ptr)f_contains, "contains", 2},
{(cfunction_ptr)f_length, "length", 1},
{(cfunction_ptr)f_type, "type", 1},
- {(cfunction_ptr)f_isinf, "isinf", 1},
+ {(cfunction_ptr)f_isinfinite, "isinfinite", 1},
{(cfunction_ptr)f_isnan, "isnan", 1},
- {(cfunction_ptr)f_inf, "inf", 1},
+ {(cfunction_ptr)f_isnormal, "isnormal", 1},
+ {(cfunction_ptr)f_infinite, "infinite", 1},
{(cfunction_ptr)f_nan, "nan", 1},
{(cfunction_ptr)f_sort, "sort", 1},
{(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2},
@@ -1340,11 +1352,14 @@ static const char* const jq_builtins[] = {
" if .|not then . else empty end)] | length == 0;",
"def all(condition): all(.[]; condition);",
"def all: all(.);",
+ "def isfinite: type == \"number\" and (isinfinite | not);",
"def arrays: select(type == \"array\");",
"def objects: select(type == \"object\");",
"def iterables: arrays, objects;",
"def booleans: select(type == \"boolean\");",
"def numbers: select(type == \"number\");",
+ "def normals: select(isnormal);",
+ "def finites: select(isinfinite|not);",
"def strings: select(type == \"string\");",
"def nulls: select(type == \"null\");",
"def values: select(. != null);",
diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml
index 8a3e20aa..92728d12 100644
--- a/docs/content/3.manual/manual.yml
+++ b/docs/content/3.manual/manual.yml
@@ -794,12 +794,13 @@ sections:
output: ['{"id": "second", "val": 2}']
- - title: "`arrays`, `objects`, `iterables`, `booleans`, `numbers`, `strings`, `nulls`, `values`, `scalars`"
+ - title: "`arrays`, `objects`, `iterables`, `booleans`, `numbers`, `normals`, `finites`, `strings`, `nulls`, `values`, `scalars`"
body: |
These built-ins select only inputs that are arrays, objects,
- iterables (arrays or objects), booleans, numbers, strings,
- null, non-null values, and non-iterables, respectively.
+ iterables (arrays or objects), booleans, numbers, normal
+ numbers, finite numbers, strings, null, non-null values, and
+ non-iterables, respectively.
examples:
- program: '.[]|numbers'
@@ -1076,22 +1077,27 @@ sections:
input: '[0, false, [], {}, null, "hello"]'
output: ['["number", "boolean", "array", "object", "null", "string"]']
- - title: "`inf`, `nan`, `isinf`, `isnan`"
+ - title: "`infinite`, `nan`, `isinfinite`, `isnan`, `isfinite`, `isnormal`"
body: |
Some arithmetic operations can yield infinities and "not a
- number" (NaN) values. The `isinf` builtin returns `true` if
- its input is infinite. The `isnan` builtin returns `true` if
- its input is a NaN. The `inf` builtin returns a positive
- infinite value. The `nan` builtin returns a NaN.
+ number" (NaN) values. The `isinfinite` builtin returns `true`
+ if its input is infinite. The `isnan` builtin returns `true`
+ if its input is a NaN. The `infinite` builtin returns a
+ positive infinite value. The `nan` builtin returns a NaN.
+ The `isnormal` builtin returns true if its input is a normal
+ number.
Note that division by zero raises an error.
+ Currently most arithmetic operations operating on infinities,
+ NaNs, and sub-normals do not raise errors.
+
examples:
- - program: '.[] | (inf * .) < 0'
+ - program: '.[] | (infinite * .) < 0'
input: '[-1, 1]'
output: ['true', 'false']
- - program: 'inf, nan | type'
+ - program: 'infinite, nan | type'
input: 'null'
output: ['"number"']
: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<?php
script('news', 'admin/Admin');
style('news', 'admin');
?>

<div class="section" id="news">
    <h2>News</h2>
    <div class="form-line">
        <p><input type="checkbox" name="news-use-cron-updates"
               <?php if ($_['useCronUpdates']) p('checked'); ?>>
            <label for="news-use-cron-updates">
                <?php p($l->t('Use system cron for updates')); ?>
            </label>
        </p>
        <p>
            <em><?php p($l->t(
                'Disable this if you run a custom updater such as the Python ' .
                'updater included in the app.'
            )); ?></em>
        </p>
    </div>
    <div class="form-line">
        <p>
            <label for="news-auto-purge-minimum-interval">
                <?php p($l->t('Purge interval')); ?></p>
            </label>
        <p>
            <em>
            <?php p($l->t(
                'Minimum amount of seconds after deleted feeds and folders ' .
                'are removed from the database; values below 60 seconds are ' .
                'ignored.'
            )); ?></em>
        </p>
        <p><input type="text" name="news-auto-purge-minimum-interval"
               value="<?php p($_['autoPurgeMinimumInterval']); ?>"></p>
    </div>
    <div class="form-line">
        <p>
            <label for="news-auto-purge-count">
                <?php p($l->t('Maximum read count per feed')); ?>
            </label>
        </p>
        <p>
            <em>
            <?php p($l->t(
                'Defines the maximum amount of articles that can be read per ' .
                "feed which won't be deleted by the cleanup job; ".
                'if old articles reappear after being read, increase ' .
                'this value; negative values such as -1 will turn this ' .
                'feature off.'
            )); ?></em>
        </p>
        <p><input type="text" name="news-auto-purge-count"
               value="<?php p($_['autoPurgeCount']); ?>"></p>
    </div>
    <div class="form-line">
        <p>
            <label for="news-max-redirects">
                <?php p($l->t('Maximum redirects')); ?>
            </label>
        </p>
        <p>
            <em>
                <?php p($l->t(
                    'How many redirects the feed fetcher should follow.'
                )); ?>
            </em>
        </p>
        <p><input type="text" name="news-max-redirects"
               value="<?php p($_['maxRedirects']); ?>"></p>
    </div>
    <div class="form-line">
        <p>
            <label for="news-feed-fetcher-timeout">
                <?php p($l->t('Feed fetcher timeout')); ?>
            </label>
        </p>
        <p>
            <em>
            <?php p($l->t(
                'Maximum number of seconds to wait for an RSS or Atom feed ' .
                'to load; if it takes longer the update will be aborted.'
            )); ?></em>
        </p>
        <p><input type="text" name="news-feed-fetcher-timeout"
               value="<?php p($_['feedFetcherTimeout']); ?>"></p>
    </div>
    <div class="form-line">
        <p>
            <label for="news-explore-url">
                <?php p($l->t('Explore Service URL')); ?>
            </label>
        </p>
        <p>
            <em>
                <?php p($l->t(
                    'If given, this service\'s URL will be queried for ' .
                    'displaying the feeds in the explore feed section. To ' .
                    'fall back to the built in explore service, leave this ' .
                    'input empty.'
                )); ?>
            </em>
            <a href="https://github.com/nextcloud/news/tree/master/docs/explore"><?php p($l->t(
                'For more information check the wiki.'
            )); ?></a>
        </p>
        <p><input type="text" name="news-explore-url"
               value="<?php p($_['exploreUrl']); ?>"></p>
    </div>
    <div class="form-line">
        <p>
            <label for="news-updater-interval">
                <?php p($l->t('Update interval')); ?>
            </label>
        </p>
        <p>
            <em>
                <?php p($l->t(
                    'Interval in seconds in which the feeds will be updated.'
                )); ?>
            </em>
            <a href="https://github.com/nextcloud/news/tree/master/docs/updateInterval"><?php p($l->t(
                'For more information check the wiki.'
            )); ?></a>
        </p>
        <p><input type="text" name="news-update-interval"
               value="<?php p($_['updateInterval']); ?>"></p>
    </div>
    <div id="news-saved-message">
        <span class="msg success"><?php p($l->t('Saved')); ?></span>
    </div>
</div>