#!/usr/bin/env ucode let fs = require("fs"); global.double = function(v) { if (v == null || v == "") return 0.0; return v * 1.0; }; function as_string(value) { return value == null ? "" : "" + value; } function read_json_file(path) { let data = fs.readfile(path); if (data == null) return null; try { return json(data); } catch (e) { return null; } } function read_stdin() { let input = fs.open("/dev/stdin", "r"); if (!input) return ""; let data = input.read("all"); input.close(); return data == null ? "" : data; } function read_stdin_json() { let data = read_stdin(); try { return json(data); } catch (e) { return null; } } function write_json(value) { print(sprintf("%J", value), "\n"); } function write_compact_string_array(values) { print("["); for (let i = 0; i < length(values); i++) { if (i > 0) print(","); print(sprintf("%J", as_string(values[i]))); } print("]\n"); } function csv_to_json_array(value) { value = as_string(value); write_compact_string_array(value == "" ? [] : split(value, ",")); } function write_json_file(path, value) { return fs.writefile(path, sprintf("%J\n", value)); } function strip_internal_fields(value) { if (type(value) == "array") { for (let i = 0; i < length(value); i++) value[i] = strip_internal_fields(value[i]); return value; } if (type(value) == "object") { for (let key in keys(value)) { if (substr(key, 0, 2) == "__") { delete value[key]; continue; } value[key] = strip_internal_fields(value[key]); } } return value; } function array_or_empty(value) { return type(value) == "array" ? value : []; } function object_or_empty(value) { return type(value) == "object" ? value : {}; } function object_key_count(value) { return type(value) == "object" ? length(keys(value)) : 0; } function option(section, key, fallback) { if (fallback == null) fallback = ""; let value = object_or_empty(section)[key]; if (value == null) return fallback; if (type(value) == "array") return join(" ", value); return as_string(value); } function list_option(section, key) { let value = object_or_empty(section)[key]; if (value == null) return []; if (type(value) == "array") return value; let text = trim(as_string(value)); return text == "" ? [] : split(text, /[ \t\r\n]+/); } function bool_option(section, key, fallback) { if (fallback == null) fallback = false; let value = option(section, key, fallback ? "1" : "0"); return value == "1" || value == "true" || value == "yes" || value == "on"; } function int_option(section, key, fallback) { let value = option(section, key, fallback); if (match(value, /[^0-9]/)) return int(fallback, 10); return int(value, 10); } function shell_quote(value) { return "'" + replace(as_string(value), /'/g, "'\\''") + "'"; } function command_from_args(args) { let parts = []; for (let arg in args) push(parts, shell_quote(arg)); return join(" ", parts); } function command_status(command) { let status = int(system(command)); return status > 255 ? int(status / 256) : status; } function command_success(command) { return command_status("(" + command + ") >/dev/null 2>&1") == 0; } function command_success_from_args(args) { return command_success(command_from_args(args)); } function command_capture(command) { let p = fs.popen(command, "r"); if (!p) return null; let output = as_string(p.read("all") || ""); let status = p.close(); status = status > 255 ? int(status / 256) : status; return { status: status, output: output }; } function command_output(command) { let res = command_capture(command); return res ? res.output : ""; } function command_output_from_args(args) { return command_output(command_from_args(args) + " 2>/dev/null"); } return { as_string, read_json_file, read_stdin, read_stdin_json, write_json, write_compact_string_array, csv_to_json_array, write_json_file, strip_internal_fields, array_or_empty, object_or_empty, object_key_count, option, list_option, bool_option, int_option, shell_quote, command_from_args, command_status, command_success, command_success_from_args, command_capture, command_output, command_output_from_args };