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