diff options
Diffstat (limited to 'src/raptor_option.c')
-rw-r--r-- | src/raptor_option.c | 718 |
1 files changed, 718 insertions, 0 deletions
diff --git a/src/raptor_option.c b/src/raptor_option.c new file mode 100644 index 0000000..119dfb8 --- /dev/null +++ b/src/raptor_option.c @@ -0,0 +1,718 @@ +/* -*- Mode: c; c-basic-offset: 2 -*- + * + * raptor_option.c - Class options + * + * Copyright (C) 2004-2010, David Beckett http://www.dajobe.org/ + * Copyright (C) 2004-2005, University of Bristol, UK http://www.bristol.ac.uk/ + * + * This package is Free Software and part of Redland http://librdf.org/ + * + * It is licensed under the following three licenses as alternatives: + * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version + * 2. GNU General Public License (GPL) V2 or any newer version + * 3. Apache License, V2.0 or any newer version + * + * You may not use this file except in compliance with at least one of + * the above three licenses. + * + * See LICENSE.html or LICENSE.txt at the top of this package for the + * complete terms and further detail along with the license texts for + * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively. + * + * + */ + + +#ifdef HAVE_CONFIG_H +#include <raptor_config.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdarg.h> + +/* Raptor includes */ +#include "raptor2.h" +#include "raptor_internal.h" + + +static const struct +{ + raptor_option option; + raptor_option_area area; + raptor_option_value_type value_type; + const char *name; + const char *label; +} raptor_options_list[RAPTOR_OPTION_LAST + 1] = { + { RAPTOR_OPTION_SCANNING, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "scanForRDF", + "RDF/XML parser scans for rdf:RDF in XML content" + }, + { RAPTOR_OPTION_ALLOW_NON_NS_ATTRIBUTES, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "allowNonNsAttributes", + "RDF/XML parser allows bare 'name' rather than namespaced 'rdf:name'" + }, + { RAPTOR_OPTION_ALLOW_OTHER_PARSETYPES, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "allowOtherParsetypes", + "RDF/XML parser allows user-defined rdf:parseType values" + }, + { RAPTOR_OPTION_ALLOW_BAGID, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "allowBagID", + "RDF/XML parser allows rdf:bagID" + }, + { RAPTOR_OPTION_ALLOW_RDF_TYPE_RDF_LIST, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "allowRDFtypeRDFlist", + "RDF/XML parser generates the collection rdf:type rdf:List triple" + }, + { RAPTOR_OPTION_NORMALIZE_LANGUAGE, + (raptor_option_area)(RAPTOR_OPTION_AREA_PARSER | RAPTOR_OPTION_AREA_SAX2), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "normalizeLanguage", + "RDF/XML parser normalizes xml:lang values to lowercase" + }, + { RAPTOR_OPTION_NON_NFC_FATAL, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "nonNFCfatal", + "RDF/XML parser makes non-NFC literals a fatal error" + }, + { RAPTOR_OPTION_WARN_OTHER_PARSETYPES, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "warnOtherParseTypes", + "RDF/XML parser warns about unknown rdf:parseType values" + }, + { RAPTOR_OPTION_CHECK_RDF_ID, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "checkRdfID", + "RDF/XML parser checks rdf:ID values for duplicates" + }, + { RAPTOR_OPTION_RELATIVE_URIS, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "relativeURIs", + "Serializers write relative URIs wherever possible." + }, + { RAPTOR_OPTION_WRITER_AUTO_INDENT, + (raptor_option_area)(RAPTOR_OPTION_AREA_XML_WRITER | RAPTOR_OPTION_AREA_TURTLE_WRITER), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "autoIndent", + "Turtle and XML Writer automatically indent elements." + }, + { RAPTOR_OPTION_WRITER_AUTO_EMPTY, + (raptor_option_area)(RAPTOR_OPTION_AREA_XML_WRITER | RAPTOR_OPTION_AREA_TURTLE_WRITER), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "autoEmpty", + "Turtle and XML Writer automatically detect and abbreviate empty elements." + }, + { RAPTOR_OPTION_WRITER_INDENT_WIDTH, + (raptor_option_area)(RAPTOR_OPTION_AREA_XML_WRITER | RAPTOR_OPTION_AREA_TURTLE_WRITER), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "indentWidth", + "Turtle and XML Writer use as number of spaces to indent." + }, + { RAPTOR_OPTION_WRITER_XML_VERSION, + (raptor_option_area)(RAPTOR_OPTION_AREA_SERIALIZER | RAPTOR_OPTION_AREA_XML_WRITER), + RAPTOR_OPTION_VALUE_TYPE_INT, + "xmlVersion", + "Serializers and XML Writer use as XML version to write." + }, + { RAPTOR_OPTION_WRITER_XML_DECLARATION, + (raptor_option_area)(RAPTOR_OPTION_AREA_SERIALIZER | RAPTOR_OPTION_AREA_XML_WRITER), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "xmlDeclaration", + "Serializers and XML Writer write XML declaration." + }, + { RAPTOR_OPTION_NO_NET, + (raptor_option_area)(RAPTOR_OPTION_AREA_PARSER | RAPTOR_OPTION_AREA_SAX2), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "noNet", + "Parsers and SAX2 XML Parser deny internal network requests." + }, + { RAPTOR_OPTION_RESOURCE_BORDER, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "resourceBorder", + "DOT serializer resource border color" + }, + { RAPTOR_OPTION_LITERAL_BORDER, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "literalBorder", + "DOT serializer literal border color" + }, + { RAPTOR_OPTION_BNODE_BORDER, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "bnodeBorder", + "DOT serializer blank node border color" + }, + { RAPTOR_OPTION_RESOURCE_FILL, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "resourceFill", + "DOT serializer resource fill color" + }, + { RAPTOR_OPTION_LITERAL_FILL, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "literalFill", + "DOT serializer literal fill color" + }, + { RAPTOR_OPTION_BNODE_FILL, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "bnodeFill", + "DOT serializer blank node fill color" + }, + { RAPTOR_OPTION_HTML_TAG_SOUP, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "htmlTagSoup", + "GRDDL parser uses a lax HTML parser" + }, + { RAPTOR_OPTION_MICROFORMATS, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "microformats", + "GRDDL parser looks for microformats" + }, + { RAPTOR_OPTION_HTML_LINK, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "htmlLink", + "GRDDL parser looks for <link type=\"application/rdf+xml\">" + }, + { RAPTOR_OPTION_WWW_TIMEOUT, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_INT, + "wwwTimeout", + "Parser WWW request retrieval timeout" + }, + { RAPTOR_OPTION_WRITE_BASE_URI, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "writeBaseURI", + "Serializers write a base URI directive @base / xml:base" + }, + { RAPTOR_OPTION_WWW_HTTP_CACHE_CONTROL, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "wwwHttpCacheControl", + "Parser WWW request HTTP Cache-Control: header value" + }, + { RAPTOR_OPTION_WWW_HTTP_USER_AGENT, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "wwwHttpUserAgent", + "Parser WWW request HTTP User-Agent: header value" + }, + { RAPTOR_OPTION_JSON_CALLBACK, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "jsonCallback", + "JSON serializer callback function name" + }, + { RAPTOR_OPTION_JSON_EXTRA_DATA, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "jsonExtraData", + "JSON serializer callback data parameter" + }, + { RAPTOR_OPTION_RSS_TRIPLES, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "rssTriples", + "Atom and RSS serializers write extra RDF triples" + }, + { RAPTOR_OPTION_ATOM_ENTRY_URI, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_URI, + "atomEntryUri", + "Atom serializer writes an atom:entry with this URI (otherwise atom:feed)" + }, + { RAPTOR_OPTION_PREFIX_ELEMENTS, + RAPTOR_OPTION_AREA_SERIALIZER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "prefixElements", + "Atom and RSS serializers write namespace-prefixed elements" + }, + { RAPTOR_OPTION_STRICT, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "strict", + "Operate in strict conformance mode (otherwise lax)" + }, + { RAPTOR_OPTION_WWW_CERT_FILENAME, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "wwwCertFilename", + "SSL client certificate filename" + }, + { RAPTOR_OPTION_WWW_CERT_TYPE, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "wwwCertType", + "SSL client certificate type" + }, + { RAPTOR_OPTION_WWW_CERT_PASSPHRASE, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_STRING, + "wwwCertPassphrase", + "SSL client certificate passphrase" + }, + { RAPTOR_OPTION_NO_FILE, + (raptor_option_area)(RAPTOR_OPTION_AREA_PARSER | RAPTOR_OPTION_AREA_SAX2), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "noFile", + "Parsers and SAX2 deny internal file requests." + }, + { RAPTOR_OPTION_WWW_SSL_VERIFY_PEER, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_INT, + "wwwSslVerifyPeer", + "SSL verify peer certficate" + }, + { RAPTOR_OPTION_WWW_SSL_VERIFY_HOST, + RAPTOR_OPTION_AREA_PARSER, + RAPTOR_OPTION_VALUE_TYPE_INT, + "wwwSslVerifyHost", + "SSL verify host matching" + }, + { RAPTOR_OPTION_LOAD_EXTERNAL_ENTITIES, + (raptor_option_area)(RAPTOR_OPTION_AREA_PARSER | RAPTOR_OPTION_AREA_SAX2), + RAPTOR_OPTION_VALUE_TYPE_BOOL, + "loadExternalEntities", + "Parsers and SAX2 should load external entities." + } +}; + + +static const char * const raptor_option_uri_prefix = "http://feature.librdf.org/raptor-"; +/* NOTE: this is strlen(raptor_option_uri_prefix) */ +static const int raptor_option_uri_prefix_len = 33; + + +static raptor_option_area +raptor_option_get_option_area_for_domain(raptor_domain domain) +{ + raptor_option_area area = RAPTOR_OPTION_AREA_NONE; + + if(domain == RAPTOR_DOMAIN_PARSER) + area = RAPTOR_OPTION_AREA_PARSER; + else if(domain == RAPTOR_DOMAIN_SERIALIZER) + area = RAPTOR_OPTION_AREA_SERIALIZER; + else if(domain == RAPTOR_DOMAIN_SAX2) + area = RAPTOR_OPTION_AREA_SAX2; + else if(domain == RAPTOR_DOMAIN_XML_WRITER) + area = RAPTOR_OPTION_AREA_XML_WRITER; + else if(domain == RAPTOR_DOMAIN_TURTLE_WRITER) + area = RAPTOR_OPTION_AREA_TURTLE_WRITER; + + return area; +} + + +/** + * raptor_free_option_description: + * @option_description: option description + * + * Destructor - free an option description object. + */ +void +raptor_free_option_description(raptor_option_description* option_description) +{ + if(!option_description) + return; + + /* these are shared strings pointing to static data in raptor_options_list[] */ + /* RAPTOR_FREE(char*, option_description->name); */ + /* RAPTOR_FREE(char*, option_description->label); */ + + if(option_description->uri) + raptor_free_uri(option_description->uri); + + RAPTOR_FREE(raptor_option_description, option_description); +} + + +/** + * raptor_world_get_option_description: + * @world: raptor world object + * @domain: domain + * @option: option enumeration (0+) + * + * Get a description of an option for a domain. + * + * The returned description must be freed with + * raptor_free_option_description(). + * + * Return value: option description or NULL on failure or if option is unknown + **/ +raptor_option_description* +raptor_world_get_option_description(raptor_world* world, + const raptor_domain domain, + const raptor_option option) +{ + raptor_option_area area; + raptor_option_description *option_description = NULL; + raptor_uri *base_uri = NULL; + int i; + + RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, raptor_world, NULL); + + raptor_world_open(world); + + area = raptor_option_get_option_area_for_domain(domain); + if(area == RAPTOR_OPTION_AREA_NONE) + return NULL; + + for(i = 0; i <= RAPTOR_OPTION_LAST; i++) { + if(raptor_options_list[i].option == option && + (raptor_options_list[i].area & area)) + break; + } + + if(i > RAPTOR_OPTION_LAST) + return NULL; + + option_description = RAPTOR_CALLOC(raptor_option_description*, 1, + sizeof(*option_description)); + if(!option_description) + return NULL; + + option_description->domain = domain; + option_description->option = option; + option_description->value_type = raptor_options_list[i].value_type; + option_description->name = raptor_options_list[i].name; + option_description->name_len = strlen(option_description->name); + option_description->label = raptor_options_list[i].label; + + base_uri = raptor_new_uri_from_counted_string(world, + (const unsigned char*)raptor_option_uri_prefix, + raptor_option_uri_prefix_len); + if(!base_uri) { + raptor_free_option_description(option_description); + return NULL; + } + + option_description->uri = raptor_new_uri_from_uri_local_name(world, + base_uri, + (const unsigned char*)raptor_options_list[i].name); + raptor_free_uri(base_uri); + if(!option_description->uri) { + raptor_free_option_description(option_description); + return NULL; + } + + return option_description; +} + + + +int +raptor_option_is_valid_for_area(const raptor_option option, + raptor_option_area area) +{ + if(option > RAPTOR_OPTION_LAST) + return 0; + return (raptor_options_list[option].area & area) != 0; +} + + +int +raptor_option_value_is_numeric(const raptor_option option) +{ + raptor_option_value_type t = raptor_options_list[option].value_type; + + return t == RAPTOR_OPTION_VALUE_TYPE_BOOL || + t == RAPTOR_OPTION_VALUE_TYPE_INT; +} + + +/** + * raptor_world_get_option_from_uri: + * @world: raptor_world instance + * @uri: option URI + * + * Get an option ID from a URI + * + * Option URIs are the concatenation of the string + * "http://feature.librdf.org/raptor-" plus the short name. + * + * They are automatically returned for any option described with + * raptor_world_get_option_description(). + * + * Return value: < 0 if the option is unknown or on error + **/ +raptor_option +raptor_world_get_option_from_uri(raptor_world* world, raptor_uri *uri) +{ + unsigned char *uri_string; + int i; + raptor_option option = (raptor_option)-1; + + if(!uri) + return option; + + RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, raptor_world, (raptor_option)-1); + + raptor_world_open(world); + + uri_string = raptor_uri_as_string(uri); + if(strncmp((const char*)uri_string, raptor_option_uri_prefix, + raptor_option_uri_prefix_len)) + return option; + + uri_string += raptor_option_uri_prefix_len; + + for(i = 0; i <= RAPTOR_OPTION_LAST; i++) + if(!strcmp(raptor_options_list[i].name, (const char*)uri_string)) { + option = (raptor_option)i; + break; + } + + return option; +} + + +/** + * raptor_option_get_count: + * + * Get the count of options defined. + * + * This is prefered to the compile time-only symbol #RAPTOR_OPTION_LAST + * and returns a count of the number of options which is + * #RAPTOR_OPTION_LAST + 1. + * + * Return value: count of options in the #raptor_option enumeration + **/ +unsigned int +raptor_option_get_count(void) +{ + return RAPTOR_OPTION_LAST + 1; +} + + +const char* const +raptor_option_value_type_labels[RAPTOR_OPTION_VALUE_TYPE_URI + 1] = { + "boolean", + "integer", + "string", + "uri" +}; + + +/** + * raptor_option_get_value_type_label: + * @type: value type + * + * Get a label for a value type + * + * Return value: label for type or NULL for invalid type + */ +const char* +raptor_option_get_value_type_label(const raptor_option_value_type type) +{ + if(type > RAPTOR_OPTION_VALUE_TYPE_LAST) + return NULL; + return raptor_option_value_type_labels[type]; +} + + +int +raptor_object_options_copy_state(raptor_object_options* to, + raptor_object_options* from) +{ + int rc = 0; + int i; + + to->area = from->area; + for(i = 0; !rc && i <= RAPTOR_OPTION_LAST; i++) { + if(raptor_option_value_is_numeric((raptor_option)i)) + to->options[i].integer = from->options[i].integer; + else { + /* non-numeric values may need allocations */ + char* string = from->options[i].string; + if(string) { + size_t len = strlen(string); + to->options[i].string = RAPTOR_MALLOC(char*, len + 1); + if(to->options[i].string) + memcpy(to->options[i].string, string, len + 1); + else + rc = 1; + } + } + } + + return rc; +} + + +void +raptor_object_options_init(raptor_object_options* options, + raptor_option_area area) +{ + int i; + + options->area = area; + + for(i = 0; i <= RAPTOR_OPTION_LAST; i++) { + if(raptor_option_value_is_numeric((raptor_option)i)) + options->options[i].integer = 0; + else + options->options[i].string = NULL; + } + + /* Initialise default options that are not 0 or NULL */ + + /* Emit @base directive or equivalent */ + options->options[RAPTOR_OPTION_WRITE_BASE_URI].integer = 1; + + /* Emit relative URIs where possible */ + options->options[RAPTOR_OPTION_RELATIVE_URIS].integer = 1; + + /* XML 1.0 output */ + options->options[RAPTOR_OPTION_WRITER_XML_VERSION].integer = 10; + + /* Write XML declaration */ + options->options[RAPTOR_OPTION_WRITER_XML_DECLARATION].integer = 1; + + /* Indent 2 spaces */ + options->options[RAPTOR_OPTION_WRITER_INDENT_WIDTH].integer = 2; + + /* lax (no strict) parsing */ + options->options[RAPTOR_OPTION_STRICT].integer = 0; + + /* SSL verify peers */ + options->options[RAPTOR_OPTION_WWW_SSL_VERIFY_PEER].integer = 1; + + /* SSL fully verify hosts */ + options->options[RAPTOR_OPTION_WWW_SSL_VERIFY_HOST].integer = 2; + +} + + +void +raptor_object_options_clear(raptor_object_options* options) +{ + int i; + + for(i = 0; i <= RAPTOR_OPTION_LAST; i++) { + if(raptor_option_value_is_numeric((raptor_option)i)) + continue; + + if(options->options[i].string) + RAPTOR_FREE(char*, options->options[i].string); + } +} + + +/* + * raptor_object_options_get_option: + * @options: options object + * @option: option to get value + * @string_p: pointer to where to store string value + * @integer_p: pointer to where to store integer value + * + * INTERNAL - get option value + * + * Any string value returned in *@string_p is shared and must be + * copied by the caller. + * + * The allowed options vary by the area field of @options. + * + * Return value: option value or < 0 for an illegal option + **/ +int +raptor_object_options_get_option(raptor_object_options* options, + raptor_option option, + char** string_p, int* integer_p) +{ + if(!raptor_option_is_valid_for_area(option, options->area)) + return 1; + + if(raptor_option_value_is_numeric(option)) { + /* numeric options */ + int value = options->options[(int)option].integer; + if(integer_p) + *integer_p = value; + } else { + /* non-numeric options */ + char* string = options->options[(int)option].string; + if(string_p) + *string_p = string; + } + + return 0; +} + + +/* + * raptor_object_options_set_option: + * @options: options object + * @option: option to set + * @string: string option value (or NULL) + * @integer: integer option value + * + * INTERNAL - set option + * + * If @string is not NULL and the option type is numeric, the string + * value is converted to an integer and used in preference to @integer. + * + * If @string is NULL and the option type is not numeric, an error is + * returned. + * + * The @string values used are copied. + * + * The allowed options vary by the area field of @options. + * + * Return value: non 0 on failure or if the option is unknown + **/ +int +raptor_object_options_set_option(raptor_object_options *options, + raptor_option option, + const char* string, int integer) +{ + if(!raptor_option_is_valid_for_area(option, options->area)) + return 1; + + if(raptor_option_value_is_numeric(option)) { + /* numeric options */ + if(string) + integer = atoi((const char*)string); + + options->options[(int)option].integer = integer; + return 0; + } else { + /* non-numeric options */ + char *string_copy; + size_t len = 0; + + if(string) + len = strlen((const char*)string); + string_copy = RAPTOR_MALLOC(char*, len + 1); + if(!string_copy) + return 1; + + if(len) + memcpy(string_copy, string, len); + string_copy[len] = '\0'; + + options->options[(int)option].string = string_copy; + } + + return 0; +} |