1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * rasqal_literal.c - Rasqal literals
4  *
5  * Copyright (C) 2003-2010, David Beckett http://www.dajobe.org/
6  * Copyright (C) 2003-2005, University of Bristol, UK http://www.bristol.ac.uk/
7  *
8  * This package is Free Software and part of Redland http://librdf.org/
9  *
10  * It is licensed under the following three licenses as alternatives:
11  *   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12  *   2. GNU General Public License (GPL) V2 or any newer version
13  *   3. Apache License, V2.0 or any newer version
14  *
15  * You may not use this file except in compliance with at least one of
16  * the above three licenses.
17  *
18  * See LICENSE.html or LICENSE.txt at the top of this package for the
19  * complete terms and further detail along with the license texts for
20  * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
21  *
22  *
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include <rasqal_config.h>
27 #endif
28 
29 #ifdef WIN32
30 #include <win32_rasqal_config.h>
31 #endif
32 
33 /* for strtof() and round() prototypes */
34 #define _ISOC99_SOURCE 1
35 
36 #include <stdio.h>
37 #include <string.h>
38 #ifdef HAVE_STRINGS_H
39 #include <strings.h>
40 #endif
41 #include <ctype.h>
42 #ifdef HAVE_STDLIB_H
43 #include <stdlib.h>
44 #endif
45 /* for ptrdiff_t */
46 #ifdef HAVE_STDDEF_H
47 #include <stddef.h>
48 #endif
49 #include <stdarg.h>
50 /* for isnan() */
51 #ifdef HAVE_MATH_H
52 #include <math.h>
53 #endif
54 /* for INT_MIN and INT_MAX */
55 #ifdef HAVE_LIMITS_H
56 #include <limits.h>
57 #endif
58 #ifdef HAVE_ERRNO_H
59 #include <errno.h>
60 #endif
61 #ifdef HAVE_FLOAT_H
62 #include <float.h>
63 #endif
64 
65 #include "rasqal.h"
66 #include "rasqal_internal.h"
67 
68 #define DEBUG_FH stderr
69 
70 
71 #ifndef STANDALONE
72 
73 /* prototypes */
74 static rasqal_literal_type rasqal_literal_promote_numerics(rasqal_literal* l1, rasqal_literal* l2, int flags);
75 static int rasqal_literal_set_typed_value(rasqal_literal* l, rasqal_literal_type type, const unsigned char* string, int canonicalize);
76 
77 
78 const unsigned char* rasqal_xsd_boolean_true = (const unsigned char*)"true";
79 const unsigned char* rasqal_xsd_boolean_false = (const unsigned char*)"false";
80 
81 
82 /**
83  * rasqal_new_integer_literal:
84  * @world: rasqal world object
85  * @type: Type of literal such as RASQAL_LITERAL_INTEGER or RASQAL_LITERAL_BOOLEAN
86  * @integer: int value
87  *
88  * Constructor - Create a new Rasqal integer literal.
89  *
90  * The integer decimal number is turned into a rasqal integer literal
91  * and given a datatype of xsd:integer
92  *
93  * Return value: New #rasqal_literal or NULL on failure
94  **/
95 rasqal_literal*
rasqal_new_integer_literal(rasqal_world * world,rasqal_literal_type type,int integer)96 rasqal_new_integer_literal(rasqal_world* world, rasqal_literal_type type,
97                            int integer)
98 {
99   raptor_uri* dt_uri;
100   rasqal_literal* l;
101 
102   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
103 
104   l  = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
105   if(l) {
106     l->valid = 1;
107     l->usage = 1;
108     l->world = world;
109     l->type = type;
110     l->value.integer = integer;
111     if(type == RASQAL_LITERAL_BOOLEAN) {
112        /* static l->string for boolean, does not need freeing */
113        l->string = integer ? rasqal_xsd_boolean_true : rasqal_xsd_boolean_false;
114        l->string_len = integer ? RASQAL_XSD_BOOLEAN_TRUE_LEN : RASQAL_XSD_BOOLEAN_FALSE_LEN;
115     } else  {
116       size_t slen = 0;
117       l->string = rasqal_xsd_format_integer(integer, &slen);
118       l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
119       if(!l->string) {
120         rasqal_free_literal(l);
121         return NULL;
122       }
123     }
124     dt_uri = rasqal_xsd_datatype_type_to_uri(world, l->type);
125     if(!dt_uri) {
126       rasqal_free_literal(l);
127       return NULL;
128     }
129     l->datatype = raptor_uri_copy(dt_uri);
130     l->parent_type = rasqal_xsd_datatype_parent_type(type);
131   }
132   return l;
133 }
134 
135 
136 /**
137  * rasqal_new_numeric_literal_from_long:
138  * @world: rasqal world object
139  * @type: Type of literal such as RASQAL_LITERAL_INTEGER or RASQAL_LITERAL_BOOLEAN
140  * @value: long value
141  *
142  * Constructor - Create a new Rasqal numeric literal from a long.
143  *
144  * The value is turned into a rasqal integer or decimal literal and
145  * given a datatype of xsd:integer
146  *
147  * Return value: New #rasqal_literal or NULL on failure
148  **/
149 rasqal_literal*
rasqal_new_numeric_literal_from_long(rasqal_world * world,rasqal_literal_type type,long value)150 rasqal_new_numeric_literal_from_long(rasqal_world* world,
151                                      rasqal_literal_type type,
152                                      long value)
153 {
154   rasqal_xsd_decimal* d;
155   unsigned char *string;
156 
157   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
158 
159   /* boolean values should always be in range */
160   if(type == RASQAL_LITERAL_BOOLEAN) {
161     int ivalue = value ? 1 : 0;
162     return rasqal_new_integer_literal(world, type, ivalue);
163   }
164 
165   /* For other types, if in int range, make an integer literal */
166   if(value >= INT_MIN && value <= INT_MAX) {
167     return rasqal_new_integer_literal(world, type, RASQAL_GOOD_CAST(int, value));
168   }
169 
170   /* Otherwise turn it into a decimal */
171   d = rasqal_new_xsd_decimal(world);
172   rasqal_xsd_decimal_set_long(d, value);
173   string = RASQAL_GOOD_CAST(unsigned char*, rasqal_xsd_decimal_as_counted_string(d, NULL));
174 
175   return rasqal_new_decimal_literal_from_decimal(world, string, d);
176 }
177 
178 
179 /**
180  * rasqal_new_typed_literal:
181  * @world: rasqal world object
182  * @type: Type of literal such as RASQAL_LITERAL_INTEGER or RASQAL_LITERAL_BOOLEAN
183  * @string: lexical form - ownership not taken
184  *
185  * Constructor - Create a new Rasqal integer literal from a string
186  *
187  * The integer decimal number is turned into a rasqal integer literal
188  * and given a datatype of xsd:integer
189  *
190  * Return value: New #rasqal_literal or NULL on failure
191  **/
192 rasqal_literal*
rasqal_new_typed_literal(rasqal_world * world,rasqal_literal_type type,const unsigned char * string)193 rasqal_new_typed_literal(rasqal_world* world, rasqal_literal_type type,
194                          const unsigned char* string)
195 {
196   rasqal_literal* l;
197 
198   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
199 
200   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
201   if(!l)
202     return NULL;
203 
204   l->valid = 1;
205   l->usage = 1;
206   l->world = world;
207   l->type = type;
208 
209   if(!rasqal_xsd_datatype_check(type, string, 0)) {
210     rasqal_free_literal(l);
211     return NULL;
212   }
213 
214   if(rasqal_literal_set_typed_value(l, type, string, 0)) {
215     rasqal_free_literal(l);
216     l = NULL;
217   }
218 
219   return l;
220 }
221 
222 
223 /**
224  * rasqal_new_floating_literal:
225  * @world: rasqal world object
226  * @type: type - #RASQAL_LITERAL_FLOAT or #RASQAL_LITERAL_DOUBLE
227  * @d:  floating literal (double)
228  *
229  * Constructor - Create a new Rasqal float literal from a double.
230  *
231  * Return value: New #rasqal_literal or NULL on failure
232  **/
233 rasqal_literal*
rasqal_new_floating_literal(rasqal_world * world,rasqal_literal_type type,double d)234 rasqal_new_floating_literal(rasqal_world *world,
235                             rasqal_literal_type type, double d)
236 {
237   raptor_uri* dt_uri;
238   rasqal_literal* l;
239 
240   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
241 
242   if(type != RASQAL_LITERAL_FLOAT && type != RASQAL_LITERAL_DOUBLE)
243     return NULL;
244 
245   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
246   if(l) {
247     size_t slen = 0;
248     l->valid = 1;
249     l->usage = 1;
250     l->world = world;
251     l->type = type;
252     l->value.floating = d;
253     l->string = rasqal_xsd_format_double(d, &slen);
254     l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
255     if(!l->string) {
256       rasqal_free_literal(l);
257       return NULL;
258     }
259     dt_uri = rasqal_xsd_datatype_type_to_uri(world, l->type);
260     if(!dt_uri) {
261       rasqal_free_literal(l);
262       return NULL;
263     }
264     l->datatype = raptor_uri_copy(dt_uri);
265   }
266   return l;
267 }
268 
269 
270 /**
271  * rasqal_new_double_literal:
272  * @world: rasqal world object
273  * @d: double literal
274  *
275  * Constructor - Create a new Rasqal double literal.
276  *
277  * Return value: New #rasqal_literal or NULL on failure
278  **/
279 rasqal_literal*
rasqal_new_double_literal(rasqal_world * world,double d)280 rasqal_new_double_literal(rasqal_world* world, double d)
281 {
282   return rasqal_new_floating_literal(world, RASQAL_LITERAL_DOUBLE, d);
283 }
284 
285 
286 #ifndef RASQAL_DISABLE_DEPRECATED
287 /**
288  * rasqal_new_float_literal:
289  * @world: rasqal world object
290  * @f:  float literal
291  *
292  * Constructor - Create a new Rasqal float literal.
293  *
294  * @Deprecated: Use rasqal_new_floating_literal() with type
295  * #RASQAL_LITERAL_FLOAT and double value.
296  *
297  * Return value: New #rasqal_literal or NULL on failure
298  **/
299 rasqal_literal*
rasqal_new_float_literal(rasqal_world * world,float f)300 rasqal_new_float_literal(rasqal_world *world, float f)
301 {
302   return rasqal_new_floating_literal(world, RASQAL_LITERAL_FLOAT, (double)f);
303 }
304 #endif
305 
306 /**
307  * rasqal_new_uri_literal:
308  * @world: rasqal world object
309  * @uri: #raptor_uri uri
310  *
311  * Constructor - Create a new Rasqal URI literal from a raptor URI.
312  *
313  * The uri is an input parameter and is stored in the literal, not copied.
314  * The uri is freed also on failure.
315  *
316  * Return value: New #rasqal_literal or NULL on failure
317  **/
318 rasqal_literal*
rasqal_new_uri_literal(rasqal_world * world,raptor_uri * uri)319 rasqal_new_uri_literal(rasqal_world* world, raptor_uri *uri)
320 {
321   rasqal_literal* l;
322 
323   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
324 
325   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
326   if(l) {
327     l->valid = 1;
328     l->usage = 1;
329     l->world = world;
330     l->type = RASQAL_LITERAL_URI;
331     l->value.uri = uri;
332   } else {
333     raptor_free_uri(uri);
334   }
335   return l;
336 }
337 
338 
339 /**
340  * rasqal_new_pattern_literal:
341  * @world: rasqal world object
342  * @pattern: regex pattern
343  * @flags: regex flags
344  *
345  * Constructor - Create a new Rasqal pattern literal.
346  *
347  * The pattern and flags are input parameters and are stored in the
348  * literal, not copied. They are freed also on failure.
349  * The set of flags recognised depends on the regex library and the query
350  * language.
351  *
352  * Return value: New #rasqal_literal or NULL on failure
353  **/
354 rasqal_literal*
rasqal_new_pattern_literal(rasqal_world * world,const unsigned char * pattern,const char * flags)355 rasqal_new_pattern_literal(rasqal_world* world,
356                            const unsigned char *pattern,
357                            const char *flags)
358 {
359   rasqal_literal* l;
360 
361   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
362   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(pattern, char*, NULL);
363 
364   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
365   if(l) {
366     l->valid = 1;
367     l->usage = 1;
368     l->world = world;
369     l->type = RASQAL_LITERAL_PATTERN;
370     l->string = pattern;
371     l->string_len = RASQAL_BAD_CAST(unsigned int, strlen(RASQAL_GOOD_CAST(const char*, pattern)));
372     l->flags = RASQAL_GOOD_CAST(const unsigned char*, flags);
373   } else {
374     if(flags)
375       RASQAL_FREE(char*, flags);
376     RASQAL_FREE(char*, pattern);
377   }
378   return l;
379 }
380 
381 
382 /**
383  * rasqal_new_decimal_literal:
384  * @world: rasqal world object
385  * @string: decimal literal
386  *
387  * Constructor - Create a new Rasqal decimal literal.
388  *
389  * Return value: New #rasqal_literal or NULL on failure
390  **/
391 rasqal_literal*
rasqal_new_decimal_literal(rasqal_world * world,const unsigned char * string)392 rasqal_new_decimal_literal(rasqal_world* world, const unsigned char *string)
393 {
394   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
395   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(string, char*, NULL);
396 
397   return rasqal_new_decimal_literal_from_decimal(world, string, NULL);
398 }
399 
400 
401 /**
402  * rasqal_new_decimal_literal_from_decimal:
403  * @world: rasqal world object
404  * @string: decimal literal string
405  * @decimal: rasqal XSD Decimal
406  *
407  * Constructor - Create a new Rasqal decimal literal.
408  *
409  * Return value: New #rasqal_literal or NULL on failure
410  **/
411 rasqal_literal*
rasqal_new_decimal_literal_from_decimal(rasqal_world * world,const unsigned char * string,rasqal_xsd_decimal * decimal)412 rasqal_new_decimal_literal_from_decimal(rasqal_world* world,
413                                         const unsigned char *string,
414                                         rasqal_xsd_decimal* decimal)
415 {
416   rasqal_literal* l;
417   raptor_uri *dt_uri;
418 
419   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
420   /* string and decimal NULLness are checked below */
421 
422   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
423   if(!l)
424     return NULL;
425 
426   l->valid = 1;
427   l->usage = 1;
428   l->world = world;
429   l->type = RASQAL_LITERAL_DECIMAL;
430   if(string) {
431     if(!rasqal_xsd_datatype_check(l->type, string, 0)) {
432       rasqal_free_literal(l);
433       return NULL;
434     }
435 
436     if(rasqal_literal_set_typed_value(l, l->type, string, 0)) {
437       rasqal_free_literal(l);
438       l = NULL;
439     }
440   } else if(decimal) {
441     dt_uri = rasqal_xsd_datatype_type_to_uri(world, l->type);
442     if(!dt_uri) {
443       rasqal_free_literal(l);
444       l = NULL;
445     } else {
446       size_t slen = 0;
447       l->datatype = raptor_uri_copy(dt_uri);
448       l->value.decimal = decimal;
449       /* string is owned by l->value.decimal */
450       l->string = RASQAL_GOOD_CAST(unsigned char*, rasqal_xsd_decimal_as_counted_string(l->value.decimal, &slen));
451       l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
452       if(!l->string) {
453         rasqal_free_literal(l);
454         l = NULL;
455       }
456     }
457   } else {
458     /* no string or decimal was given */
459     rasqal_free_literal(l);
460     l = NULL;
461   }
462 
463   return l;
464 }
465 
466 
467 /*
468  * rasqal_new_numeric_literal:
469  * @world: rasqal world object
470  * @type: datatype
471  * @double: double
472  *
473  * INTERNAL - Make a numeric datatype from a double
474  *
475  * Return value: new literal or NULL on failure
476  **/
477 rasqal_literal*
rasqal_new_numeric_literal(rasqal_world * world,rasqal_literal_type type,double d)478 rasqal_new_numeric_literal(rasqal_world* world, rasqal_literal_type type,
479                            double d)
480 {
481   char buffer[30];
482 
483   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
484 
485   switch(type) {
486     case RASQAL_LITERAL_DOUBLE:
487     case RASQAL_LITERAL_FLOAT:
488       return rasqal_new_floating_literal(world, type, d);
489 
490     case RASQAL_LITERAL_INTEGER:
491     case RASQAL_LITERAL_INTEGER_SUBTYPE:
492       if(d >= (double)INT_MIN && d <= (double)INT_MAX)
493         return rasqal_new_integer_literal(world, type, RASQAL_GOOD_CAST(int, d));
494 
495       /* otherwise FALLTHROUGH and make it a decimal */
496 
497     case RASQAL_LITERAL_DECIMAL:
498       sprintf(buffer, "%g", d);
499       return rasqal_new_decimal_literal(world, RASQAL_GOOD_CAST(unsigned char*, buffer));
500 
501     case RASQAL_LITERAL_XSD_STRING:
502     case RASQAL_LITERAL_BOOLEAN:
503     case RASQAL_LITERAL_DATE:
504     case RASQAL_LITERAL_DATETIME:
505     case RASQAL_LITERAL_UNKNOWN:
506     case RASQAL_LITERAL_BLANK:
507     case RASQAL_LITERAL_URI:
508     case RASQAL_LITERAL_STRING:
509     case RASQAL_LITERAL_PATTERN:
510     case RASQAL_LITERAL_QNAME:
511     case RASQAL_LITERAL_VARIABLE:
512     case RASQAL_LITERAL_UDT:
513       RASQAL_FATAL2("Unexpected numeric type %u", type);
514   }
515 
516   return NULL;
517 }
518 
519 
520 /**
521  * rasqal_new_datetime_literal_from_datetime:
522  * @world: rasqal world object
523  * @dt: rasqal XSD Datetime
524  *
525  * Constructor - Create a new Rasqal datetime literal from an existing datetime.
526  *
527  * Takes ownership of @dt
528  *
529  * Return value: New #rasqal_literal or NULL on failure
530  **/
531 rasqal_literal*
rasqal_new_datetime_literal_from_datetime(rasqal_world * world,rasqal_xsd_datetime * dt)532 rasqal_new_datetime_literal_from_datetime(rasqal_world* world,
533                                           rasqal_xsd_datetime* dt)
534 {
535   rasqal_literal* l;
536   raptor_uri *dt_uri;
537   size_t slen = 0;
538 
539   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
540   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(dt, rasqal_xsd_datetime, NULL);
541 
542   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
543   if(!l)
544     goto failed;
545 
546   l->valid = 1;
547   l->usage = 1;
548   l->world = world;
549   l->type = RASQAL_LITERAL_DATETIME;
550 
551   dt_uri = rasqal_xsd_datatype_type_to_uri(world, l->type);
552   if(!dt_uri)
553     goto failed;
554 
555   l->datatype = raptor_uri_copy(dt_uri);
556 
557   l->value.datetime = dt;
558 
559   l->string = RASQAL_GOOD_CAST(unsigned char*, rasqal_xsd_datetime_to_counted_string(l->value.datetime, &slen));
560   l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
561   if(!l->string)
562     goto failed;
563 
564   return l;
565 
566   failed:
567   if(l)
568     rasqal_free_literal(l);
569   if(dt)
570     rasqal_free_xsd_datetime(dt);
571 
572   return NULL;
573 }
574 
575 
576 
577 /*
578  * rasqal_literal_set_typed_value:
579  * @l: literal
580  * @type: type
581  * @string: string or NULL to use existing literal string
582  * @canonicalize: non-0 to canonicalize the existing string
583  *
584  * INTERNAL - Set a literal typed value
585  *
586  * Return value: non-0 on failure
587  **/
588 static int
rasqal_literal_set_typed_value(rasqal_literal * l,rasqal_literal_type type,const unsigned char * string,int canonicalize)589 rasqal_literal_set_typed_value(rasqal_literal* l, rasqal_literal_type type,
590                                const unsigned char* string,
591                                int canonicalize)
592 {
593   char *eptr;
594   raptor_uri* dt_uri;
595   int i;
596   double d;
597   rasqal_literal_type original_type = l->type;
598 
599   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, 1);
600 
601 retype:
602   l->valid = rasqal_xsd_datatype_check(type, string ? string : l->string,
603                                        0 /* no flags set */);
604   if(!l->valid) {
605     RASQAL_DEBUG3("Invalid type %s string '%s' - setting to type UDT\n",
606                   rasqal_xsd_datatype_label(type), string ? string : l->string);
607     type = RASQAL_LITERAL_UDT;
608   }
609 
610   if(l->language) {
611     RASQAL_FREE(char*, l->language);
612     l->language = NULL;
613   }
614   l->type = type;
615 
616   if(string && l->type != RASQAL_LITERAL_DECIMAL) {
617     if(l->string)
618       RASQAL_FREE(char*, l->string);
619 
620     l->string_len = RASQAL_BAD_CAST(unsigned int, strlen(RASQAL_GOOD_CAST(const char*, string)));
621     l->string = RASQAL_MALLOC(unsigned char*, l->string_len + 1);
622     if(!l->string)
623       return 1;
624     memcpy((void*)l->string, string, l->string_len + 1);
625   }
626 
627   if(l->type <= RASQAL_LITERAL_LAST_XSD) {
628     dt_uri = rasqal_xsd_datatype_type_to_uri(l->world, l->type);
629     if(!dt_uri)
630       return 1;
631 
632     if(l->datatype)
633       raptor_free_uri(l->datatype);
634     l->datatype = raptor_uri_copy(dt_uri);
635 
636     l->parent_type = rasqal_xsd_datatype_parent_type(type);
637   }
638 
639   switch(type) {
640     case RASQAL_LITERAL_INTEGER:
641     case RASQAL_LITERAL_INTEGER_SUBTYPE:
642       if(1) {
643         long long_i;
644 
645         eptr = NULL;
646         errno = 0;
647         long_i = strtol(RASQAL_GOOD_CAST(const char*, l->string), &eptr, 10);
648         if(*eptr)
649           return 1;
650 
651         if(errno == ERANGE) {
652           /* under or overflow of strtol() so fallthrough to DECIMAL */
653 
654         } else if(long_i >= INT_MIN && long_i <= INT_MAX) {
655           l->value.integer = RASQAL_GOOD_CAST(int, long_i);
656           break;
657         }
658       }
659 
660       /* Will not fit in an int so turn it into a decimal */
661       type = RASQAL_LITERAL_DECIMAL;
662       goto retype;
663 
664     case RASQAL_LITERAL_DOUBLE:
665     case RASQAL_LITERAL_FLOAT:
666       if(1) {
667         size_t slen = 0;
668         d = 0.0;
669         (void)sscanf(RASQAL_GOOD_CAST(char*, l->string), "%lf", &d);
670         l->value.floating = d;
671         if(canonicalize) {
672           RASQAL_FREE(char*, l->string);
673           l->string = rasqal_xsd_format_double(d, &slen);
674           l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
675         }
676       }
677       break;
678 
679     case RASQAL_LITERAL_DECIMAL:
680       if(1) {
681         size_t slen = 0;
682         rasqal_xsd_decimal* new_d;
683 
684         new_d = rasqal_new_xsd_decimal(l->world);
685         if(!new_d)
686           return 1;
687 
688         if(!string)
689           /* use existing literal decimal object (SHARED) string */
690           string = l->string;
691 
692         if(rasqal_xsd_decimal_set_string(new_d,
693                                          RASQAL_GOOD_CAST(const char*, string))) {
694           rasqal_free_xsd_decimal(new_d);
695           return 1;
696         }
697         if(l->value.decimal) {
698           rasqal_free_xsd_decimal(l->value.decimal);
699         }
700         l->value.decimal = new_d;
701 
702         /* old l->string is now invalid and MAY need to be freed */
703         if(l->string && original_type != RASQAL_LITERAL_DECIMAL)
704           RASQAL_FREE(char*, l->string);
705 
706         /* new l->string is owned by l->value.decimal and will be
707          * freed on literal destruction
708          */
709         l->string = RASQAL_GOOD_CAST(unsigned char*, rasqal_xsd_decimal_as_counted_string(l->value.decimal, &slen));
710         l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
711         if(!l->string)
712           return 1;
713       }
714       break;
715 
716     case RASQAL_LITERAL_XSD_STRING:
717     case RASQAL_LITERAL_UDT:
718       /* No change - kept as same type - xsd:string or user defined */
719       break;
720 
721     case RASQAL_LITERAL_BOOLEAN:
722       i = rasqal_xsd_boolean_value_from_string(l->string);
723       /* Free passed in string if it is not our static objects */
724       if(l->string != rasqal_xsd_boolean_true &&
725          l->string != rasqal_xsd_boolean_false)
726         RASQAL_FREE(char*, l->string);
727       /* and replace with a static string */
728       l->string = i ? rasqal_xsd_boolean_true : rasqal_xsd_boolean_false;
729       l->string_len = i ? RASQAL_XSD_BOOLEAN_TRUE_LEN : RASQAL_XSD_BOOLEAN_FALSE_LEN;
730 
731       l->value.integer = i;
732       break;
733 
734   case RASQAL_LITERAL_STRING:
735     /* No change - kept as a string */
736     break;
737 
738   case RASQAL_LITERAL_DATE:
739     if(1) {
740       size_t slen = 0;
741 
742       if(l->value.date)
743         rasqal_free_xsd_date(l->value.date);
744 
745       l->value.date = rasqal_new_xsd_date(l->world, RASQAL_GOOD_CAST(const char*, l->string));
746       if(!l->value.date) {
747         RASQAL_FREE(char*, l->string);
748         return 1;
749       }
750       RASQAL_FREE(char*, l->string);
751       l->string = RASQAL_GOOD_CAST(unsigned char*, rasqal_xsd_date_to_counted_string(l->value.date, &slen));
752       l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
753       if(!l->string)
754         return 1;
755     }
756     break;
757 
758   case RASQAL_LITERAL_DATETIME:
759     if(1) {
760       size_t slen = 0;
761 
762       if(l->value.datetime)
763         rasqal_free_xsd_datetime(l->value.datetime);
764 
765       l->value.datetime = rasqal_new_xsd_datetime(l->world,
766                                                   RASQAL_GOOD_CAST(const char*, l->string));
767       if(!l->value.datetime) {
768         RASQAL_FREE(char*, l->string);
769         return 1;
770       }
771       RASQAL_FREE(char*, l->string);
772       l->string = RASQAL_GOOD_CAST(unsigned char*, rasqal_xsd_datetime_to_counted_string(l->value.datetime, &slen));
773       l->string_len = RASQAL_BAD_CAST(unsigned int, slen);
774       if(!l->string)
775         return 1;
776     }
777     break;
778 
779   case RASQAL_LITERAL_UNKNOWN:
780   case RASQAL_LITERAL_BLANK:
781   case RASQAL_LITERAL_URI:
782   case RASQAL_LITERAL_PATTERN:
783   case RASQAL_LITERAL_QNAME:
784   case RASQAL_LITERAL_VARIABLE:
785     RASQAL_FATAL2("Unexpected native type %u", type);
786     break;
787 
788   default:
789     RASQAL_FATAL2("Unknown native type %u", type);
790   }
791 
792   return 0;
793 }
794 
795 
796 
797 /*
798  * rasqal_literal_string_to_native:
799  * @l: #rasqal_literal to operate on inline
800  * @flags: flags for literal checking.  1 to canonicalize string
801  *
802  * INTERNAL - Upgrade a datatyped literal string to an internal typed literal
803  *
804  * At present this promotes datatyped literals
805  * xsd:integer to RASQAL_LITERAL_INTEGER
806  * xsd:double to RASQAL_LITERAL_DOUBLE
807  * xsd:float to RASQAL_LITERAL_FLOAT
808  * xsd:boolean to RASQAL_LITERAL_BOOLEAN
809  * xsd:decimal to RASQAL_LITERAL_DECIMAL
810  * xsd:dateTime to RASQAL_LITERAL_DATETIME
811  * xsd:date to RASQAL_LITERAL_DATE
812  *
813  * Return value: non-0 on failure
814  **/
815 int
rasqal_literal_string_to_native(rasqal_literal * l,int flags)816 rasqal_literal_string_to_native(rasqal_literal *l, int flags)
817 {
818   rasqal_literal_type native_type = RASQAL_LITERAL_UNKNOWN;
819   int rc = 0;
820   int canonicalize = (flags & 1 );
821 
822   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, 1);
823 
824   /* RDF literal with no datatype (plain literal) */
825   if(!l->datatype)
826     return 0;
827 
828   native_type = rasqal_xsd_datatype_uri_to_type(l->world, l->datatype);
829   /* plain literal - nothing to do */
830   if(native_type == RASQAL_LITERAL_STRING)
831     return 0;
832 
833   /* xsd:string - mark and return */
834   if(native_type == RASQAL_LITERAL_XSD_STRING) {
835     l->type = native_type;
836     return 0;
837   }
838 
839   /* If a user defined type - update the literal */
840   if(native_type == RASQAL_LITERAL_UNKNOWN) {
841     l->type = RASQAL_LITERAL_UDT;
842     return 0;
843   }
844 
845   rc = rasqal_literal_set_typed_value(l, native_type,
846                                       NULL /* existing string */,
847                                       canonicalize);
848 
849   if(!rasqal_xsd_datatype_check(native_type, l->string, 1))
850     return 0;
851 
852   return rc;
853 }
854 
855 
856 /*
857  * rasqal_new_string_literal_common:
858  * @world: rasqal world object
859  * @string: UTF-8 string lexical form
860  * @language: RDF language (xml:lang) (or NULL)
861  * @datatype: datatype URI (or NULL for plain literal)
862  * @datatype_qname: datatype qname string (or NULL for plain literal)
863  * @flags: bitflags - 1 to do native type promotion; 2 to canonicalize string
864  *
865  * INTERNAL Constructor - Create a new Rasqal string literal.
866  *
867  * All parameters are input parameters and if present are stored in
868  * the literal, not copied. They are freed also on failure.
869  *
870  * The datatype and datatype_qname parameters are alternatives; the
871  * qname is a datatype that cannot be resolved till later since the
872  * prefixes have not yet been declared or checked.
873  *
874  * If the string literal is datatyped and of certain types recognised
875  * it may be converted to a different literal type by
876  * rasqal_literal_string_to_native() only if @flags has bit 1 set.
877  * If bit 2 is set AS WELL, literals will have their string converted
878  * to the canonical format.
879  *
880  * Return value: New #rasqal_literal or NULL on failure
881  **/
882 static rasqal_literal*
rasqal_new_string_literal_common(rasqal_world * world,const unsigned char * string,const char * language,raptor_uri * datatype,const unsigned char * datatype_qname,int flags)883 rasqal_new_string_literal_common(rasqal_world* world,
884                                  const unsigned char *string,
885                                  const char *language,
886                                  raptor_uri *datatype,
887                                  const unsigned char *datatype_qname,
888                                  int flags)
889 {
890   rasqal_literal* l;
891   int native_type_promotion = (flags & 1);
892   int canonicalize = (flags & 2) >> 1;
893 
894   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
895   if(l) {
896     rasqal_literal_type datatype_type = RASQAL_LITERAL_STRING;
897 
898     l->valid = 1;
899     l->usage = 1;
900     l->world = world;
901 
902     if(datatype && language) {
903       /* RDF typed literal but this is not allowed so delete language */
904       RASQAL_FREE(char*, language);
905       language = NULL;
906     }
907 
908     l->type = RASQAL_LITERAL_STRING;
909     l->string = string;
910     l->string_len = RASQAL_BAD_CAST(unsigned int, strlen(RASQAL_GOOD_CAST(const char*, string)));
911     if(language) {
912       /* Normalize language to lowercase on construction */
913       size_t lang_len = strlen(language);
914       unsigned int i;
915 
916       l->language = RASQAL_MALLOC(char*, lang_len + 1);
917       for(i = 0; i < lang_len; i++) {
918         char c = language[i];
919         if(isupper(RASQAL_GOOD_CAST(int, c)))
920           c = RASQAL_GOOD_CAST(char, tolower(RASQAL_GOOD_CAST(int, c)));
921         l->language[i] = c;
922       }
923       l->language[i] = '\0';
924       RASQAL_FREE(char*, language);
925     }
926     l->datatype = datatype;
927     l->flags = datatype_qname;
928 
929     if(datatype)
930       datatype_type = rasqal_xsd_datatype_uri_to_type(world, datatype);
931     l->parent_type = rasqal_xsd_datatype_parent_type(datatype_type);
932 
933     if(native_type_promotion &&
934        rasqal_literal_string_to_native(l, canonicalize)) {
935       rasqal_free_literal(l);
936       l = NULL;
937     }
938   } else {
939     if(language)
940       RASQAL_FREE(char*, language);
941     if(datatype)
942       raptor_free_uri(datatype);
943     if(datatype_qname)
944       RASQAL_FREE(char*, datatype_qname);
945     RASQAL_FREE(char*, string);
946   }
947 
948   return l;
949 }
950 
951 
952 /**
953  * rasqal_new_string_literal:
954  * @world: rasqal world object
955  * @string: UTF-8 string lexical form
956  * @language: RDF language (xml:lang) (or NULL)
957  * @datatype: datatype URI (or NULL for plain literal)
958  * @datatype_qname: datatype qname string (or NULL for plain literal)
959  *
960  * Constructor - Create a new Rasqal string literal.
961  *
962  * All parameters are input parameters and if present are stored in
963  * the literal, not copied. They are freed also on failure.
964  *
965  * The datatype and datatype_qname parameters are alternatives; the
966  * qname is a datatype that cannot be resolved till later since the
967  * prefixes have not yet been declared or checked.
968  *
969  * If the string literal is datatyped and of certain types recognised
970  * it may be converted to a different literal type.
971  *
972  * Return value: New #rasqal_literal or NULL on failure
973  **/
974 rasqal_literal*
rasqal_new_string_literal(rasqal_world * world,const unsigned char * string,const char * language,raptor_uri * datatype,const unsigned char * datatype_qname)975 rasqal_new_string_literal(rasqal_world* world,
976                           const unsigned char *string,
977                           const char *language,
978                           raptor_uri *datatype,
979                           const unsigned char *datatype_qname)
980 {
981   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
982   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(string, char*, NULL);
983 
984   return rasqal_new_string_literal_common(world, string, language, datatype,
985                                           datatype_qname, 1);
986 }
987 
988 
989 /*
990  * rasqal_new_string_literal_node:
991  * @world: rasqal world object
992  * @string: UTF-8 string lexical form
993  * @language: RDF language (xml:lang) (or NULL)
994  * @datatype: datatype URI (or NULL for plain literal)
995  *
996  * INTERNAL Constructor - Create a new Rasqal literal with promotion and canonicalization
997  *
998  * All parameters are input parameters and if present are stored in
999  * the literal, not copied. They are freed also on failure.
1000  *
1001  * Return value: New #rasqal_literal or NULL on failure
1002  **/
1003 rasqal_literal*
rasqal_new_string_literal_node(rasqal_world * world,const unsigned char * string,const char * language,raptor_uri * datatype)1004 rasqal_new_string_literal_node(rasqal_world* world, const unsigned char *string,
1005                                const char *language, raptor_uri *datatype)
1006 {
1007   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
1008   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(string, char*, NULL);
1009 
1010   return rasqal_new_string_literal_common(world, string, language, datatype,
1011                                           NULL, 1 | 2);
1012 }
1013 
1014 
1015 /**
1016  * rasqal_new_simple_literal:
1017  * @world: rasqal world object
1018  * @type: RASQAL_LITERAL_BLANK or RASQAL_LITERAL_BLANK_QNAME
1019  * @string: the UTF-8 string value to store
1020  *
1021  * Constructor - Create a new Rasqal simple literal.
1022  *
1023  * The string is an input parameter and is stored in the
1024  * literal, not copied. It is freed also on failure.
1025  *
1026  * Return value: New #rasqal_literal or NULL on failure
1027  **/
1028 rasqal_literal*
rasqal_new_simple_literal(rasqal_world * world,rasqal_literal_type type,const unsigned char * string)1029 rasqal_new_simple_literal(rasqal_world* world,
1030                           rasqal_literal_type type,
1031                           const unsigned char *string)
1032 {
1033   rasqal_literal* l;
1034 
1035   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
1036   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(string, char*, NULL);
1037 
1038   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
1039   if(l) {
1040     l->valid = 1;
1041     l->usage = 1;
1042     l->world = world;
1043     l->type = type;
1044     l->string = string;
1045     l->string_len = RASQAL_BAD_CAST(unsigned int, strlen(RASQAL_GOOD_CAST(const char*, string)));
1046   } else {
1047     RASQAL_FREE(char*, string);
1048   }
1049   return l;
1050 }
1051 
1052 
1053 /**
1054  * rasqal_new_boolean_literal:
1055  * @world: rasqal world object
1056  * @value: non-0 for true, 0 for false
1057  *
1058  * Constructor - Create a new Rasqal boolean literal.
1059  *
1060  * Return value: New #rasqal_literal or NULL on failure
1061  **/
1062 rasqal_literal*
rasqal_new_boolean_literal(rasqal_world * world,int value)1063 rasqal_new_boolean_literal(rasqal_world* world, int value)
1064 {
1065   raptor_uri* dt_uri;
1066   rasqal_literal* l;
1067 
1068   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
1069 
1070   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
1071   if(l) {
1072     l->valid = 1;
1073     l->usage = 1;
1074     l->world = world;
1075     l->type = RASQAL_LITERAL_BOOLEAN;
1076     l->value.integer = value;
1077     l->string = value ? rasqal_xsd_boolean_true : rasqal_xsd_boolean_false;
1078     l->string_len = value ? RASQAL_XSD_BOOLEAN_TRUE_LEN : RASQAL_XSD_BOOLEAN_FALSE_LEN;
1079     dt_uri = rasqal_xsd_datatype_type_to_uri(world, l->type);
1080     if(!dt_uri) {
1081       rasqal_free_literal(l);
1082       return NULL;
1083     }
1084     l->datatype = raptor_uri_copy(dt_uri);
1085   }
1086   return l;
1087 }
1088 
1089 
1090 /**
1091  * rasqal_new_variable_literal:
1092  * @world: rasqal_world object
1093  * @variable: #rasqal_variable to use
1094  *
1095  * Constructor - Create a new Rasqal variable literal.
1096  *
1097  * variable is an input parameter and stored in the literal, not copied.
1098  *
1099  * Return value: New #rasqal_literal or NULL on failure
1100  **/
1101 rasqal_literal*
rasqal_new_variable_literal(rasqal_world * world,rasqal_variable * variable)1102 rasqal_new_variable_literal(rasqal_world* world, rasqal_variable *variable)
1103 {
1104   rasqal_literal* l;
1105 
1106   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
1107   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(variable, rasqal_variable, NULL);
1108 
1109   l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*l));
1110   if(l) {
1111     l->valid = 1;
1112     l->usage = 1;
1113     l->world = world;
1114     l->type = RASQAL_LITERAL_VARIABLE;
1115     l->value.variable = variable;
1116   } else
1117     rasqal_free_variable(variable);
1118 
1119   return l;
1120 }
1121 
1122 
1123 /**
1124  * rasqal_new_literal_from_literal:
1125  * @l: #rasqal_literal object to copy or NULL
1126  *
1127  * Copy Constructor - create a new rasqal_literal object from an existing rasqal_literal object.
1128  *
1129  * Return value: a new #rasqal_literal object or NULL if @l was NULL.
1130  **/
1131 rasqal_literal*
rasqal_new_literal_from_literal(rasqal_literal * l)1132 rasqal_new_literal_from_literal(rasqal_literal* l)
1133 {
1134   if(!l)
1135     return NULL;
1136 
1137   l->usage++;
1138   return l;
1139 }
1140 
1141 
1142 /**
1143  * rasqal_free_literal:
1144  * @l: #rasqal_literal object
1145  *
1146  * Destructor - destroy an rasqal_literal object.
1147  *
1148  **/
1149 void
rasqal_free_literal(rasqal_literal * l)1150 rasqal_free_literal(rasqal_literal* l)
1151 {
1152   if(!l)
1153     return;
1154 
1155   if(--l->usage)
1156     return;
1157 
1158   switch(l->type) {
1159     case RASQAL_LITERAL_URI:
1160       if(l->value.uri)
1161         raptor_free_uri(l->value.uri);
1162       break;
1163     case RASQAL_LITERAL_STRING:
1164     case RASQAL_LITERAL_BLANK:
1165     case RASQAL_LITERAL_PATTERN:
1166     case RASQAL_LITERAL_QNAME:
1167     case RASQAL_LITERAL_XSD_STRING:
1168     case RASQAL_LITERAL_DOUBLE:
1169     case RASQAL_LITERAL_INTEGER:
1170     case RASQAL_LITERAL_FLOAT:
1171     case RASQAL_LITERAL_UDT:
1172     case RASQAL_LITERAL_INTEGER_SUBTYPE:
1173       if(l->string)
1174         RASQAL_FREE(char*, l->string);
1175       if(l->language)
1176         RASQAL_FREE(char*, l->language);
1177       if(l->datatype)
1178         raptor_free_uri(l->datatype);
1179       if(l->type == RASQAL_LITERAL_STRING ||
1180          l->type == RASQAL_LITERAL_PATTERN) {
1181         if(l->flags)
1182           RASQAL_FREE(char*, l->flags);
1183       }
1184       break;
1185 
1186     case RASQAL_LITERAL_DATE:
1187       if(l->string)
1188         RASQAL_FREE(char*, l->string);
1189       if(l->datatype)
1190         raptor_free_uri(l->datatype);
1191       if(l->value.date)
1192         rasqal_free_xsd_date(l->value.date);
1193       break;
1194 
1195     case RASQAL_LITERAL_DATETIME:
1196       if(l->string)
1197         RASQAL_FREE(char*, l->string);
1198       if(l->datatype)
1199         raptor_free_uri(l->datatype);
1200       if(l->value.datetime)
1201         rasqal_free_xsd_datetime(l->value.datetime);
1202       break;
1203 
1204     case RASQAL_LITERAL_DECIMAL:
1205       /* l->string is owned by l->value.decimal - do not free it */
1206       if(l->datatype)
1207         raptor_free_uri(l->datatype);
1208       if(l->value.decimal)
1209         rasqal_free_xsd_decimal(l->value.decimal);
1210       break;
1211 
1212     case RASQAL_LITERAL_BOOLEAN:
1213        /* static l->string for boolean, does not need freeing */
1214       if(l->datatype)
1215         raptor_free_uri(l->datatype);
1216       break;
1217 
1218     case RASQAL_LITERAL_VARIABLE:
1219       if(l->value.variable)
1220         rasqal_free_variable(l->value.variable);
1221       break;
1222 
1223     case RASQAL_LITERAL_UNKNOWN:
1224     default:
1225       RASQAL_FATAL2("Unknown literal type %u", l->type);
1226   }
1227   RASQAL_FREE(rasqal_literal, l);
1228 }
1229 
1230 
1231 /*
1232  * The order here must match that of rasqal_literal_type
1233  * in rasqal.h and is significant as rasqal_literal_compare
1234  * uses it for type comparisons with the RASQAL_COMPARE_XQUERY
1235  * flag.
1236  */
1237 static const char* const rasqal_literal_type_labels[RASQAL_LITERAL_LAST + 1]={
1238   "UNKNOWN",
1239   "blank",
1240   "uri",
1241   "string",
1242   "xsdstring",
1243   "boolean",
1244   "integer",
1245   "float",
1246   "double",
1247   "decimal",
1248   "datetime",
1249   "udt",
1250   "pattern",
1251   "qname",
1252   "variable",
1253   "<integer subtype>",
1254   "date"
1255 };
1256 
1257 
1258 /**
1259  * rasqal_literal_type_label:
1260  * @type: the #rasqal_literal_type object
1261  *
1262  * Get a label for the rasqal literal type
1263  *
1264  * Return value: the label (shared string) or NULL if type is out of
1265  * range or unknown
1266  **/
1267 const char*
rasqal_literal_type_label(rasqal_literal_type type)1268 rasqal_literal_type_label(rasqal_literal_type type)
1269 {
1270   if(type > RASQAL_LITERAL_LAST)
1271     type = RASQAL_LITERAL_UNKNOWN;
1272 
1273   return rasqal_literal_type_labels[RASQAL_GOOD_CAST(int, type)];
1274 }
1275 
1276 
1277 /**
1278  * rasqal_literal_write_type:
1279  * @l: the #rasqal_literal object
1280  * @iostr: the #raptor_iostream handle to print to
1281  *
1282  * Write a string form for a rasqal literal type to an iostream
1283  *
1284  **/
1285 void
rasqal_literal_write_type(rasqal_literal * l,raptor_iostream * iostr)1286 rasqal_literal_write_type(rasqal_literal* l, raptor_iostream* iostr)
1287 {
1288   if(!l) {
1289     raptor_iostream_counted_string_write("null", 4, iostr);
1290     return;
1291   }
1292 
1293   raptor_iostream_string_write(rasqal_literal_type_label(l->type), iostr);
1294 }
1295 
1296 
1297 /**
1298  * rasqal_literal_print_type:
1299  * @l: the #rasqal_literal object
1300  * @fh: the FILE* handle to print to
1301  *
1302  * Print a string form for a rasqal literal type.
1303  *
1304  **/
1305 void
rasqal_literal_print_type(rasqal_literal * l,FILE * fh)1306 rasqal_literal_print_type(rasqal_literal* l, FILE* fh)
1307 {
1308   raptor_iostream *iostr;
1309 
1310   if(!l) {
1311     fputs("null", fh);
1312     return;
1313   }
1314 
1315   iostr = raptor_new_iostream_to_file_handle(l->world->raptor_world_ptr, fh);
1316   if(!iostr)
1317     return;
1318 
1319   rasqal_literal_write_type(l, iostr);
1320 
1321   raptor_free_iostream(iostr);
1322 }
1323 
1324 
1325 /**
1326  * rasqal_literal_write:
1327  * @l: the #rasqal_literal object
1328  * @iostr: the #raptor_iostream handle to write to
1329  *
1330  * Write a Rasqal literal to an iostream in a debug format.
1331  *
1332  * The print debug format may change in any release.
1333  **/
1334 void
rasqal_literal_write(rasqal_literal * l,raptor_iostream * iostr)1335 rasqal_literal_write(rasqal_literal* l, raptor_iostream* iostr)
1336 {
1337   const unsigned char*str;
1338   size_t len;
1339 
1340   if(!l) {
1341     raptor_iostream_counted_string_write("null", 4, iostr);
1342     return;
1343   }
1344 
1345   if(!l->valid)
1346     raptor_iostream_counted_string_write("INV:", 4, iostr);
1347 
1348   if(l->type != RASQAL_LITERAL_VARIABLE)
1349     rasqal_literal_write_type(l, iostr);
1350 
1351   switch(l->type) {
1352     case RASQAL_LITERAL_URI:
1353       raptor_iostream_write_byte('<', iostr);
1354       str = raptor_uri_as_counted_string(l->value.uri, &len);
1355       raptor_string_ntriples_write(str, len, '>', iostr);
1356       raptor_iostream_write_byte('>', iostr);
1357       break;
1358     case RASQAL_LITERAL_BLANK:
1359       raptor_iostream_write_byte(' ', iostr);
1360       raptor_iostream_counted_string_write(l->string, l->string_len, iostr);
1361       break;
1362     case RASQAL_LITERAL_PATTERN:
1363       raptor_iostream_write_byte('/', iostr);
1364       raptor_iostream_counted_string_write(l->string, l->string_len, iostr);
1365       raptor_iostream_write_byte('/', iostr);
1366       if(l->flags)
1367         raptor_iostream_string_write(l->flags, iostr);
1368       break;
1369     case RASQAL_LITERAL_STRING:
1370     case RASQAL_LITERAL_UDT:
1371       raptor_iostream_counted_string_write("(\"", 2, iostr);
1372       raptor_string_ntriples_write(l->string, l->string_len, '"', iostr);
1373       raptor_iostream_write_byte('"', iostr);
1374       if(l->language) {
1375         raptor_iostream_write_byte('@', iostr);
1376         raptor_iostream_string_write(l->language, iostr);
1377       }
1378       if(l->datatype) {
1379         raptor_iostream_counted_string_write("^^<", 3, iostr);
1380         str = raptor_uri_as_counted_string(l->datatype, &len);
1381         raptor_string_ntriples_write(str, len, '>', iostr);
1382         raptor_iostream_write_byte('>', iostr);
1383       }
1384       raptor_iostream_write_byte(')', iostr);
1385       break;
1386     case RASQAL_LITERAL_VARIABLE:
1387       rasqal_variable_write(l->value.variable, iostr);
1388       break;
1389 
1390     case RASQAL_LITERAL_QNAME:
1391     case RASQAL_LITERAL_INTEGER:
1392     case RASQAL_LITERAL_XSD_STRING:
1393     case RASQAL_LITERAL_BOOLEAN:
1394     case RASQAL_LITERAL_DOUBLE:
1395     case RASQAL_LITERAL_FLOAT:
1396     case RASQAL_LITERAL_DECIMAL:
1397     case RASQAL_LITERAL_DATE:
1398     case RASQAL_LITERAL_DATETIME:
1399     case RASQAL_LITERAL_INTEGER_SUBTYPE:
1400       raptor_iostream_write_byte('(', iostr);
1401       raptor_iostream_counted_string_write(l->string, l->string_len, iostr);
1402       raptor_iostream_write_byte(')', iostr);
1403       break;
1404 
1405     case RASQAL_LITERAL_UNKNOWN:
1406     default:
1407       RASQAL_FATAL2("Unknown literal type %u", l->type);
1408   }
1409 }
1410 
1411 
1412 
1413 /**
1414  * rasqal_literal_print:
1415  * @l: the #rasqal_literal object
1416  * @fh: the FILE handle to print to
1417  *
1418  * Print a Rasqal literal in a debug format.
1419  *
1420  * The print debug format may change in any release.
1421  *
1422  * Return value: non-0 on failure
1423  **/
1424 int
rasqal_literal_print(rasqal_literal * l,FILE * fh)1425 rasqal_literal_print(rasqal_literal* l, FILE* fh)
1426 {
1427   raptor_iostream *iostr;
1428 
1429   if(!l) {
1430     fputs("NULL", fh);
1431     return 0;
1432   }
1433 
1434   iostr = raptor_new_iostream_to_file_handle(l->world->raptor_world_ptr, fh);
1435   rasqal_literal_write(l, iostr);
1436   raptor_free_iostream(iostr);
1437 
1438   return 0;
1439 }
1440 
1441 
1442 
1443 /*
1444  * rasqal_literal_as_boolean:
1445  * @l: #rasqal_literal object
1446  * @error_p: pointer to error flag
1447  *
1448  * INTERNAL - Return a literal as a boolean value
1449  *
1450  * SPARQL Effective Boolean Value (EBV) rules:
1451  *  - If the argument is a typed literal with a datatype of xsd:boolean, the
1452  *    EBV is the value of that argument.
1453  *  - If the argument is a plain literal or a typed literal with a datatype of
1454  *    xsd:string, the EBV is false if the operand value has zero length;
1455  *    otherwise the EBV is true.
1456  *  - If the argument is a numeric type or a typed literal with a datatype
1457  *    derived from a numeric type, the EBV is false if the operand value is NaN
1458  *    or is numerically equal to zero; otherwise the EBV is true.
1459  *  - All other arguments, including unbound arguments, produce a type error.
1460  *
1461  * Return value: non-0 if true
1462  **/
1463 int
rasqal_literal_as_boolean(rasqal_literal * l,int * error_p)1464 rasqal_literal_as_boolean(rasqal_literal* l, int *error_p)
1465 {
1466   if(!l) {
1467     /* type error */
1468     if(error_p)
1469       *error_p = 1;
1470     return 0;
1471   }
1472 
1473   switch(l->type) {
1474     case RASQAL_LITERAL_STRING:
1475       if(l->datatype) {
1476         if(raptor_uri_equals(l->datatype,
1477                              rasqal_xsd_datatype_type_to_uri(l->world, RASQAL_LITERAL_STRING))) {
1478           /* typed literal with xsd:string datatype -> true if non-empty */
1479           return l->string && *l->string;
1480         }
1481         /* typed literal with other datatype -> type error */
1482         if(error_p)
1483           *error_p = 1;
1484         return 0;
1485       }
1486       /* plain literal -> true if non-empty */
1487       return l->string && *l->string;
1488 
1489     case RASQAL_LITERAL_XSD_STRING:
1490       /* xsd:string -> true if non-empty */
1491       return l->string && *l->string;
1492 
1493     case RASQAL_LITERAL_URI:
1494     case RASQAL_LITERAL_BLANK:
1495     case RASQAL_LITERAL_PATTERN:
1496     case RASQAL_LITERAL_QNAME:
1497     case RASQAL_LITERAL_DECIMAL:
1498     case RASQAL_LITERAL_DATE:
1499     case RASQAL_LITERAL_DATETIME:
1500     case RASQAL_LITERAL_UDT:
1501       if(error_p)
1502         *error_p = 1;
1503       return 0;
1504 
1505     case RASQAL_LITERAL_INTEGER:
1506     case RASQAL_LITERAL_BOOLEAN:
1507     case RASQAL_LITERAL_INTEGER_SUBTYPE:
1508       return l->value.integer != 0;
1509 
1510     case RASQAL_LITERAL_DOUBLE:
1511     case RASQAL_LITERAL_FLOAT:
1512       if(isnan(l->value.floating))
1513         return 0;
1514 
1515       return fabs(l->value.floating) > RASQAL_DOUBLE_EPSILON;
1516 
1517     case RASQAL_LITERAL_VARIABLE:
1518       return rasqal_literal_as_boolean(l->value.variable->value, error_p);
1519 
1520     case RASQAL_LITERAL_UNKNOWN:
1521     default:
1522       RASQAL_FATAL2("Unknown literal type %u", l->type);
1523       return 0; /* keep some compilers happy */
1524   }
1525 }
1526 
1527 
1528 /*
1529  * rasqal_literal_as_integer
1530  * @l: #rasqal_literal object
1531  * @error_p: pointer to error flag
1532  *
1533  * INTERNAL - Return a literal as an integer value
1534  *
1535  * Integers, booleans, double and float literals natural are turned into
1536  * integers. If string values are the lexical form of an integer, that is
1537  * returned.  Otherwise the error flag is set.
1538  *
1539  * Return value: integer value
1540  **/
1541 int
rasqal_literal_as_integer(rasqal_literal * l,int * error_p)1542 rasqal_literal_as_integer(rasqal_literal* l, int *error_p)
1543 {
1544   if(!l) {
1545     /* type error */
1546     if(error_p)
1547       *error_p = 1;
1548     return 0;
1549   }
1550 
1551   switch(l->type) {
1552     case RASQAL_LITERAL_INTEGER:
1553     case RASQAL_LITERAL_INTEGER_SUBTYPE:
1554       return l->value.integer;
1555 
1556     case RASQAL_LITERAL_BOOLEAN:
1557       return l->value.integer != 0;
1558 
1559     case RASQAL_LITERAL_DOUBLE:
1560     case RASQAL_LITERAL_FLOAT:
1561       return RASQAL_FLOATING_AS_INT(l->value.floating);
1562 
1563     case RASQAL_LITERAL_DECIMAL:
1564       {
1565         int error = 0;
1566 
1567         long lvalue = rasqal_xsd_decimal_get_long(l->value.decimal, &error);
1568         if(lvalue < INT_MIN || lvalue > INT_MAX)
1569           error = 1;
1570 
1571         if(error) {
1572           if(error_p)
1573             *error_p = 1;
1574           return 0;
1575         }
1576 
1577         return RASQAL_GOOD_CAST(int, lvalue);
1578       }
1579 
1580     case RASQAL_LITERAL_STRING:
1581     case RASQAL_LITERAL_XSD_STRING:
1582       {
1583         char *eptr;
1584         double  d;
1585         long long_i;
1586 
1587         eptr = NULL;
1588         errno = 0;
1589         long_i = strtol(RASQAL_GOOD_CAST(const char*, l->string), &eptr, 10);
1590         /* If formatted correctly and no under or overflow */
1591         if(RASQAL_GOOD_CAST(unsigned char*, eptr) != l->string && *eptr=='\0' &&
1592            errno != ERANGE)
1593           /* FIXME may lose precision or be out of range from long to int */
1594           return RASQAL_BAD_CAST(int, long_i);
1595 
1596         eptr = NULL;
1597         d = strtod(RASQAL_GOOD_CAST(const char*, l->string), &eptr);
1598         if(RASQAL_GOOD_CAST(unsigned char*, eptr) != l->string && *eptr=='\0')
1599           return RASQAL_FLOATING_AS_INT(d);
1600       }
1601       if(error_p)
1602         *error_p = 1;
1603       return 0;
1604 
1605     case RASQAL_LITERAL_VARIABLE:
1606       return rasqal_literal_as_integer(l->value.variable->value, error_p);
1607 
1608     case RASQAL_LITERAL_BLANK:
1609     case RASQAL_LITERAL_URI:
1610     case RASQAL_LITERAL_QNAME:
1611     case RASQAL_LITERAL_PATTERN:
1612     case RASQAL_LITERAL_DATE:
1613     case RASQAL_LITERAL_DATETIME:
1614     case RASQAL_LITERAL_UDT:
1615       if(error_p)
1616         *error_p = 1;
1617       return 0;
1618 
1619     case RASQAL_LITERAL_UNKNOWN:
1620     default:
1621       RASQAL_FATAL2("Unknown literal type %u", l->type);
1622       return 0; /* keep some compilers happy */
1623   }
1624 }
1625 
1626 
1627 /*
1628  * rasqal_literal_as_double:
1629  * @l: #rasqal_literal object
1630  * @error_p: pointer to error flag
1631  *
1632  * INTERNAL - Return a literal as a double precision floating value
1633  *
1634  * Integers, booleans, double and float literals natural are turned into
1635  * integers. If string values are the lexical form of an floating, that is
1636  * returned.  Otherwise the error flag is set.
1637  *
1638  * Return value: double precision floating value
1639  **/
1640 double
rasqal_literal_as_double(rasqal_literal * l,int * error_p)1641 rasqal_literal_as_double(rasqal_literal* l, int *error_p)
1642 {
1643   if(!l) {
1644     /* type error */
1645     *error_p = 1;
1646     return 0.0;
1647   }
1648 
1649   switch(l->type) {
1650     case RASQAL_LITERAL_INTEGER:
1651     case RASQAL_LITERAL_BOOLEAN:
1652     case RASQAL_LITERAL_INTEGER_SUBTYPE:
1653       return (double)l->value.integer;
1654 
1655     case RASQAL_LITERAL_DOUBLE:
1656     case RASQAL_LITERAL_FLOAT:
1657       return l->value.floating;
1658 
1659     case RASQAL_LITERAL_DECIMAL:
1660       return rasqal_xsd_decimal_get_double(l->value.decimal);
1661 
1662     case RASQAL_LITERAL_STRING:
1663     case RASQAL_LITERAL_XSD_STRING:
1664       {
1665         char *eptr = NULL;
1666         double  d = strtod(RASQAL_GOOD_CAST(const char*, l->string), &eptr);
1667         if(RASQAL_GOOD_CAST(unsigned char*, eptr) != l->string && *eptr == '\0')
1668           return d;
1669       }
1670       if(error_p)
1671         *error_p = 1;
1672       return 0.0;
1673 
1674     case RASQAL_LITERAL_VARIABLE:
1675       return rasqal_literal_as_double(l->value.variable->value, error_p);
1676 
1677     case RASQAL_LITERAL_BLANK:
1678     case RASQAL_LITERAL_URI:
1679     case RASQAL_LITERAL_QNAME:
1680     case RASQAL_LITERAL_PATTERN:
1681     case RASQAL_LITERAL_DATE:
1682     case RASQAL_LITERAL_DATETIME:
1683     case RASQAL_LITERAL_UDT:
1684       if(error_p)
1685         *error_p = 1;
1686       return 0.0;
1687 
1688     case RASQAL_LITERAL_UNKNOWN:
1689     default:
1690       RASQAL_FATAL2("Unknown literal type %u", l->type);
1691       return 0.0; /* keep some compilers happy */
1692   }
1693 }
1694 
1695 
1696 /*
1697  * rasqal_literal_as_uri:
1698  * @l: #rasqal_literal object
1699  *
1700  * INTERNAL - Return a literal as a raptor_uri*
1701  *
1702  * Return value: shared raptor_uri* value or NULL on failure
1703  **/
1704 raptor_uri*
rasqal_literal_as_uri(rasqal_literal * l)1705 rasqal_literal_as_uri(rasqal_literal* l)
1706 {
1707   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
1708 
1709   if(l->type == RASQAL_LITERAL_URI)
1710     return l->value.uri;
1711 
1712   if(l->type == RASQAL_LITERAL_VARIABLE && l->value.variable->value)
1713     return rasqal_literal_as_uri(l->value.variable->value);
1714 
1715   return NULL;
1716 }
1717 
1718 
1719 /**
1720  * rasqal_literal_as_counted_string:
1721  * @l: #rasqal_literal object
1722  * @len_p: pointer to store length of string (or NULL)
1723  * @flags: comparison flags
1724  * @error_p: pointer to error
1725  *
1726  * Return a counted string format of a literal according to flags.
1727  *
1728  * flag bits affects conversion:
1729  *   RASQAL_COMPARE_XQUERY: use XQuery conversion rules
1730  *
1731  * If @error is not NULL, *error is set to non-0 on error
1732  *
1733  * Return value: pointer to a shared string format of the literal.
1734  **/
1735 const unsigned char*
rasqal_literal_as_counted_string(rasqal_literal * l,size_t * len_p,int flags,int * error_p)1736 rasqal_literal_as_counted_string(rasqal_literal* l, size_t *len_p,
1737                                  int flags, int *error_p)
1738 {
1739   if(!l) {
1740     /* type error */
1741     if(error_p)
1742       *error_p = 1;
1743     return NULL;
1744   }
1745 
1746   switch(l->type) {
1747     case RASQAL_LITERAL_XSD_STRING:
1748     case RASQAL_LITERAL_BOOLEAN:
1749     case RASQAL_LITERAL_INTEGER:
1750     case RASQAL_LITERAL_DOUBLE:
1751     case RASQAL_LITERAL_STRING:
1752     case RASQAL_LITERAL_BLANK:
1753     case RASQAL_LITERAL_PATTERN:
1754     case RASQAL_LITERAL_QNAME:
1755     case RASQAL_LITERAL_FLOAT:
1756     case RASQAL_LITERAL_DECIMAL:
1757     case RASQAL_LITERAL_DATE:
1758     case RASQAL_LITERAL_DATETIME:
1759     case RASQAL_LITERAL_UDT:
1760     case RASQAL_LITERAL_INTEGER_SUBTYPE:
1761       if(len_p)
1762         *len_p = l->string_len;
1763 
1764       return l->string;
1765 
1766     case RASQAL_LITERAL_URI:
1767       if(flags & RASQAL_COMPARE_XQUERY) {
1768         if(error_p)
1769           *error_p = 1;
1770         return NULL;
1771       }
1772       return raptor_uri_as_counted_string(l->value.uri, len_p);
1773 
1774     case RASQAL_LITERAL_VARIABLE:
1775       return rasqal_literal_as_counted_string(l->value.variable->value, len_p,
1776                                               flags, error_p);
1777 
1778     case RASQAL_LITERAL_UNKNOWN:
1779     default:
1780       RASQAL_FATAL2("Unknown literal type %u", l->type);
1781   }
1782 
1783   return NULL;
1784 }
1785 
1786 
1787 /**
1788  * rasqal_literal_as_string_flags:
1789  * @l: #rasqal_literal object
1790  * @flags: comparison flags
1791  * @error_p: pointer to error
1792  *
1793  * Return the string format of a literal according to flags.
1794  *
1795  * flag bits affects conversion:
1796  *   RASQAL_COMPARE_XQUERY: use XQuery conversion rules
1797  *
1798  * If @error is not NULL, *error is set to non-0 on error
1799  *
1800  * Return value: pointer to a shared string format of the literal.
1801  **/
1802 const unsigned char*
rasqal_literal_as_string_flags(rasqal_literal * l,int flags,int * error_p)1803 rasqal_literal_as_string_flags(rasqal_literal* l, int flags, int *error_p)
1804 {
1805   if(!l) {
1806     /* type error */
1807     *error_p = 1;
1808     return NULL;
1809   }
1810 
1811   return rasqal_literal_as_counted_string(l, NULL, flags, error_p);
1812 }
1813 
1814 
1815 /**
1816  * rasqal_literal_as_string:
1817  * @l: #rasqal_literal object
1818  *
1819  * Return the string format of a literal.
1820  *
1821  * Return value: pointer to a shared string format of the literal.
1822  **/
1823 const unsigned char*
rasqal_literal_as_string(rasqal_literal * l)1824 rasqal_literal_as_string(rasqal_literal* l)
1825 {
1826   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
1827 
1828   return rasqal_literal_as_string_flags(l, 0, NULL);
1829 }
1830 
1831 /**
1832  * rasqal_literal_as_variable:
1833  * @l: #rasqal_literal object
1834  *
1835  * Get the variable inside a literal.
1836  *
1837  * Return value: the #rasqal_variable or NULL if the literal is not a variable
1838  **/
1839 rasqal_variable*
rasqal_literal_as_variable(rasqal_literal * l)1840 rasqal_literal_as_variable(rasqal_literal* l)
1841 {
1842   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
1843 
1844   return (l->type == RASQAL_LITERAL_VARIABLE) ? l->value.variable : NULL;
1845 }
1846 
1847 
1848 /*
1849  * rasqal_literal_promote_numerics:
1850  * @l1: first literal
1851  * @l2: second literal
1852  * @flags: promotion flags
1853  *
1854  * INTERNAL - Calculate the type to promote a pair of literals to
1855  *
1856  * Numeric type promotion
1857  * http://www.w3.org/TR/xpath20/#dt-type-promotion
1858  *
1859  * [[xs:decimal (or any type derived by restriction from xs:decimal,
1860  * including xs:integer) can be promoted to either of the types
1861  * xs:float or xs:double.]]
1862  *
1863  * For here that means xs:integer to xs:double and xs:decimal to xs:double
1864  *
1865  * Return value: promote type or RASQAL_LITERAL_UNKNOWN
1866  */
1867 static rasqal_literal_type
rasqal_literal_promote_numerics(rasqal_literal * l1,rasqal_literal * l2,int flags)1868 rasqal_literal_promote_numerics(rasqal_literal* l1, rasqal_literal* l2,
1869                                 int flags)
1870 {
1871   rasqal_literal_type type1 = l1->type;
1872   rasqal_literal_type type2 = l2->type;
1873   rasqal_literal_type promotion_type;
1874   rasqal_literal_type result_type = RASQAL_LITERAL_UNKNOWN;
1875 
1876   /* B1 1.b http://www.w3.org/TR/xpath20/#dt-type-promotion */
1877   if(type1 == RASQAL_LITERAL_DECIMAL &&
1878      (type2 == RASQAL_LITERAL_FLOAT || type2 == RASQAL_LITERAL_DOUBLE)) {
1879     result_type = type2;
1880     goto done;
1881   } else if(type2 == RASQAL_LITERAL_DECIMAL &&
1882      (type1 == RASQAL_LITERAL_FLOAT || type1 == RASQAL_LITERAL_DOUBLE)) {
1883     result_type = type1;
1884     goto done;
1885   }
1886 
1887   for(promotion_type = RASQAL_LITERAL_FIRST_XSD;
1888       promotion_type <= RASQAL_LITERAL_LAST_XSD;
1889       promotion_type = (rasqal_literal_type)(RASQAL_GOOD_CAST(unsigned int, promotion_type) + 1)) {
1890     rasqal_literal_type parent_type1 = rasqal_xsd_datatype_parent_type(type1);
1891     rasqal_literal_type parent_type2 = rasqal_xsd_datatype_parent_type(type2);
1892 
1893     /* Finished */
1894     if(type1 == type2) {
1895       result_type = type1;
1896       break;
1897     }
1898 
1899     if(parent_type1 == type2) {
1900       result_type = type2;
1901       break;
1902     }
1903 
1904     if(parent_type2 == type1) {
1905       result_type = type1;
1906       break;
1907     }
1908 
1909     if(parent_type1 == promotion_type)
1910       type1 = promotion_type;
1911     if(parent_type2 == promotion_type)
1912       type2 = promotion_type;
1913   }
1914 
1915   done:
1916   RASQAL_DEBUG4("literal 1: type %s   literal 2: type %s  promoting to %s\n",
1917                 rasqal_literal_type_label(type1),
1918                 rasqal_literal_type_label(type2),
1919                 rasqal_literal_type_label(result_type));
1920 
1921   return result_type;
1922 }
1923 
1924 
1925 /**
1926  * rasqal_literal_get_rdf_term_type:
1927  * @l: literal
1928  *
1929  * Get the RDF term type of a literal
1930  *
1931  * An RDF term can be one of three choices:
1932  *   1. URI:  RASQAL_LITERAL_URI
1933  *   2. literal: RASQAL_LITERAL_STRING
1934  *   3. blank node: RASQAL_LITERAL_BLANK
1935  *
1936  * Other non RDF-term cases include: NULL pointer, invalid literal,
1937  * unknown type, a variable or other special cases (such as XML QName
1938  * or Regex pattern) which all turn into RASQAL_LITERAL_UNKNOWN
1939  *
1940  * Return value: type or RASQAL_LITERAL_UNKNOWN if cannot be an RDF term
1941  */
1942 rasqal_literal_type
rasqal_literal_get_rdf_term_type(rasqal_literal * l)1943 rasqal_literal_get_rdf_term_type(rasqal_literal* l)
1944 {
1945   rasqal_literal_type type;
1946 
1947   if(!l)
1948     return RASQAL_LITERAL_UNKNOWN;
1949 
1950   type = l->type;
1951 
1952   /* squash literal datatypes into one type: RDF Literal */
1953   if((type >= RASQAL_LITERAL_FIRST_XSD && type <= RASQAL_LITERAL_LAST_XSD) ||
1954      type == RASQAL_LITERAL_DATE || type == RASQAL_LITERAL_INTEGER_SUBTYPE)
1955     type = RASQAL_LITERAL_STRING;
1956 
1957   if(type == RASQAL_LITERAL_UDT)
1958     type = RASQAL_LITERAL_STRING;
1959 
1960   if(type != RASQAL_LITERAL_URI &&
1961      type != RASQAL_LITERAL_STRING &&
1962      type != RASQAL_LITERAL_BLANK)
1963     type = RASQAL_LITERAL_UNKNOWN;
1964 
1965   return type;
1966 }
1967 
1968 /**
1969  * rasqal_literal_get_type:
1970  * @l: literal
1971  *
1972  * Get the type of a literal
1973  *
1974  * Return value: the rasqal literal type or RASQAL_LITERAL_UNKNOWN if l is NULL
1975  */
1976 rasqal_literal_type
rasqal_literal_get_type(rasqal_literal * l)1977 rasqal_literal_get_type(rasqal_literal* l)
1978 {
1979   rasqal_literal_type type;
1980 
1981   if(!l)
1982     return RASQAL_LITERAL_UNKNOWN;
1983 
1984   type = l->type;
1985 
1986   return type;
1987 }
1988 
1989 /**
1990  * rasqal_literal_get_language:
1991  * @l: literal
1992  *
1993  * Get the language of a literal (if set)
1994  *
1995  * Return value: the literal language or NULL
1996  */
1997 char*
rasqal_literal_get_language(rasqal_literal * l)1998 rasqal_literal_get_language(rasqal_literal* l)
1999 {
2000   if(!l)
2001     return NULL;
2002 
2003   return l->language;
2004 }
2005 
2006 
2007 
2008 
2009 /*
2010  * rasqal_new_literal_from_promotion:
2011  * @lit: existing literal
2012  * @type: type to promote to
2013  * @flags: 0 (flag #RASQAL_COMPARE_URI is unused: was RDQL)
2014  *
2015  * INTERNAL - Make a new literal from a type promotion
2016  *
2017  * New literal or NULL on failure
2018 */
2019 static rasqal_literal*
rasqal_new_literal_from_promotion(rasqal_literal * lit,rasqal_literal_type type,int flags)2020 rasqal_new_literal_from_promotion(rasqal_literal* lit,
2021                                   rasqal_literal_type type,
2022                                   int flags)
2023 {
2024   rasqal_literal* new_lit = NULL;
2025   int errori = 0;
2026   double d;
2027   int i;
2028   unsigned char *new_s = NULL;
2029   unsigned char* s;
2030   size_t len = 0;
2031   rasqal_xsd_decimal* dec = NULL;
2032 
2033   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(lit, rasqal_literal, NULL);
2034 
2035   if(lit->type == type)
2036     return rasqal_new_literal_from_literal(lit);
2037 
2038   RASQAL_DEBUG3("promoting literal type %s to type %s\n",
2039                 rasqal_literal_type_label(lit->type),
2040                 rasqal_literal_type_label(type));
2041 
2042   if(lit->type == RASQAL_LITERAL_DATE && type == RASQAL_LITERAL_DATETIME) {
2043     rasqal_xsd_datetime* dt;
2044 
2045     dt = rasqal_new_xsd_datetime_from_xsd_date(lit->world, lit->value.date);
2046 
2047     /* Promotion for comparison ensures a timezone is present.
2048      *
2049      * " If either operand to a comparison function on date or time
2050      * values does not have an (explicit) timezone then, for the
2051      * purpose of the operation, an implicit timezone, provided by the
2052      * dynamic context Section C.2 Dynamic Context ComponentsXP, is
2053      * assumed to be present as part of the value."
2054      * -- XQuery & XPath F&O
2055      *    Section 10.4 Comparison Operators on Duration, Date and Time Values
2056      * http://www.w3.org/TR/xpath-functions/#comp.duration.datetime
2057      */
2058     if(dt->have_tz == 'N') {
2059       dt->have_tz = 'Z';
2060       dt->timezone_minutes = 0;
2061     }
2062     return rasqal_new_datetime_literal_from_datetime(lit->world, dt);
2063   }
2064 
2065   /* May not promote to non-numerics */
2066   if(!rasqal_xsd_datatype_is_numeric(type)) {
2067     RASQAL_DEBUG2("NOT promoting to non-numeric type %s\n",
2068                   rasqal_literal_type_label(lit->type));
2069 
2070     if(type == RASQAL_LITERAL_STRING || type ==  RASQAL_LITERAL_UDT) {
2071       s = RASQAL_GOOD_CAST(unsigned char*, rasqal_literal_as_counted_string(lit, &len, 0, NULL));
2072       new_s = RASQAL_MALLOC(unsigned char*, len + 1);
2073       if(new_s) {
2074         raptor_uri* dt_uri = NULL;
2075         memcpy(new_s, s, len + 1);
2076         if(lit->datatype) {
2077           dt_uri = raptor_uri_copy(lit->datatype);
2078         }
2079         return rasqal_new_string_literal_node(lit->world, new_s, NULL, dt_uri);
2080       } else
2081         return NULL;
2082     }
2083     return NULL;
2084   }
2085 
2086   switch(type) {
2087     case RASQAL_LITERAL_DECIMAL:
2088       dec = rasqal_new_xsd_decimal(lit->world);
2089       if(dec) {
2090         d = rasqal_literal_as_double(lit, &errori);
2091         if(errori) {
2092           rasqal_free_xsd_decimal(dec);
2093           new_lit = NULL;
2094         } else {
2095           rasqal_xsd_decimal_set_double(dec, d);
2096           new_lit = rasqal_new_decimal_literal_from_decimal(lit->world,
2097                                                             NULL, dec);
2098         }
2099       }
2100       break;
2101 
2102 
2103     case RASQAL_LITERAL_DOUBLE:
2104       d = rasqal_literal_as_double(lit, &errori);
2105       if(errori)
2106         new_lit = NULL;
2107       else
2108         new_lit = rasqal_new_double_literal(lit->world, d);
2109       break;
2110 
2111 
2112     case RASQAL_LITERAL_FLOAT:
2113       d = rasqal_literal_as_double(lit, &errori);
2114       if(errori)
2115         new_lit = NULL;
2116       else if(d < FLT_MIN || d > FLT_MAX)
2117         /* Cannot be stored in a float - fail */
2118         new_lit = NULL;
2119       else
2120         new_lit = rasqal_new_floating_literal(lit->world, RASQAL_LITERAL_FLOAT,
2121                                               d);
2122       break;
2123 
2124 
2125     case RASQAL_LITERAL_INTEGER:
2126     case RASQAL_LITERAL_INTEGER_SUBTYPE:
2127       i = rasqal_literal_as_integer(lit, &errori);
2128       /* failure always means no match */
2129       if(errori)
2130         new_lit = NULL;
2131       else
2132         new_lit = rasqal_new_integer_literal(lit->world, type, i);
2133       break;
2134 
2135     case RASQAL_LITERAL_BOOLEAN:
2136       if(flags & RASQAL_COMPARE_URI)
2137         i = rasqal_xsd_boolean_value_from_string(lit->string);
2138       else
2139         i = rasqal_literal_as_boolean(lit, &errori);
2140       /* failure always means no match */
2141       if(errori)
2142         new_lit = NULL;
2143       else
2144         new_lit = rasqal_new_integer_literal(lit->world, type, i);
2145       break;
2146 
2147     case RASQAL_LITERAL_STRING:
2148       s = RASQAL_GOOD_CAST(unsigned char*, rasqal_literal_as_counted_string(lit, &len, 0, NULL));
2149       new_s = RASQAL_MALLOC(unsigned char*, len + 1);
2150       if(new_s) {
2151         memcpy(new_s, s, len + 1);
2152         new_lit = rasqal_new_string_literal(lit->world, new_s, NULL, NULL, NULL);
2153       }
2154       break;
2155 
2156     case RASQAL_LITERAL_XSD_STRING:
2157       s = RASQAL_GOOD_CAST(unsigned char*, rasqal_literal_as_counted_string(lit, &len, 0, NULL));
2158       new_s = RASQAL_MALLOC(unsigned char*, len + 1);
2159       if(new_s) {
2160         raptor_uri* dt_uri;
2161         memcpy(new_s, s, len + 1);
2162         dt_uri = rasqal_xsd_datatype_type_to_uri(lit->world, lit->type);
2163         dt_uri = raptor_uri_copy(dt_uri);
2164         new_lit = rasqal_new_string_literal(lit->world, new_s, NULL, dt_uri,
2165                                             NULL);
2166       }
2167       break;
2168 
2169     case RASQAL_LITERAL_UNKNOWN:
2170     case RASQAL_LITERAL_BLANK:
2171     case RASQAL_LITERAL_URI:
2172     case RASQAL_LITERAL_DATE:
2173     case RASQAL_LITERAL_DATETIME:
2174     case RASQAL_LITERAL_PATTERN:
2175     case RASQAL_LITERAL_QNAME:
2176     case RASQAL_LITERAL_VARIABLE:
2177     case RASQAL_LITERAL_UDT:
2178     default:
2179       errori = 1;
2180       new_lit = NULL;
2181   }
2182 
2183 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2184   if(new_lit)
2185     RASQAL_DEBUG4("promoted literal type %s to type %s, with value '%s'\n",
2186                   rasqal_literal_type_label(lit->type),
2187                   rasqal_literal_type_label(new_lit->type),
2188                   rasqal_literal_as_string(new_lit));
2189   else
2190     RASQAL_DEBUG3("failed to promote literal type %s to type %s\n",
2191                   rasqal_literal_type_label(lit->type),
2192                   rasqal_literal_type_label(type));
2193 #endif
2194 
2195   return new_lit;
2196 }
2197 
2198 
2199 /*
2200  * rasqal_literal_string_languages_compare
2201  * @l1: #rasqal_literal first literal
2202  * @l2: #rasqal_literal second literal
2203  *
2204  * INTERNAL - Compare two string literals languages
2205  *
2206  * Return value: non-0 if equal
2207  */
2208 int
rasqal_literal_string_languages_compare(rasqal_literal * l1,rasqal_literal * l2)2209 rasqal_literal_string_languages_compare(rasqal_literal* l1, rasqal_literal* l2)
2210 {
2211   int rc = 0;
2212 
2213   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, 0);
2214   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l2, rasqal_literal, 0);
2215 
2216   if(l1->language && l2->language)
2217     /* both have a language */
2218     rc = rasqal_strcasecmp(RASQAL_GOOD_CAST(const char*, l1->language),
2219                            RASQAL_GOOD_CAST(const char*, l2->language));
2220   else if(l1->language || l2->language)
2221     /* only one has a language; the language-less one is earlier */
2222     rc = (!l1->language ? -1 : 1);
2223 
2224   return rc;
2225 }
2226 
2227 
2228 /*
2229  * rasqal_literal_string_datatypes_compare:
2230  * @l1: first string literal
2231  * @l2: first string literal
2232  *
2233  * INTERNAL - Compare the datatypes of two string RDF literals
2234  *
2235  * Return value: <1, 0, >0
2236  */
2237 int
rasqal_literal_string_datatypes_compare(rasqal_literal * l1,rasqal_literal * l2)2238 rasqal_literal_string_datatypes_compare(rasqal_literal* l1, rasqal_literal* l2)
2239 {
2240   int rc = 0;
2241 
2242   if(l1->datatype && l2->datatype) {
2243     /* both have a datatype */
2244     rc = raptor_uri_compare(l1->datatype, l2->datatype);
2245   } else if(l1->datatype || l2->datatype)
2246     /* only one has a datatype; the datatype-less one is earlier */
2247     rc = (!l1->datatype ? -1 : 1);
2248 
2249   return rc;
2250 }
2251 
2252 
2253 /*
2254  * rasqal_literal_string_compare:
2255  * @l1: first string literal
2256  * @l2: first string literal
2257  * @flags: string compare flags (flag #RASQAL_COMPARE_NOCASE is unused; was RDQL)
2258  *
2259  * INTERNAL - Compare two string RDF literals.  Bother are the same
2260  * type and either #RASQAL_LITERAL_STRING or #RASQAL_LITERAL_UDT
2261  * however their datatype URIs are the non-promoted types and may differ.
2262  *
2263  * Uses raptor_term_compare() logic for the #RAPTOR_TERM_TYPE_LITERAL
2264  * case, except adding case independent compare for RDQL.
2265  *
2266  * Return value: <1, 0, >0
2267  */
2268 static int
rasqal_literal_string_compare(rasqal_literal * l1,rasqal_literal * l2,int flags)2269 rasqal_literal_string_compare(rasqal_literal* l1, rasqal_literal* l2,
2270                               int flags)
2271 {
2272   int rc;
2273 
2274   if(flags & RASQAL_COMPARE_NOCASE)
2275     rc = rasqal_strcasecmp(RASQAL_GOOD_CAST(const char*, l1->string),
2276                            RASQAL_GOOD_CAST(const char*, l2->string));
2277   else
2278     rc = strcmp(RASQAL_GOOD_CAST(const char*, l1->string),
2279                 RASQAL_GOOD_CAST(const char*, l2->string));
2280   if(rc)
2281     return rc;
2282 
2283   rc = rasqal_literal_string_languages_compare(l1, l2);
2284   if(rc)
2285     return rc;
2286 
2287   return rasqal_literal_string_datatypes_compare(l1, l2);
2288 }
2289 
2290 
2291 /*
2292  * rasqal_literal_rdql_promote_calculate:
2293  * @l1: first literal
2294  * @l2: second literal
2295  *
2296  * INTERNAL - Handle RDQL type promotion rules
2297  *
2298  * Return value: type to promote to or RASQAL_LITERAL_UNKNOWN if not possible.
2299  */
2300 static rasqal_literal_type
rasqal_literal_rdql_promote_calculate(rasqal_literal * l1,rasqal_literal * l2)2301 rasqal_literal_rdql_promote_calculate(rasqal_literal* l1, rasqal_literal* l2)
2302 {
2303   int seen_string = 0;
2304   int seen_int = 0;
2305   int seen_double = 0;
2306   int seen_boolean = 0;
2307   int i;
2308   rasqal_literal *lits[2];
2309   rasqal_literal_type type = RASQAL_LITERAL_UNKNOWN;
2310 
2311   lits[0] = l1;
2312   lits[1] = l2;
2313 
2314   for(i = 0; i < 2; i++) {
2315     switch(lits[i]->type) {
2316     case RASQAL_LITERAL_URI:
2317     case RASQAL_LITERAL_DECIMAL:
2318       break;
2319 
2320     case RASQAL_LITERAL_STRING:
2321     case RASQAL_LITERAL_XSD_STRING:
2322     case RASQAL_LITERAL_BLANK:
2323     case RASQAL_LITERAL_PATTERN:
2324     case RASQAL_LITERAL_QNAME:
2325     case RASQAL_LITERAL_DATE:
2326     case RASQAL_LITERAL_DATETIME:
2327     case RASQAL_LITERAL_UDT:
2328       seen_string++;
2329       break;
2330 
2331     case RASQAL_LITERAL_BOOLEAN:
2332       seen_boolean = 1;
2333       break;
2334 
2335     case RASQAL_LITERAL_INTEGER:
2336     case RASQAL_LITERAL_INTEGER_SUBTYPE:
2337       seen_int++;
2338       break;
2339 
2340     case RASQAL_LITERAL_DOUBLE:
2341     case RASQAL_LITERAL_FLOAT:
2342       seen_double++;
2343       break;
2344 
2345     case RASQAL_LITERAL_VARIABLE:
2346       /* this case was dealt with elsewhere */
2347 
2348     case RASQAL_LITERAL_UNKNOWN:
2349     default:
2350       RASQAL_FATAL2("Unknown literal type %u", lits[i]->type);
2351     }
2352   }
2353 
2354 
2355   if(lits[0]->type != lits[1]->type) {
2356     type = seen_string ? RASQAL_LITERAL_STRING : RASQAL_LITERAL_INTEGER;
2357     if((seen_int & seen_double) || (seen_int & seen_string))
2358       type = RASQAL_LITERAL_DOUBLE;
2359     if(seen_boolean & seen_string)
2360       type = RASQAL_LITERAL_BOOLEAN;
2361   } else
2362     type = lits[0]->type;
2363 
2364   return type;
2365 }
2366 
2367 
2368 
2369 /**
2370  * rasqal_literal_compare:
2371  * @l1: #rasqal_literal first literal
2372  * @l2: #rasqal_literal second literal
2373  * @flags: comparison flags
2374  * @error_p: pointer to error
2375  *
2376  * Compare two literals with type promotion.
2377  *
2378  * The two literals are compared across their range.  If the types
2379  * are not the same, they are promoted.  If one is a double or float, the
2380  * other is promoted to double, otherwise for integers, otherwise
2381  * to strings (all literals have a string value).
2382  *
2383  * The comparison returned is as for strcmp, first before second
2384  * returns <0.  equal returns 0, and first after second returns >0.
2385  * For URIs, the string value is used for the comparsion.
2386  *
2387  * flag bits affects comparisons:
2388  *   RASQAL_COMPARE_NOCASE: use case independent string comparisons
2389  *   RASQAL_COMPARE_XQUERY: use XQuery comparison and type promotion rules
2390  *   RASQAL_COMPARE_RDF: use RDF term comparison
2391  *   RASQAL_COMPARE_URI: allow comparison of URIs (typically for SPARQL ORDER)
2392  *
2393  * If @error is not NULL, *error is set to non-0 on error
2394  *
2395  * Return value: <0, 0, or >0 as described above.
2396  **/
2397 int
rasqal_literal_compare(rasqal_literal * l1,rasqal_literal * l2,int flags,int * error_p)2398 rasqal_literal_compare(rasqal_literal* l1, rasqal_literal* l2, int flags,
2399                        int *error_p)
2400 {
2401   rasqal_literal *lits[2];
2402   rasqal_literal* new_lits[2]; /* after promotions */
2403   rasqal_literal_type type; /* target promotion type */
2404   int i;
2405   int result = 0;
2406   double d = 0;
2407   int promotion = 0;
2408 
2409   if(error_p)
2410     *error_p = 0;
2411 
2412   if(!l1 || !l2) {
2413     if(error_p)
2414       *error_p = 1;
2415     return 0;
2416   }
2417 
2418   lits[0] = rasqal_literal_value(l1);
2419   lits[1] = rasqal_literal_value(l2);
2420 
2421   /* null literals */
2422   if(!lits[0] || !lits[1]) {
2423     /* if either is not NULL, the comparison fails */
2424     if(lits[0] || lits[1]) {
2425       if(error_p)
2426         *error_p = 1;
2427     }
2428     return 0;
2429   }
2430 
2431   new_lits[0] = NULL;
2432   new_lits[1] = NULL;
2433 
2434 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2435   RASQAL_DEBUG3("literal 0 type %s.  literal 1 type %s\n",
2436                 rasqal_literal_type_label(lits[0]->type),
2437                 rasqal_literal_type_label(lits[1]->type));
2438 #endif
2439 
2440   if(flags & RASQAL_COMPARE_RDF) {
2441     /* no promotion but compare as RDF terms; like rasqal_literal_as_node() */
2442     rasqal_literal_type type0 = rasqal_literal_get_rdf_term_type(lits[0]);
2443     rasqal_literal_type type1 = rasqal_literal_get_rdf_term_type(lits[1]);
2444     int type_diff;
2445 
2446     if(type0 == RASQAL_LITERAL_UNKNOWN || type1 == RASQAL_LITERAL_UNKNOWN)
2447       return 1;
2448 
2449     type_diff = RASQAL_GOOD_CAST(int, type0) - RASQAL_GOOD_CAST(int, type1);
2450     if(type_diff != 0) {
2451 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2452       RASQAL_DEBUG2("RDF term literal returning type difference %d\n",
2453                     type_diff);
2454 #endif
2455       return type_diff;
2456     }
2457     type = type1;
2458   } else if(flags & RASQAL_COMPARE_XQUERY) {
2459     /* SPARQL / XQuery promotion rules */
2460     rasqal_literal_type type0 = lits[0]->type;
2461     rasqal_literal_type type1 = lits[1]->type;
2462 
2463 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2464     RASQAL_DEBUG3("xquery literal compare types %s vs %s\n",
2465                   rasqal_literal_type_label(type0),
2466                   rasqal_literal_type_label(type1));
2467 #endif
2468 
2469     /* cannot compare UDTs */
2470     if(type0 == RASQAL_LITERAL_UDT || type1 == RASQAL_LITERAL_UDT) {
2471       if(error_p)
2472         *error_p = 1;
2473       return 0;
2474     }
2475 
2476     type = rasqal_literal_promote_numerics(lits[0], lits[1], flags);
2477     if(type == RASQAL_LITERAL_UNKNOWN) {
2478       int type_diff;
2479 
2480       /* no promotion but compare as RDF terms; like rasqal_literal_as_node() */
2481       type0 = rasqal_literal_get_rdf_term_type(lits[0]);
2482       type1 = rasqal_literal_get_rdf_term_type(lits[1]);
2483 
2484       if(type0 == RASQAL_LITERAL_UNKNOWN || type1 == RASQAL_LITERAL_UNKNOWN)
2485         return 1;
2486 
2487       type_diff = RASQAL_GOOD_CAST(int, type0) - RASQAL_GOOD_CAST(int, type1);
2488       if(type_diff != 0) {
2489 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2490         RASQAL_DEBUG2("RDF term literal returning type difference %d\n",
2491                       type_diff);
2492 #endif
2493         return type_diff;
2494       }
2495       if(error_p)
2496         *error_p = 1;
2497       return 0;
2498     }
2499     promotion = 1;
2500   } else {
2501     /* RDQL promotion rules */
2502     type = rasqal_literal_rdql_promote_calculate(lits[0], lits[1]);
2503     promotion = 1;
2504   }
2505 
2506 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2507   if(promotion)
2508     RASQAL_DEBUG2("promoting to type %s\n", rasqal_literal_type_label(type));
2509 #endif
2510 
2511   /* do promotions */
2512   for(i = 0; i < 2; i++) {
2513     if(promotion) {
2514       new_lits[i] = rasqal_new_literal_from_promotion(lits[i], type, flags);
2515       if(!new_lits[i]) {
2516         if(error_p)
2517           *error_p = 1;
2518         goto done;
2519       }
2520     } else {
2521       new_lits[i] = lits[i];
2522     }
2523   }
2524 
2525 
2526   switch(type) {
2527     case RASQAL_LITERAL_URI:
2528       if(flags & RASQAL_COMPARE_URI)
2529         result = raptor_uri_compare(new_lits[0]->value.uri,
2530                                     new_lits[1]->value.uri);
2531       else {
2532         if(error_p)
2533           *error_p = 1;
2534         result = 0;
2535         goto done;
2536       }
2537       break;
2538 
2539     case RASQAL_LITERAL_STRING:
2540     case RASQAL_LITERAL_UDT:
2541       result = rasqal_literal_string_compare(new_lits[0], new_lits[1],
2542                                              flags);
2543       break;
2544 
2545     case RASQAL_LITERAL_BLANK:
2546     case RASQAL_LITERAL_PATTERN:
2547     case RASQAL_LITERAL_QNAME:
2548     case RASQAL_LITERAL_XSD_STRING:
2549       if(flags & RASQAL_COMPARE_NOCASE)
2550         result = rasqal_strcasecmp(RASQAL_GOOD_CAST(const char*, new_lits[0]->string),
2551                                    RASQAL_GOOD_CAST(const char*, new_lits[1]->string));
2552       else
2553         result = strcmp(RASQAL_GOOD_CAST(const char*, new_lits[0]->string),
2554                         RASQAL_GOOD_CAST(const char*, new_lits[1]->string));
2555       break;
2556 
2557     case RASQAL_LITERAL_DATE:
2558       result = rasqal_xsd_date_compare(new_lits[0]->value.date,
2559                                        new_lits[1]->value.date,
2560                                        error_p);
2561       break;
2562 
2563     case RASQAL_LITERAL_DATETIME:
2564       result = rasqal_xsd_datetime_compare2(new_lits[0]->value.datetime,
2565                                             new_lits[1]->value.datetime,
2566                                             error_p);
2567       break;
2568 
2569     case RASQAL_LITERAL_INTEGER:
2570     case RASQAL_LITERAL_BOOLEAN:
2571     case RASQAL_LITERAL_INTEGER_SUBTYPE:
2572       result = new_lits[0]->value.integer - new_lits[1]->value.integer;
2573       break;
2574 
2575     case RASQAL_LITERAL_DOUBLE:
2576     case RASQAL_LITERAL_FLOAT:
2577       d = new_lits[0]->value.floating - new_lits[1]->value.floating;
2578       result = (d > 0.0) ? 1: (d < 0.0) ? -1 : 0;
2579       break;
2580 
2581     case RASQAL_LITERAL_DECIMAL:
2582       result = rasqal_xsd_decimal_compare(new_lits[0]->value.decimal,
2583                                         new_lits[1]->value.decimal);
2584       break;
2585 
2586     case RASQAL_LITERAL_UNKNOWN:
2587     case RASQAL_LITERAL_VARIABLE:
2588     default:
2589       RASQAL_FATAL2("Literal type %u cannot be compared", type);
2590       result = 0; /* keep some compilers happy */
2591   }
2592 
2593   done:
2594   if(promotion) {
2595     for(i = 0; i < 2; i++) {
2596       if(new_lits[i])
2597         rasqal_free_literal(new_lits[i]);
2598     }
2599   }
2600 
2601   return result;
2602 }
2603 
2604 
2605 /*
2606  * rasqal_literal_is_string:
2607  * @l1: #rasqal_literal first literal
2608  *
2609  * INTERNAL - check literal is a string literal
2610  *
2611  * Return value: non-0 if literal is a string
2612  */
2613 int
rasqal_literal_is_string(rasqal_literal * l1)2614 rasqal_literal_is_string(rasqal_literal* l1)
2615 {
2616   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, 1);
2617 
2618   return (l1->type == RASQAL_LITERAL_STRING || l1->type == RASQAL_LITERAL_XSD_STRING);
2619 }
2620 
2621 
2622 /*
2623  * rasqal_literal_string_equals_flags:
2624  * @l1: #rasqal_literal first literal
2625  * @l2: #rasqal_literal second literal
2626  * @flags: comparison flags
2627  * @error_p: pointer to error
2628  *
2629  * INTERNAL - Compare two typed literals
2630  *
2631  * flag bits affects equality:
2632  *   RASQAL_COMPARE_XQUERY: use value equality
2633  *   RASQAL_COMPARE_RDF: use RDF term equality
2634  *
2635  * Return value: non-0 if equal
2636  */
2637 static int
rasqal_literal_string_equals_flags(rasqal_literal * l1,rasqal_literal * l2,int flags,int * error_p)2638 rasqal_literal_string_equals_flags(rasqal_literal* l1, rasqal_literal* l2,
2639                                    int flags, int* error_p)
2640 {
2641   int result = 1;
2642   raptor_uri* dt1;
2643   int free_dt1 = 0;
2644   raptor_uri* dt2;
2645   int free_dt2 = 0;
2646   raptor_uri* xsd_string_uri;
2647 
2648   if(error_p)
2649     *error_p = 0;
2650 
2651   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, 0);
2652   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l2, rasqal_literal, 0);
2653 
2654   dt1 = l1->datatype;
2655   dt2 = l2->datatype;
2656 
2657   xsd_string_uri = rasqal_xsd_datatype_type_to_uri(l1->world,
2658                                                    RASQAL_LITERAL_XSD_STRING);
2659 
2660   if(rasqal_literal_string_languages_compare(l1, l2))
2661     return 0;
2662 
2663   /* For a value comparison (or RDQL), promote plain literal to typed
2664    * literal "xx"^^xsd:string if the other literal is typed
2665    */
2666   if(flags & RASQAL_COMPARE_XQUERY || flags & RASQAL_COMPARE_URI) {
2667     if(l1->type == RASQAL_LITERAL_STRING &&
2668        l2->type == RASQAL_LITERAL_XSD_STRING) {
2669       dt1 = raptor_uri_copy(xsd_string_uri);
2670       free_dt1 = 1;
2671     } else if(l1->type == RASQAL_LITERAL_XSD_STRING &&
2672               l2->type == RASQAL_LITERAL_STRING) {
2673       dt2 = raptor_uri_copy(xsd_string_uri);
2674       free_dt2 = 1;
2675     }
2676   }
2677 
2678   if(dt1 || dt2) {
2679     /* if either is NULL - type error */
2680     if(!dt1 || !dt2) {
2681       if(error_p)
2682         *error_p = 1;
2683       result = 0;
2684       goto done;
2685     }
2686     /* if different - type error */
2687     if(!raptor_uri_equals(dt1, dt2)) {
2688       if(error_p)
2689         *error_p = 1;
2690       result = 0;
2691       goto done;
2692     }
2693     /* at this point the datatypes (URIs) are the same */
2694   }
2695 
2696   /* Finally check the lexical forms */
2697 
2698   /* not-equal if lengths are different - cheaper to try this first */
2699   if(l1->string_len != l2->string_len) {
2700     result = 0;
2701     goto done;
2702   }
2703 
2704   result = !strcmp(RASQAL_GOOD_CAST(const char*, l1->string),
2705                    RASQAL_GOOD_CAST(const char*, l2->string));
2706 
2707   /* If result is equality but literals were both typed literals with
2708    * user-defined types then cause a type error; equality is unknown.
2709    */
2710   if(!result &&
2711      (l1->type == RASQAL_LITERAL_UDT && l2->type == RASQAL_LITERAL_UDT)) {
2712     if(error_p)
2713       *error_p = 1;
2714   }
2715 
2716   done:
2717   if(dt1 && free_dt1)
2718     raptor_free_uri(dt1);
2719   if(dt2 && free_dt2)
2720     raptor_free_uri(dt2);
2721 
2722   return result;
2723 }
2724 
2725 
2726 static int
rasqal_literal_uri_equals(rasqal_literal * l1,rasqal_literal * l2)2727 rasqal_literal_uri_equals(rasqal_literal* l1, rasqal_literal* l2)
2728 {
2729   return raptor_uri_equals(l1->value.uri, l2->value.uri);
2730 }
2731 
2732 
2733 static int
rasqal_literal_blank_equals(rasqal_literal * l1,rasqal_literal * l2)2734 rasqal_literal_blank_equals(rasqal_literal* l1, rasqal_literal* l2)
2735 {
2736   /* not-equal if lengths are different - cheap to compare this first */
2737   if(l1->string_len != l2->string_len)
2738     return 0;
2739 
2740   return !strcmp(RASQAL_GOOD_CAST(const char*, l1->string),
2741                  RASQAL_GOOD_CAST(const char*, l2->string));
2742 }
2743 
2744 
2745 /**
2746  * rasqal_literal_not_equals_flags:
2747  * @l1: #rasqal_literal literal
2748  * @l2: #rasqal_literal data literal
2749  *
2750  * Check if two literals are not equal with optional type promotion.
2751  *
2752  * Return value: non-0 if not-equal
2753  **/
2754 int
rasqal_literal_not_equals_flags(rasqal_literal * l1,rasqal_literal * l2,int flags,int * error_p)2755 rasqal_literal_not_equals_flags(rasqal_literal* l1, rasqal_literal* l2,
2756                                 int flags, int* error_p)
2757 {
2758   /* rasqal_literal_equals_flags() checks for NULLs */
2759 
2760   return !rasqal_literal_equals_flags(l1, l2, flags, error_p);
2761 }
2762 
2763 
2764 /**
2765  * rasqal_literal_equals:
2766  * @l1: #rasqal_literal literal
2767  * @l2: #rasqal_literal data literal
2768  *
2769  * Compare two literals with no type promotion.
2770  *
2771  * If the l2 data literal value is a boolean, it will match
2772  * the string "true" or "false" in the first literal l1.
2773  *
2774  * Return value: non-0 if equal
2775  **/
2776 int
rasqal_literal_equals(rasqal_literal * l1,rasqal_literal * l2)2777 rasqal_literal_equals(rasqal_literal* l1, rasqal_literal* l2)
2778 {
2779   /* rasqal_literal_equals_flags() checks for NULLs */
2780 
2781   return rasqal_literal_equals_flags(l1, l2, 0, NULL);
2782 }
2783 
2784 
2785 /*
2786  * rasqal_literal_equals_flags:
2787  * @l1: #rasqal_literal literal
2788  * @l2: #rasqal_literal data literal
2789  * @flags: comparison flags
2790  * @error_p: type error
2791  *
2792  * INTERNAL - Compare two literals with optional type promotion.
2793  *
2794  * flag bits affects equality:
2795  *   RASQAL_COMPARE_XQUERY: use XQuery comparison and type promotion rules
2796  *   RASQAL_COMPARE_RDF: use RDF term equality
2797  *
2798  * Return value: non-0 if equal
2799  **/
2800 int
rasqal_literal_equals_flags(rasqal_literal * l1,rasqal_literal * l2,int flags,int * error_p)2801 rasqal_literal_equals_flags(rasqal_literal* l1, rasqal_literal* l2,
2802                             int flags, int* error_p)
2803 {
2804   rasqal_literal_type type;
2805   rasqal_literal* l1_p = NULL;
2806   rasqal_literal* l2_p = NULL;
2807   int result = 0;
2808   int promotion = 0;
2809 
2810   /* NULL literals */
2811   if(!l1 || !l2) {
2812     /* if either is not null, the comparison fails */
2813     return !(l1 || l2);
2814   }
2815 
2816 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2817   RASQAL_DEBUG1(" ");
2818   rasqal_literal_print(l1, stderr);
2819   fputs( " to ", stderr);
2820   rasqal_literal_print(l2, stderr);
2821   fprintf(stderr, " with flags %d\n", flags);
2822 #endif
2823 
2824   if(flags & RASQAL_COMPARE_RDF) {
2825     /* no promotion but compare as RDF terms; like rasqal_literal_as_node() */
2826     rasqal_literal_type type1 = rasqal_literal_get_rdf_term_type(l1);
2827     rasqal_literal_type type2 = rasqal_literal_get_rdf_term_type(l2);
2828 
2829     if(type1 == RASQAL_LITERAL_UNKNOWN || type2 == RASQAL_LITERAL_UNKNOWN ||
2830        type1 != type2)
2831       goto tidy;
2832 
2833     type = type1;
2834   } else if(flags & RASQAL_COMPARE_XQUERY) {
2835     /* SPARQL / XSD promotion rules */
2836 
2837     /* Ensure the values are native */
2838     rasqal_literal_string_to_native(l1, 0);
2839     rasqal_literal_string_to_native(l2, 0);
2840 
2841     if((l1->type == RASQAL_LITERAL_DATE &&
2842         l2->type == RASQAL_LITERAL_DATETIME) ||
2843        (l1->type == RASQAL_LITERAL_DATETIME &&
2844         l2->type == RASQAL_LITERAL_DATE)) {
2845       type = RASQAL_LITERAL_DATETIME;
2846       promotion = 1;
2847     } else if(l1->type != l2->type) {
2848       type = rasqal_literal_promote_numerics(l1, l2, flags);
2849       if(type == RASQAL_LITERAL_UNKNOWN) {
2850         /* Cannot numeric promote - try RDF equality */
2851         rasqal_literal_type type1 = rasqal_literal_get_rdf_term_type(l1);
2852         rasqal_literal_type type2 = rasqal_literal_get_rdf_term_type(l2);
2853 
2854         if(type1 == RASQAL_LITERAL_UNKNOWN || type2 == RASQAL_LITERAL_UNKNOWN ||
2855            type1 != type2)
2856           goto tidy;
2857 
2858         type = type1;
2859       } else
2860         promotion = 1;
2861 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2862       RASQAL_DEBUG4("xquery promoted literals types (%s, %s) to type %s\n",
2863                     rasqal_literal_type_label(l1->type),
2864                     rasqal_literal_type_label(l2->type),
2865                     rasqal_literal_type_label(type));
2866 #endif
2867     } else
2868       type = l1->type;
2869   } else {
2870     /* RDQL rules: compare as values with no promotion */
2871     if(l1->type != l2->type) {
2872       /* booleans can be compared to strings */
2873       if(l2->type == RASQAL_LITERAL_BOOLEAN &&
2874          l1->type == RASQAL_LITERAL_STRING)
2875         result = !strcmp(RASQAL_GOOD_CAST(const char*, l1->string),
2876                          RASQAL_GOOD_CAST(const char*, l2->string));
2877       goto tidy;
2878     }
2879     type = l1->type;
2880   }
2881 
2882   if(promotion) {
2883     l1_p = rasqal_new_literal_from_promotion(l1, type, flags);
2884     if(l1_p)
2885       l2_p = rasqal_new_literal_from_promotion(l2, type, flags);
2886     if(!l1_p || !l2_p) {
2887       result = 1;
2888       goto tidy;
2889     }
2890   } else {
2891     l1_p = l1;
2892     l2_p = l2;
2893   }
2894 
2895   switch(type) {
2896     case RASQAL_LITERAL_URI:
2897       result = rasqal_literal_uri_equals(l1_p, l2_p);
2898       break;
2899 
2900     case RASQAL_LITERAL_STRING:
2901     case RASQAL_LITERAL_XSD_STRING:
2902     case RASQAL_LITERAL_UDT:
2903       result = rasqal_literal_string_equals_flags(l1_p, l2_p, flags, error_p);
2904       break;
2905 
2906     case RASQAL_LITERAL_BLANK:
2907       result = rasqal_literal_blank_equals(l1_p, l2_p);
2908       break;
2909 
2910     case RASQAL_LITERAL_DATE:
2911       result = rasqal_xsd_date_equals(l1_p->value.date, l2_p->value.date,
2912                                       error_p);
2913       break;
2914 
2915     case RASQAL_LITERAL_DATETIME:
2916       result = rasqal_xsd_datetime_equals2(l1_p->value.datetime,
2917                                            l2_p->value.datetime,
2918                                            error_p);
2919       break;
2920 
2921     case RASQAL_LITERAL_INTEGER:
2922     case RASQAL_LITERAL_BOOLEAN:
2923     case RASQAL_LITERAL_INTEGER_SUBTYPE:
2924       result = l1_p->value.integer == l2_p->value.integer;
2925       break;
2926 
2927 
2928     case RASQAL_LITERAL_DOUBLE:
2929     case RASQAL_LITERAL_FLOAT:
2930       result = rasqal_double_approximately_equal(l1_p->value.floating,
2931                                                  l2_p->value.floating);
2932       break;
2933 
2934 
2935     case RASQAL_LITERAL_DECIMAL:
2936       result = rasqal_xsd_decimal_equals(l1_p->value.decimal,
2937                                        l2_p->value.decimal);
2938       break;
2939 
2940     case RASQAL_LITERAL_VARIABLE:
2941       /* both are variables */
2942       result = rasqal_literal_equals(l1_p->value.variable->value,
2943                                      l2_p->value.variable->value);
2944       break;
2945 
2946     case RASQAL_LITERAL_UNKNOWN:
2947     case RASQAL_LITERAL_PATTERN:
2948     case RASQAL_LITERAL_QNAME:
2949     default:
2950       if(error_p)
2951         *error_p = 1;
2952       result = 0; /* keep some compilers happy */
2953   }
2954 
2955   tidy:
2956   if(promotion) {
2957     if(l1_p)
2958       rasqal_free_literal(l1_p);
2959     if(l2_p)
2960       rasqal_free_literal(l2_p);
2961   }
2962 
2963 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
2964   RASQAL_DEBUG2("equals result %d\n", result);
2965 #endif
2966 
2967   return result;
2968 }
2969 
2970 
2971 /*
2972  * rasqal_literal_expand_qname:
2973  * @user_data: #rasqal_query cast as void for use with raptor_sequence_foreach
2974  * @l: #rasqal_literal literal
2975  *
2976  * INTERNAL - Expand any qname in a literal into a URI
2977  *
2978  * Expands any QName inside the literal using prefixes that are
2979  * declared in the query that may not have been present when the
2980  * literal was first declared.  Intended to be used standalone
2981  * as well as with raptor_sequence_foreach which takes a function
2982  * signature that this function matches.
2983  *
2984  * Return value: non-0 on failure
2985  **/
2986 int
rasqal_literal_expand_qname(void * user_data,rasqal_literal * l)2987 rasqal_literal_expand_qname(void *user_data, rasqal_literal *l)
2988 {
2989   rasqal_query *rq = (rasqal_query *)user_data;
2990 
2991   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, 1);
2992 
2993   if(l->type == RASQAL_LITERAL_QNAME) {
2994     raptor_uri *uri;
2995 
2996     /* expand a literal qname */
2997     uri = raptor_qname_string_to_uri(rq->namespaces,
2998                                      l->string, l->string_len);
2999     if(!uri)
3000       return 1;
3001     RASQAL_FREE(char*, l->string);
3002     l->string = NULL;
3003     l->type = RASQAL_LITERAL_URI;
3004     l->value.uri = uri;
3005   } else if (l->type == RASQAL_LITERAL_STRING) {
3006     raptor_uri *uri;
3007 
3008     if(l->flags) {
3009       /* expand a literal string datatype qname */
3010       uri = raptor_qname_string_to_uri(rq->namespaces,
3011                                        l->flags,
3012                                        strlen(RASQAL_GOOD_CAST(const char*, l->flags)));
3013       if(!uri)
3014         return 1;
3015       l->datatype = uri;
3016       RASQAL_FREE(char*, l->flags);
3017       l->flags = NULL;
3018 
3019       if(l->language && uri) {
3020         RASQAL_FREE(char*, l->language);
3021         l->language = NULL;
3022       }
3023 
3024       if(rasqal_literal_string_to_native(l, 0)) {
3025         rasqal_free_literal(l);
3026         return 1;
3027       }
3028     }
3029   }
3030   return 0;
3031 }
3032 
3033 
3034 /*
3035  * rasqal_literal_has_qname
3036  * @l: #rasqal_literal literal
3037  *
3038  * INTERNAL - Check if literal has a qname part
3039  *
3040  * Checks if any part ofthe literal has an unexpanded QName.
3041  *
3042  * Return value: non-0 if a QName is present
3043  **/
3044 int
rasqal_literal_has_qname(rasqal_literal * l)3045 rasqal_literal_has_qname(rasqal_literal *l)
3046 {
3047   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, 0);
3048 
3049   return (l->type == RASQAL_LITERAL_QNAME) ||
3050          (l->type == RASQAL_LITERAL_STRING && (l->flags));
3051 }
3052 
3053 
3054 /**
3055  * rasqal_literal_as_node:
3056  * @l: #rasqal_literal object
3057  *
3058  * Turn a literal into a new RDF string, URI or blank literal.
3059  *
3060  * Return value: the new #rasqal_literal or NULL on failure or if the literal was an unbound variable.
3061  **/
3062 rasqal_literal*
rasqal_literal_as_node(rasqal_literal * l)3063 rasqal_literal_as_node(rasqal_literal* l)
3064 {
3065   raptor_uri* dt_uri;
3066   rasqal_literal* new_l = NULL;
3067 
3068   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
3069 
3070   reswitch:
3071   switch(l->type) {
3072     case RASQAL_LITERAL_URI:
3073     case RASQAL_LITERAL_STRING:
3074     case RASQAL_LITERAL_BLANK:
3075       new_l = rasqal_new_literal_from_literal(l);
3076       break;
3077 
3078     case RASQAL_LITERAL_VARIABLE:
3079       l = l->value.variable->value;
3080       if(!l)
3081         return NULL;
3082       goto reswitch;
3083 
3084     case RASQAL_LITERAL_DOUBLE:
3085     case RASQAL_LITERAL_FLOAT:
3086     case RASQAL_LITERAL_INTEGER:
3087     case RASQAL_LITERAL_XSD_STRING:
3088     case RASQAL_LITERAL_BOOLEAN:
3089     case RASQAL_LITERAL_DECIMAL:
3090     case RASQAL_LITERAL_DATE:
3091     case RASQAL_LITERAL_DATETIME:
3092     case RASQAL_LITERAL_UDT:
3093     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3094       new_l = RASQAL_CALLOC(rasqal_literal*, 1, sizeof(*new_l));
3095       if(new_l) {
3096         new_l->valid = 1;
3097         new_l->usage = 1;
3098         new_l->world = l->world;
3099         new_l->type = RASQAL_LITERAL_STRING;
3100         new_l->string_len = l->string_len;
3101         new_l->string = RASQAL_MALLOC(unsigned char*, l->string_len + 1);
3102         if(!new_l->string) {
3103           rasqal_free_literal(new_l);
3104           return NULL;
3105         }
3106         memcpy((void*)new_l->string, l->string, l->string_len + 1);
3107 
3108         if(l->type <= RASQAL_LITERAL_LAST_XSD) {
3109           dt_uri = rasqal_xsd_datatype_type_to_uri(l->world, l->type);
3110           if(!dt_uri) {
3111             rasqal_free_literal(new_l);
3112             return NULL;
3113           }
3114         } else {
3115           /* from the case: above this is UDT and INTEGER_SUBTYPE */
3116           dt_uri = l->datatype;
3117         }
3118         new_l->datatype = raptor_uri_copy(dt_uri);
3119         new_l->flags = NULL;
3120       }
3121       break;
3122 
3123     case RASQAL_LITERAL_QNAME:
3124       /* QNames should be gone by the time expression eval happens */
3125 
3126     case RASQAL_LITERAL_PATTERN:
3127       /* FALLTHROUGH */
3128 
3129     case RASQAL_LITERAL_UNKNOWN:
3130     default:
3131       RASQAL_FATAL2("Literal type %u has no node value", l->type);
3132   }
3133 
3134   return new_l;
3135 }
3136 
3137 
3138 /*
3139  * rasqal_literal_ebv:
3140  * @l: #rasqal_literal literal
3141  *
3142  * INTERNAL -  Get the rasqal_literal effective boolean value
3143  *
3144  * Return value: non-0 if EBV is true, else false
3145  **/
3146 int
rasqal_literal_ebv(rasqal_literal * l)3147 rasqal_literal_ebv(rasqal_literal* l)
3148 {
3149   rasqal_variable* v;
3150   /* Result is true unless... */
3151   int b = 1;
3152 
3153   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, 0);
3154 
3155   v = rasqal_literal_as_variable(l);
3156   if(v) {
3157     if(v->value == NULL) {
3158       /* ... The operand is unbound */
3159       b = 0;
3160       goto done;
3161     }
3162     l = v->value;
3163   }
3164 
3165   if(l->type == RASQAL_LITERAL_BOOLEAN && !l->value.integer) {
3166     /* ... The operand is an xs:boolean with a FALSE value. */
3167     b = 0;
3168   } else if(l->type == RASQAL_LITERAL_STRING &&
3169             !l->datatype && !l->string_len) {
3170     /* ... The operand is a 0-length untyped RDF literal or xs:string. */
3171     b = 0;
3172   } else if(((l->type == RASQAL_LITERAL_INTEGER || l->type == RASQAL_LITERAL_INTEGER_SUBTYPE) && !l->value.integer) ||
3173             ((l->type == RASQAL_LITERAL_DOUBLE ||
3174               l->type == RASQAL_LITERAL_FLOAT) &&
3175              !RASQAL_FLOATING_AS_INT(l->value.floating))
3176             ) {
3177     /* ... The operand is any numeric type with a value of 0. */
3178     b = 0;
3179   } else if(l->type == RASQAL_LITERAL_DECIMAL &&
3180             rasqal_xsd_decimal_is_zero(l->value.decimal)) {
3181     /* ... The operand is any numeric type with a value of 0 (decimal) */
3182     b = 0;
3183   } else if((l->type == RASQAL_LITERAL_DOUBLE ||
3184              l->type == RASQAL_LITERAL_FLOAT) &&
3185             isnan(l->value.floating)
3186             ) {
3187     /* ... The operand is an xs:double or xs:float with a value of NaN */
3188     b = 0;
3189   }
3190 
3191   done:
3192   return b;
3193 }
3194 
3195 
3196 /*
3197  * rasqal_literal_is_constant:
3198  * @l: #rasqal_literal literal
3199  *
3200  * INTERNAL - Check if a literal is a constant
3201  *
3202  * Return value: non-0 if literal is a constant
3203  **/
3204 int
rasqal_literal_is_constant(rasqal_literal * l)3205 rasqal_literal_is_constant(rasqal_literal* l)
3206 {
3207   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, 0);
3208 
3209   switch(l->type) {
3210     case RASQAL_LITERAL_URI:
3211     case RASQAL_LITERAL_BLANK:
3212     case RASQAL_LITERAL_STRING:
3213     case RASQAL_LITERAL_PATTERN:
3214     case RASQAL_LITERAL_QNAME:
3215     case RASQAL_LITERAL_INTEGER:
3216     case RASQAL_LITERAL_XSD_STRING:
3217     case RASQAL_LITERAL_BOOLEAN:
3218     case RASQAL_LITERAL_DOUBLE:
3219     case RASQAL_LITERAL_FLOAT:
3220     case RASQAL_LITERAL_DECIMAL:
3221     case RASQAL_LITERAL_DATE:
3222     case RASQAL_LITERAL_DATETIME:
3223     case RASQAL_LITERAL_UDT:
3224     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3225       return 1;
3226 
3227     case RASQAL_LITERAL_VARIABLE:
3228       return 0;
3229 
3230     case RASQAL_LITERAL_UNKNOWN:
3231     default:
3232       RASQAL_FATAL2("Literal type %u cannot be checked for constant", l->type);
3233       return 0; /* keep some compilers happy */
3234   }
3235 }
3236 
3237 
3238 /**
3239  * rasqal_literal_datatype:
3240  * @l: #rasqal_literal object
3241  *
3242  * Get the datatype URI of a literal
3243  *
3244  * Return value: shared pointer to #raptor_uri of datatype or NULL on failure or no value
3245  */
3246 raptor_uri*
rasqal_literal_datatype(rasqal_literal * l)3247 rasqal_literal_datatype(rasqal_literal* l)
3248 {
3249   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
3250 
3251   if(l->type != RASQAL_LITERAL_VARIABLE)
3252     return l->datatype;
3253   return rasqal_literal_datatype(l->value.variable->value);
3254 }
3255 
3256 
3257 rasqal_literal*
rasqal_literal_cast(rasqal_literal * l,raptor_uri * to_datatype,int flags,int * error_p)3258 rasqal_literal_cast(rasqal_literal* l, raptor_uri* to_datatype, int flags,
3259                     int* error_p)
3260 {
3261 #ifdef RASQAL_DEBUG
3262   raptor_uri* from_datatype = NULL;
3263 #endif
3264   const unsigned char *string = NULL;
3265   unsigned char *new_string;
3266   rasqal_literal* result = NULL;
3267   rasqal_literal_type from_native_type;
3268   rasqal_literal_type to_native_type;
3269   size_t len;
3270 
3271   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
3272 
3273   l = rasqal_literal_value(l);
3274   if(!l)
3275     return NULL;
3276 
3277 #ifdef RASQAL_DEBUG
3278   from_datatype = l->datatype;
3279 #endif
3280   from_native_type = l->type;
3281 
3282   to_native_type = rasqal_xsd_datatype_uri_to_type(l->world, to_datatype);
3283 
3284   if(from_native_type == to_native_type) {
3285     /* cast to same type is always allowed */
3286     return rasqal_new_literal_from_literal(l);
3287 
3288   } else {
3289     int failed = 0;
3290 
3291     /* switch on FROM type to check YES/NO conversions and get the string */
3292     switch(from_native_type) {
3293       /* string */
3294       case RASQAL_LITERAL_STRING:
3295       case RASQAL_LITERAL_XSD_STRING:
3296       case RASQAL_LITERAL_UDT:
3297         string = l->string;
3298         len =  l->string_len;
3299         break;
3300 
3301       /* XSD datatypes: RASQAL_LITERAL_FIRST_XSD to RASQAL_LITERAL_LAST_XSD */
3302       case RASQAL_LITERAL_BOOLEAN:
3303       case RASQAL_LITERAL_INTEGER:
3304       case RASQAL_LITERAL_DOUBLE:
3305       case RASQAL_LITERAL_FLOAT:
3306       case RASQAL_LITERAL_DECIMAL:
3307       case RASQAL_LITERAL_INTEGER_SUBTYPE:
3308         /* XSD (boolean, integer, decimal, double, float) may NOT be
3309          * cast to dateTime or date */
3310         if(to_native_type == RASQAL_LITERAL_DATE ||
3311            to_native_type == RASQAL_LITERAL_DATETIME) {
3312           failed = 1;
3313           if(error_p)
3314             *error_p = 1;
3315           break;
3316         }
3317         string = l->string;
3318         len =  l->string_len;
3319         break;
3320 
3321       case RASQAL_LITERAL_DATE:
3322       case RASQAL_LITERAL_DATETIME:
3323         string = l->string;
3324         len =  l->string_len;
3325         break;
3326 
3327       /* SPARQL casts - FIXME */
3328       case RASQAL_LITERAL_BLANK:
3329       case RASQAL_LITERAL_PATTERN:
3330       case RASQAL_LITERAL_QNAME:
3331         string = l->string;
3332         len =  l->string_len;
3333         break;
3334 
3335       case RASQAL_LITERAL_URI:
3336         /* URI (IRI) May ONLY be cast to an xsd:string */
3337         if(to_native_type != RASQAL_LITERAL_XSD_STRING) {
3338           failed = 1;
3339           if(error_p)
3340             *error_p = 1;
3341           break;
3342         }
3343 
3344         string = raptor_uri_as_counted_string(l->value.uri, &len);
3345         if(!string) {
3346           failed = 1;
3347           if(error_p)
3348             *error_p = 1;
3349         }
3350         break;
3351 
3352       case RASQAL_LITERAL_VARIABLE:
3353         /* fallthrough since rasqal_literal_value() handled this above */
3354       case RASQAL_LITERAL_UNKNOWN:
3355       default:
3356         RASQAL_FATAL2("Literal type %u cannot be cast", l->type);
3357         failed = 1;
3358         return NULL; /* keep some compilers happy */
3359     }
3360 
3361     if(to_native_type == RASQAL_LITERAL_DATE ||
3362        to_native_type == RASQAL_LITERAL_DATETIME) {
3363       /* XSD date and dateTime may ONLY be cast from string (cast
3364        * from dateTime is checked above)
3365        */
3366       if(from_native_type != RASQAL_LITERAL_STRING) {
3367         failed = 1;
3368         if(error_p)
3369           *error_p = 1;
3370       }
3371     }
3372 
3373     if(failed)
3374       return NULL;
3375   }
3376 
3377 
3378   /* switch on the TO type to check MAYBE conversions */
3379 
3380   RASQAL_DEBUG4("CAST from \"%s\" type %s to type %s\n",
3381                 string,
3382                 from_datatype ? RASQAL_GOOD_CAST(const char*, raptor_uri_as_string(from_datatype)) : "(NONE)",
3383                 raptor_uri_as_string(to_datatype));
3384 
3385   if(!rasqal_xsd_datatype_check(to_native_type, string, flags)) {
3386     if(error_p)
3387       *error_p = 1;
3388     RASQAL_DEBUG3("Illegal cast to type %s string '%s'",
3389                   rasqal_xsd_datatype_label(to_native_type), string);
3390     return NULL;
3391   }
3392 
3393   new_string = RASQAL_MALLOC(unsigned char*, len + 1);
3394   if(!new_string) {
3395     if(error_p)
3396       *error_p = 1;
3397     return NULL;
3398   }
3399   memcpy(new_string, string, len + 1);
3400   to_datatype = raptor_uri_copy(to_datatype);
3401 
3402   result = rasqal_new_string_literal(l->world, new_string, NULL,
3403                                      to_datatype, NULL);
3404   if(!result) {
3405     if(error_p)
3406       *error_p = 1;
3407   }
3408   return result;
3409 }
3410 
3411 
3412 /**
3413  * rasqal_literal_value:
3414  * @l: #rasqal_literal object
3415  *
3416  * Get the literal value looking up any variables needed
3417  *
3418  * Return value: literal value or NULL if has no value
3419  */
3420 rasqal_literal*
rasqal_literal_value(rasqal_literal * l)3421 rasqal_literal_value(rasqal_literal* l)
3422 {
3423   if(!l)
3424     return NULL;
3425 
3426   while(l && l->type == RASQAL_LITERAL_VARIABLE) {
3427     l = l->value.variable->value;
3428   }
3429 
3430   return l;
3431 }
3432 
3433 
3434 int
rasqal_literal_is_numeric(rasqal_literal * literal)3435 rasqal_literal_is_numeric(rasqal_literal* literal)
3436 {
3437   rasqal_literal_type parent_type;
3438 
3439   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(literal, rasqal_literal, 0);
3440 
3441   parent_type = rasqal_xsd_datatype_parent_type(literal->type);
3442 
3443   return (rasqal_xsd_datatype_is_numeric(literal->type) ||
3444           rasqal_xsd_datatype_is_numeric(parent_type));
3445 }
3446 
3447 
3448 rasqal_literal*
rasqal_literal_add(rasqal_literal * l1,rasqal_literal * l2,int * error_p)3449 rasqal_literal_add(rasqal_literal* l1, rasqal_literal* l2, int *error_p)
3450 {
3451   int i;
3452   double d;
3453   rasqal_xsd_decimal* dec;
3454   int error = 0;
3455   rasqal_literal_type type;
3456   rasqal_literal* l1_p = NULL;
3457   rasqal_literal* l2_p = NULL;
3458   int flags = 0;
3459   rasqal_literal* result = NULL;
3460 
3461   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, NULL);
3462   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l2, rasqal_literal, NULL);
3463 
3464   type = rasqal_literal_promote_numerics(l1, l2, flags);
3465   switch(type) {
3466     case RASQAL_LITERAL_INTEGER:
3467     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3468       i = rasqal_literal_as_integer(l1, &error);
3469       if(error)
3470         break;
3471       i = i + rasqal_literal_as_integer(l2, &error);
3472       if(error)
3473         break;
3474 
3475       result = rasqal_new_integer_literal(l1->world, RASQAL_LITERAL_INTEGER, i);
3476       break;
3477 
3478     case RASQAL_LITERAL_FLOAT:
3479     case RASQAL_LITERAL_DOUBLE:
3480       d = rasqal_literal_as_double(l1, &error);
3481       if(error)
3482         break;
3483       d = d + rasqal_literal_as_double(l2, &error);
3484       if(error)
3485         break;
3486 
3487       result = rasqal_new_numeric_literal(l1->world, type, d);
3488       break;
3489 
3490     case RASQAL_LITERAL_DECIMAL:
3491       l1_p = rasqal_new_literal_from_promotion(l1, type, flags);
3492       if(l1_p)
3493         l2_p = rasqal_new_literal_from_promotion(l2, type, flags);
3494       if(l1_p && l2_p) {
3495         dec = rasqal_new_xsd_decimal(l1->world);
3496         if(rasqal_xsd_decimal_add(dec, l1_p->value.decimal,
3497                                   l2_p->value.decimal)) {
3498           error = 1;
3499           rasqal_free_xsd_decimal(dec);
3500         } else
3501           result = rasqal_new_decimal_literal_from_decimal(l1->world, NULL, dec);
3502       }
3503       break;
3504 
3505     case RASQAL_LITERAL_UNKNOWN:
3506     case RASQAL_LITERAL_BLANK:
3507     case RASQAL_LITERAL_URI:
3508     case RASQAL_LITERAL_STRING:
3509     case RASQAL_LITERAL_XSD_STRING:
3510     case RASQAL_LITERAL_BOOLEAN:
3511     case RASQAL_LITERAL_DATE:
3512     case RASQAL_LITERAL_DATETIME:
3513     case RASQAL_LITERAL_PATTERN:
3514     case RASQAL_LITERAL_QNAME:
3515     case RASQAL_LITERAL_VARIABLE:
3516     case RASQAL_LITERAL_UDT:
3517     default:
3518       error = 1;
3519       break;
3520   }
3521 
3522   if(error) {
3523     if(error_p)
3524       *error_p = 1;
3525   }
3526 
3527   if(l1_p)
3528     rasqal_free_literal(l1_p);
3529   if(l2_p)
3530     rasqal_free_literal(l2_p);
3531 
3532   return result;
3533 }
3534 
3535 
3536 rasqal_literal*
rasqal_literal_subtract(rasqal_literal * l1,rasqal_literal * l2,int * error_p)3537 rasqal_literal_subtract(rasqal_literal* l1, rasqal_literal* l2, int *error_p)
3538 {
3539   int i;
3540   double d;
3541   rasqal_xsd_decimal* dec;
3542   int error = 0;
3543   rasqal_literal_type type;
3544   rasqal_literal* l1_p = NULL;
3545   rasqal_literal* l2_p = NULL;
3546   int flags = 0;
3547   rasqal_literal* result = NULL;
3548 
3549   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, NULL);
3550   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l2, rasqal_literal, NULL);
3551 
3552   type = rasqal_literal_promote_numerics(l1, l2, flags);
3553   switch(type) {
3554     case RASQAL_LITERAL_INTEGER:
3555     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3556       i = rasqal_literal_as_integer(l1, &error);
3557       if(error)
3558         break;
3559       i = i - rasqal_literal_as_integer(l2, &error);
3560       if(error)
3561         break;
3562 
3563       result = rasqal_new_integer_literal(l1->world, RASQAL_LITERAL_INTEGER, i);
3564       break;
3565 
3566     case RASQAL_LITERAL_FLOAT:
3567     case RASQAL_LITERAL_DOUBLE:
3568       d = rasqal_literal_as_double(l1, &error);
3569       if(error)
3570         break;
3571       d = d - rasqal_literal_as_double(l2, &error);
3572       if(error)
3573         break;
3574 
3575       result = rasqal_new_numeric_literal(l1->world, type, d);
3576       break;
3577 
3578     case RASQAL_LITERAL_DECIMAL:
3579       l1_p = rasqal_new_literal_from_promotion(l1, type, flags);
3580       if(l1_p)
3581         l2_p = rasqal_new_literal_from_promotion(l2, type, flags);
3582       if(l1_p && l2_p) {
3583         dec = rasqal_new_xsd_decimal(l1->world);
3584         if(rasqal_xsd_decimal_subtract(dec, l1_p->value.decimal,
3585                                        l2_p->value.decimal)) {
3586           error = 1;
3587           rasqal_free_xsd_decimal(dec);
3588         } else
3589           result = rasqal_new_decimal_literal_from_decimal(l1->world, NULL, dec);
3590       }
3591       break;
3592 
3593     case RASQAL_LITERAL_UNKNOWN:
3594     case RASQAL_LITERAL_BLANK:
3595     case RASQAL_LITERAL_URI:
3596     case RASQAL_LITERAL_STRING:
3597     case RASQAL_LITERAL_XSD_STRING:
3598     case RASQAL_LITERAL_BOOLEAN:
3599     case RASQAL_LITERAL_DATE:
3600     case RASQAL_LITERAL_DATETIME:
3601     case RASQAL_LITERAL_PATTERN:
3602     case RASQAL_LITERAL_QNAME:
3603     case RASQAL_LITERAL_VARIABLE:
3604     case RASQAL_LITERAL_UDT:
3605     default:
3606       error = 1;
3607       break;
3608   }
3609 
3610   if(error) {
3611     if(error_p)
3612       *error_p = 1;
3613   }
3614 
3615   if(l1_p)
3616     rasqal_free_literal(l1_p);
3617   if(l2_p)
3618     rasqal_free_literal(l2_p);
3619 
3620   return result;
3621 }
3622 
3623 
3624 rasqal_literal*
rasqal_literal_multiply(rasqal_literal * l1,rasqal_literal * l2,int * error_p)3625 rasqal_literal_multiply(rasqal_literal* l1, rasqal_literal* l2, int *error_p)
3626 {
3627   int i;
3628   double d;
3629   rasqal_xsd_decimal* dec;
3630   int error = 0;
3631   rasqal_literal_type type;
3632   rasqal_literal* l1_p = NULL;
3633   rasqal_literal* l2_p = NULL;
3634   int flags = 0;
3635   rasqal_literal* result = NULL;
3636 
3637   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, NULL);
3638   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l2, rasqal_literal, NULL);
3639 
3640   type = rasqal_literal_promote_numerics(l1, l2, flags);
3641   switch(type) {
3642     case RASQAL_LITERAL_INTEGER:
3643     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3644       i = rasqal_literal_as_integer(l1, &error);
3645       if(error)
3646         break;
3647       i = i * rasqal_literal_as_integer(l2, &error);
3648       if(error)
3649         break;
3650 
3651       result = rasqal_new_integer_literal(l1->world, RASQAL_LITERAL_INTEGER, i);
3652       break;
3653 
3654     case RASQAL_LITERAL_FLOAT:
3655     case RASQAL_LITERAL_DOUBLE:
3656       d = rasqal_literal_as_double(l1, &error);
3657       if(error)
3658         break;
3659       d = d * rasqal_literal_as_double(l2, &error);
3660       if(error)
3661         break;
3662 
3663       result = rasqal_new_numeric_literal(l1->world, type, d);
3664       break;
3665 
3666     case RASQAL_LITERAL_DECIMAL:
3667       l1_p = rasqal_new_literal_from_promotion(l1, type, flags);
3668       if(l1_p)
3669         l2_p = rasqal_new_literal_from_promotion(l2, type, flags);
3670       if(l1_p && l2_p) {
3671         dec = rasqal_new_xsd_decimal(l1->world);
3672         if(rasqal_xsd_decimal_multiply(dec, l1_p->value.decimal,
3673                                        l2_p->value.decimal)) {
3674           error = 1;
3675           rasqal_free_xsd_decimal(dec);
3676         } else
3677           result = rasqal_new_decimal_literal_from_decimal(l1->world, NULL, dec);
3678       }
3679       break;
3680 
3681     case RASQAL_LITERAL_UNKNOWN:
3682     case RASQAL_LITERAL_BLANK:
3683     case RASQAL_LITERAL_URI:
3684     case RASQAL_LITERAL_STRING:
3685     case RASQAL_LITERAL_XSD_STRING:
3686     case RASQAL_LITERAL_BOOLEAN:
3687     case RASQAL_LITERAL_DATE:
3688     case RASQAL_LITERAL_DATETIME:
3689     case RASQAL_LITERAL_PATTERN:
3690     case RASQAL_LITERAL_QNAME:
3691     case RASQAL_LITERAL_VARIABLE:
3692     case RASQAL_LITERAL_UDT:
3693     default:
3694       error = 1;
3695       break;
3696   }
3697 
3698   if(error) {
3699     if(error_p)
3700       *error_p = 1;
3701   }
3702 
3703   if(l1_p)
3704     rasqal_free_literal(l1_p);
3705   if(l2_p)
3706     rasqal_free_literal(l2_p);
3707 
3708   return result;
3709 }
3710 
3711 
3712 rasqal_literal*
rasqal_literal_divide(rasqal_literal * l1,rasqal_literal * l2,int * error_p)3713 rasqal_literal_divide(rasqal_literal* l1, rasqal_literal* l2, int *error_p)
3714 {
3715   double d1, d2;
3716   rasqal_xsd_decimal* dec;
3717   int error = 0;
3718   rasqal_literal_type type;
3719   rasqal_literal* l1_p = NULL;
3720   rasqal_literal* l2_p = NULL;
3721   int flags = 0;
3722   rasqal_literal* result = NULL;
3723 
3724   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, NULL);
3725   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l2, rasqal_literal, NULL);
3726 
3727   type = rasqal_literal_promote_numerics(l1, l2, flags);
3728   switch(type) {
3729     case RASQAL_LITERAL_FLOAT:
3730     case RASQAL_LITERAL_DOUBLE:
3731       d2 = rasqal_literal_as_double(l2, &error);
3732       if(!RASQAL_FLOATING_AS_INT(d2))
3733         /* division by zero error */
3734         error = 1;
3735       if(error)
3736         break;
3737       d1 = rasqal_literal_as_double(l1, &error);
3738       if(error)
3739         break;
3740       d1 = d1 / d2;
3741 
3742       result = rasqal_new_numeric_literal(l1->world, type, d1);
3743       break;
3744 
3745     case RASQAL_LITERAL_INTEGER:
3746     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3747       /* "As a special case, if the types of both $arg1 and $arg2 are
3748        * xs:integer, then the return type is xs:decimal." - F&O
3749        */
3750       type = RASQAL_LITERAL_DECIMAL;
3751       /* fallthrough */
3752 
3753     case RASQAL_LITERAL_DECIMAL:
3754       l1_p = rasqal_new_literal_from_promotion(l1, type, flags);
3755       if(l1_p)
3756         l2_p = rasqal_new_literal_from_promotion(l2, type, flags);
3757       if(l1_p && l2_p) {
3758         dec = rasqal_new_xsd_decimal(l1->world);
3759         if(rasqal_xsd_decimal_divide(dec, l1_p->value.decimal,
3760                                      l2_p->value.decimal)) {
3761           error = 1;
3762           rasqal_free_xsd_decimal(dec);
3763         } else
3764           result = rasqal_new_decimal_literal_from_decimal(l1->world, NULL, dec);
3765       }
3766       break;
3767 
3768     case RASQAL_LITERAL_UNKNOWN:
3769     case RASQAL_LITERAL_BLANK:
3770     case RASQAL_LITERAL_URI:
3771     case RASQAL_LITERAL_STRING:
3772     case RASQAL_LITERAL_XSD_STRING:
3773     case RASQAL_LITERAL_BOOLEAN:
3774     case RASQAL_LITERAL_DATE:
3775     case RASQAL_LITERAL_DATETIME:
3776     case RASQAL_LITERAL_PATTERN:
3777     case RASQAL_LITERAL_QNAME:
3778     case RASQAL_LITERAL_VARIABLE:
3779     case RASQAL_LITERAL_UDT:
3780     default:
3781       error = 1;
3782       break;
3783   }
3784 
3785   if(error) {
3786     if(error_p)
3787       *error_p = 1;
3788   }
3789 
3790   if(l1_p)
3791     rasqal_free_literal(l1_p);
3792   if(l2_p)
3793     rasqal_free_literal(l2_p);
3794 
3795   return result;
3796 }
3797 
3798 
3799 rasqal_literal*
rasqal_literal_negate(rasqal_literal * l,int * error_p)3800 rasqal_literal_negate(rasqal_literal* l, int *error_p)
3801 {
3802   int i;
3803   double d;
3804   rasqal_xsd_decimal* dec;
3805   int error = 0;
3806   rasqal_literal* result = NULL;
3807 
3808   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
3809 
3810   switch(l->type) {
3811     case RASQAL_LITERAL_INTEGER:
3812     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3813       i = rasqal_literal_as_integer(l, &error);
3814       if(error)
3815         break;
3816       i = -i;
3817       result = rasqal_new_integer_literal(l->world, RASQAL_LITERAL_INTEGER, i);
3818       break;
3819 
3820     case RASQAL_LITERAL_FLOAT:
3821     case RASQAL_LITERAL_DOUBLE:
3822       d = rasqal_literal_as_double(l, &error);
3823       if(!RASQAL_FLOATING_AS_INT(d))
3824         error = 1;
3825       d = -d;
3826       result = rasqal_new_numeric_literal(l->world, l->type, d);
3827       break;
3828 
3829     case RASQAL_LITERAL_DECIMAL:
3830       dec = rasqal_new_xsd_decimal(l->world);
3831       if(rasqal_xsd_decimal_negate(dec, l->value.decimal)) {
3832         error = 1;
3833         rasqal_free_xsd_decimal(dec);
3834       } else
3835         result = rasqal_new_decimal_literal_from_decimal(l->world, NULL, dec);
3836       break;
3837 
3838     case RASQAL_LITERAL_UNKNOWN:
3839     case RASQAL_LITERAL_BLANK:
3840     case RASQAL_LITERAL_URI:
3841     case RASQAL_LITERAL_STRING:
3842     case RASQAL_LITERAL_XSD_STRING:
3843     case RASQAL_LITERAL_BOOLEAN:
3844     case RASQAL_LITERAL_DATE:
3845     case RASQAL_LITERAL_DATETIME:
3846     case RASQAL_LITERAL_PATTERN:
3847     case RASQAL_LITERAL_QNAME:
3848     case RASQAL_LITERAL_VARIABLE:
3849     case RASQAL_LITERAL_UDT:
3850     default:
3851       error = 1;
3852       break;
3853   }
3854 
3855   if(error) {
3856     if(error_p)
3857       *error_p = 1;
3858   }
3859 
3860   return result;
3861 }
3862 
3863 
3864 rasqal_literal*
rasqal_literal_abs(rasqal_literal * l,int * error_p)3865 rasqal_literal_abs(rasqal_literal* l, int *error_p)
3866 {
3867   int i;
3868   double d;
3869   rasqal_xsd_decimal* dec;
3870   int error = 0;
3871   rasqal_literal* result = NULL;
3872 
3873   if(!rasqal_literal_is_numeric(l))
3874     return NULL;
3875 
3876   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
3877 
3878   switch(l->type) {
3879     case RASQAL_LITERAL_INTEGER:
3880     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3881       i = rasqal_literal_as_integer(l, &error);
3882       if(error)
3883         break;
3884 
3885       i = abs(i);
3886       result = rasqal_new_integer_literal(l->world, RASQAL_LITERAL_INTEGER, i);
3887       break;
3888 
3889     case RASQAL_LITERAL_FLOAT:
3890     case RASQAL_LITERAL_DOUBLE:
3891       d = rasqal_literal_as_double(l, &error);
3892       if(!RASQAL_FLOATING_AS_INT(d))
3893         error = 1;
3894 
3895       d = fabs(d);
3896       result = rasqal_new_numeric_literal(l->world, l->type, d);
3897       break;
3898 
3899     case RASQAL_LITERAL_DECIMAL:
3900       dec = rasqal_new_xsd_decimal(l->world);
3901       if(rasqal_xsd_decimal_abs(dec, l->value.decimal)) {
3902         error = 1;
3903         rasqal_free_xsd_decimal(dec);
3904       } else
3905         result = rasqal_new_decimal_literal_from_decimal(l->world, NULL, dec);
3906       break;
3907 
3908     case RASQAL_LITERAL_UNKNOWN:
3909     case RASQAL_LITERAL_BLANK:
3910     case RASQAL_LITERAL_URI:
3911     case RASQAL_LITERAL_STRING:
3912     case RASQAL_LITERAL_XSD_STRING:
3913     case RASQAL_LITERAL_BOOLEAN:
3914     case RASQAL_LITERAL_DATE:
3915     case RASQAL_LITERAL_DATETIME:
3916     case RASQAL_LITERAL_PATTERN:
3917     case RASQAL_LITERAL_QNAME:
3918     case RASQAL_LITERAL_VARIABLE:
3919     case RASQAL_LITERAL_UDT:
3920     default:
3921       error = 1;
3922       break;
3923   }
3924 
3925   if(error) {
3926     if(error_p)
3927       *error_p = 1;
3928   }
3929 
3930   return result;
3931 }
3932 
3933 
3934 rasqal_literal*
rasqal_literal_round(rasqal_literal * l,int * error_p)3935 rasqal_literal_round(rasqal_literal* l, int *error_p)
3936 {
3937   double d;
3938   rasqal_xsd_decimal* dec;
3939   int error = 0;
3940   rasqal_literal* result = NULL;
3941 
3942   if(!rasqal_literal_is_numeric(l))
3943     return NULL;
3944 
3945   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
3946 
3947   switch(l->type) {
3948     case RASQAL_LITERAL_INTEGER:
3949     case RASQAL_LITERAL_INTEGER_SUBTYPE:
3950       /* Result is same as input for integral types */
3951       result = rasqal_new_literal_from_literal(l);
3952       break;
3953 
3954     case RASQAL_LITERAL_FLOAT:
3955     case RASQAL_LITERAL_DOUBLE:
3956       d = rasqal_literal_as_double(l, &error);
3957       if(!RASQAL_FLOATING_AS_INT(d))
3958         error = 1;
3959 
3960       d = round(d);
3961       result = rasqal_new_numeric_literal(l->world, l->type, d);
3962       break;
3963 
3964     case RASQAL_LITERAL_DECIMAL:
3965       dec = rasqal_new_xsd_decimal(l->world);
3966       if(rasqal_xsd_decimal_round(dec, l->value.decimal)) {
3967         error = 1;
3968         rasqal_free_xsd_decimal(dec);
3969       } else
3970         result = rasqal_new_decimal_literal_from_decimal(l->world, NULL, dec);
3971       break;
3972 
3973     case RASQAL_LITERAL_UNKNOWN:
3974     case RASQAL_LITERAL_BLANK:
3975     case RASQAL_LITERAL_URI:
3976     case RASQAL_LITERAL_STRING:
3977     case RASQAL_LITERAL_XSD_STRING:
3978     case RASQAL_LITERAL_BOOLEAN:
3979     case RASQAL_LITERAL_DATE:
3980     case RASQAL_LITERAL_DATETIME:
3981     case RASQAL_LITERAL_PATTERN:
3982     case RASQAL_LITERAL_QNAME:
3983     case RASQAL_LITERAL_VARIABLE:
3984     case RASQAL_LITERAL_UDT:
3985     default:
3986       error = 1;
3987       break;
3988   }
3989 
3990   if(error) {
3991     if(error_p)
3992       *error_p = 1;
3993   }
3994 
3995   return result;
3996 }
3997 
3998 
3999 rasqal_literal*
rasqal_literal_ceil(rasqal_literal * l,int * error_p)4000 rasqal_literal_ceil(rasqal_literal* l, int *error_p)
4001 {
4002   double d;
4003   rasqal_xsd_decimal* dec;
4004   int error = 0;
4005   rasqal_literal* result = NULL;
4006 
4007   if(!rasqal_literal_is_numeric(l))
4008     return NULL;
4009 
4010   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
4011 
4012   switch(l->type) {
4013     case RASQAL_LITERAL_INTEGER:
4014     case RASQAL_LITERAL_INTEGER_SUBTYPE:
4015       /* Result is same as input for integral types */
4016       result = rasqal_new_literal_from_literal(l);
4017       break;
4018 
4019     case RASQAL_LITERAL_FLOAT:
4020     case RASQAL_LITERAL_DOUBLE:
4021       d = rasqal_literal_as_double(l, &error);
4022       if(!RASQAL_FLOATING_AS_INT(d))
4023         error = 1;
4024 
4025       d = ceil(d);
4026       result = rasqal_new_numeric_literal(l->world, l->type, d);
4027       break;
4028 
4029     case RASQAL_LITERAL_DECIMAL:
4030       dec = rasqal_new_xsd_decimal(l->world);
4031       if(rasqal_xsd_decimal_ceil(dec, l->value.decimal)) {
4032         error = 1;
4033         rasqal_free_xsd_decimal(dec);
4034       } else
4035         result = rasqal_new_decimal_literal_from_decimal(l->world, NULL, dec);
4036       break;
4037 
4038     case RASQAL_LITERAL_UNKNOWN:
4039     case RASQAL_LITERAL_BLANK:
4040     case RASQAL_LITERAL_URI:
4041     case RASQAL_LITERAL_STRING:
4042     case RASQAL_LITERAL_XSD_STRING:
4043     case RASQAL_LITERAL_BOOLEAN:
4044     case RASQAL_LITERAL_DATE:
4045     case RASQAL_LITERAL_DATETIME:
4046     case RASQAL_LITERAL_PATTERN:
4047     case RASQAL_LITERAL_QNAME:
4048     case RASQAL_LITERAL_VARIABLE:
4049     case RASQAL_LITERAL_UDT:
4050     default:
4051       error = 1;
4052       break;
4053   }
4054 
4055   if(error) {
4056     if(error_p)
4057       *error_p = 1;
4058   }
4059 
4060   return result;
4061 }
4062 
4063 
4064 rasqal_literal*
rasqal_literal_floor(rasqal_literal * l,int * error_p)4065 rasqal_literal_floor(rasqal_literal* l, int *error_p)
4066 {
4067   double d;
4068   rasqal_xsd_decimal* dec;
4069   int error = 0;
4070   rasqal_literal* result = NULL;
4071 
4072   if(!rasqal_literal_is_numeric(l))
4073     return NULL;
4074 
4075   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, NULL);
4076 
4077   switch(l->type) {
4078     case RASQAL_LITERAL_INTEGER:
4079     case RASQAL_LITERAL_INTEGER_SUBTYPE:
4080       /* Result is same as input for integral types */
4081       result = rasqal_new_literal_from_literal(l);
4082       break;
4083 
4084     case RASQAL_LITERAL_FLOAT:
4085     case RASQAL_LITERAL_DOUBLE:
4086       d = rasqal_literal_as_double(l, &error);
4087       if(!RASQAL_FLOATING_AS_INT(d))
4088         error = 1;
4089 
4090       d = floor(d);
4091       result = rasqal_new_numeric_literal(l->world, l->type, d);
4092       break;
4093 
4094     case RASQAL_LITERAL_DECIMAL:
4095       dec = rasqal_new_xsd_decimal(l->world);
4096       if(rasqal_xsd_decimal_floor(dec, l->value.decimal)) {
4097         error = 1;
4098         rasqal_free_xsd_decimal(dec);
4099       } else
4100         result = rasqal_new_decimal_literal_from_decimal(l->world, NULL, dec);
4101       break;
4102 
4103     case RASQAL_LITERAL_UNKNOWN:
4104     case RASQAL_LITERAL_BLANK:
4105     case RASQAL_LITERAL_URI:
4106     case RASQAL_LITERAL_STRING:
4107     case RASQAL_LITERAL_XSD_STRING:
4108     case RASQAL_LITERAL_BOOLEAN:
4109     case RASQAL_LITERAL_DATE:
4110     case RASQAL_LITERAL_DATETIME:
4111     case RASQAL_LITERAL_PATTERN:
4112     case RASQAL_LITERAL_QNAME:
4113     case RASQAL_LITERAL_VARIABLE:
4114     case RASQAL_LITERAL_UDT:
4115     default:
4116       error = 1;
4117       break;
4118   }
4119 
4120   if(error) {
4121     if(error_p)
4122       *error_p = 1;
4123   }
4124 
4125   return result;
4126 }
4127 
4128 
4129 /**
4130  * rasqal_literal_same_term:
4131  * @l1: #rasqal_literal literal
4132  * @l2: #rasqal_literal data literal
4133  *
4134  * Check if literals are same term (URI, literal, blank)
4135  *
4136  * Return value: non-0 if same
4137  **/
4138 int
rasqal_literal_same_term(rasqal_literal * l1,rasqal_literal * l2)4139 rasqal_literal_same_term(rasqal_literal* l1, rasqal_literal* l2)
4140 {
4141   rasqal_literal_type type1;
4142   rasqal_literal_type type2;
4143 
4144   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l1, rasqal_literal, 0);
4145   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l2, rasqal_literal, 0);
4146 
4147   type1 = rasqal_literal_get_rdf_term_type(l1);
4148   type2 = rasqal_literal_get_rdf_term_type(l2);
4149 
4150   if(type1 != type2)
4151     return 0;
4152 
4153   if(type1 == RASQAL_LITERAL_UNKNOWN)
4154     return 0;
4155 
4156   if(type1 == RASQAL_LITERAL_URI)
4157     return rasqal_literal_uri_equals(l1, l2);
4158 
4159   if(type1 == RASQAL_LITERAL_STRING)
4160     /* value compare */
4161     return rasqal_literal_string_equals_flags(l1, l2, RASQAL_COMPARE_XQUERY,
4162                                               NULL);
4163 
4164   if(type1 == RASQAL_LITERAL_BLANK)
4165     return rasqal_literal_blank_equals(l1, l2);
4166 
4167   return 0;
4168 }
4169 
4170 
4171 /**
4172  * rasqal_literal_is_rdf_literal:
4173  * @l: #rasqal_literal literal
4174  *
4175  * Check if a literal is any RDF term literal - plain or typed literal
4176  *
4177  * Return value: non-0 if the value is an RDF term literal
4178  **/
4179 int
rasqal_literal_is_rdf_literal(rasqal_literal * l)4180 rasqal_literal_is_rdf_literal(rasqal_literal* l)
4181 {
4182   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(l, rasqal_literal, 0);
4183 
4184   return (rasqal_literal_get_rdf_term_type(l) == RASQAL_LITERAL_STRING);
4185 }
4186 
4187 
4188 /**
4189  * rasqal_literal_sequence_compare:
4190  * @compare_flags: comparison flags for rasqal_literal_compare()
4191  * @values_a: first sequence of literals
4192  * @values_b: second sequence of literals
4193  *
4194  * INTERNAL - compare two sequences of literals
4195  *
4196  * Return value: <0, 0 or >1 comparison
4197  */
4198 int
rasqal_literal_sequence_compare(int compare_flags,raptor_sequence * values_a,raptor_sequence * values_b)4199 rasqal_literal_sequence_compare(int compare_flags,
4200                                 raptor_sequence* values_a,
4201                                 raptor_sequence* values_b)
4202 {
4203   int result = 0;
4204   int i;
4205   int size_a = 0;
4206   int size_b = 0;
4207 
4208   /* Turn 0-length sequences into NULL */
4209   if(values_a) {
4210     size_a = raptor_sequence_size(values_a);
4211     if(!size_a)
4212       values_a = NULL;
4213   }
4214 
4215   if(values_b) {
4216     size_b = raptor_sequence_size(values_b);
4217     if(!size_b)
4218       values_b = NULL;
4219   }
4220 
4221   /* Handle empty sequences: equal if both empty, otherwise empty is earlier */
4222   if(!size_a && !size_b)
4223     return 0;
4224   else if(!size_a)
4225     return -1;
4226   else if(!size_b)
4227     return 1;
4228 
4229 
4230   /* Now know they are not 0 length */
4231 
4232   /* Walk maximum length of the values */
4233   if(size_b > size_a)
4234     size_a = size_b;
4235 
4236   for(i = 0; i < size_a; i++) {
4237     rasqal_literal* literal_a = (rasqal_literal*)raptor_sequence_get_at(values_a, i);
4238     rasqal_literal* literal_b = (rasqal_literal*)raptor_sequence_get_at(values_b, i);
4239     int error = 0;
4240 
4241 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4242     RASQAL_DEBUG1("Comparing ");
4243     rasqal_literal_print(literal_a, DEBUG_FH);
4244     fputs(" to ", DEBUG_FH);
4245     rasqal_literal_print(literal_b, DEBUG_FH);
4246     fputs("\n", DEBUG_FH);
4247 #endif
4248 
4249     if(!literal_a || !literal_b) {
4250       if(!literal_a && !literal_b) {
4251         result = 0;
4252       } else {
4253         result = literal_a ? 1 : -1;
4254 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4255         RASQAL_DEBUG2("Got one NULL literal comparison, returning %d\n",
4256                       result);
4257 #endif
4258       }
4259       break;
4260     }
4261 
4262     result = rasqal_literal_compare(literal_a, literal_b,
4263                                     compare_flags, &error);
4264 
4265     if(error) {
4266 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4267       RASQAL_DEBUG2("Got literal comparison error at literal %d, returning 0\n",
4268                     i);
4269 #endif
4270       result = 0;
4271       break;
4272     }
4273 
4274     if(!result)
4275       continue;
4276 
4277 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4278     RASQAL_DEBUG3("Returning comparison result %d at literal %d\n", result, i);
4279 #endif
4280     break;
4281   }
4282 
4283   return result;
4284 }
4285 
4286 
4287 int
rasqal_literal_write_turtle(rasqal_literal * l,raptor_iostream * iostr)4288 rasqal_literal_write_turtle(rasqal_literal* l, raptor_iostream* iostr)
4289 {
4290   const unsigned char* str;
4291   size_t len;
4292   int rc = 0;
4293 
4294   if(!l)
4295     return rc;
4296 
4297   switch(l->type) {
4298     case RASQAL_LITERAL_URI:
4299       str = RASQAL_GOOD_CAST(const unsigned char*, raptor_uri_as_counted_string(l->value.uri, &len));
4300 
4301       raptor_iostream_write_byte('<', iostr);
4302       if(str)
4303         raptor_string_ntriples_write(str, len, '>', iostr);
4304       raptor_iostream_write_byte('>', iostr);
4305       break;
4306 
4307     case RASQAL_LITERAL_BLANK:
4308       raptor_iostream_counted_string_write("_:", 2, iostr);
4309       raptor_iostream_counted_string_write(l->string, l->string_len,
4310                                            iostr);
4311       break;
4312 
4313     case RASQAL_LITERAL_STRING:
4314     case RASQAL_LITERAL_UDT:
4315       raptor_iostream_write_byte('"', iostr);
4316       raptor_string_ntriples_write(l->string, l->string_len, '"', iostr);
4317       raptor_iostream_write_byte('"', iostr);
4318 
4319       if(l->language) {
4320         raptor_iostream_write_byte('@', iostr);
4321         raptor_iostream_string_write(l->language, iostr);
4322       }
4323 
4324       if(l->datatype) {
4325         str = RASQAL_GOOD_CAST(const unsigned char*, raptor_uri_as_counted_string(l->datatype, &len));
4326         raptor_iostream_counted_string_write("^^<", 3, iostr);
4327         raptor_string_ntriples_write(str, len, '>', iostr);
4328         raptor_iostream_write_byte('>', iostr);
4329       }
4330 
4331       break;
4332 
4333     case RASQAL_LITERAL_PATTERN:
4334     case RASQAL_LITERAL_QNAME:
4335     case RASQAL_LITERAL_INTEGER:
4336     case RASQAL_LITERAL_XSD_STRING:
4337     case RASQAL_LITERAL_BOOLEAN:
4338     case RASQAL_LITERAL_DOUBLE:
4339     case RASQAL_LITERAL_FLOAT:
4340     case RASQAL_LITERAL_VARIABLE:
4341     case RASQAL_LITERAL_DECIMAL:
4342     case RASQAL_LITERAL_DATE:
4343     case RASQAL_LITERAL_DATETIME:
4344     case RASQAL_LITERAL_INTEGER_SUBTYPE:
4345 
4346     case RASQAL_LITERAL_UNKNOWN:
4347     default:
4348       rasqal_log_error_simple(l->world, RAPTOR_LOG_LEVEL_ERROR, NULL,
4349                               "Cannot turn literal type %u into Turtle",
4350                               l->type);
4351       rc = 1;
4352   }
4353 
4354   return rc;
4355 }
4356 
4357 
4358 /*
4359  * rasqal_literal_array_compare:
4360  * @values_a: first array of literals
4361  * @values_b: second array of literals
4362  * @exprs_seq: array of expressions (or NULL)
4363  * @size: size of arrays
4364  * @compare_flags: comparison flags for rasqal_literal_compare()
4365  *
4366  * INTERNAL - compare two arrays of literals evaluated in an optional array of expressions
4367  *
4368  * Return value: <0, 0 or >0 comparison
4369  */
4370 int
rasqal_literal_array_compare(rasqal_literal ** values_a,rasqal_literal ** values_b,raptor_sequence * exprs_seq,int size,int compare_flags)4371 rasqal_literal_array_compare(rasqal_literal** values_a,
4372                              rasqal_literal** values_b,
4373                              raptor_sequence* exprs_seq,
4374                              int size,
4375                              int compare_flags)
4376 {
4377   int result = 0;
4378   int i;
4379 
4380   for(i = 0; i < size; i++) {
4381     rasqal_expression* e = NULL;
4382     int error = 0;
4383     rasqal_literal* literal_a = values_a[i];
4384     rasqal_literal* literal_b = values_b[i];
4385 
4386     if(exprs_seq)
4387       e = (rasqal_expression*)raptor_sequence_get_at(exprs_seq, i);
4388 
4389 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4390     RASQAL_DEBUG1("Comparing ");
4391     rasqal_literal_print(literal_a, DEBUG_FH);
4392     fputs(" to ", DEBUG_FH);
4393     rasqal_literal_print(literal_b, DEBUG_FH);
4394     fputs("\n", DEBUG_FH);
4395 #endif
4396 
4397     /* NULLs order first */
4398     if(!literal_a || !literal_b) {
4399       if(!literal_a && !literal_b) {
4400         result = 0;
4401       } else {
4402         result = (!literal_a) ? -1 : 1;
4403 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4404         RASQAL_DEBUG2("Got one NULL literal comparison, returning %d\n", result);
4405 #endif
4406       }
4407       break;
4408     }
4409 
4410     result = rasqal_literal_compare(literal_a, literal_b,
4411                                     compare_flags | RASQAL_COMPARE_URI,
4412                                     &error);
4413     if(error) {
4414 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4415       RASQAL_DEBUG2("Got literal comparison error at expression %d, returning 0\n", i);
4416 #endif
4417       result = 0;
4418       break;
4419     }
4420 
4421     if(!result)
4422       continue;
4423 
4424     if(e && e->op == RASQAL_EXPR_ORDER_COND_DESC)
4425       result = -result;
4426     /* else Order condition is RASQAL_EXPR_ORDER_COND_ASC so nothing to do */
4427 
4428 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4429     RASQAL_DEBUG3("Returning comparison result %d at expression %d\n", result, i);
4430 #endif
4431     break;
4432   }
4433 
4434   return result;
4435 }
4436 
4437 
4438 /*
4439  * rasqal_literal_array_compare_by_order:
4440  * @values_a: first array of literals
4441  * @values_b: second array of literals
4442  * @order: array of order offsets
4443  * @size: size of arrays
4444  * @compare_flags: comparison flags for rasqal_literal_compare()
4445  *
4446  * INTERNAL - compare two arrays of literals evaluated in a given order
4447  *
4448  * Return value: <0, 0 or >0 comparison
4449  */
4450 int
rasqal_literal_array_compare_by_order(rasqal_literal ** values_a,rasqal_literal ** values_b,int * order,int size,int compare_flags)4451 rasqal_literal_array_compare_by_order(rasqal_literal** values_a,
4452                                       rasqal_literal** values_b,
4453                                       int* order,
4454                                       int size,
4455                                       int compare_flags)
4456 {
4457   int result = 0;
4458   int i;
4459 
4460   for(i = 0; i < size; i++) {
4461     int error = 0;
4462     int order_i = order[i];
4463     rasqal_literal* literal_a = values_a[order_i];
4464     rasqal_literal* literal_b = values_b[order_i];
4465 
4466     /* NULLs order first */
4467     if(!literal_a || !literal_b) {
4468       if(!literal_a && !literal_b) {
4469         result = 0;
4470       } else {
4471         result = (!literal_a) ? -1 : 1;
4472       }
4473       break;
4474     }
4475 
4476     result = rasqal_literal_compare(literal_a, literal_b,
4477                                     compare_flags | RASQAL_COMPARE_URI,
4478                                     &error);
4479     if(error) {
4480       result = 0;
4481       break;
4482     }
4483 
4484     if(!result)
4485       continue;
4486     break;
4487   }
4488 
4489   return result;
4490 }
4491 
4492 
4493 /**
4494  * rasqal_literal_array_equals:
4495  * @values_a: first array of literals
4496  * @values_b: second array of literals
4497  * @size: size of arrays
4498  *
4499  * INTERNAL - compare two arrays of literals for equality
4500  *
4501  * Return value: non-0 if equal
4502  */
4503 int
rasqal_literal_array_equals(rasqal_literal ** values_a,rasqal_literal ** values_b,int size)4504 rasqal_literal_array_equals(rasqal_literal** values_a,
4505                             rasqal_literal** values_b,
4506                             int size)
4507 {
4508   int result = 1; /* equal */
4509   int i;
4510   int error = 0;
4511 
4512   for(i = 0; i < size; i++) {
4513     rasqal_literal* literal_a = values_a[i];
4514     rasqal_literal* literal_b = values_b[i];
4515 
4516     result = rasqal_literal_equals_flags(literal_a, literal_b,
4517                                          RASQAL_COMPARE_RDF, &error);
4518 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4519     RASQAL_DEBUG1("Comparing ");
4520     rasqal_literal_print(literal_a, DEBUG_FH);
4521     fputs(" to ", DEBUG_FH);
4522     rasqal_literal_print(literal_b, DEBUG_FH);
4523     fprintf(DEBUG_FH, " gave %s\n", (result ? "equality" : "not equal"));
4524 #endif
4525 
4526     if(error)
4527       result = 0;
4528 
4529     /* if different, end */
4530     if(!result)
4531       break;
4532   }
4533 
4534   return result;
4535 }
4536 
4537 
4538 /**
4539  * rasqal_literal_sequence_equals:
4540  * @values_a: first sequence of literals
4541  * @values_b: second sequence of literals
4542  *
4543  * INTERNAL - compare two arrays of literals for equality
4544  *
4545  * Return value: non-0 if equal
4546  */
4547 int
rasqal_literal_sequence_equals(raptor_sequence * values_a,raptor_sequence * values_b)4548 rasqal_literal_sequence_equals(raptor_sequence* values_a,
4549                                raptor_sequence* values_b)
4550 {
4551   int result = 1; /* equal */
4552   int i;
4553   int error = 0;
4554   int size = raptor_sequence_size(values_a);
4555 
4556   for(i = 0; i < size; i++) {
4557     rasqal_literal* literal_a = (rasqal_literal*)raptor_sequence_get_at(values_a, i);
4558     rasqal_literal* literal_b = (rasqal_literal*)raptor_sequence_get_at(values_b, i);
4559 
4560     result = rasqal_literal_equals_flags(literal_a, literal_b,
4561                                          RASQAL_COMPARE_RDF, &error);
4562 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
4563     RASQAL_DEBUG1("Comparing ");
4564     rasqal_literal_print(literal_a, DEBUG_FH);
4565     fputs(" to ", DEBUG_FH);
4566     rasqal_literal_print(literal_b, DEBUG_FH);
4567     fprintf(DEBUG_FH, " gave %s\n", (result ? "equality" : "not equal"));
4568 #endif
4569 
4570     if(error)
4571       result = 0;
4572 
4573     /* if different, end */
4574     if(!result)
4575       break;
4576   }
4577 
4578   return result;
4579 }
4580 
4581 
4582 typedef struct
4583 {
4584   int is_distinct;
4585   int compare_flags;
4586 } literal_sequence_sort_compare_data;
4587 
4588 
4589 /**
4590  * rasqal_literal_sequence_sort_map_compare:
4591  * @user_data: comparison user data pointer
4592  * @a: pointer to address of first array
4593  * @b: pointer to address of second array
4594  *
4595  * INTERNAL - compare two pointers to array of iterals objects
4596  *
4597  * Suitable for use as a compare function in qsort_r() or similar.
4598  *
4599  * Return value: <0, 0 or >1 comparison
4600  */
4601 static int
rasqal_literal_sequence_sort_map_compare(void * user_data,const void * a,const void * b)4602 rasqal_literal_sequence_sort_map_compare(void* user_data,
4603                                          const void *a,
4604                                          const void *b)
4605 {
4606   raptor_sequence* literal_seq_a;
4607   raptor_sequence* literal_seq_b;
4608   literal_sequence_sort_compare_data* lsscd;
4609   int result = 0;
4610 
4611   lsscd = (literal_sequence_sort_compare_data*)user_data;
4612 
4613   literal_seq_a = (raptor_sequence*)a;
4614   literal_seq_b = (raptor_sequence*)b;
4615 
4616   if(lsscd->is_distinct) {
4617     result = !rasqal_literal_sequence_equals(literal_seq_a, literal_seq_b);
4618     if(!result)
4619       /* duplicate, so return that */
4620       return 0;
4621   }
4622 
4623   /* now order it */
4624   result = rasqal_literal_sequence_compare(lsscd->compare_flags,
4625                                            literal_seq_a, literal_seq_b);
4626 
4627   /* still equal?  make sort stable by using the pointers */
4628   if(!result) {
4629     ptrdiff_t d;
4630 
4631     /* Have to cast raptor_sequence* to something with a known type
4632      * (not void*, not raptor_sequence* whose size is private to
4633      * raptor) so we can do pointer arithmetic.  We only care about
4634      * the relative pointer difference.
4635      */
4636     d = RASQAL_GOOD_CAST(char*, literal_seq_a) - RASQAL_GOOD_CAST(char*, literal_seq_b);
4637 
4638     /* copy the sign of the (unknown size) signed integer 'd' into an
4639      * int result
4640      */
4641     result = (d > 0) - (d < 0);
4642     RASQAL_DEBUG2("Got equality result so using pointers, returning %d\n",
4643                   result);
4644   }
4645 
4646   return result;
4647 }
4648 
4649 
4650 static int
rasqal_literal_sequence_sort_map_print_literal_sequence(void * object,FILE * fh)4651 rasqal_literal_sequence_sort_map_print_literal_sequence(void *object, FILE *fh)
4652 {
4653   if(object)
4654     raptor_sequence_print((raptor_sequence*)object, fh);
4655   else
4656     fputs("NULL", fh);
4657   return 0;
4658 }
4659 
4660 
4661 /**
4662  * rasqal_new_literal_sequence_sort_map:
4663  * @compare_flags: flags for rasqal_literal_compare()
4664  *
4665  * INTERNAL - create a new map for sorting arrays of literals
4666  *
4667  */
4668 rasqal_map*
rasqal_new_literal_sequence_sort_map(int is_distinct,int compare_flags)4669 rasqal_new_literal_sequence_sort_map(int is_distinct, int compare_flags)
4670 {
4671   literal_sequence_sort_compare_data* lsscd;
4672 
4673   lsscd = RASQAL_MALLOC(literal_sequence_sort_compare_data*, sizeof(*lsscd));
4674   if(!lsscd)
4675     return NULL;
4676 
4677   lsscd->is_distinct = is_distinct;
4678   lsscd->compare_flags = compare_flags;
4679 
4680   return rasqal_new_map(rasqal_literal_sequence_sort_map_compare,
4681                         lsscd,
4682                         (raptor_data_free_handler)rasqal_free_memory,
4683                         (raptor_data_free_handler)raptor_free_sequence,
4684                         NULL, /* free_value_fn */
4685                         rasqal_literal_sequence_sort_map_print_literal_sequence,
4686                         NULL,
4687                         0 /* do not allow duplicates */);
4688 }
4689 
4690 
4691 /**
4692  * rasqal_literal_sequence_sort_map_add_literal_sequence:
4693  * @map: literal sort map
4694  * @literals_seq: Sequence of #rasqal_literal to add
4695  *
4696  * INTERNAL - Add a row to an literal sequence sort map for sorting
4697  *
4698  * The literals array @literals_sequence becomes owned by the map.
4699  *
4700  * return value: non-0 if the array of literals was a duplicate (and not added)
4701  */
4702 int
rasqal_literal_sequence_sort_map_add_literal_sequence(rasqal_map * map,raptor_sequence * literals_seq)4703 rasqal_literal_sequence_sort_map_add_literal_sequence(rasqal_map* map,
4704                                                       raptor_sequence *literals_seq)
4705 {
4706   if(!rasqal_map_add_kv(map, literals_seq, NULL))
4707     return 0;
4708 
4709   /* duplicate, and not added so delete it */
4710 #ifdef RASQAL_DEBUG
4711   RASQAL_DEBUG1("Got duplicate array of literals ");
4712   raptor_sequence_print(literals_seq, DEBUG_FH);
4713   fputc('\n', DEBUG_FH);
4714 #endif
4715   raptor_free_sequence(literals_seq);
4716 
4717   return 1;
4718 }
4719 
4720 
4721 /**
4722  * rasqal_new_literal_sequence_of_sequence_from_data:
4723  * @world: world object ot use
4724  * @row_data: row data
4725  *
4726  * INTERNAL - Make a sequence of sequence of #rasqal_literal* literals
4727  *
4728  * The @row_data parameter is an array of strings forming a table of
4729  * width (literals_count * 2).
4730  * The rows are values where offset 0 is a string literal and
4731  * offset 1 is a URI string literal.  If a string literal looks like
4732  * a number (strtol passes), an integer literal is formed.
4733  *
4734  * The end of data is indicated by an entire row of NULLs.
4735  *
4736  * Return value: sequence of rows or NULL on failure
4737  */
4738 raptor_sequence*
rasqal_new_literal_sequence_of_sequence_from_data(rasqal_world * world,const char * const row_data[],int width)4739 rasqal_new_literal_sequence_of_sequence_from_data(rasqal_world* world,
4740                                                   const char* const row_data[],
4741                                                   int width)
4742 {
4743   raptor_sequence *seq = NULL;
4744   int row_i;
4745   int column_i;
4746   int failed = 0;
4747 
4748 #define GET_CELL(row, column, offset) \
4749   row_data[((((row) * width) + (column))<<1) + (offset)]
4750 
4751   seq = raptor_new_sequence((raptor_data_free_handler)raptor_free_sequence,
4752                             (raptor_data_print_handler)raptor_sequence_print);
4753   if(!seq)
4754     return NULL;
4755 
4756   for(row_i = 0; 1; row_i++) {
4757     raptor_sequence* row;
4758     int data_values_seen = 0;
4759 
4760     /* Terminate on an entire row of NULLs */
4761     for(column_i = 0; column_i < width; column_i++) {
4762       if(GET_CELL(row_i, column_i, 0) || GET_CELL(row_i, column_i, 1)) {
4763         data_values_seen++;
4764         break;
4765       }
4766     }
4767     if(!data_values_seen)
4768       break;
4769 
4770     row = raptor_new_sequence((raptor_data_free_handler)rasqal_free_literal,
4771                               (raptor_data_print_handler)rasqal_literal_print);
4772     if(!row) {
4773       raptor_free_sequence(seq); seq = NULL;
4774       goto tidy;
4775     }
4776 
4777     for(column_i = 0; column_i < width; column_i++) {
4778       rasqal_literal* l = NULL;
4779 
4780       if(GET_CELL(row_i, column_i, 0)) {
4781         /* string literal */
4782         const char* str = GET_CELL(row_i, column_i, 0);
4783         size_t str_len = strlen(str);
4784         char *eptr = NULL;
4785         long number;
4786 
4787         number = strtol(RASQAL_GOOD_CAST(const char*, str), &eptr, 10);
4788         if(!*eptr) {
4789           /* is numeric */
4790           l = rasqal_new_numeric_literal_from_long(world,
4791                                                    RASQAL_LITERAL_INTEGER,
4792                                                    number);
4793         } else {
4794           unsigned char *val;
4795           val = RASQAL_MALLOC(unsigned char*, str_len + 1);
4796           if(val) {
4797             memcpy(val, str, str_len + 1);
4798 
4799             l = rasqal_new_string_literal_node(world, val, NULL, NULL);
4800           } else
4801             failed = 1;
4802         }
4803       } else if(GET_CELL(row_i, column_i, 1)) {
4804         /* URI */
4805         const unsigned char* str;
4806         raptor_uri* u;
4807 
4808         str = RASQAL_GOOD_CAST(const unsigned char*, GET_CELL(row_i, column_i, 1));
4809         u = raptor_new_uri(world->raptor_world_ptr, str);
4810 
4811         if(u)
4812           l = rasqal_new_uri_literal(world, u);
4813         else
4814           failed = 1;
4815       } else {
4816         /* variable is not defined for this row */
4817         continue;
4818       }
4819 
4820       if(!l) {
4821         raptor_free_sequence(row);
4822         failed = 1;
4823         goto tidy;
4824       }
4825       raptor_sequence_set_at(row, column_i, l);
4826     }
4827 
4828     raptor_sequence_push(seq, row);
4829   }
4830 
4831   tidy:
4832   if(failed) {
4833     if(seq) {
4834       raptor_free_sequence(seq);
4835       seq = NULL;
4836     }
4837   }
4838 
4839   return seq;
4840 }
4841 
4842 
4843 
4844 /*
4845  * rasqal_new_literal_from_term:
4846  * @world: rasqal world
4847  * @term: term object
4848  *
4849  * INTERNAL - create a new literal from a #raptor_term
4850  *
4851  * Return value: new literal or NULL on failure
4852 */
4853 rasqal_literal*
rasqal_new_literal_from_term(rasqal_world * world,raptor_term * term)4854 rasqal_new_literal_from_term(rasqal_world* world, raptor_term* term)
4855 {
4856   rasqal_literal* l = NULL;
4857   size_t len;
4858   unsigned char* new_str = NULL;
4859 
4860   if(!term)
4861     return NULL;
4862 
4863   if(term->type == RAPTOR_TERM_TYPE_LITERAL) {
4864     char *language = NULL;
4865     raptor_uri* uri = NULL;
4866 
4867     len = term->value.literal.string_len;
4868     new_str = RASQAL_MALLOC(unsigned char*, len + 1);
4869     if(!new_str)
4870       goto fail;
4871 
4872     memcpy(new_str, term->value.literal.string, len + 1);
4873 
4874     if(term->value.literal.language) {
4875       len = term->value.literal.language_len;
4876       language = RASQAL_MALLOC(char*, len + 1);
4877       if(!language)
4878         goto fail;
4879 
4880       memcpy(language, term->value.literal.language, len + 1);
4881     }
4882 
4883     if(term->value.literal.datatype)
4884       uri = raptor_uri_copy(term->value.literal.datatype);
4885 
4886     l = rasqal_new_string_literal(world, new_str, language, uri, NULL);
4887   } else if(term->type == RAPTOR_TERM_TYPE_BLANK) {
4888     len = term->value.blank.string_len;
4889     new_str = RASQAL_MALLOC(unsigned char*, len + 1);
4890     if(!new_str)
4891       goto fail;
4892 
4893     memcpy(new_str, term->value.blank.string, len + 1);
4894     l = rasqal_new_simple_literal(world, RASQAL_LITERAL_BLANK, new_str);
4895   } else if(term->type == RAPTOR_TERM_TYPE_URI) {
4896     raptor_uri* uri;
4897     uri = raptor_uri_copy((raptor_uri*)term->value.uri);
4898     l = rasqal_new_uri_literal(world, uri);
4899   } else
4900     goto fail;
4901 
4902   return l;
4903 
4904   fail:
4905   if(new_str)
4906     RASQAL_FREE(unsigned char*, new_str);
4907 
4908   return NULL;
4909 }
4910 
4911 
4912 #endif /* not STANDALONE */
4913 
4914 
4915 
4916 
4917 #ifdef STANDALONE
4918 #include <stdio.h>
4919 
4920 int main(int argc, char *argv[]);
4921 
4922 /* Test 0 */
4923 static const char* const data_3x3_unique_rows[] =
4924 {
4925   /* 3 literals in 3 rows - all distinct */
4926   /* row 1 data */
4927   "0",  NULL, "1",  NULL, "2", NULL,
4928   /* row 2 data */
4929   "3",  NULL, "4",  NULL, "5", NULL,
4930   /* row 3 data */
4931   "6",  NULL, "7",  NULL, "8", NULL,
4932   /* end of data */
4933   NULL, NULL, NULL, NULL, NULL, NULL,
4934 };
4935 
4936 static const char* const data_3x4_1_duplicate_rows[] =
4937 {
4938   /* 3 literals in 4 rows - with one duplicate */
4939   /* row 1 data */
4940   "0",  NULL, "1",  NULL, "2", NULL,
4941   /* row 2 data */
4942   "3",  NULL, "4",  NULL, "5", NULL,
4943   /* row 3 data */
4944   "0",  NULL, "1",  NULL, "2", NULL,
4945   /* row 4 data */
4946   "6",  NULL, "7",  NULL, "8", NULL,
4947   /* end of data */
4948   NULL, NULL, NULL, NULL, NULL, NULL,
4949 };
4950 
4951 static const char* const data_3x6_2_duplicate_rows[] =
4952 {
4953   /* 3 literals in 6 rows - with one duplicate */
4954   /* row 1 data */
4955   "0",  NULL, "1",  NULL, "2", NULL,
4956   /* row 2 data */
4957   "3",  NULL, "4",  NULL, "5", NULL,
4958   /* row 3 data */
4959   "0",  NULL, "1",  NULL, "2", NULL,
4960   /* row 4 data */
4961   "3",  NULL, "4",  NULL, "5", NULL,
4962   /* row 5 data */
4963   "6",  NULL, "7",  NULL, "8", NULL,
4964   /* row 6 data */
4965   "8",  NULL, "9",  NULL, "0", NULL,
4966   /* end of data */
4967   NULL, NULL, NULL, NULL, NULL, NULL,
4968 };
4969 
4970 
4971 
4972 #define TESTS_COUNT 3
4973 
4974 static const struct {
4975   int width;
4976   int expected_rows;
4977   const char* const *data;
4978 } test_data[TESTS_COUNT] = {
4979   /* Test 0: 3 literals, 3 rows (no duplicates) */
4980   {3, 3, data_3x3_unique_rows },
4981   /* Test 1: 3 literals, 4 rows (1 duplicate) */
4982   {3, 3, data_3x4_1_duplicate_rows },
4983   /* Test 2: 3 literals, 6 rows (2 duplicate2) */
4984   {3, 4, data_3x6_2_duplicate_rows }
4985 };
4986 
4987 
4988 int
main(int argc,char * argv[])4989 main(int argc, char *argv[])
4990 {
4991   const char *program = rasqal_basename(argv[0]);
4992   int failures = 0;
4993   rasqal_world *world;
4994   int test_id;
4995 
4996   world = rasqal_new_world();
4997   if(!world || rasqal_world_open(world)) {
4998     fprintf(stderr, "%s: rasqal_world init failed\n", program);
4999     return(1);
5000   }
5001 
5002   /* test */
5003   fprintf(stderr, "%s: Testing literals\n", program);
5004 
5005   for(test_id = 0; test_id < TESTS_COUNT; test_id++) {
5006     int expected_rows = test_data[test_id].expected_rows;
5007     int width = test_data[test_id].width;
5008     raptor_sequence* seq;
5009     int duplicates;
5010     int count;
5011     int i;
5012     raptor_sequence* seq2;
5013     rasqal_map* map;
5014 
5015     seq = rasqal_new_literal_sequence_of_sequence_from_data(world,
5016                                                             test_data[test_id].data,
5017                                                             width);
5018     if(!seq) {
5019       fprintf(stderr, "%s: failed to create seq of literal seq\n", program);
5020       failures++;
5021       goto tidy;
5022     }
5023 
5024     fprintf(DEBUG_FH, "%s: Test %d data (seq of seq of literals) is: ", program,
5025             test_id);
5026     raptor_sequence_print(seq, DEBUG_FH);
5027     fputc('\n', DEBUG_FH);
5028 
5029     map = rasqal_new_literal_sequence_sort_map(1 /* is_distinct */,
5030                                                0 /* compare_flags */);
5031     if(!map) {
5032       fprintf(DEBUG_FH, "%s: Test %d failed to create map\n",
5033               program, test_id);
5034       failures++;
5035       raptor_free_sequence(seq);
5036       continue;
5037     }
5038 
5039     duplicates = 0;
5040     count = 0;
5041     for(i = 0;
5042         (seq2 = (raptor_sequence*)raptor_sequence_delete_at(seq, i));
5043         i++) {
5044       int rc;
5045 
5046       rc = rasqal_literal_sequence_sort_map_add_literal_sequence(map, seq2);
5047       if(rc) {
5048         fprintf(DEBUG_FH, "%s: Test %d literal seq %d is a duplicate\n",
5049                 program, test_id, i);
5050         duplicates++;
5051       } else
5052         count++;
5053     }
5054     rasqal_free_map(map);
5055 
5056 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
5057     fprintf(DEBUG_FH, "%s: Test %d had %d duplicates\n", program, test_id,
5058             duplicates);
5059 #endif
5060 
5061     raptor_free_sequence(seq);
5062 
5063     if(count != expected_rows) {
5064       fprintf(DEBUG_FH, "%s: Test %d returned %d rows expected %d\n", program,
5065               test_id, count, expected_rows);
5066       failures++;
5067     }
5068   }
5069 
5070 
5071   tidy:
5072   rasqal_free_world(world);
5073 
5074   return failures;
5075 }
5076 #endif /* STANDALONE */
5077