void fix_echo_line(char *line) { // to substitute the variables with their values char *pointer = line; char *ret = malloc(sizeof(char) * BUFFER_SIZE); bzero(ret, BUFFER_SIZE); int in_match = 0; char *var_name = malloc(sizeof(char) * BUFFER_SIZE); while (*pointer != '\0') { if (!in_match) { if (*pointer == '$') { in_match = 1; bzero(var_name, BUFFER_SIZE); } else { strncat(ret, pointer, 1); } } else { if (is_seperator(*pointer)) { if (is_env_var(var_name)) { char *val = getenv(var_name); strncat(ret, val, strlen(val)); } else { char *val = get_var_val(var_name); strncat(ret, val, strlen(val)); } in_match = 0; if (*pointer != '$') { strncat(ret, pointer, 1); } else { in_match = 1; } } else { strncat(var_name, pointer, 1); } } pointer++; } if (in_match) { if (is_env_var(var_name)) { char *val = getenv(var_name); strncat(ret, val, strlen(val)); } else { char *val = get_var_val(var_name); strncat(ret, val, strlen(val)); } in_match = 0; if (*pointer != '$') { strncat(var_name, pointer, 1); } else { in_match = 1; } } strncat(ret, "\0", 1); strcpy(line, ret); }
/** Parse the command line arguments, configuring the Jsonnet VM context and * populating the JsonnetConfig. */ static ArgStatus process_args(int argc, const char **argv, JsonnetConfig *config, JsonnetVm *vm) { auto args = simplify_args(argc, argv); std::vector<std::string> remaining_args; unsigned i = 0; if (args.size() > 0 && args[i] == "fmt") { config->cmd = FMT; i++; } else if (args.size() > 0 && args[i] == "eval") { config->cmd = EVAL; i++; } for (; i < args.size(); ++i) { const std::string &arg = args[i]; if (arg == "-h" || arg == "--help") { usage(std::cout); return ARG_SUCCESS; } else if (arg == "-v" || arg == "--version") { version(std::cout); return ARG_SUCCESS; } else if (arg == "-e" || arg == "--exec") { config->filenameIsCode = true; } else if (arg == "-o" || arg == "--output-file") { std::string output_file = next_arg(i, args); if (output_file.length() == 0) { std::cerr << "ERROR: -o argument was empty string" << std::endl; return ARG_FAILURE; } config->outputFile = output_file; } else if (arg == "--") { // All subsequent args are not options. while ((++i) < args.size()) remaining_args.push_back(args[i]); break; } else if (config->cmd == EVAL) { if (arg == "-s" || arg == "--max-stack") { long l = strtol_check(next_arg(i, args)); if (l < 1) { std::cerr << "ERROR: Invalid --max-stack value: " << l << std::endl; return ARG_FAILURE; } jsonnet_max_stack(vm, l); } else if (arg == "-J" || arg == "--jpath") { std::string dir = next_arg(i, args); if (dir.length() == 0) { std::cerr << "ERROR: -J argument was empty string" << std::endl; return ARG_FAILURE; } if (dir[dir.length() - 1] != '/') { dir += '/'; } jsonnet_jpath_add(vm, dir.c_str()); } else if (arg == "-V" || arg == "--ext-str") { std::string var, val; if (!get_var_val(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_ext_var(vm, var.c_str(), val.c_str()); } else if (arg == "--ext-str-file") { std::string var, val; if (!get_var_file(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_ext_var(vm, var.c_str(), val.c_str()); } else if (arg == "--ext-code") { std::string var, val; if (!get_var_val(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_ext_code(vm, var.c_str(), val.c_str()); } else if (arg == "--ext-code-file") { std::string var, val; if (!get_var_file(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_ext_code(vm, var.c_str(), val.c_str()); } else if (arg == "-A" || arg == "--tla-str") { std::string var, val; if (!get_var_val(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_tla_var(vm, var.c_str(), val.c_str()); } else if (arg == "--tla-str-file") { std::string var, val; if (!get_var_file(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_tla_var(vm, var.c_str(), val.c_str()); } else if (arg == "--tla-code") { std::string var, val; if (!get_var_val(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_tla_code(vm, var.c_str(), val.c_str()); } else if (arg == "--tla-code-file") { std::string var, val; if (!get_var_file(next_arg(i, args), var, val)) return ARG_FAILURE; jsonnet_tla_code(vm, var.c_str(), val.c_str()); } else if (arg == "--gc-min-objects") { long l = strtol_check(next_arg(i, args)); if (l < 0) { std::cerr << "ERROR: Invalid --gc-min-objects value: " << l << std::endl; return ARG_FAILURE; } jsonnet_gc_min_objects(vm, l); } else if (arg == "-t" || arg == "--max-trace") { long l = strtol_check(next_arg(i, args)); if (l < 0) { std::cerr << "ERROR: Invalid --max-trace value: " << l << std::endl; return ARG_FAILURE; } jsonnet_max_trace(vm, l); } else if (arg == "--gc-growth-trigger") { const char *arg = next_arg(i, args).c_str(); char *ep; double v = std::strtod(arg, &ep); if (*ep != '\0' || *arg == '\0') { std::cerr << "ERROR: Invalid number \"" << arg << "\"" << std::endl; return ARG_FAILURE; } if (v < 0) { std::cerr << "ERROR: Invalid --gc-growth-trigger \"" << arg << "\"" << std::endl; return ARG_FAILURE; } jsonnet_gc_growth_trigger(vm, v); } else if (arg == "-m" || arg == "--multi") { config->evalMulti = true; std::string output_dir = next_arg(i, args); if (output_dir.length() == 0) { std::cerr << "ERROR: -m argument was empty string" << std::endl; return ARG_FAILURE; } if (output_dir[output_dir.length() - 1] != '/') { output_dir += '/'; } config->evalMultiOutputDir = output_dir; } else if (arg == "-y" || arg == "--yaml-stream") { config->evalStream = true; } else if (arg == "-S" || arg == "--string") { jsonnet_string_output(vm, 1); } else if (arg.length() > 1 && arg[0] == '-') { std::cerr << "ERROR: Unrecognized argument: " << arg << std::endl; return ARG_FAILURE; } else { remaining_args.push_back(args[i]); } } else { assert(config->cmd == FMT); if (arg == "-i" || arg == "--in-place") { config->fmtInPlace = true; } else if (arg == "--test") { config->fmtTest = true; } else if (arg == "-n" || arg == "--indent") { long l = strtol_check(next_arg(i, args)); if (l < 0) { std::cerr << "ERROR: Invalid --indent value: " << l << std::endl; return ARG_FAILURE; } jsonnet_fmt_indent(vm, l); } else if (arg == "--max-blank-lines") { long l = strtol_check(next_arg(i, args)); if (l < 0) { std::cerr << "ERROR: Invalid --max-blank-lines value: " << l << "" << std::endl; return ARG_FAILURE; } jsonnet_fmt_max_blank_lines(vm, l); } else if (arg == "--comment-style") { const std::string val = next_arg(i, args); if (val == "h") { jsonnet_fmt_comment(vm, 'h'); } else if (val == "s") { jsonnet_fmt_comment(vm, 's'); } else if (val == "l") { jsonnet_fmt_comment(vm, 'l'); } else { std::cerr << "ERROR: Invalid --comment-style value: " << val << std::endl; return ARG_FAILURE; } } else if (arg == "--string-style") { const std::string val = next_arg(i, args); if (val == "d") { jsonnet_fmt_string(vm, 'd'); } else if (val == "s") { jsonnet_fmt_string(vm, 's'); } else if (val == "l") { jsonnet_fmt_string(vm, 'l'); } else { std::cerr << "ERROR: Invalid --string-style value: " << val << std::endl; return ARG_FAILURE; } } else if (arg == "--pad-arrays") { jsonnet_fmt_pad_arrays(vm, true); } else if (arg == "--no-pad-arrays") { jsonnet_fmt_pad_arrays(vm, false); } else if (arg == "--pad-objects") { jsonnet_fmt_pad_objects(vm, true); } else if (arg == "--no-pad-objects") { jsonnet_fmt_pad_objects(vm, false); } else if (arg == "--pretty-field-names") { jsonnet_fmt_pretty_field_names(vm, true); } else if (arg == "--no-pretty-field-names") { jsonnet_fmt_pretty_field_names(vm, false); } else if (arg == "--sort-imports") { jsonnet_fmt_sort_imports(vm, true); } else if (arg == "--no-sort-imports") { jsonnet_fmt_sort_imports(vm, false); } else if (arg == "--debug-desugaring") { jsonnet_fmt_debug_desugaring(vm, true); } else if (arg.length() > 1 && arg[0] == '-') { std::cerr << "ERROR: Unrecognized argument: " << arg << std::endl; return ARG_FAILURE; } else { remaining_args.push_back(args[i]); } } } const char *want = config->filenameIsCode ? "code" : "filename"; if (remaining_args.size() == 0) { std::cerr << "ERROR: Must give " << want << "\n" << std::endl; usage(std::cerr); return ARG_FAILURE; } bool multiple_files_allowed = config->cmd == FMT && (config->fmtTest || config->fmtInPlace); if (!multiple_files_allowed) { if (remaining_args.size() > 1) { std::string filename = remaining_args[0]; std::cerr << "ERROR: Only one " << want << " is allowed\n" << std::endl; return ARG_FAILURE; } } config->inputFiles = remaining_args; return ARG_CONTINUE; }