1 /*
2  * Copyright (c) 1999-2019 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
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.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
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.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 /*
30  * HISTORY
31  *
32  * OSUnserializeXML.y created by rsulack on Tue Oct 12 1999
33  */
34 
35 // parser for unserializing OSContainer objects serialized to XML
36 //
37 // to build :
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
41 //
42 //	when changing code check in both OSUnserializeXML.y and OSUnserializeXML.cpp
43 //
44 //
45 //
46 //
47 //
48 //		 DO NOT EDIT OSUnserializeXML.cpp!
49 //
50 //			this means you!
51 /* A Bison parser, made by GNU Bison 2.3.  */
52 
53 /* Skeleton implementation for Bison's Yacc-like parsers in C
54  *
55  *  Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
56  *  Free Software Foundation, Inc.
57  *
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)
61  *  any later version.
62  *
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.
67  *
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.  */
72 
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.
82  *
83  *  This special exception was added by the Free Software Foundation in
84  *  version 2.2 of Bison.  */
85 
86 /* C LALR(1) parser skeleton written by Richard Stallman, by
87 *  simplifying the original so-called "semantic" parser.  */
88 
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.  */
95 
96 /* Identify Bison output.  */
97 #define YYBISON 1
98 
99 /* Bison version.  */
100 #define YYBISON_VERSION "2.3"
101 
102 /* Skeleton name.  */
103 #define YYSKELETON_NAME "yacc.c"
104 
105 /* Pure parsers.  */
106 #define YYPURE 1
107 
108 /* Using locations.  */
109 #define YYLSP_NEEDED 0
110 
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
119 
120 
121 /* Tokens.  */
122 #ifndef YYTOKENTYPE
123 # define YYTOKENTYPE
124 /* Put the tokens into the symbol table, so that GDB and other debuggers
125  *  know about them.  */
126 enum yytokentype {
127 	ARRAY = 258,
128 	BOOLEAN = 259,
129 	DATA = 260,
130 	DICTIONARY = 261,
131 	IDREF = 262,
132 	KEY = 263,
133 	NUMBER = 264,
134 	SET = 265,
135 	STRING = 266,
136 	SYNTAX_ERROR = 267
137 };
138 #endif
139 /* Tokens.  */
140 #define ARRAY 258
141 #define BOOLEAN 259
142 #define DATA 260
143 #define DICTIONARY 261
144 #define IDREF 262
145 #define KEY 263
146 #define NUMBER 264
147 #define SET 265
148 #define STRING 266
149 #define SYNTAX_ERROR 267
150 
151 
152 
153 
154 /* Copy the first part of user declarations.  */
155 #line 61 "OSUnserializeXML.y"
156 
157 #include <string.h>
158 #include <libkern/c++/OSMetaClass.h>
159 #include <libkern/c++/OSContainers.h>
160 #include <libkern/c++/OSLib.h>
161 
162 #define MAX_OBJECTS              131071
163 #define MAX_REFED_OBJECTS        65535
164 
165 #define YYSTYPE object_t *
166 #define YYPARSE_PARAM   state
167 #define YYLEX_PARAM     (parser_state_t *)state
168 
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 {
172 	struct object   *next;
173 	struct object   *free;
174 	struct object   *elements;
175 	OSObject        *object;
176 	OSSymbol        *key;                   // for dictionary
177 	int             size;
178 	void            *data;                  // for data
179 	char            *string;                // for string & symbol
180 	int             string_alloc_length;
181 	long long       number;                 // for number
182 	int             idref;
183 } object_t;
184 
185 // this code is reentrant, this structure contains all
186 // state information for the parsing of a single buffer
187 typedef struct parser_state {
188 	const char      *parseBuffer;           // start of text to be parsed
189 	int             parseBufferIndex;       // current index into text
190 	int             lineNumber;             // current line number
191 	object_t        *objects;               // internal objects in use
192 	object_t        *freeObjects;           // internal objects that are free
193 	OSDictionary    *tags;                  // used to remember "ID" tags
194 	OSString        **errorString;          // parse error with line
195 	OSObject        *parsedObject;          // resultant object of parsed text
196 	int             parsedObjectCount;
197 	int             retrievedObjectCount;
198 } parser_state_t;
199 
200 #define STATE           ((parser_state_t *)state)
201 
202 #undef yyerror
203 #define yyerror(s)      OSUnserializeerror(STATE, (s))
204 static int              OSUnserializeerror(parser_state_t *state, const char *s);
205 
206 static int              yylex(YYSTYPE *lvalp, parser_state_t *state);
207 
208 static object_t         *newObject(parser_state_t *state);
209 static void             freeObject(parser_state_t *state, object_t *o);
210 static void             rememberObject(parser_state_t *state, int tag, OSObject *o);
211 static object_t         *retrieveObject(parser_state_t *state, int tag);
212 static void             cleanupObjects(parser_state_t *state);
213 
214 static object_t         *buildDictionary(parser_state_t *state, object_t *o);
215 static object_t         *buildArray(parser_state_t *state, object_t *o);
216 static object_t         *buildSet(parser_state_t *state, object_t *o);
217 static object_t         *buildString(parser_state_t *state, object_t *o);
218 static object_t         *buildSymbol(parser_state_t *state, object_t *o);
219 static object_t         *buildData(parser_state_t *state, object_t *o);
220 static object_t         *buildNumber(parser_state_t *state, object_t *o);
221 static object_t         *buildBoolean(parser_state_t *state, object_t *o);
222 
223 __BEGIN_DECLS
224 #include <kern/kalloc.h>
225 __END_DECLS
226 
227 #define malloc(size) malloc_impl(size)
228 static inline void *
229 malloc_impl(size_t size)
230 {
231 	if (size == 0) {
232 		return NULL;
233 	}
234 	return kheap_alloc_tag_bt(KHEAP_DEFAULT, size,
235 	           (zalloc_flags_t) (Z_WAITOK | Z_ZERO),
236 	           VM_KERN_MEMORY_LIBKERN);
237 }
238 
239 #define free(addr) free_impl(addr)
240 static inline void
241 free_impl(void *addr)
242 {
243 	kheap_free_addr(KHEAP_DEFAULT, addr);
244 }
245 static inline void
246 safe_free(void *addr, size_t size)
247 {
248 	if (addr) {
249 		assert(size != 0);
250 		kheap_free(KHEAP_DEFAULT, addr, size);
251 	}
252 }
253 
254 #define realloc(addr, osize, nsize) realloc_impl(addr, osize, nsize)
255 static inline void *
256 realloc_impl(void *addr, size_t osize, size_t nsize)
257 {
258 	if (!addr) {
259 		return malloc(nsize);
260 	}
261 	if (nsize == osize) {
262 		return addr;
263 	}
264 	void *nmem = malloc(nsize);
265 	if (!nmem) {
266 		safe_free(addr, osize);
267 		return NULL;
268 	}
269 	(void)memcpy(nmem, addr, (nsize > osize) ? osize : nsize);
270 	safe_free(addr, osize);
271 
272 	return nmem;
273 }
274 
275 
276 
277 /* Enabling traces.  */
278 #ifndef YYDEBUG
279 # define YYDEBUG 0
280 #endif
281 
282 /* Enabling verbose error messages.  */
283 #ifdef YYERROR_VERBOSE
284 # undef YYERROR_VERBOSE
285 # define YYERROR_VERBOSE 1
286 #else
287 # define YYERROR_VERBOSE 0
288 #endif
289 
290 /* Enabling the token table.  */
291 #ifndef YYTOKEN_TABLE
292 # define YYTOKEN_TABLE 0
293 #endif
294 
295 #if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED
296 typedef int YYSTYPE;
297 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
298 # define YYSTYPE_IS_DECLARED 1
299 # define YYSTYPE_IS_TRIVIAL 1
300 #endif
301 
302 
303 
304 /* Copy the second part of user declarations.  */
305 
306 
307 /* Line 216 of yacc.c.  */
308 #line 258 "OSUnserializeXML.tab.c"
309 
310 #ifdef short
311 # undef short
312 #endif
313 
314 #ifdef YYTYPE_UINT8
315 typedef YYTYPE_UINT8 yytype_uint8;
316 #else
317 typedef unsigned char yytype_uint8;
318 #endif
319 
320 #ifdef YYTYPE_INT8
321 typedef YYTYPE_INT8 yytype_int8;
322 #elif (defined __STDC__ || defined __C99__FUNC__ \
323         || defined __cplusplus || defined _MSC_VER)
324 typedef signed char yytype_int8;
325 #else
326 typedef short int yytype_int8;
327 #endif
328 
329 #ifdef YYTYPE_UINT16
330 typedef YYTYPE_UINT16 yytype_uint16;
331 #else
332 typedef unsigned short int yytype_uint16;
333 #endif
334 
335 #ifdef YYTYPE_INT16
336 typedef YYTYPE_INT16 yytype_int16;
337 #else
338 typedef short int yytype_int16;
339 #endif
340 
341 #ifndef YYSIZE_T
342 # ifdef __SIZE_TYPE__
343 #  define YYSIZE_T __SIZE_TYPE__
344 # elif defined size_t
345 #  define YYSIZE_T size_t
346 # elif !defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
347         || defined __cplusplus || defined _MSC_VER)
348 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
349 #  define YYSIZE_T size_t
350 # else
351 #  define YYSIZE_T unsigned int
352 # endif
353 #endif
354 
355 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
356 
357 #ifndef YY_
358 # if defined YYENABLE_NLS && YYENABLE_NLS
359 #  if ENABLE_NLS
360 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
361 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
362 #  endif
363 # endif
364 # ifndef YY_
365 #  define YY_(msgid) msgid
366 # endif
367 #endif
368 
369 /* Suppress unused-variable warnings by "using" E.  */
370 #if !defined lint || defined __GNUC__
371 # define YYUSE(e) ((void) (e))
372 #else
373 # define YYUSE(e) /* empty */
374 #endif
375 
376 /* Identity function, used to suppress warnings about constant conditions.  */
377 #ifndef lint
378 # define YYID(n) (n)
379 #else
380 #if (defined __STDC__ || defined __C99__FUNC__ \
381         || defined __cplusplus || defined _MSC_VER)
382 static int
383 YYID(int i)
384 #else
385 static int
386     YYID(i)
387 int i;
388 #endif
389 {
390 	return i;
391 }
392 #endif
393 
394 #if !defined yyoverflow || YYERROR_VERBOSE
395 
396 /* The parser invokes alloca or malloc; define the necessary symbols.  */
397 
398 # ifdef YYSTACK_USE_ALLOCA
399 #  if YYSTACK_USE_ALLOCA
400 #   ifdef __GNUC__
401 #    define YYSTACK_ALLOC __builtin_alloca
402 #   elif defined __BUILTIN_VA_ARG_INCR
403 #    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
404 #   elif defined _AIX
405 #    define YYSTACK_ALLOC __alloca
406 #   elif defined _MSC_VER
407 #    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
408 #    define alloca _alloca
409 #   else
410 #    define YYSTACK_ALLOC alloca
411 #    if !defined _ALLOCA_H && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
412         || defined __cplusplus || defined _MSC_VER)
413 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
414 #     ifndef _STDLIB_H
415 #      define _STDLIB_H 1
416 #     endif
417 #    endif
418 #   endif
419 #  endif
420 # endif
421 
422 # ifdef YYSTACK_ALLOC
423 /* Pacify GCC's `empty if-body' warning.  */
424 #  define YYSTACK_FREE(Ptr) do { /* empty */ ; } while (YYID (0))
425 #  ifndef YYSTACK_ALLOC_MAXIMUM
426 /* The OS might guarantee only one guard page at the bottom of the stack,
427  *  and a page size can be as small as 4096 bytes.  So we cannot safely
428  *  invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
429  *  to allow for a few compiler-allocated temporary stack slots.  */
430 #   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
431 #  endif
432 # else
433 #  define YYSTACK_ALLOC YYMALLOC
434 #  define YYSTACK_FREE YYFREE
435 #  ifndef YYSTACK_ALLOC_MAXIMUM
436 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
437 #  endif
438 #  if (defined __cplusplus && !defined _STDLIB_H \
439         && !((defined YYMALLOC || defined malloc) \
440         && (defined YYFREE || defined free)))
441 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
442 #   ifndef _STDLIB_H
443 #    define _STDLIB_H 1
444 #   endif
445 #  endif
446 #  ifndef YYMALLOC
447 #   define YYMALLOC malloc
448 #   if !defined malloc && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
449         || defined __cplusplus || defined _MSC_VER)
450 void *malloc(YYSIZE_T);  /* INFRINGES ON USER NAME SPACE */
451 #   endif
452 #  endif
453 #  ifndef YYFREE
454 #   define YYFREE free
455 #   if !defined free && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
456         || defined __cplusplus || defined _MSC_VER)
457 void free(void *);  /* INFRINGES ON USER NAME SPACE */
458 #   endif
459 #  endif
460 # endif
461 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
462 
463 
464 #if (!defined yyoverflow \
465         && (!defined __cplusplus \
466         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
467 
468 /* A type that is properly aligned for any stack member.  */
469 union yyalloc {
470 	yytype_int16 yyss;
471 	YYSTYPE yyvs;
472 };
473 
474 /* The size of the maximum gap between one aligned stack and the next.  */
475 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
476 
477 /* The size of an array large to enough to hold all stacks, each with
478  *  N elements.  */
479 # define YYSTACK_BYTES(N) \
480      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
481       + YYSTACK_GAP_MAXIMUM)
482 
483 /* Copy COUNT objects from FROM to TO.  The source and destination do
484  *  not overlap.  */
485 # ifndef YYCOPY
486 #  if defined __GNUC__ && 1 < __GNUC__
487 #   define YYCOPY(To, From, Count) \
488       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
489 #  else
490 #   define YYCOPY(To, From, Count)              \
491       do                                        \
492 	{                                       \
493 	  YYSIZE_T yyi;                         \
494 	  for (yyi = 0; yyi < (Count); yyi++)   \
495 	    (To)[yyi] = (From)[yyi];            \
496 	}                                       \
497       while (YYID (0))
498 #  endif
499 # endif
500 
501 /* Relocate STACK from its old location to the new one.  The
502  *  local variables YYSIZE and YYSTACKSIZE give the old and new number of
503  *  elements in the stack, and YYPTR gives the new location of the
504  *  stack.  Advance YYPTR to a properly aligned location for the next
505  *  stack.  */
506 # define YYSTACK_RELOCATE(Stack)                                        \
507     do                                                                  \
508       {                                                                 \
509 	YYSIZE_T yynewbytes;                                            \
510 	YYCOPY (&yyptr->Stack, Stack, yysize);                          \
511 	Stack = &yyptr->Stack;                                          \
512 	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
513 	yyptr += yynewbytes / sizeof (*yyptr);                          \
514       }                                                                 \
515     while (YYID (0))
516 
517 #endif
518 
519 /* YYFINAL -- State number of the termination state.  */
520 #define YYFINAL  33
521 /* YYLAST -- Last index in YYTABLE.  */
522 #define YYLAST   108
523 
524 /* YYNTOKENS -- Number of terminals.  */
525 #define YYNTOKENS  19
526 /* YYNNTS -- Number of nonterminals.  */
527 #define YYNNTS  15
528 /* YYNRULES -- Number of rules.  */
529 #define YYNRULES  32
530 /* YYNRULES -- Number of states.  */
531 #define YYNSTATES  40
532 
533 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
534 #define YYUNDEFTOK  2
535 #define YYMAXUTOK   267
536 
537 #define YYTRANSLATE(YYX)                                                \
538   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
539 
540 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
541 static const yytype_uint8 yytranslate[] =
542 {
543 	0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
544 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
545 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
546 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
547 	15, 16, 2, 2, 2, 2, 2, 2, 2, 2,
548 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
549 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
550 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
551 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
552 	2, 17, 2, 18, 2, 2, 2, 2, 2, 2,
553 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
554 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
555 	2, 2, 2, 13, 2, 14, 2, 2, 2, 2,
556 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
557 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
558 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
559 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
560 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
561 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
562 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
563 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
564 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
565 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
566 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
567 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
568 	2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
569 	5, 6, 7, 8, 9, 10, 11, 12
570 };
571 
572 #if YYDEBUG
573 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
574  *  YYRHS.  */
575 static const yytype_uint8 yyprhs[] =
576 {
577 	0, 0, 3, 4, 6, 8, 10, 12, 14, 16,
578 	18, 20, 22, 24, 27, 31, 33, 35, 38, 41,
579 	43, 46, 50, 52, 55, 59, 61, 63, 66, 68,
580 	70, 72, 74
581 };
582 
583 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
584 static const yytype_int8 yyrhs[] =
585 {
586 	20, 0, -1, -1, 21, -1, 12, -1, 22, -1,
587 	26, -1, 27, -1, 33, -1, 30, -1, 32, -1,
588 	29, -1, 31, -1, 13, 14, -1, 13, 23, 14,
589 	-1, 6, -1, 24, -1, 23, 24, -1, 25, 21,
590 	-1, 8, -1, 15, 16, -1, 15, 28, 16, -1,
591 	3, -1, 17, 18, -1, 17, 28, 18, -1, 10,
592 	-1, 21, -1, 28, 21, -1, 4, -1, 5, -1,
593 	7, -1, 9, -1, 11, -1
594 };
595 
596 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
597 static const yytype_uint16 yyrline[] =
598 {
599 	0, 192, 192, 195, 200, 205, 217, 229, 241, 253,
600 	265, 277, 289, 313, 316, 319, 322, 323, 338, 347,
601 	359, 362, 365, 368, 371, 374, 377, 380, 387, 390,
602 	393, 396, 399
603 };
604 #endif
605 
606 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
607 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
608  *  First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
609 static const char *const yytname[] =
610 {
611 	"$end", "error", "$undefined", "ARRAY", "BOOLEAN", "DATA", "DICTIONARY",
612 	"IDREF", "KEY", "NUMBER", "SET", "STRING", "SYNTAX_ERROR", "'{'", "'}'",
613 	"'('", "')'", "'['", "']'", "$accept", "input", "object", "dict",
614 	"pairs", "pair", "key", "array", "set", "elements", "boolean", "data",
615 	"idref", "number", "string", 0
616 };
617 #endif
618 
619 # ifdef YYPRINT
620 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
621  *  token YYLEX-NUM.  */
622 static const yytype_uint16 yytoknum[] =
623 {
624 	0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
625 	265, 266, 267, 123, 125, 40, 41, 91, 93
626 };
627 # endif
628 
629 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
630 static const yytype_uint8 yyr1[] =
631 {
632 	0, 19, 20, 20, 20, 21, 21, 21, 21, 21,
633 	21, 21, 21, 22, 22, 22, 23, 23, 24, 25,
634 	26, 26, 26, 27, 27, 27, 28, 28, 29, 30,
635 	31, 32, 33
636 };
637 
638 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
639 static const yytype_uint8 yyr2[] =
640 {
641 	0, 2, 0, 1, 1, 1, 1, 1, 1, 1,
642 	1, 1, 1, 2, 3, 1, 1, 2, 2, 1,
643 	2, 3, 1, 2, 3, 1, 1, 2, 1, 1,
644 	1, 1, 1
645 };
646 
647 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
648  *  STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
649  *  means the default is an error.  */
650 static const yytype_uint8 yydefact[] =
651 {
652 	2, 22, 28, 29, 15, 30, 31, 25, 32, 4,
653 	0, 0, 0, 0, 3, 5, 6, 7, 11, 9,
654 	12, 10, 8, 19, 13, 0, 16, 0, 20, 26,
655 	0, 23, 0, 1, 14, 17, 18, 21, 27, 24
656 };
657 
658 /* YYDEFGOTO[NTERM-NUM].  */
659 static const yytype_int8 yydefgoto[] =
660 {
661 	-1, 13, 29, 15, 25, 26, 27, 16, 17, 30,
662 	18, 19, 20, 21, 22
663 };
664 
665 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
666  *  STATE-NUM.  */
667 #define YYPACT_NINF -20
668 static const yytype_int8 yypact[] =
669 {
670 	46, -20, -20, -20, -20, -20, -20, -20, -20, -20,
671 	4, 61, -2, 10, -20, -20, -20, -20, -20, -20,
672 	-20, -20, -20, -20, -20, 6, -20, 91, -20, -20,
673 	76, -20, 30, -20, -20, -20, -20, -20, -20, -20
674 };
675 
676 /* YYPGOTO[NTERM-NUM].  */
677 static const yytype_int8 yypgoto[] =
678 {
679 	-20, -20, 0, -20, -20, -19, -20, -20, -20, 5,
680 	-20, -20, -20, -20, -20
681 };
682 
683 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
684  *  positive, shift that token.  If negative, reduce the rule which
685  *  number is the opposite.  If zero, do what YYDEFACT says.
686  *  If YYTABLE_NINF, syntax error.  */
687 #define YYTABLE_NINF -1
688 static const yytype_uint8 yytable[] =
689 {
690 	14, 1, 2, 3, 4, 5, 35, 6, 7, 8,
691 	33, 10, 23, 11, 23, 12, 31, 32, 24, 0,
692 	34, 0, 0, 0, 0, 0, 0, 36, 0, 0,
693 	38, 0, 38, 1, 2, 3, 4, 5, 0, 6,
694 	7, 8, 0, 10, 0, 11, 0, 12, 39, 1,
695 	2, 3, 4, 5, 0, 6, 7, 8, 9, 10,
696 	0, 11, 0, 12, 1, 2, 3, 4, 5, 0,
697 	6, 7, 8, 0, 10, 0, 11, 28, 12, 1,
698 	2, 3, 4, 5, 0, 6, 7, 8, 0, 10,
699 	0, 11, 37, 12, 1, 2, 3, 4, 5, 0,
700 	6, 7, 8, 0, 10, 0, 11, 0, 12
701 };
702 
703 static const yytype_int8 yycheck[] =
704 {
705 	0, 3, 4, 5, 6, 7, 25, 9, 10, 11,
706 	0, 13, 8, 15, 8, 17, 18, 12, 14, -1,
707 	14, -1, -1, -1, -1, -1, -1, 27, -1, -1,
708 	30, -1, 32, 3, 4, 5, 6, 7, -1, 9,
709 	10, 11, -1, 13, -1, 15, -1, 17, 18, 3,
710 	4, 5, 6, 7, -1, 9, 10, 11, 12, 13,
711 	-1, 15, -1, 17, 3, 4, 5, 6, 7, -1,
712 	9, 10, 11, -1, 13, -1, 15, 16, 17, 3,
713 	4, 5, 6, 7, -1, 9, 10, 11, -1, 13,
714 	-1, 15, 16, 17, 3, 4, 5, 6, 7, -1,
715 	9, 10, 11, -1, 13, -1, 15, -1, 17
716 };
717 
718 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
719  *  symbol of state STATE-NUM.  */
720 static const yytype_uint8 yystos[] =
721 {
722 	0, 3, 4, 5, 6, 7, 9, 10, 11, 12,
723 	13, 15, 17, 20, 21, 22, 26, 27, 29, 30,
724 	31, 32, 33, 8, 14, 23, 24, 25, 16, 21,
725 	28, 18, 28, 0, 14, 24, 21, 16, 21, 18
726 };
727 
728 #define yyerrok         (yyerrstatus = 0)
729 #define yyclearin       (yychar = YYEMPTY)
730 #define YYEMPTY         (-2)
731 #define YYEOF           0
732 
733 #define YYACCEPT        goto yyacceptlab
734 #define YYABORT         goto yyabortlab
735 #define YYERROR         goto yyerrorlab
736 
737 
738 /* Like YYERROR except do call yyerror.  This remains here temporarily
739  *  to ease the transition to the new meaning of YYERROR, for GCC.
740  *  Once GCC version 2 has supplanted version 1, this can go.  */
741 
742 #define YYFAIL          goto yyerrlab
743 
744 #define YYRECOVERING()  (!!yyerrstatus)
745 
746 #define YYBACKUP(Token, Value)                                  \
747 do                                                              \
748   if (yychar == YYEMPTY && yylen == 1)                          \
749     {                                                           \
750       yychar = (Token);                                         \
751       yylval = (Value);                                         \
752       yytoken = YYTRANSLATE (yychar);                           \
753       YYPOPSTACK (1);                                           \
754       goto yybackup;                                            \
755     }                                                           \
756   else                                                          \
757     {                                                           \
758       yyerror (YY_("syntax error: cannot back up")); \
759       YYERROR;                                                  \
760     }                                                           \
761 while (YYID (0))
762 
763 
764 #define YYTERROR        1
765 #define YYERRCODE       256
766 
767 
768 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
769  *  If N is 0, then set CURRENT to the empty location which ends
770  *  the previous symbol: RHS[0] (always defined).  */
771 
772 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
773 #ifndef YYLLOC_DEFAULT
774 # define YYLLOC_DEFAULT(Current, Rhs, N)                                \
775     do                                                                  \
776       if (YYID (N))                                                    \
777 	{                                                               \
778 	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
779 	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
780 	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
781 	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
782 	}                                                               \
783       else                                                              \
784 	{                                                               \
785 	  (Current).first_line   = (Current).last_line   =              \
786 	    YYRHSLOC (Rhs, 0).last_line;                                \
787 	  (Current).first_column = (Current).last_column =              \
788 	    YYRHSLOC (Rhs, 0).last_column;                              \
789 	}                                                               \
790     while (YYID (0))
791 #endif
792 
793 
794 /* YY_LOCATION_PRINT -- Print the location on the stream.
795  *  This macro was not mandated originally: define only if we know
796  *  we won't break user code: when these are the locations we know.  */
797 
798 #ifndef YY_LOCATION_PRINT
799 # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
800 #  define YY_LOCATION_PRINT(File, Loc)                  \
801      fprintf (File, "%d.%d-%d.%d",                      \
802 	      (Loc).first_line, (Loc).first_column,     \
803 	      (Loc).last_line,  (Loc).last_column)
804 # else
805 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
806 # endif
807 #endif
808 
809 
810 /* YYLEX -- calling `yylex' with the right arguments.  */
811 
812 #ifdef YYLEX_PARAM
813 # define YYLEX yylex (&yylval, YYLEX_PARAM)
814 #else
815 # define YYLEX yylex (&yylval)
816 #endif
817 
818 /* Enable debugging if requested.  */
819 #if YYDEBUG
820 
821 # ifndef YYFPRINTF
822 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
823 #  define YYFPRINTF fprintf
824 # endif
825 
826 # define YYDPRINTF(Args)                        \
827 do {                                            \
828   if (yydebug)                                  \
829     YYFPRINTF Args;                             \
830 } while (YYID (0))
831 
832 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
833 do {                                                                      \
834   if (yydebug)                                                            \
835     {                                                                     \
836       YYFPRINTF (stderr, "%s ", Title);                                   \
837       yy_symbol_print (stderr,                                            \
838 	          Type, Value); \
839       YYFPRINTF (stderr, "\n");                                           \
840     }                                                                     \
841 } while (YYID (0))
842 
843 
844 /*--------------------------------.
845  | Print this symbol on YYOUTPUT.  |
846  |   `--------------------------------*/
847 
848 /*ARGSUSED*/
849 #if (defined __STDC__ || defined __C99__FUNC__ \
850         || defined __cplusplus || defined _MSC_VER)
851 static void
852 yy_symbol_value_print(FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
853 #else
854 static void
855     yy_symbol_value_print(yyoutput, yytype, yyvaluep)
856 FILE *yyoutput;
857 int yytype;
858 YYSTYPE const * const yyvaluep;
859 #endif
860 {
861 	if (!yyvaluep) {
862 		return;
863 	}
864 # ifdef YYPRINT
865 	if (yytype < YYNTOKENS) {
866 		YYPRINT(yyoutput, yytoknum[yytype], *yyvaluep);
867 	}
868 # else
869 	YYUSE(yyoutput);
870 # endif
871 	switch (yytype) {
872 	default:
873 		break;
874 	}
875 }
876 
877 
878 /*--------------------------------.
879  | Print this symbol on YYOUTPUT.  |
880  |   `--------------------------------*/
881 
882 #if (defined __STDC__ || defined __C99__FUNC__ \
883         || defined __cplusplus || defined _MSC_VER)
884 static void
885 yy_symbol_print(FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
886 #else
887 static void
888     yy_symbol_print(yyoutput, yytype, yyvaluep)
889 FILE *yyoutput;
890 int yytype;
891 YYSTYPE const * const yyvaluep;
892 #endif
893 {
894 	if (yytype < YYNTOKENS) {
895 		YYFPRINTF(yyoutput, "token %s (", yytname[yytype]);
896 	} else {
897 		YYFPRINTF(yyoutput, "nterm %s (", yytname[yytype]);
898 	}
899 
900 	yy_symbol_value_print(yyoutput, yytype, yyvaluep);
901 	YYFPRINTF(yyoutput, ")");
902 }
903 
904 /*------------------------------------------------------------------.
905  | yy_stack_print -- Print the state stack from its BOTTOM up to its |
906  | TOP (included).                                                   |
907  |   `------------------------------------------------------------------*/
908 
909 #if (defined __STDC__ || defined __C99__FUNC__ \
910         || defined __cplusplus || defined _MSC_VER)
911 static void
912 yy_stack_print(yytype_int16 *bottom, yytype_int16 *top)
913 #else
914 static void
915     yy_stack_print(bottom, top)
916 yytype_int16 *bottom;
917 yytype_int16 *top;
918 #endif
919 {
920 	YYFPRINTF(stderr, "Stack now");
921 	for (; bottom <= top; ++bottom) {
922 		YYFPRINTF(stderr, " %d", *bottom);
923 	}
924 	YYFPRINTF(stderr, "\n");
925 }
926 
927 # define YY_STACK_PRINT(Bottom, Top)                            \
928 do {                                                            \
929   if (yydebug)                                                  \
930     yy_stack_print ((Bottom), (Top));                           \
931 } while (YYID (0))
932 
933 
934 /*------------------------------------------------.
935  | Report that the YYRULE is going to be reduced.  |
936  |   `------------------------------------------------*/
937 
938 #if (defined __STDC__ || defined __C99__FUNC__ \
939         || defined __cplusplus || defined _MSC_VER)
940 static void
941 yy_reduce_print(YYSTYPE *yyvsp, int yyrule)
942 #else
943 static void
944     yy_reduce_print(yyvsp, yyrule)
945 YYSTYPE *yyvsp;
946 int yyrule;
947 #endif
948 {
949 	int yynrhs = yyr2[yyrule];
950 	int yyi;
951 	unsigned long int yylno = yyrline[yyrule];
952 	YYFPRINTF(stderr, "Reducing stack by rule %d (line %lu):\n",
953 	    yyrule - 1, yylno);
954 	/* The symbols being reduced.  */
955 	for (yyi = 0; yyi < yynrhs; yyi++) {
956 		fprintf(stderr, "   $%d = ", yyi + 1);
957 		yy_symbol_print(stderr, yyrhs[yyprhs[yyrule] + yyi],
958 		    &(yyvsp[(yyi + 1) - (yynrhs)])
959 		    );
960 		fprintf(stderr, "\n");
961 	}
962 }
963 
964 # define YY_REDUCE_PRINT(Rule)          \
965 do {                                    \
966   if (yydebug)                          \
967     yy_reduce_print (yyvsp, Rule); \
968 } while (YYID (0))
969 
970 /* Nonzero means print parse trace.  It is left uninitialized so that
971  *  multiple parsers can coexist.  */
972 int yydebug;
973 #else /* !YYDEBUG */
974 # define YYDPRINTF(Args)
975 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
976 # define YY_STACK_PRINT(Bottom, Top)
977 # define YY_REDUCE_PRINT(Rule)
978 #endif /* !YYDEBUG */
979 
980 
981 /* YYINITDEPTH -- initial size of the parser's stacks.  */
982 #ifndef YYINITDEPTH
983 # define YYINITDEPTH 200
984 #endif
985 
986 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
987  *  if the built-in stack extension method is used).
988  *
989  *  Do not make this value too large; the results are undefined if
990  *  YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
991  *  evaluated with infinite-precision integer arithmetic.  */
992 
993 #ifndef YYMAXDEPTH
994 # define YYMAXDEPTH 10000
995 #endif
996 
997 
998 
999 #if YYERROR_VERBOSE
1000 
1001 # ifndef yystrlen
1002 #  if defined __GLIBC__ && defined _STRING_H
1003 #   define yystrlen strlen
1004 #  else
1005 /* Return the length of YYSTR.  */
1006 #if (defined __STDC__ || defined __C99__FUNC__ \
1007         || defined __cplusplus || defined _MSC_VER)
1008 static YYSIZE_T
1009 yystrlen(const char *yystr)
1010 #else
1011 static YYSIZE_T
1012     yystrlen(yystr)
1013 const char *yystr;
1014 #endif
1015 {
1016 	YYSIZE_T yylen;
1017 	for (yylen = 0; yystr[yylen]; yylen++) {
1018 		continue;
1019 	}
1020 	return yylen;
1021 }
1022 #  endif
1023 # endif
1024 
1025 # ifndef yystpcpy
1026 #  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1027 #   define yystpcpy stpcpy
1028 #  else
1029 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1030  *  YYDEST.  */
1031 #if (defined __STDC__ || defined __C99__FUNC__ \
1032         || defined __cplusplus || defined _MSC_VER)
1033 static char *
1034 yystpcpy(char *yydest, const char *yysrc)
1035 #else
1036 static char *
1037 yystpcpy(yydest, yysrc)
1038 char *yydest;
1039 const char *yysrc;
1040 #endif
1041 {
1042 	char *yyd = yydest;
1043 	const char *yys = yysrc;
1044 
1045 	while ((*yyd++ = *yys++) != '\0') {
1046 		continue;
1047 	}
1048 
1049 	return yyd - 1;
1050 }
1051 #  endif
1052 # endif
1053 
1054 # ifndef yytnamerr
1055 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1056  *  quotes and backslashes, so that it's suitable for yyerror.  The
1057  *  heuristic is that double-quoting is unnecessary unless the string
1058  *  contains an apostrophe, a comma, or backslash (other than
1059  *  backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
1060  *  null, do not copy; instead, return the length of what the result
1061  *  would have been.  */
1062 static YYSIZE_T
1063 yytnamerr(char *yyres, const char *yystr)
1064 {
1065 	if (*yystr == '"') {
1066 		YYSIZE_T yyn = 0;
1067 		char const *yyp = yystr;
1068 
1069 		for (;;) {
1070 			switch (*++yyp) {
1071 			case '\'':
1072 			case ',':
1073 				goto do_not_strip_quotes;
1074 
1075 			case '\\':
1076 				if (*++yyp != '\\') {
1077 					goto do_not_strip_quotes;
1078 				}
1079 			/* Fall through.  */
1080 			default:
1081 				if (yyres) {
1082 					yyres[yyn] = *yyp;
1083 				}
1084 				yyn++;
1085 				break;
1086 
1087 			case '"':
1088 				if (yyres) {
1089 					yyres[yyn] = '\0';
1090 				}
1091 				return yyn;
1092 			}
1093 		}
1094 do_not_strip_quotes:;
1095 	}
1096 
1097 	if (!yyres) {
1098 		return yystrlen(yystr);
1099 	}
1100 
1101 	return yystpcpy(yyres, yystr) - yyres;
1102 }
1103 # endif
1104 
1105 /* Copy into YYRESULT an error message about the unexpected token
1106  *  YYCHAR while in state YYSTATE.  Return the number of bytes copied,
1107  *  including the terminating null byte.  If YYRESULT is null, do not
1108  *  copy anything; just return the number of bytes that would be
1109  *  copied.  As a special case, return 0 if an ordinary "syntax error"
1110  *  message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
1111  *  size calculation.  */
1112 static YYSIZE_T
1113 yysyntax_error(char *yyresult, int yystate, int yychar)
1114 {
1115 	int yyn = yypact[yystate];
1116 
1117 	if (!(YYPACT_NINF < yyn && yyn <= YYLAST)) {
1118 		return 0;
1119 	} else {
1120 		int yytype = YYTRANSLATE(yychar);
1121 		YYSIZE_T yysize0 = yytnamerr(0, yytname[yytype]);
1122 		YYSIZE_T yysize = yysize0;
1123 		YYSIZE_T yysize1;
1124 		int yysize_overflow = 0;
1125 		enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1126 		char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1127 		int yyx;
1128 
1129 # if 0
1130 		/* This is so xgettext sees the translatable formats that are
1131 		 *  constructed on the fly.  */
1132 		YY_("syntax error, unexpected %s");
1133 		YY_("syntax error, unexpected %s, expecting %s");
1134 		YY_("syntax error, unexpected %s, expecting %s or %s");
1135 		YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1136 		YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1137 # endif
1138 		char *yyfmt;
1139 		char const *yyf;
1140 		static char const yyunexpected[] = "syntax error, unexpected %s";
1141 		static char const yyexpecting[] = ", expecting %s";
1142 		static char const yyor[] = " or %s";
1143 		char yyformat[sizeof yyunexpected
1144 		+ sizeof yyexpecting - 1
1145 		+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1146 		* (sizeof yyor - 1))];
1147 		char const *yyprefix = yyexpecting;
1148 
1149 		/* Start YYX at -YYN if negative to avoid negative indexes in
1150 		 *  YYCHECK.  */
1151 		int yyxbegin = yyn < 0 ? -yyn : 0;
1152 
1153 		/* Stay within bounds of both yycheck and yytname.  */
1154 		int yychecklim = YYLAST - yyn + 1;
1155 		int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1156 		int yycount = 1;
1157 
1158 		yyarg[0] = yytname[yytype];
1159 		yyfmt = yystpcpy(yyformat, yyunexpected);
1160 
1161 		for (yyx = yyxbegin; yyx < yyxend; ++yyx) {
1162 			if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) {
1163 				if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) {
1164 					yycount = 1;
1165 					yysize = yysize0;
1166 					yyformat[sizeof yyunexpected - 1] = '\0';
1167 					break;
1168 				}
1169 				yyarg[yycount++] = yytname[yyx];
1170 				yysize1 = yysize + yytnamerr(0, yytname[yyx]);
1171 				yysize_overflow |= (yysize1 < yysize);
1172 				yysize = yysize1;
1173 				yyfmt = yystpcpy(yyfmt, yyprefix);
1174 				yyprefix = yyor;
1175 			}
1176 		}
1177 
1178 		yyf = YY_(yyformat);
1179 		yysize1 = yysize + yystrlen(yyf);
1180 		yysize_overflow |= (yysize1 < yysize);
1181 		yysize = yysize1;
1182 
1183 		if (yysize_overflow) {
1184 			return YYSIZE_MAXIMUM;
1185 		}
1186 
1187 		if (yyresult) {
1188 			/* Avoid sprintf, as that infringes on the user's name space.
1189 			 *  Don't have undefined behavior even if the translation
1190 			 *  produced a string with the wrong number of "%s"s.  */
1191 			char *yyp = yyresult;
1192 			int yyi = 0;
1193 			while ((*yyp = *yyf) != '\0') {
1194 				if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) {
1195 					yyp += yytnamerr(yyp, yyarg[yyi++]);
1196 					yyf += 2;
1197 				} else {
1198 					yyp++;
1199 					yyf++;
1200 				}
1201 			}
1202 		}
1203 		return yysize;
1204 	}
1205 }
1206 #endif /* YYERROR_VERBOSE */
1207 
1208 
1209 /*-----------------------------------------------.
1210  | Release the memory associated to this symbol.  |
1211  |   `-----------------------------------------------*/
1212 
1213 /*ARGSUSED*/
1214 #if (defined __STDC__ || defined __C99__FUNC__ \
1215         || defined __cplusplus || defined _MSC_VER)
1216 static void
1217 yydestruct(const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1218 #else
1219 static void
1220     yydestruct(yymsg, yytype, yyvaluep)
1221 const char *yymsg;
1222 int yytype;
1223 YYSTYPE *yyvaluep;
1224 #endif
1225 {
1226 	YYUSE(yyvaluep);
1227 
1228 	if (!yymsg) {
1229 		yymsg = "Deleting";
1230 	}
1231 	YY_SYMBOL_PRINT(yymsg, yytype, yyvaluep, yylocationp);
1232 
1233 	switch (yytype) {
1234 	default:
1235 		break;
1236 	}
1237 }
1238 
1239 
1240 /* Prevent warnings from -Wmissing-prototypes.  */
1241 
1242 #ifdef YYPARSE_PARAM
1243 #if defined __STDC__ || defined __cplusplus
1244 int yyparse(void *YYPARSE_PARAM);
1245 #else
1246 int yyparse();
1247 #endif
1248 #else /* ! YYPARSE_PARAM */
1249 #if defined __STDC__ || defined __cplusplus
1250 int yyparse(void);
1251 #else
1252 int yyparse();
1253 #endif
1254 #endif /* ! YYPARSE_PARAM */
1255 
1256 
1257 
1258 
1259 
1260 
1261 /*----------.
1262  | yyparse.  |
1263  |   `----------*/
1264 
1265 #ifdef YYPARSE_PARAM
1266 #if (defined __STDC__ || defined __C99__FUNC__ \
1267         || defined __cplusplus || defined _MSC_VER)
1268 int
1269 yyparse(void *YYPARSE_PARAM)
1270 #else
1271 int
1272     yyparse(YYPARSE_PARAM)
1273 void *YYPARSE_PARAM;
1274 #endif
1275 #else /* ! YYPARSE_PARAM */
1276 #if (defined __STDC__ || defined __C99__FUNC__ \
1277         || defined __cplusplus || defined _MSC_VER)
1278 int
1279 yyparse(void)
1280 #else
1281 int
1282 yyparse()
1283 
1284 #endif
1285 #endif
1286 {
1287 	/* The look-ahead symbol.  */
1288 	int yychar;
1289 
1290 /* The semantic value of the look-ahead symbol.  */
1291 	YYSTYPE yylval;
1292 
1293 /* Number of syntax errors so far.  */
1294 	int yynerrs;
1295 
1296 	int yystate;
1297 	int yyn;
1298 	int yyresult;
1299 	/* Number of tokens to shift before error messages enabled.  */
1300 	int yyerrstatus;
1301 	/* Look-ahead token as an internal (translated) token number.  */
1302 	int yytoken = 0;
1303 #if YYERROR_VERBOSE
1304 	/* Buffer for error messages, and its allocated size.  */
1305 	char yymsgbuf[128];
1306 	char *yymsg = yymsgbuf;
1307 	YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1308 #endif
1309 
1310 	/* Three stacks and their tools:
1311 	 *  `yyss': related to states,
1312 	 *  `yyvs': related to semantic values,
1313 	 *  `yyls': related to locations.
1314 	 *
1315 	 *  Refer to the stacks thru separate pointers, to allow yyoverflow
1316 	 *  to reallocate them elsewhere.  */
1317 
1318 	/* The state stack.  */
1319 	yytype_int16 yyssa[YYINITDEPTH];
1320 	yytype_int16 *yyss = yyssa;
1321 	yytype_int16 *yyssp;
1322 
1323 	/* The semantic value stack.  */
1324 	YYSTYPE yyvsa[YYINITDEPTH];
1325 	YYSTYPE *yyvs = yyvsa;
1326 	YYSTYPE *yyvsp;
1327 
1328 
1329 
1330 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
1331 
1332 	YYSIZE_T yystacksize = YYINITDEPTH;
1333 
1334 	/* The variables used to return semantic value and location from the
1335 	 *  action routines.  */
1336 	YYSTYPE yyval;
1337 
1338 
1339 	/* The number of symbols on the RHS of the reduced rule.
1340 	 *  Keep to zero when no symbol should be popped.  */
1341 	int yylen = 0;
1342 
1343 	YYDPRINTF((stderr, "Starting parse\n"));
1344 
1345 	yystate = 0;
1346 	yyerrstatus = 0;
1347 	yynerrs = 0;
1348 	yychar = YYEMPTY;       /* Cause a token to be read.  */
1349 
1350 	/* Initialize stack pointers.
1351 	 *  Waste one element of value and location stack
1352 	 *  so that they stay on the same level as the state stack.
1353 	 *  The wasted elements are never initialized.  */
1354 
1355 	yyssp = yyss;
1356 	yyvsp = yyvs;
1357 
1358 	goto yysetstate;
1359 
1360 /*------------------------------------------------------------.
1361  | yynewstate -- Push a new state, which is found in yystate.  |
1362  |   `------------------------------------------------------------*/
1363 yynewstate:
1364 	/* In all cases, when you get here, the value and location stacks
1365 	 *  have just been pushed.  So pushing a state here evens the stacks.  */
1366 	yyssp++;
1367 
1368 yysetstate:
1369 	*yyssp = yystate;
1370 
1371 	if (yyss + yystacksize - 1 <= yyssp) {
1372 		/* Get the current used size of the three stacks, in elements.  */
1373 		YYSIZE_T yysize = yyssp - yyss + 1;
1374 
1375 #ifdef yyoverflow
1376 		{
1377 			/* Give user a chance to reallocate the stack.  Use copies of
1378 			 *  these so that the &'s don't force the real ones into
1379 			 *  memory.  */
1380 			YYSTYPE *yyvs1 = yyvs;
1381 			yytype_int16 *yyss1 = yyss;
1382 
1383 
1384 			/* Each stack pointer address is followed by the size of the
1385 			 *  data in use in that stack, in bytes.  This used to be a
1386 			 *  conditional around just the two extra args, but that might
1387 			 *  be undefined if yyoverflow is a macro.  */
1388 			yyoverflow(YY_("memory exhausted"),
1389 			    &yyss1, yysize * sizeof(*yyssp),
1390 			    &yyvs1, yysize * sizeof(*yyvsp),
1391 
1392 			    &yystacksize);
1393 
1394 			yyss = yyss1;
1395 			yyvs = yyvs1;
1396 		}
1397 #else /* no yyoverflow */
1398 # ifndef YYSTACK_RELOCATE
1399 		goto yyexhaustedlab;
1400 # else
1401 		/* Extend the stack our own way.  */
1402 		if (YYMAXDEPTH <= yystacksize) {
1403 			goto yyexhaustedlab;
1404 		}
1405 		yystacksize *= 2;
1406 		if (YYMAXDEPTH < yystacksize) {
1407 			yystacksize = YYMAXDEPTH;
1408 		}
1409 
1410 		{
1411 			yytype_int16 *yyss1 = yyss;
1412 			union yyalloc *yyptr =
1413 			    (union yyalloc *) YYSTACK_ALLOC(YYSTACK_BYTES(yystacksize));
1414 			if (!yyptr) {
1415 				goto yyexhaustedlab;
1416 			}
1417 			YYSTACK_RELOCATE(yyss);
1418 			YYSTACK_RELOCATE(yyvs);
1419 
1420 #  undef YYSTACK_RELOCATE
1421 			if (yyss1 != yyssa) {
1422 				YYSTACK_FREE(yyss1);
1423 			}
1424 		}
1425 # endif
1426 #endif /* no yyoverflow */
1427 
1428 		yyssp = yyss + yysize - 1;
1429 		yyvsp = yyvs + yysize - 1;
1430 
1431 
1432 		YYDPRINTF((stderr, "Stack size increased to %lu\n",
1433 		    (unsigned long int) yystacksize));
1434 
1435 		if (yyss + yystacksize - 1 <= yyssp) {
1436 			YYABORT;
1437 		}
1438 	}
1439 
1440 	YYDPRINTF((stderr, "Entering state %d\n", yystate));
1441 
1442 	goto yybackup;
1443 
1444 /*-----------.
1445  | yybackup.  |
1446  |   `-----------*/
1447 yybackup:
1448 
1449 	/* Do appropriate processing given the current state.  Read a
1450 	 *  look-ahead token if we need one and don't already have one.  */
1451 
1452 	/* First try to decide what to do without reference to look-ahead token.  */
1453 	yyn = yypact[yystate];
1454 	if (yyn == YYPACT_NINF) {
1455 		goto yydefault;
1456 	}
1457 
1458 	/* Not known => get a look-ahead token if don't already have one.  */
1459 
1460 	/* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
1461 	if (yychar == YYEMPTY) {
1462 		YYDPRINTF((stderr, "Reading a token: "));
1463 		yychar = YYLEX;
1464 	}
1465 
1466 	if (yychar <= YYEOF) {
1467 		yychar = yytoken = YYEOF;
1468 		YYDPRINTF((stderr, "Now at end of input.\n"));
1469 	} else {
1470 		yytoken = YYTRANSLATE(yychar);
1471 		YY_SYMBOL_PRINT("Next token is", yytoken, &yylval, &yylloc);
1472 	}
1473 
1474 	/* If the proper action on seeing token YYTOKEN is to reduce or to
1475 	 *  detect an error, take that action.  */
1476 	yyn += yytoken;
1477 	if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) {
1478 		goto yydefault;
1479 	}
1480 	yyn = yytable[yyn];
1481 	if (yyn <= 0) {
1482 		if (yyn == 0 || yyn == YYTABLE_NINF) {
1483 			goto yyerrlab;
1484 		}
1485 		yyn = -yyn;
1486 		goto yyreduce;
1487 	}
1488 
1489 	if (yyn == YYFINAL) {
1490 		YYACCEPT;
1491 	}
1492 
1493 	/* Count tokens shifted since error; after three, turn off error
1494 	 *  status.  */
1495 	if (yyerrstatus) {
1496 		yyerrstatus--;
1497 	}
1498 
1499 	/* Shift the look-ahead token.  */
1500 	YY_SYMBOL_PRINT("Shifting", yytoken, &yylval, &yylloc);
1501 
1502 	/* Discard the shifted token unless it is eof.  */
1503 	if (yychar != YYEOF) {
1504 		yychar = YYEMPTY;
1505 	}
1506 
1507 	yystate = yyn;
1508 	*++yyvsp = yylval;
1509 
1510 	goto yynewstate;
1511 
1512 
1513 /*-----------------------------------------------------------.
1514  | yydefault -- do the default action for the current state.  |
1515  |   `-----------------------------------------------------------*/
1516 yydefault:
1517 	yyn = yydefact[yystate];
1518 	if (yyn == 0) {
1519 		goto yyerrlab;
1520 	}
1521 	goto yyreduce;
1522 
1523 
1524 /*-----------------------------.
1525  | yyreduce -- Do a reduction.  |
1526  |   `-----------------------------*/
1527 yyreduce:
1528 	/* yyn is the number of a rule to reduce with.  */
1529 	yylen = yyr2[yyn];
1530 
1531 	/* If YYLEN is nonzero, implement the default value of the action:
1532 	 *  `$$ = $1'.
1533 	 *
1534 	 *  Otherwise, the following line sets YYVAL to garbage.
1535 	 *  This behavior is undocumented and Bison
1536 	 *  users should not rely upon it.  Assigning to YYVAL
1537 	 *  unconditionally makes the parser a bit smaller, and it avoids a
1538 	 *  GCC warning that YYVAL may be used uninitialized.  */
1539 	yyval = yyvsp[1 - yylen];
1540 
1541 
1542 	YY_REDUCE_PRINT(yyn);
1543 	switch (yyn) {
1544 	case 2:
1545 #line 192 "OSUnserializeXML.y"
1546 		{ yyerror("unexpected end of buffer");
1547 		  YYERROR;
1548 		  ;}
1549 		break;
1550 
1551 	case 3:
1552 #line 195 "OSUnserializeXML.y"
1553 		{ STATE->parsedObject = (yyvsp[(1) - (1)])->object;
1554 		  (yyvsp[(1) - (1)])->object = 0;
1555 		  freeObject(STATE, (yyvsp[(1) - (1)]));
1556 		  YYACCEPT;
1557 		  ;}
1558 		break;
1559 
1560 	case 4:
1561 #line 200 "OSUnserializeXML.y"
1562 		{ yyerror("syntax error");
1563 		  YYERROR;
1564 		  ;}
1565 		break;
1566 
1567 	case 5:
1568 #line 205 "OSUnserializeXML.y"
1569 		{ (yyval) = buildDictionary(STATE, (yyvsp[(1) - (1)]));
1570 
1571 		  if (!yyval->object) {
1572 			  yyerror("buildDictionary");
1573 			  YYERROR;
1574 		  }
1575 		  STATE->parsedObjectCount++;
1576 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1577 			  yyerror("maximum object count");
1578 			  YYERROR;
1579 		  }
1580 		  ;}
1581 		break;
1582 
1583 	case 6:
1584 #line 217 "OSUnserializeXML.y"
1585 		{ (yyval) = buildArray(STATE, (yyvsp[(1) - (1)]));
1586 
1587 		  if (!yyval->object) {
1588 			  yyerror("buildArray");
1589 			  YYERROR;
1590 		  }
1591 		  STATE->parsedObjectCount++;
1592 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1593 			  yyerror("maximum object count");
1594 			  YYERROR;
1595 		  }
1596 		  ;}
1597 		break;
1598 
1599 	case 7:
1600 #line 229 "OSUnserializeXML.y"
1601 		{ (yyval) = buildSet(STATE, (yyvsp[(1) - (1)]));
1602 
1603 		  if (!yyval->object) {
1604 			  yyerror("buildSet");
1605 			  YYERROR;
1606 		  }
1607 		  STATE->parsedObjectCount++;
1608 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1609 			  yyerror("maximum object count");
1610 			  YYERROR;
1611 		  }
1612 		  ;}
1613 		break;
1614 
1615 	case 8:
1616 #line 241 "OSUnserializeXML.y"
1617 		{ (yyval) = buildString(STATE, (yyvsp[(1) - (1)]));
1618 
1619 		  if (!yyval->object) {
1620 			  yyerror("buildString");
1621 			  YYERROR;
1622 		  }
1623 		  STATE->parsedObjectCount++;
1624 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1625 			  yyerror("maximum object count");
1626 			  YYERROR;
1627 		  }
1628 		  ;}
1629 		break;
1630 
1631 	case 9:
1632 #line 253 "OSUnserializeXML.y"
1633 		{ (yyval) = buildData(STATE, (yyvsp[(1) - (1)]));
1634 
1635 		  if (!yyval->object) {
1636 			  yyerror("buildData");
1637 			  YYERROR;
1638 		  }
1639 		  STATE->parsedObjectCount++;
1640 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1641 			  yyerror("maximum object count");
1642 			  YYERROR;
1643 		  }
1644 		  ;}
1645 		break;
1646 
1647 	case 10:
1648 #line 265 "OSUnserializeXML.y"
1649 		{ (yyval) = buildNumber(STATE, (yyvsp[(1) - (1)]));
1650 
1651 		  if (!yyval->object) {
1652 			  yyerror("buildNumber");
1653 			  YYERROR;
1654 		  }
1655 		  STATE->parsedObjectCount++;
1656 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1657 			  yyerror("maximum object count");
1658 			  YYERROR;
1659 		  }
1660 		  ;}
1661 		break;
1662 
1663 	case 11:
1664 #line 277 "OSUnserializeXML.y"
1665 		{ (yyval) = buildBoolean(STATE, (yyvsp[(1) - (1)]));
1666 
1667 		  if (!yyval->object) {
1668 			  yyerror("buildBoolean");
1669 			  YYERROR;
1670 		  }
1671 		  STATE->parsedObjectCount++;
1672 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1673 			  yyerror("maximum object count");
1674 			  YYERROR;
1675 		  }
1676 		  ;}
1677 		break;
1678 
1679 	case 12:
1680 #line 289 "OSUnserializeXML.y"
1681 		{ (yyval) = retrieveObject(STATE, (yyvsp[(1) - (1)])->idref);
1682 		  if ((yyval)) {
1683 			  STATE->retrievedObjectCount++;
1684 			  (yyval)->object->retain();
1685 			  if (STATE->retrievedObjectCount > MAX_REFED_OBJECTS) {
1686 				  yyerror("maximum object reference count");
1687 				  YYERROR;
1688 			  }
1689 		  } else {
1690 			  yyerror("forward reference detected");
1691 			  YYERROR;
1692 		  }
1693 		  freeObject(STATE, (yyvsp[(1) - (1)]));
1694 
1695 		  STATE->parsedObjectCount++;
1696 		  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1697 			  yyerror("maximum object count");
1698 			  YYERROR;
1699 		  }
1700 		  ;}
1701 		break;
1702 
1703 	case 13:
1704 #line 313 "OSUnserializeXML.y"
1705 		{ (yyval) = (yyvsp[(1) - (2)]);
1706 		  (yyval)->elements = NULL;
1707 		  ;}
1708 		break;
1709 
1710 	case 14:
1711 #line 316 "OSUnserializeXML.y"
1712 		{ (yyval) = (yyvsp[(1) - (3)]);
1713 		  (yyval)->elements = (yyvsp[(2) - (3)]);
1714 		  ;}
1715 		break;
1716 
1717 	case 17:
1718 #line 323 "OSUnserializeXML.y"
1719 		{ (yyval) = (yyvsp[(2) - (2)]);
1720 		  (yyval)->next = (yyvsp[(1) - (2)]);
1721 
1722 		  object_t *o;
1723 		  o = (yyval)->next;
1724 		  while (o) {
1725 			  if (o->key == (yyval)->key) {
1726 				  yyerror("duplicate dictionary key");
1727 				  YYERROR;
1728 			  }
1729 			  o = o->next;
1730 		  }
1731 		  ;}
1732 		break;
1733 
1734 	case 18:
1735 #line 338 "OSUnserializeXML.y"
1736 		{ (yyval) = (yyvsp[(1) - (2)]);
1737 		  (yyval)->key = (OSSymbol *)(yyval)->object;
1738 		  (yyval)->object = (yyvsp[(2) - (2)])->object;
1739 		  (yyval)->next = NULL;
1740 		  (yyvsp[(2) - (2)])->object = 0;
1741 		  freeObject(STATE, (yyvsp[(2) - (2)]));
1742 		  ;}
1743 		break;
1744 
1745 	case 19:
1746 #line 347 "OSUnserializeXML.y"
1747 		{ (yyval) = buildSymbol(STATE, (yyvsp[(1) - (1)]));
1748 
1749 //				  STATE->parsedObjectCount++;
1750 //				  if (STATE->parsedObjectCount > MAX_OBJECTS) {
1751 //				    yyerror("maximum object count");
1752 //				    YYERROR;
1753 //				  }
1754 		  ;}
1755 		break;
1756 
1757 	case 20:
1758 #line 359 "OSUnserializeXML.y"
1759 		{ (yyval) = (yyvsp[(1) - (2)]);
1760 		  (yyval)->elements = NULL;
1761 		  ;}
1762 		break;
1763 
1764 	case 21:
1765 #line 362 "OSUnserializeXML.y"
1766 		{ (yyval) = (yyvsp[(1) - (3)]);
1767 		  (yyval)->elements = (yyvsp[(2) - (3)]);
1768 		  ;}
1769 		break;
1770 
1771 	case 23:
1772 #line 368 "OSUnserializeXML.y"
1773 		{ (yyval) = (yyvsp[(1) - (2)]);
1774 		  (yyval)->elements = NULL;
1775 		  ;}
1776 		break;
1777 
1778 	case 24:
1779 #line 371 "OSUnserializeXML.y"
1780 		{ (yyval) = (yyvsp[(1) - (3)]);
1781 		  (yyval)->elements = (yyvsp[(2) - (3)]);
1782 		  ;}
1783 		break;
1784 
1785 	case 26:
1786 #line 377 "OSUnserializeXML.y"
1787 		{ (yyval) = (yyvsp[(1) - (1)]);
1788 		  (yyval)->next = NULL;
1789 		  ;}
1790 		break;
1791 
1792 	case 27:
1793 #line 380 "OSUnserializeXML.y"
1794 		{ (yyval) = (yyvsp[(2) - (2)]);
1795 		  (yyval)->next = (yyvsp[(1) - (2)]);
1796 		  ;}
1797 		break;
1798 
1799 
1800 /* Line 1267 of yacc.c.  */
1801 #line 1747 "OSUnserializeXML.tab.c"
1802 	default: break;
1803 	}
1804 	YY_SYMBOL_PRINT("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1805 
1806 	YYPOPSTACK(yylen);
1807 	yylen = 0;
1808 	YY_STACK_PRINT(yyss, yyssp);
1809 
1810 	*++yyvsp = yyval;
1811 
1812 
1813 	/* Now `shift' the result of the reduction.  Determine what state
1814 	 *  that goes to, based on the state we popped back to and the rule
1815 	 *  number reduced by.  */
1816 
1817 	yyn = yyr1[yyn];
1818 
1819 	yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1820 	if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) {
1821 		yystate = yytable[yystate];
1822 	} else {
1823 		yystate = yydefgoto[yyn - YYNTOKENS];
1824 	}
1825 
1826 	goto yynewstate;
1827 
1828 
1829 /*------------------------------------.
1830  | yyerrlab -- here on detecting error |
1831  |   `------------------------------------*/
1832 yyerrlab:
1833 	/* If not already recovering from an error, report this error.  */
1834 	if (!yyerrstatus) {
1835 		++yynerrs;
1836 #if !YYERROR_VERBOSE
1837 		yyerror(YY_("syntax error"));
1838 #else
1839 		{
1840 			YYSIZE_T yysize = yysyntax_error(0, yystate, yychar);
1841 			if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) {
1842 				YYSIZE_T yyalloc = 2 * yysize;
1843 				if (!(yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) {
1844 					yyalloc = YYSTACK_ALLOC_MAXIMUM;
1845 				}
1846 				if (yymsg != yymsgbuf) {
1847 					YYSTACK_FREE(yymsg);
1848 				}
1849 				yymsg = (char *) YYSTACK_ALLOC(yyalloc);
1850 				if (yymsg) {
1851 					yymsg_alloc = yyalloc;
1852 				} else {
1853 					yymsg = yymsgbuf;
1854 					yymsg_alloc = sizeof yymsgbuf;
1855 				}
1856 			}
1857 
1858 			if (0 < yysize && yysize <= yymsg_alloc) {
1859 				(void) yysyntax_error(yymsg, yystate, yychar);
1860 				yyerror(yymsg);
1861 			} else {
1862 				yyerror(YY_("syntax error"));
1863 				if (yysize != 0) {
1864 					goto yyexhaustedlab;
1865 				}
1866 			}
1867 		}
1868 #endif
1869 	}
1870 
1871 
1872 
1873 	if (yyerrstatus == 3) {
1874 		/* If just tried and failed to reuse look-ahead token after an
1875 		 *  error, discard it.  */
1876 
1877 		if (yychar <= YYEOF) {
1878 			/* Return failure if at end of input.  */
1879 			if (yychar == YYEOF) {
1880 				YYABORT;
1881 			}
1882 		} else {
1883 			yydestruct("Error: discarding",
1884 			    yytoken, &yylval);
1885 			yychar = YYEMPTY;
1886 		}
1887 	}
1888 
1889 	/* Else will try to reuse look-ahead token after shifting the error
1890 	 *  token.  */
1891 	goto yyerrlab1;
1892 
1893 
1894 /*---------------------------------------------------.
1895  | yyerrorlab -- error raised explicitly by YYERROR.  |
1896  |   `---------------------------------------------------*/
1897 yyerrorlab:
1898 
1899 	/* Pacify compilers like GCC when the user code never invokes
1900 	 *  YYERROR and the label yyerrorlab therefore never appears in user
1901 	 *  code.  */
1902 	if (/*CONSTCOND*/ 0) {
1903 		goto yyerrorlab;
1904 	}
1905 
1906 	/* Do not reclaim the symbols of the rule which action triggered
1907 	 *  this YYERROR.  */
1908 	YYPOPSTACK(yylen);
1909 	yylen = 0;
1910 	YY_STACK_PRINT(yyss, yyssp);
1911 	yystate = *yyssp;
1912 	goto yyerrlab1;
1913 
1914 
1915 /*-------------------------------------------------------------.
1916  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
1917  |   `-------------------------------------------------------------*/
1918 yyerrlab1:
1919 	yyerrstatus = 3; /* Each real token shifted decrements this.  */
1920 
1921 	for (;;) {
1922 		yyn = yypact[yystate];
1923 		if (yyn != YYPACT_NINF) {
1924 			yyn += YYTERROR;
1925 			if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) {
1926 				yyn = yytable[yyn];
1927 				if (0 < yyn) {
1928 					break;
1929 				}
1930 			}
1931 		}
1932 
1933 		/* Pop the current state because it cannot handle the error token.  */
1934 		if (yyssp == yyss) {
1935 			YYABORT;
1936 		}
1937 
1938 
1939 		yydestruct("Error: popping",
1940 		    yystos[yystate], yyvsp);
1941 		YYPOPSTACK(1);
1942 		yystate = *yyssp;
1943 		YY_STACK_PRINT(yyss, yyssp);
1944 	}
1945 
1946 	if (yyn == YYFINAL) {
1947 		YYACCEPT;
1948 	}
1949 
1950 	*++yyvsp = yylval;
1951 
1952 
1953 	/* Shift the error token.  */
1954 	YY_SYMBOL_PRINT("Shifting", yystos[yyn], yyvsp, yylsp);
1955 
1956 	yystate = yyn;
1957 	goto yynewstate;
1958 
1959 
1960 /*-------------------------------------.
1961  | yyacceptlab -- YYACCEPT comes here.  |
1962  |   `-------------------------------------*/
1963 yyacceptlab:
1964 	yyresult = 0;
1965 	goto yyreturn;
1966 
1967 /*-----------------------------------.
1968  | yyabortlab -- YYABORT comes here.  |
1969  |   `-----------------------------------*/
1970 yyabortlab:
1971 	yyresult = 1;
1972 	goto yyreturn;
1973 
1974 #ifndef yyoverflow
1975 /*-------------------------------------------------.
1976  | yyexhaustedlab -- memory exhaustion comes here.  |
1977  |   `-------------------------------------------------*/
1978 yyexhaustedlab:
1979 	yyerror(YY_("memory exhausted"));
1980 	yyresult = 2;
1981 	/* Fall through.  */
1982 #endif
1983 
1984 yyreturn:
1985 	if (yychar != YYEOF && yychar != YYEMPTY) {
1986 		yydestruct("Cleanup: discarding lookahead",
1987 		    yytoken, &yylval);
1988 	}
1989 	/* Do not reclaim the symbols of the rule which action triggered
1990 	 *  this YYABORT or YYACCEPT.  */
1991 	YYPOPSTACK(yylen);
1992 	YY_STACK_PRINT(yyss, yyssp);
1993 	while (yyssp != yyss) {
1994 		yydestruct("Cleanup: popping",
1995 		    yystos[*yyssp], yyvsp);
1996 		YYPOPSTACK(1);
1997 	}
1998 #ifndef yyoverflow
1999 	if (yyss != yyssa) {
2000 		YYSTACK_FREE(yyss);
2001 	}
2002 #endif
2003 #if YYERROR_VERBOSE
2004 	if (yymsg != yymsgbuf) {
2005 		YYSTACK_FREE(yymsg);
2006 	}
2007 #endif
2008 	/* Make sure YYID is used.  */
2009 	return YYID(yyresult);
2010 }
2011 
2012 
2013 #line 402 "OSUnserializeXML.y"
2014 
2015 
2016 int
2017 OSUnserializeerror(parser_state_t * state, const char *s)  /* Called by yyparse on errors */
2018 {
2019 	if (state->errorString) {
2020 		char tempString[128];
2021 		snprintf(tempString, 128, "OSUnserializeXML: %s near line %d\n", s, state->lineNumber);
2022 		*(state->errorString) = OSString::withCString(tempString);
2023 	}
2024 
2025 	return 0;
2026 }
2027 
2028 #define TAG_MAX_LENGTH          32
2029 #define TAG_MAX_ATTRIBUTES      32
2030 #define TAG_BAD                 0
2031 #define TAG_START               1
2032 #define TAG_END                 2
2033 #define TAG_EMPTY               3
2034 #define TAG_IGNORE              4
2035 
2036 #define currentChar()   (state->parseBuffer[state->parseBufferIndex])
2037 #define nextChar()      (state->parseBuffer[++state->parseBufferIndex])
2038 #define prevChar()      (state->parseBuffer[state->parseBufferIndex - 1])
2039 
2040 #define isSpace(c)      ((c) == ' ' || (c) == '\t')
2041 #define isAlpha(c)      (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
2042 #define isDigit(c)      ((c) >= '0' && (c) <= '9')
2043 #define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
2044 #define isHexDigit(c)   (isDigit(c) || isAlphaDigit(c))
2045 #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
2046 
2047 static int
2048 getTag(parser_state_t *state,
2049     char tag[TAG_MAX_LENGTH],
2050     int *attributeCount,
2051     char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH],
2052     char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH] )
2053 {
2054 	int length = 0;
2055 	int c = currentChar();
2056 	int tagType = TAG_START;
2057 
2058 	*attributeCount = 0;
2059 
2060 	if (c != '<') {
2061 		return TAG_BAD;
2062 	}
2063 	c = nextChar();         // skip '<'
2064 
2065 
2066 	// <!TAG   declarations     >
2067 	// <!--     comments      -->
2068 	if (c == '!') {
2069 		c = nextChar();
2070 		bool isComment = (c == '-') && ((c = nextChar()) != 0) && (c == '-');
2071 		if (!isComment && !isAlpha(c)) {
2072 			return TAG_BAD;                      // <!1, <!-A, <!eos
2073 		}
2074 		while (c && (c = nextChar()) != 0) {
2075 			if (c == '\n') {
2076 				state->lineNumber++;
2077 			}
2078 			if (isComment) {
2079 				if (c != '-') {
2080 					continue;
2081 				}
2082 				c = nextChar();
2083 				if (c != '-') {
2084 					continue;
2085 				}
2086 				c = nextChar();
2087 			}
2088 			if (c == '>') {
2089 				(void)nextChar();
2090 				return TAG_IGNORE;
2091 			}
2092 			if (isComment) {
2093 				break;
2094 			}
2095 		}
2096 		return TAG_BAD;
2097 	} else
2098 	// <? Processing Instructions  ?>
2099 	if (c == '?') {
2100 		while ((c = nextChar()) != 0) {
2101 			if (c == '\n') {
2102 				state->lineNumber++;
2103 			}
2104 			if (c != '?') {
2105 				continue;
2106 			}
2107 			c = nextChar();
2108 			if (!c) {
2109 				return TAG_IGNORE;
2110 			}
2111 			if (c == '>') {
2112 				(void)nextChar();
2113 				return TAG_IGNORE;
2114 			}
2115 		}
2116 		return TAG_BAD;
2117 	} else
2118 	// </ end tag >
2119 	if (c == '/') {
2120 		c = nextChar();         // skip '/'
2121 		tagType = TAG_END;
2122 	}
2123 	if (!isAlpha(c)) {
2124 		return TAG_BAD;
2125 	}
2126 
2127 	/* find end of tag while copying it */
2128 	while (isAlphaNumeric(c)) {
2129 		tag[length++] = c;
2130 		c = nextChar();
2131 		if (length >= (TAG_MAX_LENGTH - 1)) {
2132 			return TAG_BAD;
2133 		}
2134 	}
2135 
2136 	tag[length] = 0;
2137 
2138 //	printf("tag %s, type %d\n", tag, tagType);
2139 
2140 	// look for attributes of the form attribute = "value" ...
2141 	while ((c != '>') && (c != '/')) {
2142 		while (isSpace(c)) {
2143 			c = nextChar();
2144 		}
2145 
2146 		length = 0;
2147 		while (isAlphaNumeric(c)) {
2148 			attributes[*attributeCount][length++] = c;
2149 			if (length >= (TAG_MAX_LENGTH - 1)) {
2150 				return TAG_BAD;
2151 			}
2152 			c = nextChar();
2153 		}
2154 		attributes[*attributeCount][length] = 0;
2155 
2156 		while (isSpace(c)) {
2157 			c = nextChar();
2158 		}
2159 
2160 		if (c != '=') {
2161 			return TAG_BAD;
2162 		}
2163 		c = nextChar();
2164 
2165 		while (isSpace(c)) {
2166 			c = nextChar();
2167 		}
2168 
2169 		if (c != '"') {
2170 			return TAG_BAD;
2171 		}
2172 		c = nextChar();
2173 		length = 0;
2174 		while (c != '"') {
2175 			values[*attributeCount][length++] = c;
2176 			if (length >= (TAG_MAX_LENGTH - 1)) {
2177 				return TAG_BAD;
2178 			}
2179 			c = nextChar();
2180 			if (!c) {
2181 				return TAG_BAD;
2182 			}
2183 		}
2184 		values[*attributeCount][length] = 0;
2185 
2186 		c = nextChar(); // skip closing quote
2187 
2188 //		printf("	attribute '%s' = '%s', nextchar = '%c'\n",
2189 //		       attributes[*attributeCount], values[*attributeCount], c);
2190 
2191 		(*attributeCount)++;
2192 		if (*attributeCount >= TAG_MAX_ATTRIBUTES) {
2193 			return TAG_BAD;
2194 		}
2195 	}
2196 
2197 	if (c == '/') {
2198 		c = nextChar();         // skip '/'
2199 		tagType = TAG_EMPTY;
2200 	}
2201 	if (c != '>') {
2202 		return TAG_BAD;
2203 	}
2204 	c = nextChar();         // skip '>'
2205 
2206 	return tagType;
2207 }
2208 
2209 static char *
2210 getString(parser_state_t *state, int *alloc_lengthp)
2211 {
2212 	int c = currentChar();
2213 	int start, length, i, j;
2214 	char * tempString;
2215 
2216 	start = state->parseBufferIndex;
2217 	/* find end of string */
2218 
2219 	while (c != 0) {
2220 		if (c == '\n') {
2221 			state->lineNumber++;
2222 		}
2223 		if (c == '<') {
2224 			break;
2225 		}
2226 		c = nextChar();
2227 	}
2228 
2229 	if (c != '<') {
2230 		return 0;
2231 	}
2232 
2233 	length = state->parseBufferIndex - start;
2234 
2235 	/* copy to null terminated buffer */
2236 	tempString = (char *)malloc(length + 1);
2237 	if (tempString == NULL) {
2238 		printf("OSUnserializeXML: can't alloc temp memory\n");
2239 		goto error;
2240 	}
2241 	if (alloc_lengthp) {
2242 		*alloc_lengthp = length + 1;
2243 	}
2244 
2245 	// copy out string in tempString
2246 	// "&amp;" -> '&', "&lt;" -> '<', "&gt;" -> '>'
2247 
2248 	i = j = 0;
2249 	while (i < length) {
2250 		c = state->parseBuffer[start + i++];
2251 		if (c != '&') {
2252 			tempString[j++] = c;
2253 		} else {
2254 			if ((i + 3) > length) {
2255 				goto error;
2256 			}
2257 			c = state->parseBuffer[start + i++];
2258 			if (c == 'l') {
2259 				if (state->parseBuffer[start + i++] != 't') {
2260 					goto error;
2261 				}
2262 				if (state->parseBuffer[start + i++] != ';') {
2263 					goto error;
2264 				}
2265 				tempString[j++] = '<';
2266 				continue;
2267 			}
2268 			if (c == 'g') {
2269 				if (state->parseBuffer[start + i++] != 't') {
2270 					goto error;
2271 				}
2272 				if (state->parseBuffer[start + i++] != ';') {
2273 					goto error;
2274 				}
2275 				tempString[j++] = '>';
2276 				continue;
2277 			}
2278 			if ((i + 3) > length) {
2279 				goto error;
2280 			}
2281 			if (c == 'a') {
2282 				if (state->parseBuffer[start + i++] != 'm') {
2283 					goto error;
2284 				}
2285 				if (state->parseBuffer[start + i++] != 'p') {
2286 					goto error;
2287 				}
2288 				if (state->parseBuffer[start + i++] != ';') {
2289 					goto error;
2290 				}
2291 				tempString[j++] = '&';
2292 				continue;
2293 			}
2294 			goto error;
2295 		}
2296 	}
2297 	tempString[j] = 0;
2298 
2299 //	printf("string %s\n", tempString);
2300 
2301 	return tempString;
2302 
2303 error:
2304 	if (tempString) {
2305 		safe_free(tempString, length + 1);
2306 		if (alloc_lengthp) {
2307 			*alloc_lengthp = 0;
2308 		}
2309 	}
2310 	return 0;
2311 }
2312 
2313 static long long
2314 getNumber(parser_state_t *state)
2315 {
2316 	unsigned long long n = 0;
2317 	int base = 10;
2318 	bool negate = false;
2319 	int c = currentChar();
2320 
2321 	if (c == '0') {
2322 		c = nextChar();
2323 		if (c == 'x') {
2324 			base = 16;
2325 			c = nextChar();
2326 		}
2327 	}
2328 	if (base == 10) {
2329 		if (c == '-') {
2330 			negate = true;
2331 			c = nextChar();
2332 		}
2333 		while (isDigit(c)) {
2334 			n = (n * base + c - '0');
2335 			c = nextChar();
2336 		}
2337 		if (negate) {
2338 			n = (unsigned long long)((long long)n * (long long)-1);
2339 		}
2340 	} else {
2341 		while (isHexDigit(c)) {
2342 			if (isDigit(c)) {
2343 				n = (n * base + c - '0');
2344 			} else {
2345 				n = (n * base + 0xa + c - 'a');
2346 			}
2347 			c = nextChar();
2348 		}
2349 	}
2350 //	printf("number 0x%x\n", (unsigned long)n);
2351 	return n;
2352 }
2353 
2354 // taken from CFXMLParsing/CFPropertyList.c
2355 
2356 static const signed char __CFPLDataDecodeTable[128] = {
2357 	/* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
2358 	/* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
2359 	/* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
2360 	/* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
2361 	/* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
2362 	/* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
2363 	/* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
2364 	/* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
2365 	/* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
2366 	/* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
2367 	/* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
2368 	/* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
2369 	/* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
2370 	/* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
2371 	/* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
2372 	/* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
2373 };
2374 
2375 #define DATA_ALLOC_SIZE 4096
2376 
2377 static void *
2378 getCFEncodedData(parser_state_t *state, unsigned int *size)
2379 {
2380 	int numeq = 0, cntr = 0;
2381 	unsigned int acc = 0;
2382 	int tmpbufpos = 0;
2383 	size_t tmpbuflen = DATA_ALLOC_SIZE;
2384 	unsigned char *tmpbuf = (unsigned char *)malloc(tmpbuflen);
2385 
2386 	int c = currentChar();
2387 	*size = 0;
2388 
2389 	while (c != '<') {
2390 		c &= 0x7f;
2391 		if (c == 0) {
2392 			safe_free(tmpbuf, tmpbuflen);
2393 			return 0;
2394 		}
2395 		if (c == '=') {
2396 			numeq++;
2397 		} else {
2398 			numeq = 0;
2399 		}
2400 		if (c == '\n') {
2401 			state->lineNumber++;
2402 		}
2403 		if (__CFPLDataDecodeTable[c] < 0) {
2404 			c = nextChar();
2405 			continue;
2406 		}
2407 		cntr++;
2408 		acc <<= 6;
2409 		acc += __CFPLDataDecodeTable[c];
2410 		if (0 == (cntr & 0x3)) {
2411 			if (tmpbuflen <= tmpbufpos + 2) {
2412 				size_t oldsize = tmpbuflen;
2413 				tmpbuflen += DATA_ALLOC_SIZE;
2414 				tmpbuf = (unsigned char *)realloc(tmpbuf, oldsize, tmpbuflen);
2415 			}
2416 			tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
2417 			if (numeq < 2) {
2418 				tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
2419 			}
2420 			if (numeq < 1) {
2421 				tmpbuf[tmpbufpos++] = acc & 0xff;
2422 			}
2423 		}
2424 		c = nextChar();
2425 	}
2426 	*size = tmpbufpos;
2427 	if (*size == 0) {
2428 		safe_free(tmpbuf, tmpbuflen);
2429 		return 0;
2430 	}
2431 	return tmpbuf;
2432 }
2433 
2434 static void *
2435 getHexData(parser_state_t *state, unsigned int *size)
2436 {
2437 	int c;
2438 	unsigned char *d, *start, *lastStart;
2439 
2440 	size_t buflen = DATA_ALLOC_SIZE;
2441 	start = lastStart = d = (unsigned char *)malloc(buflen);
2442 	c = currentChar();
2443 
2444 	while (c != '<') {
2445 		if (isSpace(c)) {
2446 			while ((c = nextChar()) != 0 && isSpace(c)) {
2447 			}
2448 		}
2449 		;
2450 		if (c == '\n') {
2451 			state->lineNumber++;
2452 			c = nextChar();
2453 			continue;
2454 		}
2455 
2456 		// get high nibble
2457 		if (isDigit(c)) {
2458 			*d = (c - '0') << 4;
2459 		} else if (isAlphaDigit(c)) {
2460 			*d =  (0xa + (c - 'a')) << 4;
2461 		} else {
2462 			goto error;
2463 		}
2464 
2465 		// get low nibble
2466 		c = nextChar();
2467 		if (isDigit(c)) {
2468 			*d |= c - '0';
2469 		} else if (isAlphaDigit(c)) {
2470 			*d |= 0xa + (c - 'a');
2471 		} else {
2472 			goto error;
2473 		}
2474 
2475 		d++;
2476 		if ((d - lastStart) >= DATA_ALLOC_SIZE) {
2477 			int oldsize = d - start;
2478 			assert(oldsize == buflen);
2479 			buflen += DATA_ALLOC_SIZE;
2480 			start = (unsigned char *)realloc(start, oldsize, buflen);
2481 			d = lastStart = start + oldsize;
2482 		}
2483 		c = nextChar();
2484 	}
2485 
2486 	*size = d - start;
2487 	return start;
2488 
2489 error:
2490 
2491 	*size = 0;
2492 	safe_free(start, buflen);
2493 	return 0;
2494 }
2495 
2496 static int
2497 yylex(YYSTYPE *lvalp, parser_state_t *state)
2498 {
2499 	int c, i;
2500 	int tagType;
2501 	char tag[TAG_MAX_LENGTH];
2502 	int attributeCount;
2503 	char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
2504 	char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
2505 	object_t *object;
2506 	int alloc_length;
2507 top:
2508 	c = currentChar();
2509 
2510 	/* skip white space  */
2511 	if (isSpace(c)) {
2512 		while ((c = nextChar()) != 0 && isSpace(c)) {
2513 		}
2514 	}
2515 	;
2516 
2517 	/* keep track of line number, don't return \n's */
2518 	if (c == '\n') {
2519 		STATE->lineNumber++;
2520 		(void)nextChar();
2521 		goto top;
2522 	}
2523 
2524 	// end of the buffer?
2525 	if (!c) {
2526 		return 0;
2527 	}
2528 
2529 	tagType = getTag(STATE, tag, &attributeCount, attributes, values);
2530 	if (tagType == TAG_BAD) {
2531 		return SYNTAX_ERROR;
2532 	}
2533 	if (tagType == TAG_IGNORE) {
2534 		goto top;
2535 	}
2536 
2537 	// handle allocation and check for "ID" and "IDREF" tags up front
2538 	*lvalp = object = newObject(STATE);
2539 	object->idref = -1;
2540 	for (i = 0; i < attributeCount; i++) {
2541 		if (attributes[i][0] == 'I' && attributes[i][1] == 'D') {
2542 			// check for idref's, note: we ignore the tag, for
2543 			// this to work correctly, all idrefs must be unique
2544 			// across the whole serialization
2545 			if (attributes[i][2] == 'R' && attributes[i][3] == 'E' &&
2546 			    attributes[i][4] == 'F' && !attributes[i][5]) {
2547 				if (tagType != TAG_EMPTY) {
2548 					return SYNTAX_ERROR;
2549 				}
2550 				object->idref = strtol(values[i], NULL, 0);
2551 				return IDREF;
2552 			}
2553 			// check for id's
2554 			if (!attributes[i][2]) {
2555 				object->idref = strtol(values[i], NULL, 0);
2556 			} else {
2557 				return SYNTAX_ERROR;
2558 			}
2559 		}
2560 	}
2561 
2562 	switch (*tag) {
2563 	case 'a':
2564 		if (!strcmp(tag, "array")) {
2565 			if (tagType == TAG_EMPTY) {
2566 				object->elements = NULL;
2567 				return ARRAY;
2568 			}
2569 			return (tagType == TAG_START) ? '(' : ')';
2570 		}
2571 		break;
2572 	case 'd':
2573 		if (!strcmp(tag, "dict")) {
2574 			if (tagType == TAG_EMPTY) {
2575 				object->elements = NULL;
2576 				return DICTIONARY;
2577 			}
2578 			return (tagType == TAG_START) ? '{' : '}';
2579 		}
2580 		if (!strcmp(tag, "data")) {
2581 			unsigned int size;
2582 			if (tagType == TAG_EMPTY) {
2583 				object->data = NULL;
2584 				object->size = 0;
2585 				return DATA;
2586 			}
2587 
2588 			bool isHexFormat = false;
2589 			for (i = 0; i < attributeCount; i++) {
2590 				if (!strcmp(attributes[i], "format") && !strcmp(values[i], "hex")) {
2591 					isHexFormat = true;
2592 					break;
2593 				}
2594 			}
2595 			// CF encoded is the default form
2596 			if (isHexFormat) {
2597 				object->data = getHexData(STATE, &size);
2598 			} else {
2599 				object->data = getCFEncodedData(STATE, &size);
2600 			}
2601 			object->size = size;
2602 			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "data")) {
2603 				return SYNTAX_ERROR;
2604 			}
2605 			return DATA;
2606 		}
2607 		break;
2608 	case 'f':
2609 		if (!strcmp(tag, "false")) {
2610 			if (tagType == TAG_EMPTY) {
2611 				object->number = 0;
2612 				return BOOLEAN;
2613 			}
2614 		}
2615 		break;
2616 	case 'i':
2617 		if (!strcmp(tag, "integer")) {
2618 			object->size = 64;      // default
2619 			for (i = 0; i < attributeCount; i++) {
2620 				if (!strcmp(attributes[i], "size")) {
2621 					object->size = strtoul(values[i], NULL, 0);
2622 				}
2623 			}
2624 			if (tagType == TAG_EMPTY) {
2625 				object->number = 0;
2626 				return NUMBER;
2627 			}
2628 			object->number = getNumber(STATE);
2629 			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "integer")) {
2630 				return SYNTAX_ERROR;
2631 			}
2632 			return NUMBER;
2633 		}
2634 		break;
2635 	case 'k':
2636 		if (!strcmp(tag, "key")) {
2637 			if (tagType == TAG_EMPTY) {
2638 				return SYNTAX_ERROR;
2639 			}
2640 			object->string = getString(STATE, &alloc_length);
2641 			if (!object->string) {
2642 				return SYNTAX_ERROR;
2643 			}
2644 			object->string_alloc_length = alloc_length;
2645 			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
2646 			    || strcmp(tag, "key")) {
2647 				return SYNTAX_ERROR;
2648 			}
2649 			return KEY;
2650 		}
2651 		break;
2652 	case 'p':
2653 		if (!strcmp(tag, "plist")) {
2654 			freeObject(STATE, object);
2655 			goto top;
2656 		}
2657 		break;
2658 	case 's':
2659 		if (!strcmp(tag, "string")) {
2660 			if (tagType == TAG_EMPTY) {
2661 				object->string = (char *)malloc(1);
2662 				object->string_alloc_length = 1;
2663 				object->string[0] = 0;
2664 				return STRING;
2665 			}
2666 			object->string = getString(STATE, &alloc_length);
2667 			if (!object->string) {
2668 				return SYNTAX_ERROR;
2669 			}
2670 			object->string_alloc_length = alloc_length;
2671 			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
2672 			    || strcmp(tag, "string")) {
2673 				return SYNTAX_ERROR;
2674 			}
2675 			return STRING;
2676 		}
2677 		if (!strcmp(tag, "set")) {
2678 			if (tagType == TAG_EMPTY) {
2679 				object->elements = NULL;
2680 				return SET;;
2681 			}
2682 			if (tagType == TAG_START) {
2683 				return '[';
2684 			} else {
2685 				return ']';
2686 			}
2687 		}
2688 		break;
2689 	case 't':
2690 		if (!strcmp(tag, "true")) {
2691 			if (tagType == TAG_EMPTY) {
2692 				object->number = 1;
2693 				return BOOLEAN;
2694 			}
2695 		}
2696 		break;
2697 	}
2698 
2699 	return SYNTAX_ERROR;
2700 }
2701 
2702 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2703 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2704 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2705 
2706 // "java" like allocation, if this code hits a syntax error in the
2707 // the middle of the parsed string we just bail with pointers hanging
2708 // all over place, this code helps keeps it all together
2709 
2710 //static int object_count = 0;
2711 
2712 object_t *
2713 newObject(parser_state_t *state)
2714 {
2715 	object_t *o;
2716 
2717 	if (state->freeObjects) {
2718 		o = state->freeObjects;
2719 		state->freeObjects = state->freeObjects->next;
2720 	} else {
2721 		o = (object_t *)malloc(sizeof(object_t));
2722 //		object_count++;
2723 		o->free = state->objects;
2724 		state->objects = o;
2725 	}
2726 
2727 	return o;
2728 }
2729 
2730 void
2731 freeObject(parser_state_t * state, object_t *o)
2732 {
2733 	o->next = state->freeObjects;
2734 	state->freeObjects = o;
2735 }
2736 
2737 void
2738 cleanupObjects(parser_state_t *state)
2739 {
2740 	object_t *t, *o = state->objects;
2741 
2742 	while (o) {
2743 		if (o->object) {
2744 //			printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
2745 			o->object->release();
2746 		}
2747 		if (o->data) {
2748 //			printf("OSUnserializeXML: freeing   object o=%x data=%x\n", (int)o, (int)o->data);
2749 			free(o->data);
2750 		}
2751 		if (o->key) {
2752 //			printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
2753 			o->key->release();
2754 		}
2755 		if (o->string) {
2756 //			printf("OSUnserializeXML: freeing   object o=%x string=%x\n", (int)o, (int)o->string);
2757 			free(o->string);
2758 		}
2759 
2760 		t = o;
2761 		o = o->free;
2762 		safe_free(t, sizeof(object_t));
2763 //		object_count--;
2764 	}
2765 //	printf("object_count = %d\n", object_count);
2766 }
2767 
2768 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2769 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2770 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2771 
2772 static void
2773 rememberObject(parser_state_t *state, int tag, OSObject *o)
2774 {
2775 	char key[16];
2776 	snprintf(key, 16, "%u", tag);
2777 
2778 //	printf("remember key %s\n", key);
2779 
2780 	state->tags->setObject(key, o);
2781 }
2782 
2783 static object_t *
2784 retrieveObject(parser_state_t *state, int tag)
2785 {
2786 	OSObject *ref;
2787 	object_t *o;
2788 	char key[16];
2789 	snprintf(key, 16, "%u", tag);
2790 
2791 //	printf("retrieve key '%s'\n", key);
2792 
2793 	ref = state->tags->getObject(key);
2794 	if (!ref) {
2795 		return 0;
2796 	}
2797 
2798 	o = newObject(state);
2799 	o->object = ref;
2800 	return o;
2801 }
2802 
2803 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2804 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2805 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2806 
2807 object_t *
2808 buildDictionary(parser_state_t *state, object_t * header)
2809 {
2810 	object_t *o, *t;
2811 	int count = 0;
2812 	OSDictionary *dict;
2813 
2814 	// get count and reverse order
2815 	o = header->elements;
2816 	header->elements = 0;
2817 	while (o) {
2818 		count++;
2819 		t = o;
2820 		o = o->next;
2821 
2822 		t->next = header->elements;
2823 		header->elements = t;
2824 	}
2825 
2826 	dict = OSDictionary::withCapacity(count);
2827 	if (header->idref >= 0) {
2828 		rememberObject(state, header->idref, dict);
2829 	}
2830 
2831 	o = header->elements;
2832 	while (o) {
2833 		dict->setObject(o->key, o->object);
2834 
2835 		o->key->release();
2836 		o->object->release();
2837 		o->key = 0;
2838 		o->object = 0;
2839 
2840 		t = o;
2841 		o = o->next;
2842 		freeObject(state, t);
2843 	}
2844 	o = header;
2845 	o->object = dict;
2846 	return o;
2847 };
2848 
2849 object_t *
2850 buildArray(parser_state_t *state, object_t * header)
2851 {
2852 	object_t *o, *t;
2853 	int count = 0;
2854 	OSArray *array;
2855 
2856 	// get count and reverse order
2857 	o = header->elements;
2858 	header->elements = 0;
2859 	while (o) {
2860 		count++;
2861 		t = o;
2862 		o = o->next;
2863 
2864 		t->next = header->elements;
2865 		header->elements = t;
2866 	}
2867 
2868 	array = OSArray::withCapacity(count);
2869 	if (header->idref >= 0) {
2870 		rememberObject(state, header->idref, array);
2871 	}
2872 
2873 	o = header->elements;
2874 	while (o) {
2875 		array->setObject(o->object);
2876 
2877 		o->object->release();
2878 		o->object = 0;
2879 
2880 		t = o;
2881 		o = o->next;
2882 		freeObject(state, t);
2883 	}
2884 	o = header;
2885 	o->object = array;
2886 	return o;
2887 };
2888 
2889 object_t *
2890 buildSet(parser_state_t *state, object_t *header)
2891 {
2892 	object_t *o = buildArray(state, header);
2893 
2894 	OSArray *array = (OSArray *)o->object;
2895 	OSSet *set = OSSet::withArray(array, array->getCapacity());
2896 
2897 	// write over the reference created in buildArray
2898 	if (header->idref >= 0) {
2899 		rememberObject(state, header->idref, set);
2900 	}
2901 
2902 	array->release();
2903 	o->object = set;
2904 	return o;
2905 };
2906 
2907 object_t *
2908 buildString(parser_state_t *state, object_t *o)
2909 {
2910 	OSString *string;
2911 
2912 	string = OSString::withCString(o->string);
2913 	if (o->idref >= 0) {
2914 		rememberObject(state, o->idref, string);
2915 	}
2916 
2917 	free(o->string);
2918 	o->string = 0;
2919 	o->object = string;
2920 
2921 	return o;
2922 };
2923 
2924 object_t *
2925 buildSymbol(parser_state_t *state, object_t *o)
2926 {
2927 	OSSymbol *symbol;
2928 
2929 	symbol = const_cast < OSSymbol * > (OSSymbol::withCString(o->string));
2930 	if (o->idref >= 0) {
2931 		rememberObject(state, o->idref, symbol);
2932 	}
2933 
2934 	safe_free(o->string, o->string_alloc_length);
2935 	o->string = 0;
2936 	o->object = symbol;
2937 
2938 	return o;
2939 };
2940 
2941 object_t *
2942 buildData(parser_state_t *state, object_t *o)
2943 {
2944 	OSData *data;
2945 
2946 	if (o->size) {
2947 		data = OSData::withBytes(o->data, o->size);
2948 	} else {
2949 		data = OSData::withCapacity(0);
2950 	}
2951 	if (o->idref >= 0) {
2952 		rememberObject(state, o->idref, data);
2953 	}
2954 
2955 	if (o->size) {
2956 		free(o->data);
2957 	}
2958 	o->data = 0;
2959 	o->object = data;
2960 	return o;
2961 };
2962 
2963 object_t *
2964 buildNumber(parser_state_t *state, object_t *o)
2965 {
2966 	OSNumber *number = OSNumber::withNumber(o->number, o->size);
2967 
2968 	if (o->idref >= 0) {
2969 		rememberObject(state, o->idref, number);
2970 	}
2971 
2972 	o->object = number;
2973 	return o;
2974 };
2975 
2976 object_t *
2977 buildBoolean(parser_state_t *state __unused, object_t *o)
2978 {
2979 	o->object = ((o->number == 0) ? kOSBooleanFalse : kOSBooleanTrue);
2980 	o->object->retain();
2981 	return o;
2982 };
2983 
2984 OSObject*
2985 OSUnserializeXML(const char *buffer, OSString **errorString)
2986 {
2987 	OSObject *object;
2988 
2989 	if (!buffer) {
2990 		return 0;
2991 	}
2992 	parser_state_t *state = (parser_state_t *)malloc(sizeof(parser_state_t));
2993 	if (!state) {
2994 		return 0;
2995 	}
2996 
2997 	// just in case
2998 	if (errorString) {
2999 		*errorString = NULL;
3000 	}
3001 
3002 	state->parseBuffer = buffer;
3003 	state->parseBufferIndex = 0;
3004 	state->lineNumber = 1;
3005 	state->objects = 0;
3006 	state->freeObjects = 0;
3007 	state->tags = OSDictionary::withCapacity(128);
3008 	state->errorString = errorString;
3009 	state->parsedObject = 0;
3010 	state->parsedObjectCount = 0;
3011 	state->retrievedObjectCount = 0;
3012 
3013 	(void)yyparse((void *)state);
3014 
3015 	object = state->parsedObject;
3016 
3017 	cleanupObjects(state);
3018 	state->tags->release();
3019 	safe_free(state, sizeof(parser_state_t));
3020 
3021 	return object;
3022 }
3023 
3024 #include <libkern/OSSerializeBinary.h>
3025 
3026 OSObject*
3027 OSUnserializeXML(const char *buffer, size_t bufferSize, OSString **errorString)
3028 {
3029 	if (!buffer) {
3030 		return 0;
3031 	}
3032 	if (bufferSize < sizeof(kOSSerializeBinarySignature)) {
3033 		return 0;
3034 	}
3035 
3036 	if (!strcmp(kOSSerializeBinarySignature, buffer)
3037 	    || (kOSSerializeIndexedBinarySignature == (uint8_t)buffer[0])) {
3038 		return OSUnserializeBinary(buffer, bufferSize, errorString);
3039 	}
3040 
3041 	// XML must be null terminated
3042 	if (buffer[bufferSize - 1]) {
3043 		return 0;
3044 	}
3045 
3046 	return OSUnserializeXML(buffer, errorString);
3047 }
3048 
3049 
3050 //
3051 //
3052 //
3053 //
3054 //
3055 //		 DO NOT EDIT OSUnserializeXML.cpp!
3056 //
3057 //			this means you!
3058 //
3059 //
3060 //
3061 //
3062 //
3063