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