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