2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
23 * @APPLE_LICENSE_HEADER_END@
26 /* OSUnserialize.y created by rsulack on Nov 21 1998 */
28 // "classic" parser for unserializing OSContainer objects
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
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
42 // when changing code check in both OSUnserialize.y and OSUnserialize.cpp
47 // DO NOT EDIT OSUnserialize.tab.cpp!
55 /* A Bison parser, made from OSUnserialize.y
56 by GNU Bison version 1.28 */
58 #define YYBISON 1 /* Identify Bison output. */
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
71 #define SYNTAX_ERROR 261
73 #line 54 "OSUnserialize.y"
75 #include <libkern/c++/OSMetaClass.h>
76 #include <libkern/c++/OSContainers.h>
77 #include <libkern/c++/OSLib.h>
79 typedef struct object
{
85 void *key
; // for dictionary
86 long long offset
; // for offset
92 static int yyerror(char *s
);
95 static object_t
* newObject();
96 static void freeObject(object_t
*o
);
98 static OSObject
*buildOSDictionary(object_t
*);
99 static OSObject
*buildOSArray(object_t
*);
100 static OSObject
*buildOSSet(object_t
*);
101 static OSObject
*buildOSString(object_t
*);
102 static OSObject
*buildOSData(object_t
*);
103 static OSObject
*buildOSOffset(object_t
*);
104 static OSObject
*buildOSBoolean(object_t
*o
);
106 static void rememberObject(int, object_t
*);
107 static OSObject
*retrieveObject(int);
109 // temp variable to use during parsing
112 // resultant object of parsed text
113 static OSObject
*parsedObject
;
115 #define YYSTYPE object_t *
118 extern void *kern_os_malloc(size_t size
);
119 extern void *kern_os_realloc(void * addr
, size_t size
);
120 extern void kern_os_free(void * addr
);
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)
140 #define YYFLAG -32768
143 #define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 31)
145 static 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,
176 static 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
182 static 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,
196 static 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
204 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
206 static 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
213 static 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
219 static 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,
225 static 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,
233 static const short yydefgoto
[] = { 41,
234 21, 11, 22, 23, 12, 13, 26, 14, 15, 16,
238 static 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,
246 static const short yypgoto
[] = {-32768,
247 0,-32768,-32768, 23,-32768,-32768, 38,-32768,-32768,-32768,
255 static 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,
267 static 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
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. */
282 /* Skeleton output parser for bison,
283 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
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)
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.
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. */
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. */
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. */
310 #ifndef YYSTACK_USE_ALLOCA
312 #define YYSTACK_USE_ALLOCA
313 #else /* alloca not defined */
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
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. */
330 #else /* not MSDOS, or __TURBOC__ */
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> */
336 #define YYSTACK_USE_ALLOCA
337 #else /* not MSDOS, or __TURBOC__, or _AIX */
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
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 */
352 #ifdef YYSTACK_USE_ALLOCA
353 #define YYSTACK_ALLOC alloca
355 #define YYSTACK_ALLOC malloc
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. */
362 #define yyerrok (yyerrstatus = 0)
363 #define yyclearin (yychar = YYEMPTY)
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) \
377 if (yychar == YYEMPTY && yylen == 1) \
378 { yychar = (token), yylval = (value); \
379 yychar1 = YYTRANSLATE (yychar); \
384 { yyerror ("syntax error: cannot back up"); YYERROR; } \
388 #define YYERRCODE 256
391 #define YYLEX yylex()
397 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
399 #define YYLEX yylex(&yylval, &yylloc)
401 #else /* not YYLSP_NEEDED */
403 #define YYLEX yylex(&yylval, YYLEX_PARAM)
405 #define YYLEX yylex(&yylval)
407 #endif /* not YYLSP_NEEDED */
410 /* If nonreentrant, generate the variables here */
414 int yychar
; /* the lookahead symbol */
415 YYSTYPE yylval
; /* the semantic value of the */
416 /* lookahead symbol */
419 YYLTYPE yylloc
; /* location data for the lookahead */
423 int yynerrs
; /* number of parse errors so far */
424 #endif /* not YYPURE */
427 int yydebug
; /* nonzero means print parse trace */
428 /* Since this is uninitialized, it does not stop multiple parsers
432 /* YYINITDEPTH indicates the initial size of the parser's stacks */
435 #define YYINITDEPTH 200
438 /* YYMAXDEPTH is the maximum size the stacks can grow to
439 (effective only if the built-in stack extension method is used). */
446 #define YYMAXDEPTH 10000
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. */
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++ */
459 /* This is the most reliable way to avoid incompatibilities
460 in available built-in functions on various systems. */
462 __yy_memcpy (to
, from
, count
)
467 register char *f
= from
;
468 register char *t
= to
;
469 register int i
= count
;
475 #else /* __cplusplus */
477 /* This is the most reliable way to avoid incompatibilities
478 in available built-in functions on various systems. */
480 __yy_memcpy (char *to
, char *from
, unsigned int count
)
482 register char *t
= to
;
483 register char *f
= from
;
484 register int i
= count
;
493 #line 217 "/usr/share/bison.simple"
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. */
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 */
514 /* Prevent warning if -Wstrict-prototypes. */
517 int yyparse (void *);
524 yyparse(YYPARSE_PARAM_ARG
)
527 register int yystate
;
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 */
534 short yyssa
[YYINITDEPTH
]; /* the state stack */
535 YYSTYPE yyvsa
[YYINITDEPTH
]; /* the semantic value stack */
537 short *yyss
= yyssa
; /* refer to the stacks thru separate pointers */
538 YYSTYPE
*yyvs
= yyvsa
; /* to allow yyoverflow to reallocate them elsewhere */
541 YYLTYPE yylsa
[YYINITDEPTH
]; /* the location stack */
542 YYLTYPE
*yyls
= yylsa
;
545 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
547 #define YYPOPSTACK (yyvsp--, yyssp--)
550 int yystacksize
= YYINITDEPTH
;
551 int yyfree_stacks
= 0;
562 YYSTYPE yyval
; /* the variable used to return */
563 /* semantic values from the action */
570 fprintf(stderr
, "Starting parse\n");
576 yychar
= YYEMPTY
; /* Cause a token to be read. */
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. */
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. */
596 if (yyssp
>= yyss
+ yystacksize
- 1)
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
;
603 YYLTYPE
*yyls1
= yyls
;
606 /* Get the current used size of the three stacks, in elements. */
607 int size
= yyssp
- yyss
+ 1;
610 /* Each stack pointer address is followed by the size of
611 the data in use in that stack, in bytes. */
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
),
621 yyoverflow("parser stack overflow",
622 &yyss1
, size
* sizeof (*yyssp
),
623 &yyvs1
, size
* sizeof (*yyvsp
),
627 yyss
= yyss1
; yyvs
= yyvs1
;
631 #else /* no yyoverflow */
632 /* Extend the stack our own way. */
633 if (yystacksize
>= YYMAXDEPTH
)
635 yyerror("parser stack overflow");
647 if (yystacksize
> YYMAXDEPTH
)
648 yystacksize
= YYMAXDEPTH
;
649 #ifndef YYSTACK_USE_ALLOCA
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
));
659 yyls
= (YYLTYPE
*) YYSTACK_ALLOC (yystacksize
* sizeof (*yylsp
));
660 __yy_memcpy ((char *)yyls
, (char *)yyls1
,
661 size
* (unsigned int) sizeof (*yylsp
));
663 #endif /* no yyoverflow */
665 yyssp
= yyss
+ size
- 1;
666 yyvsp
= yyvs
+ size
- 1;
668 yylsp
= yyls
+ size
- 1;
673 fprintf(stderr
, "Stack size increased to %d\n", yystacksize
);
676 if (yyssp
>= yyss
+ yystacksize
- 1)
682 fprintf(stderr
, "Entering state %d\n", yystate
);
688 /* Do appropriate processing given the current state. */
689 /* Read a lookahead token if we need one and don't already have one. */
692 /* First try to decide what to do without reference to lookahead token. */
694 yyn
= yypact
[yystate
];
698 /* Not known => get a lookahead token if don't already have one. */
700 /* yychar is either YYEMPTY or YYEOF
701 or a valid token in external form. */
703 if (yychar
== YYEMPTY
)
707 fprintf(stderr
, "Reading a token: ");
712 /* Convert token to internal form (in yychar1) for indexing tables with */
714 if (yychar
<= 0) /* This means end of input. */
717 yychar
= YYEOF
; /* Don't call YYLEX any more */
721 fprintf(stderr
, "Now at end of input.\n");
726 yychar1
= YYTRANSLATE(yychar
);
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. */
735 YYPRINT (stderr
, yychar
, yylval
);
737 fprintf (stderr
, ")\n");
743 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != yychar1
)
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,
753 0, or most negative number => error. */
768 /* Shift the lookahead token. */
772 fprintf(stderr
, "Shifting token %d (%s), ", yychar
, yytname
[yychar1
]);
775 /* Discard the token being shifted unless it is eof. */
784 /* count tokens shifted since error; after three, turn off error status. */
785 if (yyerrstatus
) yyerrstatus
--;
790 /* Do the default action for the current state. */
793 yyn
= yydefact
[yystate
];
797 /* Do a reduction. yyn is the number of a rule to reduce with. */
801 yyval
= yyvsp
[1-yylen
]; /* implement default value of the action */
808 fprintf (stderr
, "Reducing via rule %d (line %d), ",
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
]]);
822 #line 116 "OSUnserialize.y"
823 { parsedObject
= (OSObject
*)NULL
; YYACCEPT
; ;
826 #line 117 "OSUnserialize.y"
827 { parsedObject
= (OSObject
*)yyvsp
[0]; YYACCEPT
; ;
830 #line 118 "OSUnserialize.y"
831 { yyerror("syntax error"); YYERROR
; ;
834 #line 121 "OSUnserialize.y"
835 { yyval
= (object_t
*)buildOSDictionary(yyvsp
[0]); ;
838 #line 122 "OSUnserialize.y"
839 { yyval
= (object_t
*)buildOSArray(yyvsp
[0]); ;
842 #line 123 "OSUnserialize.y"
843 { yyval
= (object_t
*)buildOSSet(yyvsp
[0]); ;
846 #line 124 "OSUnserialize.y"
847 { yyval
= (object_t
*)buildOSString(yyvsp
[0]); ;
850 #line 125 "OSUnserialize.y"
851 { yyval
= (object_t
*)buildOSData(yyvsp
[0]); ;
854 #line 126 "OSUnserialize.y"
855 { yyval
= (object_t
*)buildOSOffset(yyvsp
[0]); ;
858 #line 127 "OSUnserialize.y"
859 { yyval
= (object_t
*)buildOSBoolean(yyvsp
[0]); ;
862 #line 128 "OSUnserialize.y"
863 { yyval
= (object_t
*)retrieveObject(yyvsp
[0]->u
.offset
);
865 ((OSObject
*)yyval
)->retain();
867 yyerror("forward reference detected");
870 freeObject(yyvsp
[0]);
874 #line 137 "OSUnserialize.y"
876 rememberObject(yyvsp
[0]->u
.offset
, yyvsp
[-2]);
877 freeObject(yyvsp
[0]);
881 #line 145 "OSUnserialize.y"
885 #line 146 "OSUnserialize.y"
886 { yyval
= yyvsp
[-1]; ;
889 #line 150 "OSUnserialize.y"
890 { yyvsp
[0]->next
= yyvsp
[-1]; yyvsp
[-1]->prev
= yyvsp
[0]; yyval
= yyvsp
[0]; ;
893 #line 153 "OSUnserialize.y"
894 { yyval
= newObject();
897 yyval
->u
.key
= yyvsp
[-3];
898 yyval
->object
= yyvsp
[-1];
902 #line 163 "OSUnserialize.y"
906 #line 164 "OSUnserialize.y"
907 { yyval
= yyvsp
[-1]; ;
910 #line 167 "OSUnserialize.y"
914 #line 168 "OSUnserialize.y"
915 { yyval
= yyvsp
[-1]; ;
918 #line 171 "OSUnserialize.y"
919 { yyval
= newObject();
920 yyval
->object
= yyvsp
[0];
926 #line 176 "OSUnserialize.y"
928 o
->object
= yyvsp
[0];
936 #line 187 "OSUnserialize.y"
938 yyval
->size
= yyvsp
[0]->u
.offset
;
939 freeObject(yyvsp
[0]);
943 /* the action file gets copied in in place of this dollarsign */
944 #line 543 "/usr/share/bison.simple"
955 short *ssp1
= yyss
- 1;
956 fprintf (stderr
, "state stack now");
957 while (ssp1
!= yyssp
)
958 fprintf (stderr
, " %d", *++ssp1
);
959 fprintf (stderr
, "\n");
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
;
977 yylsp
->last_line
= (yylsp
+yylen
-1)->last_line
;
978 yylsp
->last_column
= (yylsp
+yylen
-1)->last_column
;
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. */
989 yystate
= yypgoto
[yyn
- YYNTBASE
] + *yyssp
;
990 if (yystate
>= 0 && yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
991 yystate
= yytable
[yystate
];
993 yystate
= yydefgoto
[yyn
- YYNTBASE
];
997 yyerrlab
: /* here on detecting error */
1000 /* If not already recovering from an error, report this error. */
1004 #ifdef YYERROR_VERBOSE
1005 yyn
= yypact
[yystate
];
1007 if (yyn
> YYFLAG
&& yyn
< YYLAST
)
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);
1022 strcpy(msg
, "parse error");
1027 for (x
= (yyn
< 0 ? -yyn
: 0);
1028 x
< (sizeof(yytname
) / sizeof(char *)); x
++)
1029 if (yycheck
[x
+ yyn
] == x
)
1031 strcat(msg
, count
== 0 ? ", expecting `" : " or `");
1032 strcat(msg
, yytname
[x
]);
1041 yyerror ("parse error; also virtual memory exceeded");
1044 #endif /* YYERROR_VERBOSE */
1045 yyerror("parse error");
1049 yyerrlab1
: /* here on error raised explicitly by an action */
1051 if (yyerrstatus
== 3)
1053 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1055 /* return failure if at end of input */
1056 if (yychar
== YYEOF
)
1061 fprintf(stderr
, "Discarding token %d (%s).\n", yychar
, yytname
[yychar1
]);
1067 /* Else will try to reuse lookahead token
1068 after shifting the error token. */
1070 yyerrstatus
= 3; /* Each real token shifted decrements this */
1074 yyerrdefault
: /* current state does not do anything special for the error token. */
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
;
1083 yyerrpop
: /* pop the current state because it cannot handle the error token */
1085 if (yyssp
== yyss
) YYABORT
;
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");
1105 yyn
= yypact
[yystate
];
1110 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != YYTERROR
)
1129 fprintf(stderr
, "Shifting error token, ");
1141 /* YYACCEPT comes here. */
1153 /* YYABORT comes here. */
1164 #line 208 "OSUnserialize.y"
1167 static int lineNumber
= 0;
1168 static const char *parseBuffer
;
1169 static int parseBufferIndex
;
1171 #define currentChar() (parseBuffer[parseBufferIndex])
1172 #define nextChar() (parseBuffer[++parseBufferIndex])
1173 #define prevChar() (parseBuffer[parseBufferIndex - 1])
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) == '-'))
1182 static char yyerror_message
[128];
1185 yyerror(char *s
) /* Called by yyparse on error */
1187 sprintf(yyerror_message
, "OSUnserialize: %s near line %d\n", s
, lineNumber
);
1196 if (parseBufferIndex
== 0) lineNumber
= 1;
1201 /* skip white space */
1202 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1204 /* skip over comments */
1205 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1207 /* keep track of line number, don't return \n's */
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
;
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
;
1229 if (nextChar() != '.') return SYNTAX_ERROR
;
1233 yylval
= (object_t
*)boolean
;
1237 /* parse unquoted string */
1242 start
= parseBufferIndex
;
1243 /* find end of string */
1244 while (isAlphaNumeric(c
)) {
1247 length
= parseBufferIndex
- start
;
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");
1255 bcopy(&parseBuffer
[start
], tempString
, length
);
1256 tempString
[length
] = 0;
1257 yylval
= (object_t
*)tempString
;
1261 /* parse quoted string */
1262 if (c
== '"' || c
== '\'') {
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
;
1274 length
= parseBufferIndex
- start
;
1275 /* skip over trailing quote */
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");
1285 for (int from
=start
; from
< parseBufferIndex
; from
++) {
1286 // hack - skip over backslashes
1287 if (parseBuffer
[from
] == '\\') {
1291 tempString
[to
] = parseBuffer
[from
];
1294 tempString
[length
] = 0;
1295 yylval
= (object_t
*)tempString
;
1299 /* process numbers */
1302 unsigned long long n
= 0;
1314 n
= (n
* base
+ c
- '0');
1318 while(isHexDigit(c
)) {
1320 n
= (n
* base
+ c
- '0');
1322 n
= (n
* base
+ 0xa + c
- 'a');
1328 yylval
= newObject();
1329 yylval
->u
.offset
= n
;
1334 #define OSDATA_ALLOC_SIZE 4096
1338 unsigned char *d
, *start
, *lastStart
;
1340 start
= lastStart
= d
= (unsigned char *)malloc(OSDATA_ALLOC_SIZE
);
1341 c
= nextChar(); // skip over '<'
1342 while (c
!= 0 && c
!= '>') {
1344 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1345 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1353 if (!isHexDigit(c
)) break;
1355 *d
= (c
- '0') << 4;
1357 *d
= (0xa + (c
- 'a')) << 4;
1362 if (!isHexDigit(c
)) break;
1366 *d
|= 0xa + (c
- 'a');
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
;
1379 return SYNTAX_ERROR
;
1383 yylval
= newObject();
1384 yylval
->object
= start
;
1385 yylval
->size
= d
- start
;
1387 (void)nextChar(); // skip over '>'
1392 /* return single chars, move pointer to next char */
1397 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1398 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1399 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1402 int debugUnserializeAllocCount
= 0;
1409 debugUnserializeAllocCount
++;
1411 return (object_t
*)malloc(sizeof(object_t
));
1415 freeObject(object_t
*o
)
1418 debugUnserializeAllocCount
--;
1423 static OSDictionary
*tags
;
1426 rememberObject(int tag
, object_t
*o
)
1429 sprintf(key
, "%u", tag
);
1431 tags
->setObject(key
, (OSObject
*)o
);
1435 retrieveObject(int tag
)
1438 sprintf(key
, "%u", tag
);
1440 return tags
->getObject(key
);
1444 buildOSDictionary(object_t
*o
)
1446 object_t
*temp
, *last
= o
;
1449 // get count and last object
1457 OSDictionary
*d
= OSDictionary::withCapacity(count
);
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
);
1465 // If it isn't a symbol, I hope it's a string!
1466 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1469 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1471 ((OSObject
*)o
->object
)->release();
1472 ((OSObject
*)o
->u
.key
)->release();
1481 buildOSArray(object_t
*o
)
1483 object_t
*temp
, *last
= o
;
1486 // get count and last object
1494 OSArray
*a
= OSArray::withCapacity(count
);
1497 a
->setObject((OSObject
*)o
->object
);
1498 ((OSObject
*)o
->object
)->release();
1507 buildOSSet(object_t
*o
)
1509 OSArray
*a
= (OSArray
*)buildOSArray(o
);
1510 OSSet
*s
= OSSet::withArray(a
, a
->getCapacity());
1517 buildOSString(object_t
*o
)
1519 OSString
*s
= OSString::withCString((char *)o
);
1527 buildOSData(object_t
*o
)
1532 d
= OSData::withBytes(o
->object
, o
->size
);
1534 d
= OSData::withCapacity(0);
1542 buildOSOffset(object_t
*o
)
1544 OSNumber
*off
= OSNumber::withNumber(o
->u
.offset
, o
->size
);
1550 buildOSBoolean(object_t
*o
)
1552 OSBoolean
*b
= OSBoolean::withBoolean((bool)o
);
1557 #include <kern/lock.h>
1560 static mutex_t
*lock
= 0;
1563 OSUnserialize(const char *buffer
, OSString
**errorString
)
1568 lock
= mutex_alloc(ETAP_IO_AHA
);
1576 debugUnserializeAllocCount
= 0;
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;
1588 *errorString
= OSString::withCString(yyerror_message
);
1593 if (debugUnserializeAllocCount
) {
1594 printf("OSUnserialize: allocation check failed, count = %d.\n",
1595 debugUnserializeAllocCount
);
1609 // DO NOT EDIT OSUnserialize.cpp!