annotate ext/sord/src/sordi.c @ 296:50a0b4fea7f1 tip master

Merge pull request #8 from michel-slm/gcc15 Include headers needed to compile with GCC 15's -std=gnu23 default
author Chris Cannam <cannam@all-day-breakfast.com>
date Mon, 27 Jan 2025 08:53:58 +0000
parents c5cdc9e6a4bf
children
rev   line source
cannam@226 1 /*
cannam@226 2 Copyright 2011-2016 David Robillard <http://drobilla.net>
cannam@226 3
cannam@226 4 Permission to use, copy, modify, and/or distribute this software for any
cannam@226 5 purpose with or without fee is hereby granted, provided that the above
cannam@226 6 copyright notice and this permission notice appear in all copies.
cannam@226 7
cannam@226 8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
cannam@226 9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
cannam@226 10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
cannam@226 11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
cannam@226 12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
cannam@226 13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
cannam@226 14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
cannam@226 15 */
cannam@226 16
cannam@226 17 #include <assert.h>
cannam@226 18 #include <stdlib.h>
cannam@226 19 #include <string.h>
cannam@226 20
cannam@226 21 #ifdef _WIN32
cannam@226 22 # include <windows.h>
cannam@226 23 #endif
cannam@226 24
cannam@226 25 #include "serd/serd.h"
cannam@226 26 #include "sord/sord.h"
cannam@226 27 #include "sord_config.h"
cannam@226 28
cannam@226 29 #define SORDI_ERROR(msg) fprintf(stderr, "sordi: " msg);
cannam@226 30 #define SORDI_ERRORF(fmt, ...) fprintf(stderr, "sordi: " fmt, __VA_ARGS__);
cannam@226 31
cannam@226 32 typedef struct {
cannam@226 33 SerdWriter* writer;
cannam@226 34 SerdEnv* env;
cannam@226 35 SerdNode base_uri_node;
cannam@226 36 SerdURI base_uri;
cannam@226 37 SordModel* sord;
cannam@226 38 } State;
cannam@226 39
cannam@226 40 static int
cannam@226 41 print_version(void)
cannam@226 42 {
cannam@226 43 printf("sordi " SORD_VERSION " <http://drobilla.net/software/sord>\n");
cannam@226 44 printf("Copyright 2011-2016 David Robillard <http://drobilla.net>.\n"
cannam@226 45 "License: <http://www.opensource.org/licenses/isc>\n"
cannam@226 46 "This is free software; you are free to change and redistribute it."
cannam@226 47 "\nThere is NO WARRANTY, to the extent permitted by law.\n");
cannam@226 48 return 0;
cannam@226 49 }
cannam@226 50
cannam@226 51 static int
cannam@226 52 print_usage(const char* name, bool error)
cannam@226 53 {
cannam@226 54 FILE* const os = error ? stderr : stdout;
cannam@226 55 fprintf(os, "%s", error ? "\n" : "");
cannam@226 56 fprintf(os, "Usage: %s [OPTION]... INPUT [BASE_URI]\n", name);
cannam@226 57 fprintf(os, "Load and re-serialise RDF data.\n");
cannam@226 58 fprintf(os, "Use - for INPUT to read from standard input.\n\n");
cannam@226 59 fprintf(os, " -h Display this help and exit\n");
cannam@226 60 fprintf(os, " -i SYNTAX Input syntax (`turtle' or `ntriples')\n");
cannam@226 61 fprintf(os, " -o SYNTAX Output syntax (`turtle' or `ntriples')\n");
cannam@226 62 fprintf(os, " -s INPUT Parse INPUT as string (terminates options)\n");
cannam@226 63 fprintf(os, " -v Display version information and exit\n");
cannam@226 64 return error ? 1 : 0;
cannam@226 65 }
cannam@226 66
cannam@226 67 static bool
cannam@226 68 set_syntax(SerdSyntax* syntax, const char* name)
cannam@226 69 {
cannam@226 70 if (!strcmp(name, "turtle")) {
cannam@226 71 *syntax = SERD_TURTLE;
cannam@226 72 } else if (!strcmp(name, "ntriples")) {
cannam@226 73 *syntax = SERD_NTRIPLES;
cannam@226 74 } else {
cannam@226 75 SORDI_ERRORF("unknown syntax `%s'\n", name);
cannam@226 76 return false;
cannam@226 77 }
cannam@226 78 return true;
cannam@226 79 }
cannam@226 80
cannam@226 81 int
cannam@226 82 main(int argc, char** argv)
cannam@226 83 {
cannam@226 84 if (argc < 2) {
cannam@226 85 return print_usage(argv[0], true);
cannam@226 86 }
cannam@226 87
cannam@226 88 FILE* in_fd = NULL;
cannam@226 89 SerdSyntax input_syntax = SERD_TURTLE;
cannam@226 90 SerdSyntax output_syntax = SERD_NTRIPLES;
cannam@226 91 bool from_file = true;
cannam@226 92 const uint8_t* in_name = NULL;
cannam@226 93 int a = 1;
cannam@226 94 for (; a < argc && argv[a][0] == '-'; ++a) {
cannam@226 95 if (argv[a][1] == '\0') {
cannam@226 96 in_name = (const uint8_t*)"(stdin)";
cannam@226 97 in_fd = stdin;
cannam@226 98 break;
cannam@226 99 } else if (argv[a][1] == 'h') {
cannam@226 100 return print_usage(argv[0], false);
cannam@226 101 } else if (argv[a][1] == 'v') {
cannam@226 102 return print_version();
cannam@226 103 } else if (argv[a][1] == 's') {
cannam@226 104 in_name = (const uint8_t*)"(string)";
cannam@226 105 from_file = false;
cannam@226 106 ++a;
cannam@226 107 break;
cannam@226 108 } else if (argv[a][1] == 'i') {
cannam@226 109 if (++a == argc) {
cannam@226 110 SORDI_ERROR("option requires an argument -- 'i'\n\n");
cannam@226 111 return print_usage(argv[0], true);
cannam@226 112 }
cannam@226 113 if (!set_syntax(&input_syntax, argv[a])) {
cannam@226 114 return print_usage(argv[0], true);
cannam@226 115 }
cannam@226 116 } else if (argv[a][1] == 'o') {
cannam@226 117 if (++a == argc) {
cannam@226 118 SORDI_ERROR("option requires an argument -- 'o'\n\n");
cannam@226 119 return print_usage(argv[0], true);
cannam@226 120 }
cannam@226 121 if (!set_syntax(&output_syntax, argv[a])) {
cannam@226 122 return print_usage(argv[0], true);
cannam@226 123 }
cannam@226 124 } else {
cannam@226 125 SORDI_ERRORF("invalid option -- '%s'\n", argv[a] + 1);
cannam@226 126 return print_usage(argv[0], true);
cannam@226 127 }
cannam@226 128 }
cannam@226 129
cannam@226 130 if (a == argc) {
cannam@226 131 SORDI_ERROR("missing input\n");
cannam@226 132 return print_usage(argv[0], true);
cannam@226 133 }
cannam@226 134
cannam@226 135 const uint8_t* input = (const uint8_t*)argv[a++];
cannam@226 136 if (from_file) {
cannam@226 137 in_name = in_name ? in_name : input;
cannam@226 138 if (!in_fd) {
cannam@226 139 input = serd_uri_to_path(in_name);
cannam@226 140 if (!input || !(in_fd = fopen((const char*)input, "rb"))) {
cannam@226 141 return 1;
cannam@226 142 }
cannam@226 143 }
cannam@226 144 }
cannam@226 145
cannam@226 146 SerdURI base_uri = SERD_URI_NULL;
cannam@226 147 SerdNode base = SERD_NODE_NULL;
cannam@226 148 if (a < argc) { // Base URI given on command line
cannam@226 149 base = serd_node_new_uri_from_string(
cannam@226 150 (const uint8_t*)argv[a], NULL, &base_uri);
cannam@226 151 } else if (from_file && in_fd != stdin) { // Use input file URI
cannam@226 152 base = serd_node_new_file_uri(input, NULL, &base_uri, true);
cannam@226 153 }
cannam@226 154
cannam@226 155 SordWorld* world = sord_world_new();
cannam@226 156 SordModel* sord = sord_new(world, SORD_SPO|SORD_OPS, false);
cannam@226 157 SerdEnv* env = serd_env_new(&base);
cannam@226 158 SerdReader* reader = sord_new_reader(sord, env, input_syntax, NULL);
cannam@226 159
cannam@226 160 SerdStatus status = (from_file)
cannam@226 161 ? serd_reader_read_file_handle(reader, in_fd, in_name)
cannam@226 162 : serd_reader_read_string(reader, input);
cannam@226 163
cannam@226 164 serd_reader_free(reader);
cannam@226 165
cannam@226 166 FILE* out_fd = stdout;
cannam@226 167 SerdEnv* write_env = serd_env_new(&base);
cannam@226 168
cannam@226 169 int output_style = SERD_STYLE_RESOLVED;
cannam@226 170 if (output_syntax == SERD_NTRIPLES) {
cannam@226 171 output_style |= SERD_STYLE_ASCII;
cannam@226 172 } else {
cannam@226 173 output_style |= SERD_STYLE_CURIED | SERD_STYLE_ABBREVIATED;
cannam@226 174 }
cannam@226 175
cannam@226 176 SerdWriter* writer = serd_writer_new(
cannam@226 177 output_syntax,
cannam@226 178 (SerdStyle)output_style,
cannam@226 179 write_env, &base_uri, serd_file_sink, stdout);
cannam@226 180
cannam@226 181 // Write @prefix directives
cannam@226 182 serd_env_foreach(env,
cannam@226 183 (SerdPrefixSink)serd_writer_set_prefix,
cannam@226 184 writer);
cannam@226 185
cannam@226 186 // Write statements
cannam@226 187 sord_write(sord, writer, NULL);
cannam@226 188
cannam@226 189 serd_writer_finish(writer);
cannam@226 190 serd_writer_free(writer);
cannam@226 191
cannam@226 192 serd_env_free(env);
cannam@226 193 serd_env_free(write_env);
cannam@226 194 serd_node_free(&base);
cannam@226 195
cannam@226 196 sord_free(sord);
cannam@226 197 sord_world_free(world);
cannam@226 198
cannam@226 199 if (from_file) {
cannam@226 200 fclose(in_fd);
cannam@226 201 }
cannam@226 202
cannam@226 203 if (fclose(out_fd)) {
cannam@226 204 perror("sordi: write error");
cannam@226 205 status = SERD_ERR_UNKNOWN;
cannam@226 206 }
cannam@226 207
cannam@226 208 return (status > SERD_FAILURE) ? 1 : 0;
cannam@226 209 }