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