function()

in src/scripting_api/util.js [72:203]


      function (match, nDecSep, cFlags, nWidth, nPrecision, cConvChar) {
        // cConvChar must be one of d, f, s, x
        if (
          cConvChar !== "d" &&
          cConvChar !== "f" &&
          cConvChar !== "s" &&
          cConvChar !== "x"
        ) {
          const buf = ["%"];
          for (const str of [nDecSep, cFlags, nWidth, nPrecision, cConvChar]) {
            if (str) {
              buf.push(str);
            }
          }
          return buf.join("");
        }

        i++;
        if (i === args.length) {
          throw new Error("Not enough arguments in printf");
        }
        const arg = args[i];

        if (cConvChar === "s") {
          return arg.toString();
        }

        let flags = 0;
        if (cFlags) {
          for (const flag of cFlags) {
            switch (flag) {
              case "+":
                flags |= PLUS;
                break;
              case " ":
                flags |= SPACE;
                break;
              case "0":
                flags |= ZERO;
                break;
              case "#":
                flags |= HASH;
                break;
            }
          }
        }
        cFlags = flags;

        if (nWidth) {
          nWidth = parseInt(nWidth);
        }

        let intPart = Math.trunc(arg);

        if (cConvChar === "x") {
          let hex = Math.abs(intPart).toString(16).toUpperCase();
          if (nWidth !== undefined) {
            hex = hex.padStart(nWidth, cFlags & ZERO ? "0" : " ");
          }
          if (cFlags & HASH) {
            hex = `0x${hex}`;
          }
          return hex;
        }

        if (nPrecision) {
          nPrecision = parseInt(nPrecision.substring(1));
        }

        nDecSep = nDecSep ? nDecSep.substring(1) : "0";
        const separators = {
          0: [",", "."],
          1: ["", "."],
          2: [".", ","],
          3: ["", ","],
          4: ["'", "."],
        };
        const [thousandSep, decimalSep] = separators[nDecSep];

        let decPart = "";
        if (cConvChar === "f") {
          decPart =
            nPrecision !== undefined
              ? Math.abs(arg - intPart).toFixed(nPrecision)
              : Math.abs(arg - intPart).toString();
          if (decPart.length > 2) {
            if (/^1\.0+$/.test(decPart)) {
              intPart += Math.sign(arg);
              decPart = `${decimalSep}${decPart.split(".")[1]}`;
            } else {
              decPart = `${decimalSep}${decPart.substring(2)}`;
            }
          } else {
            if (decPart === "1") {
              intPart += Math.sign(arg);
            }
            decPart = cFlags & HASH ? "." : "";
          }
        }

        let sign = "";
        if (intPart < 0) {
          sign = "-";
          intPart = -intPart;
        } else if (cFlags & PLUS) {
          sign = "+";
        } else if (cFlags & SPACE) {
          sign = " ";
        }

        if (thousandSep && intPart >= 1000) {
          const buf = [];
          while (true) {
            buf.push((intPart % 1000).toString().padStart(3, "0"));
            intPart = Math.trunc(intPart / 1000);
            if (intPart < 1000) {
              buf.push(intPart.toString());
              break;
            }
          }
          intPart = buf.reverse().join(thousandSep);
        } else {
          intPart = intPart.toString();
        }

        let n = `${intPart}${decPart}`;
        if (nWidth !== undefined) {
          n = n.padStart(nWidth - sign.length, cFlags & ZERO ? "0" : " ");
        }

        return `${sign}${n}`;
      }