gkeyfile: Only test file descriptors against -1
[platform/upstream/glib.git] / glib / gvariant-parser.c
1 /*
2  * Copyright © 2009, 2010 Codethink Limited
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the licence, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Author: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include "gerror.h"
29 #include "gquark.h"
30 #include "gstring.h"
31 #include "gstrfuncs.h"
32 #include "gtestutils.h"
33 #include "gvariant.h"
34 #include "gvarianttype.h"
35
36 /*
37  * two-pass algorithm
38  * designed by ryan lortie and william hua
39  * designed in itb-229 and at ghazi's, 2009.
40  */
41
42 /**
43  * G_VARIANT_PARSE_ERROR:
44  *
45  * Error domain for GVariant text format parsing.  Specific error codes
46  * are not currently defined for this domain.  See #GError for
47  * information on error domains.
48  **/
49 /**
50  * GVariantParseError:
51  * @G_VARIANT_PARSE_ERROR_FAILED: generic error (unused)
52  * @G_VARIANT_PARSE_ERROR_BASIC_TYPE_EXPECTED: a non-basic #GVariantType was given where a basic type was expected
53  * @G_VARIANT_PARSE_ERROR_CANNOT_INFER_TYPE: cannot infer the #GVariantType
54  * @G_VARIANT_PARSE_ERROR_DEFINITE_TYPE_EXPECTED: an indefinite #GVariantType was given where a definite type was expected
55  * @G_VARIANT_PARSE_ERROR_INPUT_NOT_AT_END: extra data after parsing finished
56  * @G_VARIANT_PARSE_ERROR_INVALID_CHARACTER: invalid character in number or unicode escape
57  * @G_VARIANT_PARSE_ERROR_INVALID_FORMAT_STRING: not a valid #GVariant format string
58  * @G_VARIANT_PARSE_ERROR_INVALID_OBJECT_PATH: not a valid object path
59  * @G_VARIANT_PARSE_ERROR_INVALID_SIGNATURE: not a valid type signature
60  * @G_VARIANT_PARSE_ERROR_INVALID_TYPE_STRING: not a valid #GVariant type string
61  * @G_VARIANT_PARSE_ERROR_NO_COMMON_TYPE: could not find a common type for array entries
62  * @G_VARIANT_PARSE_ERROR_NUMBER_OUT_OF_RANGE: the numerical value is out of range of the given type
63  * @G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG: the numerical value is out of range for any type
64  * @G_VARIANT_PARSE_ERROR_TYPE_ERROR: cannot parse as variant of the specified type
65  * @G_VARIANT_PARSE_ERROR_UNEXPECTED_TOKEN: an unexpected token was encountered
66  * @G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD: an unknown keyword was encountered
67  * @G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT: unterminated string constant
68  * @G_VARIANT_PARSE_ERROR_VALUE_EXPECTED: no value given
69  *
70  * Error codes returned by parsing text-format GVariants.
71  **/
72 GQuark
73 g_variant_parser_get_error_quark (void)
74 {
75   static GQuark the_quark;
76
77   if (the_quark == 0)
78     the_quark = g_quark_from_static_string ("g-variant-parse-error-quark");
79
80   return the_quark;
81 }
82
83 typedef struct
84 {
85   gint start, end;
86 } SourceRef;
87
88 static void
89 parser_set_error_va (GError      **error,
90                      SourceRef    *location,
91                      SourceRef    *other,
92                      gint          code,
93                      const gchar  *format,
94                      va_list       ap)
95 {
96   GString *msg = g_string_new (NULL);
97
98   if (location->start == location->end)
99     g_string_append_printf (msg, "%d", location->start);
100   else
101     g_string_append_printf (msg, "%d-%d", location->start, location->end);
102
103   if (other != NULL)
104     {
105       g_assert (other->start != other->end);
106       g_string_append_printf (msg, ",%d-%d", other->start, other->end);
107     }
108   g_string_append_c (msg, ':');
109
110   g_string_append_vprintf (msg, format, ap);
111   g_set_error_literal (error, G_VARIANT_PARSE_ERROR, code, msg->str);
112   g_string_free (msg, TRUE);
113 }
114
115 static void
116 parser_set_error (GError      **error,
117                   SourceRef    *location,
118                   SourceRef    *other,
119                   gint          code,
120                   const gchar  *format,
121                   ...)
122 {
123   va_list ap;
124
125   va_start (ap, format);
126   parser_set_error_va (error, location, other, code, format, ap);
127   va_end (ap);
128 }
129
130 typedef struct
131 {
132   const gchar *start;
133   const gchar *stream;
134   const gchar *end;
135
136   const gchar *this;
137 } TokenStream;
138
139
140 static void
141 token_stream_set_error (TokenStream  *stream,
142                         GError      **error,
143                         gboolean      this_token,
144                         gint          code,
145                         const gchar  *format,
146                         ...)
147 {
148   SourceRef ref;
149   va_list ap;
150
151   ref.start = stream->this - stream->start;
152
153   if (this_token)
154     ref.end = stream->stream - stream->start;
155   else
156     ref.end = ref.start;
157
158   va_start (ap, format);
159   parser_set_error_va (error, &ref, NULL, code, format, ap);
160   va_end (ap);
161 }
162
163 static gboolean
164 token_stream_prepare (TokenStream *stream)
165 {
166   gint brackets = 0;
167   const gchar *end;
168
169   if (stream->this != NULL)
170     return TRUE;
171
172   while (stream->stream != stream->end && g_ascii_isspace (*stream->stream))
173     stream->stream++;
174
175   if (stream->stream == stream->end || *stream->stream == '\0')
176     {
177       stream->this = stream->stream;
178       return FALSE;
179     }
180
181   switch (stream->stream[0])
182     {
183     case '-': case '+': case '.': case '0': case '1': case '2':
184     case '3': case '4': case '5': case '6': case '7': case '8':
185     case '9':
186       for (end = stream->stream; end != stream->end; end++)
187         if (!g_ascii_isalnum (*end) &&
188             *end != '-' && *end != '+' && *end != '.')
189           break;
190       break;
191
192     case 'b':
193       if (stream->stream[1] == '\'' || stream->stream[1] == '"')
194         {
195           for (end = stream->stream + 2; end != stream->end; end++)
196             if (*end == stream->stream[1] || *end == '\0' ||
197                 (*end == '\\' && (++end == stream->end || *end == '\0')))
198               break;
199
200           if (end != stream->end && *end)
201             end++;
202           break;
203         }
204
205       else    /* ↓↓↓ */;
206
207     case 'a': /* 'b' */ case 'c': case 'd': case 'e': case 'f':
208     case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
209     case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
210     case 's': case 't': case 'u': case 'v': case 'w': case 'x':
211     case 'y': case 'z':
212       for (end = stream->stream; end != stream->end; end++)
213         if (!g_ascii_isalnum (*end))
214           break;
215       break;
216
217     case '\'': case '"':
218       for (end = stream->stream + 1; end != stream->end; end++)
219         if (*end == stream->stream[0] || *end == '\0' ||
220             (*end == '\\' && (++end == stream->end || *end == '\0')))
221           break;
222
223       if (end != stream->end && *end)
224         end++;
225       break;
226
227     case '@': case '%':
228       /* stop at the first space, comma, colon or unmatched bracket.
229        * deals nicely with cases like (%i, %i) or {%i: %i}.
230        */
231       for (end = stream->stream + 1;
232            end != stream->end && *end != ',' &&
233            *end != ':' && *end != '>' && !g_ascii_isspace (*end);
234            end++)
235
236         if (*end == '(' || *end == '{')
237           brackets++;
238
239         else if ((*end == ')' || *end == '}') && !brackets--)
240           break;
241
242       break;
243
244     default:
245       end = stream->stream + 1;
246       break;
247     }
248
249   stream->this = stream->stream;
250   stream->stream = end;
251
252   return TRUE;
253 }
254
255 static void
256 token_stream_next (TokenStream *stream)
257 {
258   stream->this = NULL;
259 }
260
261 static gboolean
262 token_stream_peek (TokenStream *stream,
263                    gchar        first_char)
264 {
265   if (!token_stream_prepare (stream))
266     return FALSE;
267
268   return stream->this[0] == first_char;
269 }
270
271 static gboolean
272 token_stream_peek2 (TokenStream *stream,
273                     gchar        first_char,
274                     gchar        second_char)
275 {
276   if (!token_stream_prepare (stream))
277     return FALSE;
278
279   return stream->this[0] == first_char &&
280          stream->this[1] == second_char;
281 }
282
283 static gboolean
284 token_stream_is_keyword (TokenStream *stream)
285 {
286   if (!token_stream_prepare (stream))
287     return FALSE;
288
289   return g_ascii_isalpha (stream->this[0]) &&
290          g_ascii_isalpha (stream->this[1]);
291 }
292
293 static gboolean
294 token_stream_is_numeric (TokenStream *stream)
295 {
296   if (!token_stream_prepare (stream))
297     return FALSE;
298
299   return (g_ascii_isdigit (stream->this[0]) ||
300           stream->this[0] == '-' ||
301           stream->this[0] == '+' ||
302           stream->this[0] == '.');
303 }
304
305 static gboolean
306 token_stream_peek_string (TokenStream *stream,
307                           const gchar *token)
308 {
309   gint length = strlen (token);
310
311   return token_stream_prepare (stream) &&
312          stream->stream - stream->this == length &&
313          memcmp (stream->this, token, length) == 0;
314 }
315
316 static gboolean
317 token_stream_consume (TokenStream *stream,
318                       const gchar *token)
319 {
320   if (!token_stream_peek_string (stream, token))
321     return FALSE;
322
323   token_stream_next (stream);
324   return TRUE;
325 }
326
327 static gboolean
328 token_stream_require (TokenStream  *stream,
329                       const gchar  *token,
330                       const gchar  *purpose,
331                       GError      **error)
332 {
333
334   if (!token_stream_consume (stream, token))
335     {
336       token_stream_set_error (stream, error, FALSE,
337                               G_VARIANT_PARSE_ERROR_UNEXPECTED_TOKEN,
338                               "expected `%s'%s", token, purpose);
339       return FALSE;
340     }
341
342   return TRUE;
343 }
344
345 static void
346 token_stream_assert (TokenStream *stream,
347                      const gchar *token)
348 {
349   gboolean correct_token;
350
351   correct_token = token_stream_consume (stream, token);
352   g_assert (correct_token);
353 }
354
355 static gchar *
356 token_stream_get (TokenStream *stream)
357 {
358   gchar *result;
359
360   if (!token_stream_prepare (stream))
361     return NULL;
362
363   result = g_strndup (stream->this, stream->stream - stream->this);
364
365   return result;
366 }
367
368 static void
369 token_stream_start_ref (TokenStream *stream,
370                         SourceRef   *ref)
371 {
372   token_stream_prepare (stream);
373   ref->start = stream->this - stream->start;
374 }
375
376 static void
377 token_stream_end_ref (TokenStream *stream,
378                       SourceRef   *ref)
379 {
380   ref->end = stream->stream - stream->start;
381 }
382
383 void
384 pattern_copy (gchar       **out,
385               const gchar **in)
386 {
387   gint brackets = 0;
388
389   while (**in == 'a' || **in == 'm' || **in == 'M')
390     *(*out)++ = *(*in)++;
391
392   do
393     {
394       if (**in == '(' || **in == '{')
395         brackets++;
396
397       else if (**in == ')' || **in == '}')
398         brackets--;
399
400       *(*out)++ = *(*in)++;
401     }
402   while (brackets);
403 }
404
405 static gchar *
406 pattern_coalesce (const gchar *left,
407                   const gchar *right)
408 {
409   gchar *result;
410   gchar *out;
411
412   /* the length of the output is loosely bound by the sum of the input
413    * lengths, not simply the greater of the two lengths.
414    *
415    *   (*(iii)) + ((iii)*) ((iii)(iii))
416    *
417    *      8     +    8    =  12
418    */
419   out = result = g_malloc (strlen (left) + strlen (right));
420
421   while (*left && *right)
422     {
423       if (*left == *right)
424         {
425           *out++ = *left++;
426           right++;
427         }
428
429       else
430         {
431           const gchar **one = &left, **the_other = &right;
432
433          again:
434           if (**one == '*' && **the_other != ')')
435             {
436               pattern_copy (&out, the_other);
437               (*one)++;
438             }
439
440           else if (**one == 'M' && **the_other == 'm')
441             {
442               *out++ = *(*the_other)++;
443             }
444
445           else if (**one == 'M' && **the_other != 'm')
446             {
447               (*one)++;
448             }
449
450           else if (**one == 'N' && strchr ("ynqiuxthd", **the_other))
451             {
452               *out++ = *(*the_other)++;
453               (*one)++;
454             }
455
456           else if (**one == 'S' && strchr ("sog", **the_other))
457             {
458               *out++ = *(*the_other)++;
459               (*one)++;
460             }
461
462           else if (one == &left)
463             {
464               one = &right, the_other = &left;
465               goto again;
466             }
467
468           else
469             break;
470         }
471     }
472
473   if (*left || *right)
474     {
475       g_free (result);
476       result = NULL;
477     }
478   else
479     *out++ = '\0';
480
481   return result;
482 }
483
484 typedef struct _AST AST;
485 typedef gchar *    (*get_pattern_func)    (AST                 *ast,
486                                            GError             **error);
487 typedef GVariant * (*get_value_func)      (AST                 *ast,
488                                            const GVariantType  *type,
489                                            GError             **error);
490 typedef GVariant * (*get_base_value_func) (AST                 *ast,
491                                            const GVariantType  *type,
492                                            GError             **error);
493 typedef void       (*free_func)           (AST                 *ast);
494
495 typedef struct
496 {
497   gchar *    (* get_pattern)    (AST                 *ast,
498                                  GError             **error);
499   GVariant * (* get_value)      (AST                 *ast,
500                                  const GVariantType  *type,
501                                  GError             **error);
502   GVariant * (* get_base_value) (AST                 *ast,
503                                  const GVariantType  *type,
504                                  GError             **error);
505   void       (* free)           (AST                 *ast);
506 } ASTClass;
507
508 struct _AST
509 {
510   const ASTClass *class;
511   SourceRef source_ref;
512 };
513
514 static gchar *
515 ast_get_pattern (AST     *ast,
516                  GError **error)
517 {
518   return ast->class->get_pattern (ast, error);
519 }
520
521 static GVariant *
522 ast_get_value (AST                 *ast,
523                const GVariantType  *type,
524                GError             **error)
525 {
526   return ast->class->get_value (ast, type, error);
527 }
528
529 static void
530 ast_free (AST *ast)
531 {
532   ast->class->free (ast);
533 }
534
535 static void
536 ast_set_error (AST          *ast,
537                GError      **error,
538                AST          *other_ast,
539                gint          code,
540                const gchar  *format,
541                ...)
542 {
543   va_list ap;
544
545   va_start (ap, format);
546   parser_set_error_va (error, &ast->source_ref,
547                        other_ast ? & other_ast->source_ref : NULL,
548                        code,
549                        format, ap);
550   va_end (ap);
551 }
552
553 static GVariant *
554 ast_type_error (AST                 *ast,
555                 const GVariantType  *type,
556                 GError             **error)
557 {
558   gchar *typestr;
559
560   typestr = g_variant_type_dup_string (type);
561   ast_set_error (ast, error, NULL,
562                  G_VARIANT_PARSE_ERROR_TYPE_ERROR,
563                  "can not parse as value of type `%s'",
564                  typestr);
565   g_free (typestr);
566
567   return NULL;
568 }
569
570 static GVariant *
571 ast_resolve (AST     *ast,
572              GError **error)
573 {
574   GVariant *value;
575   gchar *pattern;
576   gint i, j = 0;
577
578   pattern = ast_get_pattern (ast, error);
579
580   if (pattern == NULL)
581     return NULL;
582
583   /* choose reasonable defaults
584    *
585    *   1) favour non-maybe values where possible
586    *   2) default type for strings is 's'
587    *   3) default type for integers is 'i'
588    */
589   for (i = 0; pattern[i]; i++)
590     switch (pattern[i])
591       {
592       case '*':
593         ast_set_error (ast, error, NULL,
594                        G_VARIANT_PARSE_ERROR_CANNOT_INFER_TYPE,
595                        "unable to infer type");
596         g_free (pattern);
597         return NULL;
598
599       case 'M':
600         break;
601
602       case 'S':
603         pattern[j++] = 's';
604         break;
605
606       case 'N':
607         pattern[j++] = 'i';
608         break;
609
610       default:
611         pattern[j++] = pattern[i];
612         break;
613       }
614   pattern[j++] = '\0';
615
616   value = ast_get_value (ast, G_VARIANT_TYPE (pattern), error);
617   g_free (pattern);
618
619   return value;
620 }
621
622
623 static AST *parse (TokenStream  *stream,
624                    va_list      *app,
625                    GError      **error);
626
627 static void
628 ast_array_append (AST  ***array,
629                   gint   *n_items,
630                   AST    *ast)
631 {
632   if ((*n_items & (*n_items - 1)) == 0)
633     *array = g_renew (AST *, *array, *n_items ? 2 ** n_items : 1);
634
635   (*array)[(*n_items)++] = ast;
636 }
637
638 static void
639 ast_array_free (AST  **array,
640                 gint   n_items)
641 {
642   gint i;
643
644   for (i = 0; i < n_items; i++)
645     ast_free (array[i]);
646   g_free (array);
647 }
648
649 static gchar *
650 ast_array_get_pattern (AST    **array,
651                        gint     n_items,
652                        GError **error)
653 {
654   gchar *pattern;
655   gint i;
656
657   pattern = ast_get_pattern (array[0], error);
658
659   if (pattern == NULL)
660     return NULL;
661
662   for (i = 1; i < n_items; i++)
663     {
664       gchar *tmp, *merged;
665
666       tmp = ast_get_pattern (array[i], error);
667
668       if (tmp == NULL)
669         {
670           g_free (pattern);
671           return NULL;
672         }
673
674       merged = pattern_coalesce (pattern, tmp);
675       g_free (pattern);
676       pattern = merged;
677
678       if (merged == NULL)
679         /* set coalescence implies pairwise coalescence (i think).
680          * we should therefore be able to trace the failure to a single
681          * pair of values.
682          */
683         {
684           int j = 0;
685
686           while (TRUE)
687             {
688               gchar *tmp2;
689               gchar *m;
690
691               /* if 'j' reaches 'i' then we failed to find the pair */
692               g_assert (j < i);
693
694               tmp2 = ast_get_pattern (array[j], NULL);
695               g_assert (tmp2 != NULL);
696
697               m = pattern_coalesce (tmp, tmp2);
698               g_free (tmp2);
699               g_free (m);
700
701               if (m == NULL)
702                 {
703                   /* we found a conflict between 'i' and 'j'.
704                    *
705                    * report the error.  note: 'j' is first.
706                    */
707                   ast_set_error (array[j], error, array[i],
708                                  G_VARIANT_PARSE_ERROR_NO_COMMON_TYPE,
709                                  "unable to find a common type");
710                   g_free (tmp);
711                   return NULL;
712                 }
713
714               j++;
715             }
716
717         }
718
719       g_free (tmp);
720     }
721
722   return pattern;
723 }
724
725 typedef struct
726 {
727   AST ast;
728
729   AST *child;
730 } Maybe;
731
732 static gchar *
733 maybe_get_pattern (AST     *ast,
734                    GError **error)
735 {
736   Maybe *maybe = (Maybe *) ast;
737
738   if (maybe->child != NULL)
739     {
740       gchar *child_pattern;
741       gchar *pattern;
742
743       child_pattern = ast_get_pattern (maybe->child, error);
744
745       if (child_pattern == NULL)
746         return NULL;
747
748       pattern = g_strdup_printf ("m%s", child_pattern);
749       g_free (child_pattern);
750
751       return pattern;
752     }
753
754   return g_strdup ("m*");
755 }
756
757 static GVariant *
758 maybe_get_value (AST                 *ast,
759                  const GVariantType  *type,
760                  GError             **error)
761 {
762   Maybe *maybe = (Maybe *) ast;
763   GVariant *value;
764
765   if (!g_variant_type_is_maybe (type))
766     return ast_type_error (ast, type, error);
767
768   type = g_variant_type_element (type);
769
770   if (maybe->child)
771     {
772       value = ast_get_value (maybe->child, type, error);
773
774       if (value == NULL)
775         return NULL;
776     }
777   else
778     value = NULL;
779
780   return g_variant_new_maybe (type, value);
781 }
782
783 static void
784 maybe_free (AST *ast)
785 {
786   Maybe *maybe = (Maybe *) ast;
787
788   if (maybe->child != NULL)
789     ast_free (maybe->child);
790
791   g_slice_free (Maybe, maybe);
792 }
793
794 static AST *
795 maybe_parse (TokenStream  *stream,
796              va_list      *app,
797              GError      **error)
798 {
799   static const ASTClass maybe_class = {
800     maybe_get_pattern,
801     maybe_get_value, NULL,
802     maybe_free
803   };
804   AST *child = NULL;
805   Maybe *maybe;
806
807   if (token_stream_consume (stream, "just"))
808     {
809       child = parse (stream, app, error);
810       if (child == NULL)
811         return NULL;
812     }
813
814   else if (!token_stream_consume (stream, "nothing"))
815     {
816       token_stream_set_error (stream, error, TRUE,
817                               G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD,
818                               "unknown keyword");
819       return NULL;
820     }
821
822   maybe = g_slice_new (Maybe);
823   maybe->ast.class = &maybe_class;
824   maybe->child = child;
825
826   return (AST *) maybe;
827 }
828
829 static GVariant *
830 maybe_wrapper (AST                 *ast,
831                const GVariantType  *type,
832                GError             **error)
833 {
834   const GVariantType *t;
835   GVariant *value;
836   int depth;
837
838   for (depth = 0, t = type;
839        g_variant_type_is_maybe (t);
840        depth++, t = g_variant_type_element (t));
841
842   value = ast->class->get_base_value (ast, t, error);
843
844   if (value == NULL)
845     return NULL;
846
847   while (depth--)
848     value = g_variant_new_maybe (NULL, value);
849
850   return value;
851 }
852
853 typedef struct
854 {
855   AST ast;
856
857   AST **children;
858   gint n_children;
859 } Array;
860
861 static gchar *
862 array_get_pattern (AST     *ast,
863                    GError **error)
864 {
865   Array *array = (Array *) ast;
866   gchar *pattern;
867   gchar *result;
868
869   if (array->n_children == 0)
870     return g_strdup ("Ma*");
871
872   pattern = ast_array_get_pattern (array->children, array->n_children, error);
873
874   if (pattern == NULL)
875     return NULL;
876
877   result = g_strdup_printf ("Ma%s", pattern);
878   g_free (pattern);
879
880   return result;
881 }
882
883 static GVariant *
884 array_get_value (AST                 *ast,
885                  const GVariantType  *type,
886                  GError             **error)
887 {
888   Array *array = (Array *) ast;
889   const GVariantType *childtype;
890   GVariantBuilder builder;
891   gint i;
892
893   if (!g_variant_type_is_array (type))
894     return ast_type_error (ast, type, error);
895
896   g_variant_builder_init (&builder, type);
897   childtype = g_variant_type_element (type);
898
899   for (i = 0; i < array->n_children; i++)
900     {
901       GVariant *child;
902
903       if (!(child = ast_get_value (array->children[i], childtype, error)))
904         {
905           g_variant_builder_clear (&builder);
906           return NULL;
907         }
908
909       g_variant_builder_add_value (&builder, child);
910     }
911
912   return g_variant_builder_end (&builder);
913 }
914
915 static void
916 array_free (AST *ast)
917 {
918   Array *array = (Array *) ast;
919
920   ast_array_free (array->children, array->n_children);
921   g_slice_free (Array, array);
922 }
923
924 static AST *
925 array_parse (TokenStream  *stream,
926              va_list      *app,
927              GError      **error)
928 {
929   static const ASTClass array_class = {
930     array_get_pattern,
931     maybe_wrapper, array_get_value,
932     array_free
933   };
934   gboolean need_comma = FALSE;
935   Array *array;
936
937   array = g_slice_new (Array);
938   array->ast.class = &array_class;
939   array->children = NULL;
940   array->n_children = 0;
941
942   token_stream_assert (stream, "[");
943   while (!token_stream_consume (stream, "]"))
944     {
945       AST *child;
946
947       if (need_comma &&
948           !token_stream_require (stream, ",",
949                                  " or `]' to follow array element",
950                                  error))
951         goto error;
952
953       child = parse (stream, app, error);
954
955       if (!child)
956         goto error;
957
958       ast_array_append (&array->children, &array->n_children, child);
959       need_comma = TRUE;
960     }
961
962   return (AST *) array;
963
964  error:
965   ast_array_free (array->children, array->n_children);
966   g_slice_free (Array, array);
967
968   return NULL;
969 }
970
971 typedef struct
972 {
973   AST ast;
974
975   AST **children;
976   gint n_children;
977 } Tuple;
978
979 static gchar *
980 tuple_get_pattern (AST     *ast,
981                    GError **error)
982 {
983   Tuple *tuple = (Tuple *) ast;
984   gchar *result = NULL;
985   gchar **parts;
986   gint i;
987
988   parts = g_new (gchar *, tuple->n_children + 4);
989   parts[tuple->n_children + 1] = (gchar *) ")";
990   parts[tuple->n_children + 2] = NULL;
991   parts[0] = (gchar *) "M(";
992
993   for (i = 0; i < tuple->n_children; i++)
994     if (!(parts[i + 1] = ast_get_pattern (tuple->children[i], error)))
995       break;
996
997   if (i == tuple->n_children)
998     result = g_strjoinv ("", parts);
999
1000   /* parts[0] should not be freed */
1001   while (i)
1002     g_free (parts[i--]);
1003   g_free (parts);
1004
1005   return result;
1006 }
1007
1008 static GVariant *
1009 tuple_get_value (AST                 *ast,
1010                  const GVariantType  *type,
1011                  GError             **error)
1012 {
1013   Tuple *tuple = (Tuple *) ast;
1014   const GVariantType *childtype;
1015   GVariantBuilder builder;
1016   gint i;
1017
1018   if (!g_variant_type_is_tuple (type))
1019     return ast_type_error (ast, type, error);
1020
1021   g_variant_builder_init (&builder, type);
1022   childtype = g_variant_type_first (type);
1023
1024   for (i = 0; i < tuple->n_children; i++)
1025     {
1026       GVariant *child;
1027
1028       if (childtype == NULL)
1029         {
1030           g_variant_builder_clear (&builder);
1031           return ast_type_error (ast, type, error);
1032         }
1033
1034       if (!(child = ast_get_value (tuple->children[i], childtype, error)))
1035         {
1036           g_variant_builder_clear (&builder);
1037           return FALSE;
1038         }
1039
1040       g_variant_builder_add_value (&builder, child);
1041       childtype = g_variant_type_next (childtype);
1042     }
1043
1044   if (childtype != NULL)
1045     {
1046       g_variant_builder_clear (&builder);
1047       return ast_type_error (ast, type, error);
1048     }
1049
1050   return g_variant_builder_end (&builder);
1051 }
1052
1053 static void
1054 tuple_free (AST *ast)
1055 {
1056   Tuple *tuple = (Tuple *) ast;
1057
1058   ast_array_free (tuple->children, tuple->n_children);
1059   g_slice_free (Tuple, tuple);
1060 }
1061
1062 static AST *
1063 tuple_parse (TokenStream  *stream,
1064              va_list      *app,
1065              GError      **error)
1066 {
1067   static const ASTClass tuple_class = {
1068     tuple_get_pattern,
1069     maybe_wrapper, tuple_get_value,
1070     tuple_free
1071   };
1072   gboolean need_comma = FALSE;
1073   gboolean first = TRUE;
1074   Tuple *tuple;
1075
1076   tuple = g_slice_new (Tuple);
1077   tuple->ast.class = &tuple_class;
1078   tuple->children = NULL;
1079   tuple->n_children = 0;
1080
1081   token_stream_assert (stream, "(");
1082   while (!token_stream_consume (stream, ")"))
1083     {
1084       AST *child;
1085
1086       if (need_comma &&
1087           !token_stream_require (stream, ",",
1088                                  " or `)' to follow tuple element",
1089                                  error))
1090         goto error;
1091
1092       child = parse (stream, app, error);
1093
1094       if (!child)
1095         goto error;
1096
1097       ast_array_append (&tuple->children, &tuple->n_children, child);
1098
1099       /* the first time, we absolutely require a comma, so grab it here
1100        * and leave need_comma = FALSE so that the code above doesn't
1101        * require a second comma.
1102        *
1103        * the second and remaining times, we set need_comma = TRUE.
1104        */
1105       if (first)
1106         {
1107           if (!token_stream_require (stream, ",",
1108                                      " after first tuple element", error))
1109             goto error;
1110
1111           first = FALSE;
1112         }
1113       else
1114         need_comma = TRUE;
1115     }
1116
1117   return (AST *) tuple;
1118
1119  error:
1120   ast_array_free (tuple->children, tuple->n_children);
1121   g_slice_free (Tuple, tuple);
1122
1123   return NULL;
1124 }
1125
1126 typedef struct
1127 {
1128   AST ast;
1129
1130   AST *value;
1131 } Variant;
1132
1133 static gchar *
1134 variant_get_pattern (AST     *ast,
1135                      GError **error)
1136 {
1137   return g_strdup ("Mv");
1138 }
1139
1140 static GVariant *
1141 variant_get_value (AST                 *ast,
1142                    const GVariantType  *type,
1143                    GError             **error)
1144 {
1145   Variant *variant = (Variant *) ast;
1146   GVariant *child;
1147
1148   g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT));
1149   child = ast_resolve (variant->value, error);
1150
1151   if (child == NULL)
1152     return NULL;
1153
1154   return g_variant_new_variant (child);
1155 }
1156
1157 static void
1158 variant_free (AST *ast)
1159 {
1160   Variant *variant = (Variant *) ast;
1161
1162   ast_free (variant->value);
1163   g_slice_free (Variant, variant);
1164 }
1165
1166 static AST *
1167 variant_parse (TokenStream  *stream,
1168                va_list      *app,
1169                GError      **error)
1170 {
1171   static const ASTClass variant_class = {
1172     variant_get_pattern,
1173     maybe_wrapper, variant_get_value,
1174     variant_free
1175   };
1176   Variant *variant;
1177   AST *value;
1178
1179   token_stream_assert (stream, "<");
1180   value = parse (stream, app, error);
1181
1182   if (!value)
1183     return NULL;
1184
1185   if (!token_stream_require (stream, ">", " to follow variant value", error))
1186     {
1187       ast_free (value);
1188       return NULL;
1189     }
1190
1191   variant = g_slice_new (Variant);
1192   variant->ast.class = &variant_class;
1193   variant->value = value;
1194
1195   return (AST *) variant;
1196 }
1197
1198 typedef struct
1199 {
1200   AST ast;
1201
1202   AST **keys;
1203   AST **values;
1204   gint n_children;
1205 } Dictionary;
1206
1207 static gchar *
1208 dictionary_get_pattern (AST     *ast,
1209                         GError **error)
1210 {
1211   Dictionary *dict = (Dictionary *) ast;
1212   gchar *value_pattern;
1213   gchar *key_pattern;
1214   gchar key_char;
1215   gchar *result;
1216
1217   if (dict->n_children == 0)
1218     return g_strdup ("Ma{**}");
1219
1220   key_pattern = ast_array_get_pattern (dict->keys,
1221                                        abs (dict->n_children),
1222                                        error);
1223
1224   if (key_pattern == NULL)
1225     return NULL;
1226
1227   /* we can not have maybe keys */
1228   if (key_pattern[0] == 'M')
1229     key_char = key_pattern[1];
1230   else
1231     key_char = key_pattern[0];
1232
1233   g_free (key_pattern);
1234
1235   /* the basic types,
1236    * plus undetermined number type and undetermined string type.
1237    */
1238   if (!strchr ("bynqiuxthdsogNS", key_char))
1239     {
1240       ast_set_error (ast, error, NULL,
1241                      G_VARIANT_PARSE_ERROR_BASIC_TYPE_EXPECTED,
1242                      "dictionary keys must have basic types");
1243       return NULL;
1244     }
1245
1246   value_pattern = ast_get_pattern (dict->values[0], error);
1247
1248   if (value_pattern == NULL)
1249     return NULL;
1250
1251   result = g_strdup_printf ("M%s{%c%s}",
1252                             dict->n_children > 0 ? "a" : "",
1253                             key_char, value_pattern);
1254   g_free (value_pattern);
1255
1256   return result;
1257 }
1258
1259 static GVariant *
1260 dictionary_get_value (AST                 *ast,
1261                       const GVariantType  *type,
1262                       GError             **error)
1263 {
1264   Dictionary *dict = (Dictionary *) ast;
1265
1266   if (dict->n_children == -1)
1267     {
1268       const GVariantType *subtype;
1269       GVariantBuilder builder;
1270       GVariant *subvalue;
1271
1272       if (!g_variant_type_is_dict_entry (type))
1273         return ast_type_error (ast, type, error);
1274
1275       g_variant_builder_init (&builder, type);
1276
1277       subtype = g_variant_type_key (type);
1278       if (!(subvalue = ast_get_value (dict->keys[0], subtype, error)))
1279         {
1280           g_variant_builder_clear (&builder);
1281           return NULL;
1282         }
1283       g_variant_builder_add_value (&builder, subvalue);
1284
1285       subtype = g_variant_type_value (type);
1286       if (!(subvalue = ast_get_value (dict->values[0], subtype, error)))
1287         {
1288           g_variant_builder_clear (&builder);
1289           return NULL;
1290         }
1291       g_variant_builder_add_value (&builder, subvalue);
1292
1293       return g_variant_builder_end (&builder);
1294     }
1295   else
1296     {
1297       const GVariantType *entry, *key, *val;
1298       GVariantBuilder builder;
1299       gint i;
1300
1301       if (!g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_DICTIONARY))
1302         return ast_type_error (ast, type, error);
1303
1304       entry = g_variant_type_element (type);
1305       key = g_variant_type_key (entry);
1306       val = g_variant_type_value (entry);
1307
1308       g_variant_builder_init (&builder, type);
1309
1310       for (i = 0; i < dict->n_children; i++)
1311         {
1312           GVariant *subvalue;
1313
1314           g_variant_builder_open (&builder, entry);
1315
1316           if (!(subvalue = ast_get_value (dict->keys[i], key, error)))
1317             {
1318               g_variant_builder_clear (&builder);
1319               return NULL;
1320             }
1321           g_variant_builder_add_value (&builder, subvalue);
1322
1323           if (!(subvalue = ast_get_value (dict->values[i], val, error)))
1324             {
1325               g_variant_builder_clear (&builder);
1326               return NULL;
1327             }
1328           g_variant_builder_add_value (&builder, subvalue);
1329           g_variant_builder_close (&builder);
1330         }
1331
1332       return g_variant_builder_end (&builder);
1333     }
1334 }
1335
1336 static void
1337 dictionary_free (AST *ast)
1338 {
1339   Dictionary *dict = (Dictionary *) ast;
1340   gint n_children;
1341
1342   if (dict->n_children > -1)
1343     n_children = dict->n_children;
1344   else
1345     n_children = 1;
1346
1347   ast_array_free (dict->keys, n_children);
1348   ast_array_free (dict->values, n_children);
1349   g_slice_free (Dictionary, dict);
1350 }
1351
1352 static AST *
1353 dictionary_parse (TokenStream  *stream,
1354                   va_list      *app,
1355                   GError      **error)
1356 {
1357   static const ASTClass dictionary_class = {
1358     dictionary_get_pattern,
1359     maybe_wrapper, dictionary_get_value,
1360     dictionary_free
1361   };
1362   gint n_keys, n_values;
1363   gboolean only_one;
1364   Dictionary *dict;
1365   AST *first;
1366
1367   dict = g_slice_new (Dictionary);
1368   dict->ast.class = &dictionary_class;
1369   dict->keys = NULL;
1370   dict->values = NULL;
1371   n_keys = n_values = 0;
1372
1373   token_stream_assert (stream, "{");
1374
1375   if (token_stream_consume (stream, "}"))
1376     {
1377       dict->n_children = 0;
1378       return (AST *) dict;
1379     }
1380
1381   if ((first = parse (stream, app, error)) == NULL)
1382     goto error;
1383
1384   ast_array_append (&dict->keys, &n_keys, first);
1385
1386   only_one = token_stream_consume (stream, ",");
1387   if (!only_one &&
1388       !token_stream_require (stream, ":",
1389                              " or `,' to follow dictionary entry key",
1390                              error))
1391     goto error;
1392
1393   if ((first = parse (stream, app, error)) == NULL)
1394     goto error;
1395
1396   ast_array_append (&dict->values, &n_values, first);
1397
1398   if (only_one)
1399     {
1400       if (!token_stream_require (stream, "}", " at end of dictionary entry",
1401                                  error))
1402         goto error;
1403
1404       g_assert (n_keys == 1 && n_values == 1);
1405       dict->n_children = -1;
1406
1407       return (AST *) dict;
1408     }
1409
1410   while (!token_stream_consume (stream, "}"))
1411     {
1412       AST *child;
1413
1414       if (!token_stream_require (stream, ",",
1415                                  " or `}' to follow dictionary entry", error))
1416         goto error;
1417
1418       child = parse (stream, app, error);
1419
1420       if (!child)
1421         goto error;
1422
1423       ast_array_append (&dict->keys, &n_keys, child);
1424
1425       if (!token_stream_require (stream, ":",
1426                                  " to follow dictionary entry key", error))
1427         goto error;
1428
1429       child = parse (stream, app, error);
1430
1431       if (!child)
1432         goto error;
1433
1434       ast_array_append (&dict->values, &n_values, child);
1435     }
1436
1437   g_assert (n_keys == n_values);
1438   dict->n_children = n_keys;
1439
1440   return (AST *) dict;
1441
1442  error:
1443   ast_array_free (dict->keys, n_keys);
1444   ast_array_free (dict->values, n_values);
1445   g_slice_free (Dictionary, dict);
1446
1447   return NULL;
1448 }
1449
1450 typedef struct
1451 {
1452   AST ast;
1453   gchar *string;
1454 } String;
1455
1456 static gchar *
1457 string_get_pattern (AST     *ast,
1458                     GError **error)
1459 {
1460   return g_strdup ("MS");
1461 }
1462
1463 static GVariant *
1464 string_get_value (AST                 *ast,
1465                   const GVariantType  *type,
1466                   GError             **error)
1467 {
1468   String *string = (String *) ast;
1469
1470   if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
1471     return g_variant_new_string (string->string);
1472
1473   else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
1474     {
1475       if (!g_variant_is_object_path (string->string))
1476         {
1477           ast_set_error (ast, error, NULL,
1478                          G_VARIANT_PARSE_ERROR_INVALID_OBJECT_PATH,
1479                          "not a valid object path");
1480           return NULL;
1481         }
1482
1483       return g_variant_new_object_path (string->string);
1484     }
1485
1486   else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
1487     {
1488       if (!g_variant_is_signature (string->string))
1489         {
1490           ast_set_error (ast, error, NULL,
1491                          G_VARIANT_PARSE_ERROR_INVALID_SIGNATURE,
1492                          "not a valid signature");
1493           return NULL;
1494         }
1495
1496       return g_variant_new_signature (string->string);
1497     }
1498
1499   else
1500     return ast_type_error (ast, type, error);
1501 }
1502
1503 static void
1504 string_free (AST *ast)
1505 {
1506   String *string = (String *) ast;
1507
1508   g_free (string->string);
1509   g_slice_free (String, string);
1510 }
1511
1512 static gboolean
1513 unicode_unescape (const gchar  *src,
1514                   gint         *src_ofs,
1515                   gchar        *dest,
1516                   gint         *dest_ofs,
1517                   gint          length,
1518                   SourceRef    *ref,
1519                   GError      **error)
1520 {
1521   gchar buffer[9];
1522   guint64 value;
1523   gchar *end;
1524
1525   (*src_ofs)++;
1526
1527   g_assert (length < sizeof (buffer));
1528   strncpy (buffer, src + *src_ofs, length);
1529   buffer[length] = '\0';
1530
1531   value = g_ascii_strtoull (buffer, &end, 0x10);
1532
1533   if (value == 0 || end != buffer + length)
1534     {
1535       parser_set_error (error, ref, NULL,
1536                         G_VARIANT_PARSE_ERROR_INVALID_CHARACTER,
1537                         "invalid %d-character unicode escape", length);
1538       return FALSE;
1539     }
1540
1541   g_assert (value <= G_MAXUINT32);
1542
1543   *dest_ofs += g_unichar_to_utf8 (value, dest + *dest_ofs);
1544   *src_ofs += length;
1545
1546   return TRUE;
1547 }
1548
1549 static AST *
1550 string_parse (TokenStream  *stream,
1551               va_list      *app,
1552               GError      **error)
1553 {
1554   static const ASTClass string_class = {
1555     string_get_pattern,
1556     maybe_wrapper, string_get_value,
1557     string_free
1558   };
1559   String *string;
1560   SourceRef ref;
1561   gchar *token;
1562   gsize length;
1563   gchar quote;
1564   gchar *str;
1565   gint i, j;
1566
1567   token_stream_start_ref (stream, &ref);
1568   token = token_stream_get (stream);
1569   token_stream_end_ref (stream, &ref);
1570   length = strlen (token);
1571   quote = token[0];
1572
1573   str = g_malloc (length);
1574   g_assert (quote == '"' || quote == '\'');
1575   j = 0;
1576   i = 1;
1577   while (token[i] != quote)
1578     switch (token[i])
1579       {
1580       case '\0':
1581         parser_set_error (error, &ref, NULL,
1582                           G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT,
1583                           "unterminated string constant");
1584         g_free (token);
1585         g_free (str);
1586         return NULL;
1587
1588       case '\\':
1589         switch (token[++i])
1590           {
1591           case '\0':
1592             parser_set_error (error, &ref, NULL,
1593                               G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT,
1594                               "unterminated string constant");
1595             g_free (token);
1596             g_free (str);
1597             return NULL;
1598
1599           case 'u':
1600             if (!unicode_unescape (token, &i, str, &j, 4, &ref, error))
1601               {
1602                 g_free (token);
1603                 g_free (str);
1604                 return NULL;
1605               }
1606             continue;
1607
1608           case 'U':
1609             if (!unicode_unescape (token, &i, str, &j, 8, &ref, error))
1610               {
1611                 g_free (token);
1612                 g_free (str);
1613                 return NULL;
1614               }
1615             continue;
1616
1617           case 'a': str[j++] = '\a'; i++; continue;
1618           case 'b': str[j++] = '\b'; i++; continue;
1619           case 'f': str[j++] = '\f'; i++; continue;
1620           case 'n': str[j++] = '\n'; i++; continue;
1621           case 'r': str[j++] = '\r'; i++; continue;
1622           case 't': str[j++] = '\t'; i++; continue;
1623           case 'v': str[j++] = '\v'; i++; continue;
1624           case '\n': i++; continue;
1625           }
1626
1627       default:
1628         str[j++] = token[i++];
1629       }
1630   str[j++] = '\0';
1631   g_free (token);
1632
1633   string = g_slice_new (String);
1634   string->ast.class = &string_class;
1635   string->string = str;
1636
1637   token_stream_next (stream);
1638
1639   return (AST *) string;
1640 }
1641
1642 typedef struct
1643 {
1644   AST ast;
1645   gchar *string;
1646 } ByteString;
1647
1648 static gchar *
1649 bytestring_get_pattern (AST     *ast,
1650                         GError **error)
1651 {
1652   return g_strdup ("May");
1653 }
1654
1655 static GVariant *
1656 bytestring_get_value (AST                 *ast,
1657                       const GVariantType  *type,
1658                       GError             **error)
1659 {
1660   ByteString *string = (ByteString *) ast;
1661
1662   g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_BYTESTRING));
1663
1664   return g_variant_new_bytestring (string->string);
1665 }
1666
1667 static void
1668 bytestring_free (AST *ast)
1669 {
1670   ByteString *string = (ByteString *) ast;
1671
1672   g_free (string->string);
1673   g_slice_free (ByteString, string);
1674 }
1675
1676 static AST *
1677 bytestring_parse (TokenStream  *stream,
1678                   va_list      *app,
1679                   GError      **error)
1680 {
1681   static const ASTClass bytestring_class = {
1682     bytestring_get_pattern,
1683     maybe_wrapper, bytestring_get_value,
1684     bytestring_free
1685   };
1686   ByteString *string;
1687   SourceRef ref;
1688   gchar *token;
1689   gsize length;
1690   gchar quote;
1691   gchar *str;
1692   gint i, j;
1693
1694   token_stream_start_ref (stream, &ref);
1695   token = token_stream_get (stream);
1696   token_stream_end_ref (stream, &ref);
1697   g_assert (token[0] == 'b');
1698   length = strlen (token);
1699   quote = token[1];
1700
1701   str = g_malloc (length);
1702   g_assert (quote == '"' || quote == '\'');
1703   j = 0;
1704   i = 2;
1705   while (token[i] != quote)
1706     switch (token[i])
1707       {
1708       case '\0':
1709         parser_set_error (error, &ref, NULL,
1710                           G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT,
1711                           "unterminated string constant");
1712         g_free (token);
1713         return NULL;
1714
1715       case '\\':
1716         switch (token[++i])
1717           {
1718           case '\0':
1719             parser_set_error (error, &ref, NULL,
1720                               G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT,
1721                               "unterminated string constant");
1722             g_free (token);
1723             return NULL;
1724
1725           case '0': case '1': case '2': case '3':
1726           case '4': case '5': case '6': case '7':
1727             {
1728               /* up to 3 characters */
1729               guchar val = token[i++] - '0';
1730
1731               if ('0' <= token[i] && token[i] < '8')
1732                 val = (val << 3) | (token[i++] - '0');
1733
1734               if ('0' <= token[i] && token[i] < '8')
1735                 val = (val << 3) | (token[i++] - '0');
1736
1737               str[j++] = val;
1738             }
1739             continue;
1740
1741           case 'a': str[j++] = '\a'; i++; continue;
1742           case 'b': str[j++] = '\b'; i++; continue;
1743           case 'f': str[j++] = '\f'; i++; continue;
1744           case 'n': str[j++] = '\n'; i++; continue;
1745           case 'r': str[j++] = '\r'; i++; continue;
1746           case 't': str[j++] = '\t'; i++; continue;
1747           case 'v': str[j++] = '\v'; i++; continue;
1748           case '\n': i++; continue;
1749           }
1750
1751       default:
1752         str[j++] = token[i++];
1753       }
1754   str[j++] = '\0';
1755   g_free (token);
1756
1757   string = g_slice_new (ByteString);
1758   string->ast.class = &bytestring_class;
1759   string->string = str;
1760
1761   token_stream_next (stream);
1762
1763   return (AST *) string;
1764 }
1765
1766 typedef struct
1767 {
1768   AST ast;
1769
1770   gchar *token;
1771 } Number;
1772
1773 static gchar *
1774 number_get_pattern (AST     *ast,
1775                     GError **error)
1776 {
1777   Number *number = (Number *) ast;
1778
1779   if (strchr (number->token, '.') ||
1780       (!g_str_has_prefix (number->token, "0x") && strchr (number->token, 'e')) ||
1781       strstr (number->token, "inf") ||
1782       strstr (number->token, "nan"))
1783     return g_strdup ("Md");
1784
1785   return g_strdup ("MN");
1786 }
1787
1788 static GVariant *
1789 number_overflow (AST                 *ast,
1790                  const GVariantType  *type,
1791                  GError             **error)
1792 {
1793   ast_set_error (ast, error, NULL,
1794                  G_VARIANT_PARSE_ERROR_NUMBER_OUT_OF_RANGE,
1795                  "number out of range for type `%c'",
1796                  g_variant_type_peek_string (type)[0]);
1797   return NULL;
1798 }
1799
1800 static GVariant *
1801 number_get_value (AST                 *ast,
1802                   const GVariantType  *type,
1803                   GError             **error)
1804 {
1805   Number *number = (Number *) ast;
1806   const gchar *token;
1807   gboolean negative;
1808   gboolean floating;
1809   guint64 abs_val;
1810   gdouble dbl_val;
1811   gchar *end;
1812
1813   token = number->token;
1814
1815   if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
1816     {
1817       floating = TRUE;
1818
1819       errno = 0;
1820       dbl_val = g_ascii_strtod (token, &end);
1821       if (dbl_val != 0.0 && errno == ERANGE)
1822         {
1823           ast_set_error (ast, error, NULL,
1824                          G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG,
1825                          "number too big for any type");
1826           return NULL;
1827         }
1828
1829       /* silence uninitialised warnings... */
1830       negative = FALSE;
1831       abs_val = 0;
1832     }
1833   else
1834     {
1835       floating = FALSE;
1836       negative = token[0] == '-';
1837       if (token[0] == '-')
1838         token++;
1839
1840       errno = 0;
1841       abs_val = g_ascii_strtoull (token, &end, 0);
1842       if (abs_val == G_MAXUINT64 && errno == ERANGE)
1843         {
1844           ast_set_error (ast, error, NULL,
1845                          G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG,
1846                          "integer too big for any type");
1847           return NULL;
1848         }
1849
1850       if (abs_val == 0)
1851         negative = FALSE;
1852
1853       /* silence uninitialised warning... */
1854       dbl_val = 0.0;
1855     }
1856
1857   if (*end != '\0')
1858     {
1859       SourceRef ref;
1860
1861       ref = ast->source_ref;
1862       ref.start += end - number->token;
1863       ref.end = ref.start + 1;
1864
1865       parser_set_error (error, &ref, NULL,
1866                         G_VARIANT_PARSE_ERROR_INVALID_CHARACTER,
1867                         "invalid character in number");
1868       return NULL;
1869      }
1870
1871   if (floating)
1872     return g_variant_new_double (dbl_val);
1873
1874   switch (*g_variant_type_peek_string (type))
1875     {
1876     case 'y':
1877       if (negative || abs_val > G_MAXUINT8)
1878         return number_overflow (ast, type, error);
1879       return g_variant_new_byte (abs_val);
1880
1881     case 'n':
1882       if (abs_val - negative > G_MAXINT16)
1883         return number_overflow (ast, type, error);
1884       return g_variant_new_int16 (negative ? -abs_val : abs_val);
1885
1886     case 'q':
1887       if (negative || abs_val > G_MAXUINT16)
1888         return number_overflow (ast, type, error);
1889       return g_variant_new_uint16 (negative ? -abs_val : abs_val);
1890
1891     case 'i':
1892       if (abs_val - negative > G_MAXINT32)
1893         return number_overflow (ast, type, error);
1894       return g_variant_new_int32 (negative ? -abs_val : abs_val);
1895
1896     case 'u':
1897       if (negative || abs_val > G_MAXUINT32)
1898         return number_overflow (ast, type, error);
1899       return g_variant_new_uint32 (negative ? -abs_val : abs_val);
1900
1901     case 'x':
1902       if (abs_val - negative > G_MAXINT64)
1903         return number_overflow (ast, type, error);
1904       return g_variant_new_int64 (negative ? -abs_val : abs_val);
1905
1906     case 't':
1907       if (negative)
1908         return number_overflow (ast, type, error);
1909       return g_variant_new_uint64 (negative ? -abs_val : abs_val);
1910
1911     case 'h':
1912       if (abs_val - negative > G_MAXINT32)
1913         return number_overflow (ast, type, error);
1914       return g_variant_new_handle (negative ? -abs_val : abs_val);
1915
1916     default:
1917       return ast_type_error (ast, type, error);
1918     }
1919 }
1920
1921 static void
1922 number_free (AST *ast)
1923 {
1924   Number *number = (Number *) ast;
1925
1926   g_free (number->token);
1927   g_slice_free (Number, number);
1928 }
1929
1930 static AST *
1931 number_parse (TokenStream  *stream,
1932               va_list      *app,
1933               GError      **error)
1934 {
1935   static const ASTClass number_class = {
1936     number_get_pattern,
1937     maybe_wrapper, number_get_value,
1938     number_free
1939   };
1940   Number *number;
1941
1942   number = g_slice_new (Number);
1943   number->ast.class = &number_class;
1944   number->token = token_stream_get (stream);
1945   token_stream_next (stream);
1946
1947   return (AST *) number;
1948 }
1949
1950 typedef struct
1951 {
1952   AST ast;
1953   gboolean value;
1954 } Boolean;
1955
1956 static gchar *
1957 boolean_get_pattern (AST     *ast,
1958                      GError **error)
1959 {
1960   return g_strdup ("Mb");
1961 }
1962
1963 static GVariant *
1964 boolean_get_value (AST                 *ast,
1965                    const GVariantType  *type,
1966                    GError             **error)
1967 {
1968   Boolean *boolean = (Boolean *) ast;
1969
1970   if (!g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
1971     return ast_type_error (ast, type, error);
1972
1973   return g_variant_new_boolean (boolean->value);
1974 }
1975
1976 static void
1977 boolean_free (AST *ast)
1978 {
1979   Boolean *boolean = (Boolean *) ast;
1980
1981   g_slice_free (Boolean, boolean);
1982 }
1983
1984 static AST *
1985 boolean_new (gboolean value)
1986 {
1987   static const ASTClass boolean_class = {
1988     boolean_get_pattern,
1989     maybe_wrapper, boolean_get_value,
1990     boolean_free
1991   };
1992   Boolean *boolean;
1993
1994   boolean = g_slice_new (Boolean);
1995   boolean->ast.class = &boolean_class;
1996   boolean->value = value;
1997
1998   return (AST *) boolean;
1999 }
2000
2001 typedef struct
2002 {
2003   AST ast;
2004
2005   GVariant *value;
2006 } Positional;
2007
2008 static gchar *
2009 positional_get_pattern (AST     *ast,
2010                         GError **error)
2011 {
2012   Positional *positional = (Positional *) ast;
2013
2014   return g_strdup (g_variant_get_type_string (positional->value));
2015 }
2016
2017 static GVariant *
2018 positional_get_value (AST                 *ast,
2019                       const GVariantType  *type,
2020                       GError             **error)
2021 {
2022   Positional *positional = (Positional *) ast;
2023   GVariant *value;
2024
2025   g_assert (positional->value != NULL);
2026
2027   if G_UNLIKELY (!g_variant_is_of_type (positional->value, type))
2028     return ast_type_error (ast, type, error);
2029
2030   /* NOTE: if _get is called more than once then
2031    * things get messed up with respect to floating refs.
2032    *
2033    * fortunately, this function should only ever get called once.
2034    */
2035   g_assert (positional->value != NULL);
2036   value = positional->value;
2037   positional->value = NULL;
2038
2039   return value;
2040 }
2041
2042 static void
2043 positional_free (AST *ast)
2044 {
2045   Positional *positional = (Positional *) ast;
2046
2047   /* if positional->value is set, just leave it.
2048    * memory management doesn't matter in case of programmer error.
2049    */
2050   g_slice_free (Positional, positional);
2051 }
2052
2053 static AST *
2054 positional_parse (TokenStream  *stream,
2055                   va_list      *app,
2056                   GError      **error)
2057 {
2058   static const ASTClass positional_class = {
2059     positional_get_pattern,
2060     positional_get_value, NULL,
2061     positional_free
2062   };
2063   Positional *positional;
2064   const gchar *endptr;
2065   gchar *token;
2066
2067   token = token_stream_get (stream);
2068   g_assert (token[0] == '%');
2069
2070   positional = g_slice_new (Positional);
2071   positional->ast.class = &positional_class;
2072   positional->value = g_variant_new_va (token + 1, &endptr, app);
2073
2074   if (*endptr || positional->value == NULL)
2075     {
2076       token_stream_set_error (stream, error, TRUE,
2077                               G_VARIANT_PARSE_ERROR_INVALID_FORMAT_STRING,
2078                               "invalid GVariant format string");
2079       /* memory management doesn't matter in case of programmer error. */
2080       return NULL;
2081     }
2082
2083   token_stream_next (stream);
2084   g_free (token);
2085
2086   return (AST *) positional;
2087 }
2088
2089 typedef struct
2090 {
2091   AST ast;
2092
2093   GVariantType *type;
2094   AST *child;
2095 } TypeDecl;
2096
2097 static gchar *
2098 typedecl_get_pattern (AST     *ast,
2099                       GError **error)
2100 {
2101   TypeDecl *decl = (TypeDecl *) ast;
2102
2103   return g_variant_type_dup_string (decl->type);
2104 }
2105
2106 static GVariant *
2107 typedecl_get_value (AST                 *ast,
2108                     const GVariantType  *type,
2109                     GError             **error)
2110 {
2111   TypeDecl *decl = (TypeDecl *) ast;
2112
2113   return ast_get_value (decl->child, type, error);
2114 }
2115
2116 static void
2117 typedecl_free (AST *ast)
2118 {
2119   TypeDecl *decl = (TypeDecl *) ast;
2120
2121   ast_free (decl->child);
2122   g_variant_type_free (decl->type);
2123   g_slice_free (TypeDecl, decl);
2124 }
2125
2126 static AST *
2127 typedecl_parse (TokenStream  *stream,
2128                 va_list      *app,
2129                 GError      **error)
2130 {
2131   static const ASTClass typedecl_class = {
2132     typedecl_get_pattern,
2133     typedecl_get_value, NULL,
2134     typedecl_free
2135   };
2136   GVariantType *type;
2137   TypeDecl *decl;
2138   AST *child;
2139
2140   if (token_stream_peek (stream, '@'))
2141     {
2142       gchar *token;
2143
2144       token = token_stream_get (stream);
2145
2146       if (!g_variant_type_string_is_valid (token + 1))
2147         {
2148           token_stream_set_error (stream, error, TRUE,
2149                                   G_VARIANT_PARSE_ERROR_INVALID_TYPE_STRING,
2150                                   "invalid type declaration");
2151           g_free (token);
2152
2153           return NULL;
2154         }
2155
2156       type = g_variant_type_new (token + 1);
2157
2158       if (!g_variant_type_is_definite (type))
2159         {
2160           token_stream_set_error (stream, error, TRUE,
2161                                   G_VARIANT_PARSE_ERROR_DEFINITE_TYPE_EXPECTED,
2162                                   "type declarations must be definite");
2163           g_variant_type_free (type);
2164           g_free (token);
2165
2166           return NULL;
2167         }
2168
2169       token_stream_next (stream);
2170       g_free (token);
2171     }
2172   else
2173     {
2174       if (token_stream_consume (stream, "boolean"))
2175         type = g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
2176
2177       else if (token_stream_consume (stream, "byte"))
2178         type = g_variant_type_copy (G_VARIANT_TYPE_BYTE);
2179
2180       else if (token_stream_consume (stream, "int16"))
2181         type = g_variant_type_copy (G_VARIANT_TYPE_INT16);
2182
2183       else if (token_stream_consume (stream, "uint16"))
2184         type = g_variant_type_copy (G_VARIANT_TYPE_UINT16);
2185
2186       else if (token_stream_consume (stream, "int32"))
2187         type = g_variant_type_copy (G_VARIANT_TYPE_INT32);
2188
2189       else if (token_stream_consume (stream, "handle"))
2190         type = g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
2191
2192       else if (token_stream_consume (stream, "uint32"))
2193         type = g_variant_type_copy (G_VARIANT_TYPE_UINT32);
2194
2195       else if (token_stream_consume (stream, "int64"))
2196         type = g_variant_type_copy (G_VARIANT_TYPE_INT64);
2197
2198       else if (token_stream_consume (stream, "uint64"))
2199         type = g_variant_type_copy (G_VARIANT_TYPE_UINT64);
2200
2201       else if (token_stream_consume (stream, "double"))
2202         type = g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
2203
2204       else if (token_stream_consume (stream, "string"))
2205         type = g_variant_type_copy (G_VARIANT_TYPE_STRING);
2206
2207       else if (token_stream_consume (stream, "objectpath"))
2208         type = g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
2209
2210       else if (token_stream_consume (stream, "signature"))
2211         type = g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
2212
2213       else
2214         {
2215           token_stream_set_error (stream, error, TRUE,
2216                                   G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD,
2217                                   "unknown keyword");
2218           return NULL;
2219         }
2220     }
2221
2222   if ((child = parse (stream, app, error)) == NULL)
2223     {
2224       g_variant_type_free (type);
2225       return NULL;
2226     }
2227
2228   decl = g_slice_new (TypeDecl);
2229   decl->ast.class = &typedecl_class;
2230   decl->type = type;
2231   decl->child = child;
2232
2233   return (AST *) decl;
2234 }
2235
2236 static AST *
2237 parse (TokenStream  *stream,
2238        va_list      *app,
2239        GError      **error)
2240 {
2241   SourceRef source_ref;
2242   AST *result;
2243
2244   token_stream_prepare (stream);
2245   token_stream_start_ref (stream, &source_ref);
2246
2247   if (token_stream_peek (stream, '['))
2248     result = array_parse (stream, app, error);
2249
2250   else if (token_stream_peek (stream, '('))
2251     result = tuple_parse (stream, app, error);
2252
2253   else if (token_stream_peek (stream, '<'))
2254     result = variant_parse (stream, app, error);
2255
2256   else if (token_stream_peek (stream, '{'))
2257     result = dictionary_parse (stream, app, error);
2258
2259   else if (app && token_stream_peek (stream, '%'))
2260     result = positional_parse (stream, app, error);
2261
2262   else if (token_stream_consume (stream, "true"))
2263     result = boolean_new (TRUE);
2264
2265   else if (token_stream_consume (stream, "false"))
2266     result = boolean_new (FALSE);
2267
2268   else if (token_stream_is_numeric (stream) ||
2269            token_stream_peek_string (stream, "inf") ||
2270            token_stream_peek_string (stream, "nan"))
2271     result = number_parse (stream, app, error);
2272
2273   else if (token_stream_peek (stream, 'n') ||
2274            token_stream_peek (stream, 'j'))
2275     result = maybe_parse (stream, app, error);
2276
2277   else if (token_stream_peek (stream, '@') ||
2278            token_stream_is_keyword (stream))
2279     result = typedecl_parse (stream, app, error);
2280
2281   else if (token_stream_peek (stream, '\'') ||
2282            token_stream_peek (stream, '"'))
2283     result = string_parse (stream, app, error);
2284
2285   else if (token_stream_peek2 (stream, 'b', '\'') ||
2286            token_stream_peek2 (stream, 'b', '"'))
2287     result = bytestring_parse (stream, app, error);
2288
2289   else
2290     {
2291       token_stream_set_error (stream, error, FALSE,
2292                               G_VARIANT_PARSE_ERROR_VALUE_EXPECTED,
2293                               "expected value");
2294       return NULL;
2295     }
2296
2297   if (result != NULL)
2298     {
2299       token_stream_end_ref (stream, &source_ref);
2300       result->source_ref = source_ref;
2301     }
2302
2303   return result;
2304 }
2305
2306 /**
2307  * g_variant_parse:
2308  * @type: a #GVariantType, or %NULL
2309  * @text: a string containing a GVariant in text form
2310  * @limit: a pointer to the end of @text, or %NULL
2311  * @endptr: a location to store the end pointer, or %NULL
2312  * @error: a pointer to a %NULL #GError pointer, or %NULL
2313  * @Returns: a reference to a #GVariant, or %NULL
2314  *
2315  * Parses a #GVariant from a text representation.
2316  *
2317  * A single #GVariant is parsed from the content of @text.
2318  *
2319  * The format is described <link linkend='gvariant-text'>here</link>.
2320  *
2321  * The memory at @limit will never be accessed and the parser behaves as
2322  * if the character at @limit is the nul terminator.  This has the
2323  * effect of bounding @text.
2324  *
2325  * If @endptr is non-%NULL then @text is permitted to contain data
2326  * following the value that this function parses and @endptr will be
2327  * updated to point to the first character past the end of the text
2328  * parsed by this function.  If @endptr is %NULL and there is extra data
2329  * then an error is returned.
2330  *
2331  * If @type is non-%NULL then the value will be parsed to have that
2332  * type.  This may result in additional parse errors (in the case that
2333  * the parsed value doesn't fit the type) but may also result in fewer
2334  * errors (in the case that the type would have been ambiguous, such as
2335  * with empty arrays).
2336  *
2337  * In the event that the parsing is successful, the resulting #GVariant
2338  * is returned.
2339  *
2340  * In case of any error, %NULL will be returned.  If @error is non-%NULL
2341  * then it will be set to reflect the error that occured.
2342  *
2343  * Officially, the language understood by the parser is "any string
2344  * produced by g_variant_print()".
2345  **/
2346 GVariant *
2347 g_variant_parse (const GVariantType  *type,
2348                  const gchar         *text,
2349                  const gchar         *limit,
2350                  const gchar        **endptr,
2351                  GError             **error)
2352 {
2353   TokenStream stream = { 0, };
2354   GVariant *result = NULL;
2355   AST *ast;
2356
2357   g_return_val_if_fail (text != NULL, NULL);
2358   g_return_val_if_fail (text == limit || text != NULL, NULL);
2359
2360   stream.start = text;
2361   stream.stream = text;
2362   stream.end = limit;
2363
2364   if ((ast = parse (&stream, NULL, error)))
2365     {
2366       if (type == NULL)
2367         result = ast_resolve (ast, error);
2368       else
2369         result = ast_get_value (ast, type, error);
2370
2371       if (result != NULL)
2372         {
2373           g_variant_ref_sink (result);
2374
2375           if (endptr == NULL)
2376             {
2377               while (stream.stream != limit &&
2378                      g_ascii_isspace (*stream.stream))
2379                 stream.stream++;
2380
2381               if (stream.stream != limit && *stream.stream != '\0')
2382                 {
2383                   SourceRef ref = { stream.stream - text,
2384                                     stream.stream - text };
2385
2386                   parser_set_error (error, &ref, NULL,
2387                                     G_VARIANT_PARSE_ERROR_INPUT_NOT_AT_END,
2388                                     "expected end of input");
2389                   g_variant_unref (result);
2390
2391                   result = NULL;
2392                 }
2393             }
2394           else
2395             *endptr = stream.stream;
2396         }
2397
2398       ast_free (ast);
2399     }
2400
2401   return result;
2402 }
2403
2404 /**
2405  * g_variant_new_parsed_va:
2406  * @format: a text format #GVariant
2407  * @app: a pointer to a #va_list
2408  * @returns: a new, usually floating, #GVariant
2409  *
2410  * Parses @format and returns the result.
2411  *
2412  * This is the version of g_variant_new_parsed() intended to be used
2413  * from libraries.
2414  *
2415  * The return value will be floating if it was a newly created GVariant
2416  * instance.  In the case that @format simply specified the collection
2417  * of a #GVariant pointer (eg: @format was "%*") then the collected
2418  * #GVariant pointer will be returned unmodified, without adding any
2419  * additional references.
2420  *
2421  * In order to behave correctly in all cases it is necessary for the
2422  * calling function to g_variant_ref_sink() the return result before
2423  * returning control to the user that originally provided the pointer.
2424  * At this point, the caller will have their own full reference to the
2425  * result.  This can also be done by adding the result to a container,
2426  * or by passing it to another g_variant_new() call.
2427  **/
2428 GVariant *
2429 g_variant_new_parsed_va (const gchar *format,
2430                          va_list     *app)
2431 {
2432   TokenStream stream = { 0, };
2433   GVariant *result = NULL;
2434   GError *error = NULL;
2435   AST *ast;
2436
2437   g_return_val_if_fail (format != NULL, NULL);
2438   g_return_val_if_fail (app != NULL, NULL);
2439
2440   stream.start = format;
2441   stream.stream = format;
2442   stream.end = NULL;
2443
2444   if ((ast = parse (&stream, app, &error)))
2445     {
2446       result = ast_resolve (ast, &error);
2447       ast_free (ast);
2448     }
2449
2450   if (result == NULL)
2451     g_error ("g_variant_new_parsed: %s", error->message);
2452
2453   if (*stream.stream)
2454     g_error ("g_variant_new_parsed: trailing text after value");
2455
2456   return result;
2457 }
2458
2459 /**
2460  * g_variant_new_parsed:
2461  * @format: a text format #GVariant
2462  * @...: arguments as per @format
2463  * @returns: a new floating #GVariant instance
2464  *
2465  * Parses @format and returns the result.
2466  *
2467  * @format must be a text format #GVariant with one extension: at any
2468  * point that a value may appear in the text, a '%' character followed
2469  * by a GVariant format string (as per g_variant_new()) may appear.  In
2470  * that case, the same arguments are collected from the argument list as
2471  * g_variant_new() would have collected.
2472  *
2473  * Consider this simple example:
2474  *
2475  * <informalexample><programlisting>
2476  *  g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three");
2477  * </programlisting></informalexample>
2478  *
2479  * In the example, the variable argument parameters are collected and
2480  * filled in as if they were part of the original string to produce the
2481  * result of <code>[('one', 1), ('two', 2), ('three', 3)]</code>.
2482  *
2483  * This function is intended only to be used with @format as a string
2484  * literal.  Any parse error is fatal to the calling process.  If you
2485  * want to parse data from untrusted sources, use g_variant_parse().
2486  *
2487  * You may not use this function to return, unmodified, a single
2488  * #GVariant pointer from the argument list.  ie: @format may not solely
2489  * be anything along the lines of "%*", "%?", "%r", or anything starting
2490  * with "%@".
2491  **/
2492 GVariant *
2493 g_variant_new_parsed (const gchar *format,
2494                       ...)
2495 {
2496   GVariant *result;
2497   va_list ap;
2498
2499   va_start (ap, format);
2500   result = g_variant_new_parsed_va (format, &ap);
2501   va_end (ap);
2502
2503   return result;
2504 }
2505
2506 /**
2507  * g_variant_builder_add_parsed:
2508  * @builder: a #GVariantBuilder
2509  * @format: a text format #GVariant
2510  * @...: arguments as per @format
2511  *
2512  * Adds to a #GVariantBuilder.
2513  *
2514  * This call is a convenience wrapper that is exactly equivalent to
2515  * calling g_variant_new_parsed() followed by
2516  * g_variant_builder_add_value().
2517  *
2518  * This function might be used as follows:
2519  *
2520  * <programlisting>
2521  * GVariant *
2522  * make_pointless_dictionary (void)
2523  * {
2524  *   GVariantBuilder *builder;
2525  *   int i;
2526  *
2527  *   builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
2528  *   g_variant_builder_add_parsed (builder, "{'width', <%i>}", 600);
2529  *   g_variant_builder_add_parsed (builder, "{'title', <%s>}", "foo");
2530  *   g_variant_builder_add_parsed (builder, "{'transparency', <0.5>}");
2531  *   return g_variant_builder_end (builder);
2532  * }
2533  * </programlisting>
2534  *
2535  * Since: 2.26
2536  **/
2537 void
2538 g_variant_builder_add_parsed (GVariantBuilder *builder,
2539                               const gchar     *format,
2540                               ...)
2541 {
2542   va_list ap;
2543
2544   va_start (ap, format);
2545   g_variant_builder_add_value (builder, g_variant_new_parsed_va (format, &ap));
2546   va_end (ap);
2547 }