/** * raptor_init: * * Initialise the raptor library. * * This function MUST be called before using any of the raptor APIs. **/ void raptor_init(void) { if(raptor_initialised++) return; if(raptor_sax2_init()) goto failure; if(raptor_parsers_init()) goto failure; if(raptor_serializers_init()) goto failure; if(raptor_uri_init()) goto failure; raptor_www_init(); /* raptor_www_init() is part of raptor API, prototype not changed yet to return an error code */ return; failure: raptor_finish(); RAPTOR_FATAL1("raptor_init() failed"); }
/* * raptor_turtle_emit_subject_list_items: * @serializer: #raptor_serializer object * @subject: subject node * @depth: depth into tree * * Emit an rdf list of items (rdf:li) about a subject node. * * Return value: non-0 on failure **/ static int raptor_turtle_emit_subject_list_items(raptor_serializer* serializer, raptor_abbrev_subject* subject, int depth) { int rv = 0; int i=0; RAPTOR_DEBUG5("Emitting subject list items for node %p refcount %d subject %d object %d\n", subject->node, subject->node->ref_count, subject->node->count_as_subject, subject->node->count_as_object); while(!rv && i < raptor_sequence_size(subject->list_items)) { raptor_abbrev_node* object; object = (raptor_abbrev_node*)raptor_sequence_get_at(subject->list_items, i++); if(!object) continue; switch(object->type) { case RAPTOR_IDENTIFIER_TYPE_RESOURCE: rv = raptor_turtle_emit_resource(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_LITERAL: rv = raptor_turtle_emit_literal(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: rv = raptor_turtle_emit_xml_literal(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: rv = raptor_turtle_emit_blank(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: /* ordinals should never appear as an object with current parsers */ case RAPTOR_IDENTIFIER_TYPE_PREDICATE: /* predicates should never appear as an object */ case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: RAPTOR_FATAL1("Unsupported identifier type\n"); break; } } return rv; }
/* * raptor_abbrev_subject implementation * * The subject of triples, with all predicates and values * linked from them. * **/ raptor_abbrev_subject* raptor_new_abbrev_subject(raptor_abbrev_node* node) { raptor_abbrev_subject* subject; if(!(node->type == RAPTOR_IDENTIFIER_TYPE_RESOURCE || node->type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS || node->type == RAPTOR_IDENTIFIER_TYPE_ORDINAL)) { RAPTOR_FATAL1("Subject node must be a resource, blank, or ordinal\n"); return NULL; } subject = (raptor_abbrev_subject*)RAPTOR_CALLOC(raptor_subject, 1, sizeof(raptor_abbrev_subject)); if(subject) { subject->node = node; subject->node->ref_count++; subject->node->count_as_subject++; subject->node_type = NULL; subject->properties = raptor_new_avltree((raptor_data_compare_function)raptor_compare_abbrev_po, (raptor_data_free_function)raptor_free_abbrev_po, 0); #ifdef RAPTOR_DEBUG raptor_avltree_set_print_handler(subject->properties, (raptor_data_print_function)raptor_print_abbrev_po); #endif subject->list_items = raptor_new_sequence((raptor_sequence_free_handler *)raptor_free_abbrev_node, NULL); if(!subject->node || !subject->properties || !subject->list_items) { raptor_free_abbrev_subject(subject); subject = NULL; } } return subject; }
static void raptor_librdfa_generate_statement(rdftriple* triple, void* callback_data) { raptor_parser* parser=(raptor_parser*)callback_data; raptor_statement *s=&parser->statement; raptor_uri *subject_uri=NULL; raptor_uri *predicate_uri=NULL; raptor_uri *object_uri=NULL; raptor_uri *datatype_uri=NULL; if(!triple->subject || !triple->predicate || !triple->object) { RAPTOR_FATAL1("Triple has NULL parts\n"); rdfa_free_triple(triple); return; } if(triple->object_type == RDF_TYPE_NAMESPACE_PREFIX) { RAPTOR_FATAL1("Triple has namespace object type\n"); rdfa_free_triple(triple); return; } if((triple->subject[0] == '_') && (triple->subject[1] == ':')) { s->subject_type = RAPTOR_IDENTIFIER_TYPE_ANONYMOUS; s->subject= (triple->subject + 2); } else { s->subject_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE; subject_uri=raptor_new_uri((const unsigned char*)triple->subject); if(!subject_uri) goto cleanup; s->subject=subject_uri; } predicate_uri=raptor_new_uri((const unsigned char*)triple->predicate); if(!predicate_uri) goto cleanup; s->predicate=predicate_uri; s->predicate_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE; s->object = triple->object; s->object_literal_datatype=NULL; s->object_literal_language=NULL; if(triple->object_type == RDF_TYPE_IRI) { if((triple->object[0] == '_') && (triple->object[1] == ':')) { s->object_type = RAPTOR_IDENTIFIER_TYPE_ANONYMOUS; s->object = (triple->object + 2); } else { s->object_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE; object_uri=raptor_new_uri((const unsigned char*)triple->object); if(!object_uri) goto cleanup; s->object=object_uri; } } else if(triple->object_type == RDF_TYPE_PLAIN_LITERAL) { s->object_type=RAPTOR_IDENTIFIER_TYPE_LITERAL; if(triple->language) s->object_literal_language=(const unsigned char*)triple->language; } else if(triple->object_type == RDF_TYPE_XML_LITERAL) { s->object_type = RAPTOR_IDENTIFIER_TYPE_XML_LITERAL; } else if(triple->object_type == RDF_TYPE_TYPED_LITERAL) { s->object_type=RAPTOR_IDENTIFIER_TYPE_LITERAL; if(triple->language) s->object_literal_language=(const unsigned char*)triple->language; if(triple->datatype) { datatype_uri=raptor_new_uri((const unsigned char*)triple->datatype); if(!datatype_uri) goto cleanup; s->object_literal_datatype=datatype_uri; /* If datatype, no language allowed */ s->object_literal_language=NULL; } } else { RAPTOR_FATAL2("Triple has unknown object type %d\n", s->object_type); goto cleanup; } if(!parser->statement_handler) goto cleanup; /* Generate triple */ (*parser->statement_handler)(parser->user_data, s); cleanup: rdfa_free_triple(triple); if(subject_uri) raptor_free_uri(subject_uri); if(predicate_uri) raptor_free_uri(predicate_uri); if(object_uri) raptor_free_uri(object_uri); if(datatype_uri) raptor_free_uri(datatype_uri); }
/* * raptor_turtle_emit_subject_properties: * @serializer: #raptor_serializer object * @subject: subject node * @depth: depth into tree * * Emit the properties about a subject node. * * Return value: non-0 on failure **/ static int raptor_turtle_emit_subject_properties(raptor_serializer* serializer, raptor_abbrev_subject* subject, int depth) { raptor_turtle_context* context=(raptor_turtle_context*)serializer->context; raptor_turtle_writer *turtle_writer = context->turtle_writer; raptor_abbrev_node* last_predicate=NULL; int rv = 0; raptor_avltree_iterator* iter=NULL; int i; RAPTOR_DEBUG5("Emitting subject properties for node %p refcount %d subject %d object %d\n", subject->node, subject->node->ref_count, subject->node->count_as_subject, subject->node->count_as_object); /* Emit any rdf:_n properties collected */ if(raptor_sequence_size(subject->list_items) > 0) rv = raptor_turtle_emit_subject_list_items(serializer, subject, depth+1); for(i=0, (iter=raptor_new_avltree_iterator(subject->properties, NULL, NULL, 1)); iter && !rv; i++, (rv=raptor_avltree_iterator_next(iter))) { raptor_abbrev_node** nodes; raptor_abbrev_node* predicate; raptor_abbrev_node* object; raptor_qname *qname; nodes=(raptor_abbrev_node**)raptor_avltree_iterator_get(iter); if(!nodes) break; predicate= nodes[0]; object= nodes[1]; if(!(last_predicate && raptor_abbrev_node_equals(predicate, last_predicate))) { /* no object list abbreviation possible, terminate last object */ if(last_predicate) { raptor_turtle_writer_raw(turtle_writer, (const unsigned char*)" ;"); raptor_turtle_writer_newline(turtle_writer); } if(predicate->type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) { /* we should only get here in rare cases -- usually when there * are multiple ordinals with the same value. */ unsigned char uri_string[MAX_ASCII_INT_SIZE + 2]; sprintf((char*)uri_string, "_%d", predicate->value.ordinal.ordinal); qname = raptor_new_qname_from_namespace_local_name_v2(serializer->world, context->rdf_nspace, uri_string, NULL); } else { qname = raptor_namespaces_qname_from_uri(context->nstack, predicate->value.resource.uri, 10); } if(raptor_abbrev_node_equals(predicate, context->rdf_type)) raptor_turtle_writer_raw(turtle_writer, (const unsigned char*)"a"); else if(qname) raptor_turtle_writer_qname(turtle_writer, qname); else raptor_turtle_writer_reference(turtle_writer, predicate->value.resource.uri); raptor_turtle_writer_raw(turtle_writer, (const unsigned char*)" "); if(qname) raptor_free_qname(qname); } else raptor_turtle_writer_raw(turtle_writer, (const unsigned char*)", "); switch(object->type) { case RAPTOR_IDENTIFIER_TYPE_RESOURCE: rv = raptor_turtle_emit_resource(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_LITERAL: rv = raptor_turtle_emit_literal(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: rv = raptor_turtle_emit_blank(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: rv = raptor_turtle_emit_xml_literal(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: /* ordinals should never appear as an object with current parsers */ case RAPTOR_IDENTIFIER_TYPE_PREDICATE: /* predicates should never appear as an object */ case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: RAPTOR_FATAL1("Unsupported identifier type\n"); break; } last_predicate = predicate; } if (iter) raptor_free_avltree_iterator(iter); return rv; }
/* * raptor_turtle_emit_subject_collection_items: * @serializer: #raptor_serializer object * @subject: subject node * @depth: depth into tree * * Emit an abbreviated rdf collection of items (rdf:first, rdf:rest) about a subject node. * * Return value: non-0 on failure **/ static int raptor_turtle_emit_subject_collection_items(raptor_serializer* serializer, raptor_abbrev_subject* subject, int depth) { raptor_turtle_context* context=(raptor_turtle_context*)serializer->context; int rv = 0; raptor_avltree_iterator* iter=NULL; int i; int is_new_subject = 0; RAPTOR_DEBUG5("Emitting subject collection items for node %p refcount %d subject %d object %d\n", subject->node, subject->node->ref_count, subject->node->count_as_subject, subject->node->count_as_object); /* if just saw a new subject (is_new_subject is true) then there is no need * to advance the iterator - it was just reset */ for(i=0, (iter=raptor_new_avltree_iterator(subject->properties, NULL, NULL, 1)); iter && !rv; i++, (rv = is_new_subject ? 0 : raptor_avltree_iterator_next(iter))) { raptor_abbrev_node** nodes; raptor_abbrev_node* predicate; raptor_abbrev_node* object; is_new_subject = 0; nodes=(raptor_abbrev_node**)raptor_avltree_iterator_get(iter); if(!nodes) break; predicate= nodes[0]; object= nodes[1]; if(!raptor_uri_equals_v2(serializer->world, predicate->value.resource.uri, context->rdf_first_uri)) { raptor_serializer_error(serializer, "Malformed collection - first predicate is not rdf:first"); return 1; } if(!object) continue; if(i > 0) raptor_turtle_writer_newline(context->turtle_writer); switch(object->type) { case RAPTOR_IDENTIFIER_TYPE_RESOURCE: rv = raptor_turtle_emit_resource(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_LITERAL: rv = raptor_turtle_emit_literal(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: rv = raptor_turtle_emit_xml_literal(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: rv = raptor_turtle_emit_blank(serializer, object, depth+1); break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: /* ordinals should never appear as an object with current parsers */ case RAPTOR_IDENTIFIER_TYPE_PREDICATE: /* predicates should never appear as an object */ case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: RAPTOR_FATAL1("Unsupported identifier type\n"); break; } /* last item */ rv=raptor_avltree_iterator_next(iter); if(rv) break; nodes=(raptor_abbrev_node**)raptor_avltree_iterator_get(iter); predicate = nodes[0]; object = nodes[1]; if(!raptor_uri_equals_v2(serializer->world, predicate->value.resource.uri, context->rdf_rest_uri)) { raptor_serializer_error(serializer, "Malformed collection - second predicate is not rdf:rest"); return 1; } if(object->type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) { subject = raptor_abbrev_subject_find(context->blanks, object->type, object->value.blank.string); if(!subject) { raptor_serializer_error(serializer, "Malformed collection - could not find subject for rdf:rest"); return 1; } /* got a <(old)subject> rdf:rest <(new)subject> triple so know * subject has changed and should reset the properties iterator */ if(iter) raptor_free_avltree_iterator(iter); iter = raptor_new_avltree_iterator(subject->properties, NULL, NULL, 1); is_new_subject = 1; } else { if(object->type != RAPTOR_IDENTIFIER_TYPE_RESOURCE || !raptor_uri_equals_v2(serializer->world, object->value.resource.uri, context->rdf_nil_uri)) { raptor_serializer_error(serializer, "Malformed collection - last rdf:rest resource is not rdf:nil"); return 1; } break; } } if(iter) raptor_free_avltree_iterator(iter); return rv; }
/* * raptor_dot_serializer_node_matches: * @node: #raptor_node to compare * @node_type: Raptor identifier type * @node_data: For node_type RAPTOR_IDENTIFIER_TYPE_ORDINAL, int* to the * ordinal. * @datatype: Literal datatype or NULL * @language: Literal language or NULL * * Return value: non-zero if @node matches the node described by the rest of * the parameters. */ static int raptor_dot_serializer_node_matches(raptor_dot_serializer_node* node, raptor_identifier_type node_type, const void* node_data, raptor_uri* datatype, const unsigned char* language) { int rv = 0; if(node->type != node_type) return 0; switch (node->type) { case RAPTOR_IDENTIFIER_TYPE_RESOURCE: case RAPTOR_IDENTIFIER_TYPE_PREDICATE: rv = raptor_uri_equals(node->value.resource.uri, (raptor_uri*)node_data); break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: rv = !strcmp((const char*)node->value.blank.string, (const char*)node_data); break; case RAPTOR_IDENTIFIER_TYPE_LITERAL: case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: if((char*)node->value.literal.string != NULL && (char*)node_data != NULL) { /* string */ rv = (strcmp((char*)node->value.literal.string, (char*)node_data) == 0); /* language */ if((char*)node->value.literal.language != NULL && (char*)language != NULL) rv &= (strcmp((char*)node->value.literal.language, (char*)language) == 0); else if((char*)node->value.literal.language != NULL || (char*)language != NULL) rv= 0; /* datatype */ if(node->value.literal.datatype != NULL && datatype != NULL) rv &= (raptor_uri_equals(node->value.literal.datatype,datatype) !=0); else if(node->value.literal.datatype != NULL || datatype != NULL) rv = 0; } else { RAPTOR_FATAL1("string must be non-NULL for literal or xml literal\n"); rv = 0; } break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: /* Nothing to do */ break; } return rv; }
static void raptor_librdfa_generate_statement(rdftriple* triple, void* callback_data) { raptor_parser* parser = (raptor_parser*)callback_data; raptor_statement *s = &parser->statement; raptor_term *subject_term = NULL; raptor_term *predicate_term = NULL; raptor_uri *predicate_uri = NULL; raptor_term *object_term = NULL; if(!parser->emitted_default_graph) { raptor_parser_start_graph(parser, NULL, 0); parser->emitted_default_graph++; } if(!parser->statement_handler) goto cleanup; if(!triple->subject || !triple->predicate || !triple->object) { #ifdef RAPTOR_DEBUG RAPTOR_FATAL1("Triple has NULL parts\n"); #else rdfa_free_triple(triple); return; #endif } if(triple->predicate[0] == '_') { raptor_parser_warning(parser, "Ignoring RDFa triple with blank node predicate %s.", triple->predicate); rdfa_free_triple(triple); return; } if(triple->object_type == RDF_TYPE_NAMESPACE_PREFIX) { #ifdef RAPTOR_DEBUG RAPTOR_FATAL1("Triple has namespace object type\n"); #else rdfa_free_triple(triple); return; #endif } if((triple->subject[0] == '_') && (triple->subject[1] == ':')) { subject_term = raptor_new_term_from_blank(parser->world, (const unsigned char*)triple->subject + 2); } else { raptor_uri* subject_uri; subject_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->subject); subject_term = raptor_new_term_from_uri(parser->world, subject_uri); raptor_free_uri(subject_uri); subject_uri = NULL; } s->subject = subject_term; predicate_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->predicate); if(!predicate_uri) goto cleanup; predicate_term = raptor_new_term_from_uri(parser->world, predicate_uri); raptor_free_uri(predicate_uri); predicate_uri = NULL; s->predicate = predicate_term; if(triple->object_type == RDF_TYPE_IRI) { if((triple->object[0] == '_') && (triple->object[1] == ':')) { object_term = raptor_new_term_from_blank(parser->world, (const unsigned char*)triple->object + 2); } else { raptor_uri* object_uri; object_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->object); if(!object_uri) goto cleanup; object_term = raptor_new_term_from_uri(parser->world, object_uri); raptor_free_uri(object_uri); } } else if(triple->object_type == RDF_TYPE_PLAIN_LITERAL) { object_term = raptor_new_term_from_literal(parser->world, (const unsigned char*)triple->object, NULL, (const unsigned char*)triple->language); } else if(triple->object_type == RDF_TYPE_XML_LITERAL) { raptor_uri* datatype_uri; datatype_uri = raptor_new_uri_from_counted_string(parser->world, (const unsigned char*)raptor_xml_literal_datatype_uri_string, raptor_xml_literal_datatype_uri_string_len); object_term = raptor_new_term_from_literal(parser->world, (const unsigned char*)triple->object, datatype_uri, NULL); raptor_free_uri(datatype_uri); } else if(triple->object_type == RDF_TYPE_TYPED_LITERAL) { raptor_uri *datatype_uri = NULL; const unsigned char* language = (const unsigned char*)triple->language; if(triple->datatype) { /* If datatype, no language allowed */ language = NULL; datatype_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->datatype); if(!datatype_uri) goto cleanup; } object_term = raptor_new_term_from_literal(parser->world, (const unsigned char*)triple->object, datatype_uri, language); raptor_free_uri(datatype_uri); } else { raptor_log_error_formatted(parser->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Triple has unknown object term type %u", s->object->type); goto cleanup; } s->object = object_term; /* Generate statement */ (*parser->statement_handler)(parser->user_data, s); cleanup: rdfa_free_triple(triple); if(subject_term) raptor_free_term(subject_term); if(predicate_term) raptor_free_term(predicate_term); if(object_term) raptor_free_term(object_term); }
/* * raptor_new_qname_from_resource: * @namespaces: sequence of namespaces (corresponding to nstack) * @nstack: #raptor_namespace_stack to use/update * @namespace_count: size of nstack (may be modified) * @node: #raptor_abbrev_node to use * * Make an XML QName from the URI associated with the node. * * Return value: the QName or NULL on failure **/ raptor_qname* raptor_new_qname_from_resource(raptor_sequence* namespaces, raptor_namespace_stack* nstack, int* namespace_count, raptor_abbrev_node* node) { unsigned char* name=NULL; /* where to split predicate name */ size_t name_len=1; unsigned char *uri_string; size_t uri_len; unsigned char c; unsigned char *p; raptor_uri *ns_uri; raptor_namespace *ns; raptor_qname *qname; if(node->type != RAPTOR_IDENTIFIER_TYPE_RESOURCE) { RAPTOR_FATAL1("Node must be a resource\n"); return NULL; } qname=raptor_namespaces_qname_from_uri(nstack, node->value.resource.uri, 10); if(qname) return qname; uri_string = raptor_uri_as_counted_string(node->value.resource.uri, &uri_len); p= uri_string; name_len=uri_len; while(name_len >0) { if(raptor_xml_name_check(p, name_len, 10)) { name=p; break; } p++; name_len--; } if(!name || (name == uri_string)) return NULL; c=*name; *name='\0'; ns_uri=raptor_new_uri(uri_string); if(!ns_uri) return NULL; *name=c; ns = raptor_namespaces_find_namespace_by_uri(nstack, ns_uri); if(!ns) { /* The namespace was not declared, so create one */ unsigned char prefix[2 + MAX_ASCII_INT_SIZE + 1]; *namespace_count = *namespace_count + 1; sprintf((char *)prefix, "ns%d", *namespace_count); ns = raptor_new_namespace_from_uri(nstack, prefix, ns_uri, 0); /* We'll most likely need this namespace again. Push it on our * stack. It will be deleted in * raptor_rdfxmla_serialize_terminate */ if(raptor_sequence_push(namespaces, ns)) { /* namespaces sequence has no free handler so we have to free the ns ourselves on error */ raptor_free_namespace(ns); raptor_free_uri(ns_uri); return NULL; } } qname = raptor_new_qname_from_namespace_local_name(ns, name, NULL); raptor_free_uri(ns_uri); return qname; }
/* compare two raptor_abbrev_nodes. * * This needs to be a strong ordering for use by raptor_avltree. * This is very performance critical, anything to make it faster is worth it. */ int raptor_abbrev_node_cmp(raptor_abbrev_node* node1, raptor_abbrev_node* node2) { int rv = 0; if(node1 == node2) { return 0; } else if(node1->type < node2->type) { return -1; } else if(node1->type > node2->type) { return 1; } switch (node1->type) { case RAPTOR_IDENTIFIER_TYPE_RESOURCE: case RAPTOR_IDENTIFIER_TYPE_PREDICATE: rv = raptor_uri_compare(node1->value.resource.uri, node2->value.resource.uri); break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: rv = strcmp((const char*)node1->value.blank.string, (const char*)node2->value.blank.string); break; case RAPTOR_IDENTIFIER_TYPE_LITERAL: case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: if((char *)node1->value.literal.string != NULL && (char *)node2->value.literal.string != NULL) { /* string */ rv = strcmp((const char*)node1->value.literal.string, (const char*)node2->value.literal.string); if(rv != 0) { break; /* if string is equal, order by language */ } else { if((const char*)node1->value.literal.language != NULL && (const char*)node2->value.literal.language != NULL) { rv = strcmp((const char*)node1->value.literal.language, (const char*)node2->value.literal.language); } else if(node1->value.literal.language == NULL) { rv = -1; break; } else { rv = 1; break; } } /* if string and language are equal, order by datatype */ /* (rv == 0 if we get here) */ if(node1->value.literal.datatype != NULL && node2->value.literal.datatype != NULL) { rv = strcmp((char*)node1->value.literal.datatype, (char*)node2->value.literal.datatype); } else if(node1->value.literal.datatype == NULL) { rv = -1; } else { rv = 1; } } else { RAPTOR_FATAL1("string must be non-NULL for literal or xml literal\n"); rv = 0; } break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: if(node1->value.ordinal.ordinal == node2->value.ordinal.ordinal) rv = 0; else if(node1->value.ordinal.ordinal < node2->value.ordinal.ordinal) rv = -1; else rv = 1; break; case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: /* Nothing to do */ break; } return rv; }