2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* OSUnserialize.y created by rsulack on Nov 21 1998 */
31 // "classic" parser for unserializing OSContainer objects
33 // XXX - this code should really be removed!
34 // - the XML format is now prefered
35 // - this code leaks on syntax errors, the XML doesn't
36 // - "classic" looks, reads, ... much better than XML :-(
37 // - well except the XML is more efficent on OSData
41 // bison -p OSUnserialize OSUnserialize.y
42 // head -50 OSUnserialize.y > OSUnserialize.cpp
43 // sed -e "s/stdio.h/stddef.h/" < OSUnserialize.tab.c >> OSUnserialize.cpp
45 // when changing code check in both OSUnserialize.y and OSUnserialize.cpp
50 // DO NOT EDIT OSUnserialize.tab.cpp!
58 /* A Bison parser, made from OSUnserialize.y
59 by GNU Bison version 1.28 */
61 #define YYBISON 1 /* Identify Bison output. */
63 #define yyparse OSUnserializeparse
64 #define yylex OSUnserializelex
65 #define yyerror OSUnserializeerror
66 #define yylval OSUnserializelval
67 #define yychar OSUnserializechar
68 #define yydebug OSUnserializedebug
69 #define yynerrs OSUnserializenerrs
74 #define SYNTAX_ERROR 261
76 #line 54 "OSUnserialize.y"
78 #include <libkern/c++/OSMetaClass.h>
79 #include <libkern/c++/OSContainers.h>
80 #include <libkern/c++/OSLib.h>
82 typedef struct object
{
88 void *key
; // for dictionary
89 long long offset
; // for offset
95 static int yyerror(char *s
);
98 static object_t
* newObject();
99 static void freeObject(object_t
*o
);
101 static OSObject
*buildOSDictionary(object_t
*);
102 static OSObject
*buildOSArray(object_t
*);
103 static OSObject
*buildOSSet(object_t
*);
104 static OSObject
*buildOSString(object_t
*);
105 static OSObject
*buildOSData(object_t
*);
106 static OSObject
*buildOSOffset(object_t
*);
107 static OSObject
*buildOSBoolean(object_t
*o
);
109 static void rememberObject(int, object_t
*);
110 static OSObject
*retrieveObject(int);
112 // temp variable to use during parsing
115 // resultant object of parsed text
116 static OSObject
*parsedObject
;
118 #define YYSTYPE object_t *
121 extern void *kern_os_malloc(size_t size
);
122 extern void *kern_os_realloc(void * addr
, size_t size
);
123 extern void kern_os_free(void * addr
);
126 #define malloc(s) kern_os_malloc(s)
127 #define realloc(a, s) kern_os_realloc(a, s)
128 #define free(a) kern_os_free(a)
143 #define YYFLAG -32768
146 #define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 31)
148 static const char yytranslate
[] = { 0,
149 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
150 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
151 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
152 2, 2, 2, 2, 2, 2, 2, 2, 2, 13,
153 14, 2, 2, 17, 2, 2, 2, 2, 2, 2,
154 2, 2, 2, 2, 2, 2, 2, 18, 12, 2,
155 11, 2, 2, 8, 2, 2, 2, 2, 2, 2,
156 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
157 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
158 15, 2, 16, 2, 2, 2, 2, 2, 2, 2,
159 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
160 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
161 2, 2, 9, 2, 10, 2, 2, 2, 2, 2,
162 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
163 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
164 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
165 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
166 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
167 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
168 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
169 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
170 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
171 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
172 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
173 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
174 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
179 static const short yyprhs
[] = { 0,
180 0, 1, 3, 5, 7, 9, 11, 13, 15, 17,
181 19, 22, 26, 29, 33, 35, 38, 43, 46, 50,
182 53, 57, 59, 63, 67, 69, 71
185 static const short yyrhs
[] = { -1,
186 20, 0, 7, 0, 21, 0, 24, 0, 25, 0,
187 29, 0, 28, 0, 27, 0, 30, 0, 8, 3,
188 0, 20, 8, 3, 0, 9, 10, 0, 9, 22,
189 10, 0, 23, 0, 22, 23, 0, 20, 11, 20,
190 12, 0, 13, 14, 0, 13, 26, 14, 0, 15,
191 16, 0, 15, 26, 16, 0, 20, 0, 26, 17,
192 20, 0, 3, 18, 3, 0, 5, 0, 4, 0,
199 static const short yyrline
[] = { 0,
200 116, 117, 118, 121, 122, 123, 124, 125, 126, 127,
201 128, 137, 145, 146, 149, 150, 153, 163, 164, 167,
202 168, 171, 176, 187, 195, 200, 205
207 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
209 static const char * const yytname
[] = { "$","error","$undefined.","NUMBER",
210 "STRING","DATA","BOOLEAN","SYNTAX_ERROR","'@'","'{'","'}'","'='","';'","'('",
211 "')'","'['","']'","','","':'","input","object","dict","pairs","pair","array",
212 "set","elements","offset","data","string","boolean", NULL
216 static const short yyr1
[] = { 0,
217 19, 19, 19, 20, 20, 20, 20, 20, 20, 20,
218 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
219 25, 26, 26, 27, 28, 29, 30
222 static const short yyr2
[] = { 0,
223 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
224 2, 3, 2, 3, 1, 2, 4, 2, 3, 2,
228 static const short yydefact
[] = { 1,
229 0, 26, 25, 27, 3, 0, 0, 0, 0, 2,
230 4, 5, 6, 9, 8, 7, 10, 0, 11, 13,
231 0, 0, 15, 18, 22, 0, 20, 0, 0, 24,
232 0, 14, 16, 19, 0, 21, 12, 0, 23, 17,
236 static const short yydefgoto
[] = { 41,
237 21, 11, 22, 23, 12, 13, 26, 14, 15, 16,
241 static const short yypact
[] = { 12,
242 -13,-32768,-32768,-32768,-32768, 9, 33, 46, -2, 2,
243 -32768,-32768,-32768,-32768,-32768,-32768,-32768, 25,-32768,-32768,
244 21, 59,-32768,-32768, 2, 16,-32768, 7, 31,-32768,
245 72,-32768,-32768,-32768, 72,-32768,-32768, 14, 2,-32768,
249 static const short yypgoto
[] = {-32768,
250 0,-32768,-32768, 23,-32768,-32768, 38,-32768,-32768,-32768,
258 static const short yytable
[] = { 10,
259 1, 2, 3, 4, 18, 6, 7, 25, 25, 29,
260 8, 19, 9, 27, 1, 2, 3, 4, 5, 6,
261 7, 29, 36, 35, 8, 40, 9, 30, 29, 34,
262 38, 31, 35, 37, 39, 1, 2, 3, 4, 42,
263 6, 7, 20, 43, 33, 8, 28, 9, 1, 2,
264 3, 4, 0, 6, 7, 0, 0, 0, 8, 24,
265 9, 1, 2, 3, 4, 0, 6, 7, 32, 0,
266 0, 8, 0, 9, 1, 2, 3, 4, 0, 6,
270 static const short yycheck
[] = { 0,
271 3, 4, 5, 6, 18, 8, 9, 8, 9, 8,
272 13, 3, 15, 16, 3, 4, 5, 6, 7, 8,
273 9, 8, 16, 17, 13, 12, 15, 3, 8, 14,
274 31, 11, 17, 3, 35, 3, 4, 5, 6, 0,
275 8, 9, 10, 0, 22, 13, 9, 15, 3, 4,
276 5, 6, -1, 8, 9, -1, -1, -1, 13, 14,
277 15, 3, 4, 5, 6, -1, 8, 9, 10, -1,
278 -1, 13, -1, 15, 3, 4, 5, 6, -1, 8,
279 9, -1, -1, -1, 13, -1, 15
281 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
282 #line 3 "/usr/share/bison.simple"
283 /* This file comes from bison-1.28. */
285 /* Skeleton output parser for bison,
286 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
288 This program is free software; you can redistribute it and/or modify
289 it under the terms of the GNU General Public License as published by
290 the Free Software Foundation; either version 2, or (at your option)
293 This program is distributed in the hope that it will be useful,
294 but WITHOUT ANY WARRANTY; without even the implied warranty of
295 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
296 GNU General Public License for more details.
298 You should have received a copy of the GNU General Public License
299 along with this program; if not, write to the Free Software
300 Foundation, Inc., 59 Temple Place - Suite 330,
301 Boston, MA 02111-1307, USA. */
303 /* As a special exception, when this file is copied by Bison into a
304 Bison output file, you may use that output file without restriction.
305 This special exception was added by the Free Software Foundation
306 in version 1.24 of Bison. */
308 /* This is the parser code that is written into each bison parser
309 when the %semantic_parser declaration is not specified in the grammar.
310 It was written by Richard Stallman by simplifying the hairy parser
311 used when %semantic_parser is specified. */
313 #ifndef YYSTACK_USE_ALLOCA
315 #define YYSTACK_USE_ALLOCA
316 #else /* alloca not defined */
318 #define YYSTACK_USE_ALLOCA
319 #define alloca __builtin_alloca
320 #else /* not GNU C. */
321 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) || defined (__arm)
322 #define YYSTACK_USE_ALLOCA
324 #else /* not sparc */
325 /* We think this test detects Watcom and Microsoft C. */
326 /* This used to test MSDOS, but that is a bad idea
327 since that symbol is in the user namespace. */
328 #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
329 #if 0 /* No need for malloc.h, which pollutes the namespace;
330 instead, just don't use alloca. */
333 #else /* not MSDOS, or __TURBOC__ */
335 /* I don't know what this was needed for, but it pollutes the namespace.
336 So I turned it off. rms, 2 May 1997. */
337 /* #include <malloc.h> */
339 #define YYSTACK_USE_ALLOCA
340 #else /* not MSDOS, or __TURBOC__, or _AIX */
342 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
343 and on HPUX 10. Eventually we can turn this on. */
344 #define YYSTACK_USE_ALLOCA
345 #define alloca __builtin_alloca
348 #endif /* not _AIX */
349 #endif /* not MSDOS, or __TURBOC__ */
350 #endif /* not sparc */
351 #endif /* not GNU C */
352 #endif /* alloca not defined */
353 #endif /* YYSTACK_USE_ALLOCA not defined */
355 #ifdef YYSTACK_USE_ALLOCA
356 #define YYSTACK_ALLOC alloca
358 #define YYSTACK_ALLOC malloc
361 /* Note: there must be only one dollar sign in this file.
362 It is replaced by the list of actions, each action
363 as one case of the switch. */
365 #define yyerrok (yyerrstatus = 0)
366 #define yyclearin (yychar = YYEMPTY)
369 #define YYACCEPT goto yyacceptlab
370 #define YYABORT goto yyabortlab
371 #define YYERROR goto yyerrlab1
372 /* Like YYERROR except do call yyerror.
373 This remains here temporarily to ease the
374 transition to the new meaning of YYERROR, for GCC.
375 Once GCC version 2 has supplanted version 1, this can go. */
376 #define YYFAIL goto yyerrlab
377 #define YYRECOVERING() (!!yyerrstatus)
378 #define YYBACKUP(token, value) \
380 if (yychar == YYEMPTY && yylen == 1) \
381 { yychar = (token), yylval = (value); \
382 yychar1 = YYTRANSLATE (yychar); \
387 { yyerror ("syntax error: cannot back up"); YYERROR; } \
391 #define YYERRCODE 256
394 #define YYLEX yylex()
400 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
402 #define YYLEX yylex(&yylval, &yylloc)
404 #else /* not YYLSP_NEEDED */
406 #define YYLEX yylex(&yylval, YYLEX_PARAM)
408 #define YYLEX yylex(&yylval)
410 #endif /* not YYLSP_NEEDED */
413 /* If nonreentrant, generate the variables here */
417 int yychar
; /* the lookahead symbol */
418 YYSTYPE yylval
; /* the semantic value of the */
419 /* lookahead symbol */
422 YYLTYPE yylloc
; /* location data for the lookahead */
426 int yynerrs
; /* number of parse errors so far */
427 #endif /* not YYPURE */
430 int yydebug
; /* nonzero means print parse trace */
431 /* Since this is uninitialized, it does not stop multiple parsers
435 /* YYINITDEPTH indicates the initial size of the parser's stacks */
438 #define YYINITDEPTH 200
441 /* YYMAXDEPTH is the maximum size the stacks can grow to
442 (effective only if the built-in stack extension method is used). */
449 #define YYMAXDEPTH 10000
452 /* Define __yy_memcpy. Note that the size argument
453 should be passed with type unsigned int, because that is what the non-GCC
454 definitions require. With GCC, __builtin_memcpy takes an arg
455 of type size_t, but it can handle unsigned int. */
457 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
458 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
459 #else /* not GNU C or C++ */
462 /* This is the most reliable way to avoid incompatibilities
463 in available built-in functions on various systems. */
465 __yy_memcpy (to
, from
, count
)
470 register char *f
= from
;
471 register char *t
= to
;
472 register int i
= count
;
478 #else /* __cplusplus */
480 /* This is the most reliable way to avoid incompatibilities
481 in available built-in functions on various systems. */
483 __yy_memcpy (char *to
, char *from
, unsigned int count
)
485 register char *t
= to
;
486 register char *f
= from
;
487 register int i
= count
;
496 #line 217 "/usr/share/bison.simple"
498 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
499 into yyparse. The argument should have type void *.
500 It should actually point to an object.
501 Grammar actions can access the variable by casting it
502 to the proper pointer type. */
506 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
507 #define YYPARSE_PARAM_DECL
508 #else /* not __cplusplus */
509 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
510 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
511 #endif /* not __cplusplus */
512 #else /* not YYPARSE_PARAM */
513 #define YYPARSE_PARAM_ARG
514 #define YYPARSE_PARAM_DECL
515 #endif /* not YYPARSE_PARAM */
517 /* Prevent warning if -Wstrict-prototypes. */
520 int yyparse (void *);
527 yyparse(YYPARSE_PARAM_ARG
)
530 register int yystate
;
532 register short *yyssp
;
533 register YYSTYPE
*yyvsp
;
534 int yyerrstatus
; /* number of tokens to shift before error messages enabled */
535 int yychar1
= 0; /* lookahead token as an internal (translated) token number */
537 short yyssa
[YYINITDEPTH
]; /* the state stack */
538 YYSTYPE yyvsa
[YYINITDEPTH
]; /* the semantic value stack */
540 short *yyss
= yyssa
; /* refer to the stacks thru separate pointers */
541 YYSTYPE
*yyvs
= yyvsa
; /* to allow yyoverflow to reallocate them elsewhere */
544 YYLTYPE yylsa
[YYINITDEPTH
]; /* the location stack */
545 YYLTYPE
*yyls
= yylsa
;
548 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
550 #define YYPOPSTACK (yyvsp--, yyssp--)
553 int yystacksize
= YYINITDEPTH
;
554 int yyfree_stacks
= 0;
565 YYSTYPE yyval
; /* the variable used to return */
566 /* semantic values from the action */
573 fprintf(stderr
, "Starting parse\n");
579 yychar
= YYEMPTY
; /* Cause a token to be read. */
581 /* Initialize stack pointers.
582 Waste one element of value and location stack
583 so that they stay on the same level as the state stack.
584 The wasted elements are never initialized. */
592 /* Push a new state, which is found in yystate . */
593 /* In all cases, when you get here, the value and location stacks
594 have just been pushed. so pushing a state here evens the stacks. */
599 if (yyssp
>= yyss
+ yystacksize
- 1)
601 /* Give user a chance to reallocate the stack */
602 /* Use copies of these so that the &'s don't force the real ones into memory. */
603 YYSTYPE
*yyvs1
= yyvs
;
606 YYLTYPE
*yyls1
= yyls
;
609 /* Get the current used size of the three stacks, in elements. */
610 int size
= yyssp
- yyss
+ 1;
613 /* Each stack pointer address is followed by the size of
614 the data in use in that stack, in bytes. */
616 /* This used to be a conditional around just the two extra args,
617 but that might be undefined if yyoverflow is a macro. */
618 yyoverflow("parser stack overflow",
619 &yyss1
, size
* sizeof (*yyssp
),
620 &yyvs1
, size
* sizeof (*yyvsp
),
621 &yyls1
, size
* sizeof (*yylsp
),
624 yyoverflow("parser stack overflow",
625 &yyss1
, size
* sizeof (*yyssp
),
626 &yyvs1
, size
* sizeof (*yyvsp
),
630 yyss
= yyss1
; yyvs
= yyvs1
;
634 #else /* no yyoverflow */
635 /* Extend the stack our own way. */
636 if (yystacksize
>= YYMAXDEPTH
)
638 yyerror("parser stack overflow");
650 if (yystacksize
> YYMAXDEPTH
)
651 yystacksize
= YYMAXDEPTH
;
652 #ifndef YYSTACK_USE_ALLOCA
655 yyss
= (short *) YYSTACK_ALLOC (yystacksize
* sizeof (*yyssp
));
656 __yy_memcpy ((char *)yyss
, (char *)yyss1
,
657 size
* (unsigned int) sizeof (*yyssp
));
658 yyvs
= (YYSTYPE
*) YYSTACK_ALLOC (yystacksize
* sizeof (*yyvsp
));
659 __yy_memcpy ((char *)yyvs
, (char *)yyvs1
,
660 size
* (unsigned int) sizeof (*yyvsp
));
662 yyls
= (YYLTYPE
*) YYSTACK_ALLOC (yystacksize
* sizeof (*yylsp
));
663 __yy_memcpy ((char *)yyls
, (char *)yyls1
,
664 size
* (unsigned int) sizeof (*yylsp
));
666 #endif /* no yyoverflow */
668 yyssp
= yyss
+ size
- 1;
669 yyvsp
= yyvs
+ size
- 1;
671 yylsp
= yyls
+ size
- 1;
676 fprintf(stderr
, "Stack size increased to %d\n", yystacksize
);
679 if (yyssp
>= yyss
+ yystacksize
- 1)
685 fprintf(stderr
, "Entering state %d\n", yystate
);
691 /* Do appropriate processing given the current state. */
692 /* Read a lookahead token if we need one and don't already have one. */
695 /* First try to decide what to do without reference to lookahead token. */
697 yyn
= yypact
[yystate
];
701 /* Not known => get a lookahead token if don't already have one. */
703 /* yychar is either YYEMPTY or YYEOF
704 or a valid token in external form. */
706 if (yychar
== YYEMPTY
)
710 fprintf(stderr
, "Reading a token: ");
715 /* Convert token to internal form (in yychar1) for indexing tables with */
717 if (yychar
<= 0) /* This means end of input. */
720 yychar
= YYEOF
; /* Don't call YYLEX any more */
724 fprintf(stderr
, "Now at end of input.\n");
729 yychar1
= YYTRANSLATE(yychar
);
734 fprintf (stderr
, "Next token is %d (%s", yychar
, yytname
[yychar1
]);
735 /* Give the individual parser a way to print the precise meaning
736 of a token, for further debugging info. */
738 YYPRINT (stderr
, yychar
, yylval
);
740 fprintf (stderr
, ")\n");
746 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != yychar1
)
751 /* yyn is what to do for this token type in this state.
752 Negative => reduce, -yyn is rule number.
753 Positive => shift, yyn is new state.
754 New state is final state => don't bother to shift,
756 0, or most negative number => error. */
771 /* Shift the lookahead token. */
775 fprintf(stderr
, "Shifting token %d (%s), ", yychar
, yytname
[yychar1
]);
778 /* Discard the token being shifted unless it is eof. */
787 /* count tokens shifted since error; after three, turn off error status. */
788 if (yyerrstatus
) yyerrstatus
--;
793 /* Do the default action for the current state. */
796 yyn
= yydefact
[yystate
];
800 /* Do a reduction. yyn is the number of a rule to reduce with. */
804 yyval
= yyvsp
[1-yylen
]; /* implement default value of the action */
811 fprintf (stderr
, "Reducing via rule %d (line %d), ",
814 /* Print the symbols being reduced, and their result. */
815 for (i
= yyprhs
[yyn
]; yyrhs
[i
] > 0; i
++)
816 fprintf (stderr
, "%s ", yytname
[yyrhs
[i
]]);
817 fprintf (stderr
, " -> %s\n", yytname
[yyr1
[yyn
]]);
825 #line 116 "OSUnserialize.y"
826 { parsedObject
= (OSObject
*)NULL
; YYACCEPT
; ;
829 #line 117 "OSUnserialize.y"
830 { parsedObject
= (OSObject
*)yyvsp
[0]; YYACCEPT
; ;
833 #line 118 "OSUnserialize.y"
834 { yyerror("syntax error"); YYERROR
; ;
837 #line 121 "OSUnserialize.y"
838 { yyval
= (object_t
*)buildOSDictionary(yyvsp
[0]); ;
841 #line 122 "OSUnserialize.y"
842 { yyval
= (object_t
*)buildOSArray(yyvsp
[0]); ;
845 #line 123 "OSUnserialize.y"
846 { yyval
= (object_t
*)buildOSSet(yyvsp
[0]); ;
849 #line 124 "OSUnserialize.y"
850 { yyval
= (object_t
*)buildOSString(yyvsp
[0]); ;
853 #line 125 "OSUnserialize.y"
854 { yyval
= (object_t
*)buildOSData(yyvsp
[0]); ;
857 #line 126 "OSUnserialize.y"
858 { yyval
= (object_t
*)buildOSOffset(yyvsp
[0]); ;
861 #line 127 "OSUnserialize.y"
862 { yyval
= (object_t
*)buildOSBoolean(yyvsp
[0]); ;
865 #line 128 "OSUnserialize.y"
866 { yyval
= (object_t
*)retrieveObject(yyvsp
[0]->u
.offset
);
868 ((OSObject
*)yyval
)->retain();
870 yyerror("forward reference detected");
873 freeObject(yyvsp
[0]);
877 #line 137 "OSUnserialize.y"
879 rememberObject(yyvsp
[0]->u
.offset
, yyvsp
[-2]);
880 freeObject(yyvsp
[0]);
884 #line 145 "OSUnserialize.y"
888 #line 146 "OSUnserialize.y"
889 { yyval
= yyvsp
[-1]; ;
892 #line 150 "OSUnserialize.y"
893 { yyvsp
[0]->next
= yyvsp
[-1]; yyvsp
[-1]->prev
= yyvsp
[0]; yyval
= yyvsp
[0]; ;
896 #line 153 "OSUnserialize.y"
897 { yyval
= newObject();
900 yyval
->u
.key
= yyvsp
[-3];
901 yyval
->object
= yyvsp
[-1];
905 #line 163 "OSUnserialize.y"
909 #line 164 "OSUnserialize.y"
910 { yyval
= yyvsp
[-1]; ;
913 #line 167 "OSUnserialize.y"
917 #line 168 "OSUnserialize.y"
918 { yyval
= yyvsp
[-1]; ;
921 #line 171 "OSUnserialize.y"
922 { yyval
= newObject();
923 yyval
->object
= yyvsp
[0];
929 #line 176 "OSUnserialize.y"
931 o
->object
= yyvsp
[0];
939 #line 187 "OSUnserialize.y"
941 yyval
->size
= yyvsp
[0]->u
.offset
;
942 freeObject(yyvsp
[0]);
946 /* the action file gets copied in in place of this dollarsign */
947 #line 543 "/usr/share/bison.simple"
958 short *ssp1
= yyss
- 1;
959 fprintf (stderr
, "state stack now");
960 while (ssp1
!= yyssp
)
961 fprintf (stderr
, " %d", *++ssp1
);
962 fprintf (stderr
, "\n");
972 yylsp
->first_line
= yylloc
.first_line
;
973 yylsp
->first_column
= yylloc
.first_column
;
974 yylsp
->last_line
= (yylsp
-1)->last_line
;
975 yylsp
->last_column
= (yylsp
-1)->last_column
;
980 yylsp
->last_line
= (yylsp
+yylen
-1)->last_line
;
981 yylsp
->last_column
= (yylsp
+yylen
-1)->last_column
;
985 /* Now "shift" the result of the reduction.
986 Determine what state that goes to,
987 based on the state we popped back to
988 and the rule number reduced by. */
992 yystate
= yypgoto
[yyn
- YYNTBASE
] + *yyssp
;
993 if (yystate
>= 0 && yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
994 yystate
= yytable
[yystate
];
996 yystate
= yydefgoto
[yyn
- YYNTBASE
];
1000 yyerrlab
: /* here on detecting error */
1003 /* If not already recovering from an error, report this error. */
1007 #ifdef YYERROR_VERBOSE
1008 yyn
= yypact
[yystate
];
1010 if (yyn
> YYFLAG
&& yyn
< YYLAST
)
1017 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1018 for (x
= (yyn
< 0 ? -yyn
: 0);
1019 x
< (sizeof(yytname
) / sizeof(char *)); x
++)
1020 if (yycheck
[x
+ yyn
] == x
)
1021 size
+= strlen(yytname
[x
]) + 15, count
++;
1023 msg
= (char *) malloc(len
);
1026 strlcpy(msg
, "parse error", len
);
1031 for (x
= (yyn
< 0 ? -yyn
: 0);
1032 x
< (sizeof(yytname
) / sizeof(char *)); x
++)
1033 if (yycheck
[x
+ yyn
] == x
)
1035 strlcat(msg
, count
== 0 ? ", expecting `" : " or `",
1037 strlcat(msg
, yytname
[x
], len
);
1038 strlcat(msg
, "'", len
);
1046 yyerror ("parse error; also virtual memory exceeded");
1049 #endif /* YYERROR_VERBOSE */
1050 yyerror("parse error");
1054 yyerrlab1
: /* here on error raised explicitly by an action */
1056 if (yyerrstatus
== 3)
1058 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1060 /* return failure if at end of input */
1061 if (yychar
== YYEOF
)
1066 fprintf(stderr
, "Discarding token %d (%s).\n", yychar
, yytname
[yychar1
]);
1072 /* Else will try to reuse lookahead token
1073 after shifting the error token. */
1075 yyerrstatus
= 3; /* Each real token shifted decrements this */
1079 yyerrdefault
: /* current state does not do anything special for the error token. */
1082 /* This is wrong; only states that explicitly want error tokens
1083 should shift them. */
1084 yyn
= yydefact
[yystate
]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1085 if (yyn
) goto yydefault
;
1088 yyerrpop
: /* pop the current state because it cannot handle the error token */
1090 if (yyssp
== yyss
) YYABORT
;
1100 short *ssp1
= yyss
- 1;
1101 fprintf (stderr
, "Error: state stack now");
1102 while (ssp1
!= yyssp
)
1103 fprintf (stderr
, " %d", *++ssp1
);
1104 fprintf (stderr
, "\n");
1110 yyn
= yypact
[yystate
];
1115 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != YYTERROR
)
1134 fprintf(stderr
, "Shifting error token, ");
1146 /* YYACCEPT comes here. */
1158 /* YYABORT comes here. */
1169 #line 208 "OSUnserialize.y"
1172 static int lineNumber
= 0;
1173 static const char *parseBuffer
;
1174 static int parseBufferIndex
;
1176 #define currentChar() (parseBuffer[parseBufferIndex])
1177 #define nextChar() (parseBuffer[++parseBufferIndex])
1178 #define prevChar() (parseBuffer[parseBufferIndex - 1])
1180 #define isSpace(c) ((c) == ' ' || (c) == '\t')
1181 #define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1182 #define isDigit(c) ((c) >= '0' && (c) <= '9')
1183 #define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
1184 #define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
1185 #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
1187 static char yyerror_message
[128];
1190 yyerror(char *s
) /* Called by yyparse on error */
1192 sprintf(yyerror_message
, "OSUnserialize: %s near line %d\n", s
, lineNumber
);
1201 if (parseBufferIndex
== 0) lineNumber
= 1;
1206 /* skip white space */
1207 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1209 /* skip over comments */
1210 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1212 /* keep track of line number, don't return \n's */
1221 bool boolean
= false;
1222 if (nextChar() == 't') {
1223 if (nextChar() != 'r') return SYNTAX_ERROR
;
1224 if (nextChar() != 'u') return SYNTAX_ERROR
;
1225 if (nextChar() != 'e') return SYNTAX_ERROR
;
1228 if (currentChar() != 'f') return SYNTAX_ERROR
;
1229 if (nextChar() != 'a') return SYNTAX_ERROR
;
1230 if (nextChar() != 'l') return SYNTAX_ERROR
;
1231 if (nextChar() != 's') return SYNTAX_ERROR
;
1232 if (nextChar() != 'e') return SYNTAX_ERROR
;
1234 if (nextChar() != '.') return SYNTAX_ERROR
;
1238 yylval
= (object_t
*)boolean
;
1242 /* parse unquoted string */
1247 start
= parseBufferIndex
;
1248 /* find end of string */
1249 while (isAlphaNumeric(c
)) {
1252 length
= parseBufferIndex
- start
;
1254 /* copy to null terminated buffer */
1255 tempString
= (char *)malloc(length
+ 1);
1256 if (tempString
== 0) {
1257 printf("OSUnserialize: can't alloc temp memory\n");
1260 bcopy(&parseBuffer
[start
], tempString
, length
);
1261 tempString
[length
] = 0;
1262 yylval
= (object_t
*)tempString
;
1266 /* parse quoted string */
1267 if (c
== '"' || c
== '\'') {
1272 start
= parseBufferIndex
+ 1; // skip quote
1273 /* find end of string, line, buffer */
1274 while ((c
= nextChar()) != quoteChar
) {
1275 if (c
== '\\') c
= nextChar();
1276 if (c
== '\n') lineNumber
++;
1277 if (c
== 0) return SYNTAX_ERROR
;
1279 length
= parseBufferIndex
- start
;
1280 /* skip over trailing quote */
1282 /* copy to null terminated buffer */
1283 tempString
= (char *)malloc(length
+ 1);
1284 if (tempString
== 0) {
1285 printf("OSUnserialize: can't alloc temp memory\n");
1290 for (int from
=start
; from
< parseBufferIndex
; from
++) {
1291 // hack - skip over backslashes
1292 if (parseBuffer
[from
] == '\\') {
1296 tempString
[to
] = parseBuffer
[from
];
1299 tempString
[length
] = 0;
1300 yylval
= (object_t
*)tempString
;
1304 /* process numbers */
1307 unsigned long long n
= 0;
1319 n
= (n
* base
+ c
- '0');
1323 while(isHexDigit(c
)) {
1325 n
= (n
* base
+ c
- '0');
1327 n
= (n
* base
+ 0xa + c
- 'a');
1333 yylval
= newObject();
1334 yylval
->u
.offset
= n
;
1339 #define OSDATA_ALLOC_SIZE 4096
1343 unsigned char *d
, *start
, *lastStart
;
1345 start
= lastStart
= d
= (unsigned char *)malloc(OSDATA_ALLOC_SIZE
);
1346 c
= nextChar(); // skip over '<'
1347 while (c
!= 0 && c
!= '>') {
1349 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1350 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1358 if (!isHexDigit(c
)) break;
1360 *d
= (c
- '0') << 4;
1362 *d
= (0xa + (c
- 'a')) << 4;
1367 if (!isHexDigit(c
)) break;
1371 *d
|= 0xa + (c
- 'a');
1375 if ((d
- lastStart
) >= OSDATA_ALLOC_SIZE
) {
1376 int oldsize
= d
- start
;
1377 start
= (unsigned char *)realloc(start
, oldsize
+ OSDATA_ALLOC_SIZE
);
1378 d
= lastStart
= start
+ oldsize
;
1384 return SYNTAX_ERROR
;
1388 yylval
= newObject();
1389 yylval
->object
= start
;
1390 yylval
->size
= d
- start
;
1392 (void)nextChar(); // skip over '>'
1397 /* return single chars, move pointer to next char */
1402 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1403 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1404 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1407 int debugUnserializeAllocCount
= 0;
1414 debugUnserializeAllocCount
++;
1416 return (object_t
*)malloc(sizeof(object_t
));
1420 freeObject(object_t
*o
)
1423 debugUnserializeAllocCount
--;
1428 static OSDictionary
*tags
;
1431 rememberObject(int tag
, object_t
*o
)
1434 sprintf(key
, "%u", tag
);
1436 tags
->setObject(key
, (OSObject
*)o
);
1440 retrieveObject(int tag
)
1443 sprintf(key
, "%u", tag
);
1445 return tags
->getObject(key
);
1449 buildOSDictionary(object_t
*o
)
1451 object_t
*temp
, *last
= o
;
1454 // get count and last object
1462 OSDictionary
*d
= OSDictionary::withCapacity(count
);
1465 #ifdef metaclass_stuff_worksXXX
1466 if (((OSObject
*)o
->u
.key
)->metaCast("OSSymbol")) {
1467 // XXX the evil frontdoor
1468 d
->setObject((OSSymbol
*)o
->u
.key
, (OSObject
*)o
->object
);
1470 // If it isn't a symbol, I hope it's a string!
1471 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1474 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1476 ((OSObject
*)o
->object
)->release();
1477 ((OSObject
*)o
->u
.key
)->release();
1486 buildOSArray(object_t
*o
)
1488 object_t
*temp
, *last
= o
;
1491 // get count and last object
1499 OSArray
*a
= OSArray::withCapacity(count
);
1502 a
->setObject((OSObject
*)o
->object
);
1503 ((OSObject
*)o
->object
)->release();
1512 buildOSSet(object_t
*o
)
1514 OSArray
*a
= (OSArray
*)buildOSArray(o
);
1515 OSSet
*s
= OSSet::withArray(a
, a
->getCapacity());
1522 buildOSString(object_t
*o
)
1524 OSString
*s
= OSString::withCString((char *)o
);
1532 buildOSData(object_t
*o
)
1537 d
= OSData::withBytes(o
->object
, o
->size
);
1539 d
= OSData::withCapacity(0);
1547 buildOSOffset(object_t
*o
)
1549 OSNumber
*off
= OSNumber::withNumber(o
->u
.offset
, o
->size
);
1555 buildOSBoolean(object_t
*o
)
1557 OSBoolean
*b
= OSBoolean::withBoolean((bool)o
);
1562 #include <kern/lock.h>
1565 static mutex_t
*lock
= 0;
1568 OSUnserialize(const char *buffer
, OSString
**errorString
)
1573 lock
= mutex_alloc(0);
1581 debugUnserializeAllocCount
= 0;
1583 yyerror_message
[0] = 0; //just in case
1584 parseBuffer
= buffer
;
1585 parseBufferIndex
= 0;
1586 tags
= OSDictionary::withCapacity(128);
1587 if (yyparse() == 0) {
1588 object
= parsedObject
;
1589 if (errorString
) *errorString
= 0;
1593 *errorString
= OSString::withCString(yyerror_message
);
1598 if (debugUnserializeAllocCount
) {
1599 printf("OSUnserialize: allocation check failed, count = %d.\n",
1600 debugUnserializeAllocCount
);
1614 // DO NOT EDIT OSUnserialize.cpp!