xref: /xnu-11215/libkern/c++/OSUnserialize.cpp (revision e13b1fa5)
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 
82 typedef	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 
94 static int yyparse();
95 static int yyerror(char *s);
96 static int yylex();
97 
98 static object_t * newObject();
99 static void freeObject(object_t *o);
100 
101 static OSObject *buildOSDictionary(object_t *);
102 static OSObject *buildOSArray(object_t *);
103 static OSObject *buildOSSet(object_t *);
104 static OSObject *buildOSString(object_t *);
105 static OSObject *buildOSData(object_t *);
106 static OSObject *buildOSOffset(object_t *);
107 static OSObject *buildOSBoolean(object_t *o);
108 
109 static void rememberObject(int, object_t *);
110 static OSObject *retrieveObject(int);
111 
112 // temp variable to use during parsing
113 static object_t *o;
114 
115 // resultant object of parsed text
116 static OSObject	*parsedObject;
117 
118 #define YYSTYPE object_t *
119 
120 extern "C" {
121 extern void *kern_os_malloc(size_t size);
122 extern void *kern_os_realloc(void * addr, size_t size);
123 extern 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 
148 static 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
179 static 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 
185 static 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
199 static 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 
209 static 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 
216 static 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 
222 static 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 
228 static 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 
236 static const short yydefgoto[] = {    41,
237     21,    11,    22,    23,    12,    13,    26,    14,    15,    16,
238     17
239 };
240 
241 static 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 
249 static 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 
258 static 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 
270 static 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 /* [email protected] 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) \
379 do								\
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; }	\
388 while (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 
417 int	yychar;			/*  the lookahead symbol		*/
418 YYSTYPE	yylval;			/*  the semantic value of the		*/
419 				/*  lookahead symbol			*/
420 
421 #ifdef YYLSP_NEEDED
422 YYLTYPE yylloc;			/*  location data for the lookahead	*/
423 				/*  symbol				*/
424 #endif
425 
426 int yynerrs;			/*  number of parse errors so far       */
427 #endif  /* not YYPURE */
428 
429 #if YYDEBUG != 0
430 int 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.  */
464 static 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.  */
482 static 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
520 int yyparse (void *);
521 #else
522 int yyparse (void);
523 #endif
524 #endif
525 
526 int
527 yyparse(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.  */
595 yynewstate:
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.  */
794 yydefault:
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.  */
801 yyreduce:
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 
824 case 1:
825 #line 116 "OSUnserialize.y"
826 { parsedObject = (OSObject *)NULL; YYACCEPT; ;
827     break;}
828 case 2:
829 #line 117 "OSUnserialize.y"
830 { parsedObject = (OSObject *)yyvsp[0];   YYACCEPT; ;
831     break;}
832 case 3:
833 #line 118 "OSUnserialize.y"
834 { yyerror("syntax error");	   YYERROR; ;
835     break;}
836 case 4:
837 #line 121 "OSUnserialize.y"
838 { yyval = (object_t *)buildOSDictionary(yyvsp[0]); ;
839     break;}
840 case 5:
841 #line 122 "OSUnserialize.y"
842 { yyval = (object_t *)buildOSArray(yyvsp[0]); ;
843     break;}
844 case 6:
845 #line 123 "OSUnserialize.y"
846 { yyval = (object_t *)buildOSSet(yyvsp[0]); ;
847     break;}
848 case 7:
849 #line 124 "OSUnserialize.y"
850 { yyval = (object_t *)buildOSString(yyvsp[0]); ;
851     break;}
852 case 8:
853 #line 125 "OSUnserialize.y"
854 { yyval = (object_t *)buildOSData(yyvsp[0]); ;
855     break;}
856 case 9:
857 #line 126 "OSUnserialize.y"
858 { yyval = (object_t *)buildOSOffset(yyvsp[0]); ;
859     break;}
860 case 10:
861 #line 127 "OSUnserialize.y"
862 { yyval = (object_t *)buildOSBoolean(yyvsp[0]); ;
863     break;}
864 case 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;}
876 case 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;}
883 case 13:
884 #line 145 "OSUnserialize.y"
885 { yyval = NULL; ;
886     break;}
887 case 14:
888 #line 146 "OSUnserialize.y"
889 { yyval = yyvsp[-1]; ;
890     break;}
891 case 16:
892 #line 150 "OSUnserialize.y"
893 { yyvsp[0]->next = yyvsp[-1]; yyvsp[-1]->prev = yyvsp[0]; yyval = yyvsp[0]; ;
894     break;}
895 case 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;}
904 case 18:
905 #line 163 "OSUnserialize.y"
906 { yyval = NULL; ;
907     break;}
908 case 19:
909 #line 164 "OSUnserialize.y"
910 { yyval = yyvsp[-1]; ;
911     break;}
912 case 20:
913 #line 167 "OSUnserialize.y"
914 { yyval = NULL; ;
915     break;}
916 case 21:
917 #line 168 "OSUnserialize.y"
918 { yyval = yyvsp[-1]; ;
919     break;}
920 case 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;}
928 case 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;}
938 case 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 
1000 yyerrlab:   /* 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;
1054 yyerrlab1:   /* 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 
1079 yyerrdefault:  /* 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 
1088 yyerrpop:   /* 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 
1108 yyerrhandle:
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 
1172 static int		lineNumber = 0;
1173 static const char	*parseBuffer;
1174 static 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 
1187 static char yyerror_message[128];
1188 
1189 int
1190 yyerror(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 
1196 int
1197 yylex()
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
1407 int debugUnserializeAllocCount = 0;
1408 #endif
1409 
1410 object_t *
1411 newObject()
1412 {
1413 #ifdef DEBUG
1414 	debugUnserializeAllocCount++;
1415 #endif
1416 	return (object_t *)malloc(sizeof(object_t));
1417 }
1418 
1419 void
1420 freeObject(object_t *o)
1421 {
1422 #ifdef DEBUG
1423 	debugUnserializeAllocCount--;
1424 #endif
1425 	free(o);
1426 }
1427 
1428 static OSDictionary *tags;
1429 
1430 static void
1431 rememberObject(int tag, object_t *o)
1432 {
1433 	char key[16];
1434 	sprintf(key, "%u", tag);
1435 
1436 	tags->setObject(key, (OSObject *)o);
1437 }
1438 
1439 static OSObject *
1440 retrieveObject(int tag)
1441 {
1442 	char key[16];
1443 	sprintf(key, "%u", tag);
1444 
1445 	return tags->getObject(key);
1446 }
1447 
1448 OSObject *
1449 buildOSDictionary(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 
1485 OSObject *
1486 buildOSArray(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 
1511 OSObject *
1512 buildOSSet(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 
1521 OSObject *
1522 buildOSString(object_t *o)
1523 {
1524 	OSString *s = OSString::withCString((char *)o);
1525 
1526 	free(o);
1527 
1528 	return s;
1529 };
1530 
1531 OSObject *
1532 buildOSData(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 
1546 OSObject *
1547 buildOSOffset(object_t *o)
1548 {
1549 	OSNumber *off = OSNumber::withNumber(o->u.offset, o->size);
1550 	freeObject(o);
1551 	return off;
1552 };
1553 
1554 OSObject *
1555 buildOSBoolean(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 
1565 static mutex_t *lock = 0;
1566 
1567 OSObject*
1568 OSUnserialize(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