]> git.saurik.com Git - apple/xnu.git/blame - libkern/c++/OSUnserializeXML.cpp
xnu-4570.51.1.tar.gz
[apple/xnu.git] / libkern / c++ / OSUnserializeXML.cpp
CommitLineData
1c79356b 1/*
39236c6e 2 * Copyright (c) 1999-2013 Apple 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
55e303ae
A
29/*
30 * HISTORY
31 *
32 * OSUnserializeXML.y created by rsulack on Tue Oct 12 1999
33 */
1c79356b 34
55e303ae 35// parser for unserializing OSContainer objects serialized to XML
1c79356b
A
36//
37// to build :
38// bison -p OSUnserializeXML OSUnserializeXML.y
39// head -50 OSUnserializeXML.y > OSUnserializeXML.cpp
55e303ae 40// sed -e "s/#include <stdio.h>//" < OSUnserializeXML.tab.c >> OSUnserializeXML.cpp
1c79356b
A
41//
42// when changing code check in both OSUnserializeXML.y and OSUnserializeXML.cpp
43//
44//
45//
46//
47//
1c79356b
A
48// DO NOT EDIT OSUnserializeXML.cpp!
49//
50// this means you!
2d21ac55
A
51/* A Bison parser, made by GNU Bison 2.3. */
52
53/* Skeleton implementation for Bison's Yacc-like parsers in C
1c79356b 54
2d21ac55
A
55 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
56 Free Software Foundation, Inc.
1c79356b 57
2d21ac55
A
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.
1c79356b 62
2d21ac55
A
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 1
107
108/* Using locations. */
109#define YYLSP_NEEDED 0
110
111/* Substitute the variable and function names. */
1c79356b 112#define yyparse OSUnserializeXMLparse
2d21ac55 113#define yylex OSUnserializeXMLlex
1c79356b 114#define yyerror OSUnserializeXMLerror
2d21ac55
A
115#define yylval OSUnserializeXMLlval
116#define yychar OSUnserializeXMLchar
1c79356b
A
117#define yydebug OSUnserializeXMLdebug
118#define yynerrs OSUnserializeXMLnerrs
2d21ac55
A
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 ARRAY = 258,
128 BOOLEAN = 259,
129 DATA = 260,
130 DICTIONARY = 261,
131 IDREF = 262,
132 KEY = 263,
133 NUMBER = 264,
134 SET = 265,
135 STRING = 266,
136 SYNTAX_ERROR = 267
137 };
138#endif
139/* Tokens. */
140#define ARRAY 258
141#define BOOLEAN 259
142#define DATA 260
143#define DICTIONARY 261
144#define IDREF 262
145#define KEY 263
146#define NUMBER 264
147#define SET 265
148#define STRING 266
149#define SYNTAX_ERROR 267
150
151
152
153
154/* Copy the first part of user declarations. */
155#line 61 "OSUnserializeXML.y"
1c79356b
A
156
157#include <string.h>
158#include <libkern/c++/OSMetaClass.h>
159#include <libkern/c++/OSContainers.h>
160#include <libkern/c++/OSLib.h>
161
5ba3f43e
A
162#define MAX_OBJECTS 131071
163#define MAX_REFED_OBJECTS 65535
39236c6e 164
55e303ae
A
165#define YYSTYPE object_t *
166#define YYPARSE_PARAM state
0c530ab8 167#define YYLEX_PARAM (parser_state_t *)state
55e303ae
A
168
169// this is the internal struct used to hold objects on parser stack
170// it represents objects both before and after they have been created
1c79356b
A
171typedef struct object {
172 struct object *next;
173 struct object *free;
174 struct object *elements;
175 OSObject *object;
39236c6e 176 OSSymbol *key; // for dictionary
1c79356b 177 int size;
55e303ae
A
178 void *data; // for data
179 char *string; // for string & symbol
180 long long number; // for number
1c79356b
A
181 int idref;
182} object_t;
183
55e303ae
A
184// this code is reentrant, this structure contains all
185// state information for the parsing of a single buffer
186typedef struct parser_state {
187 const char *parseBuffer; // start of text to be parsed
188 int parseBufferIndex; // current index into text
189 int lineNumber; // current line number
190 object_t *objects; // internal objects in use
191 object_t *freeObjects; // internal objects that are free
192 OSDictionary *tags; // used to remember "ID" tags
193 OSString **errorString; // parse error with line
194 OSObject *parsedObject; // resultant object of parsed text
39236c6e 195 int parsedObjectCount;
5ba3f43e 196 int retrievedObjectCount;
55e303ae
A
197} parser_state_t;
198
199#define STATE ((parser_state_t *)state)
200
201#undef yyerror
202#define yyerror(s) OSUnserializeerror(STATE, (s))
b0d623f7 203static int OSUnserializeerror(parser_state_t *state, const char *s);
55e303ae
A
204
205static int yylex(YYSTYPE *lvalp, parser_state_t *state);
55e303ae
A
206
207static object_t *newObject(parser_state_t *state);
208static void freeObject(parser_state_t *state, object_t *o);
209static void rememberObject(parser_state_t *state, int tag, OSObject *o);
210static object_t *retrieveObject(parser_state_t *state, int tag);
211static void cleanupObjects(parser_state_t *state);
212
213static object_t *buildDictionary(parser_state_t *state, object_t *o);
214static object_t *buildArray(parser_state_t *state, object_t *o);
215static object_t *buildSet(parser_state_t *state, object_t *o);
216static object_t *buildString(parser_state_t *state, object_t *o);
39236c6e 217static object_t *buildSymbol(parser_state_t *state, object_t *o);
55e303ae
A
218static object_t *buildData(parser_state_t *state, object_t *o);
219static object_t *buildNumber(parser_state_t *state, object_t *o);
220static object_t *buildBoolean(parser_state_t *state, object_t *o);
1c79356b
A
221
222extern "C" {
55e303ae
A
223extern void *kern_os_malloc(size_t size);
224extern void *kern_os_realloc(void * addr, size_t size);
225extern void kern_os_free(void * addr);
1c79356b 226
1c79356b
A
227} /* extern "C" */
228
229#define malloc(s) kern_os_malloc(s)
230#define realloc(a, s) kern_os_realloc(a, s)
0c530ab8 231#define free(a) kern_os_free((void *)a)
1c79356b 232
2d21ac55
A
233
234
235/* Enabling traces. */
236#ifndef YYDEBUG
237# define YYDEBUG 0
1c79356b 238#endif
1c79356b 239
2d21ac55
A
240/* Enabling verbose error messages. */
241#ifdef YYERROR_VERBOSE
242# undef YYERROR_VERBOSE
243# define YYERROR_VERBOSE 1
244#else
245# define YYERROR_VERBOSE 0
246#endif
55e303ae 247
2d21ac55
A
248/* Enabling the token table. */
249#ifndef YYTOKEN_TABLE
250# define YYTOKEN_TABLE 0
1c79356b 251#endif
2d21ac55
A
252
253#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
254typedef int YYSTYPE;
255# define yystype YYSTYPE /* obsolescent; will be withdrawn */
256# define YYSTYPE_IS_DECLARED 1
257# define YYSTYPE_IS_TRIVIAL 1
1c79356b
A
258#endif
259
260
261
2d21ac55 262/* Copy the second part of user declarations. */
1c79356b 263
1c79356b 264
2d21ac55 265/* Line 216 of yacc.c. */
39236c6e 266#line 215 "OSUnserializeXML.tab.c"
1c79356b 267
2d21ac55
A
268#ifdef short
269# undef short
1c79356b
A
270#endif
271
2d21ac55
A
272#ifdef YYTYPE_UINT8
273typedef YYTYPE_UINT8 yytype_uint8;
274#else
275typedef unsigned char yytype_uint8;
1c79356b
A
276#endif
277
2d21ac55
A
278#ifdef YYTYPE_INT8
279typedef YYTYPE_INT8 yytype_int8;
280#elif (defined __STDC__ || defined __C99__FUNC__ \
281 || defined __cplusplus || defined _MSC_VER)
282typedef signed char yytype_int8;
283#else
284typedef short int yytype_int8;
285#endif
1c79356b 286
2d21ac55
A
287#ifdef YYTYPE_UINT16
288typedef YYTYPE_UINT16 yytype_uint16;
289#else
290typedef unsigned short int yytype_uint16;
291#endif
1c79356b 292
2d21ac55
A
293#ifdef YYTYPE_INT16
294typedef YYTYPE_INT16 yytype_int16;
295#else
296typedef short int yytype_int16;
1c79356b
A
297#endif
298
2d21ac55
A
299#ifndef YYSIZE_T
300# ifdef __SIZE_TYPE__
301# define YYSIZE_T __SIZE_TYPE__
302# elif defined size_t
303# define YYSIZE_T size_t
304# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
305 || defined __cplusplus || defined _MSC_VER)
306# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
307# define YYSIZE_T size_t
308# else
309# define YYSIZE_T unsigned int
310# endif
311#endif
1c79356b 312
2d21ac55
A
313#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
314
315#ifndef YY_
b0d623f7 316# if defined YYENABLE_NLS && YYENABLE_NLS
2d21ac55
A
317# if ENABLE_NLS
318# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
319# define YY_(msgid) dgettext ("bison-runtime", msgid)
320# endif
321# endif
322# ifndef YY_
323# define YY_(msgid) msgid
324# endif
325#endif
326
327/* Suppress unused-variable warnings by "using" E. */
328#if ! defined lint || defined __GNUC__
329# define YYUSE(e) ((void) (e))
330#else
331# define YYUSE(e) /* empty */
332#endif
1c79356b 333
2d21ac55
A
334/* Identity function, used to suppress warnings about constant conditions. */
335#ifndef lint
336# define YYID(n) (n)
337#else
338#if (defined __STDC__ || defined __C99__FUNC__ \
339 || defined __cplusplus || defined _MSC_VER)
340static int
341YYID (int i)
342#else
343static int
344YYID (i)
345 int i;
346#endif
347{
348 return i;
349}
350#endif
351
352#if ! defined yyoverflow || YYERROR_VERBOSE
353
354/* The parser invokes alloca or malloc; define the necessary symbols. */
355
356# ifdef YYSTACK_USE_ALLOCA
357# if YYSTACK_USE_ALLOCA
358# ifdef __GNUC__
359# define YYSTACK_ALLOC __builtin_alloca
360# elif defined __BUILTIN_VA_ARG_INCR
361# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
362# elif defined _AIX
363# define YYSTACK_ALLOC __alloca
364# elif defined _MSC_VER
365# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
366# define alloca _alloca
367# else
368# define YYSTACK_ALLOC alloca
369# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
370 || defined __cplusplus || defined _MSC_VER)
371# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
372# ifndef _STDLIB_H
373# define _STDLIB_H 1
374# endif
375# endif
376# endif
377# endif
378# endif
379
380# ifdef YYSTACK_ALLOC
381 /* Pacify GCC's `empty if-body' warning. */
382# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
383# ifndef YYSTACK_ALLOC_MAXIMUM
384 /* The OS might guarantee only one guard page at the bottom of the stack,
385 and a page size can be as small as 4096 bytes. So we cannot safely
386 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
387 to allow for a few compiler-allocated temporary stack slots. */
388# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
389# endif
390# else
391# define YYSTACK_ALLOC YYMALLOC
392# define YYSTACK_FREE YYFREE
393# ifndef YYSTACK_ALLOC_MAXIMUM
394# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
395# endif
396# if (defined __cplusplus && ! defined _STDLIB_H \
397 && ! ((defined YYMALLOC || defined malloc) \
398 && (defined YYFREE || defined free)))
399# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
400# ifndef _STDLIB_H
401# define _STDLIB_H 1
402# endif
403# endif
404# ifndef YYMALLOC
405# define YYMALLOC malloc
406# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
407 || defined __cplusplus || defined _MSC_VER)
408void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
409# endif
410# endif
411# ifndef YYFREE
412# define YYFREE free
413# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
414 || defined __cplusplus || defined _MSC_VER)
415void free (void *); /* INFRINGES ON USER NAME SPACE */
416# endif
417# endif
418# endif
419#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
420
421
422#if (! defined yyoverflow \
423 && (! defined __cplusplus \
424 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
425
426/* A type that is properly aligned for any stack member. */
427union yyalloc
428{
429 yytype_int16 yyss;
430 YYSTYPE yyvs;
431 };
432
433/* The size of the maximum gap between one aligned stack and the next. */
434# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
435
436/* The size of an array large to enough to hold all stacks, each with
437 N elements. */
438# define YYSTACK_BYTES(N) \
439 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
440 + YYSTACK_GAP_MAXIMUM)
441
442/* Copy COUNT objects from FROM to TO. The source and destination do
443 not overlap. */
444# ifndef YYCOPY
445# if defined __GNUC__ && 1 < __GNUC__
446# define YYCOPY(To, From, Count) \
447 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
448# else
449# define YYCOPY(To, From, Count) \
450 do \
451 { \
452 YYSIZE_T yyi; \
453 for (yyi = 0; yyi < (Count); yyi++) \
454 (To)[yyi] = (From)[yyi]; \
455 } \
456 while (YYID (0))
457# endif
458# endif
459
460/* Relocate STACK from its old location to the new one. The
461 local variables YYSIZE and YYSTACKSIZE give the old and new number of
462 elements in the stack, and YYPTR gives the new location of the
463 stack. Advance YYPTR to a properly aligned location for the next
464 stack. */
465# define YYSTACK_RELOCATE(Stack) \
466 do \
467 { \
468 YYSIZE_T yynewbytes; \
469 YYCOPY (&yyptr->Stack, Stack, yysize); \
470 Stack = &yyptr->Stack; \
471 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
472 yyptr += yynewbytes / sizeof (*yyptr); \
473 } \
474 while (YYID (0))
475
476#endif
477
478/* YYFINAL -- State number of the termination state. */
479#define YYFINAL 33
480/* YYLAST -- Last index in YYTABLE. */
481#define YYLAST 108
482
483/* YYNTOKENS -- Number of terminals. */
484#define YYNTOKENS 19
485/* YYNNTS -- Number of nonterminals. */
486#define YYNNTS 15
487/* YYNRULES -- Number of rules. */
488#define YYNRULES 32
489/* YYNRULES -- Number of states. */
490#define YYNSTATES 40
491
492/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
493#define YYUNDEFTOK 2
494#define YYMAXUTOK 267
495
496#define YYTRANSLATE(YYX) \
497 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
498
499/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
500static const yytype_uint8 yytranslate[] =
501{
502 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
503 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
504 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
505 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
506 15, 16, 2, 2, 2, 2, 2, 2, 2, 2,
507 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
508 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
509 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
510 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
511 2, 17, 2, 18, 2, 2, 2, 2, 2, 2,
512 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
513 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
514 2, 2, 2, 13, 2, 14, 2, 2, 2, 2,
515 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
516 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
517 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
518 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
519 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
520 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
521 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
522 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
523 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
524 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
525 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
526 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
527 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
528 5, 6, 7, 8, 9, 10, 11, 12
1c79356b
A
529};
530
2d21ac55
A
531#if YYDEBUG
532/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
533 YYRHS. */
534static const yytype_uint8 yyprhs[] =
535{
536 0, 0, 3, 4, 6, 8, 10, 12, 14, 16,
537 18, 20, 22, 24, 27, 31, 33, 35, 38, 41,
538 43, 46, 50, 52, 55, 59, 61, 63, 66, 68,
539 70, 72, 74
1c79356b
A
540};
541
2d21ac55
A
542/* YYRHS -- A `-1'-separated list of the rules' RHS. */
543static const yytype_int8 yyrhs[] =
544{
545 20, 0, -1, -1, 21, -1, 12, -1, 22, -1,
546 26, -1, 27, -1, 33, -1, 30, -1, 32, -1,
547 29, -1, 31, -1, 13, 14, -1, 13, 23, 14,
548 -1, 6, -1, 24, -1, 23, 24, -1, 25, 21,
549 -1, 8, -1, 15, 16, -1, 15, 28, 16, -1,
550 3, -1, 17, 18, -1, 17, 28, 18, -1, 10,
551 -1, 21, -1, 28, 21, -1, 4, -1, 5, -1,
552 7, -1, 9, -1, 11, -1
1c79356b
A
553};
554
2d21ac55 555/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
39236c6e 556static const yytype_uint16 yyrline[] =
2d21ac55 557{
d190cdc3
A
558 0, 149, 149, 152, 157, 162, 174, 186, 198, 210,
559 222, 234, 246, 265, 268, 271, 274, 275, 290, 299,
560 311, 314, 317, 320, 323, 326, 329, 332, 339, 342,
561 345, 348, 351
1c79356b 562};
2d21ac55 563#endif
1c79356b 564
2d21ac55
A
565#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
566/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
567 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
568static const char *const yytname[] =
569{
570 "$end", "error", "$undefined", "ARRAY", "BOOLEAN", "DATA", "DICTIONARY",
571 "IDREF", "KEY", "NUMBER", "SET", "STRING", "SYNTAX_ERROR", "'{'", "'}'",
572 "'('", "')'", "'['", "']'", "$accept", "input", "object", "dict",
573 "pairs", "pair", "key", "array", "set", "elements", "boolean", "data",
574 "idref", "number", "string", 0
575};
576#endif
1c79356b 577
2d21ac55
A
578# ifdef YYPRINT
579/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
580 token YYLEX-NUM. */
581static const yytype_uint16 yytoknum[] =
582{
583 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
584 265, 266, 267, 123, 125, 40, 41, 91, 93
585};
586# endif
1c79356b 587
2d21ac55
A
588/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
589static const yytype_uint8 yyr1[] =
590{
591 0, 19, 20, 20, 20, 21, 21, 21, 21, 21,
592 21, 21, 21, 22, 22, 22, 23, 23, 24, 25,
593 26, 26, 26, 27, 27, 27, 28, 28, 29, 30,
594 31, 32, 33
595};
1c79356b 596
2d21ac55
A
597/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
598static const yytype_uint8 yyr2[] =
599{
600 0, 2, 0, 1, 1, 1, 1, 1, 1, 1,
601 1, 1, 1, 2, 3, 1, 1, 2, 2, 1,
602 2, 3, 1, 2, 3, 1, 1, 2, 1, 1,
603 1, 1, 1
1c79356b
A
604};
605
2d21ac55
A
606/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
607 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
608 means the default is an error. */
609static const yytype_uint8 yydefact[] =
610{
611 2, 22, 28, 29, 15, 30, 31, 25, 32, 4,
612 0, 0, 0, 0, 3, 5, 6, 7, 11, 9,
613 12, 10, 8, 19, 13, 0, 16, 0, 20, 26,
614 0, 23, 0, 1, 14, 17, 18, 21, 27, 24
1c79356b 615};
55e303ae 616
2d21ac55
A
617/* YYDEFGOTO[NTERM-NUM]. */
618static const yytype_int8 yydefgoto[] =
619{
620 -1, 13, 29, 15, 25, 26, 27, 16, 17, 30,
621 18, 19, 20, 21, 22
622};
1c79356b 623
2d21ac55
A
624/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
625 STATE-NUM. */
626#define YYPACT_NINF -20
627static const yytype_int8 yypact[] =
628{
629 46, -20, -20, -20, -20, -20, -20, -20, -20, -20,
630 4, 61, -2, 10, -20, -20, -20, -20, -20, -20,
631 -20, -20, -20, -20, -20, 6, -20, 91, -20, -20,
632 76, -20, 30, -20, -20, -20, -20, -20, -20, -20
633};
1c79356b 634
2d21ac55
A
635/* YYPGOTO[NTERM-NUM]. */
636static const yytype_int8 yypgoto[] =
637{
638 -20, -20, 0, -20, -20, -19, -20, -20, -20, 5,
639 -20, -20, -20, -20, -20
640};
1c79356b 641
2d21ac55
A
642/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
643 positive, shift that token. If negative, reduce the rule which
644 number is the opposite. If zero, do what YYDEFACT says.
645 If YYTABLE_NINF, syntax error. */
646#define YYTABLE_NINF -1
647static const yytype_uint8 yytable[] =
648{
649 14, 1, 2, 3, 4, 5, 35, 6, 7, 8,
650 33, 10, 23, 11, 23, 12, 31, 32, 24, 0,
651 34, 0, 0, 0, 0, 0, 0, 36, 0, 0,
652 38, 0, 38, 1, 2, 3, 4, 5, 0, 6,
653 7, 8, 0, 10, 0, 11, 0, 12, 39, 1,
654 2, 3, 4, 5, 0, 6, 7, 8, 9, 10,
655 0, 11, 0, 12, 1, 2, 3, 4, 5, 0,
656 6, 7, 8, 0, 10, 0, 11, 28, 12, 1,
657 2, 3, 4, 5, 0, 6, 7, 8, 0, 10,
658 0, 11, 37, 12, 1, 2, 3, 4, 5, 0,
659 6, 7, 8, 0, 10, 0, 11, 0, 12
660};
1c79356b 661
2d21ac55
A
662static const yytype_int8 yycheck[] =
663{
664 0, 3, 4, 5, 6, 7, 25, 9, 10, 11,
665 0, 13, 8, 15, 8, 17, 18, 12, 14, -1,
666 14, -1, -1, -1, -1, -1, -1, 27, -1, -1,
667 30, -1, 32, 3, 4, 5, 6, 7, -1, 9,
668 10, 11, -1, 13, -1, 15, -1, 17, 18, 3,
669 4, 5, 6, 7, -1, 9, 10, 11, 12, 13,
670 -1, 15, -1, 17, 3, 4, 5, 6, 7, -1,
671 9, 10, 11, -1, 13, -1, 15, 16, 17, 3,
672 4, 5, 6, 7, -1, 9, 10, 11, -1, 13,
673 -1, 15, 16, 17, 3, 4, 5, 6, 7, -1,
674 9, 10, 11, -1, 13, -1, 15, -1, 17
675};
1c79356b 676
2d21ac55
A
677/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
678 symbol of state STATE-NUM. */
679static const yytype_uint8 yystos[] =
680{
681 0, 3, 4, 5, 6, 7, 9, 10, 11, 12,
682 13, 15, 17, 20, 21, 22, 26, 27, 29, 30,
683 31, 32, 33, 8, 14, 23, 24, 25, 16, 21,
684 28, 18, 28, 0, 14, 24, 21, 16, 21, 18
685};
1c79356b
A
686
687#define yyerrok (yyerrstatus = 0)
688#define yyclearin (yychar = YYEMPTY)
2d21ac55 689#define YYEMPTY (-2)
1c79356b 690#define YYEOF 0
2d21ac55 691
1c79356b 692#define YYACCEPT goto yyacceptlab
2d21ac55
A
693#define YYABORT goto yyabortlab
694#define YYERROR goto yyerrorlab
695
696
697/* Like YYERROR except do call yyerror. This remains here temporarily
698 to ease the transition to the new meaning of YYERROR, for GCC.
1c79356b 699 Once GCC version 2 has supplanted version 1, this can go. */
2d21ac55 700
1c79356b 701#define YYFAIL goto yyerrlab
2d21ac55 702
1c79356b 703#define YYRECOVERING() (!!yyerrstatus)
2d21ac55
A
704
705#define YYBACKUP(Token, Value) \
1c79356b
A
706do \
707 if (yychar == YYEMPTY && yylen == 1) \
2d21ac55
A
708 { \
709 yychar = (Token); \
710 yylval = (Value); \
711 yytoken = YYTRANSLATE (yychar); \
712 YYPOPSTACK (1); \
1c79356b
A
713 goto yybackup; \
714 } \
715 else \
2d21ac55
A
716 { \
717 yyerror (YY_("syntax error: cannot back up")); \
718 YYERROR; \
719 } \
720while (YYID (0))
721
1c79356b
A
722
723#define YYTERROR 1
724#define YYERRCODE 256
725
2d21ac55
A
726
727/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
728 If N is 0, then set CURRENT to the empty location which ends
729 the previous symbol: RHS[0] (always defined). */
730
731#define YYRHSLOC(Rhs, K) ((Rhs)[K])
732#ifndef YYLLOC_DEFAULT
733# define YYLLOC_DEFAULT(Current, Rhs, N) \
734 do \
735 if (YYID (N)) \
736 { \
737 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
738 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
739 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
740 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
741 } \
742 else \
743 { \
744 (Current).first_line = (Current).last_line = \
745 YYRHSLOC (Rhs, 0).last_line; \
746 (Current).first_column = (Current).last_column = \
747 YYRHSLOC (Rhs, 0).last_column; \
748 } \
749 while (YYID (0))
1c79356b
A
750#endif
751
2d21ac55
A
752
753/* YY_LOCATION_PRINT -- Print the location on the stream.
754 This macro was not mandated originally: define only if we know
755 we won't break user code: when these are the locations we know. */
756
757#ifndef YY_LOCATION_PRINT
b0d623f7 758# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
2d21ac55
A
759# define YY_LOCATION_PRINT(File, Loc) \
760 fprintf (File, "%d.%d-%d.%d", \
761 (Loc).first_line, (Loc).first_column, \
762 (Loc).last_line, (Loc).last_column)
763# else
764# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
765# endif
1c79356b 766#endif
2d21ac55
A
767
768
769/* YYLEX -- calling `yylex' with the right arguments. */
770
1c79356b 771#ifdef YYLEX_PARAM
2d21ac55 772# define YYLEX yylex (&yylval, YYLEX_PARAM)
1c79356b 773#else
2d21ac55 774# define YYLEX yylex (&yylval)
1c79356b 775#endif
2d21ac55
A
776
777/* Enable debugging if requested. */
778#if YYDEBUG
779
780# ifndef YYFPRINTF
781# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
782# define YYFPRINTF fprintf
783# endif
784
785# define YYDPRINTF(Args) \
786do { \
787 if (yydebug) \
788 YYFPRINTF Args; \
789} while (YYID (0))
790
791# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
792do { \
793 if (yydebug) \
794 { \
795 YYFPRINTF (stderr, "%s ", Title); \
796 yy_symbol_print (stderr, \
797 Type, Value); \
798 YYFPRINTF (stderr, "\n"); \
799 } \
800} while (YYID (0))
801
802
803/*--------------------------------.
804| Print this symbol on YYOUTPUT. |
805`--------------------------------*/
806
807/*ARGSUSED*/
808#if (defined __STDC__ || defined __C99__FUNC__ \
809 || defined __cplusplus || defined _MSC_VER)
810static void
811yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
812#else
813static void
814yy_symbol_value_print (yyoutput, yytype, yyvaluep)
815 FILE *yyoutput;
816 int yytype;
817 YYSTYPE const * const yyvaluep;
1c79356b 818#endif
2d21ac55
A
819{
820 if (!yyvaluep)
821 return;
822# ifdef YYPRINT
823 if (yytype < YYNTOKENS)
824 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
825# else
826 YYUSE (yyoutput);
827# endif
828 switch (yytype)
829 {
830 default:
831 break;
832 }
833}
1c79356b 834
1c79356b 835
2d21ac55
A
836/*--------------------------------.
837| Print this symbol on YYOUTPUT. |
838`--------------------------------*/
1c79356b 839
2d21ac55
A
840#if (defined __STDC__ || defined __C99__FUNC__ \
841 || defined __cplusplus || defined _MSC_VER)
842static void
843yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
844#else
845static void
846yy_symbol_print (yyoutput, yytype, yyvaluep)
847 FILE *yyoutput;
848 int yytype;
849 YYSTYPE const * const yyvaluep;
850#endif
851{
852 if (yytype < YYNTOKENS)
853 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
854 else
855 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
856
857 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
858 YYFPRINTF (yyoutput, ")");
859}
860
861/*------------------------------------------------------------------.
862| yy_stack_print -- Print the state stack from its BOTTOM up to its |
863| TOP (included). |
864`------------------------------------------------------------------*/
1c79356b 865
2d21ac55
A
866#if (defined __STDC__ || defined __C99__FUNC__ \
867 || defined __cplusplus || defined _MSC_VER)
868static void
869yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
870#else
871static void
872yy_stack_print (bottom, top)
873 yytype_int16 *bottom;
874 yytype_int16 *top;
1c79356b 875#endif
2d21ac55
A
876{
877 YYFPRINTF (stderr, "Stack now");
878 for (; bottom <= top; ++bottom)
879 YYFPRINTF (stderr, " %d", *bottom);
880 YYFPRINTF (stderr, "\n");
881}
882
883# define YY_STACK_PRINT(Bottom, Top) \
884do { \
885 if (yydebug) \
886 yy_stack_print ((Bottom), (Top)); \
887} while (YYID (0))
1c79356b 888
1c79356b 889
2d21ac55
A
890/*------------------------------------------------.
891| Report that the YYRULE is going to be reduced. |
892`------------------------------------------------*/
893
894#if (defined __STDC__ || defined __C99__FUNC__ \
895 || defined __cplusplus || defined _MSC_VER)
896static void
897yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
898#else
899static void
900yy_reduce_print (yyvsp, yyrule)
901 YYSTYPE *yyvsp;
902 int yyrule;
1c79356b 903#endif
2d21ac55
A
904{
905 int yynrhs = yyr2[yyrule];
906 int yyi;
907 unsigned long int yylno = yyrline[yyrule];
908 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
909 yyrule - 1, yylno);
910 /* The symbols being reduced. */
911 for (yyi = 0; yyi < yynrhs; yyi++)
912 {
913 fprintf (stderr, " $%d = ", yyi + 1);
914 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
915 &(yyvsp[(yyi + 1) - (yynrhs)])
916 );
917 fprintf (stderr, "\n");
918 }
919}
920
921# define YY_REDUCE_PRINT(Rule) \
922do { \
923 if (yydebug) \
924 yy_reduce_print (yyvsp, Rule); \
925} while (YYID (0))
926
927/* Nonzero means print parse trace. It is left uninitialized so that
928 multiple parsers can coexist. */
929int yydebug;
930#else /* !YYDEBUG */
931# define YYDPRINTF(Args)
932# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
933# define YY_STACK_PRINT(Bottom, Top)
934# define YY_REDUCE_PRINT(Rule)
935#endif /* !YYDEBUG */
1c79356b 936
1c79356b 937
2d21ac55 938/* YYINITDEPTH -- initial size of the parser's stacks. */
1c79356b 939#ifndef YYINITDEPTH
d190cdc3 940# define YYINITDEPTH 64
1c79356b
A
941#endif
942
2d21ac55
A
943/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
944 if the built-in stack extension method is used).
1c79356b 945
2d21ac55
A
946 Do not make this value too large; the results are undefined if
947 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
948 evaluated with infinite-precision integer arithmetic. */
1c79356b
A
949
950#ifndef YYMAXDEPTH
2d21ac55 951# define YYMAXDEPTH 10000
1c79356b 952#endif
2d21ac55 953
1c79356b 954\f
2d21ac55
A
955
956#if YYERROR_VERBOSE
957
958# ifndef yystrlen
959# if defined __GLIBC__ && defined _STRING_H
960# define yystrlen strlen
961# else
962/* Return the length of YYSTR. */
963#if (defined __STDC__ || defined __C99__FUNC__ \
964 || defined __cplusplus || defined _MSC_VER)
965static YYSIZE_T
966yystrlen (const char *yystr)
967#else
968static YYSIZE_T
969yystrlen (yystr)
970 const char *yystr;
971#endif
972{
973 YYSIZE_T yylen;
974 for (yylen = 0; yystr[yylen]; yylen++)
975 continue;
976 return yylen;
977}
978# endif
979# endif
980
981# ifndef yystpcpy
982# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
983# define yystpcpy stpcpy
984# else
985/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
986 YYDEST. */
987#if (defined __STDC__ || defined __C99__FUNC__ \
988 || defined __cplusplus || defined _MSC_VER)
989static char *
990yystpcpy (char *yydest, const char *yysrc)
991#else
992static char *
993yystpcpy (yydest, yysrc)
994 char *yydest;
995 const char *yysrc;
996#endif
1c79356b 997{
2d21ac55
A
998 char *yyd = yydest;
999 const char *yys = yysrc;
1000
1001 while ((*yyd++ = *yys++) != '\0')
1002 continue;
1c79356b 1003
2d21ac55 1004 return yyd - 1;
1c79356b 1005}
2d21ac55
A
1006# endif
1007# endif
1008
1009# ifndef yytnamerr
1010/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1011 quotes and backslashes, so that it's suitable for yyerror. The
1012 heuristic is that double-quoting is unnecessary unless the string
1013 contains an apostrophe, a comma, or backslash (other than
1014 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1015 null, do not copy; instead, return the length of what the result
1016 would have been. */
1017static YYSIZE_T
1018yytnamerr (char *yyres, const char *yystr)
1019{
1020 if (*yystr == '"')
1021 {
1022 YYSIZE_T yyn = 0;
1023 char const *yyp = yystr;
1024
1025 for (;;)
1026 switch (*++yyp)
1027 {
1028 case '\'':
1029 case ',':
1030 goto do_not_strip_quotes;
1031
1032 case '\\':
1033 if (*++yyp != '\\')
1034 goto do_not_strip_quotes;
1035 /* Fall through. */
1036 default:
1037 if (yyres)
1038 yyres[yyn] = *yyp;
1039 yyn++;
1040 break;
1041
1042 case '"':
1043 if (yyres)
1044 yyres[yyn] = '\0';
1045 return yyn;
1046 }
1047 do_not_strip_quotes: ;
1048 }
1c79356b 1049
2d21ac55
A
1050 if (! yyres)
1051 return yystrlen (yystr);
1c79356b 1052
2d21ac55
A
1053 return yystpcpy (yyres, yystr) - yyres;
1054}
1055# endif
1056
1057/* Copy into YYRESULT an error message about the unexpected token
1058 YYCHAR while in state YYSTATE. Return the number of bytes copied,
1059 including the terminating null byte. If YYRESULT is null, do not
1060 copy anything; just return the number of bytes that would be
1061 copied. As a special case, return 0 if an ordinary "syntax error"
1062 message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1063 size calculation. */
1064static YYSIZE_T
1065yysyntax_error (char *yyresult, int yystate, int yychar)
1c79356b 1066{
2d21ac55 1067 int yyn = yypact[yystate];
1c79356b 1068
2d21ac55
A
1069 if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
1070 return 0;
1071 else
1072 {
1073 int yytype = YYTRANSLATE (yychar);
1074 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1075 YYSIZE_T yysize = yysize0;
1076 YYSIZE_T yysize1;
1077 int yysize_overflow = 0;
1078 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1079 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1080 int yyx;
1081
1082# if 0
1083 /* This is so xgettext sees the translatable formats that are
1084 constructed on the fly. */
1085 YY_("syntax error, unexpected %s");
1086 YY_("syntax error, unexpected %s, expecting %s");
1087 YY_("syntax error, unexpected %s, expecting %s or %s");
1088 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1089 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1090# endif
1091 char *yyfmt;
1092 char const *yyf;
1093 static char const yyunexpected[] = "syntax error, unexpected %s";
1094 static char const yyexpecting[] = ", expecting %s";
1095 static char const yyor[] = " or %s";
1096 char yyformat[sizeof yyunexpected
1097 + sizeof yyexpecting - 1
1098 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1099 * (sizeof yyor - 1))];
1100 char const *yyprefix = yyexpecting;
1101
1102 /* Start YYX at -YYN if negative to avoid negative indexes in
1103 YYCHECK. */
1104 int yyxbegin = yyn < 0 ? -yyn : 0;
1105
1106 /* Stay within bounds of both yycheck and yytname. */
1107 int yychecklim = YYLAST - yyn + 1;
1108 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1109 int yycount = 1;
1110
1111 yyarg[0] = yytname[yytype];
1112 yyfmt = yystpcpy (yyformat, yyunexpected);
1113
1114 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1115 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1116 {
1117 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1118 {
1119 yycount = 1;
1120 yysize = yysize0;
1121 yyformat[sizeof yyunexpected - 1] = '\0';
1122 break;
1123 }
1124 yyarg[yycount++] = yytname[yyx];
1125 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1126 yysize_overflow |= (yysize1 < yysize);
1127 yysize = yysize1;
1128 yyfmt = yystpcpy (yyfmt, yyprefix);
1129 yyprefix = yyor;
1130 }
1131
1132 yyf = YY_(yyformat);
1133 yysize1 = yysize + yystrlen (yyf);
1134 yysize_overflow |= (yysize1 < yysize);
1135 yysize = yysize1;
1136
1137 if (yysize_overflow)
1138 return YYSIZE_MAXIMUM;
1139
1140 if (yyresult)
1141 {
1142 /* Avoid sprintf, as that infringes on the user's name space.
1143 Don't have undefined behavior even if the translation
1144 produced a string with the wrong number of "%s"s. */
1145 char *yyp = yyresult;
1146 int yyi = 0;
1147 while ((*yyp = *yyf) != '\0')
1148 {
1149 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1150 {
1151 yyp += yytnamerr (yyp, yyarg[yyi++]);
1152 yyf += 2;
1153 }
1154 else
1155 {
1156 yyp++;
1157 yyf++;
1158 }
1159 }
1160 }
1161 return yysize;
1162 }
1c79356b 1163}
2d21ac55
A
1164#endif /* YYERROR_VERBOSE */
1165\f
1c79356b 1166
2d21ac55
A
1167/*-----------------------------------------------.
1168| Release the memory associated to this symbol. |
1169`-----------------------------------------------*/
1170
1171/*ARGSUSED*/
1172#if (defined __STDC__ || defined __C99__FUNC__ \
1173 || defined __cplusplus || defined _MSC_VER)
1174static void
1175yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1176#else
1177static void
1178yydestruct (yymsg, yytype, yyvaluep)
1179 const char *yymsg;
1180 int yytype;
1181 YYSTYPE *yyvaluep;
1c79356b 1182#endif
2d21ac55
A
1183{
1184 YYUSE (yyvaluep);
1185
1186 if (!yymsg)
1187 yymsg = "Deleting";
1188 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1189
1190 switch (yytype)
1191 {
1192
1193 default:
1194 break;
1195 }
1196}
1c79356b 1197\f
1c79356b 1198
2d21ac55 1199/* Prevent warnings from -Wmissing-prototypes. */
1c79356b
A
1200
1201#ifdef YYPARSE_PARAM
2d21ac55
A
1202#if defined __STDC__ || defined __cplusplus
1203int yyparse (void *YYPARSE_PARAM);
1c79356b 1204#else
2d21ac55 1205int yyparse ();
1c79356b 1206#endif
2d21ac55
A
1207#else /* ! YYPARSE_PARAM */
1208#if defined __STDC__ || defined __cplusplus
1209int yyparse (void);
1210#else
1211int yyparse ();
1c79356b 1212#endif
2d21ac55 1213#endif /* ! YYPARSE_PARAM */
1c79356b 1214
1c79356b 1215
1c79356b 1216
1c79356b 1217
1c79356b 1218
2d21ac55
A
1219
1220/*----------.
1221| yyparse. |
1222`----------*/
1223
1224#ifdef YYPARSE_PARAM
1225#if (defined __STDC__ || defined __C99__FUNC__ \
1226 || defined __cplusplus || defined _MSC_VER)
1227int
1228yyparse (void *YYPARSE_PARAM)
1c79356b 1229#else
2d21ac55
A
1230int
1231yyparse (YYPARSE_PARAM)
1232 void *YYPARSE_PARAM;
1c79356b 1233#endif
2d21ac55
A
1234#else /* ! YYPARSE_PARAM */
1235#if (defined __STDC__ || defined __C99__FUNC__ \
1236 || defined __cplusplus || defined _MSC_VER)
1237int
1238yyparse (void)
1239#else
1240int
1241yyparse ()
1c79356b 1242
1c79356b 1243#endif
2d21ac55
A
1244#endif
1245{
1246 /* The look-ahead symbol. */
1247int yychar;
1248
1249/* The semantic value of the look-ahead symbol. */
1250YYSTYPE yylval;
1251
1252/* Number of syntax errors so far. */
1253int yynerrs;
1254
1255 int yystate;
1256 int yyn;
1257 int yyresult;
1258 /* Number of tokens to shift before error messages enabled. */
1259 int yyerrstatus;
1260 /* Look-ahead token as an internal (translated) token number. */
1261 int yytoken = 0;
1262#if YYERROR_VERBOSE
1263 /* Buffer for error messages, and its allocated size. */
1264 char yymsgbuf[128];
1265 char *yymsg = yymsgbuf;
1266 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1c79356b
A
1267#endif
1268
2d21ac55
A
1269 /* Three stacks and their tools:
1270 `yyss': related to states,
1271 `yyvs': related to semantic values,
1272 `yyls': related to locations.
1c79356b 1273
2d21ac55
A
1274 Refer to the stacks thru separate pointers, to allow yyoverflow
1275 to reallocate them elsewhere. */
1c79356b 1276
2d21ac55
A
1277 /* The state stack. */
1278 yytype_int16 yyssa[YYINITDEPTH];
1279 yytype_int16 *yyss = yyssa;
1280 yytype_int16 *yyssp;
1281
1282 /* The semantic value stack. */
1283 YYSTYPE yyvsa[YYINITDEPTH];
1284 YYSTYPE *yyvs = yyvsa;
1285 YYSTYPE *yyvsp;
1286
1287
1288
1289#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1290
1291 YYSIZE_T yystacksize = YYINITDEPTH;
1292
1293 /* The variables used to return semantic value and location from the
1294 action routines. */
1295 YYSTYPE yyval;
1296
1297
1298 /* The number of symbols on the RHS of the reduced rule.
1299 Keep to zero when no symbol should be popped. */
1300 int yylen = 0;
1301
1302 YYDPRINTF ((stderr, "Starting parse\n"));
1c79356b
A
1303
1304 yystate = 0;
1305 yyerrstatus = 0;
1306 yynerrs = 0;
1307 yychar = YYEMPTY; /* Cause a token to be read. */
1308
1309 /* Initialize stack pointers.
1310 Waste one element of value and location stack
1311 so that they stay on the same level as the state stack.
1312 The wasted elements are never initialized. */
1313
2d21ac55 1314 yyssp = yyss;
1c79356b 1315 yyvsp = yyvs;
1c79356b 1316
2d21ac55 1317 goto yysetstate;
1c79356b 1318
2d21ac55
A
1319/*------------------------------------------------------------.
1320| yynewstate -- Push a new state, which is found in yystate. |
1321`------------------------------------------------------------*/
1322 yynewstate:
1323 /* In all cases, when you get here, the value and location stacks
1324 have just been pushed. So pushing a state here evens the stacks. */
1325 yyssp++;
1c79356b 1326
2d21ac55
A
1327 yysetstate:
1328 *yyssp = yystate;
1c79356b 1329
2d21ac55
A
1330 if (yyss + yystacksize - 1 <= yyssp)
1331 {
1c79356b 1332 /* Get the current used size of the three stacks, in elements. */
2d21ac55 1333 YYSIZE_T yysize = yyssp - yyss + 1;
1c79356b
A
1334
1335#ifdef yyoverflow
2d21ac55
A
1336 {
1337 /* Give user a chance to reallocate the stack. Use copies of
1338 these so that the &'s don't force the real ones into
1339 memory. */
1340 YYSTYPE *yyvs1 = yyvs;
1341 yytype_int16 *yyss1 = yyss;
1342
1343
1344 /* Each stack pointer address is followed by the size of the
1345 data in use in that stack, in bytes. This used to be a
1346 conditional around just the two extra args, but that might
1347 be undefined if yyoverflow is a macro. */
1348 yyoverflow (YY_("memory exhausted"),
1349 &yyss1, yysize * sizeof (*yyssp),
1350 &yyvs1, yysize * sizeof (*yyvsp),
1351
1352 &yystacksize);
1353
1354 yyss = yyss1;
1355 yyvs = yyvs1;
1356 }
1c79356b 1357#else /* no yyoverflow */
2d21ac55
A
1358# ifndef YYSTACK_RELOCATE
1359 goto yyexhaustedlab;
1360# else
1c79356b 1361 /* Extend the stack our own way. */
2d21ac55
A
1362 if (YYMAXDEPTH <= yystacksize)
1363 goto yyexhaustedlab;
1c79356b 1364 yystacksize *= 2;
2d21ac55 1365 if (YYMAXDEPTH < yystacksize)
1c79356b 1366 yystacksize = YYMAXDEPTH;
2d21ac55
A
1367
1368 {
1369 yytype_int16 *yyss1 = yyss;
1370 union yyalloc *yyptr =
1371 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1372 if (! yyptr)
1373 goto yyexhaustedlab;
1374 YYSTACK_RELOCATE (yyss);
1375 YYSTACK_RELOCATE (yyvs);
1376
1377# undef YYSTACK_RELOCATE
1378 if (yyss1 != yyssa)
1379 YYSTACK_FREE (yyss1);
1380 }
1381# endif
1c79356b
A
1382#endif /* no yyoverflow */
1383
2d21ac55
A
1384 yyssp = yyss + yysize - 1;
1385 yyvsp = yyvs + yysize - 1;
1c79356b 1386
1c79356b 1387
2d21ac55
A
1388 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1389 (unsigned long int) yystacksize));
1390
1391 if (yyss + yystacksize - 1 <= yyssp)
1c79356b
A
1392 YYABORT;
1393 }
1394
2d21ac55 1395 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1c79356b
A
1396
1397 goto yybackup;
1c79356b 1398
2d21ac55
A
1399/*-----------.
1400| yybackup. |
1401`-----------*/
1402yybackup:
1c79356b 1403
2d21ac55
A
1404 /* Do appropriate processing given the current state. Read a
1405 look-ahead token if we need one and don't already have one. */
1c79356b 1406
2d21ac55 1407 /* First try to decide what to do without reference to look-ahead token. */
1c79356b 1408 yyn = yypact[yystate];
2d21ac55 1409 if (yyn == YYPACT_NINF)
1c79356b
A
1410 goto yydefault;
1411
2d21ac55 1412 /* Not known => get a look-ahead token if don't already have one. */
1c79356b 1413
2d21ac55 1414 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1c79356b
A
1415 if (yychar == YYEMPTY)
1416 {
2d21ac55 1417 YYDPRINTF ((stderr, "Reading a token: "));
1c79356b
A
1418 yychar = YYLEX;
1419 }
1420
2d21ac55 1421 if (yychar <= YYEOF)
1c79356b 1422 {
2d21ac55
A
1423 yychar = yytoken = YYEOF;
1424 YYDPRINTF ((stderr, "Now at end of input.\n"));
1c79356b
A
1425 }
1426 else
1427 {
2d21ac55
A
1428 yytoken = YYTRANSLATE (yychar);
1429 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1c79356b
A
1430 }
1431
2d21ac55
A
1432 /* If the proper action on seeing token YYTOKEN is to reduce or to
1433 detect an error, take that action. */
1434 yyn += yytoken;
1435 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1c79356b 1436 goto yydefault;
1c79356b 1437 yyn = yytable[yyn];
2d21ac55 1438 if (yyn <= 0)
1c79356b 1439 {
2d21ac55 1440 if (yyn == 0 || yyn == YYTABLE_NINF)
1c79356b
A
1441 goto yyerrlab;
1442 yyn = -yyn;
1443 goto yyreduce;
1444 }
1c79356b
A
1445
1446 if (yyn == YYFINAL)
1447 YYACCEPT;
1448
2d21ac55
A
1449 /* Count tokens shifted since error; after three, turn off error
1450 status. */
1451 if (yyerrstatus)
1452 yyerrstatus--;
1c79356b 1453
2d21ac55
A
1454 /* Shift the look-ahead token. */
1455 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1c79356b 1456
2d21ac55 1457 /* Discard the shifted token unless it is eof. */
1c79356b
A
1458 if (yychar != YYEOF)
1459 yychar = YYEMPTY;
1460
2d21ac55 1461 yystate = yyn;
1c79356b 1462 *++yyvsp = yylval;
1c79356b 1463
1c79356b
A
1464 goto yynewstate;
1465
1c79356b 1466
2d21ac55
A
1467/*-----------------------------------------------------------.
1468| yydefault -- do the default action for the current state. |
1469`-----------------------------------------------------------*/
1470yydefault:
1c79356b
A
1471 yyn = yydefact[yystate];
1472 if (yyn == 0)
1473 goto yyerrlab;
2d21ac55
A
1474 goto yyreduce;
1475
1c79356b 1476
2d21ac55
A
1477/*-----------------------------.
1478| yyreduce -- Do a reduction. |
1479`-----------------------------*/
1c79356b 1480yyreduce:
2d21ac55 1481 /* yyn is the number of a rule to reduce with. */
1c79356b 1482 yylen = yyr2[yyn];
1c79356b 1483
2d21ac55
A
1484 /* If YYLEN is nonzero, implement the default value of the action:
1485 `$$ = $1'.
1c79356b 1486
2d21ac55
A
1487 Otherwise, the following line sets YYVAL to garbage.
1488 This behavior is undocumented and Bison
1489 users should not rely upon it. Assigning to YYVAL
1490 unconditionally makes the parser a bit smaller, and it avoids a
1491 GCC warning that YYVAL may be used uninitialized. */
1492 yyval = yyvsp[1-yylen];
1c79356b 1493
1c79356b 1494
2d21ac55
A
1495 YY_REDUCE_PRINT (yyn);
1496 switch (yyn)
1497 {
1498 case 2:
39236c6e 1499#line 149 "OSUnserializeXML.y"
2d21ac55 1500 { yyerror("unexpected end of buffer");
55e303ae 1501 YYERROR;
2d21ac55
A
1502 ;}
1503 break;
1504
1505 case 3:
39236c6e 1506#line 152 "OSUnserializeXML.y"
2d21ac55
A
1507 { STATE->parsedObject = (yyvsp[(1) - (1)])->object;
1508 (yyvsp[(1) - (1)])->object = 0;
1509 freeObject(STATE, (yyvsp[(1) - (1)]));
1c79356b 1510 YYACCEPT;
2d21ac55
A
1511 ;}
1512 break;
1513
1514 case 4:
39236c6e 1515#line 157 "OSUnserializeXML.y"
2d21ac55
A
1516 { yyerror("syntax error");
1517 YYERROR;
1518 ;}
1519 break;
1520
1521 case 5:
39236c6e
A
1522#line 162 "OSUnserializeXML.y"
1523 { (yyval) = buildDictionary(STATE, (yyvsp[(1) - (1)]));
1524
d190cdc3
A
1525 if (!yyval->object) {
1526 yyerror("buildDictionary");
1527 YYERROR;
1528 }
39236c6e
A
1529 STATE->parsedObjectCount++;
1530 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1531 yyerror("maximum object count");
1532 YYERROR;
1533 }
1534 ;}
2d21ac55
A
1535 break;
1536
1537 case 6:
d190cdc3 1538#line 174 "OSUnserializeXML.y"
39236c6e
A
1539 { (yyval) = buildArray(STATE, (yyvsp[(1) - (1)]));
1540
d190cdc3
A
1541 if (!yyval->object) {
1542 yyerror("buildArray");
1543 YYERROR;
1544 }
39236c6e
A
1545 STATE->parsedObjectCount++;
1546 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1547 yyerror("maximum object count");
1548 YYERROR;
1549 }
1550 ;}
2d21ac55
A
1551 break;
1552
1553 case 7:
d190cdc3 1554#line 186 "OSUnserializeXML.y"
39236c6e
A
1555 { (yyval) = buildSet(STATE, (yyvsp[(1) - (1)]));
1556
d190cdc3
A
1557 if (!yyval->object) {
1558 yyerror("buildSet");
1559 YYERROR;
1560 }
39236c6e
A
1561 STATE->parsedObjectCount++;
1562 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1563 yyerror("maximum object count");
1564 YYERROR;
1565 }
1566 ;}
2d21ac55
A
1567 break;
1568
1569 case 8:
d190cdc3 1570#line 198 "OSUnserializeXML.y"
39236c6e
A
1571 { (yyval) = buildString(STATE, (yyvsp[(1) - (1)]));
1572
d190cdc3
A
1573 if (!yyval->object) {
1574 yyerror("buildString");
1575 YYERROR;
1576 }
39236c6e
A
1577 STATE->parsedObjectCount++;
1578 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1579 yyerror("maximum object count");
1580 YYERROR;
1581 }
1582 ;}
2d21ac55
A
1583 break;
1584
1585 case 9:
d190cdc3 1586#line 210 "OSUnserializeXML.y"
39236c6e
A
1587 { (yyval) = buildData(STATE, (yyvsp[(1) - (1)]));
1588
d190cdc3
A
1589 if (!yyval->object) {
1590 yyerror("buildData");
1591 YYERROR;
1592 }
39236c6e
A
1593 STATE->parsedObjectCount++;
1594 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1595 yyerror("maximum object count");
1596 YYERROR;
1597 }
1598 ;}
2d21ac55
A
1599 break;
1600
1601 case 10:
d190cdc3 1602#line 222 "OSUnserializeXML.y"
39236c6e
A
1603 { (yyval) = buildNumber(STATE, (yyvsp[(1) - (1)]));
1604
d190cdc3
A
1605 if (!yyval->object) {
1606 yyerror("buildNumber");
1607 YYERROR;
1608 }
39236c6e
A
1609 STATE->parsedObjectCount++;
1610 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1611 yyerror("maximum object count");
1612 YYERROR;
1613 }
1614 ;}
2d21ac55
A
1615 break;
1616
1617 case 11:
d190cdc3 1618#line 234 "OSUnserializeXML.y"
39236c6e
A
1619 { (yyval) = buildBoolean(STATE, (yyvsp[(1) - (1)]));
1620
d190cdc3
A
1621 if (!yyval->object) {
1622 yyerror("buildBoolean");
1623 YYERROR;
1624 }
39236c6e
A
1625 STATE->parsedObjectCount++;
1626 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1627 yyerror("maximum object count");
1628 YYERROR;
1629 }
1630 ;}
2d21ac55
A
1631 break;
1632
1633 case 12:
d190cdc3 1634#line 246 "OSUnserializeXML.y"
2d21ac55
A
1635 { (yyval) = retrieveObject(STATE, (yyvsp[(1) - (1)])->idref);
1636 if ((yyval)) {
5ba3f43e
A
1637 STATE->retrievedObjectCount++;
1638 if (STATE->retrievedObjectCount > MAX_REFED_OBJECTS) {
1639 yyerror("maximum object reference count");
1640 YYERROR;
1641 }
2d21ac55 1642 (yyval)->object->retain();
1c79356b
A
1643 } else {
1644 yyerror("forward reference detected");
1645 YYERROR;
1646 }
2d21ac55 1647 freeObject(STATE, (yyvsp[(1) - (1)]));
39236c6e
A
1648
1649 STATE->parsedObjectCount++;
1650 if (STATE->parsedObjectCount > MAX_OBJECTS) {
1651 yyerror("maximum object count");
1652 YYERROR;
1653 }
2d21ac55
A
1654 ;}
1655 break;
1656
1657 case 13:
d190cdc3 1658#line 265 "OSUnserializeXML.y"
2d21ac55
A
1659 { (yyval) = (yyvsp[(1) - (2)]);
1660 (yyval)->elements = NULL;
1661 ;}
1662 break;
1663
1664 case 14:
d190cdc3 1665#line 268 "OSUnserializeXML.y"
2d21ac55
A
1666 { (yyval) = (yyvsp[(1) - (3)]);
1667 (yyval)->elements = (yyvsp[(2) - (3)]);
1668 ;}
1669 break;
1670
1671 case 17:
d190cdc3 1672#line 275 "OSUnserializeXML.y"
2d21ac55
A
1673 { (yyval) = (yyvsp[(2) - (2)]);
1674 (yyval)->next = (yyvsp[(1) - (2)]);
39236c6e
A
1675
1676 object_t *o;
1677 o = (yyval)->next;
1678 while (o) {
1679 if (o->key == (yyval)->key) {
1680 yyerror("duplicate dictionary key");
1681 YYERROR;
1682 }
1683 o = o->next;
1684 }
2d21ac55
A
1685 ;}
1686 break;
1687
1688 case 18:
d190cdc3 1689#line 290 "OSUnserializeXML.y"
2d21ac55 1690 { (yyval) = (yyvsp[(1) - (2)]);
39236c6e 1691 (yyval)->key = (OSSymbol *)(yyval)->object;
2d21ac55
A
1692 (yyval)->object = (yyvsp[(2) - (2)])->object;
1693 (yyval)->next = NULL;
1694 (yyvsp[(2) - (2)])->object = 0;
1695 freeObject(STATE, (yyvsp[(2) - (2)]));
1696 ;}
1697 break;
1698
1699 case 19:
d190cdc3 1700#line 299 "OSUnserializeXML.y"
39236c6e
A
1701 { (yyval) = buildSymbol(STATE, (yyvsp[(1) - (1)]));
1702
1703// STATE->parsedObjectCount++;
1704// if (STATE->parsedObjectCount > MAX_OBJECTS) {
1705// yyerror("maximum object count");
1706// YYERROR;
1707// }
1708 ;}
2d21ac55
A
1709 break;
1710
1711 case 20:
d190cdc3 1712#line 311 "OSUnserializeXML.y"
2d21ac55
A
1713 { (yyval) = (yyvsp[(1) - (2)]);
1714 (yyval)->elements = NULL;
1715 ;}
1716 break;
1717
1718 case 21:
d190cdc3 1719#line 314 "OSUnserializeXML.y"
2d21ac55
A
1720 { (yyval) = (yyvsp[(1) - (3)]);
1721 (yyval)->elements = (yyvsp[(2) - (3)]);
1722 ;}
1723 break;
1724
1725 case 23:
d190cdc3 1726#line 320 "OSUnserializeXML.y"
2d21ac55
A
1727 { (yyval) = (yyvsp[(1) - (2)]);
1728 (yyval)->elements = NULL;
1729 ;}
1730 break;
1731
1732 case 24:
d190cdc3 1733#line 323 "OSUnserializeXML.y"
2d21ac55
A
1734 { (yyval) = (yyvsp[(1) - (3)]);
1735 (yyval)->elements = (yyvsp[(2) - (3)]);
1736 ;}
1737 break;
1738
1739 case 26:
d190cdc3 1740#line 329 "OSUnserializeXML.y"
2d21ac55
A
1741 { (yyval) = (yyvsp[(1) - (1)]);
1742 (yyval)->next = NULL;
1743 ;}
1744 break;
1745
1746 case 27:
d190cdc3 1747#line 332 "OSUnserializeXML.y"
2d21ac55
A
1748 { (yyval) = (yyvsp[(2) - (2)]);
1749 (yyval)->next = (yyvsp[(1) - (2)]);
1750 ;}
1751 break;
1752
1753
1754/* Line 1267 of yacc.c. */
d190cdc3 1755#line 1699 "OSUnserializeXML.tab.c"
2d21ac55 1756 default: break;
1c79356b 1757 }
2d21ac55
A
1758 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1759
1760 YYPOPSTACK (yylen);
1761 yylen = 0;
1762 YY_STACK_PRINT (yyss, yyssp);
1c79356b
A
1763
1764 *++yyvsp = yyval;
1765
1c79356b 1766
2d21ac55
A
1767 /* Now `shift' the result of the reduction. Determine what state
1768 that goes to, based on the state we popped back to and the rule
1769 number reduced by. */
1c79356b
A
1770
1771 yyn = yyr1[yyn];
1772
2d21ac55
A
1773 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1774 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1c79356b
A
1775 yystate = yytable[yystate];
1776 else
2d21ac55 1777 yystate = yydefgoto[yyn - YYNTOKENS];
1c79356b
A
1778
1779 goto yynewstate;
1780
1c79356b 1781
2d21ac55
A
1782/*------------------------------------.
1783| yyerrlab -- here on detecting error |
1784`------------------------------------*/
1785yyerrlab:
1786 /* If not already recovering from an error, report this error. */
1787 if (!yyerrstatus)
1c79356b
A
1788 {
1789 ++yynerrs;
2d21ac55
A
1790#if ! YYERROR_VERBOSE
1791 yyerror (YY_("syntax error"));
1792#else
1793 {
1794 YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
1795 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
1796 {
1797 YYSIZE_T yyalloc = 2 * yysize;
1798 if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
1799 yyalloc = YYSTACK_ALLOC_MAXIMUM;
1800 if (yymsg != yymsgbuf)
1801 YYSTACK_FREE (yymsg);
1802 yymsg = (char *) YYSTACK_ALLOC (yyalloc);
1803 if (yymsg)
1804 yymsg_alloc = yyalloc;
1805 else
1806 {
1807 yymsg = yymsgbuf;
1808 yymsg_alloc = sizeof yymsgbuf;
1809 }
1810 }
1811
1812 if (0 < yysize && yysize <= yymsg_alloc)
1813 {
1814 (void) yysyntax_error (yymsg, yystate, yychar);
1815 yyerror (yymsg);
1816 }
1817 else
1818 {
1819 yyerror (YY_("syntax error"));
1820 if (yysize != 0)
1821 goto yyexhaustedlab;
1822 }
1823 }
1824#endif
1c79356b
A
1825 }
1826
2d21ac55 1827
1c79356b
A
1828
1829 if (yyerrstatus == 3)
1830 {
2d21ac55
A
1831 /* If just tried and failed to reuse look-ahead token after an
1832 error, discard it. */
1c79356b 1833
2d21ac55
A
1834 if (yychar <= YYEOF)
1835 {
1836 /* Return failure if at end of input. */
1837 if (yychar == YYEOF)
1838 YYABORT;
1839 }
1840 else
1841 {
1842 yydestruct ("Error: discarding",
1843 yytoken, &yylval);
1844 yychar = YYEMPTY;
1845 }
1c79356b
A
1846 }
1847
2d21ac55
A
1848 /* Else will try to reuse look-ahead token after shifting the error
1849 token. */
1850 goto yyerrlab1;
1c79356b 1851
1c79356b 1852
2d21ac55
A
1853/*---------------------------------------------------.
1854| yyerrorlab -- error raised explicitly by YYERROR. |
1855`---------------------------------------------------*/
1856yyerrorlab:
1c79356b 1857
2d21ac55
A
1858 /* Pacify compilers like GCC when the user code never invokes
1859 YYERROR and the label yyerrorlab therefore never appears in user
1860 code. */
1861 if (/*CONSTCOND*/ 0)
1862 goto yyerrorlab;
1c79356b 1863
2d21ac55
A
1864 /* Do not reclaim the symbols of the rule which action triggered
1865 this YYERROR. */
1866 YYPOPSTACK (yylen);
1867 yylen = 0;
1868 YY_STACK_PRINT (yyss, yyssp);
1869 yystate = *yyssp;
1870 goto yyerrlab1;
1c79356b 1871
1c79356b 1872
2d21ac55
A
1873/*-------------------------------------------------------------.
1874| yyerrlab1 -- common code for both syntax error and YYERROR. |
1875`-------------------------------------------------------------*/
1876yyerrlab1:
1877 yyerrstatus = 3; /* Each real token shifted decrements this. */
1c79356b 1878
2d21ac55 1879 for (;;)
1c79356b 1880 {
2d21ac55
A
1881 yyn = yypact[yystate];
1882 if (yyn != YYPACT_NINF)
1883 {
1884 yyn += YYTERROR;
1885 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1886 {
1887 yyn = yytable[yyn];
1888 if (0 < yyn)
1889 break;
1890 }
1891 }
1c79356b 1892
2d21ac55
A
1893 /* Pop the current state because it cannot handle the error token. */
1894 if (yyssp == yyss)
1895 YYABORT;
1c79356b 1896
1c79356b 1897
2d21ac55
A
1898 yydestruct ("Error: popping",
1899 yystos[yystate], yyvsp);
1900 YYPOPSTACK (1);
1901 yystate = *yyssp;
1902 YY_STACK_PRINT (yyss, yyssp);
1c79356b 1903 }
1c79356b
A
1904
1905 if (yyn == YYFINAL)
1906 YYACCEPT;
1907
1c79356b 1908 *++yyvsp = yylval;
2d21ac55
A
1909
1910
1911 /* Shift the error token. */
1912 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1c79356b
A
1913
1914 yystate = yyn;
1915 goto yynewstate;
1916
2d21ac55
A
1917
1918/*-------------------------------------.
1919| yyacceptlab -- YYACCEPT comes here. |
1920`-------------------------------------*/
1921yyacceptlab:
1922 yyresult = 0;
1923 goto yyreturn;
1924
1925/*-----------------------------------.
1926| yyabortlab -- YYABORT comes here. |
1927`-----------------------------------*/
1928yyabortlab:
1929 yyresult = 1;
1930 goto yyreturn;
1931
1932#ifndef yyoverflow
1933/*-------------------------------------------------.
1934| yyexhaustedlab -- memory exhaustion comes here. |
1935`-------------------------------------------------*/
1936yyexhaustedlab:
1937 yyerror (YY_("memory exhausted"));
1938 yyresult = 2;
1939 /* Fall through. */
1c79356b 1940#endif
1c79356b 1941
2d21ac55
A
1942yyreturn:
1943 if (yychar != YYEOF && yychar != YYEMPTY)
1944 yydestruct ("Cleanup: discarding lookahead",
1945 yytoken, &yylval);
1946 /* Do not reclaim the symbols of the rule which action triggered
1947 this YYABORT or YYACCEPT. */
1948 YYPOPSTACK (yylen);
1949 YY_STACK_PRINT (yyss, yyssp);
1950 while (yyssp != yyss)
1c79356b 1951 {
2d21ac55
A
1952 yydestruct ("Cleanup: popping",
1953 yystos[*yyssp], yyvsp);
1954 YYPOPSTACK (1);
1c79356b 1955 }
2d21ac55
A
1956#ifndef yyoverflow
1957 if (yyss != yyssa)
1958 YYSTACK_FREE (yyss);
1959#endif
1960#if YYERROR_VERBOSE
1961 if (yymsg != yymsgbuf)
1962 YYSTACK_FREE (yymsg);
1963#endif
1964 /* Make sure YYID is used. */
1965 return YYID (yyresult);
1c79356b 1966}
2d21ac55
A
1967
1968
d190cdc3 1969#line 354 "OSUnserializeXML.y"
1c79356b 1970
1c79356b
A
1971
1972int
b0d623f7 1973OSUnserializeerror(parser_state_t * state, const char *s) /* Called by yyparse on errors */
1c79356b 1974{
55e303ae 1975 if (state->errorString) {
b0d623f7 1976 char tempString[128];
55e303ae
A
1977 snprintf(tempString, 128, "OSUnserializeXML: %s near line %d\n", s, state->lineNumber);
1978 *(state->errorString) = OSString::withCString(tempString);
1979 }
b0d623f7 1980
55e303ae 1981 return 0;
1c79356b
A
1982}
1983
1984#define TAG_MAX_LENGTH 32
1985#define TAG_MAX_ATTRIBUTES 32
1986#define TAG_BAD 0
1987#define TAG_START 1
1988#define TAG_END 2
1989#define TAG_EMPTY 3
b0d623f7 1990#define TAG_IGNORE 4
1c79356b 1991
55e303ae
A
1992#define currentChar() (state->parseBuffer[state->parseBufferIndex])
1993#define nextChar() (state->parseBuffer[++state->parseBufferIndex])
1994#define prevChar() (state->parseBuffer[state->parseBufferIndex - 1])
1995
1996#define isSpace(c) ((c) == ' ' || (c) == '\t')
1997#define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1998#define isDigit(c) ((c) >= '0' && (c) <= '9')
1999#define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
2000#define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
2001#define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
2002
1c79356b 2003static int
55e303ae
A
2004getTag(parser_state_t *state,
2005 char tag[TAG_MAX_LENGTH],
1c79356b
A
2006 int *attributeCount,
2007 char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH],
2008 char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH] )
2009{
55e303ae 2010 int length = 0;
1c79356b
A
2011 int c = currentChar();
2012 int tagType = TAG_START;
2013
2014 *attributeCount = 0;
2015
2016 if (c != '<') return TAG_BAD;
2017 c = nextChar(); // skip '<'
2018
1c79356b 2019
b0d623f7
A
2020 // <!TAG declarations >
2021 // <!-- comments -->
2022 if (c == '!') {
2023 c = nextChar();
2024 bool isComment = (c == '-') && ((c = nextChar()) != 0) && (c == '-');
2025 if (!isComment && !isAlpha(c)) return TAG_BAD; // <!1, <!-A, <!eos
2026
2027 while (c && (c = nextChar()) != 0) {
2028 if (c == '\n') state->lineNumber++;
2029 if (isComment) {
2030 if (c != '-') continue;
2031 c = nextChar();
2032 if (c != '-') continue;
2033 c = nextChar();
2034 }
2035 if (c == '>') {
2036 (void)nextChar();
2037 return TAG_IGNORE;
2038 }
2039 if (isComment) break;
2040 }
2041 return TAG_BAD;
2042 }
2043
2044 else
2045
2046 // <? Processing Instructions ?>
2047 if (c == '?') {
2048 while ((c = nextChar()) != 0) {
2049 if (c == '\n') state->lineNumber++;
2050 if (c != '?') continue;
2051 c = nextChar();
39037602 2052 if (!c) return TAG_IGNORE;
b0d623f7
A
2053 if (c == '>') {
2054 (void)nextChar();
2055 return TAG_IGNORE;
2056 }
2057 }
2058 return TAG_BAD;
2059 }
2060
2061 else
2062
2063 // </ end tag >
1c79356b
A
2064 if (c == '/') {
2065 c = nextChar(); // skip '/'
2066 tagType = TAG_END;
2067 }
2068 if (!isAlpha(c)) return TAG_BAD;
2069
2070 /* find end of tag while copying it */
2071 while (isAlphaNumeric(c)) {
2072 tag[length++] = c;
2073 c = nextChar();
2074 if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
2075 }
2076
2077 tag[length] = 0;
2078
55e303ae 2079// printf("tag %s, type %d\n", tag, tagType);
1c79356b
A
2080
2081 // look for attributes of the form attribute = "value" ...
2082 while ((c != '>') && (c != '/')) {
2083 while (isSpace(c)) c = nextChar();
2084
2085 length = 0;
2086 while (isAlphaNumeric(c)) {
2087 attributes[*attributeCount][length++] = c;
2088 if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
2089 c = nextChar();
2090 }
2091 attributes[*attributeCount][length] = 0;
2092
2093 while (isSpace(c)) c = nextChar();
2094
2095 if (c != '=') return TAG_BAD;
2096 c = nextChar();
2097
2098 while (isSpace(c)) c = nextChar();
2099
2100 if (c != '"') return TAG_BAD;
2101 c = nextChar();
2102 length = 0;
2103 while (c != '"') {
2104 values[*attributeCount][length++] = c;
2105 if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
2106 c = nextChar();
39037602 2107 if (!c) return TAG_BAD;
1c79356b
A
2108 }
2109 values[*attributeCount][length] = 0;
2110
2111 c = nextChar(); // skip closing quote
2112
55e303ae
A
2113// printf(" attribute '%s' = '%s', nextchar = '%c'\n",
2114// attributes[*attributeCount], values[*attributeCount], c);
1c79356b
A
2115
2116 (*attributeCount)++;
2117 if (*attributeCount >= TAG_MAX_ATTRIBUTES) return TAG_BAD;
2118 }
2119
2120 if (c == '/') {
2121 c = nextChar(); // skip '/'
2122 tagType = TAG_EMPTY;
2123 }
2124 if (c != '>') return TAG_BAD;
2125 c = nextChar(); // skip '>'
2126
2127 return tagType;
2128}
2129
2130static char *
55e303ae 2131getString(parser_state_t *state)
1c79356b
A
2132{
2133 int c = currentChar();
55e303ae 2134 int start, length, i, j;
1c79356b
A
2135 char * tempString;
2136
55e303ae 2137 start = state->parseBufferIndex;
1c79356b
A
2138 /* find end of string */
2139
2140 while (c != 0) {
55e303ae 2141 if (c == '\n') state->lineNumber++;
1c79356b
A
2142 if (c == '<') {
2143 break;
2144 }
2145 c = nextChar();
2146 }
2147
2148 if (c != '<') return 0;
2149
55e303ae 2150 length = state->parseBufferIndex - start;
1c79356b
A
2151
2152 /* copy to null terminated buffer */
2153 tempString = (char *)malloc(length + 1);
2154 if (tempString == 0) {
2155 printf("OSUnserializeXML: can't alloc temp memory\n");
55e303ae 2156 goto error;
1c79356b
A
2157 }
2158
2159 // copy out string in tempString
2160 // "&amp;" -> '&', "&lt;" -> '<', "&gt;" -> '>'
2161
2162 i = j = 0;
2163 while (i < length) {
55e303ae 2164 c = state->parseBuffer[start + i++];
1c79356b
A
2165 if (c != '&') {
2166 tempString[j++] = c;
2167 } else {
2168 if ((i+3) > length) goto error;
55e303ae 2169 c = state->parseBuffer[start + i++];
1c79356b 2170 if (c == 'l') {
55e303ae
A
2171 if (state->parseBuffer[start + i++] != 't') goto error;
2172 if (state->parseBuffer[start + i++] != ';') goto error;
1c79356b
A
2173 tempString[j++] = '<';
2174 continue;
2175 }
2176 if (c == 'g') {
55e303ae
A
2177 if (state->parseBuffer[start + i++] != 't') goto error;
2178 if (state->parseBuffer[start + i++] != ';') goto error;
1c79356b
A
2179 tempString[j++] = '>';
2180 continue;
2181 }
2182 if ((i+3) > length) goto error;
2183 if (c == 'a') {
55e303ae
A
2184 if (state->parseBuffer[start + i++] != 'm') goto error;
2185 if (state->parseBuffer[start + i++] != 'p') goto error;
2186 if (state->parseBuffer[start + i++] != ';') goto error;
1c79356b
A
2187 tempString[j++] = '&';
2188 continue;
2189 }
2190 goto error;
2191 }
2192 }
2193 tempString[j] = 0;
2194
55e303ae 2195// printf("string %s\n", tempString);
1c79356b
A
2196
2197 return tempString;
2198
2199error:
2200 if (tempString) free(tempString);
2201 return 0;
2202}
2203
2204static long long
55e303ae 2205getNumber(parser_state_t *state)
1c79356b
A
2206{
2207 unsigned long long n = 0;
2208 int base = 10;
91447636 2209 bool negate = false;
1c79356b
A
2210 int c = currentChar();
2211
1c79356b
A
2212 if (c == '0') {
2213 c = nextChar();
2214 if (c == 'x') {
2215 base = 16;
2216 c = nextChar();
2217 }
2218 }
2219 if (base == 10) {
91447636
A
2220 if (c == '-') {
2221 negate = true;
2222 c = nextChar();
2223 }
1c79356b
A
2224 while(isDigit(c)) {
2225 n = (n * base + c - '0');
2226 c = nextChar();
2227 }
91447636
A
2228 if (negate) {
2229 n = (unsigned long long)((long long)n * (long long)-1);
2230 }
1c79356b
A
2231 } else {
2232 while(isHexDigit(c)) {
2233 if (isDigit(c)) {
2234 n = (n * base + c - '0');
2235 } else {
2236 n = (n * base + 0xa + c - 'a');
2237 }
2238 c = nextChar();
2239 }
2240 }
55e303ae 2241// printf("number 0x%x\n", (unsigned long)n);
1c79356b
A
2242 return n;
2243}
2244
2245// taken from CFXMLParsing/CFPropertyList.c
2246
2247static const signed char __CFPLDataDecodeTable[128] = {
2248 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
2249 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
2250 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
2251 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
2252 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
2253 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
2254 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
2255 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
2256 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
2257 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
2258 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
2259 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
2260 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
2261 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
2262 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
2263 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
2264};
2265
55e303ae 2266#define DATA_ALLOC_SIZE 4096
1c79356b
A
2267
2268static void *
55e303ae 2269getCFEncodedData(parser_state_t *state, unsigned int *size)
1c79356b
A
2270{
2271 int numeq = 0, acc = 0, cntr = 0;
2272 int tmpbufpos = 0, tmpbuflen = 0;
55e303ae 2273 unsigned char *tmpbuf = (unsigned char *)malloc(DATA_ALLOC_SIZE);
1c79356b
A
2274
2275 int c = currentChar();
2276 *size = 0;
2277
2278 while (c != '<') {
2279 c &= 0x7f;
2280 if (c == 0) {
2281 free(tmpbuf);
2282 return 0;
2283 }
2284 if (c == '=') numeq++; else numeq = 0;
55e303ae 2285 if (c == '\n') state->lineNumber++;
1c79356b
A
2286 if (__CFPLDataDecodeTable[c] < 0) {
2287 c = nextChar();
2288 continue;
2289 }
2290 cntr++;
2291 acc <<= 6;
2292 acc += __CFPLDataDecodeTable[c];
2293 if (0 == (cntr & 0x3)) {
2294 if (tmpbuflen <= tmpbufpos + 2) {
55e303ae 2295 tmpbuflen += DATA_ALLOC_SIZE;
1c79356b
A
2296 tmpbuf = (unsigned char *)realloc(tmpbuf, tmpbuflen);
2297 }
2298 tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
2299 if (numeq < 2)
2300 tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
2301 if (numeq < 1)
2302 tmpbuf[tmpbufpos++] = acc & 0xff;
2303 }
2304 c = nextChar();
2305 }
2306 *size = tmpbufpos;
55e303ae
A
2307 if (*size == 0) {
2308 free(tmpbuf);
2309 return 0;
2310 }
1c79356b
A
2311 return tmpbuf;
2312}
2313
2314static void *
55e303ae 2315getHexData(parser_state_t *state, unsigned int *size)
1c79356b
A
2316{
2317 int c;
2318 unsigned char *d, *start, *lastStart;
2319
55e303ae 2320 start = lastStart = d = (unsigned char *)malloc(DATA_ALLOC_SIZE);
1c79356b
A
2321 c = currentChar();
2322
2323 while (c != '<') {
2324
2325 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
2326 if (c == '\n') {
55e303ae 2327 state->lineNumber++;
1c79356b
A
2328 c = nextChar();
2329 continue;
2330 }
2331
2332 // get high nibble
2333 if (isDigit(c)) {
2334 *d = (c - '0') << 4;
2335 } else if (isAlphaDigit(c)) {
2336 *d = (0xa + (c - 'a')) << 4;
2337 } else {
2338 goto error;
2339 }
2340
2341 // get low nibble
2342 c = nextChar();
2343 if (isDigit(c)) {
2344 *d |= c - '0';
2345 } else if (isAlphaDigit(c)) {
2346 *d |= 0xa + (c - 'a');
2347 } else {
2348 goto error;
2349 }
2350
2351 d++;
55e303ae 2352 if ((d - lastStart) >= DATA_ALLOC_SIZE) {
1c79356b 2353 int oldsize = d - start;
55e303ae 2354 start = (unsigned char *)realloc(start, oldsize + DATA_ALLOC_SIZE);
1c79356b
A
2355 d = lastStart = start + oldsize;
2356 }
2357 c = nextChar();
2358 }
2359
2360 *size = d - start;
2361 return start;
2362
2363 error:
2364
2365 *size = 0;
2366 free(start);
2367 return 0;
2368}
2369
2370static int
55e303ae 2371yylex(YYSTYPE *lvalp, parser_state_t *state)
1c79356b 2372{
55e303ae 2373 int c, i;
1c79356b
A
2374 int tagType;
2375 char tag[TAG_MAX_LENGTH];
2376 int attributeCount;
2377 char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
2378 char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
55e303ae 2379 object_t *object;
1c79356b
A
2380
2381 top:
2382 c = currentChar();
2383
2384 /* skip white space */
2385 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
2386
2387 /* keep track of line number, don't return \n's */
2388 if (c == '\n') {
55e303ae 2389 STATE->lineNumber++;
1c79356b
A
2390 (void)nextChar();
2391 goto top;
2392 }
1c79356b 2393
55e303ae
A
2394 // end of the buffer?
2395 if (!c) return 0;
2396
2397 tagType = getTag(STATE, tag, &attributeCount, attributes, values);
1c79356b 2398 if (tagType == TAG_BAD) return SYNTAX_ERROR;
b0d623f7 2399 if (tagType == TAG_IGNORE) goto top;
1c79356b
A
2400
2401 // handle allocation and check for "ID" and "IDREF" tags up front
55e303ae
A
2402 *lvalp = object = newObject(STATE);
2403 object->idref = -1;
2404 for (i=0; i < attributeCount; i++) {
1c79356b
A
2405 if (attributes[i][0] == 'I' && attributes[i][1] == 'D') {
2406 // check for idref's, note: we ignore the tag, for
2407 // this to work correctly, all idrefs must be unique
2408 // across the whole serialization
2409 if (attributes[i][2] == 'R' && attributes[i][3] == 'E' &&
2410 attributes[i][4] == 'F' && !attributes[i][5]) {
2411 if (tagType != TAG_EMPTY) return SYNTAX_ERROR;
55e303ae 2412 object->idref = strtol(values[i], NULL, 0);
1c79356b
A
2413 return IDREF;
2414 }
2415 // check for id's
2416 if (!attributes[i][2]) {
55e303ae 2417 object->idref = strtol(values[i], NULL, 0);
1c79356b
A
2418 } else {
2419 return SYNTAX_ERROR;
2420 }
2421 }
2422 }
2423
2424 switch (*tag) {
2425 case 'a':
2426 if (!strcmp(tag, "array")) {
2427 if (tagType == TAG_EMPTY) {
55e303ae 2428 object->elements = NULL;
1c79356b
A
2429 return ARRAY;
2430 }
2431 return (tagType == TAG_START) ? '(' : ')';
2432 }
2433 break;
2434 case 'd':
2435 if (!strcmp(tag, "dict")) {
2436 if (tagType == TAG_EMPTY) {
55e303ae 2437 object->elements = NULL;
1c79356b
A
2438 return DICTIONARY;
2439 }
2440 return (tagType == TAG_START) ? '{' : '}';
2441 }
2442 if (!strcmp(tag, "data")) {
2443 unsigned int size;
1c79356b 2444 if (tagType == TAG_EMPTY) {
55e303ae
A
2445 object->data = NULL;
2446 object->size = 0;
1c79356b
A
2447 return DATA;
2448 }
55e303ae
A
2449
2450 bool isHexFormat = false;
2d21ac55 2451 for (i=0; i < attributeCount; i++) {
1c79356b 2452 if (!strcmp(attributes[i], "format") && !strcmp(values[i], "hex")) {
55e303ae 2453 isHexFormat = true;
1c79356b
A
2454 break;
2455 }
2456 }
2457 // CF encoded is the default form
55e303ae
A
2458 if (isHexFormat) {
2459 object->data = getHexData(STATE, &size);
1c79356b 2460 } else {
55e303ae 2461 object->data = getCFEncodedData(STATE, &size);
1c79356b 2462 }
55e303ae
A
2463 object->size = size;
2464 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "data")) {
1c79356b
A
2465 return SYNTAX_ERROR;
2466 }
2467 return DATA;
2468 }
2469 break;
2470 case 'f':
2471 if (!strcmp(tag, "false")) {
2472 if (tagType == TAG_EMPTY) {
55e303ae 2473 object->number = 0;
1c79356b
A
2474 return BOOLEAN;
2475 }
2476 }
2477 break;
2478 case 'i':
2479 if (!strcmp(tag, "integer")) {
55e303ae
A
2480 object->size = 64; // default
2481 for (i=0; i < attributeCount; i++) {
1c79356b 2482 if (!strcmp(attributes[i], "size")) {
55e303ae 2483 object->size = strtoul(values[i], NULL, 0);
1c79356b
A
2484 }
2485 }
2486 if (tagType == TAG_EMPTY) {
55e303ae 2487 object->number = 0;
1c79356b
A
2488 return NUMBER;
2489 }
55e303ae
A
2490 object->number = getNumber(STATE);
2491 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "integer")) {
1c79356b
A
2492 return SYNTAX_ERROR;
2493 }
2494 return NUMBER;
2495 }
2496 break;
2497 case 'k':
2498 if (!strcmp(tag, "key")) {
2499 if (tagType == TAG_EMPTY) return SYNTAX_ERROR;
55e303ae
A
2500 object->string = getString(STATE);
2501 if (!object->string) {
1c79356b
A
2502 return SYNTAX_ERROR;
2503 }
55e303ae 2504 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
1c79356b
A
2505 || strcmp(tag, "key")) {
2506 return SYNTAX_ERROR;
2507 }
2508 return KEY;
2509 }
2510 break;
2511 case 'p':
2512 if (!strcmp(tag, "plist")) {
55e303ae 2513 freeObject(STATE, object);
1c79356b
A
2514 goto top;
2515 }
2516 break;
2517 case 's':
2518 if (!strcmp(tag, "string")) {
2519 if (tagType == TAG_EMPTY) {
55e303ae
A
2520 object->string = (char *)malloc(1);
2521 object->string[0] = 0;
1c79356b
A
2522 return STRING;
2523 }
55e303ae
A
2524 object->string = getString(STATE);
2525 if (!object->string) {
1c79356b
A
2526 return SYNTAX_ERROR;
2527 }
55e303ae 2528 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
1c79356b
A
2529 || strcmp(tag, "string")) {
2530 return SYNTAX_ERROR;
2531 }
2532 return STRING;
2533 }
2534 if (!strcmp(tag, "set")) {
2535 if (tagType == TAG_EMPTY) {
55e303ae 2536 object->elements = NULL;
1c79356b
A
2537 return SET;;
2538 }
2539 if (tagType == TAG_START) {
2540 return '[';
2541 } else {
2542 return ']';
2543 }
2544 }
2545 break;
2546 case 't':
2547 if (!strcmp(tag, "true")) {
2548 if (tagType == TAG_EMPTY) {
55e303ae 2549 object->number = 1;
1c79356b
A
2550 return BOOLEAN;
2551 }
2552 }
2553 break;
1c79356b
A
2554 }
2555
55e303ae 2556 return SYNTAX_ERROR;
1c79356b
A
2557}
2558
2559// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2560// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2561// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2562
2563// "java" like allocation, if this code hits a syntax error in the
2564// the middle of the parsed string we just bail with pointers hanging
55e303ae 2565// all over place, this code helps keeps it all together
1c79356b 2566
55e303ae 2567//static int object_count = 0;
1c79356b
A
2568
2569object_t *
55e303ae 2570newObject(parser_state_t *state)
1c79356b
A
2571{
2572 object_t *o;
2573
55e303ae
A
2574 if (state->freeObjects) {
2575 o = state->freeObjects;
2576 state->freeObjects = state->freeObjects->next;
1c79356b
A
2577 } else {
2578 o = (object_t *)malloc(sizeof(object_t));
55e303ae 2579// object_count++;
1c79356b 2580 bzero(o, sizeof(object_t));
55e303ae
A
2581 o->free = state->objects;
2582 state->objects = o;
1c79356b
A
2583 }
2584
2585 return o;
2586}
2587
2588void
55e303ae 2589freeObject(parser_state_t * state, object_t *o)
1c79356b 2590{
55e303ae
A
2591 o->next = state->freeObjects;
2592 state->freeObjects = o;
1c79356b
A
2593}
2594
2595void
55e303ae 2596cleanupObjects(parser_state_t *state)
1c79356b 2597{
55e303ae 2598 object_t *t, *o = state->objects;
1c79356b
A
2599
2600 while (o) {
2601 if (o->object) {
55e303ae 2602// printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
1c79356b
A
2603 o->object->release();
2604 }
2605 if (o->data) {
55e303ae 2606// printf("OSUnserializeXML: freeing object o=%x data=%x\n", (int)o, (int)o->data);
1c79356b
A
2607 free(o->data);
2608 }
2609 if (o->key) {
55e303ae 2610// printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
1c79356b
A
2611 o->key->release();
2612 }
2613 if (o->string) {
55e303ae 2614// printf("OSUnserializeXML: freeing object o=%x string=%x\n", (int)o, (int)o->string);
1c79356b
A
2615 free(o->string);
2616 }
2617
2618 t = o;
2619 o = o->free;
2620 free(t);
55e303ae 2621// object_count--;
1c79356b 2622 }
55e303ae 2623// printf("object_count = %d\n", object_count);
1c79356b
A
2624}
2625
2626// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2627// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2628// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2629
1c79356b 2630static void
55e303ae 2631rememberObject(parser_state_t *state, int tag, OSObject *o)
1c79356b
A
2632{
2633 char key[16];
55e303ae 2634 snprintf(key, 16, "%u", tag);
1c79356b 2635
55e303ae 2636// printf("remember key %s\n", key);
1c79356b 2637
55e303ae 2638 state->tags->setObject(key, o);
1c79356b
A
2639}
2640
2641static object_t *
55e303ae 2642retrieveObject(parser_state_t *state, int tag)
1c79356b 2643{
55e303ae
A
2644 OSObject *ref;
2645 object_t *o;
1c79356b 2646 char key[16];
55e303ae 2647 snprintf(key, 16, "%u", tag);
1c79356b 2648
55e303ae 2649// printf("retrieve key '%s'\n", key);
1c79356b 2650
55e303ae 2651 ref = state->tags->getObject(key);
1c79356b
A
2652 if (!ref) return 0;
2653
55e303ae 2654 o = newObject(state);
1c79356b
A
2655 o->object = ref;
2656 return o;
2657}
2658
2659// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2660// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2661// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2662
2663object_t *
55e303ae 2664buildDictionary(parser_state_t *state, object_t * header)
1c79356b
A
2665{
2666 object_t *o, *t;
2667 int count = 0;
55e303ae 2668 OSDictionary *dict;
1c79356b
A
2669
2670 // get count and reverse order
2671 o = header->elements;
2672 header->elements = 0;
2673 while (o) {
2674 count++;
2675 t = o;
2676 o = o->next;
2677
2678 t->next = header->elements;
2679 header->elements = t;
2680 }
2681
55e303ae
A
2682 dict = OSDictionary::withCapacity(count);
2683 if (header->idref >= 0) rememberObject(state, header->idref, dict);
1c79356b
A
2684
2685 o = header->elements;
2686 while (o) {
55e303ae
A
2687 dict->setObject(o->key, o->object);
2688
1c79356b 2689 o->key->release();
55e303ae 2690 o->object->release();
1c79356b 2691 o->key = 0;
55e303ae
A
2692 o->object = 0;
2693
1c79356b
A
2694 t = o;
2695 o = o->next;
55e303ae 2696 freeObject(state, t);
1c79356b
A
2697 }
2698 o = header;
55e303ae 2699 o->object = dict;
1c79356b
A
2700 return o;
2701};
2702
2703object_t *
55e303ae 2704buildArray(parser_state_t *state, object_t * header)
1c79356b
A
2705{
2706 object_t *o, *t;
2707 int count = 0;
55e303ae 2708 OSArray *array;
1c79356b
A
2709
2710 // get count and reverse order
2711 o = header->elements;
2712 header->elements = 0;
2713 while (o) {
2714 count++;
2715 t = o;
2716 o = o->next;
2717
2718 t->next = header->elements;
2719 header->elements = t;
2720 }
2721
55e303ae
A
2722 array = OSArray::withCapacity(count);
2723 if (header->idref >= 0) rememberObject(state, header->idref, array);
1c79356b
A
2724
2725 o = header->elements;
2726 while (o) {
55e303ae
A
2727 array->setObject(o->object);
2728
1c79356b
A
2729 o->object->release();
2730 o->object = 0;
55e303ae 2731
1c79356b
A
2732 t = o;
2733 o = o->next;
55e303ae 2734 freeObject(state, t);
1c79356b
A
2735 }
2736 o = header;
55e303ae 2737 o->object = array;
1c79356b
A
2738 return o;
2739};
2740
2741object_t *
55e303ae 2742buildSet(parser_state_t *state, object_t *header)
1c79356b 2743{
55e303ae 2744 object_t *o = buildArray(state, header);
1c79356b 2745
55e303ae
A
2746 OSArray *array = (OSArray *)o->object;
2747 OSSet *set = OSSet::withArray(array, array->getCapacity());
1c79356b 2748
55e303ae
A
2749 // write over the reference created in buildArray
2750 if (header->idref >= 0) rememberObject(state, header->idref, set);
1c79356b 2751
55e303ae
A
2752 array->release();
2753 o->object = set;
1c79356b
A
2754 return o;
2755};
2756
2757object_t *
55e303ae 2758buildString(parser_state_t *state, object_t *o)
1c79356b 2759{
55e303ae 2760 OSString *string;
1c79356b 2761
55e303ae
A
2762 string = OSString::withCString(o->string);
2763 if (o->idref >= 0) rememberObject(state, o->idref, string);
1c79356b
A
2764
2765 free(o->string);
2766 o->string = 0;
55e303ae 2767 o->object = string;
1c79356b
A
2768
2769 return o;
2770};
2771
39236c6e
A
2772object_t *
2773buildSymbol(parser_state_t *state, object_t *o)
2774{
2775 OSSymbol *symbol;
2776
a39ff7e2 2777 symbol = const_cast<OSSymbol *>(OSSymbol::withCString(o->string));
39236c6e
A
2778 if (o->idref >= 0) rememberObject(state, o->idref, symbol);
2779
2780 free(o->string);
2781 o->string = 0;
2782 o->object = symbol;
2783
2784 return o;
2785};
2786
1c79356b 2787object_t *
55e303ae 2788buildData(parser_state_t *state, object_t *o)
1c79356b 2789{
55e303ae 2790 OSData *data;
1c79356b
A
2791
2792 if (o->size) {
55e303ae 2793 data = OSData::withBytes(o->data, o->size);
1c79356b 2794 } else {
55e303ae 2795 data = OSData::withCapacity(0);
1c79356b 2796 }
55e303ae 2797 if (o->idref >= 0) rememberObject(state, o->idref, data);
1c79356b 2798
55e303ae 2799 if (o->size) free(o->data);
1c79356b 2800 o->data = 0;
55e303ae 2801 o->object = data;
1c79356b
A
2802 return o;
2803};
2804
2805object_t *
55e303ae 2806buildNumber(parser_state_t *state, object_t *o)
1c79356b 2807{
55e303ae 2808 OSNumber *number = OSNumber::withNumber(o->number, o->size);
1c79356b 2809
55e303ae 2810 if (o->idref >= 0) rememberObject(state, o->idref, number);
1c79356b 2811
55e303ae 2812 o->object = number;
1c79356b
A
2813 return o;
2814};
2815
2816object_t *
b0d623f7 2817buildBoolean(parser_state_t *state __unused, object_t *o)
1c79356b 2818{
55e303ae
A
2819 o->object = ((o->number == 0) ? kOSBooleanFalse : kOSBooleanTrue);
2820 o->object->retain();
1c79356b
A
2821 return o;
2822};
2823
1c79356b
A
2824OSObject*
2825OSUnserializeXML(const char *buffer, OSString **errorString)
2826{
2827 OSObject *object;
2828
fe8ab488
A
2829 if (!buffer) return 0;
2830 parser_state_t *state = (parser_state_t *)malloc(sizeof(parser_state_t));
2831 if (!state) return 0;
1c79356b 2832
55e303ae
A
2833 // just in case
2834 if (errorString) *errorString = NULL;
1c79356b 2835
55e303ae
A
2836 state->parseBuffer = buffer;
2837 state->parseBufferIndex = 0;
2838 state->lineNumber = 1;
2839 state->objects = 0;
2840 state->freeObjects = 0;
2841 state->tags = OSDictionary::withCapacity(128);
2842 state->errorString = errorString;
2843 state->parsedObject = 0;
39236c6e 2844 state->parsedObjectCount = 0;
5ba3f43e 2845 state->retrievedObjectCount = 0;
55e303ae
A
2846
2847 (void)yyparse((void *)state);
2848
2849 object = state->parsedObject;
1c79356b 2850
55e303ae
A
2851 cleanupObjects(state);
2852 state->tags->release();
2853 free(state);
1c79356b
A
2854
2855 return object;
2856}
2857
fe8ab488
A
2858#include <libkern/OSSerializeBinary.h>
2859
39236c6e
A
2860OSObject*
2861OSUnserializeXML(const char *buffer, size_t bufferSize, OSString **errorString)
2862{
fe8ab488
A
2863 if (!buffer) return (0);
2864 if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (0);
2865
2866 if (!strcmp(kOSSerializeBinarySignature, buffer)) return OSUnserializeBinary(buffer, bufferSize, errorString);
39236c6e
A
2867
2868 // XML must be null terminated
fe8ab488 2869 if (buffer[bufferSize - 1]) return 0;
39236c6e
A
2870
2871 return OSUnserializeXML(buffer, errorString);
2872}
2873
1c79356b
A
2874
2875//
2876//
2877//
2878//
2879//
2880// DO NOT EDIT OSUnserializeXML.cpp!
2881//
2882// this means you!
2883//
2884//
2885//
2886//
2887//
2d21ac55 2888