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