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