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