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