]> git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSUnserialize.cpp
xnu-201.tar.gz
[apple/xnu.git] / libkern / c++ / OSUnserialize.cpp
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 /* OSUnserialize.y created by rsulack on Nov 21 1998 */
24
25 // "classic" parser for unserializing OSContainer objects
26 //
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
32 //
33 //
34 // to build :
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
38 //
39 // when changing code check in both OSUnserialize.y and OSUnserialize.cpp
40 //
41 //
42 //
43 //
44 // DO NOT EDIT OSUnserialize.tab.cpp!
45 //
46 // this means you!
47 //
48 //
49 //
50 //
51
52 /* A Bison parser, made from OSUnserialize.y
53 by GNU Bison version 1.28 */
54
55 #define YYBISON 1 /* Identify Bison output. */
56
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
64 #define NUMBER 257
65 #define STRING 258
66 #define DATA 259
67 #define BOOLEAN 260
68 #define SYNTAX_ERROR 261
69
70 #line 54 "OSUnserialize.y"
71
72 #include <libkern/c++/OSMetaClass.h>
73 #include <libkern/c++/OSContainers.h>
74 #include <libkern/c++/OSLib.h>
75
76 typedef struct object {
77 struct object *next;
78 struct object *prev;
79 void *object;
80 int size; // for data
81 union {
82 void *key; // for dictionary
83 long long offset; // for offset
84 } u;
85
86 } object_t;
87
88 static int yyparse();
89 static int yyerror(char *s);
90 static int yylex();
91
92 static object_t * newObject();
93 static void freeObject(object_t *o);
94
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);
102
103 static void rememberObject(int, object_t *);
104 static OSObject *retrieveObject(int);
105
106 // temp variable to use during parsing
107 static object_t *o;
108
109 // resultant object of parsed text
110 static OSObject *parsedObject;
111
112 #define YYSTYPE object_t *
113
114 extern "C" {
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);
118 } /* extern "C" */
119
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)
123
124 #ifndef YYSTYPE
125 #define YYSTYPE int
126 #endif
127 #include <stddef.h>
128
129 #ifndef __cplusplus
130 #ifndef __STDC__
131 #define const
132 #endif
133 #endif
134
135
136
137 #define YYFINAL 43
138 #define YYFLAG -32768
139 #define YYNTBASE 19
140
141 #define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 31)
142
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,
170 7
171 };
172
173 #if YYDEBUG != 0
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
178 };
179
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,
188 6, 0
189 };
190
191 #endif
192
193 #if YYDEBUG != 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
198 };
199 #endif
200
201
202 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
203
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
208 };
209 #endif
210
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
215 };
216
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,
220 3, 1, 3, 3, 1, 1, 1
221 };
222
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,
228 0, 0, 0
229 };
230
231 static const short yydefgoto[] = { 41,
232 21, 11, 22, 23, 12, 13, 26, 14, 15, 16,
233 17
234 };
235
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,
241 40, 44,-32768
242 };
243
244 static const short yypgoto[] = {-32768,
245 0,-32768,-32768, 23,-32768,-32768, 38,-32768,-32768,-32768,
246 -32768
247 };
248
249
250 #define YYLAST 87
251
252
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,
262 7, 0, 0, 0, 8, 0, 9
263 };
264
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
275 };
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. */
279
280 /* Skeleton output parser for bison,
281 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
282
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)
286 any later version.
287
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.
292
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. */
297
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. */
302
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. */
307
308 #ifndef YYSTACK_USE_ALLOCA
309 #ifdef alloca
310 #define YYSTACK_USE_ALLOCA
311 #else /* alloca not defined */
312 #ifdef __GNUC__
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
318 #include <alloca.h>
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. */
326 #include <malloc.h>
327 #endif
328 #else /* not MSDOS, or __TURBOC__ */
329 #if defined(_AIX)
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> */
333 #pragma alloca
334 #define YYSTACK_USE_ALLOCA
335 #else /* not MSDOS, or __TURBOC__, or _AIX */
336 #if 0
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
341 #endif /* __hpux */
342 #endif
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 */
349
350 #ifdef YYSTACK_USE_ALLOCA
351 #define YYSTACK_ALLOC alloca
352 #else
353 #define YYSTACK_ALLOC malloc
354 #endif
355
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. */
359
360 #define yyerrok (yyerrstatus = 0)
361 #define yyclearin (yychar = YYEMPTY)
362 #define YYEMPTY -2
363 #define YYEOF 0
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) \
374 do \
375 if (yychar == YYEMPTY && yylen == 1) \
376 { yychar = (token), yylval = (value); \
377 yychar1 = YYTRANSLATE (yychar); \
378 YYPOPSTACK; \
379 goto yybackup; \
380 } \
381 else \
382 { yyerror ("syntax error: cannot back up"); YYERROR; } \
383 while (0)
384
385 #define YYTERROR 1
386 #define YYERRCODE 256
387
388 #ifndef YYPURE
389 #define YYLEX yylex()
390 #endif
391
392 #ifdef YYPURE
393 #ifdef YYLSP_NEEDED
394 #ifdef YYLEX_PARAM
395 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
396 #else
397 #define YYLEX yylex(&yylval, &yylloc)
398 #endif
399 #else /* not YYLSP_NEEDED */
400 #ifdef YYLEX_PARAM
401 #define YYLEX yylex(&yylval, YYLEX_PARAM)
402 #else
403 #define YYLEX yylex(&yylval)
404 #endif
405 #endif /* not YYLSP_NEEDED */
406 #endif
407
408 /* If nonreentrant, generate the variables here */
409
410 #ifndef YYPURE
411
412 int yychar; /* the lookahead symbol */
413 YYSTYPE yylval; /* the semantic value of the */
414 /* lookahead symbol */
415
416 #ifdef YYLSP_NEEDED
417 YYLTYPE yylloc; /* location data for the lookahead */
418 /* symbol */
419 #endif
420
421 int yynerrs; /* number of parse errors so far */
422 #endif /* not YYPURE */
423
424 #if YYDEBUG != 0
425 int yydebug; /* nonzero means print parse trace */
426 /* Since this is uninitialized, it does not stop multiple parsers
427 from coexisting. */
428 #endif
429
430 /* YYINITDEPTH indicates the initial size of the parser's stacks */
431
432 #ifndef YYINITDEPTH
433 #define YYINITDEPTH 200
434 #endif
435
436 /* YYMAXDEPTH is the maximum size the stacks can grow to
437 (effective only if the built-in stack extension method is used). */
438
439 #if YYMAXDEPTH == 0
440 #undef YYMAXDEPTH
441 #endif
442
443 #ifndef YYMAXDEPTH
444 #define YYMAXDEPTH 10000
445 #endif
446 \f
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. */
451
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++ */
455 #ifndef __cplusplus
456
457 /* This is the most reliable way to avoid incompatibilities
458 in available built-in functions on various systems. */
459 static void
460 __yy_memcpy (to, from, count)
461 char *to;
462 char *from;
463 unsigned int count;
464 {
465 register char *f = from;
466 register char *t = to;
467 register int i = count;
468
469 while (i-- > 0)
470 *t++ = *f++;
471 }
472
473 #else /* __cplusplus */
474
475 /* This is the most reliable way to avoid incompatibilities
476 in available built-in functions on various systems. */
477 static void
478 __yy_memcpy (char *to, char *from, unsigned int count)
479 {
480 register char *t = to;
481 register char *f = from;
482 register int i = count;
483
484 while (i-- > 0)
485 *t++ = *f++;
486 }
487
488 #endif
489 #endif
490 \f
491 #line 217 "/usr/share/bison.simple"
492
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. */
498
499 #ifdef YYPARSE_PARAM
500 #ifdef __cplusplus
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 */
511
512 /* Prevent warning if -Wstrict-prototypes. */
513 #ifdef __GNUC__
514 #ifdef YYPARSE_PARAM
515 int yyparse (void *);
516 #else
517 int yyparse (void);
518 #endif
519 #endif
520
521 int
522 yyparse(YYPARSE_PARAM_ARG)
523 YYPARSE_PARAM_DECL
524 {
525 register int yystate;
526 register int yyn;
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 */
531
532 short yyssa[YYINITDEPTH]; /* the state stack */
533 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
534
535 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
536 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
537
538 #ifdef YYLSP_NEEDED
539 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
540 YYLTYPE *yyls = yylsa;
541 YYLTYPE *yylsp;
542
543 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
544 #else
545 #define YYPOPSTACK (yyvsp--, yyssp--)
546 #endif
547
548 int yystacksize = YYINITDEPTH;
549 int yyfree_stacks = 0;
550
551 #ifdef YYPURE
552 int yychar;
553 YYSTYPE yylval;
554 int yynerrs;
555 #ifdef YYLSP_NEEDED
556 YYLTYPE yylloc;
557 #endif
558 #endif
559
560 YYSTYPE yyval; /* the variable used to return */
561 /* semantic values from the action */
562 /* routines */
563
564 int yylen;
565
566 #if YYDEBUG != 0
567 if (yydebug)
568 fprintf(stderr, "Starting parse\n");
569 #endif
570
571 yystate = 0;
572 yyerrstatus = 0;
573 yynerrs = 0;
574 yychar = YYEMPTY; /* Cause a token to be read. */
575
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. */
580
581 yyssp = yyss - 1;
582 yyvsp = yyvs;
583 #ifdef YYLSP_NEEDED
584 yylsp = yyls;
585 #endif
586
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. */
590 yynewstate:
591
592 *++yyssp = yystate;
593
594 if (yyssp >= yyss + yystacksize - 1)
595 {
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;
599 short *yyss1 = yyss;
600 #ifdef YYLSP_NEEDED
601 YYLTYPE *yyls1 = yyls;
602 #endif
603
604 /* Get the current used size of the three stacks, in elements. */
605 int size = yyssp - yyss + 1;
606
607 #ifdef yyoverflow
608 /* Each stack pointer address is followed by the size of
609 the data in use in that stack, in bytes. */
610 #ifdef YYLSP_NEEDED
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),
617 &yystacksize);
618 #else
619 yyoverflow("parser stack overflow",
620 &yyss1, size * sizeof (*yyssp),
621 &yyvs1, size * sizeof (*yyvsp),
622 &yystacksize);
623 #endif
624
625 yyss = yyss1; yyvs = yyvs1;
626 #ifdef YYLSP_NEEDED
627 yyls = yyls1;
628 #endif
629 #else /* no yyoverflow */
630 /* Extend the stack our own way. */
631 if (yystacksize >= YYMAXDEPTH)
632 {
633 yyerror("parser stack overflow");
634 if (yyfree_stacks)
635 {
636 free (yyss);
637 free (yyvs);
638 #ifdef YYLSP_NEEDED
639 free (yyls);
640 #endif
641 }
642 return 2;
643 }
644 yystacksize *= 2;
645 if (yystacksize > YYMAXDEPTH)
646 yystacksize = YYMAXDEPTH;
647 #ifndef YYSTACK_USE_ALLOCA
648 yyfree_stacks = 1;
649 #endif
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));
656 #ifdef YYLSP_NEEDED
657 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
658 __yy_memcpy ((char *)yyls, (char *)yyls1,
659 size * (unsigned int) sizeof (*yylsp));
660 #endif
661 #endif /* no yyoverflow */
662
663 yyssp = yyss + size - 1;
664 yyvsp = yyvs + size - 1;
665 #ifdef YYLSP_NEEDED
666 yylsp = yyls + size - 1;
667 #endif
668
669 #if YYDEBUG != 0
670 if (yydebug)
671 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
672 #endif
673
674 if (yyssp >= yyss + yystacksize - 1)
675 YYABORT;
676 }
677
678 #if YYDEBUG != 0
679 if (yydebug)
680 fprintf(stderr, "Entering state %d\n", yystate);
681 #endif
682
683 goto yybackup;
684 yybackup:
685
686 /* Do appropriate processing given the current state. */
687 /* Read a lookahead token if we need one and don't already have one. */
688 /* yyresume: */
689
690 /* First try to decide what to do without reference to lookahead token. */
691
692 yyn = yypact[yystate];
693 if (yyn == YYFLAG)
694 goto yydefault;
695
696 /* Not known => get a lookahead token if don't already have one. */
697
698 /* yychar is either YYEMPTY or YYEOF
699 or a valid token in external form. */
700
701 if (yychar == YYEMPTY)
702 {
703 #if YYDEBUG != 0
704 if (yydebug)
705 fprintf(stderr, "Reading a token: ");
706 #endif
707 yychar = YYLEX;
708 }
709
710 /* Convert token to internal form (in yychar1) for indexing tables with */
711
712 if (yychar <= 0) /* This means end of input. */
713 {
714 yychar1 = 0;
715 yychar = YYEOF; /* Don't call YYLEX any more */
716
717 #if YYDEBUG != 0
718 if (yydebug)
719 fprintf(stderr, "Now at end of input.\n");
720 #endif
721 }
722 else
723 {
724 yychar1 = YYTRANSLATE(yychar);
725
726 #if YYDEBUG != 0
727 if (yydebug)
728 {
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. */
732 #ifdef YYPRINT
733 YYPRINT (stderr, yychar, yylval);
734 #endif
735 fprintf (stderr, ")\n");
736 }
737 #endif
738 }
739
740 yyn += yychar1;
741 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
742 goto yydefault;
743
744 yyn = yytable[yyn];
745
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,
750 just return success.
751 0, or most negative number => error. */
752
753 if (yyn < 0)
754 {
755 if (yyn == YYFLAG)
756 goto yyerrlab;
757 yyn = -yyn;
758 goto yyreduce;
759 }
760 else if (yyn == 0)
761 goto yyerrlab;
762
763 if (yyn == YYFINAL)
764 YYACCEPT;
765
766 /* Shift the lookahead token. */
767
768 #if YYDEBUG != 0
769 if (yydebug)
770 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
771 #endif
772
773 /* Discard the token being shifted unless it is eof. */
774 if (yychar != YYEOF)
775 yychar = YYEMPTY;
776
777 *++yyvsp = yylval;
778 #ifdef YYLSP_NEEDED
779 *++yylsp = yylloc;
780 #endif
781
782 /* count tokens shifted since error; after three, turn off error status. */
783 if (yyerrstatus) yyerrstatus--;
784
785 yystate = yyn;
786 goto yynewstate;
787
788 /* Do the default action for the current state. */
789 yydefault:
790
791 yyn = yydefact[yystate];
792 if (yyn == 0)
793 goto yyerrlab;
794
795 /* Do a reduction. yyn is the number of a rule to reduce with. */
796 yyreduce:
797 yylen = yyr2[yyn];
798 if (yylen > 0)
799 yyval = yyvsp[1-yylen]; /* implement default value of the action */
800
801 #if YYDEBUG != 0
802 if (yydebug)
803 {
804 int i;
805
806 fprintf (stderr, "Reducing via rule %d (line %d), ",
807 yyn, yyrline[yyn]);
808
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]]);
813 }
814 #endif
815
816
817 switch (yyn) {
818
819 case 1:
820 #line 116 "OSUnserialize.y"
821 { parsedObject = (OSObject *)NULL; YYACCEPT; ;
822 break;}
823 case 2:
824 #line 117 "OSUnserialize.y"
825 { parsedObject = (OSObject *)yyvsp[0]; YYACCEPT; ;
826 break;}
827 case 3:
828 #line 118 "OSUnserialize.y"
829 { yyerror("syntax error"); YYERROR; ;
830 break;}
831 case 4:
832 #line 121 "OSUnserialize.y"
833 { yyval = (object_t *)buildOSDictionary(yyvsp[0]); ;
834 break;}
835 case 5:
836 #line 122 "OSUnserialize.y"
837 { yyval = (object_t *)buildOSArray(yyvsp[0]); ;
838 break;}
839 case 6:
840 #line 123 "OSUnserialize.y"
841 { yyval = (object_t *)buildOSSet(yyvsp[0]); ;
842 break;}
843 case 7:
844 #line 124 "OSUnserialize.y"
845 { yyval = (object_t *)buildOSString(yyvsp[0]); ;
846 break;}
847 case 8:
848 #line 125 "OSUnserialize.y"
849 { yyval = (object_t *)buildOSData(yyvsp[0]); ;
850 break;}
851 case 9:
852 #line 126 "OSUnserialize.y"
853 { yyval = (object_t *)buildOSOffset(yyvsp[0]); ;
854 break;}
855 case 10:
856 #line 127 "OSUnserialize.y"
857 { yyval = (object_t *)buildOSBoolean(yyvsp[0]); ;
858 break;}
859 case 11:
860 #line 128 "OSUnserialize.y"
861 { yyval = (object_t *)retrieveObject(yyvsp[0]->u.offset);
862 if (yyval) {
863 ((OSObject *)yyval)->retain();
864 } else {
865 yyerror("forward reference detected");
866 YYERROR;
867 }
868 freeObject(yyvsp[0]);
869 ;
870 break;}
871 case 12:
872 #line 137 "OSUnserialize.y"
873 { yyval = yyvsp[-2];
874 rememberObject(yyvsp[0]->u.offset, yyvsp[-2]);
875 freeObject(yyvsp[0]);
876 ;
877 break;}
878 case 13:
879 #line 145 "OSUnserialize.y"
880 { yyval = NULL; ;
881 break;}
882 case 14:
883 #line 146 "OSUnserialize.y"
884 { yyval = yyvsp[-1]; ;
885 break;}
886 case 16:
887 #line 150 "OSUnserialize.y"
888 { yyvsp[0]->next = yyvsp[-1]; yyvsp[-1]->prev = yyvsp[0]; yyval = yyvsp[0]; ;
889 break;}
890 case 17:
891 #line 153 "OSUnserialize.y"
892 { yyval = newObject();
893 yyval->next = NULL;
894 yyval->prev = NULL;
895 yyval->u.key = yyvsp[-3];
896 yyval->object = yyvsp[-1];
897 ;
898 break;}
899 case 18:
900 #line 163 "OSUnserialize.y"
901 { yyval = NULL; ;
902 break;}
903 case 19:
904 #line 164 "OSUnserialize.y"
905 { yyval = yyvsp[-1]; ;
906 break;}
907 case 20:
908 #line 167 "OSUnserialize.y"
909 { yyval = NULL; ;
910 break;}
911 case 21:
912 #line 168 "OSUnserialize.y"
913 { yyval = yyvsp[-1]; ;
914 break;}
915 case 22:
916 #line 171 "OSUnserialize.y"
917 { yyval = newObject();
918 yyval->object = yyvsp[0];
919 yyval->next = NULL;
920 yyval->prev = NULL;
921 ;
922 break;}
923 case 23:
924 #line 176 "OSUnserialize.y"
925 { o = newObject();
926 o->object = yyvsp[0];
927 o->next = yyvsp[-2];
928 o->prev = NULL;
929 yyvsp[-2]->prev = o;
930 yyval = o;
931 ;
932 break;}
933 case 24:
934 #line 187 "OSUnserialize.y"
935 { yyval = yyvsp[-2];
936 yyval->size = yyvsp[0]->u.offset;
937 freeObject(yyvsp[0]);
938 ;
939 break;}
940 }
941 /* the action file gets copied in in place of this dollarsign */
942 #line 543 "/usr/share/bison.simple"
943 \f
944 yyvsp -= yylen;
945 yyssp -= yylen;
946 #ifdef YYLSP_NEEDED
947 yylsp -= yylen;
948 #endif
949
950 #if YYDEBUG != 0
951 if (yydebug)
952 {
953 short *ssp1 = yyss - 1;
954 fprintf (stderr, "state stack now");
955 while (ssp1 != yyssp)
956 fprintf (stderr, " %d", *++ssp1);
957 fprintf (stderr, "\n");
958 }
959 #endif
960
961 *++yyvsp = yyval;
962
963 #ifdef YYLSP_NEEDED
964 yylsp++;
965 if (yylen == 0)
966 {
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;
971 yylsp->text = 0;
972 }
973 else
974 {
975 yylsp->last_line = (yylsp+yylen-1)->last_line;
976 yylsp->last_column = (yylsp+yylen-1)->last_column;
977 }
978 #endif
979
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. */
984
985 yyn = yyr1[yyn];
986
987 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
988 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
989 yystate = yytable[yystate];
990 else
991 yystate = yydefgoto[yyn - YYNTBASE];
992
993 goto yynewstate;
994
995 yyerrlab: /* here on detecting error */
996
997 if (! yyerrstatus)
998 /* If not already recovering from an error, report this error. */
999 {
1000 ++yynerrs;
1001
1002 #ifdef YYERROR_VERBOSE
1003 yyn = yypact[yystate];
1004
1005 if (yyn > YYFLAG && yyn < YYLAST)
1006 {
1007 int size = 0;
1008 char *msg;
1009 int x, count;
1010
1011 count = 0;
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);
1018 if (msg != 0)
1019 {
1020 strcpy(msg, "parse error");
1021
1022 if (count < 5)
1023 {
1024 count = 0;
1025 for (x = (yyn < 0 ? -yyn : 0);
1026 x < (sizeof(yytname) / sizeof(char *)); x++)
1027 if (yycheck[x + yyn] == x)
1028 {
1029 strcat(msg, count == 0 ? ", expecting `" : " or `");
1030 strcat(msg, yytname[x]);
1031 strcat(msg, "'");
1032 count++;
1033 }
1034 }
1035 yyerror(msg);
1036 free(msg);
1037 }
1038 else
1039 yyerror ("parse error; also virtual memory exceeded");
1040 }
1041 else
1042 #endif /* YYERROR_VERBOSE */
1043 yyerror("parse error");
1044 }
1045
1046 goto yyerrlab1;
1047 yyerrlab1: /* here on error raised explicitly by an action */
1048
1049 if (yyerrstatus == 3)
1050 {
1051 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1052
1053 /* return failure if at end of input */
1054 if (yychar == YYEOF)
1055 YYABORT;
1056
1057 #if YYDEBUG != 0
1058 if (yydebug)
1059 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1060 #endif
1061
1062 yychar = YYEMPTY;
1063 }
1064
1065 /* Else will try to reuse lookahead token
1066 after shifting the error token. */
1067
1068 yyerrstatus = 3; /* Each real token shifted decrements this */
1069
1070 goto yyerrhandle;
1071
1072 yyerrdefault: /* current state does not do anything special for the error token. */
1073
1074 #if 0
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;
1079 #endif
1080
1081 yyerrpop: /* pop the current state because it cannot handle the error token */
1082
1083 if (yyssp == yyss) YYABORT;
1084 yyvsp--;
1085 yystate = *--yyssp;
1086 #ifdef YYLSP_NEEDED
1087 yylsp--;
1088 #endif
1089
1090 #if YYDEBUG != 0
1091 if (yydebug)
1092 {
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");
1098 }
1099 #endif
1100
1101 yyerrhandle:
1102
1103 yyn = yypact[yystate];
1104 if (yyn == YYFLAG)
1105 goto yyerrdefault;
1106
1107 yyn += YYTERROR;
1108 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1109 goto yyerrdefault;
1110
1111 yyn = yytable[yyn];
1112 if (yyn < 0)
1113 {
1114 if (yyn == YYFLAG)
1115 goto yyerrpop;
1116 yyn = -yyn;
1117 goto yyreduce;
1118 }
1119 else if (yyn == 0)
1120 goto yyerrpop;
1121
1122 if (yyn == YYFINAL)
1123 YYACCEPT;
1124
1125 #if YYDEBUG != 0
1126 if (yydebug)
1127 fprintf(stderr, "Shifting error token, ");
1128 #endif
1129
1130 *++yyvsp = yylval;
1131 #ifdef YYLSP_NEEDED
1132 *++yylsp = yylloc;
1133 #endif
1134
1135 yystate = yyn;
1136 goto yynewstate;
1137
1138 yyacceptlab:
1139 /* YYACCEPT comes here. */
1140 if (yyfree_stacks)
1141 {
1142 free (yyss);
1143 free (yyvs);
1144 #ifdef YYLSP_NEEDED
1145 free (yyls);
1146 #endif
1147 }
1148 return 0;
1149
1150 yyabortlab:
1151 /* YYABORT comes here. */
1152 if (yyfree_stacks)
1153 {
1154 free (yyss);
1155 free (yyvs);
1156 #ifdef YYLSP_NEEDED
1157 free (yyls);
1158 #endif
1159 }
1160 return 1;
1161 }
1162 #line 208 "OSUnserialize.y"
1163
1164
1165 static int lineNumber = 0;
1166 static const char *parseBuffer;
1167 static int parseBufferIndex;
1168
1169 #define currentChar() (parseBuffer[parseBufferIndex])
1170 #define nextChar() (parseBuffer[++parseBufferIndex])
1171 #define prevChar() (parseBuffer[parseBufferIndex - 1])
1172
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) == '-'))
1179
1180 static char yyerror_message[128];
1181
1182 int
1183 yyerror(char *s) /* Called by yyparse on error */
1184 {
1185 sprintf(yyerror_message, "OSUnserialize: %s near line %d\n", s, lineNumber);
1186 return 0;
1187 }
1188
1189 int
1190 yylex()
1191 {
1192 int c;
1193
1194 if (parseBufferIndex == 0) lineNumber = 1;
1195
1196 top:
1197 c = currentChar();
1198
1199 /* skip white space */
1200 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
1201
1202 /* skip over comments */
1203 if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {};
1204
1205 /* keep track of line number, don't return \n's */
1206 if (c == '\n') {
1207 lineNumber++;
1208 (void)nextChar();
1209 goto top;
1210 }
1211
1212 /* parse boolean */
1213 if (c == '.') {
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;
1219 boolean = true;
1220 } else {
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;
1226 }
1227 if (nextChar() != '.') return SYNTAX_ERROR;
1228 /* skip over dot */
1229 (void)nextChar();
1230
1231 yylval = (object_t *)boolean;
1232 return BOOLEAN;
1233 }
1234
1235 /* parse unquoted string */
1236 if (isAlpha(c)) {
1237 int start, length;
1238 char * tempString;
1239
1240 start = parseBufferIndex;
1241 /* find end of string */
1242 while (isAlphaNumeric(c)) {
1243 c = nextChar();
1244 }
1245 length = parseBufferIndex - start;
1246
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");
1251 return 0;
1252 }
1253 bcopy(&parseBuffer[start], tempString, length);
1254 tempString[length] = 0;
1255 yylval = (object_t *)tempString;
1256 return STRING;
1257 }
1258
1259 /* parse quoted string */
1260 if (c == '"' || c == '\'') {
1261 int start, length;
1262 char * tempString;
1263 char quoteChar = c;
1264
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;
1271 }
1272 length = parseBufferIndex - start;
1273 /* skip over trailing quote */
1274 (void)nextChar();
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");
1279 return 0;
1280 }
1281
1282 int to = 0;
1283 for (int from=start; from < parseBufferIndex; from++) {
1284 // hack - skip over backslashes
1285 if (parseBuffer[from] == '\\') {
1286 length--;
1287 continue;
1288 }
1289 tempString[to] = parseBuffer[from];
1290 to++;
1291 }
1292 tempString[length] = 0;
1293 yylval = (object_t *)tempString;
1294 return STRING;
1295 }
1296
1297 /* process numbers */
1298 if (isDigit (c))
1299 {
1300 unsigned long long n = 0;
1301 int base = 10;
1302
1303 if (c == '0') {
1304 c = nextChar();
1305 if (c == 'x') {
1306 base = 16;
1307 c = nextChar();
1308 }
1309 }
1310 if (base == 10) {
1311 while(isDigit(c)) {
1312 n = (n * base + c - '0');
1313 c = nextChar();
1314 }
1315 } else {
1316 while(isHexDigit(c)) {
1317 if (isDigit(c)) {
1318 n = (n * base + c - '0');
1319 } else {
1320 n = (n * base + 0xa + c - 'a');
1321 }
1322 c = nextChar();
1323 }
1324 }
1325
1326 yylval = newObject();
1327 yylval->u.offset = n;
1328
1329 return NUMBER;
1330 }
1331
1332 #define OSDATA_ALLOC_SIZE 4096
1333
1334 /* process data */
1335 if (c == '<') {
1336 unsigned char *d, *start, *lastStart;
1337
1338 start = lastStart = d = (unsigned char *)malloc(OSDATA_ALLOC_SIZE);
1339 c = nextChar(); // skip over '<'
1340 while (c != 0 && c != '>') {
1341
1342 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
1343 if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {};
1344 if (c == '\n') {
1345 lineNumber++;
1346 c = nextChar();
1347 continue;
1348 }
1349
1350 // get high nibble
1351 if (!isHexDigit(c)) break;
1352 if (isDigit(c)) {
1353 *d = (c - '0') << 4;
1354 } else {
1355 *d = (0xa + (c - 'a')) << 4;
1356 }
1357
1358 // get low nibble
1359 c = nextChar();
1360 if (!isHexDigit(c)) break;
1361 if (isDigit(c)) {
1362 *d |= c - '0';
1363 } else {
1364 *d |= 0xa + (c - 'a');
1365 }
1366
1367 d++;
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;
1372 }
1373 c = nextChar();
1374 }
1375 if (c != '>' ) {
1376 free(start);
1377 return SYNTAX_ERROR;
1378 }
1379
1380 // got it!
1381 yylval = newObject();
1382 yylval->object = start;
1383 yylval->size = d - start;
1384
1385 (void)nextChar(); // skip over '>'
1386 return DATA;
1387 }
1388
1389
1390 /* return single chars, move pointer to next char */
1391 (void)nextChar();
1392 return c;
1393 }
1394
1395 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1396 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1397 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1398
1399 #ifdef DEBUG
1400 int debugUnserializeAllocCount = 0;
1401 #endif
1402
1403 object_t *
1404 newObject()
1405 {
1406 #ifdef DEBUG
1407 debugUnserializeAllocCount++;
1408 #endif
1409 return (object_t *)malloc(sizeof(object_t));
1410 }
1411
1412 void
1413 freeObject(object_t *o)
1414 {
1415 #ifdef DEBUG
1416 debugUnserializeAllocCount--;
1417 #endif
1418 free(o);
1419 }
1420
1421 static OSDictionary *tags;
1422
1423 static void
1424 rememberObject(int tag, object_t *o)
1425 {
1426 char key[16];
1427 sprintf(key, "%u", tag);
1428
1429 tags->setObject(key, (OSObject *)o);
1430 }
1431
1432 static OSObject *
1433 retrieveObject(int tag)
1434 {
1435 char key[16];
1436 sprintf(key, "%u", tag);
1437
1438 return tags->getObject(key);
1439 }
1440
1441 OSObject *
1442 buildOSDictionary(object_t *o)
1443 {
1444 object_t *temp, *last = o;
1445 int count = 0;
1446
1447 // get count and last object
1448 while (o) {
1449 count++;
1450 last = o;
1451 o = o->next;
1452 }
1453 o = last;
1454
1455 OSDictionary *d = OSDictionary::withCapacity(count);
1456
1457 while (o) {
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);
1462 } else {
1463 // If it isn't a symbol, I hope it's a string!
1464 d->setObject((OSString *)o->u.key, (OSObject *)o->object);
1465 }
1466 #else
1467 d->setObject((OSString *)o->u.key, (OSObject *)o->object);
1468 #endif
1469 ((OSObject *)o->object)->release();
1470 ((OSObject *)o->u.key)->release();
1471 temp = o;
1472 o = o->prev;
1473 freeObject(temp);
1474 }
1475 return d;
1476 };
1477
1478 OSObject *
1479 buildOSArray(object_t *o)
1480 {
1481 object_t *temp, *last = o;
1482 int count = 0;
1483
1484 // get count and last object
1485 while (o) {
1486 count++;
1487 last = o;
1488 o = o->next;
1489 }
1490 o = last;
1491
1492 OSArray *a = OSArray::withCapacity(count);
1493
1494 while (o) {
1495 a->setObject((OSObject *)o->object);
1496 ((OSObject *)o->object)->release();
1497 temp = o;
1498 o = o->prev;
1499 freeObject(temp);
1500 }
1501 return a;
1502 };
1503
1504 OSObject *
1505 buildOSSet(object_t *o)
1506 {
1507 OSArray *a = (OSArray *)buildOSArray(o);
1508 OSSet *s = OSSet::withArray(a, a->getCapacity());
1509
1510 a->release();
1511 return s;
1512 };
1513
1514 OSObject *
1515 buildOSString(object_t *o)
1516 {
1517 OSString *s = OSString::withCString((char *)o);
1518
1519 free(o);
1520
1521 return s;
1522 };
1523
1524 OSObject *
1525 buildOSData(object_t *o)
1526 {
1527 OSData *d;
1528
1529 if (o->size) {
1530 d = OSData::withBytes(o->object, o->size);
1531 } else {
1532 d = OSData::withCapacity(0);
1533 }
1534 free(o->object);
1535 freeObject(o);
1536 return d;
1537 };
1538
1539 OSObject *
1540 buildOSOffset(object_t *o)
1541 {
1542 OSNumber *off = OSNumber::withNumber(o->u.offset, o->size);
1543 freeObject(o);
1544 return off;
1545 };
1546
1547 OSObject *
1548 buildOSBoolean(object_t *o)
1549 {
1550 OSBoolean *b = OSBoolean::withBoolean((bool)o);
1551 return b;
1552 };
1553
1554 __BEGIN_DECLS
1555 #include <kern/lock.h>
1556 __END_DECLS
1557
1558 static mutex_t *lock = 0;
1559
1560 OSObject*
1561 OSUnserialize(const char *buffer, OSString **errorString)
1562 {
1563 OSObject *object;
1564
1565 if (!lock) {
1566 lock = mutex_alloc(ETAP_IO_AHA);
1567 mutex_lock(lock);
1568 } else {
1569 mutex_lock(lock);
1570
1571 }
1572
1573 #ifdef DEBUG
1574 debugUnserializeAllocCount = 0;
1575 #endif
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;
1583 } else {
1584 object = 0;
1585 if (errorString)
1586 *errorString = OSString::withCString(yyerror_message);
1587 }
1588
1589 tags->release();
1590 #ifdef DEBUG
1591 if (debugUnserializeAllocCount) {
1592 printf("OSUnserialize: allocation check failed, count = %d.\n",
1593 debugUnserializeAllocCount);
1594 }
1595 #endif
1596 mutex_unlock(lock);
1597
1598 return object;
1599 }
1600
1601
1602 //
1603 //
1604 //
1605 //
1606 //
1607 // DO NOT EDIT OSUnserialize.cpp!
1608 //
1609 // this means you!
1610 //
1611 //
1612 //
1613 //
1614 //