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