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