PageRenderTime 69ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/glib-2.25.17/glib/gvariant-parser.c

https://bitbucket.org/ArminW/3p-glib
C | 2466 lines | 1814 code | 439 blank | 213 comment | 356 complexity | eb8e42bf952e76406c4f748c4b24863a MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  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. #include "config.h"
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <errno.h>
  25. #include "gerror.h"
  26. #include "gquark.h"
  27. #include "gstring.h"
  28. #include "gstrfuncs.h"
  29. #include "gtestutils.h"
  30. #include "gvariant.h"
  31. #include "gvarianttype.h"
  32. /*
  33. * two-pass algorithm
  34. * designed by ryan lortie and william hua
  35. * designed in itb-229 and at ghazi's, 2009.
  36. */
  37. /**
  38. * G_VARIANT_PARSE_ERROR:
  39. *
  40. * Error domain for GVariant text format parsing. Specific error codes
  41. * are not currently defined for this domain. See #GError for
  42. * information on error domains.
  43. **/
  44. /**
  45. * GVariantParseError:
  46. * @G_VARIANT_PARSE_ERROR_FAILED: generic error
  47. *
  48. * Error codes returned by parsing text-format GVariants. Currently the
  49. * parser makes no distinction between different types of error.
  50. **/
  51. GQuark
  52. g_variant_parser_get_error_quark (void)
  53. {
  54. static GQuark the_quark;
  55. if (the_quark == 0)
  56. the_quark = g_quark_from_static_string ("g-variant-parse-error-quark");
  57. return the_quark;
  58. }
  59. typedef struct
  60. {
  61. gint start, end;
  62. } SourceRef;
  63. static void
  64. parser_set_error_va (GError **error,
  65. SourceRef *location,
  66. SourceRef *other,
  67. const gchar *format,
  68. va_list ap)
  69. {
  70. GString *msg = g_string_new (NULL);
  71. if (location->start == location->end)
  72. g_string_append_printf (msg, "%d", location->start);
  73. else
  74. g_string_append_printf (msg, "%d-%d", location->start, location->end);
  75. if (other != NULL)
  76. {
  77. g_assert (other->start != other->end);
  78. g_string_append_printf (msg, ",%d-%d", other->start, other->end);
  79. }
  80. g_string_append_c (msg, ':');
  81. g_string_append_vprintf (msg, format, ap);
  82. g_set_error_literal (error, G_VARIANT_PARSE_ERROR, 0, msg->str);
  83. g_string_free (msg, TRUE);
  84. }
  85. static void
  86. parser_set_error (GError **error,
  87. SourceRef *location,
  88. SourceRef *other,
  89. const gchar *format,
  90. ...)
  91. {
  92. va_list ap;
  93. va_start (ap, format);
  94. parser_set_error_va (error, location, other, format, ap);
  95. va_end (ap);
  96. }
  97. typedef struct
  98. {
  99. const gchar *start;
  100. const gchar *stream;
  101. const gchar *end;
  102. const gchar *this;
  103. } TokenStream;
  104. static void
  105. token_stream_set_error (TokenStream *stream,
  106. GError **error,
  107. gboolean this_token,
  108. const gchar *format,
  109. ...)
  110. {
  111. SourceRef ref;
  112. va_list ap;
  113. ref.start = stream->this - stream->start;
  114. if (this_token)
  115. ref.end = stream->stream - stream->start;
  116. else
  117. ref.end = ref.start;
  118. va_start (ap, format);
  119. parser_set_error_va (error, &ref, NULL, format, ap);
  120. va_end (ap);
  121. }
  122. static void
  123. token_stream_prepare (TokenStream *stream)
  124. {
  125. gint brackets = 0;
  126. const gchar *end;
  127. if (stream->this != NULL)
  128. return;
  129. while (stream->stream != stream->end && g_ascii_isspace (*stream->stream))
  130. stream->stream++;
  131. if (stream->stream == stream->end || *stream->stream == '\0')
  132. {
  133. stream->this = stream->stream;
  134. return;
  135. }
  136. switch (stream->stream[0])
  137. {
  138. case '-': case '+': case '.': case '0': case '1': case '2':
  139. case '3': case '4': case '5': case '6': case '7': case '8':
  140. case '9':
  141. for (end = stream->stream; end != stream->end; end++)
  142. if (!g_ascii_isalnum (*end) &&
  143. *end != '-' && *end != '+' && *end != '.')
  144. break;
  145. break;
  146. case 'b':
  147. if (stream->stream[1] == '\'' || stream->stream[1] == '"')
  148. {
  149. for (end = stream->stream + 2; end != stream->end; end++)
  150. if (*end == stream->stream[1] || *end == '\0' ||
  151. (*end == '\\' && (++end == stream->end || *end == '\0')))
  152. break;
  153. if (end != stream->end && *end)
  154. end++;
  155. break;
  156. }
  157. else /* ↓↓↓ */;
  158. case 'a': /* 'b' */ case 'c': case 'd': case 'e': case 'f':
  159. case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
  160. case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
  161. case 's': case 't': case 'u': case 'v': case 'w': case 'x':
  162. case 'y': case 'z':
  163. for (end = stream->stream; end != stream->end; end++)
  164. if (!g_ascii_isalnum (*end))
  165. break;
  166. break;
  167. case '\'': case '"':
  168. for (end = stream->stream + 1; end != stream->end; end++)
  169. if (*end == stream->stream[0] || *end == '\0' ||
  170. (*end == '\\' && (++end == stream->end || *end == '\0')))
  171. break;
  172. if (end != stream->end && *end)
  173. end++;
  174. break;
  175. case '@': case '%':
  176. /* stop at the first space, comma, colon or unmatched bracket.
  177. * deals nicely with cases like (%i, %i) or {%i: %i}.
  178. */
  179. for (end = stream->stream + 1;
  180. end != stream->end && *end != ',' &&
  181. *end != ':' && *end != '>' && !g_ascii_isspace (*end);
  182. end++)
  183. if (*end == '(' || *end == '{')
  184. brackets++;
  185. else if ((*end == ')' || *end == '}') && !brackets--)
  186. break;
  187. break;
  188. default:
  189. end = stream->stream + 1;
  190. break;
  191. }
  192. stream->this = stream->stream;
  193. stream->stream = end;
  194. }
  195. static void
  196. token_stream_next (TokenStream *stream)
  197. {
  198. stream->this = NULL;
  199. }
  200. static gboolean
  201. token_stream_peek (TokenStream *stream,
  202. gchar first_char)
  203. {
  204. token_stream_prepare (stream);
  205. return stream->this[0] == first_char;
  206. }
  207. static gboolean
  208. token_stream_peek2 (TokenStream *stream,
  209. gchar first_char,
  210. gchar second_char)
  211. {
  212. token_stream_prepare (stream);
  213. return stream->this[0] == first_char &&
  214. stream->this[1] == second_char;
  215. }
  216. static gboolean
  217. token_stream_is_keyword (TokenStream *stream)
  218. {
  219. token_stream_prepare (stream);
  220. return g_ascii_isalpha (stream->this[0]) &&
  221. g_ascii_isalpha (stream->this[1]);
  222. }
  223. static gboolean
  224. token_stream_is_numeric (TokenStream *stream)
  225. {
  226. token_stream_prepare (stream);
  227. return (g_ascii_isdigit (stream->this[0]) ||
  228. stream->this[0] == '-' ||
  229. stream->this[0] == '+' ||
  230. stream->this[0] == '.');
  231. }
  232. static gboolean
  233. token_stream_consume (TokenStream *stream,
  234. const gchar *token)
  235. {
  236. gint length = strlen (token);
  237. token_stream_prepare (stream);
  238. if (stream->stream - stream->this == length &&
  239. memcmp (stream->this, token, length) == 0)
  240. {
  241. token_stream_next (stream);
  242. return TRUE;
  243. }
  244. return FALSE;
  245. }
  246. static gboolean
  247. token_stream_require (TokenStream *stream,
  248. const gchar *token,
  249. const gchar *purpose,
  250. GError **error)
  251. {
  252. if (!token_stream_consume (stream, token))
  253. {
  254. token_stream_set_error (stream, error, FALSE,
  255. "expected `%s'%s", token, purpose);
  256. return FALSE;
  257. }
  258. return TRUE;
  259. }
  260. static void
  261. token_stream_assert (TokenStream *stream,
  262. const gchar *token)
  263. {
  264. gboolean correct_token;
  265. correct_token = token_stream_consume (stream, token);
  266. g_assert (correct_token);
  267. }
  268. static gchar *
  269. token_stream_get (TokenStream *stream)
  270. {
  271. gchar *result;
  272. token_stream_prepare (stream);
  273. result = g_strndup (stream->this, stream->stream - stream->this);
  274. return result;
  275. }
  276. static void
  277. token_stream_start_ref (TokenStream *stream,
  278. SourceRef *ref)
  279. {
  280. token_stream_prepare (stream);
  281. ref->start = stream->this - stream->start;
  282. }
  283. static void
  284. token_stream_end_ref (TokenStream *stream,
  285. SourceRef *ref)
  286. {
  287. ref->end = stream->stream - stream->start;
  288. }
  289. void
  290. pattern_copy (gchar **out,
  291. const gchar **in)
  292. {
  293. gint brackets = 0;
  294. while (**in == 'a' || **in == 'm' || **in == 'M')
  295. *(*out)++ = *(*in)++;
  296. do
  297. {
  298. if (**in == '(' || **in == '{')
  299. brackets++;
  300. else if (**in == ')' || **in == '}')
  301. brackets--;
  302. *(*out)++ = *(*in)++;
  303. }
  304. while (brackets);
  305. }
  306. static gchar *
  307. pattern_coalesce (const gchar *left,
  308. const gchar *right)
  309. {
  310. gchar *result;
  311. gchar *out;
  312. /* the length of the output is loosely bound by the sum of the input
  313. * lengths, not simply the greater of the two lengths.
  314. *
  315. * (*(iii)) + ((iii)*) ((iii)(iii))
  316. *
  317. * 8 + 8 = 12
  318. */
  319. out = result = g_malloc (strlen (left) + strlen (right));
  320. while (*left && *right)
  321. {
  322. if (*left == *right)
  323. {
  324. *out++ = *left++;
  325. right++;
  326. }
  327. else
  328. {
  329. const gchar **one = &left, **the_other = &right;
  330. again:
  331. if (**one == '*' && **the_other != ')')
  332. {
  333. pattern_copy (&out, the_other);
  334. (*one)++;
  335. }
  336. else if (**one == 'M' && **the_other == 'm')
  337. {
  338. *out++ = *(*the_other)++;
  339. }
  340. else if (**one == 'M' && **the_other != 'm')
  341. {
  342. (*one)++;
  343. }
  344. else if (**one == 'N' && strchr ("ynqiuxthd", **the_other))
  345. {
  346. *out++ = *(*the_other)++;
  347. (*one)++;
  348. }
  349. else if (**one == 'S' && strchr ("sog", **the_other))
  350. {
  351. *out++ = *(*the_other)++;
  352. (*one)++;
  353. }
  354. else if (one == &left)
  355. {
  356. one = &right, the_other = &left;
  357. goto again;
  358. }
  359. else
  360. break;
  361. }
  362. }
  363. if (*left || *right)
  364. {
  365. g_free (result);
  366. result = NULL;
  367. }
  368. else
  369. *out++ = '\0';
  370. return result;
  371. }
  372. typedef struct _AST AST;
  373. typedef gchar * (*get_pattern_func) (AST *ast,
  374. GError **error);
  375. typedef GVariant * (*get_value_func) (AST *ast,
  376. const GVariantType *type,
  377. GError **error);
  378. typedef GVariant * (*get_base_value_func) (AST *ast,
  379. const GVariantType *type,
  380. GError **error);
  381. typedef void (*free_func) (AST *ast);
  382. typedef struct
  383. {
  384. gchar * (* get_pattern) (AST *ast,
  385. GError **error);
  386. GVariant * (* get_value) (AST *ast,
  387. const GVariantType *type,
  388. GError **error);
  389. GVariant * (* get_base_value) (AST *ast,
  390. const GVariantType *type,
  391. GError **error);
  392. void (* free) (AST *ast);
  393. } ASTClass;
  394. struct _AST
  395. {
  396. const ASTClass *class;
  397. SourceRef source_ref;
  398. };
  399. static gchar *
  400. ast_get_pattern (AST *ast,
  401. GError **error)
  402. {
  403. return ast->class->get_pattern (ast, error);
  404. }
  405. static GVariant *
  406. ast_get_value (AST *ast,
  407. const GVariantType *type,
  408. GError **error)
  409. {
  410. return ast->class->get_value (ast, type, error);
  411. }
  412. static void
  413. ast_free (AST *ast)
  414. {
  415. ast->class->free (ast);
  416. }
  417. static void
  418. ast_set_error (AST *ast,
  419. GError **error,
  420. AST *other_ast,
  421. const gchar *format,
  422. ...)
  423. {
  424. va_list ap;
  425. va_start (ap, format);
  426. parser_set_error_va (error, &ast->source_ref,
  427. other_ast ? & other_ast->source_ref : NULL,
  428. format, ap);
  429. va_end (ap);
  430. }
  431. static GVariant *
  432. ast_type_error (AST *ast,
  433. const GVariantType *type,
  434. GError **error)
  435. {
  436. gchar *typestr;
  437. typestr = g_variant_type_dup_string (type);
  438. ast_set_error (ast, error, NULL,
  439. "can not parse as value of type `%s'",
  440. typestr);
  441. g_free (typestr);
  442. return NULL;
  443. }
  444. static GVariant *
  445. ast_resolve (AST *ast,
  446. GError **error)
  447. {
  448. GVariant *value;
  449. gchar *pattern;
  450. gint i, j = 0;
  451. pattern = ast_get_pattern (ast, error);
  452. if (pattern == NULL)
  453. return NULL;
  454. /* choose reasonable defaults
  455. *
  456. * 1) favour non-maybe values where possible
  457. * 2) default type for strings is 's'
  458. * 3) default type for integers is 'i'
  459. */
  460. for (i = 0; pattern[i]; i++)
  461. switch (pattern[i])
  462. {
  463. case '*':
  464. ast_set_error (ast, error, NULL, "unable to infer type");
  465. g_free (pattern);
  466. return NULL;
  467. case 'M':
  468. break;
  469. case 'S':
  470. pattern[j++] = 's';
  471. break;
  472. case 'N':
  473. pattern[j++] = 'i';
  474. break;
  475. default:
  476. pattern[j++] = pattern[i];
  477. break;
  478. }
  479. pattern[j++] = '\0';
  480. value = ast_get_value (ast, G_VARIANT_TYPE (pattern), error);
  481. g_free (pattern);
  482. return value;
  483. }
  484. static AST *parse (TokenStream *stream,
  485. va_list *app,
  486. GError **error);
  487. static void
  488. ast_array_append (AST ***array,
  489. gint *n_items,
  490. AST *ast)
  491. {
  492. if ((*n_items & (*n_items - 1)) == 0)
  493. *array = g_renew (AST *, *array, *n_items ? 2 ** n_items : 1);
  494. (*array)[(*n_items)++] = ast;
  495. }
  496. static void
  497. ast_array_free (AST **array,
  498. gint n_items)
  499. {
  500. gint i;
  501. for (i = 0; i < n_items; i++)
  502. ast_free (array[i]);
  503. g_free (array);
  504. }
  505. static gchar *
  506. ast_array_get_pattern (AST **array,
  507. gint n_items,
  508. GError **error)
  509. {
  510. gchar *pattern;
  511. gint i;
  512. pattern = ast_get_pattern (array[0], error);
  513. if (pattern == NULL)
  514. return NULL;
  515. for (i = 1; i < n_items; i++)
  516. {
  517. gchar *tmp, *merged;
  518. tmp = ast_get_pattern (array[i], error);
  519. if (tmp == NULL)
  520. {
  521. g_free (pattern);
  522. return NULL;
  523. }
  524. merged = pattern_coalesce (pattern, tmp);
  525. g_free (pattern);
  526. pattern = merged;
  527. if (merged == NULL)
  528. /* set coalescence implies pairwise coalescence (i think).
  529. * we should therefore be able to trace the failure to a single
  530. * pair of values.
  531. */
  532. {
  533. int j = 0;
  534. while (TRUE)
  535. {
  536. gchar *tmp2;
  537. gchar *m;
  538. /* if 'j' reaches 'i' then we failed to find the pair */
  539. g_assert (j < i);
  540. tmp2 = ast_get_pattern (array[j], NULL);
  541. g_assert (tmp2 != NULL);
  542. m = pattern_coalesce (tmp, tmp2);
  543. g_free (tmp2);
  544. g_free (m);
  545. if (m == NULL)
  546. {
  547. /* we found a conflict between 'i' and 'j'.
  548. *
  549. * report the error. note: 'j' is first.
  550. */
  551. ast_set_error (array[j], error, array[i],
  552. "unable to find a common type");
  553. g_free (tmp);
  554. return NULL;
  555. }
  556. j++;
  557. }
  558. }
  559. g_free (tmp);
  560. }
  561. return pattern;
  562. }
  563. typedef struct
  564. {
  565. AST ast;
  566. AST *child;
  567. } Maybe;
  568. static gchar *
  569. maybe_get_pattern (AST *ast,
  570. GError **error)
  571. {
  572. Maybe *maybe = (Maybe *) ast;
  573. if (maybe->child != NULL)
  574. {
  575. gchar *child_pattern;
  576. gchar *pattern;
  577. child_pattern = ast_get_pattern (maybe->child, error);
  578. if (child_pattern == NULL)
  579. return NULL;
  580. pattern = g_strdup_printf ("m%s", child_pattern);
  581. g_free (child_pattern);
  582. return pattern;
  583. }
  584. return g_strdup ("m*");
  585. }
  586. static GVariant *
  587. maybe_get_value (AST *ast,
  588. const GVariantType *type,
  589. GError **error)
  590. {
  591. Maybe *maybe = (Maybe *) ast;
  592. GVariant *value;
  593. if (!g_variant_type_is_maybe (type))
  594. return ast_type_error (ast, type, error);
  595. type = g_variant_type_element (type);
  596. if (maybe->child)
  597. {
  598. value = ast_get_value (maybe->child, type, error);
  599. if (value == NULL)
  600. return NULL;
  601. }
  602. else
  603. value = NULL;
  604. return g_variant_new_maybe (type, value);
  605. }
  606. static void
  607. maybe_free (AST *ast)
  608. {
  609. Maybe *maybe = (Maybe *) ast;
  610. if (maybe->child != NULL)
  611. ast_free (maybe->child);
  612. g_slice_free (Maybe, maybe);
  613. }
  614. static AST *
  615. maybe_parse (TokenStream *stream,
  616. va_list *app,
  617. GError **error)
  618. {
  619. static const ASTClass maybe_class = {
  620. maybe_get_pattern,
  621. maybe_get_value, NULL,
  622. maybe_free
  623. };
  624. AST *child = NULL;
  625. Maybe *maybe;
  626. if (token_stream_consume (stream, "just"))
  627. {
  628. child = parse (stream, app, error);
  629. if (child == NULL)
  630. return NULL;
  631. }
  632. else if (!token_stream_consume (stream, "nothing"))
  633. {
  634. token_stream_set_error (stream, error, TRUE, "unknown keyword");
  635. return NULL;
  636. }
  637. maybe = g_slice_new (Maybe);
  638. maybe->ast.class = &maybe_class;
  639. maybe->child = child;
  640. return (AST *) maybe;
  641. }
  642. static GVariant *
  643. maybe_wrapper (AST *ast,
  644. const GVariantType *type,
  645. GError **error)
  646. {
  647. const GVariantType *t;
  648. GVariant *value;
  649. int depth;
  650. for (depth = 0, t = type;
  651. g_variant_type_is_maybe (t);
  652. depth++, t = g_variant_type_element (t));
  653. value = ast->class->get_base_value (ast, t, error);
  654. if (value == NULL)
  655. return NULL;
  656. while (depth--)
  657. value = g_variant_new_maybe (NULL, value);
  658. return value;
  659. }
  660. typedef struct
  661. {
  662. AST ast;
  663. AST **children;
  664. gint n_children;
  665. } Array;
  666. static gchar *
  667. array_get_pattern (AST *ast,
  668. GError **error)
  669. {
  670. Array *array = (Array *) ast;
  671. gchar *pattern;
  672. gchar *result;
  673. if (array->n_children == 0)
  674. return g_strdup ("Ma*");
  675. pattern = ast_array_get_pattern (array->children, array->n_children, error);
  676. if (pattern == NULL)
  677. return NULL;
  678. result = g_strdup_printf ("Ma%s", pattern);
  679. g_free (pattern);
  680. return result;
  681. }
  682. static GVariant *
  683. array_get_value (AST *ast,
  684. const GVariantType *type,
  685. GError **error)
  686. {
  687. Array *array = (Array *) ast;
  688. const GVariantType *childtype;
  689. GVariantBuilder builder;
  690. gint i;
  691. if (!g_variant_type_is_array (type))
  692. return ast_type_error (ast, type, error);
  693. g_variant_builder_init (&builder, type);
  694. childtype = g_variant_type_element (type);
  695. for (i = 0; i < array->n_children; i++)
  696. {
  697. GVariant *child;
  698. if (!(child = ast_get_value (array->children[i], childtype, error)))
  699. {
  700. g_variant_builder_clear (&builder);
  701. return NULL;
  702. }
  703. g_variant_builder_add_value (&builder, child);
  704. }
  705. return g_variant_builder_end (&builder);
  706. }
  707. static void
  708. array_free (AST *ast)
  709. {
  710. Array *array = (Array *) ast;
  711. ast_array_free (array->children, array->n_children);
  712. g_slice_free (Array, array);
  713. }
  714. static AST *
  715. array_parse (TokenStream *stream,
  716. va_list *app,
  717. GError **error)
  718. {
  719. static const ASTClass array_class = {
  720. array_get_pattern,
  721. maybe_wrapper, array_get_value,
  722. array_free
  723. };
  724. gboolean need_comma = FALSE;
  725. Array *array;
  726. array = g_slice_new (Array);
  727. array->ast.class = &array_class;
  728. array->children = NULL;
  729. array->n_children = 0;
  730. token_stream_assert (stream, "[");
  731. while (!token_stream_consume (stream, "]"))
  732. {
  733. AST *child;
  734. if (need_comma &&
  735. !token_stream_require (stream, ",",
  736. " or `]' to follow array element",
  737. error))
  738. goto error;
  739. child = parse (stream, app, error);
  740. if (!child)
  741. goto error;
  742. ast_array_append (&array->children, &array->n_children, child);
  743. need_comma = TRUE;
  744. }
  745. return (AST *) array;
  746. error:
  747. ast_array_free (array->children, array->n_children);
  748. g_slice_free (Array, array);
  749. return NULL;
  750. }
  751. typedef struct
  752. {
  753. AST ast;
  754. AST **children;
  755. gint n_children;
  756. } Tuple;
  757. static gchar *
  758. tuple_get_pattern (AST *ast,
  759. GError **error)
  760. {
  761. Tuple *tuple = (Tuple *) ast;
  762. gchar *result = NULL;
  763. gchar **parts;
  764. gint i;
  765. parts = g_new (gchar *, tuple->n_children + 4);
  766. parts[tuple->n_children + 1] = (gchar *) ")";
  767. parts[tuple->n_children + 2] = NULL;
  768. parts[0] = (gchar *) "M(";
  769. for (i = 0; i < tuple->n_children; i++)
  770. if (!(parts[i + 1] = ast_get_pattern (tuple->children[i], error)))
  771. break;
  772. if (i == tuple->n_children)
  773. result = g_strjoinv ("", parts);
  774. /* parts[0] should not be freed */
  775. while (i)
  776. g_free (parts[i--]);
  777. g_free (parts);
  778. return result;
  779. }
  780. static GVariant *
  781. tuple_get_value (AST *ast,
  782. const GVariantType *type,
  783. GError **error)
  784. {
  785. Tuple *tuple = (Tuple *) ast;
  786. const GVariantType *childtype;
  787. GVariantBuilder builder;
  788. gint i;
  789. if (!g_variant_type_is_tuple (type))
  790. return ast_type_error (ast, type, error);
  791. g_variant_builder_init (&builder, type);
  792. childtype = g_variant_type_first (type);
  793. for (i = 0; i < tuple->n_children; i++)
  794. {
  795. GVariant *child;
  796. if (!(child = ast_get_value (tuple->children[i], childtype, error)))
  797. {
  798. g_variant_builder_clear (&builder);
  799. return FALSE;
  800. }
  801. g_variant_builder_add_value (&builder, child);
  802. childtype = g_variant_type_next (childtype);
  803. }
  804. return g_variant_builder_end (&builder);
  805. }
  806. static void
  807. tuple_free (AST *ast)
  808. {
  809. Tuple *tuple = (Tuple *) ast;
  810. ast_array_free (tuple->children, tuple->n_children);
  811. g_slice_free (Tuple, tuple);
  812. }
  813. static AST *
  814. tuple_parse (TokenStream *stream,
  815. va_list *app,
  816. GError **error)
  817. {
  818. static const ASTClass tuple_class = {
  819. tuple_get_pattern,
  820. maybe_wrapper, tuple_get_value,
  821. tuple_free
  822. };
  823. gboolean need_comma = FALSE;
  824. gboolean first = TRUE;
  825. Tuple *tuple;
  826. tuple = g_slice_new (Tuple);
  827. tuple->ast.class = &tuple_class;
  828. tuple->children = NULL;
  829. tuple->n_children = 0;
  830. token_stream_assert (stream, "(");
  831. while (!token_stream_consume (stream, ")"))
  832. {
  833. AST *child;
  834. if (need_comma &&
  835. !token_stream_require (stream, ",",
  836. " or `)' to follow tuple element",
  837. error))
  838. goto error;
  839. child = parse (stream, app, error);
  840. if (!child)
  841. goto error;
  842. ast_array_append (&tuple->children, &tuple->n_children, child);
  843. /* the first time, we absolutely require a comma, so grab it here
  844. * and leave need_comma = FALSE so that the code above doesn't
  845. * require a second comma.
  846. *
  847. * the second and remaining times, we set need_comma = TRUE.
  848. */
  849. if (first)
  850. {
  851. if (!token_stream_require (stream, ",",
  852. " after first tuple element", error))
  853. goto error;
  854. first = FALSE;
  855. }
  856. else
  857. need_comma = TRUE;
  858. }
  859. return (AST *) tuple;
  860. error:
  861. ast_array_free (tuple->children, tuple->n_children);
  862. g_slice_free (Tuple, tuple);
  863. return NULL;
  864. }
  865. typedef struct
  866. {
  867. AST ast;
  868. AST *value;
  869. } Variant;
  870. static gchar *
  871. variant_get_pattern (AST *ast,
  872. GError **error)
  873. {
  874. return g_strdup ("Mv");
  875. }
  876. static GVariant *
  877. variant_get_value (AST *ast,
  878. const GVariantType *type,
  879. GError **error)
  880. {
  881. Variant *variant = (Variant *) ast;
  882. GVariant *child;
  883. g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT));
  884. child = ast_resolve (variant->value, error);
  885. if (child == NULL)
  886. return NULL;
  887. return g_variant_new_variant (child);
  888. }
  889. static void
  890. variant_free (AST *ast)
  891. {
  892. Variant *variant = (Variant *) ast;
  893. ast_free (variant->value);
  894. g_slice_free (Variant, variant);
  895. }
  896. static AST *
  897. variant_parse (TokenStream *stream,
  898. va_list *app,
  899. GError **error)
  900. {
  901. static const ASTClass variant_class = {
  902. variant_get_pattern,
  903. maybe_wrapper, variant_get_value,
  904. variant_free
  905. };
  906. Variant *variant;
  907. AST *value;
  908. token_stream_assert (stream, "<");
  909. value = parse (stream, app, error);
  910. if (!value)
  911. return NULL;
  912. if (!token_stream_require (stream, ">", " to follow variant value", error))
  913. {
  914. ast_free (value);
  915. return NULL;
  916. }
  917. variant = g_slice_new (Variant);
  918. variant->ast.class = &variant_class;
  919. variant->value = value;
  920. return (AST *) variant;
  921. }
  922. typedef struct
  923. {
  924. AST ast;
  925. AST **keys;
  926. AST **values;
  927. gint n_children;
  928. } Dictionary;
  929. static gchar *
  930. dictionary_get_pattern (AST *ast,
  931. GError **error)
  932. {
  933. Dictionary *dict = (Dictionary *) ast;
  934. gchar *value_pattern;
  935. gchar *key_pattern;
  936. gchar key_char;
  937. gchar *result;
  938. if (dict->n_children == 0)
  939. return g_strdup ("Ma{**}");
  940. key_pattern = ast_array_get_pattern (dict->keys,
  941. abs (dict->n_children),
  942. error);
  943. if (key_pattern == NULL)
  944. return NULL;
  945. /* we can not have maybe keys */
  946. if (key_pattern[0] == 'M')
  947. key_char = key_pattern[1];
  948. else
  949. key_char = key_pattern[0];
  950. g_free (key_pattern);
  951. /* the basic types,
  952. * plus undetermined number type and undetermined string type.
  953. */
  954. if (!strchr ("bynqiuxthdsogNS", key_char))
  955. {
  956. ast_set_error (ast, error, NULL,
  957. "dictionary keys must have basic types");
  958. return NULL;
  959. }
  960. value_pattern = ast_get_pattern (dict->values[0], error);
  961. if (value_pattern == NULL)
  962. return NULL;
  963. result = g_strdup_printf ("M%s{%c%s}",
  964. dict->n_children > 0 ? "a" : "",
  965. key_char, value_pattern);
  966. g_free (value_pattern);
  967. return result;
  968. }
  969. static GVariant *
  970. dictionary_get_value (AST *ast,
  971. const GVariantType *type,
  972. GError **error)
  973. {
  974. Dictionary *dict = (Dictionary *) ast;
  975. if (dict->n_children == -1)
  976. {
  977. const GVariantType *subtype;
  978. GVariantBuilder builder;
  979. GVariant *subvalue;
  980. if (!g_variant_type_is_dict_entry (type))
  981. return ast_type_error (ast, type, error);
  982. g_variant_builder_init (&builder, type);
  983. subtype = g_variant_type_key (type);
  984. if (!(subvalue = ast_get_value (dict->keys[0], subtype, error)))
  985. {
  986. g_variant_builder_clear (&builder);
  987. return NULL;
  988. }
  989. g_variant_builder_add_value (&builder, subvalue);
  990. subtype = g_variant_type_value (type);
  991. if (!(subvalue = ast_get_value (dict->values[0], subtype, error)))
  992. {
  993. g_variant_builder_clear (&builder);
  994. return NULL;
  995. }
  996. g_variant_builder_add_value (&builder, subvalue);
  997. return g_variant_builder_end (&builder);
  998. }
  999. else
  1000. {
  1001. const GVariantType *entry, *key, *val;
  1002. GVariantBuilder builder;
  1003. gint i;
  1004. if (!g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_DICTIONARY))
  1005. return ast_type_error (ast, type, error);
  1006. entry = g_variant_type_element (type);
  1007. key = g_variant_type_key (entry);
  1008. val = g_variant_type_value (entry);
  1009. g_variant_builder_init (&builder, type);
  1010. for (i = 0; i < dict->n_children; i++)
  1011. {
  1012. GVariant *subvalue;
  1013. g_variant_builder_open (&builder, entry);
  1014. if (!(subvalue = ast_get_value (dict->keys[i], key, error)))
  1015. {
  1016. g_variant_builder_clear (&builder);
  1017. return NULL;
  1018. }
  1019. g_variant_builder_add_value (&builder, subvalue);
  1020. if (!(subvalue = ast_get_value (dict->values[i], val, error)))
  1021. {
  1022. g_variant_builder_clear (&builder);
  1023. return NULL;
  1024. }
  1025. g_variant_builder_add_value (&builder, subvalue);
  1026. g_variant_builder_close (&builder);
  1027. }
  1028. return g_variant_builder_end (&builder);
  1029. }
  1030. }
  1031. static void
  1032. dictionary_free (AST *ast)
  1033. {
  1034. Dictionary *dict = (Dictionary *) ast;
  1035. gint n_children;
  1036. if (dict->n_children > -1)
  1037. n_children = dict->n_children;
  1038. else
  1039. n_children = 1;
  1040. ast_array_free (dict->keys, n_children);
  1041. ast_array_free (dict->values, n_children);
  1042. g_slice_free (Dictionary, dict);
  1043. }
  1044. static AST *
  1045. dictionary_parse (TokenStream *stream,
  1046. va_list *app,
  1047. GError **error)
  1048. {
  1049. static const ASTClass dictionary_class = {
  1050. dictionary_get_pattern,
  1051. maybe_wrapper, dictionary_get_value,
  1052. dictionary_free
  1053. };
  1054. gint n_keys, n_values;
  1055. gboolean only_one;
  1056. Dictionary *dict;
  1057. AST *first;
  1058. dict = g_slice_new (Dictionary);
  1059. dict->ast.class = &dictionary_class;
  1060. dict->keys = NULL;
  1061. dict->values = NULL;
  1062. n_keys = n_values = 0;
  1063. token_stream_assert (stream, "{");
  1064. if (token_stream_consume (stream, "}"))
  1065. {
  1066. dict->n_children = 0;
  1067. return (AST *) dict;
  1068. }
  1069. if ((first = parse (stream, app, error)) == NULL)
  1070. goto error;
  1071. ast_array_append (&dict->keys, &n_keys, first);
  1072. only_one = token_stream_consume (stream, ",");
  1073. if (!only_one &&
  1074. !token_stream_require (stream, ":",
  1075. " or `,' to follow dictionary entry key",
  1076. error))
  1077. goto error;
  1078. if ((first = parse (stream, app, error)) == NULL)
  1079. goto error;
  1080. ast_array_append (&dict->values, &n_values, first);
  1081. if (only_one)
  1082. {
  1083. if (!token_stream_require (stream, "}", " at end of dictionary entry",
  1084. error))
  1085. goto error;
  1086. g_assert (n_keys == 1 && n_values == 1);
  1087. dict->n_children = -1;
  1088. return (AST *) dict;
  1089. }
  1090. while (!token_stream_consume (stream, "}"))
  1091. {
  1092. AST *child;
  1093. if (!token_stream_require (stream, ",",
  1094. " or `}' to follow dictionary entry", error))
  1095. goto error;
  1096. child = parse (stream, app, error);
  1097. if (!child)
  1098. goto error;
  1099. ast_array_append (&dict->keys, &n_keys, child);
  1100. if (!token_stream_require (stream, ":",
  1101. " to follow dictionary entry key", error))
  1102. goto error;
  1103. child = parse (stream, app, error);
  1104. if (!child)
  1105. goto error;
  1106. ast_array_append (&dict->values, &n_values, child);
  1107. }
  1108. g_assert (n_keys == n_values);
  1109. dict->n_children = n_keys;
  1110. return (AST *) dict;
  1111. error:
  1112. ast_array_free (dict->keys, n_keys);
  1113. ast_array_free (dict->values, n_values);
  1114. g_slice_free (Dictionary, dict);
  1115. return NULL;
  1116. }
  1117. typedef struct
  1118. {
  1119. AST ast;
  1120. gchar *string;
  1121. } String;
  1122. static gchar *
  1123. string_get_pattern (AST *ast,
  1124. GError **error)
  1125. {
  1126. return g_strdup ("MS");
  1127. }
  1128. static GVariant *
  1129. string_get_value (AST *ast,
  1130. const GVariantType *type,
  1131. GError **error)
  1132. {
  1133. String *string = (String *) ast;
  1134. if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
  1135. return g_variant_new_string (string->string);
  1136. else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
  1137. {
  1138. if (!g_variant_is_object_path (string->string))
  1139. {
  1140. ast_set_error (ast, error, NULL, "not a valid object path");
  1141. return NULL;
  1142. }
  1143. return g_variant_new_object_path (string->string);
  1144. }
  1145. else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
  1146. {
  1147. if (!g_variant_is_signature (string->string))
  1148. {
  1149. ast_set_error (ast, error, NULL, "not a valid signature");
  1150. return NULL;
  1151. }
  1152. return g_variant_new_signature (string->string);
  1153. }
  1154. else
  1155. return ast_type_error (ast, type, error);
  1156. }
  1157. static void
  1158. string_free (AST *ast)
  1159. {
  1160. String *string = (String *) ast;
  1161. g_free (string->string);
  1162. g_slice_free (String, string);
  1163. }
  1164. static gboolean
  1165. unicode_unescape (const gchar *src,
  1166. gint *src_ofs,
  1167. gchar *dest,
  1168. gint *dest_ofs,
  1169. gint length,
  1170. SourceRef *ref,
  1171. GError **error)
  1172. {
  1173. gchar buffer[9];
  1174. guint64 value;
  1175. gchar *end;
  1176. (*src_ofs)++;
  1177. g_assert (length < sizeof (buffer));
  1178. strncpy (buffer, src + *src_ofs, length);
  1179. buffer[length] = '\0';
  1180. value = g_ascii_strtoull (buffer, &end, 0x10);
  1181. if (value == 0 || end != buffer + length)
  1182. {
  1183. parser_set_error (error, ref, NULL,
  1184. "invalid %d-character unicode escape", length);
  1185. return FALSE;
  1186. }
  1187. g_assert (value <= G_MAXUINT32);
  1188. *dest_ofs += g_unichar_to_utf8 (value, dest + *dest_ofs);
  1189. *src_ofs += length;
  1190. return TRUE;
  1191. }
  1192. static AST *
  1193. string_parse (TokenStream *stream,
  1194. va_list *app,
  1195. GError **error)
  1196. {
  1197. static const ASTClass string_class = {
  1198. string_get_pattern,
  1199. maybe_wrapper, string_get_value,
  1200. string_free
  1201. };
  1202. String *string;
  1203. SourceRef ref;
  1204. gchar *token;
  1205. gsize length;
  1206. gchar quote;
  1207. gchar *str;
  1208. gint i, j;
  1209. token_stream_start_ref (stream, &ref);
  1210. token = token_stream_get (stream);
  1211. token_stream_end_ref (stream, &ref);
  1212. length = strlen (token);
  1213. quote = token[0];
  1214. str = g_malloc (length);
  1215. g_assert (quote == '"' || quote == '\'');
  1216. j = 0;
  1217. i = 1;
  1218. while (token[i] != quote)
  1219. switch (token[i])
  1220. {
  1221. case '\0':
  1222. parser_set_error (error, &ref, NULL,
  1223. "unterminated string constant");
  1224. g_free (token);
  1225. g_free (str);
  1226. return NULL;
  1227. case '\\':
  1228. switch (token[++i])
  1229. {
  1230. case '\0':
  1231. parser_set_error (error, &ref, NULL,
  1232. "unterminated string constant");
  1233. g_free (token);
  1234. g_free (str);
  1235. return NULL;
  1236. case 'u':
  1237. if (!unicode_unescape (token, &i, str, &j, 4, &ref, error))
  1238. {
  1239. g_free (token);
  1240. g_free (str);
  1241. return NULL;
  1242. }
  1243. continue;
  1244. case 'U':
  1245. if (!unicode_unescape (token, &i, str, &j, 8, &ref, error))
  1246. {
  1247. g_free (token);
  1248. g_free (str);
  1249. return NULL;
  1250. }
  1251. continue;
  1252. case 'a': str[j++] = '\a'; i++; continue;
  1253. case 'b': str[j++] = '\b'; i++; continue;
  1254. case 'f': str[j++] = '\f'; i++; continue;
  1255. case 'n': str[j++] = '\n'; i++; continue;
  1256. case 'r': str[j++] = '\r'; i++; continue;
  1257. case 't': str[j++] = '\t'; i++; continue;
  1258. case 'v': str[j++] = '\v'; i++; continue;
  1259. case '\n': i++; continue;
  1260. }
  1261. default:
  1262. str[j++] = token[i++];
  1263. }
  1264. str[j++] = '\0';
  1265. g_free (token);
  1266. string = g_slice_new (String);
  1267. string->ast.class = &string_class;
  1268. string->string = str;
  1269. token_stream_next (stream);
  1270. return (AST *) string;
  1271. }
  1272. typedef struct
  1273. {
  1274. AST ast;
  1275. gchar *string;
  1276. } ByteString;
  1277. static gchar *
  1278. bytestring_get_pattern (AST *ast,
  1279. GError **error)
  1280. {
  1281. return g_strdup ("May");
  1282. }
  1283. static GVariant *
  1284. bytestring_get_value (AST *ast,
  1285. const GVariantType *type,
  1286. GError **error)
  1287. {
  1288. ByteString *string = (ByteString *) ast;
  1289. g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_BYTESTRING));
  1290. return g_variant_new_bytestring (string->string);
  1291. }
  1292. static void
  1293. bytestring_free (AST *ast)
  1294. {
  1295. ByteString *string = (ByteString *) ast;
  1296. g_free (string->string);
  1297. g_slice_free (ByteString, string);
  1298. }
  1299. static AST *
  1300. bytestring_parse (TokenStream *stream,
  1301. va_list *app,
  1302. GError **error)
  1303. {
  1304. static const ASTClass bytestring_class = {
  1305. bytestring_get_pattern,
  1306. maybe_wrapper, bytestring_get_value,
  1307. bytestring_free
  1308. };
  1309. ByteString *string;
  1310. SourceRef ref;
  1311. gchar *token;
  1312. gsize length;
  1313. gchar quote;
  1314. gchar *str;
  1315. gint i, j;
  1316. token_stream_start_ref (stream, &ref);
  1317. token = token_stream_get (stream);
  1318. token_stream_end_ref (stream, &ref);
  1319. g_assert (token[0] == 'b');
  1320. length = strlen (token);
  1321. quote = token[1];
  1322. str = g_malloc (length);
  1323. g_assert (quote == '"' || quote == '\'');
  1324. j = 0;
  1325. i = 2;
  1326. while (token[i] != quote)
  1327. switch (token[i])
  1328. {
  1329. case '\0':
  1330. parser_set_error (error, &ref, NULL,
  1331. "unterminated string constant");
  1332. g_free (token);
  1333. return NULL;
  1334. case '\\':
  1335. switch (token[++i])
  1336. {
  1337. case '\0':
  1338. parser_set_error (error, &ref, NULL,
  1339. "unterminated string constant");
  1340. g_free (token);
  1341. return NULL;
  1342. case '0': case '1': case '2': case '3':
  1343. case '4': case '5': case '6': case '7':
  1344. {
  1345. /* up to 3 characters */
  1346. guchar val = token[i++] - '0';
  1347. if ('0' <= token[i] && token[i] < '8')
  1348. val = (val << 3) | (token[i++] - '0');
  1349. if ('0' <= token[i] && token[i] < '8')
  1350. val = (val << 3) | (token[i++] - '0');
  1351. str[j++] = val;
  1352. }
  1353. continue;
  1354. case 'a': str[j++] = '\a'; i++; continue;
  1355. case 'b': str[j++] = '\b'; i++; continue;
  1356. case 'f': str[j++] = '\f'; i++; continue;
  1357. case 'n': str[j++] = '\n'; i++; continue;
  1358. case 'r': str[j++] = '\r'; i++; continue;
  1359. case 't': str[j++] = '\t'; i++; continue;
  1360. case 'v': str[j++] = '\v'; i++; continue;
  1361. case '\n': i++; continue;
  1362. }
  1363. default:
  1364. str[j++] = token[i++];
  1365. }
  1366. str[j++] = '\0';
  1367. g_free (token);
  1368. string = g_slice_new (ByteString);
  1369. string->ast.class = &bytestring_class;
  1370. string->string = str;
  1371. token_stream_next (stream);
  1372. return (AST *) string;
  1373. }
  1374. typedef struct
  1375. {
  1376. AST ast;
  1377. gchar *token;
  1378. } Number;
  1379. static gchar *
  1380. number_get_pattern (AST *ast,
  1381. GError **error)
  1382. {
  1383. Number *number = (Number *) ast;
  1384. if (strchr (number->token, '.') ||
  1385. (!g_str_has_prefix (number->token, "0x") &&
  1386. strchr (number->token, 'e')))
  1387. return g_strdup ("Md");
  1388. return g_strdup ("MN");
  1389. }
  1390. static GVariant *
  1391. number_overflow (AST *ast,
  1392. const GVariantType *type,
  1393. GError **error)
  1394. {
  1395. ast_set_error (ast, error, NULL, "number out of range for type `%c'",
  1396. g_variant_type_peek_string (type)[0]);
  1397. return NULL;
  1398. }
  1399. static GVariant *
  1400. number_get_value (AST *ast,
  1401. const GVariantType *type,
  1402. GError **error)
  1403. {
  1404. Number *number = (Number *) ast;
  1405. const gchar *token;
  1406. gboolean negative;
  1407. gboolean floating;
  1408. guint64 abs_val;
  1409. gdouble dbl_val;
  1410. gchar *end;
  1411. token = number->token;
  1412. if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
  1413. {
  1414. floating = TRUE;
  1415. errno = 0;
  1416. dbl_val = g_ascii_strtod (token, &end);
  1417. if (dbl_val != 0.0 && errno == ERANGE)
  1418. {
  1419. ast_set_error (ast, error, NULL, "number too big for any type");
  1420. return NULL;
  1421. }
  1422. /* silence uninitialised warnings... */
  1423. negative = FALSE;
  1424. abs_val = 0;
  1425. }
  1426. else
  1427. {
  1428. floating = FALSE;
  1429. negative = token[0] == '-';
  1430. if (token[0] == '-')
  1431. token++;
  1432. errno = 0;
  1433. abs_val = g_ascii_strtoull (token, &end, 0);
  1434. if (abs_val == G_MAXUINT64 && errno == ERANGE)
  1435. {
  1436. ast_set_error (ast, error, NULL, "integer too big for any type");
  1437. return NULL;
  1438. }
  1439. if (abs_val == 0)
  1440. negative = FALSE;
  1441. /* silence uninitialised warning... */
  1442. dbl_val = 0.0;
  1443. }
  1444. if (*end != '\0')
  1445. {
  1446. SourceRef ref;
  1447. ref = ast->source_ref;
  1448. ref.start += end - number->token;
  1449. ref.end = ref.start + 1;
  1450. parser_set_error (error, &ref, NULL,
  1451. "invalid character in number");
  1452. return NULL;
  1453. }
  1454. if (floating)
  1455. return g_variant_new_double (dbl_val);
  1456. switch (*g_variant_type_peek_string (type))
  1457. {
  1458. case 'y':
  1459. if (negative || abs_val > G_MAXUINT8)
  1460. return number_overflow (ast, type, error);
  1461. return g_variant_new_byte (abs_val);
  1462. case 'n':
  1463. if (abs_val - negative > G_MAXINT16)
  1464. return number_overflow (ast, type, error);
  1465. return g_variant_new_int16 (negative ? -abs_val : abs_val);
  1466. case 'q':
  1467. if (negative || abs_val > G_MAXUINT16)
  1468. return number_overflow (ast, type, error);
  1469. return g_variant_new_uint16 (negative ? -abs_val : abs_val);
  1470. case 'i':
  1471. if (abs_val - negative > G_MAXINT32)
  1472. return number_overflow (ast, type, error);
  1473. return g_variant_new_int32 (negative ? -abs_val : abs_val);
  1474. case 'u':
  1475. if (negative || abs_val > G_MAXUINT32)
  1476. return number_overflow (ast, type, error);
  1477. return g_variant_new_uint32 (negative ? -abs_val : abs_val);
  1478. case 'x':
  1479. if (abs_val - negative > G_MAXINT64)
  1480. return number_overflow (ast, type, error);
  1481. return g_variant_new_int64 (negative ? -abs_val : abs_val);
  1482. case 't':
  1483. if (negative)
  1484. return number_overflow (ast, type, error);
  1485. return g_variant_new_uint64 (negative ? -abs_val : abs_val);
  1486. case 'h':
  1487. if (abs_val - negative > G_MAXINT32)
  1488. return number_overflow (ast, type, error);
  1489. return g_variant_new_handle (negative ? -abs_val : abs_val);
  1490. default:
  1491. return ast_type_error (ast, type, error);
  1492. }
  1493. }
  1494. static void
  1495. number_free (AST *ast)
  1496. {
  1497. Number *number = (Number *) ast;
  1498. g_free (number->token);
  1499. g_slice_free (Number, number);
  1500. }
  1501. static AST *
  1502. number_parse (TokenStream *stream,
  1503. va_list *app,
  1504. GError **error)
  1505. {
  1506. static const ASTClass number_class = {
  1507. number_get_pattern,
  1508. maybe_wrapper, number_get_value,
  1509. number_free
  1510. };
  1511. Number *number;
  1512. number = g_slice_new (Number);
  1513. number->ast.class = &number_class;
  1514. number->token = token_stream_get (stream);
  1515. token_stream_next (stream);
  1516. return (AST *) number;
  1517. }
  1518. typedef struct
  1519. {
  1520. AST ast;
  1521. gboolean value;
  1522. } Boolean;
  1523. static gchar *
  1524. boolean_get_pattern (AST *ast,
  1525. GError **error)
  1526. {
  1527. return g_strdup ("Mb");
  1528. }
  1529. static GVariant *
  1530. boolean_get_value (AST *ast,
  1531. const GVariantType *type,
  1532. GError **error)
  1533. {
  1534. Boolean *boolean = (Boolean *) ast;
  1535. if (!g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
  1536. return ast_type_error (ast, type, error);
  1537. return g_variant_new_boolean (boolean->value);
  1538. }
  1539. static void
  1540. boolean_free (AST *ast)
  1541. {
  1542. Boolean *boolean = (Boolean *) ast;
  1543. g_slice_free (Boolean, boolean);
  1544. }
  1545. static AST *
  1546. boolean_new (gboolean value)
  1547. {
  1548. static const ASTClass boolean_class = {
  1549. boolean_get_pattern,
  1550. maybe_wrapper, boolean_get_value,
  1551. boolean_free
  1552. };
  1553. Boolean *boolean;
  1554. boolean = g_slice_new (Boolean);
  1555. boolean->ast.class = &boolean_class;
  1556. boolean->value = value;
  1557. return (AST *) boolean;
  1558. }
  1559. typedef struct
  1560. {
  1561. AST ast;
  1562. GVariant *value;
  1563. } Positional;
  1564. static gchar *
  1565. positional_get_pattern (AST *ast,
  1566. GError **error)
  1567. {
  1568. Positional *positional = (Positional *) ast;
  1569. return g_strdup (g_variant_get_type_string (positional->value));
  1570. }
  1571. static GVariant *
  1572. positional_get_value (AST *ast,
  1573. const GVariantType *type,
  1574. GError **error)
  1575. {
  1576. Positional *positional = (Positional *) ast;
  1577. GVariant *value;
  1578. g_assert (positional->value != NULL);
  1579. if G_UNLIKELY (!g_variant_is_of_type (positional->value, type))
  1580. return ast_type_error (ast, type, error);
  1581. /* NOTE: if _get is called more than once then
  1582. * things get messed up with respect to floating refs.
  1583. *
  1584. * fortunately, this function should only ever get called once.
  1585. */
  1586. g_assert (positional->value != NULL);
  1587. value = positional->value;
  1588. positional->value = NULL;
  1589. return value;
  1590. }
  1591. static void
  1592. positional_free (AST *ast)
  1593. {
  1594. Positional *positional = (Positional *) ast;
  1595. /* if positional->value is set, just leave it.
  1596. * memory management doesn't matter in case of programmer error.
  1597. */
  1598. g_slice_free (Positional, positional);
  1599. }
  1600. static AST *
  1601. positional_parse (TokenStream *stream,
  1602. va_list *app,
  1603. GError **error)
  1604. {
  1605. static const ASTClass positional_class = {
  1606. positional_get_pattern,
  1607. positional_get_value, NULL,
  1608. positional_free
  1609. };
  1610. Positional *positional;
  1611. const gchar *endptr;
  1612. gchar *token;
  1613. token = token_stream_get (stream);
  1614. g_assert (token[0] == '%');
  1615. positional = g_slice_new (Positional);
  1616. positional->ast.class = &positional_class;
  1617. positional->value = g_variant_new_va (token + 1, &endptr, app);
  1618. if (*endptr || positional->value == NULL)
  1619. {
  1620. token_stream_set_error (stream, error, TRUE,
  1621. "invalid GVariant format string");
  1622. /* memory management doesn't matter in case of programmer error. */
  1623. return NULL;
  1624. }
  1625. token_stream_next (stream);
  1626. g_free (token);
  1627. return (AST *) positional;
  1628. }
  1629. typedef struct
  1630. {
  1631. AST ast;
  1632. GVariantType *type;
  1633. AST *child;
  1634. } TypeDecl;
  1635. static gchar *
  1636. typedecl_get_pattern (AST *ast,
  1637. GError **error)
  1638. {
  1639. TypeDecl *decl = (TypeDecl *) ast;
  1640. return g_variant_type_dup_string (decl->type);
  1641. }
  1642. static GVariant *
  1643. typedecl_get_value (AST *ast,
  1644. const GVariantType *type,
  1645. GError **error)
  1646. {
  1647. TypeDecl *decl = (TypeDecl *) ast;
  1648. return ast_get_value (decl->child, type, error);
  1649. }
  1650. static void
  1651. typedecl_free (AST *ast)
  1652. {
  1653. TypeDecl *decl = (TypeDecl *) ast;
  1654. ast_free (decl->child);
  1655. g_variant_type_free (decl->type);
  1656. g_slice_free (TypeDecl, decl);
  1657. }
  1658. static AST *
  1659. typedecl_parse (TokenStream *stream,
  1660. va_list *app,
  1661. GError **error)
  1662. {
  1663. static const ASTClass typedecl_class = {
  1664. typedecl_get_pattern,
  1665. typedecl_get_value, NULL,
  1666. typedecl_free
  1667. };
  1668. GVariantType *type;
  1669. TypeDecl *decl;
  1670. AST *child;
  1671. if (token_stream_peek (stream, '@'))
  1672. {
  1673. gchar *token;
  1674. token = token_stream_get (stream);
  1675. if (!g_variant_type_string_is_valid (token + 1))
  1676. {
  1677. token_stream_set_error (stream, error, TRUE,
  1678. "invalid type declaration");
  1679. g_free (token);
  1680. return NULL;
  1681. }
  1682. type = g_variant_type_new (token + 1);
  1683. if (!g_variant_type_is_definite (type))
  1684. {
  1685. token_stream_set_error (stream, error, TRUE,
  1686. "type declarations must be definite");
  1687. g_variant_type_free (type);
  1688. g_free (token);
  1689. return NULL;
  1690. }
  1691. token_stream_next (stream);
  1692. g_free (token);
  1693. }
  1694. else
  1695. {
  1696. if (token_stream_consume (stream, "boolean"))
  1697. type = g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
  1698. else if (token_stream_consume (stream, "byte"))
  1699. type = g_variant_type_copy (G_VARIANT_TYPE_BYTE);
  1700. else if (token_stream_consume (stream, "int16"))
  1701. type = g_variant_type_copy (G_VARIANT_TYPE_INT16);
  1702. else if (token_stream_consume (stream, "uint16"))
  1703. type = g_variant_type_copy (G_VARIANT_TYPE_UINT16);
  1704. else if (token_stream_consume (stream, "int32"))
  1705. type = g_variant_type_copy (G_VARIANT_TYPE_INT32);
  1706. else if (token_stream_consume (stream, "handle"))
  1707. type = g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
  1708. else if (token_stream_consume (stream, "uint32"))
  1709. type = g_variant_type_copy (G_VARIANT_TYPE_UINT32);
  1710. else if (token_stream_consume (stream, "int64"))
  1711. type = g_variant_type_copy (G_VARIANT_TYPE_INT64);
  1712. else if (token_stream_consume (stream, "uint64"))
  1713. type = g_variant_type_copy (G_VARIANT_TYPE_UINT64);
  1714. else if (token_stream_consume (stream, "double"))
  1715. type = g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
  1716. else if (token_stream_consume (stream, "string"))
  1717. type = g_variant_type_copy (G_VARIANT_TYPE_STRING);
  1718. else if (token_stream_consume (stream, "objectpath"))
  1719. type = g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
  1720. else if (token_stream_consume (stream, "signature"))
  1721. type = g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
  1722. else
  1723. {
  1724. token_stream_set_error (stream, error, TRUE, "unknown keyword");
  1725. return NULL;
  1726. }
  1727. }
  1728. if ((child = parse (stream, app, error)) == NULL)
  1729. {
  1730. g_variant_type_free (type);
  1731. return NULL;
  1732. }
  1733. decl = g_slice

Large files files are truncated, but you can click here to view the full file