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