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