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