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