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)
138 #define YYFLAG -32768
141 #define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 31)
143 static const char yytranslate
[] = { 0,
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, 2,
147 2, 2, 2, 2, 2, 2, 2, 2, 2, 13,
148 14, 2, 2, 17, 2, 2, 2, 2, 2, 2,
149 2, 2, 2, 2, 2, 2, 2, 18, 12, 2,
150 11, 2, 2, 8, 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, 2,
153 15, 2, 16, 2, 2, 2, 2, 2, 2, 2,
154 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
155 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
156 2, 2, 9, 2, 10, 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, 2, 2, 2, 2, 2,
169 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
174 static const short yyprhs
[] = { 0,
175 0, 1, 3, 5, 7, 9, 11, 13, 15, 17,
176 19, 22, 26, 29, 33, 35, 38, 43, 46, 50,
177 53, 57, 59, 63, 67, 69, 71
180 static const short yyrhs
[] = { -1,
181 20, 0, 7, 0, 21, 0, 24, 0, 25, 0,
182 29, 0, 28, 0, 27, 0, 30, 0, 8, 3,
183 0, 20, 8, 3, 0, 9, 10, 0, 9, 22,
184 10, 0, 23, 0, 22, 23, 0, 20, 11, 20,
185 12, 0, 13, 14, 0, 13, 26, 14, 0, 15,
186 16, 0, 15, 26, 16, 0, 20, 0, 26, 17,
187 20, 0, 3, 18, 3, 0, 5, 0, 4, 0,
194 static const short yyrline
[] = { 0,
195 116, 117, 118, 121, 122, 123, 124, 125, 126, 127,
196 128, 137, 145, 146, 149, 150, 153, 163, 164, 167,
197 168, 171, 176, 187, 195, 200, 205
202 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
204 static const char * const yytname
[] = { "$","error","$undefined.","NUMBER",
205 "STRING","DATA","BOOLEAN","SYNTAX_ERROR","'@'","'{'","'}'","'='","';'","'('",
206 "')'","'['","']'","','","':'","input","object","dict","pairs","pair","array",
207 "set","elements","offset","data","string","boolean", NULL
211 static const short yyr1
[] = { 0,
212 19, 19, 19, 20, 20, 20, 20, 20, 20, 20,
213 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
214 25, 26, 26, 27, 28, 29, 30
217 static const short yyr2
[] = { 0,
218 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
219 2, 3, 2, 3, 1, 2, 4, 2, 3, 2,
223 static const short yydefact
[] = { 1,
224 0, 26, 25, 27, 3, 0, 0, 0, 0, 2,
225 4, 5, 6, 9, 8, 7, 10, 0, 11, 13,
226 0, 0, 15, 18, 22, 0, 20, 0, 0, 24,
227 0, 14, 16, 19, 0, 21, 12, 0, 23, 17,
231 static const short yydefgoto
[] = { 41,
232 21, 11, 22, 23, 12, 13, 26, 14, 15, 16,
236 static const short yypact
[] = { 12,
237 -13,-32768,-32768,-32768,-32768, 9, 33, 46, -2, 2,
238 -32768,-32768,-32768,-32768,-32768,-32768,-32768, 25,-32768,-32768,
239 21, 59,-32768,-32768, 2, 16,-32768, 7, 31,-32768,
240 72,-32768,-32768,-32768, 72,-32768,-32768, 14, 2,-32768,
244 static const short yypgoto
[] = {-32768,
245 0,-32768,-32768, 23,-32768,-32768, 38,-32768,-32768,-32768,
253 static const short yytable
[] = { 10,
254 1, 2, 3, 4, 18, 6, 7, 25, 25, 29,
255 8, 19, 9, 27, 1, 2, 3, 4, 5, 6,
256 7, 29, 36, 35, 8, 40, 9, 30, 29, 34,
257 38, 31, 35, 37, 39, 1, 2, 3, 4, 42,
258 6, 7, 20, 43, 33, 8, 28, 9, 1, 2,
259 3, 4, 0, 6, 7, 0, 0, 0, 8, 24,
260 9, 1, 2, 3, 4, 0, 6, 7, 32, 0,
261 0, 8, 0, 9, 1, 2, 3, 4, 0, 6,
265 static const short yycheck
[] = { 0,
266 3, 4, 5, 6, 18, 8, 9, 8, 9, 8,
267 13, 3, 15, 16, 3, 4, 5, 6, 7, 8,
268 9, 8, 16, 17, 13, 12, 15, 3, 8, 14,
269 31, 11, 17, 3, 35, 3, 4, 5, 6, 0,
270 8, 9, 10, 0, 22, 13, 9, 15, 3, 4,
271 5, 6, -1, 8, 9, -1, -1, -1, 13, 14,
272 15, 3, 4, 5, 6, -1, 8, 9, 10, -1,
273 -1, 13, -1, 15, 3, 4, 5, 6, -1, 8,
274 9, -1, -1, -1, 13, -1, 15
276 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
277 #line 3 "/usr/share/bison.simple"
278 /* This file comes from bison-1.28. */
280 /* Skeleton output parser for bison,
281 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
283 This program is free software; you can redistribute it and/or modify
284 it under the terms of the GNU General Public License as published by
285 the Free Software Foundation; either version 2, or (at your option)
288 This program is distributed in the hope that it will be useful,
289 but WITHOUT ANY WARRANTY; without even the implied warranty of
290 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
291 GNU General Public License for more details.
293 You should have received a copy of the GNU General Public License
294 along with this program; if not, write to the Free Software
295 Foundation, Inc., 59 Temple Place - Suite 330,
296 Boston, MA 02111-1307, USA. */
298 /* As a special exception, when this file is copied by Bison into a
299 Bison output file, you may use that output file without restriction.
300 This special exception was added by the Free Software Foundation
301 in version 1.24 of Bison. */
303 /* This is the parser code that is written into each bison parser
304 when the %semantic_parser declaration is not specified in the grammar.
305 It was written by Richard Stallman by simplifying the hairy parser
306 used when %semantic_parser is specified. */
308 #ifndef YYSTACK_USE_ALLOCA
310 #define YYSTACK_USE_ALLOCA
311 #else /* alloca not defined */
313 #define YYSTACK_USE_ALLOCA
314 #define alloca __builtin_alloca
315 #else /* not GNU C. */
316 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
317 #define YYSTACK_USE_ALLOCA
319 #else /* not sparc */
320 /* We think this test detects Watcom and Microsoft C. */
321 /* This used to test MSDOS, but that is a bad idea
322 since that symbol is in the user namespace. */
323 #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
324 #if 0 /* No need for malloc.h, which pollutes the namespace;
325 instead, just don't use alloca. */
328 #else /* not MSDOS, or __TURBOC__ */
330 /* I don't know what this was needed for, but it pollutes the namespace.
331 So I turned it off. rms, 2 May 1997. */
332 /* #include <malloc.h> */
334 #define YYSTACK_USE_ALLOCA
335 #else /* not MSDOS, or __TURBOC__, or _AIX */
337 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
338 and on HPUX 10. Eventually we can turn this on. */
339 #define YYSTACK_USE_ALLOCA
340 #define alloca __builtin_alloca
343 #endif /* not _AIX */
344 #endif /* not MSDOS, or __TURBOC__ */
345 #endif /* not sparc */
346 #endif /* not GNU C */
347 #endif /* alloca not defined */
348 #endif /* YYSTACK_USE_ALLOCA not defined */
350 #ifdef YYSTACK_USE_ALLOCA
351 #define YYSTACK_ALLOC alloca
353 #define YYSTACK_ALLOC malloc
356 /* Note: there must be only one dollar sign in this file.
357 It is replaced by the list of actions, each action
358 as one case of the switch. */
360 #define yyerrok (yyerrstatus = 0)
361 #define yyclearin (yychar = YYEMPTY)
364 #define YYACCEPT goto yyacceptlab
365 #define YYABORT goto yyabortlab
366 #define YYERROR goto yyerrlab1
367 /* Like YYERROR except do call yyerror.
368 This remains here temporarily to ease the
369 transition to the new meaning of YYERROR, for GCC.
370 Once GCC version 2 has supplanted version 1, this can go. */
371 #define YYFAIL goto yyerrlab
372 #define YYRECOVERING() (!!yyerrstatus)
373 #define YYBACKUP(token, value) \
375 if (yychar == YYEMPTY && yylen == 1) \
376 { yychar = (token), yylval = (value); \
377 yychar1 = YYTRANSLATE (yychar); \
382 { yyerror ("syntax error: cannot back up"); YYERROR; } \
386 #define YYERRCODE 256
389 #define YYLEX yylex()
395 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
397 #define YYLEX yylex(&yylval, &yylloc)
399 #else /* not YYLSP_NEEDED */
401 #define YYLEX yylex(&yylval, YYLEX_PARAM)
403 #define YYLEX yylex(&yylval)
405 #endif /* not YYLSP_NEEDED */
408 /* If nonreentrant, generate the variables here */
412 int yychar
; /* the lookahead symbol */
413 YYSTYPE yylval
; /* the semantic value of the */
414 /* lookahead symbol */
417 YYLTYPE yylloc
; /* location data for the lookahead */
421 int yynerrs
; /* number of parse errors so far */
422 #endif /* not YYPURE */
425 int yydebug
; /* nonzero means print parse trace */
426 /* Since this is uninitialized, it does not stop multiple parsers
430 /* YYINITDEPTH indicates the initial size of the parser's stacks */
433 #define YYINITDEPTH 200
436 /* YYMAXDEPTH is the maximum size the stacks can grow to
437 (effective only if the built-in stack extension method is used). */
444 #define YYMAXDEPTH 10000
447 /* Define __yy_memcpy. Note that the size argument
448 should be passed with type unsigned int, because that is what the non-GCC
449 definitions require. With GCC, __builtin_memcpy takes an arg
450 of type size_t, but it can handle unsigned int. */
452 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
453 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
454 #else /* not GNU C or C++ */
457 /* This is the most reliable way to avoid incompatibilities
458 in available built-in functions on various systems. */
460 __yy_memcpy (to
, from
, count
)
465 register char *f
= from
;
466 register char *t
= to
;
467 register int i
= count
;
473 #else /* __cplusplus */
475 /* This is the most reliable way to avoid incompatibilities
476 in available built-in functions on various systems. */
478 __yy_memcpy (char *to
, char *from
, unsigned int count
)
480 register char *t
= to
;
481 register char *f
= from
;
482 register int i
= count
;
491 #line 217 "/usr/share/bison.simple"
493 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
494 into yyparse. The argument should have type void *.
495 It should actually point to an object.
496 Grammar actions can access the variable by casting it
497 to the proper pointer type. */
501 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
502 #define YYPARSE_PARAM_DECL
503 #else /* not __cplusplus */
504 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
505 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
506 #endif /* not __cplusplus */
507 #else /* not YYPARSE_PARAM */
508 #define YYPARSE_PARAM_ARG
509 #define YYPARSE_PARAM_DECL
510 #endif /* not YYPARSE_PARAM */
512 /* Prevent warning if -Wstrict-prototypes. */
515 int yyparse (void *);
522 yyparse(YYPARSE_PARAM_ARG
)
525 register int yystate
;
527 register short *yyssp
;
528 register YYSTYPE
*yyvsp
;
529 int yyerrstatus
; /* number of tokens to shift before error messages enabled */
530 int yychar1
= 0; /* lookahead token as an internal (translated) token number */
532 short yyssa
[YYINITDEPTH
]; /* the state stack */
533 YYSTYPE yyvsa
[YYINITDEPTH
]; /* the semantic value stack */
535 short *yyss
= yyssa
; /* refer to the stacks thru separate pointers */
536 YYSTYPE
*yyvs
= yyvsa
; /* to allow yyoverflow to reallocate them elsewhere */
539 YYLTYPE yylsa
[YYINITDEPTH
]; /* the location stack */
540 YYLTYPE
*yyls
= yylsa
;
543 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
545 #define YYPOPSTACK (yyvsp--, yyssp--)
548 int yystacksize
= YYINITDEPTH
;
549 int yyfree_stacks
= 0;
560 YYSTYPE yyval
; /* the variable used to return */
561 /* semantic values from the action */
568 fprintf(stderr
, "Starting parse\n");
574 yychar
= YYEMPTY
; /* Cause a token to be read. */
576 /* Initialize stack pointers.
577 Waste one element of value and location stack
578 so that they stay on the same level as the state stack.
579 The wasted elements are never initialized. */
587 /* Push a new state, which is found in yystate . */
588 /* In all cases, when you get here, the value and location stacks
589 have just been pushed. so pushing a state here evens the stacks. */
594 if (yyssp
>= yyss
+ yystacksize
- 1)
596 /* Give user a chance to reallocate the stack */
597 /* Use copies of these so that the &'s don't force the real ones into memory. */
598 YYSTYPE
*yyvs1
= yyvs
;
601 YYLTYPE
*yyls1
= yyls
;
604 /* Get the current used size of the three stacks, in elements. */
605 int size
= yyssp
- yyss
+ 1;
608 /* Each stack pointer address is followed by the size of
609 the data in use in that stack, in bytes. */
611 /* This used to be a conditional around just the two extra args,
612 but that might be undefined if yyoverflow is a macro. */
613 yyoverflow("parser stack overflow",
614 &yyss1
, size
* sizeof (*yyssp
),
615 &yyvs1
, size
* sizeof (*yyvsp
),
616 &yyls1
, size
* sizeof (*yylsp
),
619 yyoverflow("parser stack overflow",
620 &yyss1
, size
* sizeof (*yyssp
),
621 &yyvs1
, size
* sizeof (*yyvsp
),
625 yyss
= yyss1
; yyvs
= yyvs1
;
629 #else /* no yyoverflow */
630 /* Extend the stack our own way. */
631 if (yystacksize
>= YYMAXDEPTH
)
633 yyerror("parser stack overflow");
645 if (yystacksize
> YYMAXDEPTH
)
646 yystacksize
= YYMAXDEPTH
;
647 #ifndef YYSTACK_USE_ALLOCA
650 yyss
= (short *) YYSTACK_ALLOC (yystacksize
* sizeof (*yyssp
));
651 __yy_memcpy ((char *)yyss
, (char *)yyss1
,
652 size
* (unsigned int) sizeof (*yyssp
));
653 yyvs
= (YYSTYPE
*) YYSTACK_ALLOC (yystacksize
* sizeof (*yyvsp
));
654 __yy_memcpy ((char *)yyvs
, (char *)yyvs1
,
655 size
* (unsigned int) sizeof (*yyvsp
));
657 yyls
= (YYLTYPE
*) YYSTACK_ALLOC (yystacksize
* sizeof (*yylsp
));
658 __yy_memcpy ((char *)yyls
, (char *)yyls1
,
659 size
* (unsigned int) sizeof (*yylsp
));
661 #endif /* no yyoverflow */
663 yyssp
= yyss
+ size
- 1;
664 yyvsp
= yyvs
+ size
- 1;
666 yylsp
= yyls
+ size
- 1;
671 fprintf(stderr
, "Stack size increased to %d\n", yystacksize
);
674 if (yyssp
>= yyss
+ yystacksize
- 1)
680 fprintf(stderr
, "Entering state %d\n", yystate
);
686 /* Do appropriate processing given the current state. */
687 /* Read a lookahead token if we need one and don't already have one. */
690 /* First try to decide what to do without reference to lookahead token. */
692 yyn
= yypact
[yystate
];
696 /* Not known => get a lookahead token if don't already have one. */
698 /* yychar is either YYEMPTY or YYEOF
699 or a valid token in external form. */
701 if (yychar
== YYEMPTY
)
705 fprintf(stderr
, "Reading a token: ");
710 /* Convert token to internal form (in yychar1) for indexing tables with */
712 if (yychar
<= 0) /* This means end of input. */
715 yychar
= YYEOF
; /* Don't call YYLEX any more */
719 fprintf(stderr
, "Now at end of input.\n");
724 yychar1
= YYTRANSLATE(yychar
);
729 fprintf (stderr
, "Next token is %d (%s", yychar
, yytname
[yychar1
]);
730 /* Give the individual parser a way to print the precise meaning
731 of a token, for further debugging info. */
733 YYPRINT (stderr
, yychar
, yylval
);
735 fprintf (stderr
, ")\n");
741 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != yychar1
)
746 /* yyn is what to do for this token type in this state.
747 Negative => reduce, -yyn is rule number.
748 Positive => shift, yyn is new state.
749 New state is final state => don't bother to shift,
751 0, or most negative number => error. */
766 /* Shift the lookahead token. */
770 fprintf(stderr
, "Shifting token %d (%s), ", yychar
, yytname
[yychar1
]);
773 /* Discard the token being shifted unless it is eof. */
782 /* count tokens shifted since error; after three, turn off error status. */
783 if (yyerrstatus
) yyerrstatus
--;
788 /* Do the default action for the current state. */
791 yyn
= yydefact
[yystate
];
795 /* Do a reduction. yyn is the number of a rule to reduce with. */
799 yyval
= yyvsp
[1-yylen
]; /* implement default value of the action */
806 fprintf (stderr
, "Reducing via rule %d (line %d), ",
809 /* Print the symbols being reduced, and their result. */
810 for (i
= yyprhs
[yyn
]; yyrhs
[i
] > 0; i
++)
811 fprintf (stderr
, "%s ", yytname
[yyrhs
[i
]]);
812 fprintf (stderr
, " -> %s\n", yytname
[yyr1
[yyn
]]);
820 #line 116 "OSUnserialize.y"
821 { parsedObject
= (OSObject
*)NULL
; YYACCEPT
; ;
824 #line 117 "OSUnserialize.y"
825 { parsedObject
= (OSObject
*)yyvsp
[0]; YYACCEPT
; ;
828 #line 118 "OSUnserialize.y"
829 { yyerror("syntax error"); YYERROR
; ;
832 #line 121 "OSUnserialize.y"
833 { yyval
= (object_t
*)buildOSDictionary(yyvsp
[0]); ;
836 #line 122 "OSUnserialize.y"
837 { yyval
= (object_t
*)buildOSArray(yyvsp
[0]); ;
840 #line 123 "OSUnserialize.y"
841 { yyval
= (object_t
*)buildOSSet(yyvsp
[0]); ;
844 #line 124 "OSUnserialize.y"
845 { yyval
= (object_t
*)buildOSString(yyvsp
[0]); ;
848 #line 125 "OSUnserialize.y"
849 { yyval
= (object_t
*)buildOSData(yyvsp
[0]); ;
852 #line 126 "OSUnserialize.y"
853 { yyval
= (object_t
*)buildOSOffset(yyvsp
[0]); ;
856 #line 127 "OSUnserialize.y"
857 { yyval
= (object_t
*)buildOSBoolean(yyvsp
[0]); ;
860 #line 128 "OSUnserialize.y"
861 { yyval
= (object_t
*)retrieveObject(yyvsp
[0]->u
.offset
);
863 ((OSObject
*)yyval
)->retain();
865 yyerror("forward reference detected");
868 freeObject(yyvsp
[0]);
872 #line 137 "OSUnserialize.y"
874 rememberObject(yyvsp
[0]->u
.offset
, yyvsp
[-2]);
875 freeObject(yyvsp
[0]);
879 #line 145 "OSUnserialize.y"
883 #line 146 "OSUnserialize.y"
884 { yyval
= yyvsp
[-1]; ;
887 #line 150 "OSUnserialize.y"
888 { yyvsp
[0]->next
= yyvsp
[-1]; yyvsp
[-1]->prev
= yyvsp
[0]; yyval
= yyvsp
[0]; ;
891 #line 153 "OSUnserialize.y"
892 { yyval
= newObject();
895 yyval
->u
.key
= yyvsp
[-3];
896 yyval
->object
= yyvsp
[-1];
900 #line 163 "OSUnserialize.y"
904 #line 164 "OSUnserialize.y"
905 { yyval
= yyvsp
[-1]; ;
908 #line 167 "OSUnserialize.y"
912 #line 168 "OSUnserialize.y"
913 { yyval
= yyvsp
[-1]; ;
916 #line 171 "OSUnserialize.y"
917 { yyval
= newObject();
918 yyval
->object
= yyvsp
[0];
924 #line 176 "OSUnserialize.y"
926 o
->object
= yyvsp
[0];
934 #line 187 "OSUnserialize.y"
936 yyval
->size
= yyvsp
[0]->u
.offset
;
937 freeObject(yyvsp
[0]);
941 /* the action file gets copied in in place of this dollarsign */
942 #line 543 "/usr/share/bison.simple"
953 short *ssp1
= yyss
- 1;
954 fprintf (stderr
, "state stack now");
955 while (ssp1
!= yyssp
)
956 fprintf (stderr
, " %d", *++ssp1
);
957 fprintf (stderr
, "\n");
967 yylsp
->first_line
= yylloc
.first_line
;
968 yylsp
->first_column
= yylloc
.first_column
;
969 yylsp
->last_line
= (yylsp
-1)->last_line
;
970 yylsp
->last_column
= (yylsp
-1)->last_column
;
975 yylsp
->last_line
= (yylsp
+yylen
-1)->last_line
;
976 yylsp
->last_column
= (yylsp
+yylen
-1)->last_column
;
980 /* Now "shift" the result of the reduction.
981 Determine what state that goes to,
982 based on the state we popped back to
983 and the rule number reduced by. */
987 yystate
= yypgoto
[yyn
- YYNTBASE
] + *yyssp
;
988 if (yystate
>= 0 && yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
989 yystate
= yytable
[yystate
];
991 yystate
= yydefgoto
[yyn
- YYNTBASE
];
995 yyerrlab
: /* here on detecting error */
998 /* If not already recovering from an error, report this error. */
1002 #ifdef YYERROR_VERBOSE
1003 yyn
= yypact
[yystate
];
1005 if (yyn
> YYFLAG
&& yyn
< YYLAST
)
1012 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1013 for (x
= (yyn
< 0 ? -yyn
: 0);
1014 x
< (sizeof(yytname
) / sizeof(char *)); x
++)
1015 if (yycheck
[x
+ yyn
] == x
)
1016 size
+= strlen(yytname
[x
]) + 15, count
++;
1017 msg
= (char *) malloc(size
+ 15);
1020 strcpy(msg
, "parse error");
1025 for (x
= (yyn
< 0 ? -yyn
: 0);
1026 x
< (sizeof(yytname
) / sizeof(char *)); x
++)
1027 if (yycheck
[x
+ yyn
] == x
)
1029 strcat(msg
, count
== 0 ? ", expecting `" : " or `");
1030 strcat(msg
, yytname
[x
]);
1039 yyerror ("parse error; also virtual memory exceeded");
1042 #endif /* YYERROR_VERBOSE */
1043 yyerror("parse error");
1047 yyerrlab1
: /* here on error raised explicitly by an action */
1049 if (yyerrstatus
== 3)
1051 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1053 /* return failure if at end of input */
1054 if (yychar
== YYEOF
)
1059 fprintf(stderr
, "Discarding token %d (%s).\n", yychar
, yytname
[yychar1
]);
1065 /* Else will try to reuse lookahead token
1066 after shifting the error token. */
1068 yyerrstatus
= 3; /* Each real token shifted decrements this */
1072 yyerrdefault
: /* current state does not do anything special for the error token. */
1075 /* This is wrong; only states that explicitly want error tokens
1076 should shift them. */
1077 yyn
= yydefact
[yystate
]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1078 if (yyn
) goto yydefault
;
1081 yyerrpop
: /* pop the current state because it cannot handle the error token */
1083 if (yyssp
== yyss
) YYABORT
;
1093 short *ssp1
= yyss
- 1;
1094 fprintf (stderr
, "Error: state stack now");
1095 while (ssp1
!= yyssp
)
1096 fprintf (stderr
, " %d", *++ssp1
);
1097 fprintf (stderr
, "\n");
1103 yyn
= yypact
[yystate
];
1108 if (yyn
< 0 || yyn
> YYLAST
|| yycheck
[yyn
] != YYTERROR
)
1127 fprintf(stderr
, "Shifting error token, ");
1139 /* YYACCEPT comes here. */
1151 /* YYABORT comes here. */
1162 #line 208 "OSUnserialize.y"
1165 static int lineNumber
= 0;
1166 static const char *parseBuffer
;
1167 static int parseBufferIndex
;
1169 #define currentChar() (parseBuffer[parseBufferIndex])
1170 #define nextChar() (parseBuffer[++parseBufferIndex])
1171 #define prevChar() (parseBuffer[parseBufferIndex - 1])
1173 #define isSpace(c) ((c) == ' ' || (c) == '\t')
1174 #define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1175 #define isDigit(c) ((c) >= '0' && (c) <= '9')
1176 #define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
1177 #define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
1178 #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
1180 static char yyerror_message
[128];
1183 yyerror(char *s
) /* Called by yyparse on error */
1185 sprintf(yyerror_message
, "OSUnserialize: %s near line %d\n", s
, lineNumber
);
1194 if (parseBufferIndex
== 0) lineNumber
= 1;
1199 /* skip white space */
1200 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1202 /* skip over comments */
1203 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1205 /* keep track of line number, don't return \n's */
1214 bool boolean
= false;
1215 if (nextChar() == 't') {
1216 if (nextChar() != 'r') return SYNTAX_ERROR
;
1217 if (nextChar() != 'u') return SYNTAX_ERROR
;
1218 if (nextChar() != 'e') return SYNTAX_ERROR
;
1221 if (currentChar() != 'f') return SYNTAX_ERROR
;
1222 if (nextChar() != 'a') return SYNTAX_ERROR
;
1223 if (nextChar() != 'l') return SYNTAX_ERROR
;
1224 if (nextChar() != 's') return SYNTAX_ERROR
;
1225 if (nextChar() != 'e') return SYNTAX_ERROR
;
1227 if (nextChar() != '.') return SYNTAX_ERROR
;
1231 yylval
= (object_t
*)boolean
;
1235 /* parse unquoted string */
1240 start
= parseBufferIndex
;
1241 /* find end of string */
1242 while (isAlphaNumeric(c
)) {
1245 length
= parseBufferIndex
- start
;
1247 /* copy to null terminated buffer */
1248 tempString
= (char *)malloc(length
+ 1);
1249 if (tempString
== 0) {
1250 printf("OSUnserialize: can't alloc temp memory\n");
1253 bcopy(&parseBuffer
[start
], tempString
, length
);
1254 tempString
[length
] = 0;
1255 yylval
= (object_t
*)tempString
;
1259 /* parse quoted string */
1260 if (c
== '"' || c
== '\'') {
1265 start
= parseBufferIndex
+ 1; // skip quote
1266 /* find end of string, line, buffer */
1267 while ((c
= nextChar()) != quoteChar
) {
1268 if (c
== '\\') c
= nextChar();
1269 if (c
== '\n') lineNumber
++;
1270 if (c
== 0) return SYNTAX_ERROR
;
1272 length
= parseBufferIndex
- start
;
1273 /* skip over trailing quote */
1275 /* copy to null terminated buffer */
1276 tempString
= (char *)malloc(length
+ 1);
1277 if (tempString
== 0) {
1278 printf("OSUnserialize: can't alloc temp memory\n");
1283 for (int from
=start
; from
< parseBufferIndex
; from
++) {
1284 // hack - skip over backslashes
1285 if (parseBuffer
[from
] == '\\') {
1289 tempString
[to
] = parseBuffer
[from
];
1292 tempString
[length
] = 0;
1293 yylval
= (object_t
*)tempString
;
1297 /* process numbers */
1300 unsigned long long n
= 0;
1312 n
= (n
* base
+ c
- '0');
1316 while(isHexDigit(c
)) {
1318 n
= (n
* base
+ c
- '0');
1320 n
= (n
* base
+ 0xa + c
- 'a');
1326 yylval
= newObject();
1327 yylval
->u
.offset
= n
;
1332 #define OSDATA_ALLOC_SIZE 4096
1336 unsigned char *d
, *start
, *lastStart
;
1338 start
= lastStart
= d
= (unsigned char *)malloc(OSDATA_ALLOC_SIZE
);
1339 c
= nextChar(); // skip over '<'
1340 while (c
!= 0 && c
!= '>') {
1342 if (isSpace(c
)) while ((c
= nextChar()) != 0 && isSpace(c
)) {};
1343 if (c
== '#') while ((c
= nextChar()) != 0 && c
!= '\n') {};
1351 if (!isHexDigit(c
)) break;
1353 *d
= (c
- '0') << 4;
1355 *d
= (0xa + (c
- 'a')) << 4;
1360 if (!isHexDigit(c
)) break;
1364 *d
|= 0xa + (c
- 'a');
1368 if ((d
- lastStart
) >= OSDATA_ALLOC_SIZE
) {
1369 int oldsize
= d
- start
;
1370 start
= (unsigned char *)realloc(start
, oldsize
+ OSDATA_ALLOC_SIZE
);
1371 d
= lastStart
= start
+ oldsize
;
1377 return SYNTAX_ERROR
;
1381 yylval
= newObject();
1382 yylval
->object
= start
;
1383 yylval
->size
= d
- start
;
1385 (void)nextChar(); // skip over '>'
1390 /* return single chars, move pointer to next char */
1395 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1396 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1397 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1400 int debugUnserializeAllocCount
= 0;
1407 debugUnserializeAllocCount
++;
1409 return (object_t
*)malloc(sizeof(object_t
));
1413 freeObject(object_t
*o
)
1416 debugUnserializeAllocCount
--;
1421 static OSDictionary
*tags
;
1424 rememberObject(int tag
, object_t
*o
)
1427 sprintf(key
, "%u", tag
);
1429 tags
->setObject(key
, (OSObject
*)o
);
1433 retrieveObject(int tag
)
1436 sprintf(key
, "%u", tag
);
1438 return tags
->getObject(key
);
1442 buildOSDictionary(object_t
*o
)
1444 object_t
*temp
, *last
= o
;
1447 // get count and last object
1455 OSDictionary
*d
= OSDictionary::withCapacity(count
);
1458 #ifdef metaclass_stuff_worksXXX
1459 if (((OSObject
*)o
->u
.key
)->metaCast("OSSymbol")) {
1460 // XXX the evil frontdoor
1461 d
->setObject((OSSymbol
*)o
->u
.key
, (OSObject
*)o
->object
);
1463 // If it isn't a symbol, I hope it's a string!
1464 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1467 d
->setObject((OSString
*)o
->u
.key
, (OSObject
*)o
->object
);
1469 ((OSObject
*)o
->object
)->release();
1470 ((OSObject
*)o
->u
.key
)->release();
1479 buildOSArray(object_t
*o
)
1481 object_t
*temp
, *last
= o
;
1484 // get count and last object
1492 OSArray
*a
= OSArray::withCapacity(count
);
1495 a
->setObject((OSObject
*)o
->object
);
1496 ((OSObject
*)o
->object
)->release();
1505 buildOSSet(object_t
*o
)
1507 OSArray
*a
= (OSArray
*)buildOSArray(o
);
1508 OSSet
*s
= OSSet::withArray(a
, a
->getCapacity());
1515 buildOSString(object_t
*o
)
1517 OSString
*s
= OSString::withCString((char *)o
);
1525 buildOSData(object_t
*o
)
1530 d
= OSData::withBytes(o
->object
, o
->size
);
1532 d
= OSData::withCapacity(0);
1540 buildOSOffset(object_t
*o
)
1542 OSNumber
*off
= OSNumber::withNumber(o
->u
.offset
, o
->size
);
1548 buildOSBoolean(object_t
*o
)
1550 OSBoolean
*b
= OSBoolean::withBoolean((bool)o
);
1555 #include <kern/lock.h>
1558 static mutex_t
*lock
= 0;
1561 OSUnserialize(const char *buffer
, OSString
**errorString
)
1566 lock
= mutex_alloc(ETAP_IO_AHA
);
1574 debugUnserializeAllocCount
= 0;
1576 yyerror_message
[0] = 0; //just in case
1577 parseBuffer
= buffer
;
1578 parseBufferIndex
= 0;
1579 tags
= OSDictionary::withCapacity(128);
1580 if (yyparse() == 0) {
1581 object
= parsedObject
;
1582 if (errorString
) *errorString
= 0;
1586 *errorString
= OSString::withCString(yyerror_message
);
1591 if (debugUnserializeAllocCount
) {
1592 printf("OSUnserialize: allocation check failed, count = %d.\n",
1593 debugUnserializeAllocCount
);
1607 // DO NOT EDIT OSUnserialize.cpp!