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