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