Annotation of XNU/libkern/c++/OSUnserializeXML.y, revision 1.1.1.1

1.1       root        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: /*  OSUnserializeXML.y created by rsulack on Tue Oct 12 1999 */
                     24: 
                     25: //             XML parser for unserializing OSContainer objects
                     26: //
                     27: // to build :
                     28: //     bison -p OSUnserializeXML OSUnserializeXML.y
                     29: //     sed -e "s/stdio.h/stddef.h/" < OSUnserializeXML.tab.c > OSUnserializeXML.cpp
                     30: //
                     31: //     when changing code check in both OSUnserializeXML.y and OSUnserializeXML.cpp
                     32: //
                     33: //
                     34: //
                     35: //
                     36: //
                     37: //
                     38: //
                     39: //              DO NOT EDIT OSUnserializeXML.cpp!
                     40: //
                     41: //                     this means you!
                     42: //
                     43: //
                     44: //
                     45: //
                     46: //
                     47: 
                     48:      
                     49: %{
                     50: #include <string.h>
                     51: #include <libkern/c++/OSMetaClass.h>
                     52: #include <libkern/c++/OSContainers.h>
                     53: #include <libkern/c++/OSLib.h>
                     54: 
                     55: typedef        struct object {
                     56:        struct object   *next;
                     57:        struct object   *free;
                     58:        struct object   *elements;
                     59:        OSObject        *object;
                     60:        const OSSymbol  *key;           // for dictionary
                     61:        int             size;
                     62:        void            *data;          // for data
                     63:        char            *string;        // for string & symbol
                     64:        long long       number;         // for number
                     65:        int             idref;
                     66: } object_t;
                     67: 
                     68: static int yyparse();
                     69: static int yyerror(char *s);
                     70: static int yylex();
                     71: 
                     72: static object_t * newObject();
                     73: static void freeObject(object_t *o);
                     74: 
                     75: static object_t *buildOSDictionary(object_t *);
                     76: static object_t *buildOSArray(object_t *);
                     77: static object_t *buildOSSet(object_t *);
                     78: static object_t *buildOSString(object_t *);
                     79: static object_t *buildKey(object_t *);
                     80: static object_t *buildOSData(object_t *);
                     81: static object_t *buildOSNumber(object_t *);
                     82: static object_t *buildOSBoolean(object_t *o);
                     83: 
                     84: static void rememberObject(int, OSObject *);
                     85: static object_t *retrieveObject(int);
                     86: 
                     87: // resultant object of parsed text
                     88: static OSObject        *parsedObject;
                     89: 
                     90: #define YYSTYPE object_t *
                     91: 
                     92: extern "C" {
                     93: extern void *kern_os_malloc(size_t size);
                     94: extern void *kern_os_realloc(void * addr, size_t size);
                     95: extern void kern_os_free(void * addr);
                     96: 
                     97: //XXX shouldn't have to define these
                     98: extern long strtol(const char *, char **, int);
                     99: extern unsigned long strtoul(const char *, char **, int);
                    100: 
                    101: } /* extern "C" */
                    102: 
                    103: #define malloc(s) kern_os_malloc(s)
                    104: #define realloc(a, s) kern_os_realloc(a, s)
                    105: #define free(a) kern_os_free(a)
                    106: 
                    107: %}
                    108: %token KEY
                    109: %token NUMBER
                    110: %token STRING
                    111: %token DATA
                    112: %token IDREF
                    113: %token BOOLEAN
                    114: %token SYNTAX_ERROR     
                    115: %% /* Grammar rules and actions follow */
                    116: 
                    117: input:   /* empty */           { parsedObject = (OSObject *)NULL; YYACCEPT; }
                    118:        | object                { parsedObject = $1->object;
                    119:                                  $1->object = 0;
                    120:                                  freeObject($1);
                    121:                                  YYACCEPT;
                    122:                                }
                    123:        | SYNTAX_ERROR          {
                    124:                                  yyerror("syntax error");
                    125:                                  YYERROR;
                    126:                                }
                    127:        ;
                    128: 
                    129: object:          dict                  { $$ = buildOSDictionary($1); }
                    130:        | array                 { $$ = buildOSArray($1); }
                    131:        | set                   { $$ = buildOSSet($1); }
                    132:        | string                { $$ = buildOSString($1); }
                    133:        | data                  { $$ = buildOSData($1); }
                    134:        | number                { $$ = buildOSNumber($1); }
                    135:        | boolean               { $$ = buildOSBoolean($1); }
                    136:        | idref                 { $$ = retrieveObject($1->idref);
                    137:                                  if ($$) {
                    138:                                    $$->object->retain();
                    139:                                  } else { 
                    140:                                    yyerror("forward reference detected");
                    141:                                    YYERROR;
                    142:                                  }
                    143:                                  freeObject($1);
                    144:                                }
                    145:        ;
                    146: 
                    147: //------------------------------------------------------------------------------
                    148: 
                    149: dict:    '{' '}'               { $$ = $1;
                    150:                                  $$->elements = NULL;
                    151:                                }
                    152:        | '{' pairs '}'         { $$ = $1;
                    153:                                  $$->elements = $2;
                    154:                                }
                    155:        ;
                    156: 
                    157: pairs:   pair
                    158:        | pairs pair            { $$ = $2;
                    159:                                  $$->next = $1;
                    160:                                }
                    161:        ;
                    162: 
                    163: pair:    key object            { $$ = $1;
                    164:                                  $$->next = NULL; 
                    165:                                  $$->object = $2->object;
                    166:                                  $2->object = 0;
                    167:                                  freeObject($2);
                    168:                                }
                    169:        ;
                    170: 
                    171: key:     KEY                   { $$ = buildKey($1); }
                    172:        ;
                    173: 
                    174: //------------------------------------------------------------------------------
                    175: 
                    176: array:   '(' ')'               { $$ = $1;
                    177:                                  $$->elements = NULL;
                    178:                                }
                    179:        | '(' elements ')'      { $$ = $1;
                    180:                                  $$->elements = $2;
                    181:                                }
                    182:        ;
                    183: 
                    184: set:     '[' ']'               { $$ = $1;
                    185:                                  $$->elements = NULL;
                    186:                                }
                    187:        | '[' elements ']'      { $$ = $1;
                    188:                                  $$->elements = $2;
                    189:                                }
                    190:        ;
                    191: 
                    192: elements: object               { $$ = $1; 
                    193:                                  $$->next = NULL; 
                    194:                                }
                    195:        | elements object       { $$ = $2;
                    196:                                  $$->next = $1;
                    197:                                }
                    198:        ;
                    199: 
                    200: //------------------------------------------------------------------------------
                    201: 
                    202: number:          NUMBER
                    203:        ;
                    204: 
                    205: data:    DATA
                    206:        ;
                    207: 
                    208: string:          STRING
                    209:        ;
                    210: 
                    211: idref:   IDREF
                    212:        ;
                    213: 
                    214: boolean:  BOOLEAN
                    215:        ;
                    216: 
                    217: %%
                    218:      
                    219: static int             lineNumber = 0;
                    220: static const char      *parseBuffer;
                    221: static int             parseBufferIndex;
                    222: 
                    223: #define currentChar()  (parseBuffer[parseBufferIndex])
                    224: #define nextChar()     (parseBuffer[++parseBufferIndex])
                    225: #define prevChar()     (parseBuffer[parseBufferIndex - 1])
                    226: 
                    227: #define isSpace(c)     ((c) == ' ' || (c) == '\t')
                    228: #define isAlpha(c)     (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
                    229: #define isDigit(c)     ((c) >= '0' && (c) <= '9')
                    230: #define isAlphaDigit(c)        ((c) >= 'a' && (c) <= 'f')
                    231: #define isHexDigit(c)  (isDigit(c) || isAlphaDigit(c))
                    232: #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-')) 
                    233: 
                    234: static char yyerror_message[128];
                    235: 
                    236: int
                    237: yyerror(char *s)  /* Called by yyparse on error */
                    238: {
                    239:        sprintf(yyerror_message, "OSUnserializeXML: %s near line %d\n", s, lineNumber);
                    240:        return 0;
                    241: }
                    242: 
                    243: #define TAG_MAX_LENGTH         32
                    244: #define TAG_MAX_ATTRIBUTES     32
                    245: #define TAG_BAD                        0
                    246: #define TAG_START              1
                    247: #define TAG_END                        2
                    248: #define TAG_EMPTY              3
                    249: #define TAG_COMMENT            4
                    250: 
                    251: static int
                    252: getTag(char tag[TAG_MAX_LENGTH],
                    253:        int *attributeCount, 
                    254:        char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH],
                    255:        char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH] )
                    256: {
                    257:        int length = 0;;
                    258:        int c = currentChar();
                    259:        int tagType = TAG_START;
                    260: 
                    261:        *attributeCount = 0;
                    262: 
                    263:        if (c != '<') return TAG_BAD;
                    264:         c = nextChar();                // skip '<'
                    265: 
                    266:         if (c == '?' || c == '!') {
                    267:                 while ((c = nextChar()) != 0) {
                    268:                         if (c == '\n') lineNumber++;
                    269:                         if (c == '>') {
                    270:                                 (void)nextChar();
                    271:                                 return TAG_COMMENT;
                    272:                         }
                    273:                 }
                    274:         }
                    275: 
                    276:        if (c == '/') {
                    277:                c = nextChar();         // skip '/'
                    278:                tagType = TAG_END;
                    279:        }
                    280:         if (!isAlpha(c)) return TAG_BAD;
                    281: 
                    282:        /* find end of tag while copying it */
                    283:        while (isAlphaNumeric(c)) {
                    284:                tag[length++] = c;
                    285:                c = nextChar();
                    286:                if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
                    287:        }
                    288: 
                    289:        tag[length] = 0;
                    290: 
                    291: //printf("tag %s, type %d\n", tag, tagType);
                    292:        
                    293:        // look for attributes of the form attribute = "value" ...
                    294:        while ((c != '>') && (c != '/')) {
                    295:                while (isSpace(c)) c = nextChar();
                    296: 
                    297:                length = 0;
                    298:                while (isAlphaNumeric(c)) {
                    299:                        attributes[*attributeCount][length++] = c;
                    300:                        if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
                    301:                        c = nextChar();
                    302:                }
                    303:                attributes[*attributeCount][length] = 0;
                    304: 
                    305:                while (isSpace(c)) c = nextChar();
                    306:                
                    307:                if (c != '=') return TAG_BAD;
                    308:                c = nextChar();
                    309:                
                    310:                while (isSpace(c)) c = nextChar();
                    311: 
                    312:                if (c != '"') return TAG_BAD;
                    313:                c = nextChar();
                    314:                length = 0;
                    315:                while (c != '"') {
                    316:                        values[*attributeCount][length++] = c;
                    317:                        if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
                    318:                        c = nextChar();
                    319:                }
                    320:                values[*attributeCount][length] = 0;
                    321: 
                    322:                c = nextChar(); // skip closing quote
                    323: 
                    324: //printf("     attribute '%s' = '%s', nextchar = '%c'\n", attributes[*attributeCount], values[*attributeCount], c);
                    325: 
                    326:                (*attributeCount)++;
                    327:                if (*attributeCount >= TAG_MAX_ATTRIBUTES) return TAG_BAD;
                    328:        }
                    329: 
                    330:        if (c == '/') {
                    331:                c = nextChar();         // skip '/'
                    332:                tagType = TAG_EMPTY;
                    333:        }
                    334:        if (c != '>') return TAG_BAD;
                    335:        c = nextChar();         // skip '>'
                    336: 
                    337:        return tagType;
                    338: }
                    339: 
                    340: static char *
                    341: getString()
                    342: {
                    343:        int c = currentChar();
                    344: 
                    345:        int start, length, i, j;;
                    346:        char * tempString;
                    347: 
                    348:        start = parseBufferIndex;
                    349:        /* find end of string */
                    350: 
                    351:        while (c != 0) {
                    352:                if (c == '\n') lineNumber++;
                    353:                if (c == '<') {
                    354:                        break;
                    355:                }
                    356:                c = nextChar();
                    357:        }
                    358: 
                    359:        if (c != '<') return 0;
                    360: 
                    361:        length = parseBufferIndex - start;
                    362: 
                    363:        /* copy to null terminated buffer */
                    364:        tempString = (char *)malloc(length + 1);
                    365:        if (tempString == 0) {
                    366:                printf("OSUnserializeXML: can't alloc temp memory\n");
                    367:                return 0;
                    368:        }
                    369: 
                    370:        // copy out string in tempString
                    371:        // "&amp;" -> '&', "&lt;" -> '<', "&gt;" -> '>'
                    372: 
                    373:        i = j = 0;
                    374:        while (i < length) {
                    375:                c = parseBuffer[start + i++];
                    376:                if (c != '&') {
                    377:                        tempString[j++] = c;
                    378:                } else {
                    379:                        if ((i+3) > length) goto error;
                    380:                        c = parseBuffer[start + i++];
                    381:                        if (c == 'l') {
                    382:                                if (parseBuffer[start + i++] != 't') goto error;
                    383:                                if (parseBuffer[start + i++] != ';') goto error;
                    384:                                tempString[j++] = '<';
                    385:                                continue;
                    386:                        }       
                    387:                        if (c == 'g') {
                    388:                                if (parseBuffer[start + i++] != 't') goto error;
                    389:                                if (parseBuffer[start + i++] != ';') goto error;
                    390:                                tempString[j++] = '>';
                    391:                                continue;
                    392:                        }       
                    393:                        if ((i+3) > length) goto error;
                    394:                        if (c == 'a') {
                    395:                                if (parseBuffer[start + i++] != 'm') goto error;
                    396:                                if (parseBuffer[start + i++] != 'p') goto error;
                    397:                                if (parseBuffer[start + i++] != ';') goto error;
                    398:                                tempString[j++] = '&';
                    399:                                continue;
                    400:                        }
                    401:                        goto error;
                    402:                }       
                    403:        }
                    404:        tempString[j] = 0;
                    405: 
                    406: //printf("string %s\n", tempString);
                    407: 
                    408:        return tempString;
                    409: 
                    410: error:
                    411:        if (tempString) free(tempString);
                    412:        return 0;
                    413: }
                    414: 
                    415: static long long
                    416: getNumber()
                    417: {
                    418:        unsigned long long n = 0;
                    419:        int base = 10;
                    420:        int c = currentChar();
                    421: 
                    422:        if (!isDigit (c)) return 0;
                    423: 
                    424:        if (c == '0') {
                    425:                c = nextChar();
                    426:                if (c == 'x') {
                    427:                        base = 16;
                    428:                        c = nextChar();
                    429:                }
                    430:        }
                    431:        if (base == 10) {
                    432:                while(isDigit(c)) {
                    433:                        n = (n * base + c - '0');
                    434:                        c = nextChar();
                    435:                }
                    436:        } else {
                    437:                while(isHexDigit(c)) {
                    438:                        if (isDigit(c)) {
                    439:                                n = (n * base + c - '0');
                    440:                        } else {
                    441:                                n = (n * base + 0xa + c - 'a');
                    442:                        }
                    443:                        c = nextChar();
                    444:                }
                    445:        }
                    446: //printf("number 0x%x\n", (unsigned long)n);
                    447:        return n;
                    448: }
                    449: 
                    450: // taken from CFXMLParsing/CFPropertyList.c
                    451: 
                    452: static const signed char __CFPLDataDecodeTable[128] = {
                    453:     /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
                    454:     /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
                    455:     /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
                    456:     /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
                    457:     /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
                    458:     /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
                    459:     /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
                    460:     /* '8' */ 60, 61, -1, -1, -1,  0, -1, -1,
                    461:     /* '@' */ -1,  0,  1,  2,  3,  4,  5,  6,
                    462:     /* 'H' */  7,  8,  9, 10, 11, 12, 13, 14,
                    463:     /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
                    464:     /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
                    465:     /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
                    466:     /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
                    467:     /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
                    468:     /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
                    469: };
                    470: 
                    471: #define OSDATA_ALLOC_SIZE 4096
                    472: 
                    473: static void *
                    474: getData(unsigned int *size)
                    475: {
                    476:     int numeq = 0, acc = 0, cntr = 0;
                    477:     int tmpbufpos = 0, tmpbuflen = 0;
                    478:     unsigned char *tmpbuf = (unsigned char *)malloc(OSDATA_ALLOC_SIZE);
                    479: 
                    480:     int c = currentChar();
                    481:     *size = 0;
                    482:        
                    483:     while (c != '<') {
                    484:         c &= 0x7f;
                    485:        if (c == 0) {
                    486:                free(tmpbuf);
                    487:                return 0;
                    488:        }
                    489:        if (c == '=') numeq++; else numeq = 0;
                    490:        if (c == '\n') lineNumber++;
                    491:         if (__CFPLDataDecodeTable[c] < 0) {
                    492:            c = nextChar();
                    493:             continue;
                    494:        }
                    495:         cntr++;
                    496:         acc <<= 6;
                    497:         acc += __CFPLDataDecodeTable[c];
                    498:         if (0 == (cntr & 0x3)) {
                    499:             if (tmpbuflen <= tmpbufpos + 2) {
                    500:                 tmpbuflen += OSDATA_ALLOC_SIZE;
                    501:                tmpbuf = (unsigned char *)realloc(tmpbuf, tmpbuflen);
                    502:             }
                    503:             tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
                    504:             if (numeq < 2)
                    505:                 tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
                    506:             if (numeq < 1)
                    507:                 tmpbuf[tmpbufpos++] = acc & 0xff;
                    508:         }
                    509:        c = nextChar();
                    510:     }
                    511:     *size = tmpbufpos;
                    512:     return tmpbuf;
                    513: }
                    514: 
                    515: static int
                    516: yylex()
                    517: {
                    518:        int c;
                    519:        int tagType;
                    520:        char tag[TAG_MAX_LENGTH];
                    521:        int attributeCount;
                    522:        char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
                    523:        char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
                    524: 
                    525:        if (parseBufferIndex == 0) lineNumber = 1;
                    526: 
                    527:  top:
                    528:        c = currentChar();
                    529: 
                    530:        /* skip white space  */
                    531:        if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
                    532: 
                    533:        /* keep track of line number, don't return \n's */
                    534:        if (c == '\n') {
                    535:                lineNumber++;
                    536:                (void)nextChar();
                    537:                goto top;
                    538:        }
                    539:        
                    540:        if (!c || c == ',') {
                    541:                (void)nextChar();
                    542:                return c;
                    543:        }
                    544: 
                    545:        tagType = getTag(tag, &attributeCount, attributes, values);
                    546:        if (tagType == TAG_BAD) return SYNTAX_ERROR;
                    547:        if (tagType == TAG_COMMENT) goto top;
                    548: 
                    549:        // this code handles empty tags, for idrefs we ignore the tag
                    550:        // for this to work all idrefs must be unique across the whole serialization
                    551:        if (tagType == TAG_EMPTY) {
                    552:                if (!strcmp(tag, "true") || !strcmp(tag, "false")) {
                    553:                                yylval = newObject();
                    554:                                yylval->number = *tag == 't';
                    555:                                return BOOLEAN;
                    556:                }
                    557:                for (int i=0; i < attributeCount; i++) {
                    558:                        if (!strcmp(attributes[i], "IDREF")) {
                    559:                                yylval = newObject();
                    560:                                yylval->idref = strtol(values[i], NULL, 0);
                    561:                                return IDREF;
                    562:                        }
                    563:                }
                    564:                return SYNTAX_ERROR;
                    565:        }
                    566: 
                    567:        // handle allocation and check of "ID" tag up front
                    568:        yylval = newObject();
                    569:        yylval->idref = -1;
                    570:        for (int i=0; i < attributeCount; i++) {
                    571:                if (attributes[i][0] == 'I' && attributes[i][1] == 'D' && !attributes[i][2]) {
                    572:                        yylval->idref = strtol(values[i], NULL, 0);
                    573:                }
                    574:        }
                    575: 
                    576:        switch (*tag) {
                    577:        case 'a':
                    578:                if (!strcmp(tag, "array")) {
                    579:                        return (tagType == TAG_START) ? '(' : ')';
                    580:                }
                    581:                break;
                    582:        case 'd':
                    583:                if (!strcmp(tag, "dict")) {
                    584:                        return (tagType == TAG_START) ? '{' : '}';
                    585:                }
                    586:                if (!strcmp(tag, "data")) {
                    587:                        unsigned int size;
                    588:                        yylval->data = getData(&size);
                    589:                        yylval->size = size;
                    590:                        if ((getTag(tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "data")) {
                    591:                                return SYNTAX_ERROR;
                    592:                        }
                    593:                        return DATA;
                    594:                }
                    595:                break;
                    596:        case 'i':
                    597:                if (!strcmp(tag, "integer")) {
                    598:                        yylval->number = getNumber();
                    599:                        yylval->size = 64;      // default
                    600:                        for (int i=0; i < attributeCount; i++) {
                    601:                                if (!strcmp(attributes[i], "size")) {
                    602:                                        yylval->size = strtoul(values[i], NULL, 0);
                    603:                                }
                    604:                        }
                    605:                        if ((getTag(tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "integer")) {
                    606:                                return SYNTAX_ERROR;
                    607:                        }
                    608:                        return NUMBER;
                    609:                }
                    610:                break;
                    611:        case 'k':
                    612:                if (!strcmp(tag, "key")) {
                    613:                        yylval->string = getString();
                    614:                        if (!yylval->string) {
                    615:                                return SYNTAX_ERROR;
                    616:                        }
                    617:                        if ((getTag(tag, &attributeCount, attributes, values) != TAG_END)
                    618:                           || strcmp(tag, "key")) {
                    619:                                return SYNTAX_ERROR;
                    620:                        }
                    621:                        return KEY;
                    622:                }
                    623:                break;
                    624:        case 'p':
                    625:                if (!strcmp(tag, "plist")) {
                    626:                        freeObject(yylval);
                    627:                        goto top;
                    628:                }
                    629:                break;
                    630:        case 's':
                    631:                if (!strcmp(tag, "string")) {
                    632:                        yylval->string = getString();
                    633:                        if (!yylval->string) {
                    634:                                return SYNTAX_ERROR;
                    635:                        }
                    636:                        if ((getTag(tag, &attributeCount, attributes, values) != TAG_END)
                    637:                           || strcmp(tag, "string")) {
                    638:                                return SYNTAX_ERROR;
                    639:                        }
                    640:                        return STRING;
                    641:                }
                    642:                if (!strcmp(tag, "set")) {
                    643:                        if (tagType == TAG_START) {
                    644:                                return '[';
                    645:                        } else {
                    646:                                return ']';
                    647:                        }
                    648:                }
                    649:                break;
                    650: 
                    651:        default:
                    652:                // XXX should we ignore invalid tags?
                    653:                return SYNTAX_ERROR;
                    654:                break;
                    655:        }
                    656: 
                    657:        return 0;
                    658: }
                    659: 
                    660: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    661: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    662: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    663: 
                    664: // "java" like allocation, if this code hits a syntax error in the
                    665: // the middle of the parsed string we just bail with pointers hanging
                    666: // all over place, so this code helps keeps all together
                    667: 
                    668: static object_t *objects = 0;
                    669: static object_t *freeObjects = 0;
                    670: 
                    671: object_t *
                    672: newObject()
                    673: {
                    674:        object_t *o;
                    675: 
                    676:        if (freeObjects) {
                    677:                o = freeObjects;
                    678:                freeObjects = freeObjects->next;
                    679:        } else {
                    680:                o = (object_t *)malloc(sizeof(object_t));
                    681:                bzero(o, sizeof(object_t));
                    682:                o->free = objects;
                    683:                objects = o;
                    684:        }
                    685:        
                    686:        return o;
                    687: }
                    688: 
                    689: void
                    690: freeObject(object_t *o)
                    691: {
                    692:        o->next = freeObjects;
                    693:        freeObjects = o;        
                    694: }
                    695: 
                    696: void
                    697: cleanupObjects()
                    698: {
                    699:        object_t *t, *o = objects;
                    700: 
                    701:        while (o) {
                    702:                if (o->object) {
                    703:                        printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
                    704:                        o->object->release();
                    705:                }
                    706:                if (o->data) {
                    707:                        printf("OSUnserializeXML: freeing   object o=%x data=%x\n", (int)o, (int)o->data);
                    708:                        free(o->data);
                    709:                }
                    710:                if (o->key) {
                    711:                        printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
                    712:                        o->key->release();
                    713:                }
                    714:                if (o->string) {
                    715:                        printf("OSUnserializeXML: freeing   object o=%x string=%x\n", (int)o, (int)o->string);
                    716:                        free(o->string);
                    717:                }
                    718: 
                    719:                t = o;
                    720:                o = o->free;
                    721:                free(t);
                    722:        }
                    723: }
                    724: 
                    725: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    726: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    727: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    728: 
                    729: static OSDictionary *tags;
                    730: 
                    731: static void 
                    732: rememberObject(int tag, OSObject *o)
                    733: {
                    734:        char key[16];
                    735:        sprintf(key, "%u", tag);
                    736: 
                    737: //printf("remember key %s\n", key);
                    738: 
                    739:        tags->setObject(key, o);
                    740: }
                    741: 
                    742: static object_t *
                    743: retrieveObject(int tag)
                    744: {
                    745:        char key[16];
                    746:        sprintf(key, "%u", tag);
                    747: 
                    748: //printf("retrieve key '%s'\n", key);
                    749: 
                    750:        OSObject *ref = tags->getObject(key);
                    751:        if (!ref) return 0;
                    752: 
                    753:        object_t *o = newObject();
                    754:        o->object = ref;
                    755:        return o;
                    756: }
                    757: 
                    758: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    759: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    760: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
                    761: 
                    762: object_t *
                    763: buildOSDictionary(object_t * header)
                    764: {
                    765:        object_t *o, *t;
                    766:        int count = 0;
                    767: 
                    768:        // get count and reverse order
                    769:        o = header->elements;
                    770:        header->elements = 0;
                    771:        while (o) {
                    772:                count++;
                    773:                t = o;
                    774:                o = o->next;
                    775: 
                    776:                t->next = header->elements;
                    777:                header->elements = t;
                    778:        }
                    779: 
                    780:        OSDictionary *d = OSDictionary::withCapacity(count);
                    781: 
                    782:        if (header->idref >= 0) rememberObject(header->idref, d);
                    783: 
                    784:        o = header->elements;
                    785:        while (o) {
                    786:                d->setObject(o->key, o->object);
                    787:                o->object->release();
                    788:                o->object = 0;
                    789:                o->key->release();
                    790:                o->key = 0;
                    791:                t = o;
                    792:                o = o->next;
                    793:                freeObject(t);
                    794:        }
                    795:        o = header;
                    796:        o->object = d;
                    797:        return o;
                    798: };
                    799: 
                    800: object_t *
                    801: buildOSArray(object_t * header)
                    802: {
                    803:        object_t *o, *t;
                    804:        int count = 0;
                    805: 
                    806:        // get count and reverse order
                    807:        o = header->elements;
                    808:        header->elements = 0;
                    809:        while (o) {
                    810:                count++;
                    811:                t = o;
                    812:                o = o->next;
                    813: 
                    814:                t->next = header->elements;
                    815:                header->elements = t;
                    816:        }
                    817: 
                    818:        OSArray *a = OSArray::withCapacity(count);
                    819: 
                    820:        if (header->idref >= 0) rememberObject(header->idref, a);
                    821: 
                    822:        o = header->elements;
                    823:        while (o) {
                    824:                a->setObject(o->object);
                    825:                o->object->release();
                    826:                o->object = 0;
                    827:                t = o;
                    828:                o = o->next;
                    829:                freeObject(t);
                    830:        }
                    831:        o = header;
                    832:        o->object = a;
                    833:        return o;
                    834: };
                    835: 
                    836: object_t *
                    837: buildOSSet(object_t *o)
                    838: {
                    839:        o = buildOSArray(o);
                    840:        OSArray *a = (OSArray *)o->object;
                    841: 
                    842:        OSSet *s = OSSet::withArray(a, a->getCapacity());
                    843: 
                    844:        //write over reference created in array
                    845:        if (o->idref >= 0) rememberObject(o->idref, s);
                    846: 
                    847:        a->release();
                    848:        o->object = s;
                    849:        return o;
                    850: };
                    851: 
                    852: object_t *
                    853: buildOSString(object_t *o)
                    854: {
                    855:        OSString *s = OSString::withCString(o->string);
                    856: 
                    857:        if (o->idref >= 0) rememberObject(o->idref, s);
                    858: 
                    859:        free(o->string);
                    860:        o->string = 0;
                    861:        o->object = s;
                    862: 
                    863:        return o;
                    864: };
                    865: 
                    866: object_t *
                    867: buildKey(object_t *o)
                    868: {
                    869:        const OSSymbol *s = OSSymbol::withCString(o->string);
                    870: 
                    871:        free(o->string);
                    872:        o->string = 0;
                    873:        o->key = s;
                    874: 
                    875:        return o;
                    876: };
                    877: 
                    878: object_t *
                    879: buildOSData(object_t *o)
                    880: {
                    881:        OSData *d;
                    882: 
                    883:        if (o->size) {
                    884:                d = OSData::withBytes(o->data, o->size);
                    885:                free(o->data);
                    886:        } else {
                    887:                d = OSData::withCapacity(0);
                    888:        }
                    889:        if (o->idref >= 0) rememberObject(o->idref, d);
                    890: 
                    891:        o->data = 0;
                    892:        o->object = d;
                    893:        return o;
                    894: };
                    895: 
                    896: object_t *
                    897: buildOSNumber(object_t *o)
                    898: {
                    899:        OSNumber *n = OSNumber::withNumber(o->number, o->size);
                    900: 
                    901:        if (o->idref >= 0) rememberObject(o->idref, n);
                    902: 
                    903:        o->object = n;
                    904:        return o;
                    905: };
                    906: 
                    907: object_t *
                    908: buildOSBoolean(object_t *o)
                    909: {
                    910:        OSBoolean *b = OSBoolean::withBoolean(o->number != 0);
                    911:        o->object = b;
                    912:        return o;
                    913: };
                    914: 
                    915: __BEGIN_DECLS
                    916: #include <kern/lock.h>
                    917: __END_DECLS
                    918: 
                    919: static mutex_t *lock = 0;
                    920: 
                    921: OSObject*
                    922: OSUnserializeXML(const char *buffer, OSString **errorString)
                    923: {
                    924:        OSObject *object;
                    925: 
                    926:        if (!lock) {
                    927:                lock = mutex_alloc(ETAP_IO_AHA);
                    928:                _mutex_lock(lock);
                    929:        } else {
                    930:                _mutex_lock(lock);
                    931: 
                    932:        }
                    933: 
                    934:        objects = 0;
                    935:        freeObjects = 0;
                    936:        yyerror_message[0] = 0;         //just in case
                    937:        parseBuffer = buffer;
                    938:        parseBufferIndex = 0;
                    939:        tags = OSDictionary::withCapacity(128);
                    940:        if (yyparse() == 0) {
                    941:                object = parsedObject;
                    942:                if (errorString) *errorString = 0;
                    943:        } else {
                    944:                object = 0;
                    945:                if (errorString)
                    946:                        *errorString = OSString::withCString(yyerror_message);
                    947:        }
                    948: 
                    949:        cleanupObjects();
                    950:        tags->release();
                    951:        mutex_unlock(lock);
                    952: 
                    953:        return object;
                    954: }
                    955: 
                    956: 
                    957: //
                    958: //
                    959: //
                    960: //
                    961: //
                    962: //              DO NOT EDIT OSUnserializeXML.cpp!
                    963: //
                    964: //                     this means you!
                    965: //
                    966: //
                    967: //
                    968: //
                    969: //

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.