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