1/*
2 * Copyright (c) 2000-2006 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//
52//			this means you!
53//
54//
55//
56//
57
58/*  A Bison parser, made from OSUnserialize.y
59    by GNU Bison version 1.28  */
60
61#define YYBISON 1  /* Identify Bison output.  */
62
63#define yyparse OSUnserializeparse
64#define yylex OSUnserializelex
65#define yyerror OSUnserializeerror
66#define yylval OSUnserializelval
67#define yychar OSUnserializechar
68#define yydebug OSUnserializedebug
69#define yynerrs OSUnserializenerrs
70#define	NUMBER	257
71#define	STRING	258
72#define	DATA	259
73#define	BOOLEAN	260
74#define	SYNTAX_ERROR	261
75
76#line 54 "OSUnserialize.y"
77
78#include <libkern/c++/OSMetaClass.h>
79#include <libkern/c++/OSContainers.h>
80#include <libkern/c++/OSLib.h>
81
82typedef	struct object {
83	struct object	*next;
84	struct object	*prev;
85	void		*object;
86	int		size;		// for data
87	union {
88		void	*key;		// for dictionary
89		long long offset;	// for offset
90	} u;
91
92} object_t;
93
94static int yyparse();
95static int yyerror(char *s);
96static int yylex();
97
98static object_t * newObject();
99static void freeObject(object_t *o);
100
101static OSObject *buildOSDictionary(object_t *);
102static OSObject *buildOSArray(object_t *);
103static OSObject *buildOSSet(object_t *);
104static OSObject *buildOSString(object_t *);
105static OSObject *buildOSData(object_t *);
106static OSObject *buildOSOffset(object_t *);
107static OSObject *buildOSBoolean(object_t *o);
108
109static void rememberObject(int, object_t *);
110static OSObject *retrieveObject(int);
111
112// temp variable to use during parsing
113static object_t *o;
114
115// resultant object of parsed text
116static OSObject	*parsedObject;
117
118#define YYSTYPE object_t *
119
120extern "C" {
121extern void *kern_os_malloc(size_t size);
122extern void *kern_os_realloc(void * addr, size_t size);
123extern void kern_os_free(void * addr);
124} /* extern "C" */
125
126#define malloc(s) kern_os_malloc(s)
127#define realloc(a, s) kern_os_realloc(a, s)
128#define free(a) kern_os_free(a)
129
130#ifndef YYSTYPE
131#define YYSTYPE int
132#endif
133
134#ifndef __cplusplus
135#ifndef __STDC__
136#define const
137#endif
138#endif
139
140
141
142#define	YYFINAL		43
143#define	YYFLAG		-32768
144#define	YYNTBASE	19
145
146#define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 31)
147
148static const char yytranslate[] = {     0,
149     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
150     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
151     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
152     2,     2,     2,     2,     2,     2,     2,     2,     2,    13,
153    14,     2,     2,    17,     2,     2,     2,     2,     2,     2,
154     2,     2,     2,     2,     2,     2,     2,    18,    12,     2,
155    11,     2,     2,     8,     2,     2,     2,     2,     2,     2,
156     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
157     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
158    15,     2,    16,     2,     2,     2,     2,     2,     2,     2,
159     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
160     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
161     2,     2,     9,     2,    10,     2,     2,     2,     2,     2,
162     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
163     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
164     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
165     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
166     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
167     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
168     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
169     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
170     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
171     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
172     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
173     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
174     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
175     7
176};
177
178#if YYDEBUG != 0
179static const short yyprhs[] = {     0,
180     0,     1,     3,     5,     7,     9,    11,    13,    15,    17,
181    19,    22,    26,    29,    33,    35,    38,    43,    46,    50,
182    53,    57,    59,    63,    67,    69,    71
183};
184
185static const short yyrhs[] = {    -1,
186    20,     0,     7,     0,    21,     0,    24,     0,    25,     0,
187    29,     0,    28,     0,    27,     0,    30,     0,     8,     3,
188     0,    20,     8,     3,     0,     9,    10,     0,     9,    22,
189    10,     0,    23,     0,    22,    23,     0,    20,    11,    20,
190    12,     0,    13,    14,     0,    13,    26,    14,     0,    15,
191    16,     0,    15,    26,    16,     0,    20,     0,    26,    17,
192    20,     0,     3,    18,     3,     0,     5,     0,     4,     0,
193     6,     0
194};
195
196#endif
197
198#if YYDEBUG != 0
199static const short yyrline[] = { 0,
200   116,   117,   118,   121,   122,   123,   124,   125,   126,   127,
201   128,   137,   145,   146,   149,   150,   153,   163,   164,   167,
202   168,   171,   176,   187,   195,   200,   205
203};
204#endif
205
206
207#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
208
209static const char * const yytname[] = {   "$","error","$undefined.","NUMBER",
210"STRING","DATA","BOOLEAN","SYNTAX_ERROR","'@'","'{'","'}'","'='","';'","'('",
211"')'","'['","']'","','","':'","input","object","dict","pairs","pair","array",
212"set","elements","offset","data","string","boolean", NULL
213};
214#endif
215
216static const short yyr1[] = {     0,
217    19,    19,    19,    20,    20,    20,    20,    20,    20,    20,
218    20,    20,    21,    21,    22,    22,    23,    24,    24,    25,
219    25,    26,    26,    27,    28,    29,    30
220};
221
222static const short yyr2[] = {     0,
223     0,     1,     1,     1,     1,     1,     1,     1,     1,     1,
224     2,     3,     2,     3,     1,     2,     4,     2,     3,     2,
225     3,     1,     3,     3,     1,     1,     1
226};
227
228static const short yydefact[] = {     1,
229     0,    26,    25,    27,     3,     0,     0,     0,     0,     2,
230     4,     5,     6,     9,     8,     7,    10,     0,    11,    13,
231     0,     0,    15,    18,    22,     0,    20,     0,     0,    24,
232     0,    14,    16,    19,     0,    21,    12,     0,    23,    17,
233     0,     0,     0
234};
235
236static const short yydefgoto[] = {    41,
237    21,    11,    22,    23,    12,    13,    26,    14,    15,    16,
238    17
239};
240
241static const short yypact[] = {    12,
242   -13,-32768,-32768,-32768,-32768,     9,    33,    46,    -2,     2,
243-32768,-32768,-32768,-32768,-32768,-32768,-32768,    25,-32768,-32768,
244    21,    59,-32768,-32768,     2,    16,-32768,     7,    31,-32768,
245    72,-32768,-32768,-32768,    72,-32768,-32768,    14,     2,-32768,
246    40,    44,-32768
247};
248
249static const short yypgoto[] = {-32768,
250     0,-32768,-32768,    23,-32768,-32768,    38,-32768,-32768,-32768,
251-32768
252};
253
254
255#define	YYLAST		87
256
257
258static const short yytable[] = {    10,
259     1,     2,     3,     4,    18,     6,     7,    25,    25,    29,
260     8,    19,     9,    27,     1,     2,     3,     4,     5,     6,
261     7,    29,    36,    35,     8,    40,     9,    30,    29,    34,
262    38,    31,    35,    37,    39,     1,     2,     3,     4,    42,
263     6,     7,    20,    43,    33,     8,    28,     9,     1,     2,
264     3,     4,     0,     6,     7,     0,     0,     0,     8,    24,
265     9,     1,     2,     3,     4,     0,     6,     7,    32,     0,
266     0,     8,     0,     9,     1,     2,     3,     4,     0,     6,
267     7,     0,     0,     0,     8,     0,     9
268};
269
270static const short yycheck[] = {     0,
271     3,     4,     5,     6,    18,     8,     9,     8,     9,     8,
272    13,     3,    15,    16,     3,     4,     5,     6,     7,     8,
273     9,     8,    16,    17,    13,    12,    15,     3,     8,    14,
274    31,    11,    17,     3,    35,     3,     4,     5,     6,     0,
275     8,     9,    10,     0,    22,    13,     9,    15,     3,     4,
276     5,     6,    -1,     8,     9,    -1,    -1,    -1,    13,    14,
277    15,     3,     4,     5,     6,    -1,     8,     9,    10,    -1,
278    -1,    13,    -1,    15,     3,     4,     5,     6,    -1,     8,
279     9,    -1,    -1,    -1,    13,    -1,    15
280};
281/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
282#line 3 "/usr/share/bison.simple"
283/* This file comes from bison-1.28.  */
284
285/* Skeleton output parser for bison,
286   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
287
288   This program is free software; you can redistribute it and/or modify
289   it under the terms of the GNU General Public License as published by
290   the Free Software Foundation; either version 2, or (at your option)
291   any later version.
292
293   This program is distributed in the hope that it will be useful,
294   but WITHOUT ANY WARRANTY; without even the implied warranty of
295   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
296   GNU General Public License for more details.
297
298   You should have received a copy of the GNU General Public License
299   along with this program; if not, write to the Free Software
300   Foundation, Inc., 59 Temple Place - Suite 330,
301   Boston, MA 02111-1307, USA.  */
302
303/* As a special exception, when this file is copied by Bison into a
304   Bison output file, you may use that output file without restriction.
305   This special exception was added by the Free Software Foundation
306   in version 1.24 of Bison.  */
307
308/* This is the parser code that is written into each bison parser
309  when the %semantic_parser declaration is not specified in the grammar.
310  It was written by Richard Stallman by simplifying the hairy parser
311  used when %semantic_parser is specified.  */
312
313#ifndef YYSTACK_USE_ALLOCA
314#ifdef alloca
315#define YYSTACK_USE_ALLOCA
316#else /* alloca not defined */
317#ifdef __GNUC__
318#define YYSTACK_USE_ALLOCA
319#define alloca __builtin_alloca
320#else /* not GNU C.  */
321#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) || defined (__arm)
322#define YYSTACK_USE_ALLOCA
323#include <alloca.h>
324#else /* not sparc */
325/* We think this test detects Watcom and Microsoft C.  */
326/* This used to test MSDOS, but that is a bad idea
327   since that symbol is in the user namespace.  */
328#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
329#if 0 /* No need for malloc.h, which pollutes the namespace;
330	 instead, just don't use alloca.  */
331#include <malloc.h>
332#endif
333#else /* not MSDOS, or __TURBOC__ */
334#if defined(_AIX)
335/* I don't know what this was needed for, but it pollutes the namespace.
336   So I turned it off.   rms, 2 May 1997.  */
337/* #include <malloc.h>  */
338 #pragma alloca
339#define YYSTACK_USE_ALLOCA
340#else /* not MSDOS, or __TURBOC__, or _AIX */
341#if 0
342#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
343		 and on HPUX 10.  Eventually we can turn this on.  */
344#define YYSTACK_USE_ALLOCA
345#define alloca __builtin_alloca
346#endif /* __hpux */
347#endif
348#endif /* not _AIX */
349#endif /* not MSDOS, or __TURBOC__ */
350#endif /* not sparc */
351#endif /* not GNU C */
352#endif /* alloca not defined */
353#endif /* YYSTACK_USE_ALLOCA not defined */
354
355#ifdef YYSTACK_USE_ALLOCA
356#define YYSTACK_ALLOC alloca
357#else
358#define YYSTACK_ALLOC malloc
359#endif
360
361/* Note: there must be only one dollar sign in this file.
362   It is replaced by the list of actions, each action
363   as one case of the switch.  */
364
365#define yyerrok		(yyerrstatus = 0)
366#define yyclearin	(yychar = YYEMPTY)
367#define YYEMPTY		-2
368#define YYEOF		0
369#define YYACCEPT	goto yyacceptlab
370#define YYABORT 	goto yyabortlab
371#define YYERROR		goto yyerrlab1
372/* Like YYERROR except do call yyerror.
373   This remains here temporarily to ease the
374   transition to the new meaning of YYERROR, for GCC.
375   Once GCC version 2 has supplanted version 1, this can go.  */
376#define YYFAIL		goto yyerrlab
377#define YYRECOVERING()  (!!yyerrstatus)
378#define YYBACKUP(token, value) \
379do								\
380  if (yychar == YYEMPTY && yylen == 1)				\
381    { yychar = (token), yylval = (value);			\
382      yychar1 = YYTRANSLATE (yychar);				\
383      YYPOPSTACK;						\
384      goto yybackup;						\
385    }								\
386  else								\
387    { yyerror ("syntax error: cannot back up"); YYERROR; }	\
388while (0)
389
390#define YYTERROR	1
391#define YYERRCODE	256
392
393#ifndef YYPURE
394#define YYLEX		yylex()
395#endif
396
397#ifdef YYPURE
398#ifdef YYLSP_NEEDED
399#ifdef YYLEX_PARAM
400#define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
401#else
402#define YYLEX		yylex(&yylval, &yylloc)
403#endif
404#else /* not YYLSP_NEEDED */
405#ifdef YYLEX_PARAM
406#define YYLEX		yylex(&yylval, YYLEX_PARAM)
407#else
408#define YYLEX		yylex(&yylval)
409#endif
410#endif /* not YYLSP_NEEDED */
411#endif
412
413/* If nonreentrant, generate the variables here */
414
415#ifndef YYPURE
416
417int	yychar;			/*  the lookahead symbol		*/
418YYSTYPE	yylval;			/*  the semantic value of the		*/
419				/*  lookahead symbol			*/
420
421#ifdef YYLSP_NEEDED
422YYLTYPE yylloc;			/*  location data for the lookahead	*/
423				/*  symbol				*/
424#endif
425
426int yynerrs;			/*  number of parse errors so far       */
427#endif  /* not YYPURE */
428
429#if YYDEBUG != 0
430int yydebug;			/*  nonzero means print parse trace	*/
431/* Since this is uninitialized, it does not stop multiple parsers
432   from coexisting.  */
433#endif
434
435/*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
436
437#ifndef	YYINITDEPTH
438#define YYINITDEPTH 200
439#endif
440
441/*  YYMAXDEPTH is the maximum size the stacks can grow to
442    (effective only if the built-in stack extension method is used).  */
443
444#if YYMAXDEPTH == 0
445#undef YYMAXDEPTH
446#endif
447
448#ifndef YYMAXDEPTH
449#define YYMAXDEPTH 10000
450#endif
451
452/* Define __yy_memcpy.  Note that the size argument
453   should be passed with type unsigned int, because that is what the non-GCC
454   definitions require.  With GCC, __builtin_memcpy takes an arg
455   of type size_t, but it can handle unsigned int.  */
456
457#if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
458#define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
459#else				/* not GNU C or C++ */
460#ifndef __cplusplus
461
462/* This is the most reliable way to avoid incompatibilities
463   in available built-in functions on various systems.  */
464static void
465__yy_memcpy (to, from, count)
466     char *to;
467     char *from;
468     unsigned int count;
469{
470  register char *f = from;
471  register char *t = to;
472  register int i = count;
473
474  while (i-- > 0)
475    *t++ = *f++;
476}
477
478#else /* __cplusplus */
479
480/* This is the most reliable way to avoid incompatibilities
481   in available built-in functions on various systems.  */
482static void
483__yy_memcpy (char *to, char *from, unsigned int count)
484{
485  register char *t = to;
486  register char *f = from;
487  register int i = count;
488
489  while (i-- > 0)
490    *t++ = *f++;
491}
492
493#endif
494#endif
495
496#line 217 "/usr/share/bison.simple"
497
498/* The user can define YYPARSE_PARAM as the name of an argument to be passed
499   into yyparse.  The argument should have type void *.
500   It should actually point to an object.
501   Grammar actions can access the variable by casting it
502   to the proper pointer type.  */
503
504#ifdef YYPARSE_PARAM
505#ifdef __cplusplus
506#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
507#define YYPARSE_PARAM_DECL
508#else /* not __cplusplus */
509#define YYPARSE_PARAM_ARG YYPARSE_PARAM
510#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
511#endif /* not __cplusplus */
512#else /* not YYPARSE_PARAM */
513#define YYPARSE_PARAM_ARG
514#define YYPARSE_PARAM_DECL
515#endif /* not YYPARSE_PARAM */
516
517/* Prevent warning if -Wstrict-prototypes.  */
518#ifdef __GNUC__
519#ifdef YYPARSE_PARAM
520int yyparse (void *);
521#else
522int yyparse (void);
523#endif
524#endif
525
526int
527yyparse(YYPARSE_PARAM_ARG)
528     YYPARSE_PARAM_DECL
529{
530  register int yystate;
531  register int yyn;
532  register short *yyssp;
533  register YYSTYPE *yyvsp;
534  int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
535  int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
536
537  short	yyssa[YYINITDEPTH];	/*  the state stack			*/
538  YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
539
540  short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
541  YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
542
543#ifdef YYLSP_NEEDED
544  YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
545  YYLTYPE *yyls = yylsa;
546  YYLTYPE *yylsp;
547
548#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
549#else
550#define YYPOPSTACK   (yyvsp--, yyssp--)
551#endif
552
553  int yystacksize = YYINITDEPTH;
554  int yyfree_stacks = 0;
555
556#ifdef YYPURE
557  int yychar;
558  YYSTYPE yylval;
559  int yynerrs;
560#ifdef YYLSP_NEEDED
561  YYLTYPE yylloc;
562#endif
563#endif
564
565  YYSTYPE yyval;		/*  the variable used to return		*/
566				/*  semantic values from the action	*/
567				/*  routines				*/
568
569  int yylen;
570
571#if YYDEBUG != 0
572  if (yydebug)
573    fprintf(stderr, "Starting parse\n");
574#endif
575
576  yystate = 0;
577  yyerrstatus = 0;
578  yynerrs = 0;
579  yychar = YYEMPTY;		/* Cause a token to be read.  */
580
581  /* Initialize stack pointers.
582     Waste one element of value and location stack
583     so that they stay on the same level as the state stack.
584     The wasted elements are never initialized.  */
585
586  yyssp = yyss - 1;
587  yyvsp = yyvs;
588#ifdef YYLSP_NEEDED
589  yylsp = yyls;
590#endif
591
592/* Push a new state, which is found in  yystate  .  */
593/* In all cases, when you get here, the value and location stacks
594   have just been pushed. so pushing a state here evens the stacks.  */
595yynewstate:
596
597  *++yyssp = yystate;
598
599  if (yyssp >= yyss + yystacksize - 1)
600    {
601      /* Give user a chance to reallocate the stack */
602      /* Use copies of these so that the &'s don't force the real ones into memory. */
603      YYSTYPE *yyvs1 = yyvs;
604      short *yyss1 = yyss;
605#ifdef YYLSP_NEEDED
606      YYLTYPE *yyls1 = yyls;
607#endif
608
609      /* Get the current used size of the three stacks, in elements.  */
610      int size = yyssp - yyss + 1;
611
612#ifdef yyoverflow
613      /* Each stack pointer address is followed by the size of
614	 the data in use in that stack, in bytes.  */
615#ifdef YYLSP_NEEDED
616      /* This used to be a conditional around just the two extra args,
617	 but that might be undefined if yyoverflow is a macro.  */
618      yyoverflow("parser stack overflow",
619		 &yyss1, size * sizeof (*yyssp),
620		 &yyvs1, size * sizeof (*yyvsp),
621		 &yyls1, size * sizeof (*yylsp),
622		 &yystacksize);
623#else
624      yyoverflow("parser stack overflow",
625		 &yyss1, size * sizeof (*yyssp),
626		 &yyvs1, size * sizeof (*yyvsp),
627		 &yystacksize);
628#endif
629
630      yyss = yyss1; yyvs = yyvs1;
631#ifdef YYLSP_NEEDED
632      yyls = yyls1;
633#endif
634#else /* no yyoverflow */
635      /* Extend the stack our own way.  */
636      if (yystacksize >= YYMAXDEPTH)
637	{
638	  yyerror("parser stack overflow");
639	  if (yyfree_stacks)
640	    {
641	      free (yyss);
642	      free (yyvs);
643#ifdef YYLSP_NEEDED
644	      free (yyls);
645#endif
646	    }
647	  return 2;
648	}
649      yystacksize *= 2;
650      if (yystacksize > YYMAXDEPTH)
651	yystacksize = YYMAXDEPTH;
652#ifndef YYSTACK_USE_ALLOCA
653      yyfree_stacks = 1;
654#endif
655      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
656      __yy_memcpy ((char *)yyss, (char *)yyss1,
657		   size * (unsigned int) sizeof (*yyssp));
658      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
659      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
660		   size * (unsigned int) sizeof (*yyvsp));
661#ifdef YYLSP_NEEDED
662      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
663      __yy_memcpy ((char *)yyls, (char *)yyls1,
664		   size * (unsigned int) sizeof (*yylsp));
665#endif
666#endif /* no yyoverflow */
667
668      yyssp = yyss + size - 1;
669      yyvsp = yyvs + size - 1;
670#ifdef YYLSP_NEEDED
671      yylsp = yyls + size - 1;
672#endif
673
674#if YYDEBUG != 0
675      if (yydebug)
676	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
677#endif
678
679      if (yyssp >= yyss + yystacksize - 1)
680	YYABORT;
681    }
682
683#if YYDEBUG != 0
684  if (yydebug)
685    fprintf(stderr, "Entering state %d\n", yystate);
686#endif
687
688  goto yybackup;
689 yybackup:
690
691/* Do appropriate processing given the current state.  */
692/* Read a lookahead token if we need one and don't already have one.  */
693/* yyresume: */
694
695  /* First try to decide what to do without reference to lookahead token.  */
696
697  yyn = yypact[yystate];
698  if (yyn == YYFLAG)
699    goto yydefault;
700
701  /* Not known => get a lookahead token if don't already have one.  */
702
703  /* yychar is either YYEMPTY or YYEOF
704     or a valid token in external form.  */
705
706  if (yychar == YYEMPTY)
707    {
708#if YYDEBUG != 0
709      if (yydebug)
710	fprintf(stderr, "Reading a token: ");
711#endif
712      yychar = YYLEX;
713    }
714
715  /* Convert token to internal form (in yychar1) for indexing tables with */
716
717  if (yychar <= 0)		/* This means end of input. */
718    {
719      yychar1 = 0;
720      yychar = YYEOF;		/* Don't call YYLEX any more */
721
722#if YYDEBUG != 0
723      if (yydebug)
724	fprintf(stderr, "Now at end of input.\n");
725#endif
726    }
727  else
728    {
729      yychar1 = YYTRANSLATE(yychar);
730
731#if YYDEBUG != 0
732      if (yydebug)
733	{
734	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
735	  /* Give the individual parser a way to print the precise meaning
736	     of a token, for further debugging info.  */
737#ifdef YYPRINT
738	  YYPRINT (stderr, yychar, yylval);
739#endif
740	  fprintf (stderr, ")\n");
741	}
742#endif
743    }
744
745  yyn += yychar1;
746  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
747    goto yydefault;
748
749  yyn = yytable[yyn];
750
751  /* yyn is what to do for this token type in this state.
752     Negative => reduce, -yyn is rule number.
753     Positive => shift, yyn is new state.
754       New state is final state => don't bother to shift,
755       just return success.
756     0, or most negative number => error.  */
757
758  if (yyn < 0)
759    {
760      if (yyn == YYFLAG)
761	goto yyerrlab;
762      yyn = -yyn;
763      goto yyreduce;
764    }
765  else if (yyn == 0)
766    goto yyerrlab;
767
768  if (yyn == YYFINAL)
769    YYACCEPT;
770
771  /* Shift the lookahead token.  */
772
773#if YYDEBUG != 0
774  if (yydebug)
775    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
776#endif
777
778  /* Discard the token being shifted unless it is eof.  */
779  if (yychar != YYEOF)
780    yychar = YYEMPTY;
781
782  *++yyvsp = yylval;
783#ifdef YYLSP_NEEDED
784  *++yylsp = yylloc;
785#endif
786
787  /* count tokens shifted since error; after three, turn off error status.  */
788  if (yyerrstatus) yyerrstatus--;
789
790  yystate = yyn;
791  goto yynewstate;
792
793/* Do the default action for the current state.  */
794yydefault:
795
796  yyn = yydefact[yystate];
797  if (yyn == 0)
798    goto yyerrlab;
799
800/* Do a reduction.  yyn is the number of a rule to reduce with.  */
801yyreduce:
802  yylen = yyr2[yyn];
803  if (yylen > 0)
804    yyval = yyvsp[1-yylen]; /* implement default value of the action */
805
806#if YYDEBUG != 0
807  if (yydebug)
808    {
809      int i;
810
811      fprintf (stderr, "Reducing via rule %d (line %d), ",
812	       yyn, yyrline[yyn]);
813
814      /* Print the symbols being reduced, and their result.  */
815      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
816	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
817      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
818    }
819#endif
820
821
822  switch (yyn) {
823
824case 1:
825#line 116 "OSUnserialize.y"
826{ parsedObject = (OSObject *)NULL; YYACCEPT; ;
827    break;}
828case 2:
829#line 117 "OSUnserialize.y"
830{ parsedObject = (OSObject *)yyvsp[0];   YYACCEPT; ;
831    break;}
832case 3:
833#line 118 "OSUnserialize.y"
834{ yyerror("syntax error");	   YYERROR; ;
835    break;}
836case 4:
837#line 121 "OSUnserialize.y"
838{ yyval = (object_t *)buildOSDictionary(yyvsp[0]); ;
839    break;}
840case 5:
841#line 122 "OSUnserialize.y"
842{ yyval = (object_t *)buildOSArray(yyvsp[0]); ;
843    break;}
844case 6:
845#line 123 "OSUnserialize.y"
846{ yyval = (object_t *)buildOSSet(yyvsp[0]); ;
847    break;}
848case 7:
849#line 124 "OSUnserialize.y"
850{ yyval = (object_t *)buildOSString(yyvsp[0]); ;
851    break;}
852case 8:
853#line 125 "OSUnserialize.y"
854{ yyval = (object_t *)buildOSData(yyvsp[0]); ;
855    break;}
856case 9:
857#line 126 "OSUnserialize.y"
858{ yyval = (object_t *)buildOSOffset(yyvsp[0]); ;
859    break;}
860case 10:
861#line 127 "OSUnserialize.y"
862{ yyval = (object_t *)buildOSBoolean(yyvsp[0]); ;
863    break;}
864case 11:
865#line 128 "OSUnserialize.y"
866{ yyval = (object_t *)retrieveObject(yyvsp[0]->u.offset);
867				  if (yyval) {
868				    ((OSObject *)yyval)->retain();
869				  } else {
870				    yyerror("forward reference detected");
871				    YYERROR;
872				  }
873				  freeObject(yyvsp[0]);
874				;
875    break;}
876case 12:
877#line 137 "OSUnserialize.y"
878{ yyval = yyvsp[-2];
879				  rememberObject(yyvsp[0]->u.offset, yyvsp[-2]);
880				  freeObject(yyvsp[0]);
881				;
882    break;}
883case 13:
884#line 145 "OSUnserialize.y"
885{ yyval = NULL; ;
886    break;}
887case 14:
888#line 146 "OSUnserialize.y"
889{ yyval = yyvsp[-1]; ;
890    break;}
891case 16:
892#line 150 "OSUnserialize.y"
893{ yyvsp[0]->next = yyvsp[-1]; yyvsp[-1]->prev = yyvsp[0]; yyval = yyvsp[0]; ;
894    break;}
895case 17:
896#line 153 "OSUnserialize.y"
897{ yyval = newObject();
898				  yyval->next = NULL;
899				  yyval->prev = NULL;
900				  yyval->u.key = yyvsp[-3];
901				  yyval->object = yyvsp[-1];
902				;
903    break;}
904case 18:
905#line 163 "OSUnserialize.y"
906{ yyval = NULL; ;
907    break;}
908case 19:
909#line 164 "OSUnserialize.y"
910{ yyval = yyvsp[-1]; ;
911    break;}
912case 20:
913#line 167 "OSUnserialize.y"
914{ yyval = NULL; ;
915    break;}
916case 21:
917#line 168 "OSUnserialize.y"
918{ yyval = yyvsp[-1]; ;
919    break;}
920case 22:
921#line 171 "OSUnserialize.y"
922{ yyval = newObject();
923				  yyval->object = yyvsp[0];
924				  yyval->next = NULL;
925				  yyval->prev = NULL;
926				;
927    break;}
928case 23:
929#line 176 "OSUnserialize.y"
930{ o = newObject();
931				  o->object = yyvsp[0];
932				  o->next = yyvsp[-2];
933				  o->prev = NULL;
934				  yyvsp[-2]->prev = o;
935				  yyval = o;
936				;
937    break;}
938case 24:
939#line 187 "OSUnserialize.y"
940{ yyval = yyvsp[-2];
941				  yyval->size = yyvsp[0]->u.offset;
942				  freeObject(yyvsp[0]);
943				;
944    break;}
945}
946   /* the action file gets copied in in place of this dollarsign */
947#line 543 "/usr/share/bison.simple"
948
949  yyvsp -= yylen;
950  yyssp -= yylen;
951#ifdef YYLSP_NEEDED
952  yylsp -= yylen;
953#endif
954
955#if YYDEBUG != 0
956  if (yydebug)
957    {
958      short *ssp1 = yyss - 1;
959      fprintf (stderr, "state stack now");
960      while (ssp1 != yyssp)
961	fprintf (stderr, " %d", *++ssp1);
962      fprintf (stderr, "\n");
963    }
964#endif
965
966  *++yyvsp = yyval;
967
968#ifdef YYLSP_NEEDED
969  yylsp++;
970  if (yylen == 0)
971    {
972      yylsp->first_line = yylloc.first_line;
973      yylsp->first_column = yylloc.first_column;
974      yylsp->last_line = (yylsp-1)->last_line;
975      yylsp->last_column = (yylsp-1)->last_column;
976      yylsp->text = 0;
977    }
978  else
979    {
980      yylsp->last_line = (yylsp+yylen-1)->last_line;
981      yylsp->last_column = (yylsp+yylen-1)->last_column;
982    }
983#endif
984
985  /* Now "shift" the result of the reduction.
986     Determine what state that goes to,
987     based on the state we popped back to
988     and the rule number reduced by.  */
989
990  yyn = yyr1[yyn];
991
992  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
993  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
994    yystate = yytable[yystate];
995  else
996    yystate = yydefgoto[yyn - YYNTBASE];
997
998  goto yynewstate;
999
1000yyerrlab:   /* here on detecting error */
1001
1002  if (! yyerrstatus)
1003    /* If not already recovering from an error, report this error.  */
1004    {
1005      ++yynerrs;
1006
1007#ifdef YYERROR_VERBOSE
1008      yyn = yypact[yystate];
1009
1010      if (yyn > YYFLAG && yyn < YYLAST)
1011	{
1012	  int size = 0;
1013	  char *msg;
1014	  int x, count, len;
1015
1016	  count = 0;
1017	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
1018	  for (x = (yyn < 0 ? -yyn : 0);
1019	       x < (sizeof(yytname) / sizeof(char *)); x++)
1020	    if (yycheck[x + yyn] == x)
1021	      size += strlen(yytname[x]) + 15, count++;
1022	  len = size + 15;
1023	  msg = (char *) malloc(len);
1024	  if (msg != 0)
1025	    {
1026	      strlcpy(msg, "parse error", len);
1027
1028	      if (count < 5)
1029		{
1030		  count = 0;
1031		  for (x = (yyn < 0 ? -yyn : 0);
1032		       x < (sizeof(yytname) / sizeof(char *)); x++)
1033		    if (yycheck[x + yyn] == x)
1034		      {
1035			strlcat(msg, count == 0 ? ", expecting `" : " or `",
1036					len);
1037			strlcat(msg, yytname[x], len);
1038			strlcat(msg, "'", len);
1039			count++;
1040		      }
1041		}
1042	      yyerror(msg);
1043	      free(msg);
1044	    }
1045	  else
1046	    yyerror ("parse error; also virtual memory exceeded");
1047	}
1048      else
1049#endif /* YYERROR_VERBOSE */
1050	yyerror("parse error");
1051    }
1052
1053  goto yyerrlab1;
1054yyerrlab1:   /* here on error raised explicitly by an action */
1055
1056  if (yyerrstatus == 3)
1057    {
1058      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
1059
1060      /* return failure if at end of input */
1061      if (yychar == YYEOF)
1062	YYABORT;
1063
1064#if YYDEBUG != 0
1065      if (yydebug)
1066	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1067#endif
1068
1069      yychar = YYEMPTY;
1070    }
1071
1072  /* Else will try to reuse lookahead token
1073     after shifting the error token.  */
1074
1075  yyerrstatus = 3;		/* Each real token shifted decrements this */
1076
1077  goto yyerrhandle;
1078
1079yyerrdefault:  /* current state does not do anything special for the error token. */
1080
1081#if 0
1082  /* This is wrong; only states that explicitly want error tokens
1083     should shift them.  */
1084  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
1085  if (yyn) goto yydefault;
1086#endif
1087
1088yyerrpop:   /* pop the current state because it cannot handle the error token */
1089
1090  if (yyssp == yyss) YYABORT;
1091  yyvsp--;
1092  yystate = *--yyssp;
1093#ifdef YYLSP_NEEDED
1094  yylsp--;
1095#endif
1096
1097#if YYDEBUG != 0
1098  if (yydebug)
1099    {
1100      short *ssp1 = yyss - 1;
1101      fprintf (stderr, "Error: state stack now");
1102      while (ssp1 != yyssp)
1103	fprintf (stderr, " %d", *++ssp1);
1104      fprintf (stderr, "\n");
1105    }
1106#endif
1107
1108yyerrhandle:
1109
1110  yyn = yypact[yystate];
1111  if (yyn == YYFLAG)
1112    goto yyerrdefault;
1113
1114  yyn += YYTERROR;
1115  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1116    goto yyerrdefault;
1117
1118  yyn = yytable[yyn];
1119  if (yyn < 0)
1120    {
1121      if (yyn == YYFLAG)
1122	goto yyerrpop;
1123      yyn = -yyn;
1124      goto yyreduce;
1125    }
1126  else if (yyn == 0)
1127    goto yyerrpop;
1128
1129  if (yyn == YYFINAL)
1130    YYACCEPT;
1131
1132#if YYDEBUG != 0
1133  if (yydebug)
1134    fprintf(stderr, "Shifting error token, ");
1135#endif
1136
1137  *++yyvsp = yylval;
1138#ifdef YYLSP_NEEDED
1139  *++yylsp = yylloc;
1140#endif
1141
1142  yystate = yyn;
1143  goto yynewstate;
1144
1145 yyacceptlab:
1146  /* YYACCEPT comes here.  */
1147  if (yyfree_stacks)
1148    {
1149      free (yyss);
1150      free (yyvs);
1151#ifdef YYLSP_NEEDED
1152      free (yyls);
1153#endif
1154    }
1155  return 0;
1156
1157 yyabortlab:
1158  /* YYABORT comes here.  */
1159  if (yyfree_stacks)
1160    {
1161      free (yyss);
1162      free (yyvs);
1163#ifdef YYLSP_NEEDED
1164      free (yyls);
1165#endif
1166    }
1167  return 1;
1168}
1169#line 208 "OSUnserialize.y"
1170
1171
1172static int		lineNumber = 0;
1173static const char	*parseBuffer;
1174static int		parseBufferIndex;
1175
1176#define currentChar()	(parseBuffer[parseBufferIndex])
1177#define nextChar()	(parseBuffer[++parseBufferIndex])
1178#define prevChar()	(parseBuffer[parseBufferIndex - 1])
1179
1180#define isSpace(c)	((c) == ' ' || (c) == '\t')
1181#define isAlpha(c)	(((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1182#define isDigit(c)	((c) >= '0' && (c) <= '9')
1183#define isAlphaDigit(c)	((c) >= 'a' && (c) <= 'f')
1184#define isHexDigit(c)	(isDigit(c) || isAlphaDigit(c))
1185#define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
1186
1187static char yyerror_message[128];
1188
1189int
1190yyerror(char *s)  /* Called by yyparse on error */
1191{
1192	sprintf(yyerror_message, "OSUnserialize: %s near line %d\n", s, lineNumber);
1193	return 0;
1194}
1195
1196int
1197yylex()
1198{
1199	int c;
1200
1201	if (parseBufferIndex == 0) lineNumber = 1;
1202
1203 top:
1204	c = currentChar();
1205
1206	/* skip white space  */
1207	if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
1208
1209	/* skip over comments */
1210	if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {};
1211
1212	/* keep track of line number, don't return \n's */
1213	if (c == '\n') {
1214		lineNumber++;
1215		(void)nextChar();
1216		goto top;
1217	}
1218
1219	/* parse boolean */
1220	if (c == '.') {
1221		bool boolean = false;
1222		if (nextChar() == 't') {
1223			if (nextChar() != 'r') return SYNTAX_ERROR;
1224			if (nextChar() != 'u') return SYNTAX_ERROR;
1225			if (nextChar() != 'e') return SYNTAX_ERROR;
1226			boolean = true;
1227		} else {
1228			if (currentChar() != 'f') return SYNTAX_ERROR;
1229			if (nextChar() != 'a') return SYNTAX_ERROR;
1230			if (nextChar() != 'l') return SYNTAX_ERROR;
1231			if (nextChar() != 's') return SYNTAX_ERROR;
1232			if (nextChar() != 'e') return SYNTAX_ERROR;
1233		}
1234		if (nextChar() != '.') return SYNTAX_ERROR;
1235		/* skip over dot */
1236		(void)nextChar();
1237
1238		yylval = (object_t *)boolean;
1239		return BOOLEAN;
1240	}
1241
1242	/* parse unquoted string */
1243	if (isAlpha(c)) {
1244		int start, length;
1245		char * tempString;
1246
1247		start = parseBufferIndex;
1248		/* find end of string */
1249		while (isAlphaNumeric(c)) {
1250			c = nextChar();
1251		}
1252		length = parseBufferIndex - start;
1253
1254		/* copy to null terminated buffer */
1255		tempString = (char *)malloc(length + 1);
1256		if (tempString == 0) {
1257			printf("OSUnserialize: can't alloc temp memory\n");
1258			return 0;
1259		}
1260		bcopy(&parseBuffer[start], tempString, length);
1261		tempString[length] = 0;
1262		yylval = (object_t *)tempString;
1263		return STRING;
1264	}
1265
1266	/* parse quoted string */
1267	if (c == '"' || c == '\'') {
1268		int start, length;
1269		char * tempString;
1270		char quoteChar = c;
1271
1272		start = parseBufferIndex + 1;		// skip quote
1273		/* find end of string, line, buffer */
1274		while ((c = nextChar()) != quoteChar) {
1275			if (c == '\\') c = nextChar();
1276			if (c == '\n') lineNumber++;
1277			if (c == 0) return SYNTAX_ERROR;
1278		}
1279		length = parseBufferIndex - start;
1280		/* skip over trailing quote */
1281		(void)nextChar();
1282		/* copy to null terminated buffer */
1283		tempString = (char *)malloc(length + 1);
1284		if (tempString == 0) {
1285			printf("OSUnserialize: can't alloc temp memory\n");
1286			return 0;
1287		}
1288
1289		int to = 0;
1290		for (int from=start; from < parseBufferIndex; from++) {
1291			// hack - skip over backslashes
1292			if (parseBuffer[from] == '\\') {
1293				length--;
1294				continue;
1295			}
1296			tempString[to] = parseBuffer[from];
1297			to++;
1298		}
1299		tempString[length] = 0;
1300		yylval = (object_t *)tempString;
1301		return STRING;
1302	}
1303
1304	/* process numbers */
1305	if (isDigit (c))
1306	{
1307		unsigned long long n = 0;
1308		int base = 10;
1309
1310		if (c == '0') {
1311			c = nextChar();
1312			if (c == 'x') {
1313				base = 16;
1314				c = nextChar();
1315			}
1316		}
1317		if (base == 10) {
1318			while(isDigit(c)) {
1319				n = (n * base + c - '0');
1320				c = nextChar();
1321			}
1322		} else {
1323			while(isHexDigit(c)) {
1324				if (isDigit(c)) {
1325					n = (n * base + c - '0');
1326				} else {
1327					n = (n * base + 0xa + c - 'a');
1328				}
1329				c = nextChar();
1330			}
1331		}
1332
1333		yylval = newObject();
1334		yylval->u.offset = n;
1335
1336		return NUMBER;
1337	}
1338
1339#define OSDATA_ALLOC_SIZE 4096
1340
1341	/* process data */
1342	if (c == '<') {
1343		unsigned char *d, *start, *lastStart;
1344
1345		start = lastStart = d = (unsigned char *)malloc(OSDATA_ALLOC_SIZE);
1346		c = nextChar();	// skip over '<'
1347		while (c != 0 && c != '>') {
1348
1349			if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
1350			if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {};
1351			if (c == '\n') {
1352				lineNumber++;
1353				c = nextChar();
1354				continue;
1355			}
1356
1357			// get high nibble
1358			if (!isHexDigit(c)) break;
1359			if (isDigit(c)) {
1360				*d = (c - '0') << 4;
1361			} else {
1362				*d =  (0xa + (c - 'a')) << 4;
1363			}
1364
1365			// get low nibble
1366			c = nextChar();
1367			if (!isHexDigit(c)) break;
1368			if (isDigit(c)) {
1369				*d |= c - '0';
1370			} else {
1371				*d |= 0xa + (c - 'a');
1372			}
1373
1374			d++;
1375			if ((d - lastStart) >= OSDATA_ALLOC_SIZE) {
1376				int oldsize = d - start;
1377				start = (unsigned char *)realloc(start, oldsize + OSDATA_ALLOC_SIZE);
1378				d = lastStart = start + oldsize;
1379			}
1380			c = nextChar();
1381		}
1382		if (c != '>' ) {
1383			free(start);
1384			return SYNTAX_ERROR;
1385		}
1386
1387		// got it!
1388		yylval = newObject();
1389		yylval->object = start;
1390		yylval->size = d - start;
1391
1392		(void)nextChar();	// skip over '>'
1393		return DATA;
1394	}
1395
1396
1397	/* return single chars, move pointer to next char */
1398	(void)nextChar();
1399	return c;
1400}
1401
1402// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1403// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1404// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1405
1406#ifdef DEBUG
1407int debugUnserializeAllocCount = 0;
1408#endif
1409
1410object_t *
1411newObject()
1412{
1413#ifdef DEBUG
1414	debugUnserializeAllocCount++;
1415#endif
1416	return (object_t *)malloc(sizeof(object_t));
1417}
1418
1419void
1420freeObject(object_t *o)
1421{
1422#ifdef DEBUG
1423	debugUnserializeAllocCount--;
1424#endif
1425	free(o);
1426}
1427
1428static OSDictionary *tags;
1429
1430static void
1431rememberObject(int tag, object_t *o)
1432{
1433	char key[16];
1434	sprintf(key, "%u", tag);
1435
1436	tags->setObject(key, (OSObject *)o);
1437}
1438
1439static OSObject *
1440retrieveObject(int tag)
1441{
1442	char key[16];
1443	sprintf(key, "%u", tag);
1444
1445	return tags->getObject(key);
1446}
1447
1448OSObject *
1449buildOSDictionary(object_t *o)
1450{
1451	object_t *temp, *last = o;
1452	int count = 0;
1453
1454	// get count and last object
1455	while (o) {
1456		count++;
1457		last = o;
1458		o = o->next;
1459	}
1460	o = last;
1461
1462	OSDictionary *d = OSDictionary::withCapacity(count);
1463
1464	while (o) {
1465#ifdef metaclass_stuff_worksXXX
1466		if (((OSObject *)o->u.key)->metaCast("OSSymbol")) {
1467			// XXX the evil frontdoor
1468			d->setObject((OSSymbol *)o->u.key, (OSObject *)o->object);
1469		} else {
1470                        // If it isn't a symbol, I hope it's a string!
1471			d->setObject((OSString *)o->u.key, (OSObject *)o->object);
1472		}
1473#else
1474		d->setObject((OSString *)o->u.key, (OSObject *)o->object);
1475#endif
1476		((OSObject *)o->object)->release();
1477		((OSObject *)o->u.key)->release();
1478		temp = o;
1479		o = o->prev;
1480		freeObject(temp);
1481	}
1482	return d;
1483};
1484
1485OSObject *
1486buildOSArray(object_t *o)
1487{
1488	object_t *temp, *last = o;
1489	int count = 0;
1490
1491	// get count and last object
1492	while (o) {
1493		count++;
1494		last = o;
1495		o = o->next;
1496	}
1497	o = last;
1498
1499	OSArray *a = OSArray::withCapacity(count);
1500
1501	while (o) {
1502		a->setObject((OSObject *)o->object);
1503		((OSObject *)o->object)->release();
1504		temp = o;
1505		o = o->prev;
1506		freeObject(temp);
1507	}
1508	return a;
1509};
1510
1511OSObject *
1512buildOSSet(object_t *o)
1513{
1514	OSArray *a = (OSArray *)buildOSArray(o);
1515	OSSet *s = OSSet::withArray(a, a->getCapacity());
1516
1517	a->release();
1518	return s;
1519};
1520
1521OSObject *
1522buildOSString(object_t *o)
1523{
1524	OSString *s = OSString::withCString((char *)o);
1525
1526	free(o);
1527
1528	return s;
1529};
1530
1531OSObject *
1532buildOSData(object_t *o)
1533{
1534	OSData *d;
1535
1536	if (o->size) {
1537		d = OSData::withBytes(o->object, o->size);
1538	} else {
1539		d = OSData::withCapacity(0);
1540	}
1541	free(o->object);
1542	freeObject(o);
1543	return d;
1544};
1545
1546OSObject *
1547buildOSOffset(object_t *o)
1548{
1549	OSNumber *off = OSNumber::withNumber(o->u.offset, o->size);
1550	freeObject(o);
1551	return off;
1552};
1553
1554OSObject *
1555buildOSBoolean(object_t *o)
1556{
1557	OSBoolean *b = OSBoolean::withBoolean((bool)o);
1558	return b;
1559};
1560
1561__BEGIN_DECLS
1562#include <kern/lock.h>
1563__END_DECLS
1564
1565static mutex_t *lock = 0;
1566
1567OSObject*
1568OSUnserialize(const char *buffer, OSString **errorString)
1569{
1570	OSObject *object;
1571
1572	if (!lock) {
1573		lock = mutex_alloc(0);
1574		mutex_lock(lock);
1575	} else {
1576		mutex_lock(lock);
1577
1578	}
1579
1580#ifdef DEBUG
1581	debugUnserializeAllocCount = 0;
1582#endif
1583	yyerror_message[0] = 0;	//just in case
1584	parseBuffer = buffer;
1585	parseBufferIndex = 0;
1586	tags = OSDictionary::withCapacity(128);
1587	if (yyparse() == 0) {
1588		object = parsedObject;
1589		if (errorString) *errorString = 0;
1590	} else {
1591		object = 0;
1592		if (errorString)
1593			*errorString = OSString::withCString(yyerror_message);
1594	}
1595
1596	tags->release();
1597#ifdef DEBUG
1598	if (debugUnserializeAllocCount) {
1599		printf("OSUnserialize: allocation check failed, count = %d.\n",
1600		       debugUnserializeAllocCount);
1601	}
1602#endif
1603	mutex_unlock(lock);
1604
1605	return object;
1606}
1607
1608
1609//
1610//
1611//
1612//
1613//
1614//		 DO NOT EDIT OSUnserialize.cpp!
1615//
1616//			this means you!
1617//
1618//
1619//
1620//
1621//
1622