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