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