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