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