2 * Copyright (c) 1999-2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * OSUnserializeXML.y created by rsulack on Tue Oct 12 1999
35 // parser for unserializing OSContainer objects serialized to XML
38 // bison -p OSUnserializeXML OSUnserializeXML.y
39 // head -50 OSUnserializeXML.y > OSUnserializeXML.cpp
40 // sed -e "s/#include <stdio.h>//" < OSUnserializeXML.tab.c >> OSUnserializeXML.cpp
42 // when changing code check in both OSUnserializeXML.y and OSUnserializeXML.cpp
48 // DO NOT EDIT OSUnserializeXML.cpp!
51 /* A Bison parser, made by GNU Bison 2.3. */
53 /* Skeleton implementation for Bison's Yacc-like parsers in C
55 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
56 Free Software Foundation, Inc.
58 This program is free software; you can redistribute it and/or modify
59 it under the terms of the GNU General Public License as published by
60 the Free Software Foundation; either version 2, or (at your option)
63 This program is distributed in the hope that it will be useful,
64 but WITHOUT ANY WARRANTY; without even the implied warranty of
65 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66 GNU General Public License for more details.
68 You should have received a copy of the GNU General Public License
69 along with this program; if not, write to the Free Software
70 Foundation, Inc., 51 Franklin Street, Fifth Floor,
71 Boston, MA 02110-1301, USA. */
73 /* As a special exception, you may create a larger work that contains
74 part or all of the Bison parser skeleton and distribute that work
75 under terms of your choice, so long as that work isn't itself a
76 parser generator using the skeleton or a modified version thereof
77 as a parser skeleton. Alternatively, if you modify or redistribute
78 the parser skeleton itself, you may (at your option) remove this
79 special exception, which will cause the skeleton and the resulting
80 Bison output files to be licensed under the GNU General Public
81 License without this special exception.
83 This special exception was added by the Free Software Foundation in
84 version 2.2 of Bison. */
86 /* C LALR(1) parser skeleton written by Richard Stallman, by
87 simplifying the original so-called "semantic" parser. */
89 /* All symbols defined below should begin with yy or YY, to avoid
90 infringing on user name space. This should be done even for local
91 variables, as they might otherwise be expanded by user macros.
92 There are some unavoidable exceptions within include files to
93 define necessary library symbols; they are noted "INFRINGES ON
94 USER NAME SPACE" below. */
96 /* Identify Bison output. */
100 #define YYBISON_VERSION "2.3"
103 #define YYSKELETON_NAME "yacc.c"
108 /* Using locations. */
109 #define YYLSP_NEEDED 0
111 /* Substitute the variable and function names. */
112 #define yyparse OSUnserializeXMLparse
113 #define yylex OSUnserializeXMLlex
114 #define yyerror OSUnserializeXMLerror
115 #define yylval OSUnserializeXMLlval
116 #define yychar OSUnserializeXMLchar
117 #define yydebug OSUnserializeXMLdebug
118 #define yynerrs OSUnserializeXMLnerrs
124 /* Put the tokens into the symbol table, so that GDB and other debuggers
143 #define DICTIONARY 261
149 #define SYNTAX_ERROR 267
154 /* Copy the first part of user declarations. */
155 #line 61 "OSUnserializeXML.y"
158 #include <libkern/c++/OSMetaClass.h>
159 #include <libkern/c++/OSContainers.h>
160 #include <libkern/c++/OSLib.h>
162 #define MAX_OBJECTS 131071
163 #define MAX_REFED_OBJECTS 65535
165 #define YYSTYPE object_t *
166 #define YYPARSE_PARAM state
167 #define YYLEX_PARAM (parser_state_t *)state
169 // this is the internal struct used to hold objects on parser stack
170 // it represents objects both before and after they have been created
171 typedef struct object
{
174 struct object
*elements
;
176 OSSymbol
*key
; // for dictionary
178 void *data
; // for data
179 char *string
; // for string & symbol
180 long long number
; // for number
184 // this code is reentrant, this structure contains all
185 // state information for the parsing of a single buffer
186 typedef struct parser_state
{
187 const char *parseBuffer
; // start of text to be parsed
188 int parseBufferIndex
; // current index into text
189 int lineNumber
; // current line number
190 object_t
*objects
; // internal objects in use
191 object_t
*freeObjects
; // internal objects that are free
192 OSDictionary
*tags
; // used to remember "ID" tags
193 OSString
**errorString
; // parse error with line
194 OSObject
*parsedObject
; // resultant object of parsed text
195 int parsedObjectCount
;
196 int retrievedObjectCount
;
199 #define STATE ((parser_state_t *)state)
202 #define yyerror(s) OSUnserializeerror(STATE, (s))
203 static int OSUnserializeerror(parser_state_t
*state
, const char *s
);
205 static int yylex(YYSTYPE
*lvalp
, parser_state_t
*state
);
207 static object_t
*newObject(parser_state_t
*state
);
208 static void freeObject(parser_state_t
*state
, object_t
*o
);
209 static void rememberObject(parser_state_t
*state
, int tag
, OSObject
*o
);
210 static object_t
*retrieveObject(parser_state_t
*state
, int tag
);
211 static void cleanupObjects(parser_state_t
*state
);
213 static object_t
*buildDictionary(parser_state_t
*state
, object_t
*o
);
214 static object_t
*buildArray(parser_state_t
*state
, object_t
*o
);
215 static object_t
*buildSet(parser_state_t
*state
, object_t
*o
);
216 static object_t
*buildString(parser_state_t
*state
, object_t
*o
);
217 static object_t
*buildSymbol(parser_state_t
*state
, object_t
*o
);
218 static object_t
*buildData(parser_state_t
*state
, object_t
*o
);
219 static object_t
*buildNumber(parser_state_t
*state
, object_t
*o
);
220 static object_t
*buildBoolean(parser_state_t
*state
, object_t
*o
);
223 extern void *kern_os_malloc(size_t size
);
224 extern void *kern_os_realloc(void * addr
, size_t size
);
225 extern void kern_os_free(void * addr
);
229 #define malloc(s) kern_os_malloc(s)
230 #define realloc(a, s) kern_os_realloc(a, s)
231 #define free(a) kern_os_free((void *)a)
235 /* Enabling traces. */
240 /* Enabling verbose error messages. */
241 #ifdef YYERROR_VERBOSE
242 # undef YYERROR_VERBOSE
243 # define YYERROR_VERBOSE 1
245 # define YYERROR_VERBOSE 0
248 /* Enabling the token table. */
249 #ifndef YYTOKEN_TABLE
250 # define YYTOKEN_TABLE 0
253 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
255 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
256 # define YYSTYPE_IS_DECLARED 1
257 # define YYSTYPE_IS_TRIVIAL 1
262 /* Copy the second part of user declarations. */
265 /* Line 216 of yacc.c. */
266 #line 215 "OSUnserializeXML.tab.c"
273 typedef YYTYPE_UINT8 yytype_uint8
;
275 typedef unsigned char yytype_uint8
;
279 typedef YYTYPE_INT8 yytype_int8
;
280 #elif (defined __STDC__ || defined __C99__FUNC__ \
281 || defined __cplusplus || defined _MSC_VER)
282 typedef signed char yytype_int8
;
284 typedef short int yytype_int8
;
288 typedef YYTYPE_UINT16 yytype_uint16
;
290 typedef unsigned short int yytype_uint16
;
294 typedef YYTYPE_INT16 yytype_int16
;
296 typedef short int yytype_int16
;
300 # ifdef __SIZE_TYPE__
301 # define YYSIZE_T __SIZE_TYPE__
302 # elif defined size_t
303 # define YYSIZE_T size_t
304 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
305 || defined __cplusplus || defined _MSC_VER)
306 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
307 # define YYSIZE_T size_t
309 # define YYSIZE_T unsigned int
313 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
316 # if defined YYENABLE_NLS && YYENABLE_NLS
318 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
319 # define YY_(msgid) dgettext ("bison-runtime", msgid)
323 # define YY_(msgid) msgid
327 /* Suppress unused-variable warnings by "using" E. */
328 #if ! defined lint || defined __GNUC__
329 # define YYUSE(e) ((void) (e))
331 # define YYUSE(e) /* empty */
334 /* Identity function, used to suppress warnings about constant conditions. */
338 #if (defined __STDC__ || defined __C99__FUNC__ \
339 || defined __cplusplus || defined _MSC_VER)
352 #if ! defined yyoverflow || YYERROR_VERBOSE
354 /* The parser invokes alloca or malloc; define the necessary symbols. */
356 # ifdef YYSTACK_USE_ALLOCA
357 # if YYSTACK_USE_ALLOCA
359 # define YYSTACK_ALLOC __builtin_alloca
360 # elif defined __BUILTIN_VA_ARG_INCR
361 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
363 # define YYSTACK_ALLOC __alloca
364 # elif defined _MSC_VER
365 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
366 # define alloca _alloca
368 # define YYSTACK_ALLOC alloca
369 # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
370 || defined __cplusplus || defined _MSC_VER)
371 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
380 # ifdef YYSTACK_ALLOC
381 /* Pacify GCC's `empty if-body' warning. */
382 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
383 # ifndef YYSTACK_ALLOC_MAXIMUM
384 /* The OS might guarantee only one guard page at the bottom of the stack,
385 and a page size can be as small as 4096 bytes. So we cannot safely
386 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
387 to allow for a few compiler-allocated temporary stack slots. */
388 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
391 # define YYSTACK_ALLOC YYMALLOC
392 # define YYSTACK_FREE YYFREE
393 # ifndef YYSTACK_ALLOC_MAXIMUM
394 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
396 # if (defined __cplusplus && ! defined _STDLIB_H \
397 && ! ((defined YYMALLOC || defined malloc) \
398 && (defined YYFREE || defined free)))
399 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
405 # define YYMALLOC malloc
406 # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
407 || defined __cplusplus || defined _MSC_VER)
408 void *malloc (YYSIZE_T
); /* INFRINGES ON USER NAME SPACE */
413 # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
414 || defined __cplusplus || defined _MSC_VER)
415 void free (void *); /* INFRINGES ON USER NAME SPACE */
419 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
422 #if (! defined yyoverflow \
423 && (! defined __cplusplus \
424 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
426 /* A type that is properly aligned for any stack member. */
433 /* The size of the maximum gap between one aligned stack and the next. */
434 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
436 /* The size of an array large to enough to hold all stacks, each with
438 # define YYSTACK_BYTES(N) \
439 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
440 + YYSTACK_GAP_MAXIMUM)
442 /* Copy COUNT objects from FROM to TO. The source and destination do
445 # if defined __GNUC__ && 1 < __GNUC__
446 # define YYCOPY(To, From, Count) \
447 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
449 # define YYCOPY(To, From, Count) \
453 for (yyi = 0; yyi < (Count); yyi++) \
454 (To)[yyi] = (From)[yyi]; \
460 /* Relocate STACK from its old location to the new one. The
461 local variables YYSIZE and YYSTACKSIZE give the old and new number of
462 elements in the stack, and YYPTR gives the new location of the
463 stack. Advance YYPTR to a properly aligned location for the next
465 # define YYSTACK_RELOCATE(Stack) \
468 YYSIZE_T yynewbytes; \
469 YYCOPY (&yyptr->Stack, Stack, yysize); \
470 Stack = &yyptr->Stack; \
471 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
472 yyptr += yynewbytes / sizeof (*yyptr); \
478 /* YYFINAL -- State number of the termination state. */
480 /* YYLAST -- Last index in YYTABLE. */
483 /* YYNTOKENS -- Number of terminals. */
485 /* YYNNTS -- Number of nonterminals. */
487 /* YYNRULES -- Number of rules. */
489 /* YYNRULES -- Number of states. */
492 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
494 #define YYMAXUTOK 267
496 #define YYTRANSLATE(YYX) \
497 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
499 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
500 static const yytype_uint8 yytranslate
[] =
502 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
503 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
504 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
505 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
506 15, 16, 2, 2, 2, 2, 2, 2, 2, 2,
507 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
508 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
509 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
510 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
511 2, 17, 2, 18, 2, 2, 2, 2, 2, 2,
512 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
513 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
514 2, 2, 2, 13, 2, 14, 2, 2, 2, 2,
515 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
516 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
517 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
518 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
519 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
520 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
521 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
522 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
523 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
524 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
525 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
526 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
527 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
528 5, 6, 7, 8, 9, 10, 11, 12
532 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
534 static const yytype_uint8 yyprhs
[] =
536 0, 0, 3, 4, 6, 8, 10, 12, 14, 16,
537 18, 20, 22, 24, 27, 31, 33, 35, 38, 41,
538 43, 46, 50, 52, 55, 59, 61, 63, 66, 68,
542 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
543 static const yytype_int8 yyrhs
[] =
545 20, 0, -1, -1, 21, -1, 12, -1, 22, -1,
546 26, -1, 27, -1, 33, -1, 30, -1, 32, -1,
547 29, -1, 31, -1, 13, 14, -1, 13, 23, 14,
548 -1, 6, -1, 24, -1, 23, 24, -1, 25, 21,
549 -1, 8, -1, 15, 16, -1, 15, 28, 16, -1,
550 3, -1, 17, 18, -1, 17, 28, 18, -1, 10,
551 -1, 21, -1, 28, 21, -1, 4, -1, 5, -1,
555 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
556 static const yytype_uint16 yyrline
[] =
558 0, 149, 149, 152, 157, 162, 174, 186, 198, 210,
559 222, 234, 246, 265, 268, 271, 274, 275, 290, 299,
560 311, 314, 317, 320, 323, 326, 329, 332, 339, 342,
565 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
566 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
567 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
568 static const char *const yytname
[] =
570 "$end", "error", "$undefined", "ARRAY", "BOOLEAN", "DATA", "DICTIONARY",
571 "IDREF", "KEY", "NUMBER", "SET", "STRING", "SYNTAX_ERROR", "'{'", "'}'",
572 "'('", "')'", "'['", "']'", "$accept", "input", "object", "dict",
573 "pairs", "pair", "key", "array", "set", "elements", "boolean", "data",
574 "idref", "number", "string", 0
579 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
581 static const yytype_uint16 yytoknum
[] =
583 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
584 265, 266, 267, 123, 125, 40, 41, 91, 93
588 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
589 static const yytype_uint8 yyr1
[] =
591 0, 19, 20, 20, 20, 21, 21, 21, 21, 21,
592 21, 21, 21, 22, 22, 22, 23, 23, 24, 25,
593 26, 26, 26, 27, 27, 27, 28, 28, 29, 30,
597 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
598 static const yytype_uint8 yyr2
[] =
600 0, 2, 0, 1, 1, 1, 1, 1, 1, 1,
601 1, 1, 1, 2, 3, 1, 1, 2, 2, 1,
602 2, 3, 1, 2, 3, 1, 1, 2, 1, 1,
606 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
607 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
608 means the default is an error. */
609 static const yytype_uint8 yydefact
[] =
611 2, 22, 28, 29, 15, 30, 31, 25, 32, 4,
612 0, 0, 0, 0, 3, 5, 6, 7, 11, 9,
613 12, 10, 8, 19, 13, 0, 16, 0, 20, 26,
614 0, 23, 0, 1, 14, 17, 18, 21, 27, 24
617 /* YYDEFGOTO[NTERM-NUM]. */
618 static const yytype_int8 yydefgoto
[] =
620 -1, 13, 29, 15, 25, 26, 27, 16, 17, 30,
624 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
626 #define YYPACT_NINF -20
627 static const yytype_int8 yypact
[] =
629 46, -20, -20, -20, -20, -20, -20, -20, -20, -20,
630 4, 61, -2, 10, -20, -20, -20, -20, -20, -20,
631 -20, -20, -20, -20, -20, 6, -20, 91, -20, -20,
632 76, -20, 30, -20, -20, -20, -20, -20, -20, -20
635 /* YYPGOTO[NTERM-NUM]. */
636 static const yytype_int8 yypgoto
[] =
638 -20, -20, 0, -20, -20, -19, -20, -20, -20, 5,
639 -20, -20, -20, -20, -20
642 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
643 positive, shift that token. If negative, reduce the rule which
644 number is the opposite. If zero, do what YYDEFACT says.
645 If YYTABLE_NINF, syntax error. */
646 #define YYTABLE_NINF -1
647 static const yytype_uint8 yytable
[] =
649 14, 1, 2, 3, 4, 5, 35, 6, 7, 8,
650 33, 10, 23, 11, 23, 12, 31, 32, 24, 0,
651 34, 0, 0, 0, 0, 0, 0, 36, 0, 0,
652 38, 0, 38, 1, 2, 3, 4, 5, 0, 6,
653 7, 8, 0, 10, 0, 11, 0, 12, 39, 1,
654 2, 3, 4, 5, 0, 6, 7, 8, 9, 10,
655 0, 11, 0, 12, 1, 2, 3, 4, 5, 0,
656 6, 7, 8, 0, 10, 0, 11, 28, 12, 1,
657 2, 3, 4, 5, 0, 6, 7, 8, 0, 10,
658 0, 11, 37, 12, 1, 2, 3, 4, 5, 0,
659 6, 7, 8, 0, 10, 0, 11, 0, 12
662 static const yytype_int8 yycheck
[] =
664 0, 3, 4, 5, 6, 7, 25, 9, 10, 11,
665 0, 13, 8, 15, 8, 17, 18, 12, 14, -1,
666 14, -1, -1, -1, -1, -1, -1, 27, -1, -1,
667 30, -1, 32, 3, 4, 5, 6, 7, -1, 9,
668 10, 11, -1, 13, -1, 15, -1, 17, 18, 3,
669 4, 5, 6, 7, -1, 9, 10, 11, 12, 13,
670 -1, 15, -1, 17, 3, 4, 5, 6, 7, -1,
671 9, 10, 11, -1, 13, -1, 15, 16, 17, 3,
672 4, 5, 6, 7, -1, 9, 10, 11, -1, 13,
673 -1, 15, 16, 17, 3, 4, 5, 6, 7, -1,
674 9, 10, 11, -1, 13, -1, 15, -1, 17
677 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
678 symbol of state STATE-NUM. */
679 static const yytype_uint8 yystos
[] =
681 0, 3, 4, 5, 6, 7, 9, 10, 11, 12,
682 13, 15, 17, 20, 21, 22, 26, 27, 29, 30,
683 31, 32, 33, 8, 14, 23, 24, 25, 16, 21,
684 28, 18, 28, 0, 14, 24, 21, 16, 21, 18
687 #define yyerrok (yyerrstatus = 0)
688 #define yyclearin (yychar = YYEMPTY)
692 #define YYACCEPT goto yyacceptlab
693 #define YYABORT goto yyabortlab
694 #define YYERROR goto yyerrorlab
697 /* Like YYERROR except do call yyerror. This remains here temporarily
698 to ease the transition to the new meaning of YYERROR, for GCC.
699 Once GCC version 2 has supplanted version 1, this can go. */
701 #define YYFAIL goto yyerrlab
703 #define YYRECOVERING() (!!yyerrstatus)
705 #define YYBACKUP(Token, Value) \
707 if (yychar == YYEMPTY && yylen == 1) \
711 yytoken = YYTRANSLATE (yychar); \
717 yyerror (YY_("syntax error: cannot back up")); \
724 #define YYERRCODE 256
727 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
728 If N is 0, then set CURRENT to the empty location which ends
729 the previous symbol: RHS[0] (always defined). */
731 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
732 #ifndef YYLLOC_DEFAULT
733 # define YYLLOC_DEFAULT(Current, Rhs, N) \
737 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
738 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
739 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
740 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
744 (Current).first_line = (Current).last_line = \
745 YYRHSLOC (Rhs, 0).last_line; \
746 (Current).first_column = (Current).last_column = \
747 YYRHSLOC (Rhs, 0).last_column; \
753 /* YY_LOCATION_PRINT -- Print the location on the stream.
754 This macro was not mandated originally: define only if we know
755 we won't break user code: when these are the locations we know. */
757 #ifndef YY_LOCATION_PRINT
758 # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
759 # define YY_LOCATION_PRINT(File, Loc) \
760 fprintf (File, "%d.%d-%d.%d", \
761 (Loc).first_line, (Loc).first_column, \
762 (Loc).last_line, (Loc).last_column)
764 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
769 /* YYLEX -- calling `yylex' with the right arguments. */
772 # define YYLEX yylex (&yylval, YYLEX_PARAM)
774 # define YYLEX yylex (&yylval)
777 /* Enable debugging if requested. */
781 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
782 # define YYFPRINTF fprintf
785 # define YYDPRINTF(Args) \
791 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
795 YYFPRINTF (stderr, "%s ", Title); \
796 yy_symbol_print (stderr, \
798 YYFPRINTF (stderr, "\n"); \
803 /*--------------------------------.
804 | Print this symbol on YYOUTPUT. |
805 `--------------------------------*/
808 #if (defined __STDC__ || defined __C99__FUNC__ \
809 || defined __cplusplus || defined _MSC_VER)
811 yy_symbol_value_print (FILE *yyoutput
, int yytype
, YYSTYPE
const * const yyvaluep
)
814 yy_symbol_value_print (yyoutput
, yytype
, yyvaluep
)
817 YYSTYPE
const * const yyvaluep
;
823 if (yytype
< YYNTOKENS
)
824 YYPRINT (yyoutput
, yytoknum
[yytype
], *yyvaluep
);
836 /*--------------------------------.
837 | Print this symbol on YYOUTPUT. |
838 `--------------------------------*/
840 #if (defined __STDC__ || defined __C99__FUNC__ \
841 || defined __cplusplus || defined _MSC_VER)
843 yy_symbol_print (FILE *yyoutput
, int yytype
, YYSTYPE
const * const yyvaluep
)
846 yy_symbol_print (yyoutput
, yytype
, yyvaluep
)
849 YYSTYPE
const * const yyvaluep
;
852 if (yytype
< YYNTOKENS
)
853 YYFPRINTF (yyoutput
, "token %s (", yytname
[yytype
]);
855 YYFPRINTF (yyoutput
, "nterm %s (", yytname
[yytype
]);
857 yy_symbol_value_print (yyoutput
, yytype
, yyvaluep
);
858 YYFPRINTF (yyoutput
, ")");
861 /*------------------------------------------------------------------.
862 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
864 `------------------------------------------------------------------*/
866 #if (defined __STDC__ || defined __C99__FUNC__ \
867 || defined __cplusplus || defined _MSC_VER)
869 yy_stack_print (yytype_int16
*bottom
, yytype_int16
*top
)
872 yy_stack_print (bottom
, top
)
873 yytype_int16
*bottom
;
877 YYFPRINTF (stderr
, "Stack now");
878 for (; bottom
<= top
; ++bottom
)
879 YYFPRINTF (stderr
, " %d", *bottom
);
880 YYFPRINTF (stderr
, "\n");
883 # define YY_STACK_PRINT(Bottom, Top) \
886 yy_stack_print ((Bottom), (Top)); \
890 /*------------------------------------------------.
891 | Report that the YYRULE is going to be reduced. |
892 `------------------------------------------------*/
894 #if (defined __STDC__ || defined __C99__FUNC__ \
895 || defined __cplusplus || defined _MSC_VER)
897 yy_reduce_print (YYSTYPE
*yyvsp
, int yyrule
)
900 yy_reduce_print (yyvsp
, yyrule
)
905 int yynrhs
= yyr2
[yyrule
];
907 unsigned long int yylno
= yyrline
[yyrule
];
908 YYFPRINTF (stderr
, "Reducing stack by rule %d (line %lu):\n",
910 /* The symbols being reduced. */
911 for (yyi
= 0; yyi
< yynrhs
; yyi
++)
913 fprintf (stderr
, " $%d = ", yyi
+ 1);
914 yy_symbol_print (stderr
, yyrhs
[yyprhs
[yyrule
] + yyi
],
915 &(yyvsp
[(yyi
+ 1) - (yynrhs
)])
917 fprintf (stderr
, "\n");
921 # define YY_REDUCE_PRINT(Rule) \
924 yy_reduce_print (yyvsp, Rule); \
927 /* Nonzero means print parse trace. It is left uninitialized so that
928 multiple parsers can coexist. */
931 # define YYDPRINTF(Args)
932 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
933 # define YY_STACK_PRINT(Bottom, Top)
934 # define YY_REDUCE_PRINT(Rule)
935 #endif /* !YYDEBUG */
938 /* YYINITDEPTH -- initial size of the parser's stacks. */
940 # define YYINITDEPTH 64
943 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
944 if the built-in stack extension method is used).
946 Do not make this value too large; the results are undefined if
947 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
948 evaluated with infinite-precision integer arithmetic. */
951 # define YYMAXDEPTH 10000
959 # if defined __GLIBC__ && defined _STRING_H
960 # define yystrlen strlen
962 /* Return the length of YYSTR. */
963 #if (defined __STDC__ || defined __C99__FUNC__ \
964 || defined __cplusplus || defined _MSC_VER)
966 yystrlen (const char *yystr
)
974 for (yylen
= 0; yystr
[yylen
]; yylen
++)
982 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
983 # define yystpcpy stpcpy
985 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
987 #if (defined __STDC__ || defined __C99__FUNC__ \
988 || defined __cplusplus || defined _MSC_VER)
990 yystpcpy (char *yydest
, const char *yysrc
)
993 yystpcpy (yydest
, yysrc
)
999 const char *yys
= yysrc
;
1001 while ((*yyd
++ = *yys
++) != '\0')
1010 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1011 quotes and backslashes, so that it's suitable for yyerror. The
1012 heuristic is that double-quoting is unnecessary unless the string
1013 contains an apostrophe, a comma, or backslash (other than
1014 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1015 null, do not copy; instead, return the length of what the result
1018 yytnamerr (char *yyres
, const char *yystr
)
1023 char const *yyp
= yystr
;
1030 goto do_not_strip_quotes
;
1034 goto do_not_strip_quotes
;
1047 do_not_strip_quotes
: ;
1051 return yystrlen (yystr
);
1053 return yystpcpy (yyres
, yystr
) - yyres
;
1057 /* Copy into YYRESULT an error message about the unexpected token
1058 YYCHAR while in state YYSTATE. Return the number of bytes copied,
1059 including the terminating null byte. If YYRESULT is null, do not
1060 copy anything; just return the number of bytes that would be
1061 copied. As a special case, return 0 if an ordinary "syntax error"
1062 message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1063 size calculation. */
1065 yysyntax_error (char *yyresult
, int yystate
, int yychar
)
1067 int yyn
= yypact
[yystate
];
1069 if (! (YYPACT_NINF
< yyn
&& yyn
<= YYLAST
))
1073 int yytype
= YYTRANSLATE (yychar
);
1074 YYSIZE_T yysize0
= yytnamerr (0, yytname
[yytype
]);
1075 YYSIZE_T yysize
= yysize0
;
1077 int yysize_overflow
= 0;
1078 enum { YYERROR_VERBOSE_ARGS_MAXIMUM
= 5 };
1079 char const *yyarg
[YYERROR_VERBOSE_ARGS_MAXIMUM
];
1083 /* This is so xgettext sees the translatable formats that are
1084 constructed on the fly. */
1085 YY_("syntax error, unexpected %s");
1086 YY_("syntax error, unexpected %s, expecting %s");
1087 YY_("syntax error, unexpected %s, expecting %s or %s");
1088 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1089 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1093 static char const yyunexpected
[] = "syntax error, unexpected %s";
1094 static char const yyexpecting
[] = ", expecting %s";
1095 static char const yyor
[] = " or %s";
1096 char yyformat
[sizeof yyunexpected
1097 + sizeof yyexpecting
- 1
1098 + ((YYERROR_VERBOSE_ARGS_MAXIMUM
- 2)
1099 * (sizeof yyor
- 1))];
1100 char const *yyprefix
= yyexpecting
;
1102 /* Start YYX at -YYN if negative to avoid negative indexes in
1104 int yyxbegin
= yyn
< 0 ? -yyn
: 0;
1106 /* Stay within bounds of both yycheck and yytname. */
1107 int yychecklim
= YYLAST
- yyn
+ 1;
1108 int yyxend
= yychecklim
< YYNTOKENS
? yychecklim
: YYNTOKENS
;
1111 yyarg
[0] = yytname
[yytype
];
1112 yyfmt
= yystpcpy (yyformat
, yyunexpected
);
1114 for (yyx
= yyxbegin
; yyx
< yyxend
; ++yyx
)
1115 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1117 if (yycount
== YYERROR_VERBOSE_ARGS_MAXIMUM
)
1121 yyformat
[sizeof yyunexpected
- 1] = '\0';
1124 yyarg
[yycount
++] = yytname
[yyx
];
1125 yysize1
= yysize
+ yytnamerr (0, yytname
[yyx
]);
1126 yysize_overflow
|= (yysize1
< yysize
);
1128 yyfmt
= yystpcpy (yyfmt
, yyprefix
);
1132 yyf
= YY_(yyformat
);
1133 yysize1
= yysize
+ yystrlen (yyf
);
1134 yysize_overflow
|= (yysize1
< yysize
);
1137 if (yysize_overflow
)
1138 return YYSIZE_MAXIMUM
;
1142 /* Avoid sprintf, as that infringes on the user's name space.
1143 Don't have undefined behavior even if the translation
1144 produced a string with the wrong number of "%s"s. */
1145 char *yyp
= yyresult
;
1147 while ((*yyp
= *yyf
) != '\0')
1149 if (*yyp
== '%' && yyf
[1] == 's' && yyi
< yycount
)
1151 yyp
+= yytnamerr (yyp
, yyarg
[yyi
++]);
1164 #endif /* YYERROR_VERBOSE */
1167 /*-----------------------------------------------.
1168 | Release the memory associated to this symbol. |
1169 `-----------------------------------------------*/
1172 #if (defined __STDC__ || defined __C99__FUNC__ \
1173 || defined __cplusplus || defined _MSC_VER)
1175 yydestruct (const char *yymsg
, int yytype
, YYSTYPE
*yyvaluep
)
1178 yydestruct (yymsg
, yytype
, yyvaluep
)
1188 YY_SYMBOL_PRINT (yymsg
, yytype
, yyvaluep
, yylocationp
);
1199 /* Prevent warnings from -Wmissing-prototypes. */
1201 #ifdef YYPARSE_PARAM
1202 #if defined __STDC__ || defined __cplusplus
1203 int yyparse (void *YYPARSE_PARAM
);
1207 #else /* ! YYPARSE_PARAM */
1208 #if defined __STDC__ || defined __cplusplus
1213 #endif /* ! YYPARSE_PARAM */
1224 #ifdef YYPARSE_PARAM
1225 #if (defined __STDC__ || defined __C99__FUNC__ \
1226 || defined __cplusplus || defined _MSC_VER)
1228 yyparse (void *YYPARSE_PARAM
)
1231 yyparse (YYPARSE_PARAM
)
1232 void *YYPARSE_PARAM
;
1234 #else /* ! YYPARSE_PARAM */
1235 #if (defined __STDC__ || defined __C99__FUNC__ \
1236 || defined __cplusplus || defined _MSC_VER)
1246 /* The look-ahead symbol. */
1249 /* The semantic value of the look-ahead symbol. */
1252 /* Number of syntax errors so far. */
1258 /* Number of tokens to shift before error messages enabled. */
1260 /* Look-ahead token as an internal (translated) token number. */
1263 /* Buffer for error messages, and its allocated size. */
1265 char *yymsg
= yymsgbuf
;
1266 YYSIZE_T yymsg_alloc
= sizeof yymsgbuf
;
1269 /* Three stacks and their tools:
1270 `yyss': related to states,
1271 `yyvs': related to semantic values,
1272 `yyls': related to locations.
1274 Refer to the stacks thru separate pointers, to allow yyoverflow
1275 to reallocate them elsewhere. */
1277 /* The state stack. */
1278 yytype_int16 yyssa
[YYINITDEPTH
];
1279 yytype_int16
*yyss
= yyssa
;
1280 yytype_int16
*yyssp
;
1282 /* The semantic value stack. */
1283 YYSTYPE yyvsa
[YYINITDEPTH
];
1284 YYSTYPE
*yyvs
= yyvsa
;
1289 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1291 YYSIZE_T yystacksize
= YYINITDEPTH
;
1293 /* The variables used to return semantic value and location from the
1298 /* The number of symbols on the RHS of the reduced rule.
1299 Keep to zero when no symbol should be popped. */
1302 YYDPRINTF ((stderr
, "Starting parse\n"));
1307 yychar
= YYEMPTY
; /* Cause a token to be read. */
1309 /* Initialize stack pointers.
1310 Waste one element of value and location stack
1311 so that they stay on the same level as the state stack.
1312 The wasted elements are never initialized. */
1319 /*------------------------------------------------------------.
1320 | yynewstate -- Push a new state, which is found in yystate. |
1321 `------------------------------------------------------------*/
1323 /* In all cases, when you get here, the value and location stacks
1324 have just been pushed. So pushing a state here evens the stacks. */
1330 if (yyss
+ yystacksize
- 1 <= yyssp
)
1332 /* Get the current used size of the three stacks, in elements. */
1333 YYSIZE_T yysize
= yyssp
- yyss
+ 1;
1337 /* Give user a chance to reallocate the stack. Use copies of
1338 these so that the &'s don't force the real ones into
1340 YYSTYPE
*yyvs1
= yyvs
;
1341 yytype_int16
*yyss1
= yyss
;
1344 /* Each stack pointer address is followed by the size of the
1345 data in use in that stack, in bytes. This used to be a
1346 conditional around just the two extra args, but that might
1347 be undefined if yyoverflow is a macro. */
1348 yyoverflow (YY_("memory exhausted"),
1349 &yyss1
, yysize
* sizeof (*yyssp
),
1350 &yyvs1
, yysize
* sizeof (*yyvsp
),
1357 #else /* no yyoverflow */
1358 # ifndef YYSTACK_RELOCATE
1359 goto yyexhaustedlab
;
1361 /* Extend the stack our own way. */
1362 if (YYMAXDEPTH
<= yystacksize
)
1363 goto yyexhaustedlab
;
1365 if (YYMAXDEPTH
< yystacksize
)
1366 yystacksize
= YYMAXDEPTH
;
1369 yytype_int16
*yyss1
= yyss
;
1370 union yyalloc
*yyptr
=
1371 (union yyalloc
*) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize
));
1373 goto yyexhaustedlab
;
1374 YYSTACK_RELOCATE (yyss
);
1375 YYSTACK_RELOCATE (yyvs
);
1377 # undef YYSTACK_RELOCATE
1379 YYSTACK_FREE (yyss1
);
1382 #endif /* no yyoverflow */
1384 yyssp
= yyss
+ yysize
- 1;
1385 yyvsp
= yyvs
+ yysize
- 1;
1388 YYDPRINTF ((stderr
, "Stack size increased to %lu\n",
1389 (unsigned long int) yystacksize
));
1391 if (yyss
+ yystacksize
- 1 <= yyssp
)
1395 YYDPRINTF ((stderr
, "Entering state %d\n", yystate
));
1404 /* Do appropriate processing given the current state. Read a
1405 look-ahead token if we need one and don't already have one. */
1407 /* First try to decide what to do without reference to look-ahead token. */
1408 yyn
= yypact
[yystate
];
1409 if (yyn
== YYPACT_NINF
)
1412 /* Not known => get a look-ahead token if don't already have one. */
1414 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1415 if (yychar
== YYEMPTY
)
1417 YYDPRINTF ((stderr
, "Reading a token: "));
1421 if (yychar
<= YYEOF
)
1423 yychar
= yytoken
= YYEOF
;
1424 YYDPRINTF ((stderr
, "Now at end of input.\n"));
1428 yytoken
= YYTRANSLATE (yychar
);
1429 YY_SYMBOL_PRINT ("Next token is", yytoken
, &yylval
, &yylloc
);
1432 /* If the proper action on seeing token YYTOKEN is to reduce or to
1433 detect an error, take that action. */
1435 if (yyn
< 0 || YYLAST
< yyn
|| yycheck
[yyn
] != yytoken
)
1440 if (yyn
== 0 || yyn
== YYTABLE_NINF
)
1449 /* Count tokens shifted since error; after three, turn off error
1454 /* Shift the look-ahead token. */
1455 YY_SYMBOL_PRINT ("Shifting", yytoken
, &yylval
, &yylloc
);
1457 /* Discard the shifted token unless it is eof. */
1458 if (yychar
!= YYEOF
)
1467 /*-----------------------------------------------------------.
1468 | yydefault -- do the default action for the current state. |
1469 `-----------------------------------------------------------*/
1471 yyn
= yydefact
[yystate
];
1477 /*-----------------------------.
1478 | yyreduce -- Do a reduction. |
1479 `-----------------------------*/
1481 /* yyn is the number of a rule to reduce with. */
1484 /* If YYLEN is nonzero, implement the default value of the action:
1487 Otherwise, the following line sets YYVAL to garbage.
1488 This behavior is undocumented and Bison
1489 users should not rely upon it. Assigning to YYVAL
1490 unconditionally makes the parser a bit smaller, and it avoids a
1491 GCC warning that YYVAL may be used uninitialized. */
1492 yyval
= yyvsp
[1-yylen
];
1495 YY_REDUCE_PRINT (yyn
);
1499 #line 149 "OSUnserializeXML.y"
1500 { yyerror("unexpected end of buffer");
1506 #line 152 "OSUnserializeXML.y"
1507 { STATE
->parsedObject
= (yyvsp
[(1) - (1)])->object
;
1508 (yyvsp
[(1) - (1)])->object
= 0;
1509 freeObject(STATE
, (yyvsp
[(1) - (1)]));
1515 #line 157 "OSUnserializeXML.y"
1516 { yyerror("syntax error");
1522 #line 162 "OSUnserializeXML.y"
1523 { (yyval
) = buildDictionary(STATE
, (yyvsp
[(1) - (1)]));
1525 if (!yyval
->object
) {
1526 yyerror("buildDictionary");
1529 STATE
->parsedObjectCount
++;
1530 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1531 yyerror("maximum object count");
1538 #line 174 "OSUnserializeXML.y"
1539 { (yyval
) = buildArray(STATE
, (yyvsp
[(1) - (1)]));
1541 if (!yyval
->object
) {
1542 yyerror("buildArray");
1545 STATE
->parsedObjectCount
++;
1546 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1547 yyerror("maximum object count");
1554 #line 186 "OSUnserializeXML.y"
1555 { (yyval
) = buildSet(STATE
, (yyvsp
[(1) - (1)]));
1557 if (!yyval
->object
) {
1558 yyerror("buildSet");
1561 STATE
->parsedObjectCount
++;
1562 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1563 yyerror("maximum object count");
1570 #line 198 "OSUnserializeXML.y"
1571 { (yyval
) = buildString(STATE
, (yyvsp
[(1) - (1)]));
1573 if (!yyval
->object
) {
1574 yyerror("buildString");
1577 STATE
->parsedObjectCount
++;
1578 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1579 yyerror("maximum object count");
1586 #line 210 "OSUnserializeXML.y"
1587 { (yyval
) = buildData(STATE
, (yyvsp
[(1) - (1)]));
1589 if (!yyval
->object
) {
1590 yyerror("buildData");
1593 STATE
->parsedObjectCount
++;
1594 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1595 yyerror("maximum object count");
1602 #line 222 "OSUnserializeXML.y"
1603 { (yyval
) = buildNumber(STATE
, (yyvsp
[(1) - (1)]));
1605 if (!yyval
->object
) {
1606 yyerror("buildNumber");
1609 STATE
->parsedObjectCount
++;
1610 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1611 yyerror("maximum object count");
1618 #line 234 "OSUnserializeXML.y"
1619 { (yyval
) = buildBoolean(STATE
, (yyvsp
[(1) - (1)]));
1621 if (!yyval
->object
) {
1622 yyerror("buildBoolean");
1625 STATE
->parsedObjectCount
++;
1626 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1627 yyerror("maximum object count");
1634 #line 246 "OSUnserializeXML.y"
1635 { (yyval
) = retrieveObject(STATE
, (yyvsp
[(1) - (1)])->idref
);
1637 STATE
->retrievedObjectCount
++;
1638 if (STATE
->retrievedObjectCount
> MAX_REFED_OBJECTS
) {
1639 yyerror("maximum object reference count");
1642 (yyval
)->object
->retain();
1644 yyerror("forward reference detected");
1647 freeObject(STATE
, (yyvsp
[(1) - (1)]));
1649 STATE
->parsedObjectCount
++;
1650 if (STATE
->parsedObjectCount
> MAX_OBJECTS
) {
1651 yyerror("maximum object count");
1658 #line 265 "OSUnserializeXML.y"
1659 { (yyval
) = (yyvsp
[(1) - (2)]);
1660 (yyval
)->elements
= NULL
;
1665 #line 268 "OSUnserializeXML.y"
1666 { (yyval
) = (yyvsp
[(1) - (3)]);
1667 (yyval
)->elements
= (yyvsp
[(2) - (3)]);
1672 #line 275 "OSUnserializeXML.y"
1673 { (yyval
) = (yyvsp
[(2) - (2)]);
1674 (yyval
)->next
= (yyvsp
[(1) - (2)]);
1679 if (o
->key
== (yyval
)->key
) {
1680 yyerror("duplicate dictionary key");
1689 #line 290 "OSUnserializeXML.y"
1690 { (yyval
) = (yyvsp
[(1) - (2)]);
1691 (yyval
)->key
= (OSSymbol
*)(yyval
)->object
;
1692 (yyval
)->object
= (yyvsp
[(2) - (2)])->object
;
1693 (yyval
)->next
= NULL
;
1694 (yyvsp
[(2) - (2)])->object
= 0;
1695 freeObject(STATE
, (yyvsp
[(2) - (2)]));
1700 #line 299 "OSUnserializeXML.y"
1701 { (yyval
) = buildSymbol(STATE
, (yyvsp
[(1) - (1)]));
1703 // STATE->parsedObjectCount++;
1704 // if (STATE->parsedObjectCount > MAX_OBJECTS) {
1705 // yyerror("maximum object count");
1712 #line 311 "OSUnserializeXML.y"
1713 { (yyval
) = (yyvsp
[(1) - (2)]);
1714 (yyval
)->elements
= NULL
;
1719 #line 314 "OSUnserializeXML.y"
1720 { (yyval
) = (yyvsp
[(1) - (3)]);
1721 (yyval
)->elements
= (yyvsp
[(2) - (3)]);
1726 #line 320 "OSUnserializeXML.y"
1727 { (yyval
) = (yyvsp
[(1) - (2)]);
1728 (yyval
)->elements
= NULL
;
1733 #line 323 "OSUnserializeXML.y"
1734 { (yyval
) = (yyvsp
[(1) - (3)]);
1735 (yyval
)->elements
= (yyvsp
[(2) - (3)]);
1740 #line 329 "OSUnserializeXML.y"
1741 { (yyval
) = (yyvsp
[(1) - (1)]);
1742 (yyval
)->next
= NULL
;
1747 #line 332 "OSUnserializeXML.y"
1748 { (yyval
) = (yyvsp
[(2) - (2)]);
1749 (yyval
)->next
= (yyvsp
[(1) - (2)]);
1754 /* Line 1267 of yacc.c. */
1755 #line 1699 "OSUnserializeXML.tab.c"
1758 YY_SYMBOL_PRINT ("-> $$ =", yyr1
[yyn
], &yyval
, &yyloc
);
1762 YY_STACK_PRINT (yyss
, yyssp
);
1767 /* Now `shift' the result of the reduction. Determine what state
1768 that goes to, based on the state we popped back to and the rule
1769 number reduced by. */
1773 yystate
= yypgoto
[yyn
- YYNTOKENS
] + *yyssp
;
1774 if (0 <= yystate
&& yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
1775 yystate
= yytable
[yystate
];
1777 yystate
= yydefgoto
[yyn
- YYNTOKENS
];
1782 /*------------------------------------.
1783 | yyerrlab -- here on detecting error |
1784 `------------------------------------*/
1786 /* If not already recovering from an error, report this error. */
1790 #if ! YYERROR_VERBOSE
1791 yyerror (YY_("syntax error"));
1794 YYSIZE_T yysize
= yysyntax_error (0, yystate
, yychar
);
1795 if (yymsg_alloc
< yysize
&& yymsg_alloc
< YYSTACK_ALLOC_MAXIMUM
)
1797 YYSIZE_T yyalloc
= 2 * yysize
;
1798 if (! (yysize
<= yyalloc
&& yyalloc
<= YYSTACK_ALLOC_MAXIMUM
))
1799 yyalloc
= YYSTACK_ALLOC_MAXIMUM
;
1800 if (yymsg
!= yymsgbuf
)
1801 YYSTACK_FREE (yymsg
);
1802 yymsg
= (char *) YYSTACK_ALLOC (yyalloc
);
1804 yymsg_alloc
= yyalloc
;
1808 yymsg_alloc
= sizeof yymsgbuf
;
1812 if (0 < yysize
&& yysize
<= yymsg_alloc
)
1814 (void) yysyntax_error (yymsg
, yystate
, yychar
);
1819 yyerror (YY_("syntax error"));
1821 goto yyexhaustedlab
;
1829 if (yyerrstatus
== 3)
1831 /* If just tried and failed to reuse look-ahead token after an
1832 error, discard it. */
1834 if (yychar
<= YYEOF
)
1836 /* Return failure if at end of input. */
1837 if (yychar
== YYEOF
)
1842 yydestruct ("Error: discarding",
1848 /* Else will try to reuse look-ahead token after shifting the error
1853 /*---------------------------------------------------.
1854 | yyerrorlab -- error raised explicitly by YYERROR. |
1855 `---------------------------------------------------*/
1858 /* Pacify compilers like GCC when the user code never invokes
1859 YYERROR and the label yyerrorlab therefore never appears in user
1861 if (/*CONSTCOND*/ 0)
1864 /* Do not reclaim the symbols of the rule which action triggered
1868 YY_STACK_PRINT (yyss
, yyssp
);
1873 /*-------------------------------------------------------------.
1874 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1875 `-------------------------------------------------------------*/
1877 yyerrstatus
= 3; /* Each real token shifted decrements this. */
1881 yyn
= yypact
[yystate
];
1882 if (yyn
!= YYPACT_NINF
)
1885 if (0 <= yyn
&& yyn
<= YYLAST
&& yycheck
[yyn
] == YYTERROR
)
1893 /* Pop the current state because it cannot handle the error token. */
1898 yydestruct ("Error: popping",
1899 yystos
[yystate
], yyvsp
);
1902 YY_STACK_PRINT (yyss
, yyssp
);
1911 /* Shift the error token. */
1912 YY_SYMBOL_PRINT ("Shifting", yystos
[yyn
], yyvsp
, yylsp
);
1918 /*-------------------------------------.
1919 | yyacceptlab -- YYACCEPT comes here. |
1920 `-------------------------------------*/
1925 /*-----------------------------------.
1926 | yyabortlab -- YYABORT comes here. |
1927 `-----------------------------------*/
1933 /*-------------------------------------------------.
1934 | yyexhaustedlab -- memory exhaustion comes here. |
1935 `-------------------------------------------------*/
1937 yyerror (YY_("memory exhausted"));
1943 if (yychar
!= YYEOF
&& yychar
!= YYEMPTY
)
1944 yydestruct ("Cleanup: discarding lookahead",
1946 /* Do not reclaim the symbols of the rule which action triggered
1947 this YYABORT or YYACCEPT. */
1949 YY_STACK_PRINT (yyss
, yyssp
);
1950 while (yyssp
!= yyss
)
1952 yydestruct ("Cleanup: popping",
1953 yystos
[*yyssp
], yyvsp
);
1958 YYSTACK_FREE (yyss
);
1961 if (yymsg
!= yymsgbuf
)
1962 YYSTACK_FREE (yymsg
);
1964 /* Make sure YYID is used. */
1965 return YYID (yyresult
);
1969 #line 354 "OSUnserializeXML.y"
1973 OSUnserializeerror(parser_state_t
* state
, const char *s
) /* Called by yyparse on errors */
1975 if (state
->errorString
) {
1976 char tempString
[128];
1977 snprintf(tempString
, 128, "OSUnserializeXML: %s near line %d\n", s
, state
->lineNumber
);
1978 *(state
->errorString
) = OSString::withCString(tempString
);
1984 #define TAG_MAX_LENGTH 32
1985 #define TAG_MAX_ATTRIBUTES 32
1990 #define TAG_IGNORE 4
1992 #define currentChar() (state->parseBuffer[state->parseBufferIndex])
1993 #define nextChar() (state->parseBuffer[++state->parseBufferIndex])
1994 #define prevChar() (state->parseBuffer[state->parseBufferIndex - 1])
1996 #define isSpace(c) ((c) == ' ' || (c) == '\t')
1997 #define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1998 #define isDigit(c) ((c) >= '0' && (c) <= '9')
1999 #define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
2000 #define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
2001 #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
2004 getTag(parser_state_t
*state
,
2005 char tag
[TAG_MAX_LENGTH
],
2006 int *attributeCount
,
2007 char attributes
[TAG_MAX_ATTRIBUTES
][TAG_MAX_LENGTH
],
2008 char values
[TAG_MAX_ATTRIBUTES
][TAG_MAX_LENGTH
] )
2011 int c
= currentChar();
2012 int tagType
= TAG_START
;
2014 *attributeCount
= 0;
2016 if (c
!= '<') return TAG_BAD
;
2017 c
= nextChar(); // skip '<'
2020 // <!TAG declarations >
2021 // <!-- comments -->
2024 bool isComment
= (c
== '-') && ((c
= nextChar()) != 0) && (c
== '-');
2025 if (!isComment
&& !isAlpha(c
)) return TAG_BAD
; // <!1, <!-A, <!eos
2027 while (c
&& (c
= nextChar()) != 0) {
2028 if (c
== '\n') state
->lineNumber
++;
2030 if (c
!= '-') continue;
2032 if (c
!= '-') continue;
2039 if (isComment
) break;
2046 // <? Processing Instructions ?>
2048 while ((c
= nextChar()) != 0) {
2049 if (c
== '\n') state
->lineNumber
++;
2050 if (c
!= '?') continue;
2052 if (!c
) return TAG_IGNORE
;
2065 c
= nextChar(); // skip '/'
2068 if (!isAlpha(c
)) return TAG_BAD
;
2070 /* find end of tag while copying it */
2071 while (isAlphaNumeric(c
)) {
2074 if (length
>= (TAG_MAX_LENGTH
- 1)) return TAG_BAD
;
2079 // printf("tag %s, type %d\n", tag, tagType);
2081 // look for attributes of the form attribute = "value" ...
2082 while ((c
!= '>') && (c
!= '/')) {
2083 while (isSpace(c
)) c
= nextChar();
2086 while (isAlphaNumeric(c
)) {
2087 attributes
[*attributeCount
][length
++] = c
;
2088 if (length
>= (TAG_MAX_LENGTH
- 1)) return TAG_BAD
;
2091 attributes
[*attributeCount
][length
] = 0;
2093 while (isSpace(c
)) c
= nextChar();
2095 if (c
!= '=') return TAG_BAD
;
2098 while (isSpace(c
)) c
= nextChar();
2100 if (c
!= '"') return TAG_BAD
;
2104 values
[*attributeCount
][length
++] = c
;
2105 if (length
>= (TAG_MAX_LENGTH
- 1)) return TAG_BAD
;
2107 if (!c
) return TAG_BAD
;
2109 values
[*attributeCount
][length
] = 0;
2111 c
= nextChar(); // skip closing quote
2113 // printf(" attribute '%s' = '%s', nextchar = '%c'\n",
2114 // attributes[*attributeCount], values[*attributeCount], c);
2116 (*attributeCount
)++;
2117 if (*attributeCount
>= TAG_MAX_ATTRIBUTES
) return TAG_BAD
;
2121 c
= nextChar(); // skip '/'
2122 tagType
= TAG_EMPTY
;
2124 if (c
!= '>') return TAG_BAD
;
2125 c
= nextChar(); // skip '>'
2131 getString(parser_state_t
*state
)
2133 int c
= currentChar();
2134 int start
, length
, i
, j
;
2137 start
= state
->parseBufferIndex
;
2138 /* find end of string */
2141 if (c
== '\n') state
->lineNumber
++;
2148 if (c
!= '<') return 0;
2150 length
= state
->parseBufferIndex
- start
;
2152 /* copy to null terminated buffer */
2153 tempString
= (char *)malloc(length
+ 1);
2154 if (tempString
== 0) {
2155 printf("OSUnserializeXML: can't alloc temp memory\n");
2159 // copy out string in tempString
2160 // "&" -> '&', "<" -> '<', ">" -> '>'
2163 while (i
< length
) {
2164 c
= state
->parseBuffer
[start
+ i
++];
2166 tempString
[j
++] = c
;
2168 if ((i
+3) > length
) goto error
;
2169 c
= state
->parseBuffer
[start
+ i
++];
2171 if (state
->parseBuffer
[start
+ i
++] != 't') goto error
;
2172 if (state
->parseBuffer
[start
+ i
++] != ';') goto error
;
2173 tempString
[j
++] = '<';
2177 if (state
->parseBuffer
[start
+ i
++] != 't') goto error
;
2178 if (state
->parseBuffer
[start
+ i
++] != ';') goto error
;
2179 tempString
[j
++] = '>';
2182 if ((i
+3) > length
) goto error
;
2184 if (state
->parseBuffer
[start
+ i
++] != 'm') goto error
;
2185 if (state
->parseBuffer
[start
+ i
++] != 'p') goto error
;
2186 if (state
->parseBuffer
[start
+ i
++] != ';') goto error
;
2187 tempString
[j
++] = '&';
2195 // printf("string %s\n", tempString);
2200 if (tempString
) free(tempString
);
2205 getNumber(parser_state_t
*state
)
2207 unsigned long long n
= 0;
2209 bool negate
= false;
2210 int c
= currentChar();
2225 n
= (n
* base
+ c
- '0');
2229 n
= (unsigned long long)((long long)n
* (long long)-1);
2232 while(isHexDigit(c
)) {
2234 n
= (n
* base
+ c
- '0');
2236 n
= (n
* base
+ 0xa + c
- 'a');
2241 // printf("number 0x%x\n", (unsigned long)n);
2245 // taken from CFXMLParsing/CFPropertyList.c
2247 static const signed char __CFPLDataDecodeTable
[128] = {
2248 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
2249 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
2250 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
2251 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
2252 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
2253 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
2254 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
2255 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
2256 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
2257 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
2258 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
2259 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
2260 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
2261 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
2262 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
2263 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
2266 #define DATA_ALLOC_SIZE 4096
2269 getCFEncodedData(parser_state_t
*state
, unsigned int *size
)
2271 int numeq
= 0, acc
= 0, cntr
= 0;
2272 int tmpbufpos
= 0, tmpbuflen
= 0;
2273 unsigned char *tmpbuf
= (unsigned char *)malloc(DATA_ALLOC_SIZE
);
2275 int c
= currentChar();
2284 if (c
== '=') numeq
++; else numeq
= 0;
2285 if (c
== '\n') state
->lineNumber
++;
2286 if (__CFPLDataDecodeTable
[c
] < 0) {
2292 acc
+= __CFPLDataDecodeTable
[c
];
2293 if (0 == (cntr
& 0x3)) {
2294 if (tmpbuflen
<= tmpbufpos
+ 2) {
2295 tmpbuflen
+= DATA_ALLOC_SIZE
;
2296 tmpbuf
= (unsigned char *)realloc(tmpbuf
, tmpbuflen
);
2298 tmpbuf
[tmpbufpos
++] = (acc
>> 16) & 0xff;
2300 tmpbuf
[tmpbufpos
++] = (acc
>> 8) & 0xff;
2302 tmpbuf
[tmpbufpos
++] = acc
& 0xff;
2315 getHexData(parser_state_t
*state
, unsigned int *size
)
2318 unsigned char *d
, *start
, *lastStart
;
2320 start
= lastStart
= d
= (unsigned char *)malloc(DATA_ALLOC_SIZE
);
2325 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
2327 state
->lineNumber
++;
2334 *d
= (c
- '0') << 4;
2335 } else if (isAlphaDigit(c
)) {
2336 *d
= (0xa + (c
- 'a')) << 4;
2345 } else if (isAlphaDigit(c
)) {
2346 *d
|= 0xa + (c
- 'a');
2352 if ((d
- lastStart
) >= DATA_ALLOC_SIZE
) {
2353 int oldsize
= d
- start
;
2354 start
= (unsigned char *)realloc(start
, oldsize
+ DATA_ALLOC_SIZE
);
2355 d
= lastStart
= start
+ oldsize
;
2371 yylex(YYSTYPE
*lvalp
, parser_state_t
*state
)
2375 char tag
[TAG_MAX_LENGTH
];
2377 char attributes
[TAG_MAX_ATTRIBUTES
][TAG_MAX_LENGTH
];
2378 char values
[TAG_MAX_ATTRIBUTES
][TAG_MAX_LENGTH
];
2384 /* skip white space */
2385 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
2387 /* keep track of line number, don't return \n's */
2389 STATE
->lineNumber
++;
2394 // end of the buffer?
2397 tagType
= getTag(STATE
, tag
, &attributeCount
, attributes
, values
);
2398 if (tagType
== TAG_BAD
) return SYNTAX_ERROR
;
2399 if (tagType
== TAG_IGNORE
) goto top
;
2401 // handle allocation and check for "ID" and "IDREF" tags up front
2402 *lvalp
= object
= newObject(STATE
);
2404 for (i
=0; i
< attributeCount
; i
++) {
2405 if (attributes
[i
][0] == 'I' && attributes
[i
][1] == 'D') {
2406 // check for idref's, note: we ignore the tag, for
2407 // this to work correctly, all idrefs must be unique
2408 // across the whole serialization
2409 if (attributes
[i
][2] == 'R' && attributes
[i
][3] == 'E' &&
2410 attributes
[i
][4] == 'F' && !attributes
[i
][5]) {
2411 if (tagType
!= TAG_EMPTY
) return SYNTAX_ERROR
;
2412 object
->idref
= strtol(values
[i
], NULL
, 0);
2416 if (!attributes
[i
][2]) {
2417 object
->idref
= strtol(values
[i
], NULL
, 0);
2419 return SYNTAX_ERROR
;
2426 if (!strcmp(tag
, "array")) {
2427 if (tagType
== TAG_EMPTY
) {
2428 object
->elements
= NULL
;
2431 return (tagType
== TAG_START
) ? '(' : ')';
2435 if (!strcmp(tag
, "dict")) {
2436 if (tagType
== TAG_EMPTY
) {
2437 object
->elements
= NULL
;
2440 return (tagType
== TAG_START
) ? '{' : '}';
2442 if (!strcmp(tag
, "data")) {
2444 if (tagType
== TAG_EMPTY
) {
2445 object
->data
= NULL
;
2450 bool isHexFormat
= false;
2451 for (i
=0; i
< attributeCount
; i
++) {
2452 if (!strcmp(attributes
[i
], "format") && !strcmp(values
[i
], "hex")) {
2457 // CF encoded is the default form
2459 object
->data
= getHexData(STATE
, &size
);
2461 object
->data
= getCFEncodedData(STATE
, &size
);
2463 object
->size
= size
;
2464 if ((getTag(STATE
, tag
, &attributeCount
, attributes
, values
) != TAG_END
) || strcmp(tag
, "data")) {
2465 return SYNTAX_ERROR
;
2471 if (!strcmp(tag
, "false")) {
2472 if (tagType
== TAG_EMPTY
) {
2479 if (!strcmp(tag
, "integer")) {
2480 object
->size
= 64; // default
2481 for (i
=0; i
< attributeCount
; i
++) {
2482 if (!strcmp(attributes
[i
], "size")) {
2483 object
->size
= strtoul(values
[i
], NULL
, 0);
2486 if (tagType
== TAG_EMPTY
) {
2490 object
->number
= getNumber(STATE
);
2491 if ((getTag(STATE
, tag
, &attributeCount
, attributes
, values
) != TAG_END
) || strcmp(tag
, "integer")) {
2492 return SYNTAX_ERROR
;
2498 if (!strcmp(tag
, "key")) {
2499 if (tagType
== TAG_EMPTY
) return SYNTAX_ERROR
;
2500 object
->string
= getString(STATE
);
2501 if (!object
->string
) {
2502 return SYNTAX_ERROR
;
2504 if ((getTag(STATE
, tag
, &attributeCount
, attributes
, values
) != TAG_END
)
2505 || strcmp(tag
, "key")) {
2506 return SYNTAX_ERROR
;
2512 if (!strcmp(tag
, "plist")) {
2513 freeObject(STATE
, object
);
2518 if (!strcmp(tag
, "string")) {
2519 if (tagType
== TAG_EMPTY
) {
2520 object
->string
= (char *)malloc(1);
2521 object
->string
[0] = 0;
2524 object
->string
= getString(STATE
);
2525 if (!object
->string
) {
2526 return SYNTAX_ERROR
;
2528 if ((getTag(STATE
, tag
, &attributeCount
, attributes
, values
) != TAG_END
)
2529 || strcmp(tag
, "string")) {
2530 return SYNTAX_ERROR
;
2534 if (!strcmp(tag
, "set")) {
2535 if (tagType
== TAG_EMPTY
) {
2536 object
->elements
= NULL
;
2539 if (tagType
== TAG_START
) {
2547 if (!strcmp(tag
, "true")) {
2548 if (tagType
== TAG_EMPTY
) {
2556 return SYNTAX_ERROR
;
2559 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2560 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2561 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2563 // "java" like allocation, if this code hits a syntax error in the
2564 // the middle of the parsed string we just bail with pointers hanging
2565 // all over place, this code helps keeps it all together
2567 //static int object_count = 0;
2570 newObject(parser_state_t
*state
)
2574 if (state
->freeObjects
) {
2575 o
= state
->freeObjects
;
2576 state
->freeObjects
= state
->freeObjects
->next
;
2578 o
= (object_t
*)malloc(sizeof(object_t
));
2580 bzero(o
, sizeof(object_t
));
2581 o
->free
= state
->objects
;
2589 freeObject(parser_state_t
* state
, object_t
*o
)
2591 o
->next
= state
->freeObjects
;
2592 state
->freeObjects
= o
;
2596 cleanupObjects(parser_state_t
*state
)
2598 object_t
*t
, *o
= state
->objects
;
2602 // printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
2603 o
->object
->release();
2606 // printf("OSUnserializeXML: freeing object o=%x data=%x\n", (int)o, (int)o->data);
2610 // printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
2614 // printf("OSUnserializeXML: freeing object o=%x string=%x\n", (int)o, (int)o->string);
2623 // printf("object_count = %d\n", object_count);
2626 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2627 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2628 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2631 rememberObject(parser_state_t
*state
, int tag
, OSObject
*o
)
2634 snprintf(key
, 16, "%u", tag
);
2636 // printf("remember key %s\n", key);
2638 state
->tags
->setObject(key
, o
);
2642 retrieveObject(parser_state_t
*state
, int tag
)
2647 snprintf(key
, 16, "%u", tag
);
2649 // printf("retrieve key '%s'\n", key);
2651 ref
= state
->tags
->getObject(key
);
2654 o
= newObject(state
);
2659 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2660 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2661 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2664 buildDictionary(parser_state_t
*state
, object_t
* header
)
2670 // get count and reverse order
2671 o
= header
->elements
;
2672 header
->elements
= 0;
2678 t
->next
= header
->elements
;
2679 header
->elements
= t
;
2682 dict
= OSDictionary::withCapacity(count
);
2683 if (header
->idref
>= 0) rememberObject(state
, header
->idref
, dict
);
2685 o
= header
->elements
;
2687 dict
->setObject(o
->key
, o
->object
);
2690 o
->object
->release();
2696 freeObject(state
, t
);
2704 buildArray(parser_state_t
*state
, object_t
* header
)
2710 // get count and reverse order
2711 o
= header
->elements
;
2712 header
->elements
= 0;
2718 t
->next
= header
->elements
;
2719 header
->elements
= t
;
2722 array
= OSArray::withCapacity(count
);
2723 if (header
->idref
>= 0) rememberObject(state
, header
->idref
, array
);
2725 o
= header
->elements
;
2727 array
->setObject(o
->object
);
2729 o
->object
->release();
2734 freeObject(state
, t
);
2742 buildSet(parser_state_t
*state
, object_t
*header
)
2744 object_t
*o
= buildArray(state
, header
);
2746 OSArray
*array
= (OSArray
*)o
->object
;
2747 OSSet
*set
= OSSet::withArray(array
, array
->getCapacity());
2749 // write over the reference created in buildArray
2750 if (header
->idref
>= 0) rememberObject(state
, header
->idref
, set
);
2758 buildString(parser_state_t
*state
, object_t
*o
)
2762 string
= OSString::withCString(o
->string
);
2763 if (o
->idref
>= 0) rememberObject(state
, o
->idref
, string
);
2773 buildSymbol(parser_state_t
*state
, object_t
*o
)
2777 symbol
= const_cast<OSSymbol
*>(OSSymbol::withCString(o
->string
));
2778 if (o
->idref
>= 0) rememberObject(state
, o
->idref
, symbol
);
2788 buildData(parser_state_t
*state
, object_t
*o
)
2793 data
= OSData::withBytes(o
->data
, o
->size
);
2795 data
= OSData::withCapacity(0);
2797 if (o
->idref
>= 0) rememberObject(state
, o
->idref
, data
);
2799 if (o
->size
) free(o
->data
);
2806 buildNumber(parser_state_t
*state
, object_t
*o
)
2808 OSNumber
*number
= OSNumber::withNumber(o
->number
, o
->size
);
2810 if (o
->idref
>= 0) rememberObject(state
, o
->idref
, number
);
2817 buildBoolean(parser_state_t
*state __unused
, object_t
*o
)
2819 o
->object
= ((o
->number
== 0) ? kOSBooleanFalse
: kOSBooleanTrue
);
2820 o
->object
->retain();
2825 OSUnserializeXML(const char *buffer
, OSString
**errorString
)
2829 if (!buffer
) return 0;
2830 parser_state_t
*state
= (parser_state_t
*)malloc(sizeof(parser_state_t
));
2831 if (!state
) return 0;
2834 if (errorString
) *errorString
= NULL
;
2836 state
->parseBuffer
= buffer
;
2837 state
->parseBufferIndex
= 0;
2838 state
->lineNumber
= 1;
2840 state
->freeObjects
= 0;
2841 state
->tags
= OSDictionary::withCapacity(128);
2842 state
->errorString
= errorString
;
2843 state
->parsedObject
= 0;
2844 state
->parsedObjectCount
= 0;
2845 state
->retrievedObjectCount
= 0;
2847 (void)yyparse((void *)state
);
2849 object
= state
->parsedObject
;
2851 cleanupObjects(state
);
2852 state
->tags
->release();
2858 #include <libkern/OSSerializeBinary.h>
2861 OSUnserializeXML(const char *buffer
, size_t bufferSize
, OSString
**errorString
)
2863 if (!buffer
) return (0);
2864 if (bufferSize
< sizeof(kOSSerializeBinarySignature
)) return (0);
2866 if (!strcmp(kOSSerializeBinarySignature
, buffer
)) return OSUnserializeBinary(buffer
, bufferSize
, errorString
);
2868 // XML must be null terminated
2869 if (buffer
[bufferSize
- 1]) return 0;
2871 return OSUnserializeXML(buffer
, errorString
);
2880 // DO NOT EDIT OSUnserializeXML.cpp!