@yuneta/gobj-js 7.25.2 → 7.25.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3606,10 +3606,13 @@ var gobjJs = (function(exports) {
3606
3606
  }
3607
3607
  /************************************************************
3608
3608
  * As the C kw_get_bool(): a boolean found is the answer, and
3609
- * anything else gives the default back -- unless KW_WILD_NUMBER
3610
- * asks to read a number (0 is false), a string ("true"/"false"
3611
- * in any case, else its integer) or null (false). Before gobj-js
3612
- * 7.25.2 the value went through Boolean(), so "false" was TRUE.
3609
+ * anything else gives the default back, LOGGED ("path MUST BE a
3610
+ * json boolean", required or not) -- unless KW_WILD_NUMBER asks
3611
+ * to read a number (0 is false), a string ("true"/"false" in any
3612
+ * case, else its integer) or null (false); a list or a dict is
3613
+ * then false, logged too. Before gobj-js 7.25.2 the value went
3614
+ * through Boolean(), so "false" was TRUE; before 7.25.3 a value
3615
+ * of the wrong type gave the default back in silence.
3613
3616
  ************************************************************/
3614
3617
  function kw_get_bool(gobj, kw, path, default_value, flag) {
3615
3618
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -3637,18 +3640,47 @@ var gobjJs = (function(exports) {
3637
3640
  else if (b.toLowerCase() === "false") value = false;
3638
3641
  else value = (parseInt(b) || 0) !== 0;
3639
3642
  } else if (wild && b === null) value = false;
3640
- else {
3641
- if (required) {
3642
- log_error(`${gobj_short_name(gobj)}: path value MUST BE a boolean: ${path}`);
3643
- trace_msg(kw);
3644
- }
3643
+ else if (wild) {
3644
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3645
+ trace_json(kw);
3646
+ return false;
3647
+ } else {
3648
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json boolean: '${path}'`);
3649
+ trace_json(kw);
3645
3650
  return Boolean(default_value);
3646
3651
  }
3647
3652
  if (extract) kw_delete(gobj, kw, path);
3648
3653
  return value;
3649
3654
  }
3650
3655
  /************************************************************
3651
- *
3656
+ * The integer at the start of a string, as C's strtoll(s, 0, 0)
3657
+ * reads it: leading spaces, a sign, then "0x" for hex, "0" for
3658
+ * octal, else decimal, up to the first character that is not a
3659
+ * digit of that base. 0 when there is no digit.
3660
+ ************************************************************/
3661
+ function strtoll_base0(s) {
3662
+ const m = /^\s*([+-]?)(0[xX][0-9a-fA-F]+|0[0-7]*|[1-9][0-9]*)/.exec(s);
3663
+ if (!m) return 0;
3664
+ let digits = m[2];
3665
+ let value;
3666
+ if (digits.length > 1 && (digits[1] === "x" || digits[1] === "X")) value = parseInt(digits.substring(2), 16);
3667
+ else if (digits[0] === "0") value = parseInt(digits, 8);
3668
+ else value = parseInt(digits, 10);
3669
+ return m[1] === "-" ? -value : value;
3670
+ }
3671
+ /************************************************************
3672
+ * As the C kw_get_int(): a number found is the answer,
3673
+ * truncated toward zero as C casts a real, and anything else
3674
+ * gives the default back (as an integer), LOGGED ("path MUST BE
3675
+ * a json integer", required or not) -- unless KW_WILD_NUMBER
3676
+ * asks to read a boolean (1/0), a string (as strtoll() with base
3677
+ * 0: "0x1F" is 31, "017" is 15, "12abc" is 12, "abc" is 0) or
3678
+ * null (0); a list or a dict is then 0, logged too. KW_EXTRACT
3679
+ * takes out only a value the reader answers with.
3680
+ * Before gobj-js 7.25.4 KW_EXTRACT deleted the value before its
3681
+ * type was looked at, a value of another type was logged only
3682
+ * with KW_REQUIRED, KW_WILD_NUMBER was ignored, and a number went
3683
+ * through parseInt(), which reads it as a string: 1e-7 gave 1.
3652
3684
  ************************************************************/
3653
3685
  function kw_get_int(gobj, kw, path, default_value, flag) {
3654
3686
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -3656,6 +3688,7 @@ var gobjJs = (function(exports) {
3656
3688
  const required = flag && flag & kw_flag_t.KW_REQUIRED;
3657
3689
  const create = flag && flag & kw_flag_t.KW_CREATE;
3658
3690
  const extract = flag && flag & kw_flag_t.KW_EXTRACT;
3691
+ const wild = flag && flag & kw_flag_t.KW_WILD_NUMBER;
3659
3692
  if (v === void 0) {
3660
3693
  if (create) {
3661
3694
  let v = parseInt(default_value);
@@ -3667,18 +3700,34 @@ var gobjJs = (function(exports) {
3667
3700
  }
3668
3701
  return parseInt(default_value);
3669
3702
  }
3670
- if (extract) kw_delete(gobj, kw, path);
3671
- if (!is_number(v)) {
3672
- if (required) {
3673
- log_error(`path value MUST BE a number: ${path}`);
3674
- trace_msg(kw);
3675
- }
3703
+ let value;
3704
+ if (is_number(v)) value = Math.trunc(v);
3705
+ else if (!wild) {
3706
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json integer: '${path}'`);
3707
+ trace_json(kw);
3676
3708
  return parseInt(default_value);
3709
+ } else if (is_boolean(v)) value = v ? 1 : 0;
3710
+ else if (is_string(v)) value = strtoll_base0(v);
3711
+ else if (v === null) value = 0;
3712
+ else {
3713
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3714
+ trace_json(kw);
3715
+ return 0;
3677
3716
  }
3678
- return parseInt(v);
3717
+ if (extract) kw_delete(gobj, kw, path);
3718
+ return value;
3679
3719
  }
3680
3720
  /************************************************************
3681
- *
3721
+ * As the C kw_get_real(): a number found is the answer, and
3722
+ * anything else gives the default back (as a number), LOGGED
3723
+ * ("path MUST BE a json real", required or not) -- unless
3724
+ * KW_WILD_NUMBER asks to read a boolean (1/0), a string (as
3725
+ * parseFloat() reads it, 0 when it does not start with a number)
3726
+ * or null (0); a list or a dict is then 0, logged too.
3727
+ * KW_EXTRACT takes out only a value the reader answers with.
3728
+ * Before gobj-js 7.25.4 KW_EXTRACT deleted the value before its
3729
+ * type was looked at, a value of another type was logged only
3730
+ * with KW_REQUIRED, and KW_WILD_NUMBER was ignored.
3682
3731
  ************************************************************/
3683
3732
  function kw_get_real(gobj, kw, path, default_value, flag) {
3684
3733
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -3686,6 +3735,7 @@ var gobjJs = (function(exports) {
3686
3735
  const required = flag && flag & kw_flag_t.KW_REQUIRED;
3687
3736
  const create = flag && flag & kw_flag_t.KW_CREATE;
3688
3737
  const extract = flag && flag & kw_flag_t.KW_EXTRACT;
3738
+ const wild = flag && flag & kw_flag_t.KW_WILD_NUMBER;
3689
3739
  if (v === void 0) {
3690
3740
  if (create) {
3691
3741
  let v = Number(default_value);
@@ -3697,15 +3747,24 @@ var gobjJs = (function(exports) {
3697
3747
  }
3698
3748
  return Number(default_value);
3699
3749
  }
3700
- if (extract) kw_delete(gobj, kw, path);
3701
- if (!is_number(v)) {
3702
- if (required) {
3703
- log_error(`path value MUST BE a number: ${path}`);
3704
- trace_msg(kw);
3705
- }
3750
+ let value;
3751
+ if (is_number(v)) value = v;
3752
+ else if (!wild) {
3753
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json real: '${path}'`);
3754
+ trace_json(kw);
3706
3755
  return Number(default_value);
3756
+ } else if (is_boolean(v)) value = v ? 1 : 0;
3757
+ else if (is_string(v)) {
3758
+ value = parseFloat(v);
3759
+ if (Number.isNaN(value)) value = 0;
3760
+ } else if (v === null) value = 0;
3761
+ else {
3762
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3763
+ trace_json(kw);
3764
+ return 0;
3707
3765
  }
3708
- return Number(v);
3766
+ if (extract) kw_delete(gobj, kw, path);
3767
+ return value;
3709
3768
  }
3710
3769
  /************************************************************
3711
3770
  * The default comes back AS GIVEN, as in the C kw_get_str()
@@ -3714,6 +3773,11 @@ var gobjJs = (function(exports) {
3714
3773
  * TRUE: an `if(value)` on the answer took an absent key for a
3715
3774
  * present one. KW_CREATE stores a string default, and null for
3716
3775
  * any other, as C stores json_null() for a NULL default.
3776
+ * KW_EXTRACT takes out only a string (before gobj-js 7.25.4 it
3777
+ * deleted any value, and a value that was not a string was lost).
3778
+ * C refuses to extract a string at all ("Cannot extract a
3779
+ * string": its answer would point into the freed json); a JS
3780
+ * string outlives the kw, so here it is taken out.
3717
3781
  ************************************************************/
3718
3782
  function kw_get_str(gobj, kw, path, default_value, flag) {
3719
3783
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -3731,7 +3795,6 @@ var gobjJs = (function(exports) {
3731
3795
  }
3732
3796
  return default_value;
3733
3797
  }
3734
- if (extract) kw_delete(gobj, kw, path);
3735
3798
  if (!is_string(v)) {
3736
3799
  if (required) {
3737
3800
  log_error(`${gobj_short_name(gobj)}: path value MUST BE a string: ${path}`);
@@ -3739,6 +3802,7 @@ var gobjJs = (function(exports) {
3739
3802
  }
3740
3803
  return default_value;
3741
3804
  }
3805
+ if (extract) kw_delete(gobj, kw, path);
3742
3806
  return v;
3743
3807
  }
3744
3808
  /************************************************************