summaryrefslogtreecommitdiffstats
path: root/src/raptor_option.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/raptor_option.c')
-rw-r--r--src/raptor_option.c718
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;
+}