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