1/* 2 * Copyright (c) 2000-2006 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// 52// this means you! 53// 54// 55// 56// 57 58/* A Bison parser, made from OSUnserialize.y 59 by GNU Bison version 1.28 */ 60 61#define YYBISON 1 /* Identify Bison output. */ 62 63#define yyparse OSUnserializeparse 64#define yylex OSUnserializelex 65#define yyerror OSUnserializeerror 66#define yylval OSUnserializelval 67#define yychar OSUnserializechar 68#define yydebug OSUnserializedebug 69#define yynerrs OSUnserializenerrs 70#define NUMBER 257 71#define STRING 258 72#define DATA 259 73#define BOOLEAN 260 74#define SYNTAX_ERROR 261 75 76#line 54 "OSUnserialize.y" 77 78#include <libkern/c++/OSMetaClass.h> 79#include <libkern/c++/OSContainers.h> 80#include <libkern/c++/OSLib.h> 81 82typedef struct object { 83 struct object *next; 84 struct object *prev; 85 void *object; 86 int size; // for data 87 union { 88 void *key; // for dictionary 89 long long offset; // for offset 90 } u; 91 92} object_t; 93 94static int yyparse(); 95static int yyerror(char *s); 96static int yylex(); 97 98static object_t * newObject(); 99static void freeObject(object_t *o); 100 101static OSObject *buildOSDictionary(object_t *); 102static OSObject *buildOSArray(object_t *); 103static OSObject *buildOSSet(object_t *); 104static OSObject *buildOSString(object_t *); 105static OSObject *buildOSData(object_t *); 106static OSObject *buildOSOffset(object_t *); 107static OSObject *buildOSBoolean(object_t *o); 108 109static void rememberObject(int, object_t *); 110static OSObject *retrieveObject(int); 111 112// temp variable to use during parsing 113static object_t *o; 114 115// resultant object of parsed text 116static OSObject *parsedObject; 117 118#define YYSTYPE object_t * 119 120extern "C" { 121extern void *kern_os_malloc(size_t size); 122extern void *kern_os_realloc(void * addr, size_t size); 123extern void kern_os_free(void * addr); 124} /* extern "C" */ 125 126#define malloc(s) kern_os_malloc(s) 127#define realloc(a, s) kern_os_realloc(a, s) 128#define free(a) kern_os_free(a) 129 130#ifndef YYSTYPE 131#define YYSTYPE int 132#endif 133 134#ifndef __cplusplus 135#ifndef __STDC__ 136#define const 137#endif 138#endif 139 140 141 142#define YYFINAL 43 143#define YYFLAG -32768 144#define YYNTBASE 19 145 146#define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 31) 147 148static const char yytranslate[] = { 0, 149 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 150 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 151 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 152 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 153 14, 2, 2, 17, 2, 2, 2, 2, 2, 2, 154 2, 2, 2, 2, 2, 2, 2, 18, 12, 2, 155 11, 2, 2, 8, 2, 2, 2, 2, 2, 2, 156 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 157 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 158 15, 2, 16, 2, 2, 2, 2, 2, 2, 2, 159 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 160 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 161 2, 2, 9, 2, 10, 2, 2, 2, 2, 2, 162 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 163 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 164 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 165 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 166 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 167 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 168 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 169 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 170 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 171 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 172 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 173 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 174 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, 175 7 176}; 177 178#if YYDEBUG != 0 179static const short yyprhs[] = { 0, 180 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 181 19, 22, 26, 29, 33, 35, 38, 43, 46, 50, 182 53, 57, 59, 63, 67, 69, 71 183}; 184 185static const short yyrhs[] = { -1, 186 20, 0, 7, 0, 21, 0, 24, 0, 25, 0, 187 29, 0, 28, 0, 27, 0, 30, 0, 8, 3, 188 0, 20, 8, 3, 0, 9, 10, 0, 9, 22, 189 10, 0, 23, 0, 22, 23, 0, 20, 11, 20, 190 12, 0, 13, 14, 0, 13, 26, 14, 0, 15, 191 16, 0, 15, 26, 16, 0, 20, 0, 26, 17, 192 20, 0, 3, 18, 3, 0, 5, 0, 4, 0, 193 6, 0 194}; 195 196#endif 197 198#if YYDEBUG != 0 199static const short yyrline[] = { 0, 200 116, 117, 118, 121, 122, 123, 124, 125, 126, 127, 201 128, 137, 145, 146, 149, 150, 153, 163, 164, 167, 202 168, 171, 176, 187, 195, 200, 205 203}; 204#endif 205 206 207#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) 208 209static const char * const yytname[] = { "$","error","$undefined.","NUMBER", 210"STRING","DATA","BOOLEAN","SYNTAX_ERROR","'@'","'{'","'}'","'='","';'","'('", 211"')'","'['","']'","','","':'","input","object","dict","pairs","pair","array", 212"set","elements","offset","data","string","boolean", NULL 213}; 214#endif 215 216static const short yyr1[] = { 0, 217 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 218 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 219 25, 26, 26, 27, 28, 29, 30 220}; 221 222static const short yyr2[] = { 0, 223 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 224 2, 3, 2, 3, 1, 2, 4, 2, 3, 2, 225 3, 1, 3, 3, 1, 1, 1 226}; 227 228static const short yydefact[] = { 1, 229 0, 26, 25, 27, 3, 0, 0, 0, 0, 2, 230 4, 5, 6, 9, 8, 7, 10, 0, 11, 13, 231 0, 0, 15, 18, 22, 0, 20, 0, 0, 24, 232 0, 14, 16, 19, 0, 21, 12, 0, 23, 17, 233 0, 0, 0 234}; 235 236static const short yydefgoto[] = { 41, 237 21, 11, 22, 23, 12, 13, 26, 14, 15, 16, 238 17 239}; 240 241static const short yypact[] = { 12, 242 -13,-32768,-32768,-32768,-32768, 9, 33, 46, -2, 2, 243-32768,-32768,-32768,-32768,-32768,-32768,-32768, 25,-32768,-32768, 244 21, 59,-32768,-32768, 2, 16,-32768, 7, 31,-32768, 245 72,-32768,-32768,-32768, 72,-32768,-32768, 14, 2,-32768, 246 40, 44,-32768 247}; 248 249static const short yypgoto[] = {-32768, 250 0,-32768,-32768, 23,-32768,-32768, 38,-32768,-32768,-32768, 251-32768 252}; 253 254 255#define YYLAST 87 256 257 258static const short yytable[] = { 10, 259 1, 2, 3, 4, 18, 6, 7, 25, 25, 29, 260 8, 19, 9, 27, 1, 2, 3, 4, 5, 6, 261 7, 29, 36, 35, 8, 40, 9, 30, 29, 34, 262 38, 31, 35, 37, 39, 1, 2, 3, 4, 42, 263 6, 7, 20, 43, 33, 8, 28, 9, 1, 2, 264 3, 4, 0, 6, 7, 0, 0, 0, 8, 24, 265 9, 1, 2, 3, 4, 0, 6, 7, 32, 0, 266 0, 8, 0, 9, 1, 2, 3, 4, 0, 6, 267 7, 0, 0, 0, 8, 0, 9 268}; 269 270static const short yycheck[] = { 0, 271 3, 4, 5, 6, 18, 8, 9, 8, 9, 8, 272 13, 3, 15, 16, 3, 4, 5, 6, 7, 8, 273 9, 8, 16, 17, 13, 12, 15, 3, 8, 14, 274 31, 11, 17, 3, 35, 3, 4, 5, 6, 0, 275 8, 9, 10, 0, 22, 13, 9, 15, 3, 4, 276 5, 6, -1, 8, 9, -1, -1, -1, 13, 14, 277 15, 3, 4, 5, 6, -1, 8, 9, 10, -1, 278 -1, 13, -1, 15, 3, 4, 5, 6, -1, 8, 279 9, -1, -1, -1, 13, -1, 15 280}; 281/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ 282#line 3 "/usr/share/bison.simple" 283/* This file comes from bison-1.28. */ 284 285/* Skeleton output parser for bison, 286 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. 287 288 This program is free software; you can redistribute it and/or modify 289 it under the terms of the GNU General Public License as published by 290 the Free Software Foundation; either version 2, or (at your option) 291 any later version. 292 293 This program is distributed in the hope that it will be useful, 294 but WITHOUT ANY WARRANTY; without even the implied warranty of 295 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 296 GNU General Public License for more details. 297 298 You should have received a copy of the GNU General Public License 299 along with this program; if not, write to the Free Software 300 Foundation, Inc., 59 Temple Place - Suite 330, 301 Boston, MA 02111-1307, USA. */ 302 303/* As a special exception, when this file is copied by Bison into a 304 Bison output file, you may use that output file without restriction. 305 This special exception was added by the Free Software Foundation 306 in version 1.24 of Bison. */ 307 308/* This is the parser code that is written into each bison parser 309 when the %semantic_parser declaration is not specified in the grammar. 310 It was written by Richard Stallman by simplifying the hairy parser 311 used when %semantic_parser is specified. */ 312 313#ifndef YYSTACK_USE_ALLOCA 314#ifdef alloca 315#define YYSTACK_USE_ALLOCA 316#else /* alloca not defined */ 317#ifdef __GNUC__ 318#define YYSTACK_USE_ALLOCA 319#define alloca __builtin_alloca 320#else /* not GNU C. */ 321#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) || defined (__arm) 322#define YYSTACK_USE_ALLOCA 323#include <alloca.h> 324#else /* not sparc */ 325/* We think this test detects Watcom and Microsoft C. */ 326/* This used to test MSDOS, but that is a bad idea 327 since that symbol is in the user namespace. */ 328#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) 329#if 0 /* No need for malloc.h, which pollutes the namespace; 330 instead, just don't use alloca. */ 331#include <malloc.h> 332#endif 333#else /* not MSDOS, or __TURBOC__ */ 334#if defined(_AIX) 335/* I don't know what this was needed for, but it pollutes the namespace. 336 So I turned it off. rms, 2 May 1997. */ 337/* #include <malloc.h> */ 338 #pragma alloca 339#define YYSTACK_USE_ALLOCA 340#else /* not MSDOS, or __TURBOC__, or _AIX */ 341#if 0 342#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, 343 and on HPUX 10. Eventually we can turn this on. */ 344#define YYSTACK_USE_ALLOCA 345#define alloca __builtin_alloca 346#endif /* __hpux */ 347#endif 348#endif /* not _AIX */ 349#endif /* not MSDOS, or __TURBOC__ */ 350#endif /* not sparc */ 351#endif /* not GNU C */ 352#endif /* alloca not defined */ 353#endif /* YYSTACK_USE_ALLOCA not defined */ 354 355#ifdef YYSTACK_USE_ALLOCA 356#define YYSTACK_ALLOC alloca 357#else 358#define YYSTACK_ALLOC malloc 359#endif 360 361/* Note: there must be only one dollar sign in this file. 362 It is replaced by the list of actions, each action 363 as one case of the switch. */ 364 365#define yyerrok (yyerrstatus = 0) 366#define yyclearin (yychar = YYEMPTY) 367#define YYEMPTY -2 368#define YYEOF 0 369#define YYACCEPT goto yyacceptlab 370#define YYABORT goto yyabortlab 371#define YYERROR goto yyerrlab1 372/* Like YYERROR except do call yyerror. 373 This remains here temporarily to ease the 374 transition to the new meaning of YYERROR, for GCC. 375 Once GCC version 2 has supplanted version 1, this can go. */ 376#define YYFAIL goto yyerrlab 377#define YYRECOVERING() (!!yyerrstatus) 378#define YYBACKUP(token, value) \ 379do \ 380 if (yychar == YYEMPTY && yylen == 1) \ 381 { yychar = (token), yylval = (value); \ 382 yychar1 = YYTRANSLATE (yychar); \ 383 YYPOPSTACK; \ 384 goto yybackup; \ 385 } \ 386 else \ 387 { yyerror ("syntax error: cannot back up"); YYERROR; } \ 388while (0) 389 390#define YYTERROR 1 391#define YYERRCODE 256 392 393#ifndef YYPURE 394#define YYLEX yylex() 395#endif 396 397#ifdef YYPURE 398#ifdef YYLSP_NEEDED 399#ifdef YYLEX_PARAM 400#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) 401#else 402#define YYLEX yylex(&yylval, &yylloc) 403#endif 404#else /* not YYLSP_NEEDED */ 405#ifdef YYLEX_PARAM 406#define YYLEX yylex(&yylval, YYLEX_PARAM) 407#else 408#define YYLEX yylex(&yylval) 409#endif 410#endif /* not YYLSP_NEEDED */ 411#endif 412 413/* If nonreentrant, generate the variables here */ 414 415#ifndef YYPURE 416 417int yychar; /* the lookahead symbol */ 418YYSTYPE yylval; /* the semantic value of the */ 419 /* lookahead symbol */ 420 421#ifdef YYLSP_NEEDED 422YYLTYPE yylloc; /* location data for the lookahead */ 423 /* symbol */ 424#endif 425 426int yynerrs; /* number of parse errors so far */ 427#endif /* not YYPURE */ 428 429#if YYDEBUG != 0 430int yydebug; /* nonzero means print parse trace */ 431/* Since this is uninitialized, it does not stop multiple parsers 432 from coexisting. */ 433#endif 434 435/* YYINITDEPTH indicates the initial size of the parser's stacks */ 436 437#ifndef YYINITDEPTH 438#define YYINITDEPTH 200 439#endif 440 441/* YYMAXDEPTH is the maximum size the stacks can grow to 442 (effective only if the built-in stack extension method is used). */ 443 444#if YYMAXDEPTH == 0 445#undef YYMAXDEPTH 446#endif 447 448#ifndef YYMAXDEPTH 449#define YYMAXDEPTH 10000 450#endif 451 452/* Define __yy_memcpy. Note that the size argument 453 should be passed with type unsigned int, because that is what the non-GCC 454 definitions require. With GCC, __builtin_memcpy takes an arg 455 of type size_t, but it can handle unsigned int. */ 456 457#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ 458#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) 459#else /* not GNU C or C++ */ 460#ifndef __cplusplus 461 462/* This is the most reliable way to avoid incompatibilities 463 in available built-in functions on various systems. */ 464static void 465__yy_memcpy (to, from, count) 466 char *to; 467 char *from; 468 unsigned int count; 469{ 470 register char *f = from; 471 register char *t = to; 472 register int i = count; 473 474 while (i-- > 0) 475 *t++ = *f++; 476} 477 478#else /* __cplusplus */ 479 480/* This is the most reliable way to avoid incompatibilities 481 in available built-in functions on various systems. */ 482static void 483__yy_memcpy (char *to, char *from, unsigned int count) 484{ 485 register char *t = to; 486 register char *f = from; 487 register int i = count; 488 489 while (i-- > 0) 490 *t++ = *f++; 491} 492 493#endif 494#endif 495 496#line 217 "/usr/share/bison.simple" 497 498/* The user can define YYPARSE_PARAM as the name of an argument to be passed 499 into yyparse. The argument should have type void *. 500 It should actually point to an object. 501 Grammar actions can access the variable by casting it 502 to the proper pointer type. */ 503 504#ifdef YYPARSE_PARAM 505#ifdef __cplusplus 506#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM 507#define YYPARSE_PARAM_DECL 508#else /* not __cplusplus */ 509#define YYPARSE_PARAM_ARG YYPARSE_PARAM 510#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; 511#endif /* not __cplusplus */ 512#else /* not YYPARSE_PARAM */ 513#define YYPARSE_PARAM_ARG 514#define YYPARSE_PARAM_DECL 515#endif /* not YYPARSE_PARAM */ 516 517/* Prevent warning if -Wstrict-prototypes. */ 518#ifdef __GNUC__ 519#ifdef YYPARSE_PARAM 520int yyparse (void *); 521#else 522int yyparse (void); 523#endif 524#endif 525 526int 527yyparse(YYPARSE_PARAM_ARG) 528 YYPARSE_PARAM_DECL 529{ 530 register int yystate; 531 register int yyn; 532 register short *yyssp; 533 register YYSTYPE *yyvsp; 534 int yyerrstatus; /* number of tokens to shift before error messages enabled */ 535 int yychar1 = 0; /* lookahead token as an internal (translated) token number */ 536 537 short yyssa[YYINITDEPTH]; /* the state stack */ 538 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ 539 540 short *yyss = yyssa; /* refer to the stacks thru separate pointers */ 541 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ 542 543#ifdef YYLSP_NEEDED 544 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ 545 YYLTYPE *yyls = yylsa; 546 YYLTYPE *yylsp; 547 548#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) 549#else 550#define YYPOPSTACK (yyvsp--, yyssp--) 551#endif 552 553 int yystacksize = YYINITDEPTH; 554 int yyfree_stacks = 0; 555 556#ifdef YYPURE 557 int yychar; 558 YYSTYPE yylval; 559 int yynerrs; 560#ifdef YYLSP_NEEDED 561 YYLTYPE yylloc; 562#endif 563#endif 564 565 YYSTYPE yyval; /* the variable used to return */ 566 /* semantic values from the action */ 567 /* routines */ 568 569 int yylen; 570 571#if YYDEBUG != 0 572 if (yydebug) 573 fprintf(stderr, "Starting parse\n"); 574#endif 575 576 yystate = 0; 577 yyerrstatus = 0; 578 yynerrs = 0; 579 yychar = YYEMPTY; /* Cause a token to be read. */ 580 581 /* Initialize stack pointers. 582 Waste one element of value and location stack 583 so that they stay on the same level as the state stack. 584 The wasted elements are never initialized. */ 585 586 yyssp = yyss - 1; 587 yyvsp = yyvs; 588#ifdef YYLSP_NEEDED 589 yylsp = yyls; 590#endif 591 592/* Push a new state, which is found in yystate . */ 593/* In all cases, when you get here, the value and location stacks 594 have just been pushed. so pushing a state here evens the stacks. */ 595yynewstate: 596 597 *++yyssp = yystate; 598 599 if (yyssp >= yyss + yystacksize - 1) 600 { 601 /* Give user a chance to reallocate the stack */ 602 /* Use copies of these so that the &'s don't force the real ones into memory. */ 603 YYSTYPE *yyvs1 = yyvs; 604 short *yyss1 = yyss; 605#ifdef YYLSP_NEEDED 606 YYLTYPE *yyls1 = yyls; 607#endif 608 609 /* Get the current used size of the three stacks, in elements. */ 610 int size = yyssp - yyss + 1; 611 612#ifdef yyoverflow 613 /* Each stack pointer address is followed by the size of 614 the data in use in that stack, in bytes. */ 615#ifdef YYLSP_NEEDED 616 /* This used to be a conditional around just the two extra args, 617 but that might be undefined if yyoverflow is a macro. */ 618 yyoverflow("parser stack overflow", 619 &yyss1, size * sizeof (*yyssp), 620 &yyvs1, size * sizeof (*yyvsp), 621 &yyls1, size * sizeof (*yylsp), 622 &yystacksize); 623#else 624 yyoverflow("parser stack overflow", 625 &yyss1, size * sizeof (*yyssp), 626 &yyvs1, size * sizeof (*yyvsp), 627 &yystacksize); 628#endif 629 630 yyss = yyss1; yyvs = yyvs1; 631#ifdef YYLSP_NEEDED 632 yyls = yyls1; 633#endif 634#else /* no yyoverflow */ 635 /* Extend the stack our own way. */ 636 if (yystacksize >= YYMAXDEPTH) 637 { 638 yyerror("parser stack overflow"); 639 if (yyfree_stacks) 640 { 641 free (yyss); 642 free (yyvs); 643#ifdef YYLSP_NEEDED 644 free (yyls); 645#endif 646 } 647 return 2; 648 } 649 yystacksize *= 2; 650 if (yystacksize > YYMAXDEPTH) 651 yystacksize = YYMAXDEPTH; 652#ifndef YYSTACK_USE_ALLOCA 653 yyfree_stacks = 1; 654#endif 655 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); 656 __yy_memcpy ((char *)yyss, (char *)yyss1, 657 size * (unsigned int) sizeof (*yyssp)); 658 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); 659 __yy_memcpy ((char *)yyvs, (char *)yyvs1, 660 size * (unsigned int) sizeof (*yyvsp)); 661#ifdef YYLSP_NEEDED 662 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); 663 __yy_memcpy ((char *)yyls, (char *)yyls1, 664 size * (unsigned int) sizeof (*yylsp)); 665#endif 666#endif /* no yyoverflow */ 667 668 yyssp = yyss + size - 1; 669 yyvsp = yyvs + size - 1; 670#ifdef YYLSP_NEEDED 671 yylsp = yyls + size - 1; 672#endif 673 674#if YYDEBUG != 0 675 if (yydebug) 676 fprintf(stderr, "Stack size increased to %d\n", yystacksize); 677#endif 678 679 if (yyssp >= yyss + yystacksize - 1) 680 YYABORT; 681 } 682 683#if YYDEBUG != 0 684 if (yydebug) 685 fprintf(stderr, "Entering state %d\n", yystate); 686#endif 687 688 goto yybackup; 689 yybackup: 690 691/* Do appropriate processing given the current state. */ 692/* Read a lookahead token if we need one and don't already have one. */ 693/* yyresume: */ 694 695 /* First try to decide what to do without reference to lookahead token. */ 696 697 yyn = yypact[yystate]; 698 if (yyn == YYFLAG) 699 goto yydefault; 700 701 /* Not known => get a lookahead token if don't already have one. */ 702 703 /* yychar is either YYEMPTY or YYEOF 704 or a valid token in external form. */ 705 706 if (yychar == YYEMPTY) 707 { 708#if YYDEBUG != 0 709 if (yydebug) 710 fprintf(stderr, "Reading a token: "); 711#endif 712 yychar = YYLEX; 713 } 714 715 /* Convert token to internal form (in yychar1) for indexing tables with */ 716 717 if (yychar <= 0) /* This means end of input. */ 718 { 719 yychar1 = 0; 720 yychar = YYEOF; /* Don't call YYLEX any more */ 721 722#if YYDEBUG != 0 723 if (yydebug) 724 fprintf(stderr, "Now at end of input.\n"); 725#endif 726 } 727 else 728 { 729 yychar1 = YYTRANSLATE(yychar); 730 731#if YYDEBUG != 0 732 if (yydebug) 733 { 734 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); 735 /* Give the individual parser a way to print the precise meaning 736 of a token, for further debugging info. */ 737#ifdef YYPRINT 738 YYPRINT (stderr, yychar, yylval); 739#endif 740 fprintf (stderr, ")\n"); 741 } 742#endif 743 } 744 745 yyn += yychar1; 746 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) 747 goto yydefault; 748 749 yyn = yytable[yyn]; 750 751 /* yyn is what to do for this token type in this state. 752 Negative => reduce, -yyn is rule number. 753 Positive => shift, yyn is new state. 754 New state is final state => don't bother to shift, 755 just return success. 756 0, or most negative number => error. */ 757 758 if (yyn < 0) 759 { 760 if (yyn == YYFLAG) 761 goto yyerrlab; 762 yyn = -yyn; 763 goto yyreduce; 764 } 765 else if (yyn == 0) 766 goto yyerrlab; 767 768 if (yyn == YYFINAL) 769 YYACCEPT; 770 771 /* Shift the lookahead token. */ 772 773#if YYDEBUG != 0 774 if (yydebug) 775 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); 776#endif 777 778 /* Discard the token being shifted unless it is eof. */ 779 if (yychar != YYEOF) 780 yychar = YYEMPTY; 781 782 *++yyvsp = yylval; 783#ifdef YYLSP_NEEDED 784 *++yylsp = yylloc; 785#endif 786 787 /* count tokens shifted since error; after three, turn off error status. */ 788 if (yyerrstatus) yyerrstatus--; 789 790 yystate = yyn; 791 goto yynewstate; 792 793/* Do the default action for the current state. */ 794yydefault: 795 796 yyn = yydefact[yystate]; 797 if (yyn == 0) 798 goto yyerrlab; 799 800/* Do a reduction. yyn is the number of a rule to reduce with. */ 801yyreduce: 802 yylen = yyr2[yyn]; 803 if (yylen > 0) 804 yyval = yyvsp[1-yylen]; /* implement default value of the action */ 805 806#if YYDEBUG != 0 807 if (yydebug) 808 { 809 int i; 810 811 fprintf (stderr, "Reducing via rule %d (line %d), ", 812 yyn, yyrline[yyn]); 813 814 /* Print the symbols being reduced, and their result. */ 815 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) 816 fprintf (stderr, "%s ", yytname[yyrhs[i]]); 817 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); 818 } 819#endif 820 821 822 switch (yyn) { 823 824case 1: 825#line 116 "OSUnserialize.y" 826{ parsedObject = (OSObject *)NULL; YYACCEPT; ; 827 break;} 828case 2: 829#line 117 "OSUnserialize.y" 830{ parsedObject = (OSObject *)yyvsp[0]; YYACCEPT; ; 831 break;} 832case 3: 833#line 118 "OSUnserialize.y" 834{ yyerror("syntax error"); YYERROR; ; 835 break;} 836case 4: 837#line 121 "OSUnserialize.y" 838{ yyval = (object_t *)buildOSDictionary(yyvsp[0]); ; 839 break;} 840case 5: 841#line 122 "OSUnserialize.y" 842{ yyval = (object_t *)buildOSArray(yyvsp[0]); ; 843 break;} 844case 6: 845#line 123 "OSUnserialize.y" 846{ yyval = (object_t *)buildOSSet(yyvsp[0]); ; 847 break;} 848case 7: 849#line 124 "OSUnserialize.y" 850{ yyval = (object_t *)buildOSString(yyvsp[0]); ; 851 break;} 852case 8: 853#line 125 "OSUnserialize.y" 854{ yyval = (object_t *)buildOSData(yyvsp[0]); ; 855 break;} 856case 9: 857#line 126 "OSUnserialize.y" 858{ yyval = (object_t *)buildOSOffset(yyvsp[0]); ; 859 break;} 860case 10: 861#line 127 "OSUnserialize.y" 862{ yyval = (object_t *)buildOSBoolean(yyvsp[0]); ; 863 break;} 864case 11: 865#line 128 "OSUnserialize.y" 866{ yyval = (object_t *)retrieveObject(yyvsp[0]->u.offset); 867 if (yyval) { 868 ((OSObject *)yyval)->retain(); 869 } else { 870 yyerror("forward reference detected"); 871 YYERROR; 872 } 873 freeObject(yyvsp[0]); 874 ; 875 break;} 876case 12: 877#line 137 "OSUnserialize.y" 878{ yyval = yyvsp[-2]; 879 rememberObject(yyvsp[0]->u.offset, yyvsp[-2]); 880 freeObject(yyvsp[0]); 881 ; 882 break;} 883case 13: 884#line 145 "OSUnserialize.y" 885{ yyval = NULL; ; 886 break;} 887case 14: 888#line 146 "OSUnserialize.y" 889{ yyval = yyvsp[-1]; ; 890 break;} 891case 16: 892#line 150 "OSUnserialize.y" 893{ yyvsp[0]->next = yyvsp[-1]; yyvsp[-1]->prev = yyvsp[0]; yyval = yyvsp[0]; ; 894 break;} 895case 17: 896#line 153 "OSUnserialize.y" 897{ yyval = newObject(); 898 yyval->next = NULL; 899 yyval->prev = NULL; 900 yyval->u.key = yyvsp[-3]; 901 yyval->object = yyvsp[-1]; 902 ; 903 break;} 904case 18: 905#line 163 "OSUnserialize.y" 906{ yyval = NULL; ; 907 break;} 908case 19: 909#line 164 "OSUnserialize.y" 910{ yyval = yyvsp[-1]; ; 911 break;} 912case 20: 913#line 167 "OSUnserialize.y" 914{ yyval = NULL; ; 915 break;} 916case 21: 917#line 168 "OSUnserialize.y" 918{ yyval = yyvsp[-1]; ; 919 break;} 920case 22: 921#line 171 "OSUnserialize.y" 922{ yyval = newObject(); 923 yyval->object = yyvsp[0]; 924 yyval->next = NULL; 925 yyval->prev = NULL; 926 ; 927 break;} 928case 23: 929#line 176 "OSUnserialize.y" 930{ o = newObject(); 931 o->object = yyvsp[0]; 932 o->next = yyvsp[-2]; 933 o->prev = NULL; 934 yyvsp[-2]->prev = o; 935 yyval = o; 936 ; 937 break;} 938case 24: 939#line 187 "OSUnserialize.y" 940{ yyval = yyvsp[-2]; 941 yyval->size = yyvsp[0]->u.offset; 942 freeObject(yyvsp[0]); 943 ; 944 break;} 945} 946 /* the action file gets copied in in place of this dollarsign */ 947#line 543 "/usr/share/bison.simple" 948 949 yyvsp -= yylen; 950 yyssp -= yylen; 951#ifdef YYLSP_NEEDED 952 yylsp -= yylen; 953#endif 954 955#if YYDEBUG != 0 956 if (yydebug) 957 { 958 short *ssp1 = yyss - 1; 959 fprintf (stderr, "state stack now"); 960 while (ssp1 != yyssp) 961 fprintf (stderr, " %d", *++ssp1); 962 fprintf (stderr, "\n"); 963 } 964#endif 965 966 *++yyvsp = yyval; 967 968#ifdef YYLSP_NEEDED 969 yylsp++; 970 if (yylen == 0) 971 { 972 yylsp->first_line = yylloc.first_line; 973 yylsp->first_column = yylloc.first_column; 974 yylsp->last_line = (yylsp-1)->last_line; 975 yylsp->last_column = (yylsp-1)->last_column; 976 yylsp->text = 0; 977 } 978 else 979 { 980 yylsp->last_line = (yylsp+yylen-1)->last_line; 981 yylsp->last_column = (yylsp+yylen-1)->last_column; 982 } 983#endif 984 985 /* Now "shift" the result of the reduction. 986 Determine what state that goes to, 987 based on the state we popped back to 988 and the rule number reduced by. */ 989 990 yyn = yyr1[yyn]; 991 992 yystate = yypgoto[yyn - YYNTBASE] + *yyssp; 993 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) 994 yystate = yytable[yystate]; 995 else 996 yystate = yydefgoto[yyn - YYNTBASE]; 997 998 goto yynewstate; 999 1000yyerrlab: /* here on detecting error */ 1001 1002 if (! yyerrstatus) 1003 /* If not already recovering from an error, report this error. */ 1004 { 1005 ++yynerrs; 1006 1007#ifdef YYERROR_VERBOSE 1008 yyn = yypact[yystate]; 1009 1010 if (yyn > YYFLAG && yyn < YYLAST) 1011 { 1012 int size = 0; 1013 char *msg; 1014 int x, count, len; 1015 1016 count = 0; 1017 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ 1018 for (x = (yyn < 0 ? -yyn : 0); 1019 x < (sizeof(yytname) / sizeof(char *)); x++) 1020 if (yycheck[x + yyn] == x) 1021 size += strlen(yytname[x]) + 15, count++; 1022 len = size + 15; 1023 msg = (char *) malloc(len); 1024 if (msg != 0) 1025 { 1026 strlcpy(msg, "parse error", len); 1027 1028 if (count < 5) 1029 { 1030 count = 0; 1031 for (x = (yyn < 0 ? -yyn : 0); 1032 x < (sizeof(yytname) / sizeof(char *)); x++) 1033 if (yycheck[x + yyn] == x) 1034 { 1035 strlcat(msg, count == 0 ? ", expecting `" : " or `", 1036 len); 1037 strlcat(msg, yytname[x], len); 1038 strlcat(msg, "'", len); 1039 count++; 1040 } 1041 } 1042 yyerror(msg); 1043 free(msg); 1044 } 1045 else 1046 yyerror ("parse error; also virtual memory exceeded"); 1047 } 1048 else 1049#endif /* YYERROR_VERBOSE */ 1050 yyerror("parse error"); 1051 } 1052 1053 goto yyerrlab1; 1054yyerrlab1: /* here on error raised explicitly by an action */ 1055 1056 if (yyerrstatus == 3) 1057 { 1058 /* if just tried and failed to reuse lookahead token after an error, discard it. */ 1059 1060 /* return failure if at end of input */ 1061 if (yychar == YYEOF) 1062 YYABORT; 1063 1064#if YYDEBUG != 0 1065 if (yydebug) 1066 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); 1067#endif 1068 1069 yychar = YYEMPTY; 1070 } 1071 1072 /* Else will try to reuse lookahead token 1073 after shifting the error token. */ 1074 1075 yyerrstatus = 3; /* Each real token shifted decrements this */ 1076 1077 goto yyerrhandle; 1078 1079yyerrdefault: /* current state does not do anything special for the error token. */ 1080 1081#if 0 1082 /* This is wrong; only states that explicitly want error tokens 1083 should shift them. */ 1084 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ 1085 if (yyn) goto yydefault; 1086#endif 1087 1088yyerrpop: /* pop the current state because it cannot handle the error token */ 1089 1090 if (yyssp == yyss) YYABORT; 1091 yyvsp--; 1092 yystate = *--yyssp; 1093#ifdef YYLSP_NEEDED 1094 yylsp--; 1095#endif 1096 1097#if YYDEBUG != 0 1098 if (yydebug) 1099 { 1100 short *ssp1 = yyss - 1; 1101 fprintf (stderr, "Error: state stack now"); 1102 while (ssp1 != yyssp) 1103 fprintf (stderr, " %d", *++ssp1); 1104 fprintf (stderr, "\n"); 1105 } 1106#endif 1107 1108yyerrhandle: 1109 1110 yyn = yypact[yystate]; 1111 if (yyn == YYFLAG) 1112 goto yyerrdefault; 1113 1114 yyn += YYTERROR; 1115 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) 1116 goto yyerrdefault; 1117 1118 yyn = yytable[yyn]; 1119 if (yyn < 0) 1120 { 1121 if (yyn == YYFLAG) 1122 goto yyerrpop; 1123 yyn = -yyn; 1124 goto yyreduce; 1125 } 1126 else if (yyn == 0) 1127 goto yyerrpop; 1128 1129 if (yyn == YYFINAL) 1130 YYACCEPT; 1131 1132#if YYDEBUG != 0 1133 if (yydebug) 1134 fprintf(stderr, "Shifting error token, "); 1135#endif 1136 1137 *++yyvsp = yylval; 1138#ifdef YYLSP_NEEDED 1139 *++yylsp = yylloc; 1140#endif 1141 1142 yystate = yyn; 1143 goto yynewstate; 1144 1145 yyacceptlab: 1146 /* YYACCEPT comes here. */ 1147 if (yyfree_stacks) 1148 { 1149 free (yyss); 1150 free (yyvs); 1151#ifdef YYLSP_NEEDED 1152 free (yyls); 1153#endif 1154 } 1155 return 0; 1156 1157 yyabortlab: 1158 /* YYABORT comes here. */ 1159 if (yyfree_stacks) 1160 { 1161 free (yyss); 1162 free (yyvs); 1163#ifdef YYLSP_NEEDED 1164 free (yyls); 1165#endif 1166 } 1167 return 1; 1168} 1169#line 208 "OSUnserialize.y" 1170 1171 1172static int lineNumber = 0; 1173static const char *parseBuffer; 1174static int parseBufferIndex; 1175 1176#define currentChar() (parseBuffer[parseBufferIndex]) 1177#define nextChar() (parseBuffer[++parseBufferIndex]) 1178#define prevChar() (parseBuffer[parseBufferIndex - 1]) 1179 1180#define isSpace(c) ((c) == ' ' || (c) == '\t') 1181#define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) 1182#define isDigit(c) ((c) >= '0' && (c) <= '9') 1183#define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f') 1184#define isHexDigit(c) (isDigit(c) || isAlphaDigit(c)) 1185#define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-')) 1186 1187static char yyerror_message[128]; 1188 1189int 1190yyerror(char *s) /* Called by yyparse on error */ 1191{ 1192 sprintf(yyerror_message, "OSUnserialize: %s near line %d\n", s, lineNumber); 1193 return 0; 1194} 1195 1196int 1197yylex() 1198{ 1199 int c; 1200 1201 if (parseBufferIndex == 0) lineNumber = 1; 1202 1203 top: 1204 c = currentChar(); 1205 1206 /* skip white space */ 1207 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {}; 1208 1209 /* skip over comments */ 1210 if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {}; 1211 1212 /* keep track of line number, don't return \n's */ 1213 if (c == '\n') { 1214 lineNumber++; 1215 (void)nextChar(); 1216 goto top; 1217 } 1218 1219 /* parse boolean */ 1220 if (c == '.') { 1221 bool boolean = false; 1222 if (nextChar() == 't') { 1223 if (nextChar() != 'r') return SYNTAX_ERROR; 1224 if (nextChar() != 'u') return SYNTAX_ERROR; 1225 if (nextChar() != 'e') return SYNTAX_ERROR; 1226 boolean = true; 1227 } else { 1228 if (currentChar() != 'f') return SYNTAX_ERROR; 1229 if (nextChar() != 'a') return SYNTAX_ERROR; 1230 if (nextChar() != 'l') return SYNTAX_ERROR; 1231 if (nextChar() != 's') return SYNTAX_ERROR; 1232 if (nextChar() != 'e') return SYNTAX_ERROR; 1233 } 1234 if (nextChar() != '.') return SYNTAX_ERROR; 1235 /* skip over dot */ 1236 (void)nextChar(); 1237 1238 yylval = (object_t *)boolean; 1239 return BOOLEAN; 1240 } 1241 1242 /* parse unquoted string */ 1243 if (isAlpha(c)) { 1244 int start, length; 1245 char * tempString; 1246 1247 start = parseBufferIndex; 1248 /* find end of string */ 1249 while (isAlphaNumeric(c)) { 1250 c = nextChar(); 1251 } 1252 length = parseBufferIndex - start; 1253 1254 /* copy to null terminated buffer */ 1255 tempString = (char *)malloc(length + 1); 1256 if (tempString == 0) { 1257 printf("OSUnserialize: can't alloc temp memory\n"); 1258 return 0; 1259 } 1260 bcopy(&parseBuffer[start], tempString, length); 1261 tempString[length] = 0; 1262 yylval = (object_t *)tempString; 1263 return STRING; 1264 } 1265 1266 /* parse quoted string */ 1267 if (c == '"' || c == '\'') { 1268 int start, length; 1269 char * tempString; 1270 char quoteChar = c; 1271 1272 start = parseBufferIndex + 1; // skip quote 1273 /* find end of string, line, buffer */ 1274 while ((c = nextChar()) != quoteChar) { 1275 if (c == '\\') c = nextChar(); 1276 if (c == '\n') lineNumber++; 1277 if (c == 0) return SYNTAX_ERROR; 1278 } 1279 length = parseBufferIndex - start; 1280 /* skip over trailing quote */ 1281 (void)nextChar(); 1282 /* copy to null terminated buffer */ 1283 tempString = (char *)malloc(length + 1); 1284 if (tempString == 0) { 1285 printf("OSUnserialize: can't alloc temp memory\n"); 1286 return 0; 1287 } 1288 1289 int to = 0; 1290 for (int from=start; from < parseBufferIndex; from++) { 1291 // hack - skip over backslashes 1292 if (parseBuffer[from] == '\\') { 1293 length--; 1294 continue; 1295 } 1296 tempString[to] = parseBuffer[from]; 1297 to++; 1298 } 1299 tempString[length] = 0; 1300 yylval = (object_t *)tempString; 1301 return STRING; 1302 } 1303 1304 /* process numbers */ 1305 if (isDigit (c)) 1306 { 1307 unsigned long long n = 0; 1308 int base = 10; 1309 1310 if (c == '0') { 1311 c = nextChar(); 1312 if (c == 'x') { 1313 base = 16; 1314 c = nextChar(); 1315 } 1316 } 1317 if (base == 10) { 1318 while(isDigit(c)) { 1319 n = (n * base + c - '0'); 1320 c = nextChar(); 1321 } 1322 } else { 1323 while(isHexDigit(c)) { 1324 if (isDigit(c)) { 1325 n = (n * base + c - '0'); 1326 } else { 1327 n = (n * base + 0xa + c - 'a'); 1328 } 1329 c = nextChar(); 1330 } 1331 } 1332 1333 yylval = newObject(); 1334 yylval->u.offset = n; 1335 1336 return NUMBER; 1337 } 1338 1339#define OSDATA_ALLOC_SIZE 4096 1340 1341 /* process data */ 1342 if (c == '<') { 1343 unsigned char *d, *start, *lastStart; 1344 1345 start = lastStart = d = (unsigned char *)malloc(OSDATA_ALLOC_SIZE); 1346 c = nextChar(); // skip over '<' 1347 while (c != 0 && c != '>') { 1348 1349 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {}; 1350 if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {}; 1351 if (c == '\n') { 1352 lineNumber++; 1353 c = nextChar(); 1354 continue; 1355 } 1356 1357 // get high nibble 1358 if (!isHexDigit(c)) break; 1359 if (isDigit(c)) { 1360 *d = (c - '0') << 4; 1361 } else { 1362 *d = (0xa + (c - 'a')) << 4; 1363 } 1364 1365 // get low nibble 1366 c = nextChar(); 1367 if (!isHexDigit(c)) break; 1368 if (isDigit(c)) { 1369 *d |= c - '0'; 1370 } else { 1371 *d |= 0xa + (c - 'a'); 1372 } 1373 1374 d++; 1375 if ((d - lastStart) >= OSDATA_ALLOC_SIZE) { 1376 int oldsize = d - start; 1377 start = (unsigned char *)realloc(start, oldsize + OSDATA_ALLOC_SIZE); 1378 d = lastStart = start + oldsize; 1379 } 1380 c = nextChar(); 1381 } 1382 if (c != '>' ) { 1383 free(start); 1384 return SYNTAX_ERROR; 1385 } 1386 1387 // got it! 1388 yylval = newObject(); 1389 yylval->object = start; 1390 yylval->size = d - start; 1391 1392 (void)nextChar(); // skip over '>' 1393 return DATA; 1394 } 1395 1396 1397 /* return single chars, move pointer to next char */ 1398 (void)nextChar(); 1399 return c; 1400} 1401 1402// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!# 1403// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!# 1404// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!# 1405 1406#ifdef DEBUG 1407int debugUnserializeAllocCount = 0; 1408#endif 1409 1410object_t * 1411newObject() 1412{ 1413#ifdef DEBUG 1414 debugUnserializeAllocCount++; 1415#endif 1416 return (object_t *)malloc(sizeof(object_t)); 1417} 1418 1419void 1420freeObject(object_t *o) 1421{ 1422#ifdef DEBUG 1423 debugUnserializeAllocCount--; 1424#endif 1425 free(o); 1426} 1427 1428static OSDictionary *tags; 1429 1430static void 1431rememberObject(int tag, object_t *o) 1432{ 1433 char key[16]; 1434 sprintf(key, "%u", tag); 1435 1436 tags->setObject(key, (OSObject *)o); 1437} 1438 1439static OSObject * 1440retrieveObject(int tag) 1441{ 1442 char key[16]; 1443 sprintf(key, "%u", tag); 1444 1445 return tags->getObject(key); 1446} 1447 1448OSObject * 1449buildOSDictionary(object_t *o) 1450{ 1451 object_t *temp, *last = o; 1452 int count = 0; 1453 1454 // get count and last object 1455 while (o) { 1456 count++; 1457 last = o; 1458 o = o->next; 1459 } 1460 o = last; 1461 1462 OSDictionary *d = OSDictionary::withCapacity(count); 1463 1464 while (o) { 1465#ifdef metaclass_stuff_worksXXX 1466 if (((OSObject *)o->u.key)->metaCast("OSSymbol")) { 1467 // XXX the evil frontdoor 1468 d->setObject((OSSymbol *)o->u.key, (OSObject *)o->object); 1469 } else { 1470 // If it isn't a symbol, I hope it's a string! 1471 d->setObject((OSString *)o->u.key, (OSObject *)o->object); 1472 } 1473#else 1474 d->setObject((OSString *)o->u.key, (OSObject *)o->object); 1475#endif 1476 ((OSObject *)o->object)->release(); 1477 ((OSObject *)o->u.key)->release(); 1478 temp = o; 1479 o = o->prev; 1480 freeObject(temp); 1481 } 1482 return d; 1483}; 1484 1485OSObject * 1486buildOSArray(object_t *o) 1487{ 1488 object_t *temp, *last = o; 1489 int count = 0; 1490 1491 // get count and last object 1492 while (o) { 1493 count++; 1494 last = o; 1495 o = o->next; 1496 } 1497 o = last; 1498 1499 OSArray *a = OSArray::withCapacity(count); 1500 1501 while (o) { 1502 a->setObject((OSObject *)o->object); 1503 ((OSObject *)o->object)->release(); 1504 temp = o; 1505 o = o->prev; 1506 freeObject(temp); 1507 } 1508 return a; 1509}; 1510 1511OSObject * 1512buildOSSet(object_t *o) 1513{ 1514 OSArray *a = (OSArray *)buildOSArray(o); 1515 OSSet *s = OSSet::withArray(a, a->getCapacity()); 1516 1517 a->release(); 1518 return s; 1519}; 1520 1521OSObject * 1522buildOSString(object_t *o) 1523{ 1524 OSString *s = OSString::withCString((char *)o); 1525 1526 free(o); 1527 1528 return s; 1529}; 1530 1531OSObject * 1532buildOSData(object_t *o) 1533{ 1534 OSData *d; 1535 1536 if (o->size) { 1537 d = OSData::withBytes(o->object, o->size); 1538 } else { 1539 d = OSData::withCapacity(0); 1540 } 1541 free(o->object); 1542 freeObject(o); 1543 return d; 1544}; 1545 1546OSObject * 1547buildOSOffset(object_t *o) 1548{ 1549 OSNumber *off = OSNumber::withNumber(o->u.offset, o->size); 1550 freeObject(o); 1551 return off; 1552}; 1553 1554OSObject * 1555buildOSBoolean(object_t *o) 1556{ 1557 OSBoolean *b = OSBoolean::withBoolean((bool)o); 1558 return b; 1559}; 1560 1561__BEGIN_DECLS 1562#include <kern/lock.h> 1563__END_DECLS 1564 1565static mutex_t *lock = 0; 1566 1567OSObject* 1568OSUnserialize(const char *buffer, OSString **errorString) 1569{ 1570 OSObject *object; 1571 1572 if (!lock) { 1573 lock = mutex_alloc(0); 1574 mutex_lock(lock); 1575 } else { 1576 mutex_lock(lock); 1577 1578 } 1579 1580#ifdef DEBUG 1581 debugUnserializeAllocCount = 0; 1582#endif 1583 yyerror_message[0] = 0; //just in case 1584 parseBuffer = buffer; 1585 parseBufferIndex = 0; 1586 tags = OSDictionary::withCapacity(128); 1587 if (yyparse() == 0) { 1588 object = parsedObject; 1589 if (errorString) *errorString = 0; 1590 } else { 1591 object = 0; 1592 if (errorString) 1593 *errorString = OSString::withCString(yyerror_message); 1594 } 1595 1596 tags->release(); 1597#ifdef DEBUG 1598 if (debugUnserializeAllocCount) { 1599 printf("OSUnserialize: allocation check failed, count = %d.\n", 1600 debugUnserializeAllocCount); 1601 } 1602#endif 1603 mutex_unlock(lock); 1604 1605 return object; 1606} 1607 1608 1609// 1610// 1611// 1612// 1613// 1614// DO NOT EDIT OSUnserialize.cpp! 1615// 1616// this means you! 1617// 1618// 1619// 1620// 1621// 1622