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