PageRenderTime 30ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/glib-2.45.1/glib/gvariant-parser.c

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

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