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