@yuneta/gobj-js 7.25.3 → 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.
@@ -3651,7 +3651,34 @@ function kw_get_bool(gobj, kw, path, default_value, flag) {
3651
3651
  return value;
3652
3652
  }
3653
3653
  /************************************************************
3654
- *
3654
+ * The integer at the start of a string, as C's strtoll(s, 0, 0)
3655
+ * reads it: leading spaces, a sign, then "0x" for hex, "0" for
3656
+ * octal, else decimal, up to the first character that is not a
3657
+ * digit of that base. 0 when there is no digit.
3658
+ ************************************************************/
3659
+ function strtoll_base0(s) {
3660
+ const m = /^\s*([+-]?)(0[xX][0-9a-fA-F]+|0[0-7]*|[1-9][0-9]*)/.exec(s);
3661
+ if (!m) return 0;
3662
+ let digits = m[2];
3663
+ let value;
3664
+ if (digits.length > 1 && (digits[1] === "x" || digits[1] === "X")) value = parseInt(digits.substring(2), 16);
3665
+ else if (digits[0] === "0") value = parseInt(digits, 8);
3666
+ else value = parseInt(digits, 10);
3667
+ return m[1] === "-" ? -value : value;
3668
+ }
3669
+ /************************************************************
3670
+ * As the C kw_get_int(): a number found is the answer,
3671
+ * truncated toward zero as C casts a real, and anything else
3672
+ * gives the default back (as an integer), LOGGED ("path MUST BE
3673
+ * a json integer", required or not) -- unless KW_WILD_NUMBER
3674
+ * asks to read a boolean (1/0), a string (as strtoll() with base
3675
+ * 0: "0x1F" is 31, "017" is 15, "12abc" is 12, "abc" is 0) or
3676
+ * null (0); a list or a dict is then 0, logged too. KW_EXTRACT
3677
+ * takes out only a value the reader answers with.
3678
+ * Before gobj-js 7.25.4 KW_EXTRACT deleted the value before its
3679
+ * type was looked at, a value of another type was logged only
3680
+ * with KW_REQUIRED, KW_WILD_NUMBER was ignored, and a number went
3681
+ * through parseInt(), which reads it as a string: 1e-7 gave 1.
3655
3682
  ************************************************************/
3656
3683
  function kw_get_int(gobj, kw, path, default_value, flag) {
3657
3684
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -3659,6 +3686,7 @@ function kw_get_int(gobj, kw, path, default_value, flag) {
3659
3686
  const required = flag && flag & kw_flag_t.KW_REQUIRED;
3660
3687
  const create = flag && flag & kw_flag_t.KW_CREATE;
3661
3688
  const extract = flag && flag & kw_flag_t.KW_EXTRACT;
3689
+ const wild = flag && flag & kw_flag_t.KW_WILD_NUMBER;
3662
3690
  if (v === void 0) {
3663
3691
  if (create) {
3664
3692
  let v = parseInt(default_value);
@@ -3670,18 +3698,34 @@ function kw_get_int(gobj, kw, path, default_value, flag) {
3670
3698
  }
3671
3699
  return parseInt(default_value);
3672
3700
  }
3673
- if (extract) kw_delete(gobj, kw, path);
3674
- if (!is_number(v)) {
3675
- if (required) {
3676
- log_error(`path value MUST BE a number: ${path}`);
3677
- trace_msg(kw);
3678
- }
3701
+ let value;
3702
+ if (is_number(v)) value = Math.trunc(v);
3703
+ else if (!wild) {
3704
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json integer: '${path}'`);
3705
+ trace_json(kw);
3679
3706
  return parseInt(default_value);
3707
+ } else if (is_boolean(v)) value = v ? 1 : 0;
3708
+ else if (is_string(v)) value = strtoll_base0(v);
3709
+ else if (v === null) value = 0;
3710
+ else {
3711
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3712
+ trace_json(kw);
3713
+ return 0;
3680
3714
  }
3681
- return parseInt(v);
3715
+ if (extract) kw_delete(gobj, kw, path);
3716
+ return value;
3682
3717
  }
3683
3718
  /************************************************************
3684
- *
3719
+ * As the C kw_get_real(): a number found is the answer, and
3720
+ * anything else gives the default back (as a number), LOGGED
3721
+ * ("path MUST BE a json real", required or not) -- unless
3722
+ * KW_WILD_NUMBER asks to read a boolean (1/0), a string (as
3723
+ * parseFloat() reads it, 0 when it does not start with a number)
3724
+ * or null (0); a list or a dict is then 0, logged too.
3725
+ * KW_EXTRACT takes out only a value the reader answers with.
3726
+ * Before gobj-js 7.25.4 KW_EXTRACT deleted the value before its
3727
+ * type was looked at, a value of another type was logged only
3728
+ * with KW_REQUIRED, and KW_WILD_NUMBER was ignored.
3685
3729
  ************************************************************/
3686
3730
  function kw_get_real(gobj, kw, path, default_value, flag) {
3687
3731
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -3689,6 +3733,7 @@ function kw_get_real(gobj, kw, path, default_value, flag) {
3689
3733
  const required = flag && flag & kw_flag_t.KW_REQUIRED;
3690
3734
  const create = flag && flag & kw_flag_t.KW_CREATE;
3691
3735
  const extract = flag && flag & kw_flag_t.KW_EXTRACT;
3736
+ const wild = flag && flag & kw_flag_t.KW_WILD_NUMBER;
3692
3737
  if (v === void 0) {
3693
3738
  if (create) {
3694
3739
  let v = Number(default_value);
@@ -3700,15 +3745,24 @@ function kw_get_real(gobj, kw, path, default_value, flag) {
3700
3745
  }
3701
3746
  return Number(default_value);
3702
3747
  }
3703
- if (extract) kw_delete(gobj, kw, path);
3704
- if (!is_number(v)) {
3705
- if (required) {
3706
- log_error(`path value MUST BE a number: ${path}`);
3707
- trace_msg(kw);
3708
- }
3748
+ let value;
3749
+ if (is_number(v)) value = v;
3750
+ else if (!wild) {
3751
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json real: '${path}'`);
3752
+ trace_json(kw);
3709
3753
  return Number(default_value);
3754
+ } else if (is_boolean(v)) value = v ? 1 : 0;
3755
+ else if (is_string(v)) {
3756
+ value = parseFloat(v);
3757
+ if (Number.isNaN(value)) value = 0;
3758
+ } else if (v === null) value = 0;
3759
+ else {
3760
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3761
+ trace_json(kw);
3762
+ return 0;
3710
3763
  }
3711
- return Number(v);
3764
+ if (extract) kw_delete(gobj, kw, path);
3765
+ return value;
3712
3766
  }
3713
3767
  /************************************************************
3714
3768
  * The default comes back AS GIVEN, as in the C kw_get_str()
@@ -3717,6 +3771,11 @@ function kw_get_real(gobj, kw, path, default_value, flag) {
3717
3771
  * TRUE: an `if(value)` on the answer took an absent key for a
3718
3772
  * present one. KW_CREATE stores a string default, and null for
3719
3773
  * any other, as C stores json_null() for a NULL default.
3774
+ * KW_EXTRACT takes out only a string (before gobj-js 7.25.4 it
3775
+ * deleted any value, and a value that was not a string was lost).
3776
+ * C refuses to extract a string at all ("Cannot extract a
3777
+ * string": its answer would point into the freed json); a JS
3778
+ * string outlives the kw, so here it is taken out.
3720
3779
  ************************************************************/
3721
3780
  function kw_get_str(gobj, kw, path, default_value, flag) {
3722
3781
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -3734,7 +3793,6 @@ function kw_get_str(gobj, kw, path, default_value, flag) {
3734
3793
  }
3735
3794
  return default_value;
3736
3795
  }
3737
- if (extract) kw_delete(gobj, kw, path);
3738
3796
  if (!is_string(v)) {
3739
3797
  if (required) {
3740
3798
  log_error(`${gobj_short_name(gobj)}: path value MUST BE a string: ${path}`);
@@ -3742,6 +3800,7 @@ function kw_get_str(gobj, kw, path, default_value, flag) {
3742
3800
  }
3743
3801
  return default_value;
3744
3802
  }
3803
+ if (extract) kw_delete(gobj, kw, path);
3745
3804
  return v;
3746
3805
  }
3747
3806
  /************************************************************