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