]> git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSUnserialize.cpp
xnu-7195.50.7.100.1.tar.gz
[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 /* A Bison parser, made by GNU Bison 2.3. */
52
53 /* Skeleton implementation for Bison's Yacc-like parsers in C
54 *
55 * Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
56 * Free Software Foundation, Inc.
57 *
58 * This program is free software; you can redistribute it and/or modify
59 * it under the terms of the GNU General Public License as published by
60 * the Free Software Foundation; either version 2, or (at your option)
61 * any later version.
62 *
63 * This program is distributed in the hope that it will be useful,
64 * but WITHOUT ANY WARRANTY; without even the implied warranty of
65 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66 * GNU General Public License for more details.
67 *
68 * You should have received a copy of the GNU General Public License
69 * along with this program; if not, write to the Free Software
70 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
71 * Boston, MA 02110-1301, USA. */
72
73 /* As a special exception, you may create a larger work that contains
74 * part or all of the Bison parser skeleton and distribute that work
75 * under terms of your choice, so long as that work isn't itself a
76 * parser generator using the skeleton or a modified version thereof
77 * as a parser skeleton. Alternatively, if you modify or redistribute
78 * the parser skeleton itself, you may (at your option) remove this
79 * special exception, which will cause the skeleton and the resulting
80 * Bison output files to be licensed under the GNU General Public
81 * License without this special exception.
82 *
83 * This special exception was added by the Free Software Foundation in
84 * version 2.2 of Bison. */
85
86 /* C LALR(1) parser skeleton written by Richard Stallman, by
87 * simplifying the original so-called "semantic" parser. */
88
89 /* All symbols defined below should begin with yy or YY, to avoid
90 * infringing on user name space. This should be done even for local
91 * variables, as they might otherwise be expanded by user macros.
92 * There are some unavoidable exceptions within include files to
93 * define necessary library symbols; they are noted "INFRINGES ON
94 * USER NAME SPACE" below. */
95
96 /* Identify Bison output. */
97 #define YYBISON 1
98
99 /* Bison version. */
100 #define YYBISON_VERSION "2.3"
101
102 /* Skeleton name. */
103 #define YYSKELETON_NAME "yacc.c"
104
105 /* Pure parsers. */
106 #define YYPURE 0
107
108 /* Using locations. */
109 #define YYLSP_NEEDED 0
110
111 /* Substitute the variable and function names. */
112 #define yyparse OSUnserializeparse
113 #define yylex OSUnserializelex
114 #define yyerror OSUnserializeerror
115 #define yylval OSUnserializelval
116 #define yychar OSUnserializechar
117 #define yydebug OSUnserializedebug
118 #define yynerrs OSUnserializenerrs
119
120
121 /* Tokens. */
122 #ifndef YYTOKENTYPE
123 # define YYTOKENTYPE
124 /* Put the tokens into the symbol table, so that GDB and other debuggers
125 * know about them. */
126 enum yytokentype {
127 NUMBER = 258,
128 STRING = 259,
129 DATA = 260,
130 BOOLEAN = 261,
131 SYNTAX_ERROR = 262
132 };
133 #endif
134 /* Tokens. */
135 #define NUMBER 258
136 #define STRING 259
137 #define DATA 260
138 #define BOOLEAN 261
139 #define SYNTAX_ERROR 262
140
141
142
143
144 /* Copy the first part of user declarations. */
145 #line 60 "OSUnserialize.y"
146
147 #include <libkern/c++/OSMetaClass.h>
148 #include <libkern/c++/OSContainers.h>
149 #include <libkern/c++/OSLib.h>
150
151 typedef struct object {
152 struct object *next;
153 struct object *prev;
154 void *object;
155 int size; // for data
156 union {
157 void *key; // for dictionary
158 long long offset; // for offset
159 } u;
160 } object_t;
161
162 static int yyerror(const char *s);
163 static int yylex();
164
165 static object_t * newObject();
166 static void freeObject(object_t *o);
167
168 static OSObject *buildOSDictionary(object_t *);
169 static OSObject *buildOSArray(object_t *);
170 static OSObject *buildOSSet(object_t *);
171 static OSObject *buildOSString(object_t *);
172 static OSObject *buildOSData(object_t *);
173 static OSObject *buildOSOffset(object_t *);
174 static OSObject *buildOSBoolean(object_t *o);
175
176 static void rememberObject(int, object_t *);
177 static OSObject *retrieveObject(int);
178
179 // temp variable to use during parsing
180 static object_t *oo;
181
182 // resultant object of parsed text
183 static OSObject *parsedObject;
184
185 #define YYSTYPE object_t *
186
187 __BEGIN_DECLS
188 #include <kern/kalloc.h>
189 __END_DECLS
190
191 #define malloc(size) malloc_impl(size)
192 static inline void *
193 malloc_impl(size_t size)
194 {
195 if (size == 0) {
196 return NULL;
197 }
198 return kheap_alloc_tag_bt(KHEAP_DEFAULT, size,
199 (zalloc_flags_t) (Z_WAITOK | Z_ZERO),
200 VM_KERN_MEMORY_LIBKERN);
201 }
202
203 #define free(addr) free_impl(addr)
204 static inline void
205 free_impl(void *addr)
206 {
207 kheap_free_addr(KHEAP_DEFAULT, addr);
208 }
209 static inline void
210 safe_free(void *addr, size_t size)
211 {
212 if (addr) {
213 assert(size != 0);
214 kheap_free(KHEAP_DEFAULT, addr, size);
215 }
216 }
217
218 #define realloc(addr, osize, nsize) realloc_impl(addr, osize, nsize)
219 static inline void *
220 realloc_impl(void *addr, size_t osize, size_t nsize)
221 {
222 if (!addr) {
223 return malloc(nsize);
224 }
225 if (nsize == osize) {
226 return addr;
227 }
228 void *nmem = malloc(nsize);
229 if (!nmem) {
230 safe_free(addr, osize);
231 return NULL;
232 }
233 (void)memcpy(nmem, addr, (nsize > osize) ? osize : nsize);
234 safe_free(addr, osize);
235
236 return nmem;
237 }
238
239
240
241 /* Enabling traces. */
242 #ifndef YYDEBUG
243 # define YYDEBUG 0
244 #endif
245
246 /* Enabling verbose error messages. */
247 #ifdef YYERROR_VERBOSE
248 # undef YYERROR_VERBOSE
249 # define YYERROR_VERBOSE 1
250 #else
251 # define YYERROR_VERBOSE 0
252 #endif
253
254 /* Enabling the token table. */
255 #ifndef YYTOKEN_TABLE
256 # define YYTOKEN_TABLE 0
257 #endif
258
259 #if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED
260 typedef int YYSTYPE;
261 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
262 # define YYSTYPE_IS_DECLARED 1
263 # define YYSTYPE_IS_TRIVIAL 1
264 #endif
265
266
267
268 /* Copy the second part of user declarations. */
269
270
271 /* Line 216 of yacc.c. */
272 #line 224 "OSUnserialize.tab.c"
273
274 #ifdef short
275 # undef short
276 #endif
277
278 #ifdef YYTYPE_UINT8
279 typedef YYTYPE_UINT8 yytype_uint8;
280 #else
281 typedef unsigned char yytype_uint8;
282 #endif
283
284 #ifdef YYTYPE_INT8
285 typedef YYTYPE_INT8 yytype_int8;
286 #elif (defined __STDC__ || defined __C99__FUNC__ \
287 || defined __cplusplus || defined _MSC_VER)
288 typedef signed char yytype_int8;
289 #else
290 typedef short int yytype_int8;
291 #endif
292
293 #ifdef YYTYPE_UINT16
294 typedef YYTYPE_UINT16 yytype_uint16;
295 #else
296 typedef unsigned short int yytype_uint16;
297 #endif
298
299 #ifdef YYTYPE_INT16
300 typedef YYTYPE_INT16 yytype_int16;
301 #else
302 typedef short int yytype_int16;
303 #endif
304
305 #ifndef YYSIZE_T
306 # ifdef __SIZE_TYPE__
307 # define YYSIZE_T __SIZE_TYPE__
308 # elif defined size_t
309 # define YYSIZE_T size_t
310 # elif !defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
311 || defined __cplusplus || defined _MSC_VER)
312 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
313 # define YYSIZE_T size_t
314 # else
315 # define YYSIZE_T unsigned int
316 # endif
317 #endif
318
319 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
320
321 #ifndef YY_
322 # if defined YYENABLE_NLS && YYENABLE_NLS
323 # if ENABLE_NLS
324 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
325 # define YY_(msgid) dgettext ("bison-runtime", msgid)
326 # endif
327 # endif
328 # ifndef YY_
329 # define YY_(msgid) msgid
330 # endif
331 #endif
332
333 /* Suppress unused-variable warnings by "using" E. */
334 #if !defined lint || defined __GNUC__
335 # define YYUSE(e) ((void) (e))
336 #else
337 # define YYUSE(e) /* empty */
338 #endif
339
340 /* Identity function, used to suppress warnings about constant conditions. */
341 #ifndef lint
342 # define YYID(n) (n)
343 #else
344 #if (defined __STDC__ || defined __C99__FUNC__ \
345 || defined __cplusplus || defined _MSC_VER)
346 static int
347 YYID(int i)
348 #else
349 static int
350 YYID(i)
351 int i;
352 #endif
353 {
354 return i;
355 }
356 #endif
357
358 #if !defined yyoverflow || YYERROR_VERBOSE
359
360 /* The parser invokes alloca or malloc; define the necessary symbols. */
361
362 # ifdef YYSTACK_USE_ALLOCA
363 # if YYSTACK_USE_ALLOCA
364 # ifdef __GNUC__
365 # define YYSTACK_ALLOC __builtin_alloca
366 # elif defined __BUILTIN_VA_ARG_INCR
367 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
368 # elif defined _AIX
369 # define YYSTACK_ALLOC __alloca
370 # elif defined _MSC_VER
371 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
372 # define alloca _alloca
373 # else
374 # define YYSTACK_ALLOC alloca
375 # if !defined _ALLOCA_H && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
376 || defined __cplusplus || defined _MSC_VER)
377 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
378 # ifndef _STDLIB_H
379 # define _STDLIB_H 1
380 # endif
381 # endif
382 # endif
383 # endif
384 # endif
385
386 # ifdef YYSTACK_ALLOC
387 /* Pacify GCC's `empty if-body' warning. */
388 # define YYSTACK_FREE(Ptr) do { /* empty */ ; } while (YYID (0))
389 # ifndef YYSTACK_ALLOC_MAXIMUM
390 /* The OS might guarantee only one guard page at the bottom of the stack,
391 * and a page size can be as small as 4096 bytes. So we cannot safely
392 * invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
393 * to allow for a few compiler-allocated temporary stack slots. */
394 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
395 # endif
396 # else
397 # define YYSTACK_ALLOC YYMALLOC
398 # define YYSTACK_FREE YYFREE
399 # ifndef YYSTACK_ALLOC_MAXIMUM
400 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
401 # endif
402 # if (defined __cplusplus && !defined _STDLIB_H \
403 && !((defined YYMALLOC || defined malloc) \
404 && (defined YYFREE || defined free)))
405 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
406 # ifndef _STDLIB_H
407 # define _STDLIB_H 1
408 # endif
409 # endif
410 # ifndef YYMALLOC
411 # define YYMALLOC malloc
412 # if !defined malloc && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
413 || defined __cplusplus || defined _MSC_VER)
414 void *malloc(YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
415 # endif
416 # endif
417 # ifndef YYFREE
418 # define YYFREE free
419 # if !defined free && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
420 || defined __cplusplus || defined _MSC_VER)
421 void free(void *); /* INFRINGES ON USER NAME SPACE */
422 # endif
423 # endif
424 # endif
425 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
426
427
428 #if (!defined yyoverflow \
429 && (!defined __cplusplus \
430 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
431
432 /* A type that is properly aligned for any stack member. */
433 union yyalloc {
434 yytype_int16 yyss;
435 YYSTYPE yyvs;
436 };
437
438 /* The size of the maximum gap between one aligned stack and the next. */
439 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
440
441 /* The size of an array large to enough to hold all stacks, each with
442 * N elements. */
443 # define YYSTACK_BYTES(N) \
444 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
445 + YYSTACK_GAP_MAXIMUM)
446
447 /* Copy COUNT objects from FROM to TO. The source and destination do
448 * not overlap. */
449 # ifndef YYCOPY
450 # if defined __GNUC__ && 1 < __GNUC__
451 # define YYCOPY(To, From, Count) \
452 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
453 # else
454 # define YYCOPY(To, From, Count) \
455 do \
456 { \
457 YYSIZE_T yyi; \
458 for (yyi = 0; yyi < (Count); yyi++) \
459 (To)[yyi] = (From)[yyi]; \
460 } \
461 while (YYID (0))
462 # endif
463 # endif
464
465 /* Relocate STACK from its old location to the new one. The
466 * local variables YYSIZE and YYSTACKSIZE give the old and new number of
467 * elements in the stack, and YYPTR gives the new location of the
468 * stack. Advance YYPTR to a properly aligned location for the next
469 * stack. */
470 # define YYSTACK_RELOCATE(Stack) \
471 do \
472 { \
473 YYSIZE_T yynewbytes; \
474 YYCOPY (&yyptr->Stack, Stack, yysize); \
475 Stack = &yyptr->Stack; \
476 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
477 yyptr += yynewbytes / sizeof (*yyptr); \
478 } \
479 while (YYID (0))
480
481 #endif
482
483 /* YYFINAL -- State number of the termination state. */
484 #define YYFINAL 30
485 /* YYLAST -- Last index in YYTABLE. */
486 #define YYLAST 80
487
488 /* YYNTOKENS -- Number of terminals. */
489 #define YYNTOKENS 19
490 /* YYNNTS -- Number of nonterminals. */
491 #define YYNNTS 13
492 /* YYNRULES -- Number of rules. */
493 #define YYNRULES 28
494 /* YYNRULES -- Number of states. */
495 #define YYNSTATES 43
496
497 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
498 #define YYUNDEFTOK 2
499 #define YYMAXUTOK 262
500
501 #define YYTRANSLATE(YYX) \
502 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
503
504 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
505 static const yytype_uint8 yytranslate[] =
506 {
507 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
508 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
509 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
510 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
511 13, 14, 2, 2, 17, 2, 2, 2, 2, 2,
512 2, 2, 2, 2, 2, 2, 2, 2, 18, 12,
513 2, 11, 2, 2, 8, 2, 2, 2, 2, 2,
514 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
515 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
516 2, 15, 2, 16, 2, 2, 2, 2, 2, 2,
517 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
518 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
519 2, 2, 2, 9, 2, 10, 2, 2, 2, 2,
520 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
521 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
522 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
523 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
524 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
525 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
526 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
527 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
528 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
529 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
530 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
531 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
532 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
533 5, 6, 7
534 };
535
536 #if YYDEBUG
537 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
538 * YYRHS. */
539 static const yytype_uint8 yyprhs[] =
540 {
541 0, 0, 3, 4, 6, 8, 10, 12, 14, 16,
542 18, 20, 22, 25, 29, 32, 36, 38, 41, 46,
543 49, 53, 56, 60, 62, 66, 70, 72, 74
544 };
545
546 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
547 static const yytype_int8 yyrhs[] =
548 {
549 20, 0, -1, -1, 21, -1, 7, -1, 22, -1,
550 25, -1, 26, -1, 30, -1, 29, -1, 28, -1,
551 31, -1, 8, 3, -1, 21, 8, 3, -1, 9,
552 10, -1, 9, 23, 10, -1, 24, -1, 23, 24,
553 -1, 21, 11, 21, 12, -1, 13, 14, -1, 13,
554 27, 14, -1, 15, 16, -1, 15, 27, 16, -1,
555 21, -1, 27, 17, 21, -1, 3, 18, 3, -1,
556 5, -1, 4, -1, 6, -1
557 };
558
559 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
560 static const yytype_uint8 yyrline[] =
561 {
562 0, 163, 163, 164, 165, 168, 169, 170, 171, 172,
563 173, 174, 175, 184, 192, 193, 196, 197, 200, 210,
564 211, 214, 215, 218, 223, 234, 242, 247, 252
565 };
566 #endif
567
568 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
569 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
570 * First, the terminals, then, starting at YYNTOKENS, nonterminals. */
571 static const char *const yytname[] =
572 {
573 "$end", "error", "$undefined", "NUMBER", "STRING", "DATA", "BOOLEAN",
574 "SYNTAX_ERROR", "'@'", "'{'", "'}'", "'='", "';'", "'('", "')'", "'['",
575 "']'", "','", "':'", "$accept", "input", "object", "dict", "pairs",
576 "pair", "array", "set", "elements", "offset", "data", "string",
577 "boolean", 0
578 };
579 #endif
580
581 # ifdef YYPRINT
582 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
583 * token YYLEX-NUM. */
584 static const yytype_uint16 yytoknum[] =
585 {
586 0, 256, 257, 258, 259, 260, 261, 262, 64, 123,
587 125, 61, 59, 40, 41, 91, 93, 44, 58
588 };
589 # endif
590
591 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
592 static const yytype_uint8 yyr1[] =
593 {
594 0, 19, 20, 20, 20, 21, 21, 21, 21, 21,
595 21, 21, 21, 21, 22, 22, 23, 23, 24, 25,
596 25, 26, 26, 27, 27, 28, 29, 30, 31
597 };
598
599 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
600 static const yytype_uint8 yyr2[] =
601 {
602 0, 2, 0, 1, 1, 1, 1, 1, 1, 1,
603 1, 1, 2, 3, 2, 3, 1, 2, 4, 2,
604 3, 2, 3, 1, 3, 3, 1, 1, 1
605 };
606
607 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
608 * STATE-NUM when YYTABLE doesn't specify something else to do. Zero
609 * means the default is an error. */
610 static const yytype_uint8 yydefact[] =
611 {
612 2, 0, 27, 26, 28, 4, 0, 0, 0, 0,
613 0, 3, 5, 6, 7, 10, 9, 8, 11, 0,
614 12, 14, 0, 0, 16, 19, 23, 0, 21, 0,
615 1, 0, 25, 0, 15, 17, 20, 0, 22, 13,
616 0, 24, 18
617 };
618
619 /* YYDEFGOTO[NTERM-NUM]. */
620 static const yytype_int8 yydefgoto[] =
621 {
622 -1, 10, 22, 12, 23, 24, 13, 14, 27, 15,
623 16, 17, 18
624 };
625
626 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
627 * STATE-NUM. */
628 #define YYPACT_NINF -14
629 static const yytype_int8 yypact[] =
630 {
631 12, -13, -14, -14, -14, -14, 9, 26, 39, -2,
632 10, 20, -14, -14, -14, -14, -14, -14, -14, 35,
633 -14, -14, 38, 52, -14, -14, 20, 49, -14, 7,
634 -14, 37, -14, 65, -14, -14, -14, 65, -14, -14,
635 14, 20, -14
636 };
637
638 /* YYPGOTO[NTERM-NUM]. */
639 static const yytype_int8 yypgoto[] =
640 {
641 -14, -14, 0, -14, -14, 27, -14, -14, 42, -14,
642 -14, -14, -14
643 };
644
645 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
646 * positive, shift that token. If negative, reduce the rule which
647 * number is the opposite. If zero, do what YYDEFACT says.
648 * If YYTABLE_NINF, syntax error. */
649 #define YYTABLE_NINF -1
650 static const yytype_uint8 yytable[] =
651 {
652 11, 1, 2, 3, 4, 19, 6, 7, 26, 26,
653 30, 8, 20, 9, 28, 1, 2, 3, 4, 5,
654 6, 7, 31, 38, 37, 8, 42, 9, 31, 1,
655 2, 3, 4, 40, 6, 7, 21, 41, 32, 8,
656 39, 9, 1, 2, 3, 4, 31, 6, 7, 33,
657 35, 29, 8, 25, 9, 1, 2, 3, 4, 0,
658 6, 7, 34, 36, 0, 8, 37, 9, 1, 2,
659 3, 4, 0, 6, 7, 0, 0, 0, 8, 0,
660 9
661 };
662
663 static const yytype_int8 yycheck[] =
664 {
665 0, 3, 4, 5, 6, 18, 8, 9, 8, 9,
666 0, 13, 3, 15, 16, 3, 4, 5, 6, 7,
667 8, 9, 8, 16, 17, 13, 12, 15, 8, 3,
668 4, 5, 6, 33, 8, 9, 10, 37, 3, 13,
669 3, 15, 3, 4, 5, 6, 8, 8, 9, 11,
670 23, 9, 13, 14, 15, 3, 4, 5, 6, -1,
671 8, 9, 10, 14, -1, 13, 17, 15, 3, 4,
672 5, 6, -1, 8, 9, -1, -1, -1, 13, -1,
673 15
674 };
675
676 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
677 * symbol of state STATE-NUM. */
678 static const yytype_uint8 yystos[] =
679 {
680 0, 3, 4, 5, 6, 7, 8, 9, 13, 15,
681 20, 21, 22, 25, 26, 28, 29, 30, 31, 18,
682 3, 10, 21, 23, 24, 14, 21, 27, 16, 27,
683 0, 8, 3, 11, 10, 24, 14, 17, 16, 3,
684 21, 21, 12
685 };
686
687 #define yyerrok (yyerrstatus = 0)
688 #define yyclearin (yychar = YYEMPTY)
689 #define YYEMPTY (-2)
690 #define YYEOF 0
691
692 #define YYACCEPT goto yyacceptlab
693 #define YYABORT goto yyabortlab
694 #define YYERROR goto yyerrorlab
695
696
697 /* Like YYERROR except do call yyerror. This remains here temporarily
698 * to ease the transition to the new meaning of YYERROR, for GCC.
699 * Once GCC version 2 has supplanted version 1, this can go. */
700
701 #define YYFAIL goto yyerrlab
702
703 #define YYRECOVERING() (!!yyerrstatus)
704
705 #define YYBACKUP(Token, Value) \
706 do \
707 if (yychar == YYEMPTY && yylen == 1) \
708 { \
709 yychar = (Token); \
710 yylval = (Value); \
711 yytoken = YYTRANSLATE (yychar); \
712 YYPOPSTACK (1); \
713 goto yybackup; \
714 } \
715 else \
716 { \
717 yyerror (YY_("syntax error: cannot back up")); \
718 YYERROR; \
719 } \
720 while (YYID (0))
721
722
723 #define YYTERROR 1
724 #define YYERRCODE 256
725
726
727 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
728 * If N is 0, then set CURRENT to the empty location which ends
729 * the previous symbol: RHS[0] (always defined). */
730
731 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
732 #ifndef YYLLOC_DEFAULT
733 # define YYLLOC_DEFAULT(Current, Rhs, N) \
734 do \
735 if (YYID (N)) \
736 { \
737 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
738 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
739 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
740 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
741 } \
742 else \
743 { \
744 (Current).first_line = (Current).last_line = \
745 YYRHSLOC (Rhs, 0).last_line; \
746 (Current).first_column = (Current).last_column = \
747 YYRHSLOC (Rhs, 0).last_column; \
748 } \
749 while (YYID (0))
750 #endif
751
752
753 /* YY_LOCATION_PRINT -- Print the location on the stream.
754 * This macro was not mandated originally: define only if we know
755 * we won't break user code: when these are the locations we know. */
756
757 #ifndef YY_LOCATION_PRINT
758 # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
759 # define YY_LOCATION_PRINT(File, Loc) \
760 fprintf (File, "%d.%d-%d.%d", \
761 (Loc).first_line, (Loc).first_column, \
762 (Loc).last_line, (Loc).last_column)
763 # else
764 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
765 # endif
766 #endif
767
768
769 /* YYLEX -- calling `yylex' with the right arguments. */
770
771 #ifdef YYLEX_PARAM
772 # define YYLEX yylex (YYLEX_PARAM)
773 #else
774 # define YYLEX yylex ()
775 #endif
776
777 /* Enable debugging if requested. */
778 #if YYDEBUG
779
780 # ifndef YYFPRINTF
781 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
782 # define YYFPRINTF fprintf
783 # endif
784
785 # define YYDPRINTF(Args) \
786 do { \
787 if (yydebug) \
788 YYFPRINTF Args; \
789 } while (YYID (0))
790
791 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
792 do { \
793 if (yydebug) \
794 { \
795 YYFPRINTF (stderr, "%s ", Title); \
796 yy_symbol_print (stderr, \
797 Type, Value); \
798 YYFPRINTF (stderr, "\n"); \
799 } \
800 } while (YYID (0))
801
802
803 /*--------------------------------.
804 | Print this symbol on YYOUTPUT. |
805 | `--------------------------------*/
806
807 /*ARGSUSED*/
808 #if (defined __STDC__ || defined __C99__FUNC__ \
809 || defined __cplusplus || defined _MSC_VER)
810 static void
811 yy_symbol_value_print(FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
812 #else
813 static void
814 yy_symbol_value_print(yyoutput, yytype, yyvaluep)
815 FILE *yyoutput;
816 int yytype;
817 YYSTYPE const * const yyvaluep;
818 #endif
819 {
820 if (!yyvaluep) {
821 return;
822 }
823 # ifdef YYPRINT
824 if (yytype < YYNTOKENS) {
825 YYPRINT(yyoutput, yytoknum[yytype], *yyvaluep);
826 }
827 # else
828 YYUSE(yyoutput);
829 # endif
830 switch (yytype) {
831 default:
832 break;
833 }
834 }
835
836
837 /*--------------------------------.
838 | Print this symbol on YYOUTPUT. |
839 | `--------------------------------*/
840
841 #if (defined __STDC__ || defined __C99__FUNC__ \
842 || defined __cplusplus || defined _MSC_VER)
843 static void
844 yy_symbol_print(FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
845 #else
846 static void
847 yy_symbol_print(yyoutput, yytype, yyvaluep)
848 FILE *yyoutput;
849 int yytype;
850 YYSTYPE const * const yyvaluep;
851 #endif
852 {
853 if (yytype < YYNTOKENS) {
854 YYFPRINTF(yyoutput, "token %s (", yytname[yytype]);
855 } else {
856 YYFPRINTF(yyoutput, "nterm %s (", yytname[yytype]);
857 }
858
859 yy_symbol_value_print(yyoutput, yytype, yyvaluep);
860 YYFPRINTF(yyoutput, ")");
861 }
862
863 /*------------------------------------------------------------------.
864 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
865 | TOP (included). |
866 | `------------------------------------------------------------------*/
867
868 #if (defined __STDC__ || defined __C99__FUNC__ \
869 || defined __cplusplus || defined _MSC_VER)
870 static void
871 yy_stack_print(yytype_int16 *bottom, yytype_int16 *top)
872 #else
873 static void
874 yy_stack_print(bottom, top)
875 yytype_int16 *bottom;
876 yytype_int16 *top;
877 #endif
878 {
879 YYFPRINTF(stderr, "Stack now");
880 for (; bottom <= top; ++bottom) {
881 YYFPRINTF(stderr, " %d", *bottom);
882 }
883 YYFPRINTF(stderr, "\n");
884 }
885
886 # define YY_STACK_PRINT(Bottom, Top) \
887 do { \
888 if (yydebug) \
889 yy_stack_print ((Bottom), (Top)); \
890 } while (YYID (0))
891
892
893 /*------------------------------------------------.
894 | Report that the YYRULE is going to be reduced. |
895 | `------------------------------------------------*/
896
897 #if (defined __STDC__ || defined __C99__FUNC__ \
898 || defined __cplusplus || defined _MSC_VER)
899 static void
900 yy_reduce_print(YYSTYPE *yyvsp, int yyrule)
901 #else
902 static void
903 yy_reduce_print(yyvsp, yyrule)
904 YYSTYPE *yyvsp;
905 int yyrule;
906 #endif
907 {
908 int yynrhs = yyr2[yyrule];
909 int yyi;
910 unsigned long int yylno = yyrline[yyrule];
911 YYFPRINTF(stderr, "Reducing stack by rule %d (line %lu):\n",
912 yyrule - 1, yylno);
913 /* The symbols being reduced. */
914 for (yyi = 0; yyi < yynrhs; yyi++) {
915 fprintf(stderr, " $%d = ", yyi + 1);
916 yy_symbol_print(stderr, yyrhs[yyprhs[yyrule] + yyi],
917 &(yyvsp[(yyi + 1) - (yynrhs)])
918 );
919 fprintf(stderr, "\n");
920 }
921 }
922
923 # define YY_REDUCE_PRINT(Rule) \
924 do { \
925 if (yydebug) \
926 yy_reduce_print (yyvsp, Rule); \
927 } while (YYID (0))
928
929 /* Nonzero means print parse trace. It is left uninitialized so that
930 * multiple parsers can coexist. */
931 int yydebug;
932 #else /* !YYDEBUG */
933 # define YYDPRINTF(Args)
934 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
935 # define YY_STACK_PRINT(Bottom, Top)
936 # define YY_REDUCE_PRINT(Rule)
937 #endif /* !YYDEBUG */
938
939
940 /* YYINITDEPTH -- initial size of the parser's stacks. */
941 #ifndef YYINITDEPTH
942 # define YYINITDEPTH 200
943 #endif
944
945 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
946 * if the built-in stack extension method is used).
947 *
948 * Do not make this value too large; the results are undefined if
949 * YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
950 * evaluated with infinite-precision integer arithmetic. */
951
952 #ifndef YYMAXDEPTH
953 # define YYMAXDEPTH 10000
954 #endif
955
956
957
958 #if YYERROR_VERBOSE
959
960 # ifndef yystrlen
961 # if defined __GLIBC__ && defined _STRING_H
962 # define yystrlen strlen
963 # else
964 /* Return the length of YYSTR. */
965 #if (defined __STDC__ || defined __C99__FUNC__ \
966 || defined __cplusplus || defined _MSC_VER)
967 static YYSIZE_T
968 yystrlen(const char *yystr)
969 #else
970 static YYSIZE_T
971 yystrlen(yystr)
972 const char *yystr;
973 #endif
974 {
975 YYSIZE_T yylen;
976 for (yylen = 0; yystr[yylen]; yylen++) {
977 continue;
978 }
979 return yylen;
980 }
981 # endif
982 # endif
983
984 # ifndef yystpcpy
985 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
986 # define yystpcpy stpcpy
987 # else
988 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
989 * YYDEST. */
990 #if (defined __STDC__ || defined __C99__FUNC__ \
991 || defined __cplusplus || defined _MSC_VER)
992 static char *
993 yystpcpy(char *yydest, const char *yysrc)
994 #else
995 static char *
996 yystpcpy(yydest, yysrc)
997 char *yydest;
998 const char *yysrc;
999 #endif
1000 {
1001 char *yyd = yydest;
1002 const char *yys = yysrc;
1003
1004 while ((*yyd++ = *yys++) != '\0') {
1005 continue;
1006 }
1007
1008 return yyd - 1;
1009 }
1010 # endif
1011 # endif
1012
1013 # ifndef yytnamerr
1014 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1015 * quotes and backslashes, so that it's suitable for yyerror. The
1016 * heuristic is that double-quoting is unnecessary unless the string
1017 * contains an apostrophe, a comma, or backslash (other than
1018 * backslash-backslash). YYSTR is taken from yytname. If YYRES is
1019 * null, do not copy; instead, return the length of what the result
1020 * would have been. */
1021 static YYSIZE_T
1022 yytnamerr(char *yyres, const char *yystr)
1023 {
1024 if (*yystr == '"') {
1025 YYSIZE_T yyn = 0;
1026 char const *yyp = yystr;
1027
1028 for (;;) {
1029 switch (*++yyp) {
1030 case '\'':
1031 case ',':
1032 goto do_not_strip_quotes;
1033
1034 case '\\':
1035 if (*++yyp != '\\') {
1036 goto do_not_strip_quotes;
1037 }
1038 /* Fall through. */
1039 default:
1040 if (yyres) {
1041 yyres[yyn] = *yyp;
1042 }
1043 yyn++;
1044 break;
1045
1046 case '"':
1047 if (yyres) {
1048 yyres[yyn] = '\0';
1049 }
1050 return yyn;
1051 }
1052 }
1053 do_not_strip_quotes:;
1054 }
1055
1056 if (!yyres) {
1057 return yystrlen(yystr);
1058 }
1059
1060 return yystpcpy(yyres, yystr) - yyres;
1061 }
1062 # endif
1063
1064 /* Copy into YYRESULT an error message about the unexpected token
1065 * YYCHAR while in state YYSTATE. Return the number of bytes copied,
1066 * including the terminating null byte. If YYRESULT is null, do not
1067 * copy anything; just return the number of bytes that would be
1068 * copied. As a special case, return 0 if an ordinary "syntax error"
1069 * message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1070 * size calculation. */
1071 static YYSIZE_T
1072 yysyntax_error(char *yyresult, int yystate, int yychar)
1073 {
1074 int yyn = yypact[yystate];
1075
1076 if (!(YYPACT_NINF < yyn && yyn <= YYLAST)) {
1077 return 0;
1078 } else {
1079 int yytype = YYTRANSLATE(yychar);
1080 YYSIZE_T yysize0 = yytnamerr(0, yytname[yytype]);
1081 YYSIZE_T yysize = yysize0;
1082 YYSIZE_T yysize1;
1083 int yysize_overflow = 0;
1084 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1085 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1086 int yyx;
1087
1088 # if 0
1089 /* This is so xgettext sees the translatable formats that are
1090 * constructed on the fly. */
1091 YY_("syntax error, unexpected %s");
1092 YY_("syntax error, unexpected %s, expecting %s");
1093 YY_("syntax error, unexpected %s, expecting %s or %s");
1094 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1095 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1096 # endif
1097 char *yyfmt;
1098 char const *yyf;
1099 static char const yyunexpected[] = "syntax error, unexpected %s";
1100 static char const yyexpecting[] = ", expecting %s";
1101 static char const yyor[] = " or %s";
1102 char yyformat[sizeof yyunexpected
1103 + sizeof yyexpecting - 1
1104 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1105 * (sizeof yyor - 1))];
1106 char const *yyprefix = yyexpecting;
1107
1108 /* Start YYX at -YYN if negative to avoid negative indexes in
1109 * YYCHECK. */
1110 int yyxbegin = yyn < 0 ? -yyn : 0;
1111
1112 /* Stay within bounds of both yycheck and yytname. */
1113 int yychecklim = YYLAST - yyn + 1;
1114 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1115 int yycount = 1;
1116
1117 yyarg[0] = yytname[yytype];
1118 yyfmt = yystpcpy(yyformat, yyunexpected);
1119
1120 for (yyx = yyxbegin; yyx < yyxend; ++yyx) {
1121 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) {
1122 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) {
1123 yycount = 1;
1124 yysize = yysize0;
1125 yyformat[sizeof yyunexpected - 1] = '\0';
1126 break;
1127 }
1128 yyarg[yycount++] = yytname[yyx];
1129 yysize1 = yysize + yytnamerr(0, yytname[yyx]);
1130 yysize_overflow |= (yysize1 < yysize);
1131 yysize = yysize1;
1132 yyfmt = yystpcpy(yyfmt, yyprefix);
1133 yyprefix = yyor;
1134 }
1135 }
1136
1137 yyf = YY_(yyformat);
1138 yysize1 = yysize + yystrlen(yyf);
1139 yysize_overflow |= (yysize1 < yysize);
1140 yysize = yysize1;
1141
1142 if (yysize_overflow) {
1143 return YYSIZE_MAXIMUM;
1144 }
1145
1146 if (yyresult) {
1147 /* Avoid sprintf, as that infringes on the user's name space.
1148 * Don't have undefined behavior even if the translation
1149 * produced a string with the wrong number of "%s"s. */
1150 char *yyp = yyresult;
1151 int yyi = 0;
1152 while ((*yyp = *yyf) != '\0') {
1153 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) {
1154 yyp += yytnamerr(yyp, yyarg[yyi++]);
1155 yyf += 2;
1156 } else {
1157 yyp++;
1158 yyf++;
1159 }
1160 }
1161 }
1162 return yysize;
1163 }
1164 }
1165 #endif /* YYERROR_VERBOSE */
1166
1167
1168 /*-----------------------------------------------.
1169 | Release the memory associated to this symbol. |
1170 | `-----------------------------------------------*/
1171
1172 /*ARGSUSED*/
1173 #if (defined __STDC__ || defined __C99__FUNC__ \
1174 || defined __cplusplus || defined _MSC_VER)
1175 static void
1176 yydestruct(const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1177 #else
1178 static void
1179 yydestruct(yymsg, yytype, yyvaluep)
1180 const char *yymsg;
1181 int yytype;
1182 YYSTYPE *yyvaluep;
1183 #endif
1184 {
1185 YYUSE(yyvaluep);
1186
1187 if (!yymsg) {
1188 yymsg = "Deleting";
1189 }
1190 YY_SYMBOL_PRINT(yymsg, yytype, yyvaluep, yylocationp);
1191
1192 switch (yytype) {
1193 default:
1194 break;
1195 }
1196 }
1197
1198
1199 /* Prevent warnings from -Wmissing-prototypes. */
1200
1201 #ifdef YYPARSE_PARAM
1202 #if defined __STDC__ || defined __cplusplus
1203 int yyparse(void *YYPARSE_PARAM);
1204 #else
1205 int yyparse();
1206 #endif
1207 #else /* ! YYPARSE_PARAM */
1208 #if defined __STDC__ || defined __cplusplus
1209 int yyparse(void);
1210 #else
1211 int yyparse();
1212 #endif
1213 #endif /* ! YYPARSE_PARAM */
1214
1215
1216
1217 /* The look-ahead symbol. */
1218 int yychar;
1219
1220 /* The semantic value of the look-ahead symbol. */
1221 YYSTYPE yylval;
1222
1223 /* Number of syntax errors so far. */
1224 int yynerrs;
1225
1226
1227
1228 /*----------.
1229 | yyparse. |
1230 | `----------*/
1231
1232 #ifdef YYPARSE_PARAM
1233 #if (defined __STDC__ || defined __C99__FUNC__ \
1234 || defined __cplusplus || defined _MSC_VER)
1235 int
1236 yyparse(void *YYPARSE_PARAM)
1237 #else
1238 int
1239 yyparse(YYPARSE_PARAM)
1240 void *YYPARSE_PARAM;
1241 #endif
1242 #else /* ! YYPARSE_PARAM */
1243 #if (defined __STDC__ || defined __C99__FUNC__ \
1244 || defined __cplusplus || defined _MSC_VER)
1245 int
1246 yyparse(void)
1247 #else
1248 int
1249 yyparse()
1250
1251 #endif
1252 #endif
1253 {
1254 int yystate;
1255 int yyn;
1256 int yyresult;
1257 /* Number of tokens to shift before error messages enabled. */
1258 int yyerrstatus;
1259 /* Look-ahead token as an internal (translated) token number. */
1260 int yytoken = 0;
1261 #if YYERROR_VERBOSE
1262 /* Buffer for error messages, and its allocated size. */
1263 char yymsgbuf[128];
1264 char *yymsg = yymsgbuf;
1265 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1266 #endif
1267
1268 /* Three stacks and their tools:
1269 * `yyss': related to states,
1270 * `yyvs': related to semantic values,
1271 * `yyls': related to locations.
1272 *
1273 * Refer to the stacks thru separate pointers, to allow yyoverflow
1274 * to reallocate them elsewhere. */
1275
1276 /* The state stack. */
1277 yytype_int16 yyssa[YYINITDEPTH];
1278 yytype_int16 *yyss = yyssa;
1279 yytype_int16 *yyssp;
1280
1281 /* The semantic value stack. */
1282 YYSTYPE yyvsa[YYINITDEPTH];
1283 YYSTYPE *yyvs = yyvsa;
1284 YYSTYPE *yyvsp;
1285
1286
1287
1288 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1289
1290 YYSIZE_T yystacksize = YYINITDEPTH;
1291
1292 /* The variables used to return semantic value and location from the
1293 * action routines. */
1294 YYSTYPE yyval;
1295
1296
1297 /* The number of symbols on the RHS of the reduced rule.
1298 * Keep to zero when no symbol should be popped. */
1299 int yylen = 0;
1300
1301 YYDPRINTF((stderr, "Starting parse\n"));
1302
1303 yystate = 0;
1304 yyerrstatus = 0;
1305 yynerrs = 0;
1306 yychar = YYEMPTY; /* Cause a token to be read. */
1307
1308 /* Initialize stack pointers.
1309 * Waste one element of value and location stack
1310 * so that they stay on the same level as the state stack.
1311 * The wasted elements are never initialized. */
1312
1313 yyssp = yyss;
1314 yyvsp = yyvs;
1315
1316 goto yysetstate;
1317
1318 /*------------------------------------------------------------.
1319 | yynewstate -- Push a new state, which is found in yystate. |
1320 | `------------------------------------------------------------*/
1321 yynewstate:
1322 /* In all cases, when you get here, the value and location stacks
1323 * have just been pushed. So pushing a state here evens the stacks. */
1324 yyssp++;
1325
1326 yysetstate:
1327 *yyssp = yystate;
1328
1329 if (yyss + yystacksize - 1 <= yyssp) {
1330 /* Get the current used size of the three stacks, in elements. */
1331 YYSIZE_T yysize = yyssp - yyss + 1;
1332
1333 #ifdef yyoverflow
1334 {
1335 /* Give user a chance to reallocate the stack. Use copies of
1336 * these so that the &'s don't force the real ones into
1337 * memory. */
1338 YYSTYPE *yyvs1 = yyvs;
1339 yytype_int16 *yyss1 = yyss;
1340
1341
1342 /* Each stack pointer address is followed by the size of the
1343 * data in use in that stack, in bytes. This used to be a
1344 * conditional around just the two extra args, but that might
1345 * be undefined if yyoverflow is a macro. */
1346 yyoverflow(YY_("memory exhausted"),
1347 &yyss1, yysize * sizeof(*yyssp),
1348 &yyvs1, yysize * sizeof(*yyvsp),
1349
1350 &yystacksize);
1351
1352 yyss = yyss1;
1353 yyvs = yyvs1;
1354 }
1355 #else /* no yyoverflow */
1356 # ifndef YYSTACK_RELOCATE
1357 goto yyexhaustedlab;
1358 # else
1359 /* Extend the stack our own way. */
1360 if (YYMAXDEPTH <= yystacksize) {
1361 goto yyexhaustedlab;
1362 }
1363 yystacksize *= 2;
1364 if (YYMAXDEPTH < yystacksize) {
1365 yystacksize = YYMAXDEPTH;
1366 }
1367
1368 {
1369 yytype_int16 *yyss1 = yyss;
1370 union yyalloc *yyptr =
1371 (union yyalloc *) YYSTACK_ALLOC(YYSTACK_BYTES(yystacksize));
1372 if (!yyptr) {
1373 goto yyexhaustedlab;
1374 }
1375 YYSTACK_RELOCATE(yyss);
1376 YYSTACK_RELOCATE(yyvs);
1377
1378 # undef YYSTACK_RELOCATE
1379 if (yyss1 != yyssa) {
1380 YYSTACK_FREE(yyss1);
1381 }
1382 }
1383 # endif
1384 #endif /* no yyoverflow */
1385
1386 yyssp = yyss + yysize - 1;
1387 yyvsp = yyvs + yysize - 1;
1388
1389
1390 YYDPRINTF((stderr, "Stack size increased to %lu\n",
1391 (unsigned long int) yystacksize));
1392
1393 if (yyss + yystacksize - 1 <= yyssp) {
1394 YYABORT;
1395 }
1396 }
1397
1398 YYDPRINTF((stderr, "Entering state %d\n", yystate));
1399
1400 goto yybackup;
1401
1402 /*-----------.
1403 | yybackup. |
1404 | `-----------*/
1405 yybackup:
1406
1407 /* Do appropriate processing given the current state. Read a
1408 * look-ahead token if we need one and don't already have one. */
1409
1410 /* First try to decide what to do without reference to look-ahead token. */
1411 yyn = yypact[yystate];
1412 if (yyn == YYPACT_NINF) {
1413 goto yydefault;
1414 }
1415
1416 /* Not known => get a look-ahead token if don't already have one. */
1417
1418 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1419 if (yychar == YYEMPTY) {
1420 YYDPRINTF((stderr, "Reading a token: "));
1421 yychar = YYLEX;
1422 }
1423
1424 if (yychar <= YYEOF) {
1425 yychar = yytoken = YYEOF;
1426 YYDPRINTF((stderr, "Now at end of input.\n"));
1427 } else {
1428 yytoken = YYTRANSLATE(yychar);
1429 YY_SYMBOL_PRINT("Next token is", yytoken, &yylval, &yylloc);
1430 }
1431
1432 /* If the proper action on seeing token YYTOKEN is to reduce or to
1433 * detect an error, take that action. */
1434 yyn += yytoken;
1435 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) {
1436 goto yydefault;
1437 }
1438 yyn = yytable[yyn];
1439 if (yyn <= 0) {
1440 if (yyn == 0 || yyn == YYTABLE_NINF) {
1441 goto yyerrlab;
1442 }
1443 yyn = -yyn;
1444 goto yyreduce;
1445 }
1446
1447 if (yyn == YYFINAL) {
1448 YYACCEPT;
1449 }
1450
1451 /* Count tokens shifted since error; after three, turn off error
1452 * status. */
1453 if (yyerrstatus) {
1454 yyerrstatus--;
1455 }
1456
1457 /* Shift the look-ahead token. */
1458 YY_SYMBOL_PRINT("Shifting", yytoken, &yylval, &yylloc);
1459
1460 /* Discard the shifted token unless it is eof. */
1461 if (yychar != YYEOF) {
1462 yychar = YYEMPTY;
1463 }
1464
1465 yystate = yyn;
1466 *++yyvsp = yylval;
1467
1468 goto yynewstate;
1469
1470
1471 /*-----------------------------------------------------------.
1472 | yydefault -- do the default action for the current state. |
1473 | `-----------------------------------------------------------*/
1474 yydefault:
1475 yyn = yydefact[yystate];
1476 if (yyn == 0) {
1477 goto yyerrlab;
1478 }
1479 goto yyreduce;
1480
1481
1482 /*-----------------------------.
1483 | yyreduce -- Do a reduction. |
1484 | `-----------------------------*/
1485 yyreduce:
1486 /* yyn is the number of a rule to reduce with. */
1487 yylen = yyr2[yyn];
1488
1489 /* If YYLEN is nonzero, implement the default value of the action:
1490 * `$$ = $1'.
1491 *
1492 * Otherwise, the following line sets YYVAL to garbage.
1493 * This behavior is undocumented and Bison
1494 * users should not rely upon it. Assigning to YYVAL
1495 * unconditionally makes the parser a bit smaller, and it avoids a
1496 * GCC warning that YYVAL may be used uninitialized. */
1497 yyval = yyvsp[1 - yylen];
1498
1499
1500 YY_REDUCE_PRINT(yyn);
1501 switch (yyn) {
1502 case 2:
1503 #line 163 "OSUnserialize.y"
1504 { parsedObject = (OSObject *)NULL; YYACCEPT;;}
1505 break;
1506
1507 case 3:
1508 #line 164 "OSUnserialize.y"
1509 { parsedObject = (OSObject *)(yyvsp[(1) - (1)]); YYACCEPT;;}
1510 break;
1511
1512 case 4:
1513 #line 165 "OSUnserialize.y"
1514 { yyerror("syntax error"); YYERROR;;}
1515 break;
1516
1517 case 5:
1518 #line 168 "OSUnserialize.y"
1519 { (yyval) = (object_t *)buildOSDictionary((yyvsp[(1) - (1)]));;}
1520 break;
1521
1522 case 6:
1523 #line 169 "OSUnserialize.y"
1524 { (yyval) = (object_t *)buildOSArray((yyvsp[(1) - (1)]));;}
1525 break;
1526
1527 case 7:
1528 #line 170 "OSUnserialize.y"
1529 { (yyval) = (object_t *)buildOSSet((yyvsp[(1) - (1)]));;}
1530 break;
1531
1532 case 8:
1533 #line 171 "OSUnserialize.y"
1534 { (yyval) = (object_t *)buildOSString((yyvsp[(1) - (1)]));;}
1535 break;
1536
1537 case 9:
1538 #line 172 "OSUnserialize.y"
1539 { (yyval) = (object_t *)buildOSData((yyvsp[(1) - (1)]));;}
1540 break;
1541
1542 case 10:
1543 #line 173 "OSUnserialize.y"
1544 { (yyval) = (object_t *)buildOSOffset((yyvsp[(1) - (1)]));;}
1545 break;
1546
1547 case 11:
1548 #line 174 "OSUnserialize.y"
1549 { (yyval) = (object_t *)buildOSBoolean((yyvsp[(1) - (1)]));;}
1550 break;
1551
1552 case 12:
1553 #line 175 "OSUnserialize.y"
1554 { (yyval) = (object_t *)retrieveObject((yyvsp[(2) - (2)])->u.offset);
1555 if ((yyval)) {
1556 ((OSObject *)(yyval))->retain();
1557 } else {
1558 yyerror("forward reference detected");
1559 YYERROR;
1560 }
1561 freeObject((yyvsp[(2) - (2)]));
1562 ;}
1563 break;
1564
1565 case 13:
1566 #line 184 "OSUnserialize.y"
1567 { (yyval) = (yyvsp[(1) - (3)]);
1568 rememberObject((yyvsp[(3) - (3)])->u.offset, (yyvsp[(1) - (3)]));
1569 freeObject((yyvsp[(3) - (3)]));
1570 ;}
1571 break;
1572
1573 case 14:
1574 #line 192 "OSUnserialize.y"
1575 { (yyval) = NULL;;}
1576 break;
1577
1578 case 15:
1579 #line 193 "OSUnserialize.y"
1580 { (yyval) = (yyvsp[(2) - (3)]);;}
1581 break;
1582
1583 case 17:
1584 #line 197 "OSUnserialize.y"
1585 { (yyvsp[(2) - (2)])->next = (yyvsp[(1) - (2)]); (yyvsp[(1) - (2)])->prev = (yyvsp[(2) - (2)]); (yyval) = (yyvsp[(2) - (2)]);;}
1586 break;
1587
1588 case 18:
1589 #line 200 "OSUnserialize.y"
1590 { (yyval) = newObject();
1591 (yyval)->next = NULL;
1592 (yyval)->prev = NULL;
1593 (yyval)->u.key = (yyvsp[(1) - (4)]);
1594 (yyval)->object = (yyvsp[(3) - (4)]);
1595 ;}
1596 break;
1597
1598 case 19:
1599 #line 210 "OSUnserialize.y"
1600 { (yyval) = NULL;;}
1601 break;
1602
1603 case 20:
1604 #line 211 "OSUnserialize.y"
1605 { (yyval) = (yyvsp[(2) - (3)]);;}
1606 break;
1607
1608 case 21:
1609 #line 214 "OSUnserialize.y"
1610 { (yyval) = NULL;;}
1611 break;
1612
1613 case 22:
1614 #line 215 "OSUnserialize.y"
1615 { (yyval) = (yyvsp[(2) - (3)]);;}
1616 break;
1617
1618 case 23:
1619 #line 218 "OSUnserialize.y"
1620 { (yyval) = newObject();
1621 (yyval)->object = (yyvsp[(1) - (1)]);
1622 (yyval)->next = NULL;
1623 (yyval)->prev = NULL;
1624 ;}
1625 break;
1626
1627 case 24:
1628 #line 223 "OSUnserialize.y"
1629 { oo = newObject();
1630 oo->object = (yyvsp[(3) - (3)]);
1631 oo->next = (yyvsp[(1) - (3)]);
1632 oo->prev = NULL;
1633 (yyvsp[(1) - (3)])->prev = oo;
1634 (yyval) = oo;
1635 ;}
1636 break;
1637
1638 case 25:
1639 #line 234 "OSUnserialize.y"
1640 { (yyval) = (yyvsp[(1) - (3)]);
1641 (yyval)->size = (yyvsp[(3) - (3)])->u.offset;
1642 freeObject((yyvsp[(3) - (3)]));
1643 ;}
1644 break;
1645
1646
1647 /* Line 1267 of yacc.c. */
1648 #line 1597 "OSUnserialize.tab.c"
1649 default: break;
1650 }
1651 YY_SYMBOL_PRINT("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1652
1653 YYPOPSTACK(yylen);
1654 yylen = 0;
1655 YY_STACK_PRINT(yyss, yyssp);
1656
1657 *++yyvsp = yyval;
1658
1659
1660 /* Now `shift' the result of the reduction. Determine what state
1661 * that goes to, based on the state we popped back to and the rule
1662 * number reduced by. */
1663
1664 yyn = yyr1[yyn];
1665
1666 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1667 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) {
1668 yystate = yytable[yystate];
1669 } else {
1670 yystate = yydefgoto[yyn - YYNTOKENS];
1671 }
1672
1673 goto yynewstate;
1674
1675
1676 /*------------------------------------.
1677 | yyerrlab -- here on detecting error |
1678 | `------------------------------------*/
1679 yyerrlab:
1680 /* If not already recovering from an error, report this error. */
1681 if (!yyerrstatus) {
1682 ++yynerrs;
1683 #if !YYERROR_VERBOSE
1684 yyerror(YY_("syntax error"));
1685 #else
1686 {
1687 YYSIZE_T yysize = yysyntax_error(0, yystate, yychar);
1688 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) {
1689 YYSIZE_T yyalloc = 2 * yysize;
1690 if (!(yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) {
1691 yyalloc = YYSTACK_ALLOC_MAXIMUM;
1692 }
1693 if (yymsg != yymsgbuf) {
1694 YYSTACK_FREE(yymsg);
1695 }
1696 yymsg = (char *) YYSTACK_ALLOC(yyalloc);
1697 if (yymsg) {
1698 yymsg_alloc = yyalloc;
1699 } else {
1700 yymsg = yymsgbuf;
1701 yymsg_alloc = sizeof yymsgbuf;
1702 }
1703 }
1704
1705 if (0 < yysize && yysize <= yymsg_alloc) {
1706 (void) yysyntax_error(yymsg, yystate, yychar);
1707 yyerror(yymsg);
1708 } else {
1709 yyerror(YY_("syntax error"));
1710 if (yysize != 0) {
1711 goto yyexhaustedlab;
1712 }
1713 }
1714 }
1715 #endif
1716 }
1717
1718
1719
1720 if (yyerrstatus == 3) {
1721 /* If just tried and failed to reuse look-ahead token after an
1722 * error, discard it. */
1723
1724 if (yychar <= YYEOF) {
1725 /* Return failure if at end of input. */
1726 if (yychar == YYEOF) {
1727 YYABORT;
1728 }
1729 } else {
1730 yydestruct("Error: discarding",
1731 yytoken, &yylval);
1732 yychar = YYEMPTY;
1733 }
1734 }
1735
1736 /* Else will try to reuse look-ahead token after shifting the error
1737 * token. */
1738 goto yyerrlab1;
1739
1740
1741 /*---------------------------------------------------.
1742 | yyerrorlab -- error raised explicitly by YYERROR. |
1743 | `---------------------------------------------------*/
1744 yyerrorlab:
1745
1746 /* Pacify compilers like GCC when the user code never invokes
1747 * YYERROR and the label yyerrorlab therefore never appears in user
1748 * code. */
1749 if (/*CONSTCOND*/ 0) {
1750 goto yyerrorlab;
1751 }
1752
1753 /* Do not reclaim the symbols of the rule which action triggered
1754 * this YYERROR. */
1755 YYPOPSTACK(yylen);
1756 yylen = 0;
1757 YY_STACK_PRINT(yyss, yyssp);
1758 yystate = *yyssp;
1759 goto yyerrlab1;
1760
1761
1762 /*-------------------------------------------------------------.
1763 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1764 | `-------------------------------------------------------------*/
1765 yyerrlab1:
1766 yyerrstatus = 3; /* Each real token shifted decrements this. */
1767
1768 for (;;) {
1769 yyn = yypact[yystate];
1770 if (yyn != YYPACT_NINF) {
1771 yyn += YYTERROR;
1772 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) {
1773 yyn = yytable[yyn];
1774 if (0 < yyn) {
1775 break;
1776 }
1777 }
1778 }
1779
1780 /* Pop the current state because it cannot handle the error token. */
1781 if (yyssp == yyss) {
1782 YYABORT;
1783 }
1784
1785
1786 yydestruct("Error: popping",
1787 yystos[yystate], yyvsp);
1788 YYPOPSTACK(1);
1789 yystate = *yyssp;
1790 YY_STACK_PRINT(yyss, yyssp);
1791 }
1792
1793 if (yyn == YYFINAL) {
1794 YYACCEPT;
1795 }
1796
1797 *++yyvsp = yylval;
1798
1799
1800 /* Shift the error token. */
1801 YY_SYMBOL_PRINT("Shifting", yystos[yyn], yyvsp, yylsp);
1802
1803 yystate = yyn;
1804 goto yynewstate;
1805
1806
1807 /*-------------------------------------.
1808 | yyacceptlab -- YYACCEPT comes here. |
1809 | `-------------------------------------*/
1810 yyacceptlab:
1811 yyresult = 0;
1812 goto yyreturn;
1813
1814 /*-----------------------------------.
1815 | yyabortlab -- YYABORT comes here. |
1816 | `-----------------------------------*/
1817 yyabortlab:
1818 yyresult = 1;
1819 goto yyreturn;
1820
1821 #ifndef yyoverflow
1822 /*-------------------------------------------------.
1823 | yyexhaustedlab -- memory exhaustion comes here. |
1824 | `-------------------------------------------------*/
1825 yyexhaustedlab:
1826 yyerror(YY_("memory exhausted"));
1827 yyresult = 2;
1828 /* Fall through. */
1829 #endif
1830
1831 yyreturn:
1832 if (yychar != YYEOF && yychar != YYEMPTY) {
1833 yydestruct("Cleanup: discarding lookahead",
1834 yytoken, &yylval);
1835 }
1836 /* Do not reclaim the symbols of the rule which action triggered
1837 * this YYABORT or YYACCEPT. */
1838 YYPOPSTACK(yylen);
1839 YY_STACK_PRINT(yyss, yyssp);
1840 while (yyssp != yyss) {
1841 yydestruct("Cleanup: popping",
1842 yystos[*yyssp], yyvsp);
1843 YYPOPSTACK(1);
1844 }
1845 #ifndef yyoverflow
1846 if (yyss != yyssa) {
1847 YYSTACK_FREE(yyss);
1848 }
1849 #endif
1850 #if YYERROR_VERBOSE
1851 if (yymsg != yymsgbuf) {
1852 YYSTACK_FREE(yymsg);
1853 }
1854 #endif
1855 /* Make sure YYID is used. */
1856 return YYID(yyresult);
1857 }
1858
1859
1860 #line 255 "OSUnserialize.y"
1861
1862
1863 static int lineNumber = 0;
1864 static const char *parseBuffer;
1865 static int parseBufferIndex;
1866
1867 #define currentChar() (parseBuffer[parseBufferIndex])
1868 #define nextChar() (parseBuffer[++parseBufferIndex])
1869 #define prevChar() (parseBuffer[parseBufferIndex - 1])
1870
1871 #define isSpace(c) ((c) == ' ' || (c) == '\t')
1872 #define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1873 #define isDigit(c) ((c) >= '0' && (c) <= '9')
1874 #define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
1875 #define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
1876 #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
1877
1878 static char yyerror_message[128];
1879
1880 int
1881 yyerror(const char *s) /* Called by yyparse on error */
1882 {
1883 snprintf(yyerror_message, sizeof(yyerror_message), "OSUnserialize: %s near line %d\n", s, lineNumber);
1884 return 0;
1885 }
1886
1887 int
1888 yylex()
1889 {
1890 int c;
1891
1892 if (parseBufferIndex == 0) {
1893 lineNumber = 1;
1894 }
1895
1896 top:
1897 c = currentChar();
1898
1899 /* skip white space */
1900 if (isSpace(c)) {
1901 while ((c = nextChar()) != 0 && isSpace(c)) {
1902 }
1903 }
1904 ;
1905
1906 /* skip over comments */
1907 if (c == '#') {
1908 while ((c = nextChar()) != 0 && c != '\n') {
1909 }
1910 }
1911 ;
1912
1913 /* keep track of line number, don't return \n's */
1914 if (c == '\n') {
1915 lineNumber++;
1916 (void)nextChar();
1917 goto top;
1918 }
1919
1920 /* parse boolean */
1921 if (c == '.') {
1922 bool boolean = false;
1923 if (nextChar() == 't') {
1924 if (nextChar() != 'r') {
1925 return SYNTAX_ERROR;
1926 }
1927 if (nextChar() != 'u') {
1928 return SYNTAX_ERROR;
1929 }
1930 if (nextChar() != 'e') {
1931 return SYNTAX_ERROR;
1932 }
1933 boolean = true;
1934 } else {
1935 if (currentChar() != 'f') {
1936 return SYNTAX_ERROR;
1937 }
1938 if (nextChar() != 'a') {
1939 return SYNTAX_ERROR;
1940 }
1941 if (nextChar() != 'l') {
1942 return SYNTAX_ERROR;
1943 }
1944 if (nextChar() != 's') {
1945 return SYNTAX_ERROR;
1946 }
1947 if (nextChar() != 'e') {
1948 return SYNTAX_ERROR;
1949 }
1950 }
1951 if (nextChar() != '.') {
1952 return SYNTAX_ERROR;
1953 }
1954 /* skip over dot */
1955 (void)nextChar();
1956
1957 yylval = (object_t *)boolean;
1958 return BOOLEAN;
1959 }
1960
1961 /* parse unquoted string */
1962 if (isAlpha(c)) {
1963 int start, length;
1964 char * tempString;
1965
1966 start = parseBufferIndex;
1967 /* find end of string */
1968 while (isAlphaNumeric(c)) {
1969 c = nextChar();
1970 }
1971 length = parseBufferIndex - start;
1972
1973 /* copy to null terminated buffer */
1974 tempString = (char *)malloc(length + 1);
1975 if (tempString == NULL) {
1976 printf("OSUnserialize: can't alloc temp memory\n");
1977 return 0;
1978 }
1979 bcopy(&parseBuffer[start], tempString, length);
1980 tempString[length] = 0;
1981 yylval = (object_t *)tempString;
1982 return STRING;
1983 }
1984
1985 /* parse quoted string */
1986 if (c == '"' || c == '\'') {
1987 int start, length;
1988 char * tempString;
1989 char quoteChar = c;
1990
1991 start = parseBufferIndex + 1; // skip quote
1992 /* find end of string, line, buffer */
1993 while ((c = nextChar()) != quoteChar) {
1994 if (c == '\\') {
1995 c = nextChar();
1996 }
1997 if (c == '\n') {
1998 lineNumber++;
1999 }
2000 if (c == 0) {
2001 return SYNTAX_ERROR;
2002 }
2003 }
2004 length = parseBufferIndex - start;
2005 /* skip over trailing quote */
2006 (void)nextChar();
2007 /* copy to null terminated buffer */
2008 tempString = (char *)malloc(length + 1);
2009 if (tempString == NULL) {
2010 printf("OSUnserialize: can't alloc temp memory\n");
2011 return 0;
2012 }
2013
2014 int to = 0;
2015 for (int from = start; from < parseBufferIndex; from++) {
2016 // hack - skip over backslashes
2017 if (parseBuffer[from] == '\\') {
2018 length--;
2019 continue;
2020 }
2021 tempString[to] = parseBuffer[from];
2022 to++;
2023 }
2024 tempString[length] = 0;
2025 yylval = (object_t *)tempString;
2026 return STRING;
2027 }
2028
2029 /* process numbers */
2030 if (isDigit(c)) {
2031 unsigned long long n = 0;
2032 int base = 10;
2033
2034 if (c == '0') {
2035 c = nextChar();
2036 if (c == 'x') {
2037 base = 16;
2038 c = nextChar();
2039 }
2040 }
2041 if (base == 10) {
2042 while (isDigit(c)) {
2043 n = (n * base + c - '0');
2044 c = nextChar();
2045 }
2046 } else {
2047 while (isHexDigit(c)) {
2048 if (isDigit(c)) {
2049 n = (n * base + c - '0');
2050 } else {
2051 n = (n * base + 0xa + c - 'a');
2052 }
2053 c = nextChar();
2054 }
2055 }
2056
2057 yylval = newObject();
2058 yylval->u.offset = n;
2059
2060 return NUMBER;
2061 }
2062
2063 #define OSDATA_ALLOC_SIZE 4096
2064
2065 /* process data */
2066 if (c == '<') {
2067 unsigned char *d, *start, *lastStart;
2068
2069 size_t buflen = OSDATA_ALLOC_SIZE;
2070 start = lastStart = d = (unsigned char *)malloc(buflen);
2071 c = nextChar(); // skip over '<'
2072 while (c != 0 && c != '>') {
2073 if (isSpace(c)) {
2074 while ((c = nextChar()) != 0 && isSpace(c)) {
2075 }
2076 }
2077 ;
2078 if (c == '#') {
2079 while ((c = nextChar()) != 0 && c != '\n') {
2080 }
2081 }
2082 ;
2083 if (c == '\n') {
2084 lineNumber++;
2085 c = nextChar();
2086 continue;
2087 }
2088
2089 // get high nibble
2090 if (!isHexDigit(c)) {
2091 break;
2092 }
2093 if (isDigit(c)) {
2094 *d = (c - '0') << 4;
2095 } else {
2096 *d = (0xa + (c - 'a')) << 4;
2097 }
2098
2099 // get low nibble
2100 c = nextChar();
2101 if (!isHexDigit(c)) {
2102 break;
2103 }
2104 if (isDigit(c)) {
2105 *d |= c - '0';
2106 } else {
2107 *d |= 0xa + (c - 'a');
2108 }
2109
2110 d++;
2111 if ((d - lastStart) >= OSDATA_ALLOC_SIZE) {
2112 int oldsize = d - start;
2113 assert(buflen == oldsize);
2114 start = (unsigned char *)realloc(start, oldsize, buflen);
2115 d = lastStart = start + oldsize;
2116 }
2117 c = nextChar();
2118 }
2119 if (c != '>') {
2120 safe_free(start, buflen);
2121 return SYNTAX_ERROR;
2122 }
2123
2124 // got it!
2125 yylval = newObject();
2126 yylval->object = start;
2127 yylval->size = d - start;
2128
2129 (void)nextChar(); // skip over '>'
2130 return DATA;
2131 }
2132
2133
2134 /* return single chars, move pointer to next char */
2135 (void)nextChar();
2136 return c;
2137 }
2138
2139 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2140 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2141 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2142
2143 #if DEBUG
2144 int debugUnserializeAllocCount = 0;
2145 #endif
2146
2147 object_t *
2148 newObject()
2149 {
2150 #if DEBUG
2151 debugUnserializeAllocCount++;
2152 #endif
2153 return (object_t *)malloc(sizeof(object_t));
2154 }
2155
2156 void
2157 freeObject(object_t *o)
2158 {
2159 #if DEBUG
2160 debugUnserializeAllocCount--;
2161 #endif
2162 safe_free(o, sizeof(object_t));
2163 }
2164
2165 static OSDictionary *tags;
2166
2167 static void
2168 rememberObject(int tag, object_t *o)
2169 {
2170 char key[16];
2171 snprintf(key, sizeof(key), "%u", tag);
2172
2173 tags->setObject(key, (OSObject *)o);
2174 }
2175
2176 static OSObject *
2177 retrieveObject(int tag)
2178 {
2179 char key[16];
2180 snprintf(key, sizeof(key), "%u", tag);
2181
2182 return tags->getObject(key);
2183 }
2184
2185 OSObject *
2186 buildOSDictionary(object_t *o)
2187 {
2188 object_t *temp, *last = o;
2189 int count = 0;
2190
2191 // get count and last object
2192 while (o) {
2193 count++;
2194 last = o;
2195 o = o->next;
2196 }
2197 o = last;
2198
2199 OSDictionary *d = OSDictionary::withCapacity(count);
2200
2201 while (o) {
2202 #ifdef metaclass_stuff_worksXXX
2203 if (((OSObject *)o->u.key)->metaCast("OSSymbol")) {
2204 // XXX the evil frontdoor
2205 d->setObject((OSSymbol *)o->u.key, (OSObject *)o->object);
2206 } else {
2207 // If it isn't a symbol, I hope it's a string!
2208 d->setObject((OSString *)o->u.key, (OSObject *)o->object);
2209 }
2210 #else
2211 d->setObject((OSString *)o->u.key, (OSObject *)o->object);
2212 #endif
2213 ((OSObject *)o->object)->release();
2214 ((OSObject *)o->u.key)->release();
2215 temp = o;
2216 o = o->prev;
2217 freeObject(temp);
2218 }
2219 return d;
2220 };
2221
2222 OSObject *
2223 buildOSArray(object_t *o)
2224 {
2225 object_t *temp, *last = o;
2226 int count = 0;
2227
2228 // get count and last object
2229 while (o) {
2230 count++;
2231 last = o;
2232 o = o->next;
2233 }
2234 o = last;
2235
2236 OSArray *a = OSArray::withCapacity(count);
2237
2238 while (o) {
2239 a->setObject((OSObject *)o->object);
2240 ((OSObject *)o->object)->release();
2241 temp = o;
2242 o = o->prev;
2243 freeObject(temp);
2244 }
2245 return a;
2246 };
2247
2248 OSObject *
2249 buildOSSet(object_t *o)
2250 {
2251 OSArray *a = (OSArray *)buildOSArray(o);
2252 OSSet *s = OSSet::withArray(a, a->getCapacity());
2253
2254 a->release();
2255 return s;
2256 };
2257
2258 OSObject *
2259 buildOSString(object_t *o)
2260 {
2261 OSString *s = OSString::withCString((char *)o);
2262
2263 safe_free(o, strlen((char *)o) + 1);
2264
2265 return s;
2266 };
2267
2268 OSObject *
2269 buildOSData(object_t *o)
2270 {
2271 OSData *d;
2272
2273 if (o->size) {
2274 d = OSData::withBytes(o->object, o->size);
2275 } else {
2276 d = OSData::withCapacity(0);
2277 }
2278 safe_free(o->object, o->size);
2279 freeObject(o);
2280 return d;
2281 };
2282
2283 OSObject *
2284 buildOSOffset(object_t *o)
2285 {
2286 OSNumber *off = OSNumber::withNumber(o->u.offset, o->size);
2287 freeObject(o);
2288 return off;
2289 };
2290
2291 OSObject *
2292 buildOSBoolean(object_t *o)
2293 {
2294 OSBoolean *b = OSBoolean::withBoolean((bool)o);
2295 return b;
2296 };
2297
2298 __BEGIN_DECLS
2299 #include <kern/locks.h>
2300 __END_DECLS
2301
2302 static lck_mtx_t * lock = 0;
2303 extern lck_grp_t *IOLockGroup;
2304
2305 OSObject*
2306 OSUnserialize(const char *buffer, OSString **errorString)
2307 {
2308 OSObject *object;
2309
2310 if (!lock) {
2311 lock = lck_mtx_alloc_init(IOLockGroup, LCK_ATTR_NULL);
2312 lck_mtx_lock(lock);
2313 } else {
2314 lck_mtx_lock(lock);
2315 }
2316
2317 #if DEBUG
2318 debugUnserializeAllocCount = 0;
2319 #endif
2320 yyerror_message[0] = 0; //just in case
2321 parseBuffer = buffer;
2322 parseBufferIndex = 0;
2323 tags = OSDictionary::withCapacity(128);
2324 if (yyparse() == 0) {
2325 object = parsedObject;
2326 if (errorString) {
2327 *errorString = NULL;
2328 }
2329 } else {
2330 object = NULL;
2331 if (errorString) {
2332 *errorString = OSString::withCString(yyerror_message);
2333 }
2334 }
2335
2336 tags->release();
2337 #if DEBUG
2338 if (debugUnserializeAllocCount) {
2339 printf("OSUnserialize: allocation check failed, count = %d.\n",
2340 debugUnserializeAllocCount);
2341 }
2342 #endif
2343 lck_mtx_unlock(lock);
2344
2345 return object;
2346 }
2347
2348
2349 //
2350 //
2351 //
2352 //
2353 //
2354 // DO NOT EDIT OSUnserialize.cpp!
2355 //
2356 // this means you!
2357 //
2358 //
2359 //
2360 //
2361 //