コード例 #1
0
ファイル: _jsonnet.c プロジェクト: Gasol/deb-jsonnet
static PyObject *handle_result(struct JsonnetVm *vm, char *out, int error)
{
    if (error) {
        PyErr_SetString(PyExc_RuntimeError, out);
        jsonnet_realloc(vm, out, 0);
        jsonnet_destroy(vm);
        return NULL;
    } else {
        PyObject *ret = PyString_FromString(out);
        jsonnet_realloc(vm, out, 0);
        jsonnet_destroy(vm);
        return ret;
    }
}
コード例 #2
0
ファイル: libjsonnet.cpp プロジェクト: Neeke/Jsonnet-PHP
static char *default_import_callback(void *ctx, const char *dir, const char *file,
                                     char **found_here_cptr, int *success)
{
    auto *vm = static_cast<JsonnetVm *>(ctx);

    std::string input, found_here, err_msg;

    ImportStatus status = try_path(dir, file, input, found_here, err_msg);

    std::vector<std::string> jpaths(vm->jpaths);

    // If not found, try library search path.
    while (status == IMPORT_STATUS_FILE_NOT_FOUND) {
        if (jpaths.size() == 0) {
            *success = 0;
            const char *err = "no match locally or in the Jsonnet library paths.";
            char *r = jsonnet_realloc(vm, nullptr, std::strlen(err) + 1);
            std::strcpy(r, err);
            return r;
        }
        status = try_path(jpaths.back(), file, input, found_here, err_msg);
        jpaths.pop_back();
    }

    if (status == IMPORT_STATUS_IO_ERROR) {
        *success = 0;
        return from_string(vm, err_msg);
    } else {
        assert(status == IMPORT_STATUS_OK);
        *success = 1;
        *found_here_cptr = from_string(vm, found_here);
        return from_string(vm, input);
    }
}
コード例 #3
0
ファイル: jsonnet.cpp プロジェクト: robinivanka/jsonnet
/** Writes output files for multiple file output */
static bool write_multi_output_files(JsonnetVm* vm, char* output,
                                     const std::string& output_dir) {
    // If multiple file output is used, then iterate over each string from
    // the sequence of strings returned by jsonnet_evaluate_snippet_multi,
    // construct pairs of filename and content, and write each output file.
    std::map<std::string, std::string> r;
    for (const char *c=output ; *c!='\0' ; ) {
        const char *filename = c;
        const char *c2 = c;
        while (*c2 != '\0') ++c2;
        ++c2;
        const char *json = c2;
        while (*c2 != '\0') ++c2;
        ++c2;
        c = c2;
        r[filename] = json;
    }
    jsonnet_realloc(vm, output, 0);
    for (const auto &pair : r) {
        const std::string &new_content = pair.second;
        const std::string &filename = output_dir + pair.first;
        std::cout << filename << std::endl;
        {
            std::ifstream exists(filename.c_str());
            if (exists.good()) {
                std::string existing_content;
                existing_content.assign(std::istreambuf_iterator<char>(exists),
                                        std::istreambuf_iterator<char>());
                if (existing_content == new_content) {
                    // Do not bump the timestamp on the file if its content is
                    // the same. This may trigger other tools (e.g. make) to do
                    // unnecessary work.
                    continue;
                }
            }
        }
        std::ofstream f;
        f.open(filename.c_str());
        if (!f.good()) {
            std::string msg = "Opening output file: " + filename;
            perror(msg.c_str());
            jsonnet_destroy(vm);
            return false;
        }
        f << new_content;
        f.close();
        if (!f.good()) {
            std::string msg = "Writing to output file: " + filename;
            perror(msg.c_str());
            jsonnet_destroy(vm);
            return false;
        }
    }
    std::cout.flush();
    return true;
}
コード例 #4
0
int main(int argc, const char **argv)
{
    int error;
    char *output;
    struct JsonnetVm *vm;
    if (argc != 2) {
        fprintf(stderr, "libjsonnet_test_file <file>\n");
        return EXIT_FAILURE;
    }
    vm = jsonnet_make();
    output = jsonnet_evaluate_file(vm, argv[1], &error);
    if (error) {
        fprintf(stderr, "%s", output);
        jsonnet_realloc(vm, output, 0);
        jsonnet_destroy(vm);
        return EXIT_FAILURE;
    } 
    printf("%s", output);
    jsonnet_realloc(vm, output, 0);
    jsonnet_destroy(vm);
    return EXIT_SUCCESS;
}
コード例 #5
0
ファイル: jsonnet.cpp プロジェクト: JianKongBao/Jsonnet-PHP
/** Writes output files for YAML stream output */
static bool write_output_stream(JsonnetVm *vm, char *output, const std::string &output_file)
{
    std::ostream *o;
    std::ofstream f;

    if (output_file.empty()) {
        o = &std::cout;
    } else {
        f.open(output_file.c_str());
        if (!f.good()) {
            std::string msg = "Writing to output file: " + output_file;
            perror(msg.c_str());
            return false;
        }
        o = &f;
    }

    // If YAML stream output is used, then iterate over each string from
    // the sequence of strings returned by jsonnet_evaluate_snippet_stream,
    // and add the --- and ... as defined by the YAML spec.
    std::vector<std::string> r;
    for (const char *c = output; *c != '\0';) {
        const char *json = c;
        while (*c != '\0')
            ++c;
        ++c;
        r.emplace_back(json);
    }
    jsonnet_realloc(vm, output, 0);
    for (const auto &str : r) {
        (*o) << "---\n";
        (*o) << str;
    }
    if (r.size() > 0)
        (*o) << "...\n";
    o->flush();

    if (output_file.empty()) {
        std::cout.flush();
    } else {
        f.close();
        if (!f.good()) {
            std::string msg = "Writing to output file: " + output_file;
            perror(msg.c_str());
            return false;
        }
    }

    return true;
}
コード例 #6
0
ファイル: jsonnet.cpp プロジェクト: Dmitry666/jsonnet
static char *import_callback (void *ctx_, const char *dir, const char *file, int *success)
{
    const auto &ctx = *static_cast<ImportCallbackContext*>(ctx_);

    std::string input;

    ImportStatus status = try_path(dir, file, input);

    std::vector<std::string> jpaths(*ctx.jpaths);

    // If not found, try library search path.
    while (status == IMPORT_STATUS_FILE_NOT_FOUND) {
        if (jpaths.size() == 0) {
            *success = 0;
            const char *err = "No match locally or in the Jsonnet library path.";
            char *r = jsonnet_realloc(ctx.vm, nullptr, std::strlen(err) + 1);
            std::strcpy(r, err);
            return r;
        }
        status = try_path(jpaths.back(), file, input);
        jpaths.pop_back();
    }

    if (status == IMPORT_STATUS_IO_ERROR) {
        *success = 0;
        const char *err = std::strerror(errno);
        char *r = jsonnet_realloc(ctx.vm, nullptr, std::strlen(err) + 1);
        std::strcpy(r, err);
        return r;
    } else {
        assert(status == IMPORT_STATUS_OK);
        *success = 1;
        char *r = jsonnet_realloc(ctx.vm, nullptr, input.length() + 1);
        std::strcpy(r, input.c_str());
        return r;
    }
}
コード例 #7
0
ファイル: libjsonnet.cpp プロジェクト: Neeke/Jsonnet-PHP
static char *from_string(JsonnetVm *vm, const std::string &v)
{
    char *r = jsonnet_realloc(vm, nullptr, v.length() + 1);
    std::strcpy(r, v.c_str());
    return r;
}
コード例 #8
0
ファイル: _jsonnet.c プロジェクト: Gasol/deb-jsonnet
static char *jsonnet_str(struct JsonnetVm *vm, const char *str)
{
    char *out = jsonnet_realloc(vm, NULL, strlen(str) + 1);
    memcpy(out, str, strlen(str) + 1);
    return out;
}
コード例 #9
0
ファイル: jsonnet.cpp プロジェクト: robinivanka/jsonnet
int main(int argc, const char **argv)
{
    try {
        JsonnetVm *vm = jsonnet_make();
        JsonnetConfig config;
        if (!process_args(argc, argv, &config, vm)) {
            return EXIT_FAILURE;
        }

        // Read input files.
        std::string input;
        if (!read_input(&config, &input)) {
            return EXIT_FAILURE;
        }

        // Evaluate input Jsonnet and handle any errors from Jsonnet VM.
        int error;
        char *output;
        if (config.multi()) {
            output = jsonnet_evaluate_snippet_multi(
                vm, config.input_file().c_str(), input.c_str(), &error);
        } else {
            output = jsonnet_evaluate_snippet(
                vm, config.input_file().c_str(), input.c_str(), &error);
        }

        if (error) {
            std::cerr << output;
            std::cerr.flush();
            jsonnet_realloc(vm, output, 0);
            jsonnet_destroy(vm);
            return EXIT_FAILURE;
        }

        // Write output JSON.
        if (config.multi()) {
            if (!write_multi_output_files(vm, output, config.output_dir())) {
                return EXIT_FAILURE;
            }
        } else {
            bool successful =  write_output_file(output, config.output_file());
            jsonnet_realloc(vm, output, 0);
            if (!successful) {
                jsonnet_destroy(vm);
                return EXIT_FAILURE;
            }
        }
        jsonnet_destroy(vm);
        return EXIT_SUCCESS;

    } catch (const std::bad_alloc &) {
        // Avoid further allocation attempts
        fputs("Internal out-of-memory error (please report this)\n", stderr);
    } catch (const std::exception &e) {
        std::cerr << "Internal error (please report this): "
                  << e.what() << std::endl;
    } catch (...) {
        std::cerr << "An unknown exception occurred (please report this)."
                  << std::endl;
    }
    return EXIT_FAILURE;
}
コード例 #10
0
ファイル: jsonnet.cpp プロジェクト: JianKongBao/Jsonnet-PHP
int main(int argc, const char **argv)
{
    try {
        JsonnetVm *vm = jsonnet_make();
        JsonnetConfig config;
        ArgStatus arg_status = process_args(argc, argv, &config, vm);
        if (arg_status != ARG_CONTINUE) {
            jsonnet_destroy(vm);
            return arg_status == ARG_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
        }

        // Evaluate input Jsonnet and handle any errors from Jsonnet VM.
        int error;
        char *output;
        switch (config.cmd) {
            case EVAL: {
                assert(config.inputFiles.size() == 1);

                // Read input file.
                std::string input;
                if (!read_input(&config, &config.inputFiles[0], &input)) {
                    jsonnet_destroy(vm);
                    return EXIT_FAILURE;
                }

                if (config.evalMulti) {
                    output = jsonnet_evaluate_snippet_multi(
                        vm, config.inputFiles[0].c_str(), input.c_str(), &error);
                } else if (config.evalStream) {
                    output = jsonnet_evaluate_snippet_stream(
                        vm, config.inputFiles[0].c_str(), input.c_str(), &error);
                } else {
                    output = jsonnet_evaluate_snippet(
                        vm, config.inputFiles[0].c_str(), input.c_str(), &error);
                }

                if (error) {
                    std::cerr << output;
                    jsonnet_realloc(vm, output, 0);
                    jsonnet_destroy(vm);
                    return EXIT_FAILURE;
                }

                // Write output JSON.
                if (config.evalMulti) {
                    if (!write_multi_output_files(
                            vm, output, config.evalMultiOutputDir, config.outputFile)) {
                        jsonnet_destroy(vm);
                        return EXIT_FAILURE;
                    }
                } else if (config.evalStream) {
                    if (!write_output_stream(vm, output, config.outputFile)) {
                        jsonnet_destroy(vm);
                        return EXIT_FAILURE;
                    }
                } else {
                    bool successful = write_output_file(output, config.outputFile);
                    jsonnet_realloc(vm, output, 0);
                    if (!successful) {
                        jsonnet_destroy(vm);
                        return EXIT_FAILURE;
                    }
                }
            } break;

            case FMT: {
                std::string output_file = config.outputFile;

                if (config.fmtInPlace || config.fmtTest) {
                    assert(config.inputFiles.size() >= 1);
                    for (std::string &inputFile : config.inputFiles) {
                        if (config.fmtInPlace) {
                            output_file = inputFile;

                            if (inputFile == "-") {
                                std::cerr << "ERROR: Cannot use --in-place with stdin" << std::endl;
                                jsonnet_destroy(vm);
                                return EXIT_FAILURE;
                            }
                            if (config.filenameIsCode) {
                                std::cerr << "ERROR: Cannot use --in-place with --exec"
                                          << std::endl;
                                jsonnet_destroy(vm);
                                return EXIT_FAILURE;
                            }
                        }

                        std::string input;
                        if (!read_input(&config, &inputFile, &input)) {
                            jsonnet_destroy(vm);
                            return EXIT_FAILURE;
                        }

                        output = jsonnet_fmt_snippet(vm, inputFile.c_str(), input.c_str(), &error);

                        if (error) {
                            std::cerr << output;
                            jsonnet_realloc(vm, output, 0);
                            jsonnet_destroy(vm);
                            return EXIT_FAILURE;
                        }

                        if (config.fmtTest) {
                            // Check the output matches the input.
                            bool ok = output == input;
                            jsonnet_realloc(vm, output, 0);
                            if (!ok) {
                                jsonnet_destroy(vm);
                                return 2;
                            }
                        } else {
                            // Write output Jsonnet.
                            bool successful = write_output_file(output, output_file);
                            jsonnet_realloc(vm, output, 0);
                            if (!successful) {
                                jsonnet_destroy(vm);
                                return EXIT_FAILURE;
                            }
                        }
                    }
                } else {
                    assert(config.inputFiles.size() == 1);
                    // Read input file.
                    std::string input;
                    if (!read_input(&config, &config.inputFiles[0], &input)) {
                        jsonnet_destroy(vm);
                        return EXIT_FAILURE;
                    }

                    output = jsonnet_fmt_snippet(
                        vm, config.inputFiles[0].c_str(), input.c_str(), &error);

                    if (error) {
                        std::cerr << output;
                        jsonnet_realloc(vm, output, 0);
                        jsonnet_destroy(vm);
                        return EXIT_FAILURE;
                    }

                    // Write output Jsonnet.
                    bool successful = write_output_file(output, output_file);
                    jsonnet_realloc(vm, output, 0);
                    if (!successful) {
                        jsonnet_destroy(vm);
                        return EXIT_FAILURE;
                    }
                }
            } break;
        }

        jsonnet_destroy(vm);
        return EXIT_SUCCESS;

    } catch (const std::bad_alloc &) {
        // Avoid further allocation attempts
        fputs("Internal out-of-memory error (please report this)\n", stderr);
    } catch (const std::exception &e) {
        std::cerr << "Internal error (please report this): " << e.what() << std::endl;
    } catch (...) {
        std::cerr << "An unknown exception occurred (please report this)." << std::endl;
    }
    return EXIT_FAILURE;
}
コード例 #11
0
ファイル: jsonnet.cpp プロジェクト: Dmitry666/jsonnet
int main(int argc, const char **argv)
{
    std::vector<std::string> jpaths;
    jpaths.emplace_back("/usr/share/" JSONNET_VERSION "/");
    jpaths.emplace_back("/usr/local/share/" JSONNET_VERSION "/");

    JsonnetVm *vm = jsonnet_make();
    bool filename_is_code = false;
        
    bool multi = false;

    auto args = simplify_args(argc, argv);
    std::vector<std::string> remaining_args;

    for (unsigned i=0 ; i<args.size() ; ++i) {
        const std::string &arg = args[i];
        if (arg == "-h" || arg == "--help") {
            usage(std::cout);
            return EXIT_SUCCESS;
        } else if (arg == "-v" || arg == "--version") {
            version(std::cout);
            return EXIT_SUCCESS;
        } else 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 << "\n" << std::endl;
                usage(std::cerr);
                return EXIT_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 EXIT_FAILURE;
            }
            if (dir[dir.length() - 1] != '/')
                dir += '/';
            jpaths.push_back(dir);
        } else if (arg == "-E" || arg == "--env") {
            const std::string var = next_arg(i, args);
            const char *val = ::getenv(var.c_str());
            if (val == nullptr) {
                std::cerr << "ERROR: Environment variable " << var
                          << " was undefined." << std::endl;
                return EXIT_FAILURE;
            }
            jsonnet_ext_var(vm, var.c_str(), val);
        } else if (arg == "-V" || arg == "--var") {
            const std::string var_val = next_arg(i, args);
            size_t eq_pos = var_val.find_first_of('=', 0);
            if (eq_pos == std::string::npos) {
                std::cerr << "ERROR: argument not in form <var>=<val> \""
                          << var_val << "\"." << std::endl;
                return EXIT_FAILURE;
            }
            const std::string var = var_val.substr(0, eq_pos);
            const std::string val = var_val.substr(eq_pos + 1, std::string::npos);
            jsonnet_ext_var(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;
                usage(std::cerr);
                return EXIT_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;
                usage(std::cerr);
                return EXIT_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;
                usage(std::cerr);
                return EXIT_FAILURE;
            }
            if (v < 0) {
                std::cerr << "ERROR: Invalid --gc-growth-trigger \"" << arg << "\"\n" << std::endl;
                usage(std::cerr);
                return EXIT_FAILURE;
            }
            jsonnet_gc_growth_trigger(vm, v);
        } else if (arg == "-e" || arg == "--exec") {
            filename_is_code = true;
        } else if (arg == "-m" || arg == "--multi") {
            multi = true;
        } else if (arg == "-S" || arg == "--string") {
            jsonnet_string_output(vm, 1);
        } else if (arg == "--debug-ast") {
            jsonnet_debug_ast(vm, true);
        } else if (arg == "--") {
            // All subsequent args are not options.
            while ((++i) < args.size())
                remaining_args.push_back(args[i]);
            break;
        } else {
            remaining_args.push_back(args[i]);
        }
    }


    const char *want = filename_is_code ? "code" : "filename";

    if (remaining_args.size() == 0) {
        std::cerr << "ERROR: Must give " << want << "\n" << std::endl;
        usage(std::cerr);
        return EXIT_FAILURE;
    }

    std::string filename = remaining_args[0];

    if (remaining_args.size() > 1) {
        std::cerr << "ERROR: Already specified " << want << " as \"" << filename << "\"\n"
                  << std::endl;
        usage(std::cerr);
        return EXIT_FAILURE;
    }

    std::string input;
    if (filename_is_code) {
        input = filename;
        filename = "<cmdline>";
    } else {
        if (filename == "-") {
            filename = "<stdin>";
            input.assign(std::istreambuf_iterator<char>(std::cin),
                         std::istreambuf_iterator<char>());
        } else {
            std::ifstream f;
            f.open(filename.c_str());
            if (!f.good()) {
                std::string msg = "Opening input file: " + filename;
                perror(msg.c_str());
                return EXIT_FAILURE;
            }
            input.assign(std::istreambuf_iterator<char>(f),
                         std::istreambuf_iterator<char>());
            if (!f.good()) {
                std::string msg = "Reading input file: " + filename;
                perror(msg.c_str());
                return EXIT_FAILURE;
            }
        }
    }

    ImportCallbackContext import_callback_ctx { vm, &jpaths };
    jsonnet_import_callback(vm, import_callback, &import_callback_ctx);

    int error;
    char *output;
    if (multi) {
        output = jsonnet_evaluate_snippet_multi(vm, filename.c_str(), input.c_str(), &error);
    } else {
        output = jsonnet_evaluate_snippet(vm, filename.c_str(), input.c_str(), &error);
    }

    if (error) {
        std::cerr << output;
        std::cerr.flush();
        jsonnet_realloc(vm, output, 0);
        jsonnet_destroy(vm);
        return EXIT_FAILURE;
    }

    if (multi) {
        std::map<std::string, std::string> r;
        for (const char *c=output ; *c!='\0' ; ) {
            const char *filename = c;
            const char *c2 = c;
            while (*c2 != '\0') ++c2;
            ++c2;
            const char *json = c2;
            while (*c2 != '\0') ++c2;
            ++c2;
            c = c2;
            r[filename] = json;
        }
        jsonnet_realloc(vm, output, 0);
        for (const auto &pair : r) {
            const std::string &new_content = pair.second;
            const std::string &filename = pair.first;
            std::cout << filename << std::endl;
            {
                std::ifstream exists(filename.c_str());
                if (exists.good()) {
                    std::string existing_content;
                    existing_content.assign(std::istreambuf_iterator<char>(exists),
                                            std::istreambuf_iterator<char>());
                    if (existing_content == new_content) {
                        // Do not bump the timestamp on the file if its content is the same.
                        // This may trigger other tools (e.g. make) to do unnecessary work.
                        continue;
                    }
                }
            }
            std::ofstream f;
            f.open(filename.c_str());
            if (!f.good()) {
                std::string msg = "Opening output file: " + filename;
                perror(msg.c_str());
                jsonnet_destroy(vm);
                return EXIT_FAILURE;
            }
            f << new_content;
            f.close();
            if (!f.good()) {
                std::string msg = "Writing to output file: " + filename;
                perror(msg.c_str());
                jsonnet_destroy(vm);
                return EXIT_FAILURE;
            }
        }
        std::cout.flush();
    } else {
        std::cout << output;
        std::cout.flush();
        jsonnet_realloc(vm, output, 0);
    }
    jsonnet_destroy(vm);
    return EXIT_SUCCESS;
}