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