2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 /* OSUnserialize.y created by rsulack on Nov 21 1998 */
25 // "classic" parser for unserializing OSContainer objects
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
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
39 // when changing code check in both OSUnserialize.y and OSUnserialize.cpp
44 // DO NOT EDIT OSUnserialize.tab.cpp!
52 /* A Bison parser, made from OSUnserialize.y
53 by GNU Bison version 1.28 */
55 #define YYBISON 1 /* Identify Bison output. */
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
68 #define SYNTAX_ERROR 261
70 #line 54 "OSUnserialize.y"
72 #include <libkern/c++/OSMetaClass.h>
73 #include <libkern/c++/OSContainers.h>
74 #include <libkern/c++/OSLib.h>
76 typedef struct object
{
82 void *key
; // for dictionary
83 long long offset
; // for offset
89 static int yyerror(char *s
);
92 static object_t
* newObject();
93 static void freeObject(object_t
*o
);
95 static OSObject
*buildOSDictionary(object_t
*);
96 static OSObject
*buildOSArray(object_t
*);
97 static OSObject
*buildOSSet(object_t
*);
98 static OSObject
*buildOSString(object_t
*);
99 static OSObject
*buildOSData(object_t
*);
100 static OSObject
*buildOSOffset(object_t
*);
101 static OSObject
*buildOSBoolean(object_t
*o
);
103 static void rememberObject(int, object_t
*);
104 static OSObject
*retrieveObject(int);
106 // temp variable to use during parsing
109 // resultant object of parsed text
110 static OSObject
*parsedObject
;
112 #define YYSTYPE object_t *
115 extern void *kern_os_malloc(size_t size
);
116 extern void *kern_os_realloc(void * addr
, size_t size
);
117 extern void kern_os_free(void * addr
);
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)
137 #define YYFLAG -32768
140 #define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 31)
142 static 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,
173 static 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
179 static 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,
193 static 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
201 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
203 static 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
210 static 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
216 static 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,
222 static 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,
230 static const short yydefgoto
[] = { 41,
231 21, 11, 22, 23, 12, 13, 26, 14, 15, 16,
235 static 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,
243 static const short yypgoto
[] = {-32768,
244 0,-32768,-32768, 23,-32768,-32768, 38,-32768,-32768,-32768,
252 static 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,
264 static 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
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. */
279 /* Skeleton output parser for bison,
280 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
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)
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.
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. */
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. */
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. */
307 #ifndef YYSTACK_USE_ALLOCA
309 #define YYSTACK_USE_ALLOCA
310 #else /* alloca not defined */
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
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. */
327 #else /* not MSDOS, or __TURBOC__ */
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> */
333 #define YYSTACK_USE_ALLOCA
334 #else /* not MSDOS, or __TURBOC__, or _AIX */
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
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 */
349 #ifdef YYSTACK_USE_ALLOCA
350 #define YYSTACK_ALLOC alloca
352 #define YYSTACK_ALLOC malloc
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. */
359 #define yyerrok (yyerrstatus = 0)
360 #define yyclearin (yychar = YYEMPTY)
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) \
374 if (yychar == YYEMPTY && yylen == 1) \
375 { yychar = (token), yylval = (value); \
376 yychar1 = YYTRANSLATE (yychar); \
381 { yyerror ("syntax error: cannot back up"); YYERROR; } \
385 #define YYERRCODE 256
388 #define YYLEX yylex()
394 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
396 #define YYLEX yylex(&yylval, &yylloc)
398 #else /* not YYLSP_NEEDED */
400 #define YYLEX yylex(&yylval, YYLEX_PARAM)
402 #define YYLEX yylex(&yylval)
404 #endif /* not YYLSP_NEEDED */
407 /* If nonreentrant, generate the variables here */
411 int yychar
; /* the lookahead symbol */
412 YYSTYPE yylval
; /* the semantic value of the */
413 /* lookahead symbol */
416 YYLTYPE yylloc
; /* location data for the lookahead */
420 int yynerrs
; /* number of parse errors so far */
421 #endif /* not YYPURE */
424 int yydebug
; /* nonzero means print parse trace */
425 /* Since this is uninitialized, it does not stop multiple parsers
429 /* YYINITDEPTH indicates the initial size of the parser's stacks */
432 #define YYINITDEPTH 200
435 /* YYMAXDEPTH is the maximum size the stacks can grow to
436 (effective only if the built-in stack extension method is used). */
443 #define YYMAXDEPTH 10000
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. */
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++ */
456 /* This is the most reliable way to avoid incompatibilities
457 in available built-in functions on various systems. */
459 __yy_memcpy (to
, from
, count
)
464 register char *f
= from
;
465 register char *t
= to
;
466 register int i
= count
;
472 #else /* __cplusplus */
474 /* This is the most reliable way to avoid incompatibilities
475 in available built-in functions on various systems. */
477 __yy_memcpy (char *to
, char *from
, unsigned int count
)
479 register char *t
= to
;
480 register char *f
= from
;
481 register int i
= count
;
490 #line 217 "/usr/share/bison.simple"
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. */
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 */
511 /* Prevent warning if -Wstrict-prototypes. */
514 int yyparse (void *);
521 yyparse(YYPARSE_PARAM_ARG
)
524 register int yystate
;
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 */
531 short yyssa
[YYINITDEPTH
]; /* the state stack */
532 YYSTYPE yyvsa
[YYINITDEPTH
]; /* the semantic value stack */
534 short *yyss
= yyssa
; /* refer to the stacks thru separate pointers */
535 YYSTYPE
*yyvs
= yyvsa
; /* to allow yyoverflow to reallocate them elsewhere */
538 YYLTYPE yylsa
[YYINITDEPTH
]; /* the location stack */
539 YYLTYPE
*yyls
= yylsa
;
542 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
544 #define YYPOPSTACK (yyvsp--, yyssp--)
547 int yystacksize
= YYINITDEPTH
;
548 int yyfree_stacks
= 0;
559 YYSTYPE yyval
; /* the variable used to return */
560 /* semantic values from the action */
567 fprintf(stderr
, "Starting parse\n");
573 yychar
= YYEMPTY
; /* Cause a token to be read. */
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. */
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. */
593 if (yyssp
>= yyss
+ yystacksize
- 1)
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
;
600 YYLTYPE
*yyls1
= yyls
;
603 /* Get the current used size of the three stacks, in elements. */
604 int size
= yyssp
- yyss
+ 1;
607 /* Each stack pointer address is followed by the size of
608 the data in use in that stack, in bytes. */
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
),
618 yyoverflow("parser stack overflow",
619 &yyss1
, size
* sizeof (*yyssp
),
620 &yyvs1
, size
* sizeof (*yyvsp
),
624 yyss
= yyss1
; yyvs
= yyvs1
;
628 #else /* no yyoverflow */
629 /* Extend the stack our own way. */
630 if (yystacksize
>= YYMAXDEPTH
)
632 yyerror("parser stack overflow");
644 if (yystacksize
> YYMAXDEPTH
)
645 yystacksize
= YYMAXDEPTH
;
646 #ifndef YYSTACK_USE_ALLOCA
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
));
656 yyls
= (YYLTYPE
*) YYSTACK_ALLOC (yystacksize
* sizeof (*yylsp
));
657 __yy_memcpy ((char *)yyls
, (char *)yyls1
,
658 size
* (unsigned int) sizeof (*yylsp
));
660 #endif /* no yyoverflow */
662 yyssp
= yyss
+ size
- 1;
663 yyvsp
= yyvs
+ size
- 1;
665 yylsp
= yyls
+ size
- 1;
670 fprintf(stderr
, "Stack size increased to %d\n", yystacksize
);
673 if (yyssp
>= yyss
+ yystacksize
- 1)
679 fprintf(stderr
, "Entering state %d\n", yystate
);
685 /* Do appropriate processing given the current state. */
686 /* Read a lookahead token if we need one and don't already have one. */
689 /* First try to decide what to do without reference to lookahead token. */
691 yyn
= yypact
[yystate
];
695 /* Not known => get a lookahead token if don't already have one. */
697 /* yychar is either YYEMPTY or YYEOF
698 or a valid token in external form. */
700 if (yychar
== YYEMPTY
)
704 fprintf(stderr
, "Reading a token: ");
709 /* Convert token to internal form (in yychar1) for indexing tables with */
711 if (yychar
<= 0) /* This means end of input. */
714 yychar
= YYEOF
; /* Don't call YYLEX any more */
718 fprintf(stderr
, "Now at end of input.\n");
723 yychar1
= YYTRANSLATE(yychar
);
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. */
732 YYPRINT (stderr
, yychar
, yylval
);
734 fprintf (stderr
, ")\n");
740 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != yychar1
)
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,
750 0, or most negative number => error. */
765 /* Shift the lookahead token. */
769 fprintf(stderr
, "Shifting token %d (%s), ", yychar
, yytname
[yychar1
]);
772 /* Discard the token being shifted unless it is eof. */
781 /* count tokens shifted since error; after three, turn off error status. */
782 if (yyerrstatus
) yyerrstatus
--;
787 /* Do the default action for the current state. */
790 yyn
= yydefact
[yystate
];
794 /* Do a reduction. yyn is the number of a rule to reduce with. */
798 yyval
= yyvsp
[1-yylen
]; /* implement default value of the action */
805 fprintf (stderr
, "Reducing via rule %d (line %d), ",
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
]]);
819 #line 116 "OSUnserialize.y"
820 { parsedObject
= (OSObject
*)NULL
; YYACCEPT
; ;
823 #line 117 "OSUnserialize.y"
824 { parsedObject
= (OSObject
*)yyvsp
[0]; YYACCEPT
; ;
827 #line 118 "OSUnserialize.y"
828 { yyerror("syntax error"); YYERROR
; ;
831 #line 121 "OSUnserialize.y"
832 { yyval
= (object_t
*)buildOSDictionary(yyvsp
[0]); ;
835 #line 122 "OSUnserialize.y"
836 { yyval
= (object_t
*)buildOSArray(yyvsp
[0]); ;
839 #line 123 "OSUnserialize.y"
840 { yyval
= (object_t
*)buildOSSet(yyvsp
[0]); ;
843 #line 124 "OSUnserialize.y"
844 { yyval
= (object_t
*)buildOSString(yyvsp
[0]); ;
847 #line 125 "OSUnserialize.y"
848 { yyval
= (object_t
*)buildOSData(yyvsp
[0]); ;
851 #line 126 "OSUnserialize.y"
852 { yyval
= (object_t
*)buildOSOffset(yyvsp
[0]); ;
855 #line 127 "OSUnserialize.y"
856 { yyval
= (object_t
*)buildOSBoolean(yyvsp
[0]); ;
859 #line 128 "OSUnserialize.y"
860 { yyval
= (object_t
*)retrieveObject(yyvsp
[0]->u
.offset
);
862 ((OSObject
*)yyval
)->retain();
864 yyerror("forward reference detected");
867 freeObject(yyvsp
[0]);
871 #line 137 "OSUnserialize.y"
873 rememberObject(yyvsp
[0]->u
.offset
, yyvsp
[-2]);
874 freeObject(yyvsp
[0]);
878 #line 145 "OSUnserialize.y"
882 #line 146 "OSUnserialize.y"
883 { yyval
= yyvsp
[-1]; ;
886 #line 150 "OSUnserialize.y"
887 { yyvsp
[0]->next
= yyvsp
[-1]; yyvsp
[-1]->prev
= yyvsp
[0]; yyval
= yyvsp
[0]; ;
890 #line 153 "OSUnserialize.y"
891 { yyval
= newObject();
894 yyval
->u
.key
= yyvsp
[-3];
895 yyval
->object
= yyvsp
[-1];
899 #line 163 "OSUnserialize.y"
903 #line 164 "OSUnserialize.y"
904 { yyval
= yyvsp
[-1]; ;
907 #line 167 "OSUnserialize.y"
911 #line 168 "OSUnserialize.y"
912 { yyval
= yyvsp
[-1]; ;
915 #line 171 "OSUnserialize.y"
916 { yyval
= newObject();
917 yyval
->object
= yyvsp
[0];
923 #line 176 "OSUnserialize.y"
925 o
->object
= yyvsp
[0];
933 #line 187 "OSUnserialize.y"
935 yyval
->size
= yyvsp
[0]->u
.offset
;
936 freeObject(yyvsp
[0]);
940 /* the action file gets copied in in place of this dollarsign */
941 #line 543 "/usr/share/bison.simple"
952 short *ssp1
= yyss
- 1;
953 fprintf (stderr
, "state stack now");
954 while (ssp1
!= yyssp
)
955 fprintf (stderr
, " %d", *++ssp1
);
956 fprintf (stderr
, "\n");
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
;
974 yylsp
->last_line
= (yylsp
+yylen
-1)->last_line
;
975 yylsp
->last_column
= (yylsp
+yylen
-1)->last_column
;
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. */
986 yystate
= yypgoto
[yyn
- YYNTBASE
] + *yyssp
;
987 if (yystate
>= 0 && yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
988 yystate
= yytable
[yystate
];
990 yystate
= yydefgoto
[yyn
- YYNTBASE
];
994 yyerrlab
: /* here on detecting error */
997 /* If not already recovering from an error, report this error. */
1001 #ifdef YYERROR_VERBOSE
1002 yyn
= yypact
[yystate
];
1004 if (yyn
> YYFLAG
&& yyn
< YYLAST
)
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);
1019 strcpy(msg
, "parse error");
1024 for (x
= (yyn
< 0 ? -yyn
: 0);
1025 x
< (sizeof(yytname
) / sizeof(char *)); x
++)
1026 if (yycheck
[x
+ yyn
] == x
)
1028 strcat(msg
, count
== 0 ? ", expecting `" : " or `");
1029 strcat(msg
, yytname
[x
]);
1038 yyerror ("parse error; also virtual memory exceeded");
1041 #endif /* YYERROR_VERBOSE */
1042 yyerror("parse error");
1046 yyerrlab1
: /* here on error raised explicitly by an action */
1048 if (yyerrstatus
== 3)
1050 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1052 /* return failure if at end of input */
1053 if (yychar
== YYEOF
)
1058 fprintf(stderr
, "Discarding token %d (%s).\n", yychar
, yytname
[yychar1
]);
1064 /* Else will try to reuse lookahead token
1065 after shifting the error token. */
1067 yyerrstatus
= 3; /* Each real token shifted decrements this */
1071 yyerrdefault
: /* current state does not do anything special for the error token. */
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
;
1080 yyerrpop
: /* pop the current state because it cannot handle the error token */
1082 if (yyssp
== yyss
) YYABORT
;
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");
1102 yyn
= yypact
[yystate
];
1107 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != YYTERROR
)
1126 fprintf(stderr
, "Shifting error token, ");
1138 /* YYACCEPT comes here. */
1150 /* YYABORT comes here. */
1161 #line 208 "OSUnserialize.y"
1164 static int lineNumber
= 0;
1165 static const char *parseBuffer
;
1166 static int parseBufferIndex
;
1168 #define currentChar() (parseBuffer[parseBufferIndex])
1169 #define nextChar() (parseBuffer[++parseBufferIndex])
1170 #define prevChar() (parseBuffer[parseBufferIndex - 1])
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) == '-'))
1179 static char yyerror_message
[128];
1182 yyerror(char *s
) /* Called by yyparse on error */
1184 sprintf(yyerror_message
, "OSUnserialize: %s near line %d\n", s
, lineNumber
);
1193 if (parseBufferIndex
== 0) lineNumber
= 1;
1198 /* skip white space */
1199 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1201 /* skip over comments */
1202 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1204 /* keep track of line number, don't return \n's */
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
;
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
;
1226 if (nextChar() != '.') return SYNTAX_ERROR
;
1230 yylval
= (object_t
*)boolean
;
1234 /* parse unquoted string */
1239 start
= parseBufferIndex
;
1240 /* find end of string */
1241 while (isAlphaNumeric(c
)) {
1244 length
= parseBufferIndex
- start
;
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");
1252 bcopy(&parseBuffer
[start
], tempString
, length
);
1253 tempString
[length
] = 0;
1254 yylval
= (object_t
*)tempString
;
1258 /* parse quoted string */
1259 if (c
== '"' || c
== '\'') {
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
;
1271 length
= parseBufferIndex
- start
;
1272 /* skip over trailing quote */
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");
1282 for (int from
=start
; from
< parseBufferIndex
; from
++) {
1283 // hack - skip over backslashes
1284 if (parseBuffer
[from
] == '\\') {
1288 tempString
[to
] = parseBuffer
[from
];
1291 tempString
[length
] = 0;
1292 yylval
= (object_t
*)tempString
;
1296 /* process numbers */
1299 unsigned long long n
= 0;
1311 n
= (n
* base
+ c
- '0');
1315 while(isHexDigit(c
)) {
1317 n
= (n
* base
+ c
- '0');
1319 n
= (n
* base
+ 0xa + c
- 'a');
1325 yylval
= newObject();
1326 yylval
->u
.offset
= n
;
1331 #define OSDATA_ALLOC_SIZE 4096
1335 unsigned char *d
, *start
, *lastStart
;
1337 start
= lastStart
= d
= (unsigned char *)malloc(OSDATA_ALLOC_SIZE
);
1338 c
= nextChar(); // skip over '<'
1339 while (c
!= 0 && c
!= '>') {
1341 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1342 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1350 if (!isHexDigit(c
)) break;
1352 *d
= (c
- '0') << 4;
1354 *d
= (0xa + (c
- 'a')) << 4;
1359 if (!isHexDigit(c
)) break;
1363 *d
|= 0xa + (c
- 'a');
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
;
1376 return SYNTAX_ERROR
;
1380 yylval
= newObject();
1381 yylval
->object
= start
;
1382 yylval
->size
= d
- start
;
1384 (void)nextChar(); // skip over '>'
1389 /* return single chars, move pointer to next char */
1394 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1395 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1396 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1399 int debugUnserializeAllocCount
= 0;
1406 debugUnserializeAllocCount
++;
1408 return (object_t
*)malloc(sizeof(object_t
));
1412 freeObject(object_t
*o
)
1415 debugUnserializeAllocCount
--;
1420 static OSDictionary
*tags
;
1423 rememberObject(int tag
, object_t
*o
)
1426 sprintf(key
, "%u", tag
);
1428 tags
->setObject(key
, (OSObject
*)o
);
1432 retrieveObject(int tag
)
1435 sprintf(key
, "%u", tag
);
1437 return tags
->getObject(key
);
1441 buildOSDictionary(object_t
*o
)
1443 object_t
*temp
, *last
= o
;
1446 // get count and last object
1454 OSDictionary
*d
= OSDictionary::withCapacity(count
);
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
);
1462 // If it isn't a symbol, I hope it's a string!
1463 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1466 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1468 ((OSObject
*)o
->object
)->release();
1469 ((OSObject
*)o
->u
.key
)->release();
1478 buildOSArray(object_t
*o
)
1480 object_t
*temp
, *last
= o
;
1483 // get count and last object
1491 OSArray
*a
= OSArray::withCapacity(count
);
1494 a
->setObject((OSObject
*)o
->object
);
1495 ((OSObject
*)o
->object
)->release();
1504 buildOSSet(object_t
*o
)
1506 OSArray
*a
= (OSArray
*)buildOSArray(o
);
1507 OSSet
*s
= OSSet::withArray(a
, a
->getCapacity());
1514 buildOSString(object_t
*o
)
1516 OSString
*s
= OSString::withCString((char *)o
);
1524 buildOSData(object_t
*o
)
1529 d
= OSData::withBytes(o
->object
, o
->size
);
1531 d
= OSData::withCapacity(0);
1539 buildOSOffset(object_t
*o
)
1541 OSNumber
*off
= OSNumber::withNumber(o
->u
.offset
, o
->size
);
1547 buildOSBoolean(object_t
*o
)
1549 OSBoolean
*b
= OSBoolean::withBoolean((bool)o
);
1554 #include <kern/lock.h>
1557 static mutex_t
*lock
= 0;
1560 OSUnserialize(const char *buffer
, OSString
**errorString
)
1565 lock
= mutex_alloc(0);
1573 debugUnserializeAllocCount
= 0;
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;
1585 *errorString
= OSString::withCString(yyerror_message
);
1590 if (debugUnserializeAllocCount
) {
1591 printf("OSUnserialize: allocation check failed, count = %d.\n",
1592 debugUnserializeAllocCount
);
1606 // DO NOT EDIT OSUnserialize.cpp!