diff options
author | David Robillard <d@drobilla.net> | 2018-05-27 15:48:25 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-12-31 12:15:40 -0500 |
commit | 6650e22960f4dcd7d66dc560aae0347dc3272e1d (patch) | |
tree | c5942a6ae5a510c093eefe9ca3a50c889911518e /src/serd_validate.c | |
parent | 85627db501282f3cb49223b816dbc226bd99ca16 (diff) | |
download | serd-6650e22960f4dcd7d66dc560aae0347dc3272e1d.tar.gz serd-6650e22960f4dcd7d66dc560aae0347dc3272e1d.tar.bz2 serd-6650e22960f4dcd7d66dc560aae0347dc3272e1d.zip |
WIP: Add validation
Diffstat (limited to 'src/serd_validate.c')
-rw-r--r-- | src/serd_validate.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/serd_validate.c b/src/serd_validate.c new file mode 100644 index 00000000..dbfa608d --- /dev/null +++ b/src/serd_validate.c @@ -0,0 +1,154 @@ +/* + Copyright 2012-2018 David Robillard <http://drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#define _BSD_SOURCE 1 // for realpath +#define _DEFAULT_SOURCE 1 // for realpath + +#include "serd_config.h" + +#include "model.h" +#include "serd/serd.h" +#include "world.h" + +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + +#define CERRORF(fmt, ...) fprintf(stderr, "serd_validate: " fmt, __VA_ARGS__); + +static int +print_version(void) +{ + printf("serd_validate " SERD_VERSION + " <http://drobilla.net/software/serd>\n"); + printf("Copyright 2012-2018 David Robillard <http://drobilla.net>.\n" + "License: <http://www.opensource.org/licenses/isc>\n" + "This is free software; you are free to change and redistribute it." + "\nThere is NO WARRANTY, to the extent permitted by law.\n"); + return 0; +} + +static int +print_usage(const char* name, bool error) +{ + FILE* const os = error ? stderr : stdout; + fprintf(os, "Usage: %s [OPTION]... INPUT...\n", name); + fprintf(os, "Validate RDF data\n\n"); + fprintf(os, " -h Display this help and exit\n"); + fprintf(os, " -l Print errors on a single line.\n"); + fprintf(os, " -v Display version information and exit\n"); + fprintf(os, + "Validate RDF data. This is a simple validator which checks\n" + "that all used properties are actually defined. It does not do\n" + "any fancy file retrieval, the files passed on the command line\n" + "are the only data that is read. In other words, you must pass\n" + "the definition of all vocabularies used on the command line.\n"); + return error ? 1 : 0; +} + +static char* +absolute_path(const char* path) +{ +#ifdef _WIN32 + char* out = (char*)malloc(MAX_PATH); + GetFullPathName(path, MAX_PATH, out, NULL); + return out; +#else + return realpath(path, NULL); +#endif +} + +static int +missing_arg(const char* name, char opt) +{ + CERRORF("option requires an argument -- '%c'\n", opt); + return print_usage(name, true); +} + +int +main(int argc, char** argv) +{ + if (argc < 2) { + return print_usage(argv[0], true); + } + + int a = 1; + size_t stack_size = 4194304; + for (; a < argc && argv[a][0] == '-'; ++a) { + if (argv[a][1] == 'h') { + return print_usage(argv[0], false); + } else if (argv[a][1] == 'k') { + if (++a == argc) { + return missing_arg(argv[0], 'k'); + } + char* endptr = NULL; + const long size = strtol(argv[a], &endptr, 10); + if (size <= 0 || size == LONG_MAX || *endptr != '\0') { + CERRORF("invalid stack size `%s'\n", argv[a]); + return 1; + } + stack_size = (size_t)size; + } else if (argv[a][1] == 'v') { + return print_version(); + } else { + CERRORF("invalid option -- '%s'\n", argv[a] + 1); + return print_usage(argv[0], true); + } + } + + SerdWorld* world = serd_world_new(); + const SerdModelFlags flags = SERD_INDEX_SPO | SERD_INDEX_OPS; + SerdModel* model = serd_model_new(world, flags); + SerdEnv* env = serd_env_new(NULL); + SerdInserter* inserter = serd_inserter_new(model, env, NULL); + SerdReader* reader = serd_reader_new( + world, SERD_TURTLE, serd_inserter_get_sink(inserter), stack_size); + + for (; a < argc; ++a) { + const char* input = argv[a]; + char* in_path = absolute_path(input); + + if (!in_path) { + CERRORF("unable to open file %s\n", input); + continue; + } + + SerdNode* base_uri_node = serd_new_file_uri(in_path, NULL); + + serd_env_set_base_uri(env, base_uri_node); + SerdStatus st = serd_reader_start_file(reader, input, true); + st = serd_reader_read_document(reader); + st = serd_reader_finish(reader); + + if (st) { + CERRORF("error reading %s: %s\n", in_path, serd_strerror(st)); + return 1; + } + + serd_node_free(base_uri_node); + free(in_path); + } + serd_reader_free(reader); + serd_env_free(env); + + const SerdStatus st = serd_validate(model); + + return (int)st; +} |