1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * raptor_term.c - Raptor terms
4 *
5 * Copyright (C) 2010, David Beckett http://www.dajobe.org/
6 *
7 * This package is Free Software and part of Redland http://librdf.org/
8 *
9 * It is licensed under the following three licenses as alternatives:
10 * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
11 * 2. GNU General Public License (GPL) V2 or any newer version
12 * 3. Apache License, V2.0 or any newer version
13 *
14 * You may not use this file except in compliance with at least one of
15 * the above three licenses.
16 *
17 * See LICENSE.html or LICENSE.txt at the top of this package for the
18 * complete terms and further detail along with the license texts for
19 * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <raptor_config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <stdarg.h>
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34
35 /* Raptor includes */
36 #include "raptor2.h"
37 #include "raptor_internal.h"
38
39
40 #ifndef STANDALONE
41
42 /**
43 * raptor_new_term_from_uri:
44 * @world: raptor world
45 * @uri: uri
46 *
47 * Constructor - create a new URI statement term
48 *
49 * Takes a copy (reference) of the passed in @uri
50 *
51 * Return value: new term or NULL on failure
52 */
53 raptor_term*
raptor_new_term_from_uri(raptor_world * world,raptor_uri * uri)54 raptor_new_term_from_uri(raptor_world* world, raptor_uri* uri)
55 {
56 raptor_term *t;
57
58 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
59
60 if(!uri)
61 return NULL;
62
63 raptor_world_open(world);
64
65 t = RAPTOR_CALLOC(raptor_term*, 1, sizeof(*t));
66 if(!t)
67 return NULL;
68
69 t->usage = 1;
70 t->world = world;
71 t->type = RAPTOR_TERM_TYPE_URI;
72 t->value.uri = raptor_uri_copy(uri);
73
74 return t;
75 }
76
77
78 /**
79 * raptor_new_term_from_counted_uri_string:
80 * @world: raptor world
81 * @uri_string: UTF-8 encoded URI string.
82 * @length: length of URI string
83 *
84 * Constructor - create a new URI statement term from a UTF-8 encoded Unicode string
85 *
86 * Note: The @uri_string need not be NULL terminated - a NULL will be
87 * added to the copied string used.
88 *
89 * Return value: new term or NULL on failure
90 */
91 raptor_term*
raptor_new_term_from_counted_uri_string(raptor_world * world,const unsigned char * uri_string,size_t length)92 raptor_new_term_from_counted_uri_string(raptor_world* world,
93 const unsigned char *uri_string,
94 size_t length)
95 {
96 raptor_term *t;
97 raptor_uri* uri;
98
99 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
100
101 uri = raptor_new_uri_from_counted_string(world, uri_string, length);
102 if(!uri)
103 return NULL;
104
105 t = raptor_new_term_from_uri(world, uri);
106
107 raptor_free_uri(uri);
108
109 return t;
110 }
111
112
113 /**
114 * raptor_new_term_from_uri_string:
115 * @world: raptor world
116 * @uri_string: UTF-8 encoded URI string.
117 *
118 * Constructor - create a new URI statement term from a UTF-8 encoded Unicode string
119 *
120 * Return value: new term or NULL on failure
121 */
122 raptor_term*
raptor_new_term_from_uri_string(raptor_world * world,const unsigned char * uri_string)123 raptor_new_term_from_uri_string(raptor_world* world,
124 const unsigned char *uri_string)
125 {
126 raptor_term *t;
127 raptor_uri* uri;
128
129 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
130
131 uri = raptor_new_uri(world, uri_string);
132 if(!uri)
133 return NULL;
134
135 t = raptor_new_term_from_uri(world, uri);
136
137 raptor_free_uri(uri);
138
139 return t;
140 }
141
142
143 /**
144 * raptor_new_term_from_counted_literal:
145 * @world: raptor world
146 * @literal: UTF-8 encoded literal string (or NULL for empty literal)
147 * @literal_len: length of literal
148 * @datatype: literal datatype URI (or NULL)
149 * @language: literal language (or NULL for no language)
150 * @language_len: literal language length
151 *
152 * Constructor - create a new literal statement term from a counted UTF-8 encoded literal string
153 *
154 * Takes copies of the passed in @literal, @datatype, @language
155 *
156 * Only one of @language or @datatype may be given. If both are
157 * given, NULL is returned. If @language is the empty string, it is
158 * the equivalent to NULL.
159 *
160 * Note: The @literal need not be NULL terminated - a NULL will be
161 * added to the copied string used.
162 *
163 * Return value: new term or NULL on failure
164 */
165 raptor_term*
raptor_new_term_from_counted_literal(raptor_world * world,const unsigned char * literal,size_t literal_len,raptor_uri * datatype,const unsigned char * language,unsigned char language_len)166 raptor_new_term_from_counted_literal(raptor_world* world,
167 const unsigned char* literal,
168 size_t literal_len,
169 raptor_uri* datatype,
170 const unsigned char* language,
171 unsigned char language_len)
172 {
173 raptor_term *t;
174 unsigned char* new_literal = NULL;
175 unsigned char* new_language = NULL;
176
177 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
178
179 raptor_world_open(world);
180
181 if(language && !*language)
182 language = NULL;
183
184 if(language && datatype)
185 return NULL;
186
187
188 new_literal = RAPTOR_MALLOC(unsigned char*, literal_len + 1);
189 if(!new_literal)
190 return NULL;
191
192 if(!literal || !*literal)
193 literal_len = 0;
194
195 if(literal_len) {
196 memcpy(new_literal, literal, literal_len);
197 new_literal[literal_len] = '\0';
198 } else
199 *new_literal = '\0';
200
201 if(language) {
202 unsigned char c;
203 unsigned char* l;
204
205 new_language = RAPTOR_MALLOC(unsigned char*, language_len + 1);
206 if(!new_language) {
207 RAPTOR_FREE(char*, new_literal);
208 return NULL;
209 }
210
211 l = new_language;
212 while((c = *language++)) {
213 if(c == '_')
214 c = '-';
215 *l++ = c;
216 }
217 *l = '\0';
218 } else
219 language_len = 0;
220
221 if(datatype)
222 datatype = raptor_uri_copy(datatype);
223
224
225 t = RAPTOR_CALLOC(raptor_term*, 1, sizeof(*t));
226 if(!t) {
227 if(new_literal)
228 RAPTOR_FREE(char*, new_literal);
229 if(new_language)
230 RAPTOR_FREE(char*, new_language);
231 if(datatype)
232 raptor_free_uri(datatype);
233 return NULL;
234 }
235 t->usage = 1;
236 t->world = world;
237 t->type = RAPTOR_TERM_TYPE_LITERAL;
238 t->value.literal.string = new_literal;
239 t->value.literal.string_len = RAPTOR_LANG_LEN_FROM_INT(literal_len);
240 t->value.literal.language = new_language;
241 t->value.literal.language_len = language_len;
242 t->value.literal.datatype = datatype;
243
244 return t;
245 }
246
247
248 /**
249 * raptor_new_term_from_literal:
250 * @world: raptor world
251 * @literal: UTF-8 encoded literal string (or NULL for empty literal)
252 * @datatype: literal datatype URI (or NULL)
253 * @language: literal language (or NULL)
254 *
255 * Constructor - create a new literal statement term
256 *
257 * Takes copies of the passed in @literal, @datatype, @language
258 *
259 * Only one of @language or @datatype may be given. If both are
260 * given, NULL is returned. If @language is the empty string, it is
261 * the equivalent to NULL.
262 *
263 * Return value: new term or NULL on failure
264 */
265 raptor_term*
raptor_new_term_from_literal(raptor_world * world,const unsigned char * literal,raptor_uri * datatype,const unsigned char * language)266 raptor_new_term_from_literal(raptor_world* world,
267 const unsigned char* literal,
268 raptor_uri* datatype,
269 const unsigned char* language)
270 {
271 size_t literal_len = 0;
272 size_t language_len = 0;
273
274 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
275
276 raptor_world_open(world);
277
278 if(literal)
279 literal_len = strlen(RAPTOR_GOOD_CAST(const char*, literal));
280
281 if(language)
282 language_len = strlen(RAPTOR_GOOD_CAST(const char*, language));
283
284 return raptor_new_term_from_counted_literal(world, literal, literal_len,
285 datatype, language,
286 RAPTOR_BAD_CAST(unsigned char, language_len));
287 }
288
289
290 /**
291 * raptor_new_term_from_counted_blank:
292 * @world: raptor world
293 * @blank: UTF-8 encoded blank node identifier (or NULL)
294 * @length: length of identifier (or 0)
295 *
296 * Constructor - create a new blank node statement term from a counted UTF-8 encoded blank node ID
297 *
298 * Takes a copy of the passed in @blank
299 *
300 * If @blank is NULL, creates a new internal identifier and uses it.
301 * This will use the handler set with
302 * raptor_world_set_generate_bnodeid_parameters()
303 *
304 * Note: The @blank need not be NULL terminated - a NULL will be
305 * added to the copied string used.
306 *
307 * Return value: new term or NULL on failure
308 */
309 raptor_term*
raptor_new_term_from_counted_blank(raptor_world * world,const unsigned char * blank,size_t length)310 raptor_new_term_from_counted_blank(raptor_world* world,
311 const unsigned char* blank, size_t length)
312 {
313 raptor_term *t;
314 unsigned char* new_id;
315
316 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
317
318 raptor_world_open(world);
319
320 if (blank) {
321 new_id = RAPTOR_MALLOC(unsigned char*, length + 1);
322 if(!new_id)
323 return NULL;
324 memcpy(new_id, blank, length);
325 new_id[length] = '\0';
326 } else {
327 new_id = raptor_world_generate_bnodeid(world);
328 length = strlen((const char*)new_id);
329 }
330
331 t = RAPTOR_CALLOC(raptor_term*, 1, sizeof(*t));
332 if(!t) {
333 RAPTOR_FREE(char*, new_id);
334 return NULL;
335 }
336
337 t->usage = 1;
338 t->world = world;
339 t->type = RAPTOR_TERM_TYPE_BLANK;
340 t->value.blank.string = new_id;
341 t->value.blank.string_len = RAPTOR_BAD_CAST(int, length);
342
343 return t;
344 }
345
346
347 /**
348 * raptor_new_term_from_blank:
349 * @world: raptor world
350 * @blank: UTF-8 encoded blank node identifier (or NULL)
351 *
352 * Constructor - create a new blank node statement term from a UTF-8 encoded blank node ID
353 *
354 * Takes a copy of the passed in @blank
355 *
356 * If @blank is NULL or an empty string, creates a new internal
357 * identifier and uses it. This will use the handler set with
358 * raptor_world_set_generate_bnodeid_parameters()
359 *
360 * Return value: new term or NULL on failure
361 */
362 raptor_term*
raptor_new_term_from_blank(raptor_world * world,const unsigned char * blank)363 raptor_new_term_from_blank(raptor_world* world, const unsigned char* blank)
364 {
365 size_t length = 0;
366
367 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
368
369 raptor_world_open(world);
370
371 if(blank) {
372 if(*blank)
373 length = strlen((const char*)blank);
374 else
375 blank = NULL;
376 }
377
378 return raptor_new_term_from_counted_blank(world, blank, length);
379 }
380
381
382 /**
383 * raptor_new_term_from_counted_string:
384 * @world: raptor world
385 * @string: N-Triples format string (UTF-8)
386 * @length: length of @string (or 0)
387 *
388 * Constructor - create a new term from a Turtle / N-Triples format string in UTF-8
389 *
390 * See also raptor_term_to_counted_string() and raptor_term_to_string()
391 *
392 * Return value: new term or NULL on failure
393 */
394 raptor_term*
raptor_new_term_from_counted_string(raptor_world * world,unsigned char * string,size_t length)395 raptor_new_term_from_counted_string(raptor_world* world,
396 unsigned char* string, size_t length)
397 {
398 raptor_term* term = NULL;
399 size_t bytes_read;
400 raptor_locator locator;
401
402 RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
403
404 if(!string)
405 return NULL;
406
407 if(!length)
408 length = strlen(RAPTOR_GOOD_CAST(const char*, string));
409
410 raptor_world_open(world);
411
412 memset(&locator, '\0', sizeof(locator));
413 locator.line = -1;
414
415 bytes_read = raptor_ntriples_parse_term(world, &locator,
416 string, &length, &term, 1);
417
418 if(!bytes_read || length != 0) {
419 if(term)
420 raptor_free_term(term);
421 term = NULL;
422 }
423
424 return term;
425 }
426
427
428 /**
429 * raptor_term_copy:
430 * @term: raptor term
431 *
432 * Copy constructor - get a copy of a statement term
433 *
434 * Return value: new term object or NULL on failure
435 */
436 raptor_term*
raptor_term_copy(raptor_term * term)437 raptor_term_copy(raptor_term* term)
438 {
439 if(!term)
440 return NULL;
441
442 term->usage++;
443 return term;
444 }
445
446
447 /**
448 * raptor_free_term:
449 * @term: #raptor_term object
450 *
451 * Destructor - destroy a raptor_term object.
452 *
453 **/
454 void
raptor_free_term(raptor_term * term)455 raptor_free_term(raptor_term *term)
456 {
457 if(!term)
458 return;
459
460 if(--term->usage)
461 return;
462
463 switch(term->type) {
464 case RAPTOR_TERM_TYPE_URI:
465 if(term->value.uri) {
466 raptor_free_uri(term->value.uri);
467 term->value.uri = NULL;
468 }
469 break;
470
471 case RAPTOR_TERM_TYPE_BLANK:
472 if(term->value.blank.string) {
473 RAPTOR_FREE(char*, term->value.blank.string);
474 term->value.blank.string = NULL;
475 }
476 break;
477
478 case RAPTOR_TERM_TYPE_LITERAL:
479 if(term->value.literal.string) {
480 RAPTOR_FREE(char*, term->value.literal.string);
481 term->value.literal.string = NULL;
482 }
483
484 if(term->value.literal.datatype) {
485 raptor_free_uri(term->value.literal.datatype);
486 term->value.literal.datatype = NULL;
487 }
488
489 if(term->value.literal.language) {
490 RAPTOR_FREE(char*, term->value.literal.language);
491 term->value.literal.language = NULL;
492 }
493 break;
494
495 case RAPTOR_TERM_TYPE_UNKNOWN:
496 default:
497 break;
498 }
499
500 RAPTOR_FREE(term, term);
501 }
502
503
504 /**
505 * raptor_term_to_counted_string:
506 * @term: #raptor_term
507 * @len_p: Pointer to location to store length of new string (if not NULL)
508 *
509 * Turns a raptor term into a N-Triples format counted string.
510 *
511 * Turns the given @term into an N-Triples escaped string using all the
512 * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples
513 *
514 * This function uses raptor_term_ntriples_write() to write to an
515 * #raptor_iostream which is the prefered way to write formatted
516 * output.
517 *
518 * See also raptor_new_term_from_counted_string() to reverse this.
519 *
520 * See also raptor_term_to_turtle_string() to write as Turtle which
521 * will include Turtle syntax such as 'true' for booleans and """quoting"""
522 *
523 * Return value: the new string or NULL on failure. The length of
524 * the new string is returned in *@len_p if len_p is not NULL.
525 **/
526 unsigned char*
raptor_term_to_counted_string(raptor_term * term,size_t * len_p)527 raptor_term_to_counted_string(raptor_term *term, size_t* len_p)
528 {
529 raptor_iostream *iostr;
530 void *string = NULL;
531 int rc;
532
533 RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(term, raptor_term, NULL);
534
535 iostr = raptor_new_iostream_to_string(term->world,
536 &string, len_p, NULL);
537 if(!iostr)
538 return NULL;
539
540 rc = raptor_term_escaped_write(term, 0, iostr);
541 raptor_free_iostream(iostr);
542
543 if(rc) {
544 if(string) {
545 RAPTOR_FREE(char*, string);
546 string = NULL;
547 }
548 }
549
550 return (unsigned char *)string;
551 }
552
553
554 /**
555 * raptor_term_to_string:
556 * @term: #raptor_term
557 *
558 * Turns a raptor term into a N-Triples format string.
559 *
560 * Turns the given @term into an N-Triples escaped string using all the
561 * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples
562 *
563 * See also raptor_new_term_from_counted_string() to reverse this.
564 *
565 * See also raptor_term_to_turtle_string() to write as Turtle which
566 * will include Turtle syntax such as 'true' for booleans and """quoting"""
567 *
568 * Return value: the new string or NULL on failure.
569 **/
570 unsigned char*
raptor_term_to_string(raptor_term * term)571 raptor_term_to_string(raptor_term *term)
572 {
573 RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(term, raptor_term, NULL);
574
575 return raptor_term_to_counted_string(term, NULL);
576 }
577
578
579 /*
580 * raptor_term_print_as_ntriples:
581 * @term: #raptor_term
582 * @stream: FILE stream
583 *
584 * INTERNAL - Print a term as N-Triples
585 */
586 int
raptor_term_print_as_ntriples(const raptor_term * term,FILE * stream)587 raptor_term_print_as_ntriples(const raptor_term *term, FILE* stream)
588 {
589 int rc = 0;
590 raptor_iostream* iostr;
591
592 RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(term, raptor_term, 1);
593 RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, FILE*, 1);
594
595 iostr = raptor_new_iostream_to_file_handle(term->world, stream);
596 if(!iostr)
597 return 1;
598
599 rc = raptor_term_escaped_write(term, 0, iostr);
600
601 raptor_free_iostream(iostr);
602
603 return rc;
604 }
605
606
607 /**
608 * raptor_term_equals:
609 * @t1: first term
610 * @t2: second term
611 *
612 * Compare a pair of #raptor_term for equality
613 *
614 * Return value: non-0 if the terms are equal
615 */
616 int
raptor_term_equals(raptor_term * t1,raptor_term * t2)617 raptor_term_equals(raptor_term* t1, raptor_term* t2)
618 {
619 int d = 0;
620
621 if(!t1 || !t2)
622 return 0;
623
624 if(t1->type != t2->type)
625 return 0;
626
627 if(t1 == t2)
628 return 1;
629
630 switch(t1->type) {
631 case RAPTOR_TERM_TYPE_URI:
632 d = raptor_uri_equals(t1->value.uri, t2->value.uri);
633 break;
634
635 case RAPTOR_TERM_TYPE_BLANK:
636 if(t1->value.blank.string_len != t2->value.blank.string_len)
637 /* different lengths */
638 break;
639
640 d = !strcmp((const char*)t1->value.blank.string,
641 (const char*)t2->value.blank.string);
642 break;
643
644 case RAPTOR_TERM_TYPE_LITERAL:
645 if(t1->value.literal.string_len != t2->value.literal.string_len)
646 /* different lengths */
647 break;
648
649 d = !strcmp((const char*)t1->value.literal.string,
650 (const char*)t2->value.literal.string);
651 if(!d)
652 break;
653
654 if(t1->value.literal.language && t2->value.literal.language) {
655 /* both have a language */
656 d = !strcmp((const char*)t1->value.literal.language,
657 (const char*)t2->value.literal.language);
658 if(!d)
659 break;
660 } else if(t1->value.literal.language || t2->value.literal.language) {
661 /* only one has a language - different */
662 d = 0;
663 break;
664 }
665
666 if(t1->value.literal.datatype && t2->value.literal.datatype) {
667 /* both have a datatype */
668 d = raptor_uri_equals(t1->value.literal.datatype,
669 t2->value.literal.datatype);
670 } else if(t1->value.literal.datatype || t2->value.literal.datatype) {
671 /* only one has a datatype - different */
672 d = 0;
673 }
674 break;
675
676 case RAPTOR_TERM_TYPE_UNKNOWN:
677 default:
678 break;
679 }
680
681 return d;
682 }
683
684
685 /**
686 * raptor_term_compare:
687 * @t1: first term
688 * @t2: second term
689 *
690 * Compare a pair of #raptor_term
691 *
692 * If types are different, the #raptor_term_type order is used.
693 *
694 * Resource and datatype URIs are compared with raptor_uri_compare(),
695 * blank nodes and literals with strcmp(). If one literal has no
696 * language, it is earlier than one with a language. If one literal
697 * has no datatype, it is earlier than one with a datatype.
698 *
699 * Return value: <0 if t1 is before t2, 0 if equal, >0 if t1 is after t2
700 */
701 int
raptor_term_compare(const raptor_term * t1,const raptor_term * t2)702 raptor_term_compare(const raptor_term *t1, const raptor_term *t2)
703 {
704 int d = 0;
705
706 /* check for NULL terms */
707 if(!t1 || !t2) {
708 if(!t1 && !t2)
709 return 0; /* both NULL */
710
711 /* place NULLs before any other term */
712 return t1 ? 1 : -1;
713 }
714
715 if(t1->type != t2->type)
716 return (t1->type - t2->type);
717
718 switch(t1->type) {
719 case RAPTOR_TERM_TYPE_URI:
720 d = raptor_uri_compare(t1->value.uri, t2->value.uri);
721 break;
722
723 case RAPTOR_TERM_TYPE_BLANK:
724 d = strcmp((const char*)t1->value.blank.string,
725 (const char*)t2->value.blank.string);
726 break;
727
728 case RAPTOR_TERM_TYPE_LITERAL:
729 d = strcmp((const char*)t1->value.literal.string,
730 (const char*)t2->value.literal.string);
731 if(d)
732 break;
733
734 if(t1->value.literal.language && t2->value.literal.language) {
735 /* both have a language */
736 d = strcmp((const char*)t1->value.literal.language,
737 (const char*)t2->value.literal.language);
738 } else if(t1->value.literal.language || t2->value.literal.language)
739 /* only one has a language; the language-less one is earlier */
740 d = (!t1->value.literal.language ? -1 : 1);
741 if(d)
742 break;
743
744 if(t1->value.literal.datatype && t2->value.literal.datatype) {
745 /* both have a datatype */
746 d = raptor_uri_compare(t1->value.literal.datatype,
747 t2->value.literal.datatype);
748 } else if(t1->value.literal.datatype || t2->value.literal.datatype)
749 /* only one has a datatype; the datatype-less one is earlier */
750 d = (!t1->value.literal.datatype ? -1 : 1);
751 break;
752
753 case RAPTOR_TERM_TYPE_UNKNOWN:
754 default:
755 break;
756 }
757
758 return d;
759 }
760 #endif
761
762
763
764 #ifdef STANDALONE
765
766 /* one more prototype */
767 int main(int argc, char *argv[]);
768
769 static const unsigned char *uri_string1 = (const unsigned char *)"http://http://www.dajobe.org/";
770 static unsigned int uri_string1_len = 29; /* strlen(uri_string1) */
771 static raptor_term_type uri_string1_type = RAPTOR_TERM_TYPE_URI;
772 static const unsigned char *uri_string2 = (const unsigned char *)"http://www.example.org/";
773 static unsigned int uri_string2_len = 23; /* strlen(uri_string2) */
774 static raptor_term_type uri_string2_type = RAPTOR_TERM_TYPE_URI;
775 static const unsigned char *literal_string1 = (const unsigned char *)"Dave Beckett";
776 static unsigned int literal_string1_len = 12; /* strlen(literal_string1) */
777 static raptor_term_type literal_string1_type = RAPTOR_TERM_TYPE_LITERAL;
778 static const unsigned char *bnodeid1 = (const unsigned char *)"abc123";
779 static unsigned int bnodeid1_len = 6; /* strlen(bnode_id1) */
780 static raptor_term_type bnodeid1_type = RAPTOR_TERM_TYPE_BLANK;
781 static const unsigned char* language1 = (const unsigned char*)"en";
782
783 int
main(int argc,char * argv[])784 main(int argc, char *argv[])
785 {
786 raptor_world *world;
787 const char *program = raptor_basename(argv[0]);
788 int rc = 0;
789 raptor_term* term1 = NULL; /* URI string 1 */
790 raptor_term* term2 = NULL; /* literal string1 */
791 raptor_term* term3 = NULL; /* blank node 1 */
792 raptor_term* term4 = NULL; /* URI string 2 */
793 raptor_term* term5 = NULL; /* URI string 1 again */
794 raptor_uri* uri1;
795 unsigned char* uri_str;
796 size_t uri_len;
797
798
799 world = raptor_new_world();
800 if(!world || raptor_world_open(world))
801 exit(1);
802
803
804 /* check a term for NULL URI fails */
805 term1 = raptor_new_term_from_uri(world, NULL);
806 if(term1) {
807 fprintf(stderr, "%s: raptor_new_uri(NULL) returned object rather than failing\n", program);
808 rc = 1;
809 goto tidy;
810 }
811
812 /* check a term for non-NULL URI succeeds */
813 uri1 = raptor_new_uri(world, uri_string1);
814 if(!uri1) {
815 fprintf(stderr, "%s: raptor_new_uri(%s) failed\n", program, uri_string1);
816 rc = 1;
817 goto tidy;
818 }
819 term1 = raptor_new_term_from_uri(world, uri1);
820 if(!term1) {
821 fprintf(stderr, "%s: raptor_new_term_from_uri_string(URI %s) failed\n",
822 program, uri_string1);
823 rc = 1;
824 goto tidy;
825 }
826 raptor_free_uri(uri1); uri1 = NULL;
827 if(term1->type != uri_string1_type) {
828 fprintf(stderr, "%s: raptor term 1 is of type %d expected %d\n",
829 program, term1->type, uri_string1_type);
830 rc = 1;
831 goto tidy;
832 }
833
834
835 /* returns a pointer to shared string */
836 uri_str = raptor_uri_as_counted_string(term1->value.uri, &uri_len);
837 if(!uri_str) {
838 fprintf(stderr, "%s: raptor_uri_as_counted_string term 1 failed\n",
839 program);
840 rc = 1;
841 goto tidy;
842 }
843
844 if(uri_len != uri_string1_len) {
845 fprintf(stderr, "%s: raptor term 1 URI is of length %d expected %d\n",
846 program, (int)uri_len, (int)uri_string1_len);
847 rc = 1;
848 goto tidy;
849 }
850
851
852 /* check an empty literal is created from a NULL literal pointer succeeds */
853 term2 = raptor_new_term_from_counted_literal(world, NULL, 0, NULL, NULL, 0);
854 if(!term2) {
855 fprintf(stderr, "%s: raptor_new_term_from_counted_literal() with all NULLs failed\n", program);
856 rc = 1;
857 goto tidy;
858 }
859 raptor_free_term(term2);
860
861
862 /* check an empty literal from an empty language literal pointer succeeds */
863 term2 = raptor_new_term_from_counted_literal(world, NULL, 0, NULL,
864 (const unsigned char*)"", 0);
865 if(!term2) {
866 fprintf(stderr, "%s: raptor_new_term_from_counted_literal() with empty language failed\n", program);
867 rc = 1;
868 goto tidy;
869 }
870 raptor_free_term(term2);
871
872 /* check a literal with language and datatype fails */
873 uri1 = raptor_new_uri(world, uri_string1);
874 if(!uri1) {
875 fprintf(stderr, "%s: raptor_new_uri(%s) failed\n", program, uri_string1);
876 rc = 1;
877 goto tidy;
878 }
879 term2 = raptor_new_term_from_counted_literal(world, literal_string1,
880 literal_string1_len,
881 uri1, language1, 0);
882 raptor_free_uri(uri1); uri1 = NULL;
883 if(term2) {
884 fprintf(stderr, "%s: raptor_new_term_from_counted_literal() with language and datatype returned object rather than failing\n", program);
885 rc = 1;
886 goto tidy;
887 }
888
889 /* check a literal with no language and no datatype succeeds */
890 term2 = raptor_new_term_from_counted_literal(world, literal_string1,
891 literal_string1_len, NULL, NULL, 0);
892 if(!term2) {
893 fprintf(stderr, "%s: raptor_new_term_from_counted_literal(%s) failed\n",
894 program, literal_string1);
895 rc = 1;
896 goto tidy;
897 }
898 if(term2->type != literal_string1_type) {
899 fprintf(stderr, "%s: raptor term 2 is of type %d expected %d\n",
900 program, term2->type, literal_string1_type);
901 rc = 1;
902 goto tidy;
903 }
904
905
906 /* check a blank node term with NULL id generates a new identifier */
907 term3 = raptor_new_term_from_counted_blank(world, NULL, 0);
908 if(!term3) {
909 fprintf(stderr, "%s: raptor_new_term_from_counted_blank(NULL) failed\n",
910 program);
911 rc = 1;
912 goto tidy;
913 }
914 if(term3->type != bnodeid1_type) {
915 fprintf(stderr, "%s: raptor term 3 is of type %d expected %d\n",
916 program, term3->type, bnodeid1_type);
917 rc = 1;
918 goto tidy;
919 }
920 raptor_free_term(term3);
921
922 /* check a blank node term with an identifier succeeds */
923 term3 = raptor_new_term_from_counted_blank(world, bnodeid1, bnodeid1_len);
924 if(!term3) {
925 fprintf(stderr, "%s: raptor_new_term_from_counted_blank(%s) failed\n",
926 program, bnodeid1);
927 rc = 1;
928 goto tidy;
929 }
930 if(term3->type != bnodeid1_type) {
931 fprintf(stderr, "%s: raptor term 3 is of type %d expected %d\n",
932 program, term3->type, bnodeid1_type);
933 rc = 1;
934 goto tidy;
935 }
936
937
938 /* check a different URI term succeeds */
939 term4 = raptor_new_term_from_counted_uri_string(world, uri_string2,
940 uri_string2_len);
941 if(!term4) {
942 fprintf(stderr,
943 "%s: raptor_new_term_from_counted_uri_string(URI %s) failed\n",
944 program, uri_string2);
945 rc = 1;
946 goto tidy;
947 }
948 if(term4->type != uri_string2_type) {
949 fprintf(stderr, "%s: raptor term 4 is of type %d expected %d\n",
950 program, term4->type, uri_string2_type);
951 rc = 1;
952 goto tidy;
953 }
954 /* returns a pointer to shared string */
955 uri_str = raptor_uri_as_counted_string(term4->value.uri, &uri_len);
956 if(!uri_str) {
957 fprintf(stderr, "%s: raptor_uri_as_counted_string term 4 failed\n",
958 program);
959 rc = 1;
960 goto tidy;
961 }
962
963 if(uri_len != uri_string2_len) {
964 fprintf(stderr, "%s: raptor term 4 URI is of length %d expected %d\n",
965 program, (int)uri_len, (int)uri_string2_len);
966 rc = 1;
967 goto tidy;
968 }
969
970
971 /* check the same URI term as term1 succeeds */
972 term5 = raptor_new_term_from_uri_string(world, uri_string1);
973 if(!term5) {
974 fprintf(stderr, "%s: raptor_new_term_from_uri_string(URI %s) failed\n",
975 program, uri_string1);
976 rc = 1;
977 goto tidy;
978 }
979
980
981 if(raptor_term_equals(term1, term2)) {
982 fprintf(stderr, "%s: raptor_term_equals (URI %s, literal %s) returned equal, expected not-equal\n",
983 program, uri_string1, literal_string1);
984 rc = 1;
985 goto tidy;
986 }
987
988 if(raptor_term_equals(term1, term3)) {
989 fprintf(stderr, "%s: raptor_term_equals (URI %s, bnode %s) returned equal, expected not-equal\n",
990 program, uri_string1, bnodeid1);
991 rc = 1;
992 goto tidy;
993 }
994
995 if(raptor_term_equals(term1, term4)) {
996 fprintf(stderr, "%s: raptor_term_equals (URI %s, URI %s) returned equal, expected not-equal\n",
997 program, uri_string1, uri_string2);
998 rc = 1;
999 goto tidy;
1000 }
1001
1002 if(!raptor_term_equals(term1, term5)) {
1003 fprintf(stderr, "%s: raptor_term_equals (URI %s, URI %s) returned not-equal, expected equal\n",
1004 program, uri_string1, uri_string1);
1005 rc = 1;
1006 goto tidy;
1007 }
1008
1009 if(term1->value.uri != term5->value.uri) {
1010 fprintf(stderr, "%s: term1 and term5 URI objects returned not-equal pointers, expected equal\n",
1011 program);
1012 /* This is not necessarily a failure if the raptor_uri module has had
1013 * the URI interning disabled with
1014 * raptor_world_set_flag(world, RAPTOR_WORLD_FLAG_URI_INTERNING, 0)
1015 * however this test suite does not do that, so it is a failure here.
1016 */
1017 rc = 1;
1018 goto tidy;
1019 }
1020
1021
1022 tidy:
1023 if(term1)
1024 raptor_free_term(term1);
1025 if(term2)
1026 raptor_free_term(term2);
1027 if(term3)
1028 raptor_free_term(term3);
1029 if(term4)
1030 raptor_free_term(term4);
1031 if(term5)
1032 raptor_free_term(term5);
1033
1034 raptor_free_world(world);
1035
1036 return rc;
1037 }
1038
1039 #endif /* STANDALONE */
1040