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