Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Mac/Modules/cg/CFMLateImport.c

    r2 r391  
    11/*
    2         File:           CFMLateImport.c
    3 
    4         Contains:       Implementation of CFM late import library.
    5 
    6         Written by:     Quinn
    7 
    8         Copyright:      Copyright © 1999 by Apple Computer, Inc., all rights reserved.
    9 
    10                                 You may incorporate this Apple sample source code into your program(s) without
    11                                 restriction. This Apple sample source code has been provided "AS IS" and the
    12                                 responsibility for its operation is yours. You are not permitted to redistribute
    13                                 this Apple sample source code as "Apple sample source code" after having made
    14                                 changes. If you're going to re-distribute the source, we require that you make
    15                                 it clear in the source that the code was descended from Apple sample source
    16                                 code, but that you've made changes.
    17 
    18         Change History (most recent first):
    19 
    20         <13>     24/9/01    Quinn   Fixes to compile with C++ activated.
    21         <12>     21/9/01    Quinn   [2710489] Fix typo in the comments for FragmentLookup.
    22         <11>     21/9/01    Quinn   Changes for CWPro7 Mach-O build.
    23         <10>     19/9/01    Quinn   Corrected implementation of kPEFRelocSmBySection. Added
    24                                     implementations of kPEFRelocSetPosition and kPEFRelocLgByImport
    25                                     (from code contributed by Eric Grant, Ned Holbrook, and Steve
    26                                     Kalkwarf), although I can't test them yet.
    27          <9>     19/9/01    Quinn   We now handle unpacked data sections, courtesy of some code from
    28                                     Ned Holbrook.
    29          <8>     19/9/01    Quinn   Minor fixes for the previous checkin. Updated some comments and
    30                                     killed some dead code.
    31          <7>     19/9/01    Quinn   Simplified API and implementation after a suggestion by Eric
    32                                     Grant. You no longer have to CFM export a dummy function; you
    33                                     can just pass in the address of your fragment's init routine.
    34          <6>     15/2/01    Quinn   Modify compile-time warnings to complain if you try to build
    35                                     this module into a Mach-O binary.
    36          <5>      5/2/01    Quinn   Removed redundant assignment in CFMLateImportCore.
    37          <4>    30/11/00    Quinn   Added comment about future of data symbols in CF.
    38          <3>    16/11/00    Quinn   Allow symbol finding via a callback and use that to implement
    39                                     CFBundle support.
    40          <2>    18/10/99    Quinn   Renamed CFMLateImport to CFMLateImportLibrary to allow for
    41                                     possible future API expansion.
    42          <1>     15/6/99    Quinn   First checked in.
     2    File:               CFMLateImport.c
     3
     4    Contains:           Implementation of CFM late import library.
     5
     6    Written by:         Quinn
     7
     8    Copyright:          Copyright © 1999 by Apple Computer, Inc., all rights reserved.
     9
     10                            You may incorporate this Apple sample source code into your program(s) without
     11                            restriction. This Apple sample source code has been provided "AS IS" and the
     12                            responsibility for its operation is yours. You are not permitted to redistribute
     13                            this Apple sample source code as "Apple sample source code" after having made
     14                            changes. If you're going to re-distribute the source, we require that you make
     15                            it clear in the source that the code was descended from Apple sample source
     16                            code, but that you've made changes.
     17
     18    Change History (most recent first):
     19
     20    <13>     24/9/01    Quinn   Fixes to compile with C++ activated.
     21    <12>     21/9/01    Quinn   [2710489] Fix typo in the comments for FragmentLookup.
     22    <11>     21/9/01    Quinn   Changes for CWPro7 Mach-O build.
     23    <10>     19/9/01    Quinn   Corrected implementation of kPEFRelocSmBySection. Added
     24                                implementations of kPEFRelocSetPosition and kPEFRelocLgByImport
     25                                (from code contributed by Eric Grant, Ned Holbrook, and Steve
     26                                Kalkwarf), although I can't test them yet.
     27     <9>     19/9/01    Quinn   We now handle unpacked data sections, courtesy of some code from
     28                                Ned Holbrook.
     29     <8>     19/9/01    Quinn   Minor fixes for the previous checkin. Updated some comments and
     30                                killed some dead code.
     31     <7>     19/9/01    Quinn   Simplified API and implementation after a suggestion by Eric
     32                                Grant. You no longer have to CFM export a dummy function; you
     33                                can just pass in the address of your fragment's init routine.
     34     <6>     15/2/01    Quinn   Modify compile-time warnings to complain if you try to build
     35                                this module into a Mach-O binary.
     36     <5>      5/2/01    Quinn   Removed redundant assignment in CFMLateImportCore.
     37     <4>    30/11/00    Quinn   Added comment about future of data symbols in CF.
     38     <3>    16/11/00    Quinn   Allow symbol finding via a callback and use that to implement
     39                                CFBundle support.
     40     <2>    18/10/99    Quinn   Renamed CFMLateImport to CFMLateImportLibrary to allow for
     41                                possible future API expansion.
     42     <1>     15/6/99    Quinn   First checked in.
    4343*/
    4444
     
    6767
    6868#if ! MORE_FRAMEWORK_INCLUDES
    69         #include <CodeFragments.h>
    70         #include <PEFBinaryFormat.h>
     69    #include <CodeFragments.h>
     70    #include <PEFBinaryFormat.h>
    7171#endif
    7272
     
    8787
    8888#if TARGET_RT_MAC_MACHO
    89         #error CFMLateImport is not suitable for use in a Mach-O project.
     89    #error CFMLateImport is not suitable for use in a Mach-O project.
    9090#elif !TARGET_RT_MAC_CFM || !TARGET_CPU_PPC
    91         #error CFMLateImport has not been qualified for 68K or CFM-68K use.
     91    #error CFMLateImport has not been qualified for 68K or CFM-68K use.
    9292#endif
    9393
     
    9696
    9797static OSStatus FSReadAtOffset(SInt16 refNum, SInt32 offset, SInt32 count, void *buffer)
    98         // A convenient wrapper around PBRead which has two advantages
    99         // over FSRead.  First, it takes count as a value parameter.
    100         // Second, it reads from an arbitrary offset into the file,
    101         // which avoids a bunch of SetFPos calls.
    102         //
    103         // I guess this should go into "MoreFiles.h", but I'm not sure
    104         // how we're going to integrate such a concept into MIB yet.
    105 {
    106         ParamBlockRec pb;
    107        
    108         pb.ioParam.ioRefNum     = refNum;
    109         pb.ioParam.ioBuffer     = (Ptr) buffer;
    110         pb.ioParam.ioReqCount   = count;
    111         pb.ioParam.ioPosMode    = fsFromStart;
    112         pb.ioParam.ioPosOffset  = offset;
    113        
    114         return PBReadSync(&pb);
     98    // A convenient wrapper around PBRead which has two advantages
     99    // over FSRead.  First, it takes count as a value parameter.
     100    // Second, it reads from an arbitrary offset into the file,
     101    // which avoids a bunch of SetFPos calls.
     102    //
     103    // I guess this should go into "MoreFiles.h", but I'm not sure
     104    // how we're going to integrate such a concept into MIB yet.
     105{
     106    ParamBlockRec pb;
     107
     108    pb.ioParam.ioRefNum     = refNum;
     109    pb.ioParam.ioBuffer     = (Ptr) buffer;
     110    pb.ioParam.ioReqCount   = count;
     111    pb.ioParam.ioPosMode    = fsFromStart;
     112    pb.ioParam.ioPosOffset  = offset;
     113
     114    return PBReadSync(&pb);
    115115}
    116116
     
    125125
    126126struct FragToFixInfo {
    127         CFragSystem7DiskFlatLocator     locator;                                // How to find the fragment's container.
    128         CFragConnectionID                       connID;                                 // CFM connection to the fragment.
    129         CFragInitFunction                       initRoutine;                    // The CFM init routine for the fragment.
    130         PEFContainerHeader                      containerHeader;                // The CFM header, read in from the container.
    131         PEFSectionHeader                        *sectionHeaders;                // The CFM section headers.  A pointer block containing an array of containerHeader.sectionCount elements.
    132         PEFLoaderInfoHeader                     *loaderSection;                 // The entire CFM loader section in a pointer block.
    133         SInt16                                          fileRef;                                // A read-only path to the CFM container.  We keep this here because one that one routine needs to read from the container.
    134         void                                            *section0Base;                  // The base address of section 0, which we go through hoops to calculate.
    135         void                                            *section1Base;                  // The base address of section 1, which we go through hoops to calculate.
    136         Boolean                                         disposeSectionPointers; // See below.
     127    CFragSystem7DiskFlatLocator         locator;                                // How to find the fragment's container.
     128    CFragConnectionID                           connID;                                 // CFM connection to the fragment.
     129    CFragInitFunction                           initRoutine;                    // The CFM init routine for the fragment.
     130    PEFContainerHeader                          containerHeader;                // The CFM header, read in from the container.
     131    PEFSectionHeader                            *sectionHeaders;                // The CFM section headers.  A pointer block containing an array of containerHeader.sectionCount elements.
     132    PEFLoaderInfoHeader                         *loaderSection;                 // The entire CFM loader section in a pointer block.
     133    SInt16                                              fileRef;                                // A read-only path to the CFM container.  We keep this here because one that one routine needs to read from the container.
     134    void                                                *section0Base;                  // The base address of section 0, which we go through hoops to calculate.
     135    void                                                *section1Base;                  // The base address of section 1, which we go through hoops to calculate.
     136    Boolean                                             disposeSectionPointers; // See below.
    137137};
    138138typedef struct FragToFixInfo FragToFixInfo;
     
    152152
    153153static OSStatus ReadContainerBasics(FragToFixInfo *fragToFix)
    154         // Reads some basic information from the container of the
    155         // fragment to fix and stores it in various fields of
    156         // fragToFix.  This includes:
    157         //
    158         // o containerHeader -- The contain header itself.
    159         // o sectionHeaders  -- The array of section headers (in a newly allocated pointer block).
    160         // o loaderSection   -- The entire loader section (in a newly allocated pointer block).
    161         //
    162         // Also sets disposeSectionPointers to indicate whether
    163         // the last two pointers should be disposed of.
    164         //
    165         // Finally, it leaves the container file open for later
    166         // folks who want to read data from it.
    167 {
    168         OSStatus        err;
    169         UInt16          sectionIndex;
    170         Boolean         found;
    171 
    172         MoreAssertQ(fragToFix != nil);
    173         MoreAssertQ(fragToFix->locator.fileSpec != nil);
    174         MoreAssertQ(fragToFix->connID != nil);
    175         MoreAssertQ(fragToFix->loaderSection == nil);
    176         MoreAssertQ(fragToFix->sectionHeaders == nil);
    177         MoreAssertQ(fragToFix->fileRef == 0);
    178        
    179         fragToFix->disposeSectionPointers = true;
    180        
    181         // Open up the file, read the container head, then read in
    182         // all the section headers, then go looking through the
    183         // section headers for the loader section (PEF defines
    184         // that there can be only one).
    185        
    186         err = FSpOpenDF(fragToFix->locator.fileSpec, fsRdPerm, &fragToFix->fileRef);
    187         if (err == noErr) {
    188                 err = FSReadAtOffset(fragToFix->fileRef,
    189                                                                 fragToFix->locator.offset,
    190                                                                 sizeof(fragToFix->containerHeader),
    191                                                                 &fragToFix->containerHeader);
    192                 if (err == noErr) {
    193                         if (   fragToFix->containerHeader.tag1 != kPEFTag1
    194                                 || fragToFix->containerHeader.tag2 != kPEFTag2
    195                                 || fragToFix->containerHeader.architecture != kCompiledCFragArch
    196                                 || fragToFix->containerHeader.formatVersion != kPEFVersion) {
    197                                 err = cfragFragmentFormatErr;
    198                         }
    199                 }
    200                 if (err == noErr) {
    201                         fragToFix->sectionHeaders = (PEFSectionHeader *) NewPtr(fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader));
    202                         err = MemError();
    203                 }
    204                 if (err == noErr) {
    205                         err = FSReadAtOffset(fragToFix->fileRef,
    206                                                                         fragToFix->locator.offset + sizeof(fragToFix->containerHeader),
    207                                                                         fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader),
    208                                                                         fragToFix->sectionHeaders);
    209                 }
    210                 if (err == noErr) {
    211                         sectionIndex = 0;
    212                         found = false;
    213                         while ( sectionIndex < fragToFix->containerHeader.sectionCount && ! found ) {
    214                                 found = (fragToFix->sectionHeaders[sectionIndex].sectionKind == kPEFLoaderSection);
    215                                 if ( ! found ) {
    216                                         sectionIndex += 1;
    217                                 }
    218                         }
    219                 }
    220                 if (err == noErr && ! found) {
    221                         err = cfragNoSectionErr;
    222                 }
    223                
    224                 // Now read allocate a pointer block and read the loader section into it.
    225                
    226                 if (err == noErr) {
    227                         fragToFix->loaderSection = (PEFLoaderInfoHeader *) NewPtr(fragToFix->sectionHeaders[sectionIndex].containerLength);
    228                         err = MemError();
    229                 }
    230                 if (err == noErr) {
    231                         err = FSReadAtOffset(fragToFix->fileRef,
    232                                                                         fragToFix->locator.offset + fragToFix->sectionHeaders[sectionIndex].containerOffset,
    233                                                                         fragToFix->sectionHeaders[sectionIndex].containerLength,
    234                                                                         fragToFix->loaderSection);
    235                 }                               
    236         }
    237        
    238         // No clean up.  The client must init fragToFix to zeros and then
    239         // clean up regardless of whether we return an error.
    240                
    241         return err;
     154    // Reads some basic information from the container of the
     155    // fragment to fix and stores it in various fields of
     156    // fragToFix.  This includes:
     157    //
     158    // o containerHeader -- The contain header itself.
     159    // o sectionHeaders  -- The array of section headers (in a newly allocated pointer block).
     160    // o loaderSection   -- The entire loader section (in a newly allocated pointer block).
     161    //
     162    // Also sets disposeSectionPointers to indicate whether
     163    // the last two pointers should be disposed of.
     164    //
     165    // Finally, it leaves the container file open for later
     166    // folks who want to read data from it.
     167{
     168    OSStatus            err;
     169    UInt16              sectionIndex;
     170    Boolean             found;
     171
     172    MoreAssertQ(fragToFix != nil);
     173    MoreAssertQ(fragToFix->locator.fileSpec != nil);
     174    MoreAssertQ(fragToFix->connID != nil);
     175    MoreAssertQ(fragToFix->loaderSection == nil);
     176    MoreAssertQ(fragToFix->sectionHeaders == nil);
     177    MoreAssertQ(fragToFix->fileRef == 0);
     178
     179    fragToFix->disposeSectionPointers = true;
     180
     181    // Open up the file, read the container head, then read in
     182    // all the section headers, then go looking through the
     183    // section headers for the loader section (PEF defines
     184    // that there can be only one).
     185
     186    err = FSpOpenDF(fragToFix->locator.fileSpec, fsRdPerm, &fragToFix->fileRef);
     187    if (err == noErr) {
     188        err = FSReadAtOffset(fragToFix->fileRef,
     189                                                        fragToFix->locator.offset,
     190                                                        sizeof(fragToFix->containerHeader),
     191                                                        &fragToFix->containerHeader);
     192        if (err == noErr) {
     193            if (   fragToFix->containerHeader.tag1 != kPEFTag1
     194                || fragToFix->containerHeader.tag2 != kPEFTag2
     195                || fragToFix->containerHeader.architecture != kCompiledCFragArch
     196                || fragToFix->containerHeader.formatVersion != kPEFVersion) {
     197                err = cfragFragmentFormatErr;
     198            }
     199        }
     200        if (err == noErr) {
     201            fragToFix->sectionHeaders = (PEFSectionHeader *) NewPtr(fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader));
     202            err = MemError();
     203        }
     204        if (err == noErr) {
     205            err = FSReadAtOffset(fragToFix->fileRef,
     206                                                            fragToFix->locator.offset + sizeof(fragToFix->containerHeader),
     207                                                            fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader),
     208                                                            fragToFix->sectionHeaders);
     209        }
     210        if (err == noErr) {
     211            sectionIndex = 0;
     212            found = false;
     213            while ( sectionIndex < fragToFix->containerHeader.sectionCount && ! found ) {
     214                found = (fragToFix->sectionHeaders[sectionIndex].sectionKind == kPEFLoaderSection);
     215                if ( ! found ) {
     216                    sectionIndex += 1;
     217                }
     218            }
     219        }
     220        if (err == noErr && ! found) {
     221            err = cfragNoSectionErr;
     222        }
     223
     224        // Now read allocate a pointer block and read the loader section into it.
     225
     226        if (err == noErr) {
     227            fragToFix->loaderSection = (PEFLoaderInfoHeader *) NewPtr(fragToFix->sectionHeaders[sectionIndex].containerLength);
     228            err = MemError();
     229        }
     230        if (err == noErr) {
     231            err = FSReadAtOffset(fragToFix->fileRef,
     232                                                            fragToFix->locator.offset + fragToFix->sectionHeaders[sectionIndex].containerOffset,
     233                                                            fragToFix->sectionHeaders[sectionIndex].containerLength,
     234                                                            fragToFix->loaderSection);
     235        }
     236    }
     237
     238    // No clean up.  The client must init fragToFix to zeros and then
     239    // clean up regardless of whether we return an error.
     240
     241    return err;
    242242}
    243243
    244244static UInt32 DecodeVCountValue(const UInt8 *start, UInt32 *outCount)
    245         // Given a pointer to the start of a variable length PEF value,
    246         // work out the value (in *outCount).  Returns the number of bytes
    247         // consumed by the value.
    248 {
    249         UInt8 *                 bytePtr;
    250         UInt8                   byte;
    251         UInt32                  count;
    252        
    253         bytePtr = (UInt8 *)start;
    254        
    255         // Code taken from "PEFBinaryFormat.h".
    256         count = 0;
    257         do {
    258                 byte = *bytePtr++;
    259                 count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);
    260         } while ((byte & kPEFPkDataVCountEndMask) != 0);
    261        
    262         *outCount = count;
    263         return bytePtr - start;
     245    // Given a pointer to the start of a variable length PEF value,
     246    // work out the value (in *outCount).  Returns the number of bytes
     247    // consumed by the value.
     248{
     249    UInt8 *                     bytePtr;
     250    UInt8                       byte;
     251    UInt32                      count;
     252
     253    bytePtr = (UInt8 *)start;
     254
     255    // Code taken from "PEFBinaryFormat.h".
     256    count = 0;
     257    do {
     258        byte = *bytePtr++;
     259        count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);
     260    } while ((byte & kPEFPkDataVCountEndMask) != 0);
     261
     262    *outCount = count;
     263    return bytePtr - start;
    264264}
    265265
    266266static UInt32 DecodeInstrCountValue(const UInt8 *inOpStart, UInt32 *outCount)
    267         // Given a pointer to the start of an opcode (inOpStart), work out the
    268         // count argument for that opcode (*outCount).  Returns the number of
    269         // bytes consumed by the opcode and count combination.
    270 {
    271         MoreAssertQ(inOpStart != nil);
    272         MoreAssertQ(outCount  != nil);
    273        
    274         if (PEFPkDataCount5(*inOpStart) != 0)
    275         {
    276                 // Simple case, count encoded in opcode.
    277                 *outCount = PEFPkDataCount5(*inOpStart);
    278                 return 1;
    279         }
    280         else
    281         {
    282                 // Variable-length case.
    283                 return 1 + DecodeVCountValue(inOpStart + 1, outCount);
    284         }
     267    // Given a pointer to the start of an opcode (inOpStart), work out the
     268    // count argument for that opcode (*outCount).  Returns the number of
     269    // bytes consumed by the opcode and count combination.
     270{
     271    MoreAssertQ(inOpStart != nil);
     272    MoreAssertQ(outCount  != nil);
     273
     274    if (PEFPkDataCount5(*inOpStart) != 0)
     275    {
     276        // Simple case, count encoded in opcode.
     277        *outCount = PEFPkDataCount5(*inOpStart);
     278        return 1;
     279    }
     280    else
     281    {
     282        // Variable-length case.
     283        return 1 + DecodeVCountValue(inOpStart + 1, outCount);
     284    }
    285285}
    286286
    287287static OSStatus UnpackPEFDataSection(const UInt8 * const packedData,   UInt32 packedSize,
    288                                                                            UInt8 * const unpackedData, UInt32 unpackedSize)
    289 {
    290         OSErr                   err;
    291         UInt32                  offset;
    292         UInt8                   opCode;
    293         UInt8 *                 unpackCursor;
    294        
    295         MoreAssertQ(packedData != nil);
    296         MoreAssertQ(unpackedData != nil);
    297         MoreAssertQ(unpackedSize >= packedSize);
    298 
    299         // The following asserts assume that the client allocated the memory with NewPtr,
    300         // which may not always be true.  However, the asserts' value in preventing accidental
    301         // memory block overruns outweighs the possible maintenance effort.
    302        
    303         MoreAssertQ( packedSize   == GetPtrSize( (Ptr) packedData  ) );
    304         MoreAssertQ( unpackedSize == GetPtrSize( (Ptr) unpackedData) );
    305        
    306         err          = noErr;
    307         offset       = 0;
    308         unpackCursor = unpackedData;
    309         while (offset < packedSize) {
    310                 MoreAssertQ(unpackCursor < &unpackedData[unpackedSize]);
    311                
    312                 opCode = packedData[offset];
    313                
    314                 switch (PEFPkDataOpcode(opCode)) {
    315                         case kPEFPkDataZero:
    316                                 {
    317                                         UInt32  count;
    318                                        
    319                                         offset += DecodeInstrCountValue(&packedData[offset], &count);
    320                                        
    321                                         MoreBlockZero(unpackCursor, count);
    322                                         unpackCursor += count;
    323                                 }
    324                                 break;
    325                        
    326                         case kPEFPkDataBlock:
    327                                 {
    328                                         UInt32  blockSize;
    329                                        
    330                                         offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
    331                                        
    332                                         BlockMoveData(&packedData[offset], unpackCursor, blockSize);
    333                                         unpackCursor += blockSize;
    334                                         offset += blockSize;
    335                                 }
    336                                 break;
    337                        
    338                         case kPEFPkDataRepeat:
    339                                 {
    340                                         UInt32  blockSize;
    341                                         UInt32  repeatCount;
    342                                         UInt32  loopCounter;
    343                                        
    344                                         offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
    345                                         offset += DecodeVCountValue(&packedData[offset], &repeatCount);
    346                                         repeatCount += 1;       // stored value is (repeatCount - 1)
    347                                        
    348                                         for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
    349                                                 BlockMoveData(&packedData[offset], unpackCursor, blockSize);
    350                                                 unpackCursor += blockSize;
    351                                         }
    352                                         offset += blockSize;
    353                                 }
    354                                 break;
    355                        
    356                         case kPEFPkDataRepeatBlock:
    357                                 {
    358                                         UInt32  commonSize;
    359                                         UInt32  customSize;
    360                                         UInt32  repeatCount;
    361                                         const UInt8 *commonData;
    362                                         const UInt8 *customData;
    363                                         UInt32 loopCounter;
    364                                        
    365                                         offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
    366                                         offset += DecodeVCountValue(&packedData[offset], &customSize);
    367                                         offset += DecodeVCountValue(&packedData[offset], &repeatCount);
    368                                        
    369                                         commonData = &packedData[offset];
    370                                         customData = &packedData[offset + commonSize];
    371                                        
    372                                         for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
    373                                                 BlockMoveData(commonData, unpackCursor, commonSize);
    374                                                 unpackCursor += commonSize;
    375                                                 BlockMoveData(customData, unpackCursor, customSize);
    376                                                 unpackCursor += customSize;
    377                                                 customData += customSize;
    378                                         }
    379                                         BlockMoveData(commonData, unpackCursor, commonSize);
    380                                         unpackCursor += commonSize;
    381                                         offset += (repeatCount * (commonSize + customSize)) + commonSize;
    382                                 }
    383                                 break;
    384                        
    385                         case kPEFPkDataRepeatZero:
    386                                 {
    387                                         UInt32  commonSize;
    388                                         UInt32  customSize;
    389                                         UInt32  repeatCount;
    390                                         const UInt8 *customData;
    391                                         UInt32 loopCounter;
    392                                        
    393                                         offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
    394                                         offset += DecodeVCountValue(&packedData[offset], &customSize);
    395                                         offset += DecodeVCountValue(&packedData[offset], &repeatCount);
    396                                        
    397                                         customData = &packedData[offset];
    398                                        
    399                                         for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
    400                                                 MoreBlockZero(unpackCursor, commonSize);
    401                                                 unpackCursor += commonSize;
    402                                                 BlockMoveData(customData, unpackCursor, customSize);
    403                                                 unpackCursor += customSize;
    404                                                 customData += customSize;
    405                                         }
    406                                         MoreBlockZero(unpackCursor, commonSize);
    407                                         unpackCursor += commonSize;
    408                                         offset += repeatCount * customSize;
    409                                 }
    410                                 break;
    411                        
    412                         default:
    413                                 #if MORE_DEBUG
    414                                         DebugStr("\pUnpackPEFDataSection: Unexpected data opcode");
    415                                 #endif
    416                                 err = cfragFragmentCorruptErr;
    417                                 goto leaveNow;
    418                                 break;
    419                 }
    420         }
    421        
     288                                                                           UInt8 * const unpackedData, UInt32 unpackedSize)
     289{
     290    OSErr                       err;
     291    UInt32                      offset;
     292    UInt8                       opCode;
     293    UInt8 *                     unpackCursor;
     294
     295    MoreAssertQ(packedData != nil);
     296    MoreAssertQ(unpackedData != nil);
     297    MoreAssertQ(unpackedSize >= packedSize);
     298
     299    // The following asserts assume that the client allocated the memory with NewPtr,
     300    // which may not always be true.  However, the asserts' value in preventing accidental
     301    // memory block overruns outweighs the possible maintenance effort.
     302
     303    MoreAssertQ( packedSize   == GetPtrSize( (Ptr) packedData  ) );
     304    MoreAssertQ( unpackedSize == GetPtrSize( (Ptr) unpackedData) );
     305
     306    err          = noErr;
     307    offset       = 0;
     308    unpackCursor = unpackedData;
     309    while (offset < packedSize) {
     310        MoreAssertQ(unpackCursor < &unpackedData[unpackedSize]);
     311
     312        opCode = packedData[offset];
     313
     314        switch (PEFPkDataOpcode(opCode)) {
     315            case kPEFPkDataZero:
     316                {
     317                    UInt32                      count;
     318
     319                    offset += DecodeInstrCountValue(&packedData[offset], &count);
     320
     321                    MoreBlockZero(unpackCursor, count);
     322                    unpackCursor += count;
     323                }
     324                break;
     325
     326            case kPEFPkDataBlock:
     327                {
     328                    UInt32                      blockSize;
     329
     330                    offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
     331
     332                    BlockMoveData(&packedData[offset], unpackCursor, blockSize);
     333                    unpackCursor += blockSize;
     334                    offset += blockSize;
     335                }
     336                break;
     337
     338            case kPEFPkDataRepeat:
     339                {
     340                    UInt32                      blockSize;
     341                    UInt32                      repeatCount;
     342                    UInt32  loopCounter;
     343
     344                    offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
     345                    offset += DecodeVCountValue(&packedData[offset], &repeatCount);
     346                    repeatCount += 1;                           // stored value is (repeatCount - 1)
     347
     348                    for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
     349                        BlockMoveData(&packedData[offset], unpackCursor, blockSize);
     350                        unpackCursor += blockSize;
     351                    }
     352                    offset += blockSize;
     353                }
     354                break;
     355
     356            case kPEFPkDataRepeatBlock:
     357                {
     358                    UInt32                      commonSize;
     359                    UInt32                      customSize;
     360                    UInt32                      repeatCount;
     361                    const UInt8 *commonData;
     362                    const UInt8 *customData;
     363                    UInt32 loopCounter;
     364
     365                    offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
     366                    offset += DecodeVCountValue(&packedData[offset], &customSize);
     367                    offset += DecodeVCountValue(&packedData[offset], &repeatCount);
     368
     369                    commonData = &packedData[offset];
     370                    customData = &packedData[offset + commonSize];
     371
     372                    for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
     373                        BlockMoveData(commonData, unpackCursor, commonSize);
     374                        unpackCursor += commonSize;
     375                        BlockMoveData(customData, unpackCursor, customSize);
     376                        unpackCursor += customSize;
     377                        customData += customSize;
     378                    }
     379                    BlockMoveData(commonData, unpackCursor, commonSize);
     380                    unpackCursor += commonSize;
     381                    offset += (repeatCount * (commonSize + customSize)) + commonSize;
     382                }
     383                break;
     384
     385            case kPEFPkDataRepeatZero:
     386                {
     387                    UInt32                      commonSize;
     388                    UInt32                      customSize;
     389                    UInt32                      repeatCount;
     390                    const UInt8 *customData;
     391                    UInt32 loopCounter;
     392
     393                    offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
     394                    offset += DecodeVCountValue(&packedData[offset], &customSize);
     395                    offset += DecodeVCountValue(&packedData[offset], &repeatCount);
     396
     397                    customData = &packedData[offset];
     398
     399                    for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
     400                        MoreBlockZero(unpackCursor, commonSize);
     401                        unpackCursor += commonSize;
     402                        BlockMoveData(customData, unpackCursor, customSize);
     403                        unpackCursor += customSize;
     404                        customData += customSize;
     405                    }
     406                    MoreBlockZero(unpackCursor, commonSize);
     407                    unpackCursor += commonSize;
     408                    offset += repeatCount * customSize;
     409                }
     410                break;
     411
     412            default:
     413                #if MORE_DEBUG
     414                    DebugStr("\pUnpackPEFDataSection: Unexpected data opcode");
     415                #endif
     416                err = cfragFragmentCorruptErr;
     417                goto leaveNow;
     418                break;
     419        }
     420    }
     421
    422422leaveNow:
    423         return err;
    424 }
    425 
    426 /*      SetupSectionBaseAddresses Rationale
    427         -----------------------------------
    428        
    429         OK, here's where things get weird.  In order to run the relocation
    430         engine, I need to be able to find the base address of an instantiated
    431         section of the fragment we're fixing up given only its section number.
    432         This isn't hard for CFM to do because it's the one that instantiated the
    433         sections in the first place.  It's surprisingly difficult to do if
    434         you're not CFM.  [And you don't have access to the private CFM APis for
    435         doing it.]
    436        
    437         [Alan Lillich is going to kill me when he reads this!  I should point out
    438         that TVector's don't have to contain two words, they can be longer,
    439         and that the second word isn't necessarily a TOC pointer, it's
    440         just that the calling conventions require that it be put in the
    441         TOC register when the code is called.
    442          
    443         Furthermore, the code section isn't always section 0, and the data
    444         section isn't always section 1, and there can be zero to many sections
    445         of each type.
    446          
    447          But these niceties are besides the point: I'm doing something tricky
    448          because I don't have a nice API for getting section base addresses. 
    449         If I had a nice API for doing that, none of this code would exist.
    450         ]
    451 
    452         The technique is very sneaky (thanks to Eric Grant).  The fragment to
    453         fix necessarily has a CFM init routine (because it needs that routine
    454         in order to capture the fragment location and connection ID).  Thus the
    455         fragment to fix must have a TVector in its data section.  TVectors are
    456         interesting because they're made up of two words.  The first is a pointer
    457         to the code that implements the routine; the second is a pointer to the TOC
    458         for the fragment that's exporting the TVector.  How TVectors are
    459         created is interesting too.  On disk, a TVector consists of two words,
    460         the first being the offset from the start of the code section to the
    461         routine, the second being the offset from the start of the data section
    462         to the TOC base.  When CFM prepares a TVector, it applies the following
    463         transform:
    464        
    465                 tvector.codePtr = tvector.codeOffset + base of code section
    466                 tvector.tocPtr  = tvector.tocOffset  + base of data section
    467                
    468         Now, you can reverse these questions to make them:
    469        
    470                 base of code section = tvector.codePtr - tvector.codeOffset
    471                 base of data section = tvector.dataPtr - tvector.dataOffset
    472        
    473         So if you can find the relocated contents of the TVector and
    474         find the original offsets that made up the TVector, you can then
    475         calculate the base address of both the code and data sections.
    476        
    477         Finding the relocated contents of the TVector is easy; I simply
    478         require the client to pass in a pointer to its init routine.
    479         A routine pointer is a TVector pointer, so you can just cast it
    480         and extract the pair of words.
    481 
    482         Finding the original offsets is a trickier.  My technique is to
    483         look up the init routine in the fragment's loader info header.  This
    484         yields the section number and offset where the init routine's unrelocated
    485         TVector exists.  Once I have that, I can just read the unrelocated TVector
    486         out of the file and extract the offsets.
     423    return err;
     424}
     425
     426/*      SetupSectionBaseAddresses Rationale
     427    -----------------------------------
     428
     429    OK, here's where things get weird.  In order to run the relocation
     430    engine, I need to be able to find the base address of an instantiated
     431    section of the fragment we're fixing up given only its section number.
     432    This isn't hard for CFM to do because it's the one that instantiated the
     433    sections in the first place.  It's surprisingly difficult to do if
     434    you're not CFM.  [And you don't have access to the private CFM APis for
     435    doing it.]
     436
     437    [Alan Lillich is going to kill me when he reads this!  I should point out
     438    that TVector's don't have to contain two words, they can be longer,
     439    and that the second word isn't necessarily a TOC pointer, it's
     440    just that the calling conventions require that it be put in the
     441    TOC register when the code is called.
     442
     443    Furthermore, the code section isn't always section 0, and the data
     444    section isn't always section 1, and there can be zero to many sections
     445    of each type.
     446
     447     But these niceties are besides the point: I'm doing something tricky
     448     because I don't have a nice API for getting section base addresses.
     449    If I had a nice API for doing that, none of this code would exist.
     450    ]
     451
     452    The technique is very sneaky (thanks to Eric Grant).  The fragment to
     453    fix necessarily has a CFM init routine (because it needs that routine
     454    in order to capture the fragment location and connection ID).  Thus the
     455    fragment to fix must have a TVector in its data section.  TVectors are
     456    interesting because they're made up of two words.  The first is a pointer
     457    to the code that implements the routine; the second is a pointer to the TOC
     458    for the fragment that's exporting the TVector.  How TVectors are
     459    created is interesting too.  On disk, a TVector consists of two words,
     460    the first being the offset from the start of the code section to the
     461    routine, the second being the offset from the start of the data section
     462    to the TOC base.  When CFM prepares a TVector, it applies the following
     463    transform:
     464
     465        tvector.codePtr = tvector.codeOffset + base of code section
     466        tvector.tocPtr  = tvector.tocOffset  + base of data section
     467
     468    Now, you can reverse these questions to make them:
     469
     470        base of code section = tvector.codePtr - tvector.codeOffset
     471        base of data section = tvector.dataPtr - tvector.dataOffset
     472
     473    So if you can find the relocated contents of the TVector and
     474    find the original offsets that made up the TVector, you can then
     475    calculate the base address of both the code and data sections.
     476
     477    Finding the relocated contents of the TVector is easy; I simply
     478    require the client to pass in a pointer to its init routine.
     479    A routine pointer is a TVector pointer, so you can just cast it
     480    and extract the pair of words.
     481
     482    Finding the original offsets is a trickier.  My technique is to
     483    look up the init routine in the fragment's loader info header.  This
     484    yields the section number and offset where the init routine's unrelocated
     485    TVector exists.  Once I have that, I can just read the unrelocated TVector
     486    out of the file and extract the offsets.
    487487*/
    488488
    489489struct TVector {
    490         void *codePtr;
    491         void *tocPtr;
     490    void *codePtr;
     491    void *tocPtr;
    492492};
    493493typedef struct TVector TVector;
    494494
    495495static OSStatus SetupSectionBaseAddresses(FragToFixInfo *fragToFix)
    496         // This routine initialises the section0Base and section1Base
    497         // base fields of fragToFix to the base addresses of the
    498         // instantiated fragment represented by the other fields
    499         // of fragToFix.  The process works in three states:
    500         //
    501         // 1.   Find the contents of the relocated TVector of the
    502         //      fragment's initialisation routine, provided to us by
    503         //      the caller.
    504         //
    505         // 2.   Find the contents of the non-relocated TVector by
    506         //      looking it up in the PEF loader info header and then
    507         //      using that to read the TVector contents from disk.
    508         //      This yields the offsets from the section bases for
    509         //      the init routine.
    510         //
    511         // 3.   Subtract 2 from 3.
    512 {
    513         OSStatus                        err;
    514         TVector *                       relocatedExport;
    515         SInt32                          initSection;
    516         UInt32                          initOffset;
    517         PEFSectionHeader *      initSectionHeader;
    518         Ptr                                     packedDataSection;
    519         Ptr                                     unpackedDataSection;
    520         TVector                         originalOffsets;
    521 
    522         packedDataSection   = nil;
    523         unpackedDataSection = nil;
    524        
    525         // Step 1.
    526 
    527         // First find the init routine's TVector, which gives us the relocated
    528         // offsets of the init routine into the data and code sections.
    529 
    530         relocatedExport = (TVector *) fragToFix->initRoutine;
    531                
    532         // Step 2.
    533        
    534         // Now find the init routine's TVector's offsets in the data section on
    535         // disk.  This gives us the raw offsets from the data and code section
    536         // of the beginning of the init routine.
    537        
    538         err = noErr;
    539         initSection = fragToFix->loaderSection->initSection;
    540         initOffset  = fragToFix->loaderSection->initOffset;
    541         if (initSection == -1) {
    542                 err = cfragFragmentUsageErr;
    543         }
    544         if (err == noErr) {
    545                 MoreAssertQ( initSection >= 0 );                // Negative indexes are pseudo-sections which are just not allowed!
    546                 MoreAssertQ( initSection < fragToFix->containerHeader.sectionCount );
    547 
    548                 initSectionHeader = &fragToFix->sectionHeaders[initSection];
    549                
    550                 // If the data section is packed, unpack it to a temporary buffer and then get the
    551                 // original offsets from that buffer.  If the data section is unpacked, just read
    552                 // the original offsets directly off the disk.
    553                
    554                 if ( initSectionHeader->sectionKind == kPEFPackedDataSection ) {
    555 
    556                         // Allocate space for packed and unpacked copies of the section.
    557                        
    558                         packedDataSection = NewPtr(initSectionHeader->containerLength);
    559                         err = MemError();
    560 
    561                         if (err == noErr) {
    562                                 unpackedDataSection = NewPtr(initSectionHeader->unpackedLength);
    563                                 err = MemError();
    564                         }
    565 
    566                         // Read the contents of the packed section.
    567                        
    568                         if (err == noErr) {
    569                                 err = FSReadAtOffset(   fragToFix->fileRef,
    570                                                                                 fragToFix->locator.offset
    571                                                                                 + initSectionHeader->containerOffset,
    572                                                                                 initSectionHeader->containerLength,
    573                                                                                 packedDataSection);
    574                         }
    575                        
    576                         // Unpack the data into the unpacked section.
    577                        
    578                         if (err == noErr) {
    579                                 err = UnpackPEFDataSection( (UInt8 *) packedDataSection,   initSectionHeader->containerLength,
    580                                                                             (UInt8 *) unpackedDataSection, initSectionHeader->unpackedLength);
    581                         }
    582                        
    583                         // Extract the init routine's TVector from the unpacked section.
    584                        
    585                         if (err == noErr) {
    586                                 BlockMoveData(unpackedDataSection + initOffset, &originalOffsets, sizeof(TVector));
    587                         }
    588                        
    589                 } else {
    590                         MoreAssertQ(fragToFix->sectionHeaders[initSection].sectionKind == kPEFUnpackedDataSection);
    591                         err = FSReadAtOffset(fragToFix->fileRef,
    592                                                                         fragToFix->locator.offset
    593                                                                         + fragToFix->sectionHeaders[initSection].containerOffset
    594                                                                         + initOffset,
    595                                                                         sizeof(TVector),
    596                                                                         &originalOffsets);
    597                 }
    598         }
    599 
    600         // Step 3.
    601                
    602         // Do the maths to subtract the unrelocated offsets from the current address
    603         // to get the base address.
    604        
    605         if (err == noErr) {
    606                 fragToFix->section0Base = ((char *) relocatedExport->codePtr) - (UInt32) originalOffsets.codePtr;
    607                 fragToFix->section1Base = ((char *) relocatedExport->tocPtr)  - (UInt32) originalOffsets.tocPtr;
    608         }
    609        
    610         // Clean up.
    611        
    612         if (packedDataSection != nil) {
    613                 DisposePtr(packedDataSection);
    614                 MoreAssertQ( MemError() == noErr );
    615         }
    616         if (unpackedDataSection != nil) {
    617                 DisposePtr(unpackedDataSection);
    618                 MoreAssertQ( MemError() == noErr );
    619         }
    620         return err;
     496    // This routine initialises the section0Base and section1Base
     497    // base fields of fragToFix to the base addresses of the
     498    // instantiated fragment represented by the other fields
     499    // of fragToFix.  The process works in three states:
     500    //
     501    // 1.       Find the contents of the relocated TVector of the
     502    //      fragment's initialisation routine, provided to us by
     503    //      the caller.
     504    //
     505    // 2.       Find the contents of the non-relocated TVector by
     506    //      looking it up in the PEF loader info header and then
     507    //      using that to read the TVector contents from disk.
     508    //      This yields the offsets from the section bases for
     509    //      the init routine.
     510    //
     511    // 3.       Subtract 2 from 3.
     512{
     513    OSStatus                            err;
     514    TVector *                           relocatedExport;
     515    SInt32                              initSection;
     516    UInt32                              initOffset;
     517    PEFSectionHeader *          initSectionHeader;
     518    Ptr                                         packedDataSection;
     519    Ptr                                         unpackedDataSection;
     520    TVector                             originalOffsets;
     521
     522    packedDataSection   = nil;
     523    unpackedDataSection = nil;
     524
     525    // Step 1.
     526
     527    // First find the init routine's TVector, which gives us the relocated
     528    // offsets of the init routine into the data and code sections.
     529
     530    relocatedExport = (TVector *) fragToFix->initRoutine;
     531
     532    // Step 2.
     533
     534    // Now find the init routine's TVector's offsets in the data section on
     535    // disk.  This gives us the raw offsets from the data and code section
     536    // of the beginning of the init routine.
     537
     538    err = noErr;
     539    initSection = fragToFix->loaderSection->initSection;
     540    initOffset  = fragToFix->loaderSection->initOffset;
     541    if (initSection == -1) {
     542        err = cfragFragmentUsageErr;
     543    }
     544    if (err == noErr) {
     545        MoreAssertQ( initSection >= 0 );                        // Negative indexes are pseudo-sections which are just not allowed!
     546        MoreAssertQ( initSection < fragToFix->containerHeader.sectionCount );
     547
     548        initSectionHeader = &fragToFix->sectionHeaders[initSection];
     549
     550        // If the data section is packed, unpack it to a temporary buffer and then get the
     551        // original offsets from that buffer.  If the data section is unpacked, just read
     552        // the original offsets directly off the disk.
     553
     554        if ( initSectionHeader->sectionKind == kPEFPackedDataSection ) {
     555
     556            // Allocate space for packed and unpacked copies of the section.
     557
     558            packedDataSection = NewPtr(initSectionHeader->containerLength);
     559            err = MemError();
     560
     561            if (err == noErr) {
     562                unpackedDataSection = NewPtr(initSectionHeader->unpackedLength);
     563                err = MemError();
     564            }
     565
     566            // Read the contents of the packed section.
     567
     568            if (err == noErr) {
     569                err = FSReadAtOffset(                   fragToFix->fileRef,
     570                                                                fragToFix->locator.offset
     571                                                                + initSectionHeader->containerOffset,
     572                                                                initSectionHeader->containerLength,
     573                                                                packedDataSection);
     574            }
     575
     576            // Unpack the data into the unpacked section.
     577
     578            if (err == noErr) {
     579                err = UnpackPEFDataSection( (UInt8 *) packedDataSection,   initSectionHeader->containerLength,
     580                                                            (UInt8 *) unpackedDataSection, initSectionHeader->unpackedLength);
     581            }
     582
     583            // Extract the init routine's TVector from the unpacked section.
     584
     585            if (err == noErr) {
     586                BlockMoveData(unpackedDataSection + initOffset, &originalOffsets, sizeof(TVector));
     587            }
     588
     589        } else {
     590            MoreAssertQ(fragToFix->sectionHeaders[initSection].sectionKind == kPEFUnpackedDataSection);
     591            err = FSReadAtOffset(fragToFix->fileRef,
     592                                                            fragToFix->locator.offset
     593                                                            + fragToFix->sectionHeaders[initSection].containerOffset
     594                                                            + initOffset,
     595                                                            sizeof(TVector),
     596                                                            &originalOffsets);
     597        }
     598    }
     599
     600    // Step 3.
     601
     602    // Do the maths to subtract the unrelocated offsets from the current address
     603    // to get the base address.
     604
     605    if (err == noErr) {
     606        fragToFix->section0Base = ((char *) relocatedExport->codePtr) - (UInt32) originalOffsets.codePtr;
     607        fragToFix->section1Base = ((char *) relocatedExport->tocPtr)  - (UInt32) originalOffsets.tocPtr;
     608    }
     609
     610    // Clean up.
     611
     612    if (packedDataSection != nil) {
     613        DisposePtr(packedDataSection);
     614        MoreAssertQ( MemError() == noErr );
     615    }
     616    if (unpackedDataSection != nil) {
     617        DisposePtr(unpackedDataSection);
     618        MoreAssertQ( MemError() == noErr );
     619    }
     620    return err;
    621621}
    622622
    623623static void *GetSectionBaseAddress(const FragToFixInfo *fragToFix, UInt16 sectionIndex)
    624         // This routine returns the base of the instantiated section
    625         // whose index is sectionIndex.  This routine is the evil twin
    626         // of SetupSectionBaseAddresses.  It simply returns the values
    627         // for section 0 and 1 that we derived in SetupSectionBaseAddresses.
    628         // In a real implementation, this routine would call CFM API
    629         // to get this information, and SetupSectionBaseAddresses would
    630         // not exist, but CFM does not export the necessary APIs to
    631         // third parties.
    632 {
    633         void *result;
    634        
    635         MoreAssertQ(fragToFix != nil);
    636         MoreAssertQ(fragToFix->containerHeader.tag1 == kPEFTag1);
    637        
    638         switch (sectionIndex) {
    639                 case 0:
    640                         result = fragToFix->section0Base;
    641                         break;
    642                 case 1:
    643                         result = fragToFix->section1Base;
    644                         break;
    645                 default:
    646                         result = nil;
    647                         break;
    648         }
    649         return result;
     624    // This routine returns the base of the instantiated section
     625    // whose index is sectionIndex.  This routine is the evil twin
     626    // of SetupSectionBaseAddresses.  It simply returns the values
     627    // for section 0 and 1 that we derived in SetupSectionBaseAddresses.
     628    // In a real implementation, this routine would call CFM API
     629    // to get this information, and SetupSectionBaseAddresses would
     630    // not exist, but CFM does not export the necessary APIs to
     631    // third parties.
     632{
     633    void *result;
     634
     635    MoreAssertQ(fragToFix != nil);
     636    MoreAssertQ(fragToFix->containerHeader.tag1 == kPEFTag1);
     637
     638    switch (sectionIndex) {
     639        case 0:
     640            result = fragToFix->section0Base;
     641            break;
     642        case 1:
     643            result = fragToFix->section1Base;
     644            break;
     645        default:
     646            result = nil;
     647            break;
     648    }
     649    return result;
    650650}
    651651
    652652
    653653static OSStatus FindImportLibrary(PEFLoaderInfoHeader *loaderSection, const char *libraryName, PEFImportedLibrary **importLibrary)
    654         // This routine finds the import library description (PEFImportedLibrary)
    655         // for the import library libraryName in the PEF loader section.
    656         // It sets *importLibrary to the address of the description.
    657 {
    658         OSStatus                        err;
    659         UInt32                          librariesRemaining;
    660         PEFImportedLibrary      *thisImportLibrary;
    661         Boolean                         found;
    662        
    663         MoreAssertQ(loaderSection != nil);
    664         MoreAssertQ(libraryName != nil);
    665         MoreAssertQ(importLibrary != nil);
    666        
    667         // Loop through each import library looking for a matching name.
    668        
    669         // Initialise thisImportLibrary to point to the byte after the
    670         // end of the loader section's header.
    671        
    672         thisImportLibrary = (PEFImportedLibrary *) (loaderSection + 1);
    673         librariesRemaining = loaderSection->importedLibraryCount;
    674         found = false;
    675         while ( librariesRemaining > 0 && ! found ) {
    676                 // PEF defines that import library names will have
    677                 // a null terminator, so we can just use strcmp.
    678                 found = (strcmp( libraryName,
    679                                                 ((char *)loaderSection)
    680                                                 + loaderSection->loaderStringsOffset
    681                                                 + thisImportLibrary->nameOffset) == 0);
    682                 // *** Remove ANSI strcmp eventually.
    683                 if ( ! found ) {
    684                         thisImportLibrary += 1;
    685                         librariesRemaining -= 1;
    686                 }
    687         }
    688        
    689         if (found) {
    690                 *importLibrary = thisImportLibrary;
    691                 err = noErr;
    692         } else {
    693                 *importLibrary = nil;
    694                 err = cfragNoLibraryErr;
    695         }
    696         return err;
     654    // This routine finds the import library description (PEFImportedLibrary)
     655    // for the import library libraryName in the PEF loader section.
     656    // It sets *importLibrary to the address of the description.
     657{
     658    OSStatus                            err;
     659    UInt32                              librariesRemaining;
     660    PEFImportedLibrary          *thisImportLibrary;
     661    Boolean                             found;
     662
     663    MoreAssertQ(loaderSection != nil);
     664    MoreAssertQ(libraryName != nil);
     665    MoreAssertQ(importLibrary != nil);
     666
     667    // Loop through each import library looking for a matching name.
     668
     669    // Initialise thisImportLibrary to point to the byte after the
     670    // end of the loader section's header.
     671
     672    thisImportLibrary = (PEFImportedLibrary *) (loaderSection + 1);
     673    librariesRemaining = loaderSection->importedLibraryCount;
     674    found = false;
     675    while ( librariesRemaining > 0 && ! found ) {
     676        // PEF defines that import library names will have
     677        // a null terminator, so we can just use strcmp.
     678        found = (strcmp( libraryName,
     679                                        ((char *)loaderSection)
     680                                        + loaderSection->loaderStringsOffset
     681                                        + thisImportLibrary->nameOffset) == 0);
     682        // *** Remove ANSI strcmp eventually.
     683        if ( ! found ) {
     684            thisImportLibrary += 1;
     685            librariesRemaining -= 1;
     686        }
     687    }
     688
     689    if (found) {
     690        *importLibrary = thisImportLibrary;
     691        err = noErr;
     692    } else {
     693        *importLibrary = nil;
     694        err = cfragNoLibraryErr;
     695    }
     696    return err;
    697697}
    698698
    699699static OSStatus LookupSymbol(CFMLateImportLookupProc lookup, void *refCon,
    700                                                         PEFLoaderInfoHeader *loaderSection,
    701                                                         UInt32 symbolIndex,
    702                                                         UInt32 *symbolValue)
    703         // This routine is used to look up a symbol during relocation.
    704         // "lookup" is a client callback and refCon is its argument.
    705         // Typically refCon is the CFM connection to the library that is
    706         // substituting for the weak linked library.  loaderSection
    707         // is a pointer to the loader section of the fragment to fix up.
    708         // symbolIndex is the index of the imported symbol in the loader section.
    709         // The routine sets the word pointed to by symbolValue to the
    710         // value of the symbol.
    711         //
    712         // The routine works by using symbolIndex to index into the imported
    713         // symbol table to find the offset of the symbol's name in the string
    714         // table.  It then looks up the symbol by calling the client's "lookup"
    715         // function and passes the resulting symbol address back in symbolValue.
    716 {
    717         OSStatus                        err;
    718         UInt32                          *importSymbolTable;
    719         UInt32                          symbolStringOffset;
    720         Boolean                         symbolIsWeak;
    721         CFragSymbolClass        symbolClass;
    722         char                            *symbolStringAddress;
    723         Str255                          symbolString;
    724        
    725         MoreAssertQ(lookup != nil);
    726         MoreAssertQ(loaderSection != nil);
    727         MoreAssertQ(symbolIndex < loaderSection->totalImportedSymbolCount);
    728         MoreAssertQ(symbolValue != nil);
    729        
    730         // Find the base of the imported symbol table.
    731        
    732         importSymbolTable = (UInt32 *)(((char *)(loaderSection + 1)) + (loaderSection->importedLibraryCount * sizeof(PEFImportedLibrary)));
    733        
    734         // Grab the appropriate entry out of the table and
    735         // extract the information from that entry.
    736        
    737         symbolStringOffset = importSymbolTable[symbolIndex];
    738         symbolClass = PEFImportedSymbolClass(symbolStringOffset);
    739         symbolIsWeak = ((symbolClass & kPEFWeakImportSymMask) != 0);
    740         symbolClass = symbolClass & ~kPEFWeakImportSymMask;
    741         symbolStringOffset = PEFImportedSymbolNameOffset(symbolStringOffset);
    742        
    743         // Find the string for the symbol in the strings table and
    744         // extract it from the table into a Pascal string on the stack.
    745        
    746         symbolStringAddress = ((char *)loaderSection) + loaderSection->loaderStringsOffset + symbolStringOffset;
    747         symbolString[0] = strlen(symbolStringAddress);          // *** remove ANSI strlen
    748         BlockMoveData(symbolStringAddress, &symbolString[1], symbolString[0]);
    749        
    750         // Look up the symbol in substitute library.  If it fails, return
    751         // a 0 value and check whether the error is fatal (a strong linked
    752         // symbol) or benign (a weak linked symbol).
    753        
    754         err = lookup(symbolString, symbolClass, (void **) symbolValue, refCon);
    755         if (err != noErr) {
    756                 *symbolValue = 0;
    757                 if (symbolIsWeak) {
    758                         err = noErr;
    759                 }
    760         }
    761         return err;
     700                                                        PEFLoaderInfoHeader *loaderSection,
     701                                                        UInt32 symbolIndex,
     702                                                        UInt32 *symbolValue)
     703    // This routine is used to look up a symbol during relocation.
     704    // "lookup" is a client callback and refCon is its argument.
     705    // Typically refCon is the CFM connection to the library that is
     706    // substituting for the weak linked library.  loaderSection
     707    // is a pointer to the loader section of the fragment to fix up.
     708    // symbolIndex is the index of the imported symbol in the loader section.
     709    // The routine sets the word pointed to by symbolValue to the
     710    // value of the symbol.
     711    //
     712    // The routine works by using symbolIndex to index into the imported
     713    // symbol table to find the offset of the symbol's name in the string
     714    // table.  It then looks up the symbol by calling the client's "lookup"
     715    // function and passes the resulting symbol address back in symbolValue.
     716{
     717    OSStatus                            err;
     718    UInt32                              *importSymbolTable;
     719    UInt32                              symbolStringOffset;
     720    Boolean                             symbolIsWeak;
     721    CFragSymbolClass            symbolClass;
     722    char                                *symbolStringAddress;
     723    Str255                              symbolString;
     724
     725    MoreAssertQ(lookup != nil);
     726    MoreAssertQ(loaderSection != nil);
     727    MoreAssertQ(symbolIndex < loaderSection->totalImportedSymbolCount);
     728    MoreAssertQ(symbolValue != nil);
     729
     730    // Find the base of the imported symbol table.
     731
     732    importSymbolTable = (UInt32 *)(((char *)(loaderSection + 1)) + (loaderSection->importedLibraryCount * sizeof(PEFImportedLibrary)));
     733
     734    // Grab the appropriate entry out of the table and
     735    // extract the information from that entry.
     736
     737    symbolStringOffset = importSymbolTable[symbolIndex];
     738    symbolClass = PEFImportedSymbolClass(symbolStringOffset);
     739    symbolIsWeak = ((symbolClass & kPEFWeakImportSymMask) != 0);
     740    symbolClass = symbolClass & ~kPEFWeakImportSymMask;
     741    symbolStringOffset = PEFImportedSymbolNameOffset(symbolStringOffset);
     742
     743    // Find the string for the symbol in the strings table and
     744    // extract it from the table into a Pascal string on the stack.
     745
     746    symbolStringAddress = ((char *)loaderSection) + loaderSection->loaderStringsOffset + symbolStringOffset;
     747    symbolString[0] = strlen(symbolStringAddress);              // *** remove ANSI strlen
     748    BlockMoveData(symbolStringAddress, &symbolString[1], symbolString[0]);
     749
     750    // Look up the symbol in substitute library.  If it fails, return
     751    // a 0 value and check whether the error is fatal (a strong linked
     752    // symbol) or benign (a weak linked symbol).
     753
     754    err = lookup(symbolString, symbolClass, (void **) symbolValue, refCon);
     755    if (err != noErr) {
     756        *symbolValue = 0;
     757        if (symbolIsWeak) {
     758            err = noErr;
     759        }
     760    }
     761    return err;
    762762}
    763763
     
    772772
    773773struct EngineState {
    774         UInt32 currentReloc;            // Index of current relocation opcodes
    775         UInt32 terminatingReloc;        // Index of relocation opcodes which terminates relocation
    776         UInt32 *sectionBase;            // Start of the section
    777         UInt32 *relocAddress;           // Address within the section where the relocations are to be performed
    778         UInt32 importIndex;                     // Symbol index, which is used to access an imported symbol's address
    779         void  *sectionC;                        // Memory address of an instantiated section within the PEF container; this variable is used by relocation opcodes that relocate section addresses
    780         void  *sectionD;                        // Memory address of an instantiated section within the PEF container; this variable is used by relocation opcodes that relocate section addresses
     774    UInt32 currentReloc;                // Index of current relocation opcodes
     775    UInt32 terminatingReloc;            // Index of relocation opcodes which terminates relocation
     776    UInt32 *sectionBase;                // Start of the section
     777    UInt32 *relocAddress;               // Address within the section where the relocations are to be performed
     778    UInt32 importIndex;                         // Symbol index, which is used to access an imported symbol's address
     779    void  *sectionC;                            // Memory address of an instantiated section within the PEF container; this variable is used by relocation opcodes that relocate section addresses
     780    void  *sectionD;                            // Memory address of an instantiated section within the PEF container; this variable is used by relocation opcodes that relocate section addresses
    781781};
    782782typedef struct EngineState EngineState;
     
    787787
    788788static OSStatus InitEngineState(const FragToFixInfo *fragToFix,
    789                                                                 UInt16 relocHeaderIndex,
    790                                                                 EngineState *state)
    791         // This routine initialises the engine state suitably for
    792         // running the relocation opcodes for the section whose
    793         // index is relocHeaderIndex.  relocHeaderIndex is not a
    794         // a section number.  See the comment where it's used below
    795         // for details.  The routine basically fills out all the fields
    796         // in the EngineState structure as described by
    797         // "Mac OS Runtime Architectures".
    798 {
    799         OSStatus err;
    800         PEFLoaderRelocationHeader *relocHeader;
    801        
    802         MoreAssertQ(fragToFix != nil);
    803         MoreAssertQ(state != nil);
    804 
    805         // This bit is tricky.  relocHeaderIndex is an index into the relocation
    806         // header table, starting at relocSectionCount (which is in the loader
    807         // section header) for the first relocated section and decrementing
    808         // down to 1 for the last relocated section.  I find the relocation
    809         // header by using relocHeaderIndex as a index backwards from the
    810         // start of the relocation opcodes (ie relocInstrOffset).  If you
    811         // look at the diagram of the layout of the container in
    812         // "PEFBinaryFormat.h", you'll see that the relocation opcodes
    813         // immediately follow the relocation headers.
    814         //
    815         // I did this because the alternative (starting at the loader
    816         // header and stepping past the import library table and the
    817         // import symbol table) was a pain.
    818 
    819         relocHeader = (PEFLoaderRelocationHeader *) (((char *) fragToFix->loaderSection) + fragToFix->loaderSection->relocInstrOffset - relocHeaderIndex * sizeof(PEFLoaderRelocationHeader));
    820        
    821         MoreAssertQ(relocHeader->reservedA == 0);               // PEF spec says it must be; we check to try to catch bugs in calculation of relocHeader
    822        
    823         state->currentReloc = relocHeader->firstRelocOffset;
    824         state->terminatingReloc = relocHeader->firstRelocOffset + relocHeader->relocCount;
    825         state->sectionBase = (UInt32 *) GetSectionBaseAddress(fragToFix, relocHeader->sectionIndex);
    826         state->relocAddress = state->sectionBase;
    827         state->importIndex = 0;
    828 
    829         // From "Mac OS Runtime Architectures":
    830         //
    831         // The sectionC and sectionD variables actually contain the
    832         // memory address of an instantiated section minus the
    833         // default address for that section. The default address for a
    834         // section is contained in the defaultAddress field of the
    835         // section header. However, in almost all cases the default
    836         // address should be 0, so the simplified definition suffices.
    837         //
    838         // In the debug version, we drop into MacsBug if this weird case
    839         // ever executes because it's more likely we made a mistake than
    840         // we encountered a section with a default address.
    841 
    842         state->sectionC = GetSectionBaseAddress(fragToFix, 0);
    843         if (state->sectionC != nil) {
    844                 #if MORE_DEBUG
    845                         if (fragToFix->sectionHeaders[0].defaultAddress != 0) {
    846                                 DebugStr("\pInitEngineState: Executing weird case.");
    847                         }
    848                 #endif
    849                 (char *) state->sectionC -= fragToFix->sectionHeaders[0].defaultAddress;
    850         }
    851         state->sectionD = GetSectionBaseAddress(fragToFix, 1);
    852         if (state->sectionD != nil) {
    853                 #if MORE_DEBUG
    854                         if (fragToFix->sectionHeaders[1].defaultAddress != 0) {
    855                                 DebugStr("\pInitEngineState: Executing weird case.");
    856                         }
    857                 #endif
    858                 (char *) state->sectionD -= fragToFix->sectionHeaders[1].defaultAddress;
    859         }
    860 
    861         err = noErr;
    862         if (state->relocAddress == nil) {
    863                 err = cfragFragmentUsageErr;
    864         }
    865         return err;
     789                                                                UInt16 relocHeaderIndex,
     790                                                                EngineState *state)
     791    // This routine initialises the engine state suitably for
     792    // running the relocation opcodes for the section whose
     793    // index is relocHeaderIndex.  relocHeaderIndex is not a
     794    // a section number.  See the comment where it's used below
     795    // for details.  The routine basically fills out all the fields
     796    // in the EngineState structure as described by
     797    // "Mac OS Runtime Architectures".
     798{
     799    OSStatus err;
     800    PEFLoaderRelocationHeader *relocHeader;
     801
     802    MoreAssertQ(fragToFix != nil);
     803    MoreAssertQ(state != nil);
     804
     805    // This bit is tricky.  relocHeaderIndex is an index into the relocation
     806    // header table, starting at relocSectionCount (which is in the loader
     807    // section header) for the first relocated section and decrementing
     808    // down to 1 for the last relocated section.  I find the relocation
     809    // header by using relocHeaderIndex as a index backwards from the
     810    // start of the relocation opcodes (ie relocInstrOffset).  If you
     811    // look at the diagram of the layout of the container in
     812    // "PEFBinaryFormat.h", you'll see that the relocation opcodes
     813    // immediately follow the relocation headers.
     814    //
     815    // I did this because the alternative (starting at the loader
     816    // header and stepping past the import library table and the
     817    // import symbol table) was a pain.
     818
     819    relocHeader = (PEFLoaderRelocationHeader *) (((char *) fragToFix->loaderSection) + fragToFix->loaderSection->relocInstrOffset - relocHeaderIndex * sizeof(PEFLoaderRelocationHeader));
     820
     821    MoreAssertQ(relocHeader->reservedA == 0);                   // PEF spec says it must be; we check to try to catch bugs in calculation of relocHeader
     822
     823    state->currentReloc = relocHeader->firstRelocOffset;
     824    state->terminatingReloc = relocHeader->firstRelocOffset + relocHeader->relocCount;
     825    state->sectionBase = (UInt32 *) GetSectionBaseAddress(fragToFix, relocHeader->sectionIndex);
     826    state->relocAddress = state->sectionBase;
     827    state->importIndex = 0;
     828
     829    // From "Mac OS Runtime Architectures":
     830    //
     831    // The sectionC and sectionD variables actually contain the
     832    // memory address of an instantiated section minus the
     833    // default address for that section. The default address for a
     834    // section is contained in the defaultAddress field of the
     835    // section header. However, in almost all cases the default
     836    // address should be 0, so the simplified definition suffices.
     837    //
     838    // In the debug version, we drop into MacsBug if this weird case
     839    // ever executes because it's more likely we made a mistake than
     840    // we encountered a section with a default address.
     841
     842    state->sectionC = GetSectionBaseAddress(fragToFix, 0);
     843    if (state->sectionC != nil) {
     844        #if MORE_DEBUG
     845            if (fragToFix->sectionHeaders[0].defaultAddress != 0) {
     846                DebugStr("\pInitEngineState: Executing weird case.");
     847            }
     848        #endif
     849        (char *) state->sectionC -= fragToFix->sectionHeaders[0].defaultAddress;
     850    }
     851    state->sectionD = GetSectionBaseAddress(fragToFix, 1);
     852    if (state->sectionD != nil) {
     853        #if MORE_DEBUG
     854            if (fragToFix->sectionHeaders[1].defaultAddress != 0) {
     855                DebugStr("\pInitEngineState: Executing weird case.");
     856            }
     857        #endif
     858        (char *) state->sectionD -= fragToFix->sectionHeaders[1].defaultAddress;
     859    }
     860
     861    err = noErr;
     862    if (state->relocAddress == nil) {
     863        err = cfragFragmentUsageErr;
     864    }
     865    return err;
    866866}
    867867
     
    872872static UInt8 kPEFRelocBasicOpcodes[kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };
    873873
    874 static OSStatus RunRelocationEngine(const FragToFixInfo *fragToFix, 
    875                                                                                 PEFImportedLibrary  *importLibrary,
    876                                                                                 CFMLateImportLookupProc lookup, void *refCon)
    877         // This is where the rubber really hits the.  Given a fully
    878         // populated fragToFix structure, the import library description
    879         // of the weak imported library we're resolving, and a connection
    880         // to the library we're going to substitute it, re-execute the
    881         // relocation instructions (CFM has already executed them once)
    882         // but only *do* instructions (ie store the change to the data section)
    883         // that CFM skipped because the weak symbols were missing.
    884 {
    885         OSStatus        err;
    886         EngineState     state;
    887         UInt16          sectionsLeftToRelocate;
    888         UInt32          totalRelocs;
    889         UInt16          *relocInstrTable;
    890         UInt16          opCode;
    891        
    892         MoreAssertQ(fragToFix != nil);
    893         MoreAssertQ(fragToFix->containerHeader.tag1 == kPEFTag1);
    894         MoreAssertQ(fragToFix->sectionHeaders != nil);
    895         MoreAssertQ(fragToFix->loaderSection != nil);
    896         MoreAssertQ(fragToFix->section0Base != nil);    // Technically, having a nil for these two is not a problem, ...
    897         MoreAssertQ(fragToFix->section1Base != nil);    // but in practise it a wildly deviant case and we should know about it.
    898         MoreAssertQ(importLibrary != nil);
    899         MoreAssertQ(lookup != nil);
    900 
    901         // Before entering the loop, work out some information in advance.
    902 
    903         // totalRelocs is only used for debugging, to make sure our
    904         // relocation PC (state.currentReloc) doesn't run wild.
    905        
    906         totalRelocs = (fragToFix->loaderSection->loaderStringsOffset - fragToFix->loaderSection->relocInstrOffset) / sizeof(UInt16);
    907        
    908         // relocInstrTable is the base address of the table of relocation
    909         // instructions in the fragment to fix.
    910        
    911         relocInstrTable = (UInt16 *)((char *) fragToFix->loaderSection + fragToFix->loaderSection->relocInstrOffset);
    912        
    913         // sectionsLeftToRelocate is the loop counter for the outer loop.
    914        
    915         MoreAssertQ(fragToFix->loaderSection->relocSectionCount <= 0x0FFFF);
    916         sectionsLeftToRelocate = fragToFix->loaderSection->relocSectionCount;
    917 
    918         // Now let's run the relocation engine.  We run it once per
    919         // section in the table.  Each time around, we init the engine
    920         // and then loop again, this time executing individual opcodes.
    921         // The opcode loop terminates when the relocation PC
    922         // (state.currentReloc) hits the final opcode (state.terminatingReloc).
    923        
    924         // Note:
    925         // One design decision I made was to totally re-init the engine state
    926         // for each section.  The CFM spec is unclear as to whether you're supposed
    927         // to totally re-init the engine state, or just re-init the section-specific
    928         // state (ie currentReloc, terminatingReloc, and relocAddress).  I hope this
    929         // is correct, but it's hard to test without having a fragment with multiple
    930         // relocated sections, which is difficult to create.
    931        
    932         // How do I decide which opcodes should be effective (ie make changes to
    933         // the section being relocated) and which opcodes should just be executed
    934         // for their side effects (ie updated state.relocAddress or state.importIndex)?
    935         // The answer is both simple and subtle.  Opcodes whose actions are dependent
    936         // on a symbol that was in the weak linked library are effective, those that
    937         // an independent of those symbols are not.  The only opcodes that use
    938         // symbolic values are kPEFRelocImportRun and kPEFRelocSmByImport, and
    939         // these are only if the symbol is in the weak linked library.
    940         // All other cases are executed for their side effects only.
    941         //
    942         // How do I determine if a symbol is in the weak linked library?
    943         // Well I know the symbol's index and I know the lower bound and count
    944         // of the symbols in the weak linked library, so I just do a simple
    945         // bounds test, ie
    946         //
    947         //   firstImportedSymbol <= importIndex < firstImportedSymbol + importedSymbolCount
    948 
    949         // From this code, it's relatively easy to see which relocation opcodes
    950         // aren't implemented.  If you ever encounter one, you'll find yourself
    951         // in MacsBug with a message telling you which opcode was found.  The
    952         // two big groups of opcodes I skipped were the large format opcodes
    953         // and the repeating opcodes.  I skipped them because:
    954         //
    955         // a) I haven't got a way to generate them in a PEF container that I can
    956         //    test against. Without that, there's no way I could be assured that
    957         //    the code worked.
    958         //
    959         // b) I'm lazy.
    960 
    961         err = noErr;
    962         while ( sectionsLeftToRelocate > 0 ) {
    963                 err = InitEngineState(fragToFix, sectionsLeftToRelocate, &state);
    964                 if (err != noErr) {
    965                         goto leaveNow;
    966                 }
    967                
    968                 while ( state.currentReloc != state.terminatingReloc ) {
    969                        
    970                         MoreAssertQ( state.currentReloc < totalRelocs );
    971 
    972                         opCode = relocInstrTable[state.currentReloc];
    973                         switch ( PEFRelocBasicOpcode(opCode) ) {
    974                                 case kPEFRelocBySectDWithSkip:
    975                                         {
    976                                                 UInt16 skipCount;
    977                                                 UInt16 relocCount;
    978                                                
    979                                                 skipCount = ((opCode >> 6) & 0x00FF);
    980                                                 relocCount = (opCode & 0x003F);
    981                                                 state.relocAddress += skipCount;
    982                                                 state.relocAddress += relocCount;
    983                                         }
    984                                         break;
    985                                 case kPEFRelocBySectC:
    986                                 case kPEFRelocBySectD:
    987                                         {
    988                                                 UInt16 runLength;
    989 
    990                                                 runLength = (opCode & 0x01FF) + 1;
    991                                                 state.relocAddress += runLength;
    992                                         }
    993                                         break;
    994                                 case kPEFRelocTVector12:
    995                                         {
    996                                                 UInt16 runLength;
    997 
    998                                                 runLength = (opCode & 0x01FF) + 1;
    999                                                 state.relocAddress += (runLength * 3);
    1000                                         }
    1001                                         break;
    1002                                 case kPEFRelocTVector8:
    1003                                 case kPEFRelocVTable8:
    1004                                         {
    1005                                                 UInt16 runLength;
    1006 
    1007                                                 runLength = (opCode & 0x01FF) + 1;
    1008                                                 state.relocAddress += (runLength * 2);
    1009                                         }
    1010                                         break;
    1011                                 case kPEFRelocImportRun:
    1012                                         {
    1013                                                 UInt32 symbolValue;
    1014                                                 UInt16 runLength;
    1015                                                
    1016                                                 runLength = (opCode & 0x01FF) + 1;
    1017                                                 while (runLength > 0) {
    1018                                                         if ( state.importIndex >= importLibrary->firstImportedSymbol && state.importIndex < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
    1019                                                                 err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, state.importIndex, &symbolValue);
    1020                                                                 if (err != noErr) {
    1021                                                                         goto leaveNow;
    1022                                                                 }
    1023                                                                 *(state.relocAddress) += symbolValue;
    1024                                                         }
    1025                                                         state.importIndex += 1;
    1026                                                         state.relocAddress += 1;
    1027                                                         runLength -= 1;
    1028                                                 }
    1029                                         }
    1030                                         break;
    1031                                 case kPEFRelocSmByImport:
    1032                                         {
    1033                                                 UInt32 symbolValue;
    1034                                                 UInt32 index;
    1035 
    1036                                                 index = (opCode & 0x01FF);
    1037                                                 if ( index >= importLibrary->firstImportedSymbol && index < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
    1038                                                         err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, index, &symbolValue);
    1039                                                         if (err != noErr) {
    1040                                                                 goto leaveNow;
    1041                                                         }
    1042                                                         *(state.relocAddress) += symbolValue;
    1043                                                 }
    1044                                                 state.importIndex = index + 1;
    1045                                                 state.relocAddress += 1;
    1046                                         }
    1047                                         break;
    1048                                 case kPEFRelocSmSetSectC:
    1049                                         {
    1050                                                 UInt32 index;
    1051 
    1052                                                 index = (opCode & 0x01FF);
    1053                                                 state.sectionC = GetSectionBaseAddress(fragToFix, index);
    1054                                                 MoreAssertQ(state.sectionC != nil);
    1055                                         }
    1056                                         break;
    1057                                 case kPEFRelocSmSetSectD:
    1058                                         {
    1059                                                 UInt32 index;
    1060 
    1061                                                 index = (opCode & 0x01FF);
    1062                                                 state.sectionD = GetSectionBaseAddress(fragToFix, index);
    1063                                                 MoreAssertQ(state.sectionD != nil);
    1064                                         }
    1065                                         break;
    1066                                 case kPEFRelocSmBySection:
    1067                                         state.relocAddress += 1;
    1068                                         break;
    1069                                 case kPEFRelocIncrPosition:
    1070                                         {
    1071                                                 UInt16 offset;
    1072                                                
    1073                                                 offset = (opCode & 0x0FFF) + 1;
    1074                                                 ((char *) state.relocAddress) += offset;
    1075                                         }
    1076                                         break;
    1077                                 case kPEFRelocSmRepeat:
    1078                                         #if MORE_DEBUG
    1079                                                 DebugStr("\pRunRelocationEngine: kPEFRelocSmRepeat not yet implemented");
    1080                                         #endif
    1081                                         err = unimpErr;
    1082                                         goto leaveNow;
    1083                                         break;
    1084                                 case kPEFRelocSetPosition:
    1085                                         {
    1086                                                 UInt32 offset;
    1087 
    1088                                                 // Lot's of folks have tried various interpretations of the description of
    1089                                                 // this opCode in "Mac OS Runtime Architectures" (which states "This instruction
    1090                                                 // sets relocAddress to the address of the section offset offset."  *smile*).
    1091                                                 // I eventually dug into the CFM source code to find my interpretation, which
    1092                                                 // I believe is correct.  The key point is tht the offset is relative to
    1093                                                 // the start of the section for which these relocations are being performed.
    1094                                                
    1095                                                 // Skip to next reloc word, which is the second chunk of the offset.
    1096                                                
    1097                                                 state.currentReloc += 1;
    1098                                                
    1099                                                 // Extract offset based on the most significant 10 bits in opCode and
    1100                                                 // the next significant 16 bits in the next reloc word.
    1101                                                
    1102                                                 offset = PEFRelocSetPosFullOffset(opCode, relocInstrTable[state.currentReloc]);
    1103 
    1104                                                 state.relocAddress = (UInt32 *) ( ((char *) state.sectionBase) + offset);
    1105                                         }
    1106                                         break;
    1107                                 case kPEFRelocLgByImport:
    1108                                         {
    1109                                                 UInt32 symbolValue;
    1110                                                 UInt32 index;
    1111 
    1112                                                 // Get the 26 bit symbol index from the current and next reloc words.
    1113                                                
    1114                                                 state.currentReloc += 1;
    1115                                                 index = PEFRelocLgByImportFullIndex(opCode, relocInstrTable[state.currentReloc]);
    1116                                                
    1117                                                 if ( index >= importLibrary->firstImportedSymbol && index < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
    1118                                                         err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, index, &symbolValue);
    1119                                                         if (err != noErr) {
    1120                                                                 goto leaveNow;
    1121                                                         }
    1122                                                         *(state.relocAddress) += symbolValue;
    1123                                                 }
    1124                                                 state.importIndex = index + 1;
    1125                                                 state.relocAddress += 1;
    1126                                         }
    1127                                         break;
    1128                                 case kPEFRelocLgRepeat:
    1129                                         #if MORE_DEBUG
    1130                                                 DebugStr("\pRunRelocationEngine: kPEFRelocLgRepeat not yet implemented");
    1131                                         #endif
    1132                                         err = unimpErr;
    1133                                         goto leaveNow;
    1134                                         break;
    1135                                 case kPEFRelocLgSetOrBySection:
    1136                                         #if MORE_DEBUG
    1137                                                 DebugStr("\pRunRelocationEngine: kPEFRelocLgSetOrBySection not yet implemented");
    1138                                         #endif
    1139                                         err = unimpErr;
    1140                                         goto leaveNow;
    1141                                         break;
    1142                                 case kPEFRelocUndefinedOpcode:
    1143                                         err = cfragFragmentCorruptErr;
    1144                                         goto leaveNow;
    1145                                         break;
    1146                                 default:
    1147                                         MoreAssertQ(false);
    1148                                         err = cfragFragmentCorruptErr;
    1149                                         goto leaveNow;
    1150                                         break;
    1151                         }
    1152                         state.currentReloc += 1;
    1153                 }
    1154                
    1155                 sectionsLeftToRelocate -= 1;
    1156         }
     874static OSStatus RunRelocationEngine(const FragToFixInfo *fragToFix,
     875                                                                                PEFImportedLibrary  *importLibrary,
     876                                                                                CFMLateImportLookupProc lookup, void *refCon)
     877    // This is where the rubber really hits the.  Given a fully
     878    // populated fragToFix structure, the import library description
     879    // of the weak imported library we're resolving, and a connection
     880    // to the library we're going to substitute it, re-execute the
     881    // relocation instructions (CFM has already executed them once)
     882    // but only *do* instructions (ie store the change to the data section)
     883    // that CFM skipped because the weak symbols were missing.
     884{
     885    OSStatus            err;
     886    EngineState         state;
     887    UInt16              sectionsLeftToRelocate;
     888    UInt32              totalRelocs;
     889    UInt16              *relocInstrTable;
     890    UInt16              opCode;
     891
     892    MoreAssertQ(fragToFix != nil);
     893    MoreAssertQ(fragToFix->containerHeader.tag1 == kPEFTag1);
     894    MoreAssertQ(fragToFix->sectionHeaders != nil);
     895    MoreAssertQ(fragToFix->loaderSection != nil);
     896    MoreAssertQ(fragToFix->section0Base != nil);        // Technically, having a nil for these two is not a problem, ...
     897    MoreAssertQ(fragToFix->section1Base != nil);        // but in practise it a wildly deviant case and we should know about it.
     898    MoreAssertQ(importLibrary != nil);
     899    MoreAssertQ(lookup != nil);
     900
     901    // Before entering the loop, work out some information in advance.
     902
     903    // totalRelocs is only used for debugging, to make sure our
     904    // relocation PC (state.currentReloc) doesn't run wild.
     905
     906    totalRelocs = (fragToFix->loaderSection->loaderStringsOffset - fragToFix->loaderSection->relocInstrOffset) / sizeof(UInt16);
     907
     908    // relocInstrTable is the base address of the table of relocation
     909    // instructions in the fragment to fix.
     910
     911    relocInstrTable = (UInt16 *)((char *) fragToFix->loaderSection + fragToFix->loaderSection->relocInstrOffset);
     912
     913    // sectionsLeftToRelocate is the loop counter for the outer loop.
     914
     915    MoreAssertQ(fragToFix->loaderSection->relocSectionCount <= 0x0FFFF);
     916    sectionsLeftToRelocate = fragToFix->loaderSection->relocSectionCount;
     917
     918    // Now let's run the relocation engine.  We run it once per
     919    // section in the table.  Each time around, we init the engine
     920    // and then loop again, this time executing individual opcodes.
     921    // The opcode loop terminates when the relocation PC
     922    // (state.currentReloc) hits the final opcode (state.terminatingReloc).
     923
     924    // Note:
     925    // One design decision I made was to totally re-init the engine state
     926    // for each section.  The CFM spec is unclear as to whether you're supposed
     927    // to totally re-init the engine state, or just re-init the section-specific
     928    // state (ie currentReloc, terminatingReloc, and relocAddress).  I hope this
     929    // is correct, but it's hard to test without having a fragment with multiple
     930    // relocated sections, which is difficult to create.
     931
     932    // How do I decide which opcodes should be effective (ie make changes to
     933    // the section being relocated) and which opcodes should just be executed
     934    // for their side effects (ie updated state.relocAddress or state.importIndex)?
     935    // The answer is both simple and subtle.  Opcodes whose actions are dependent
     936    // on a symbol that was in the weak linked library are effective, those that
     937    // an independent of those symbols are not.  The only opcodes that use
     938    // symbolic values are kPEFRelocImportRun and kPEFRelocSmByImport, and
     939    // these are only if the symbol is in the weak linked library.
     940    // All other cases are executed for their side effects only.
     941    //
     942    // How do I determine if a symbol is in the weak linked library?
     943    // Well I know the symbol's index and I know the lower bound and count
     944    // of the symbols in the weak linked library, so I just do a simple
     945    // bounds test, ie
     946    //
     947    //   firstImportedSymbol <= importIndex < firstImportedSymbol + importedSymbolCount
     948
     949    // From this code, it's relatively easy to see which relocation opcodes
     950    // aren't implemented.  If you ever encounter one, you'll find yourself
     951    // in MacsBug with a message telling you which opcode was found.  The
     952    // two big groups of opcodes I skipped were the large format opcodes
     953    // and the repeating opcodes.  I skipped them because:
     954    //
     955    // a) I haven't got a way to generate them in a PEF container that I can
     956    //    test against. Without that, there's no way I could be assured that
     957    //    the code worked.
     958    //
     959    // b) I'm lazy.
     960
     961    err = noErr;
     962    while ( sectionsLeftToRelocate > 0 ) {
     963        err = InitEngineState(fragToFix, sectionsLeftToRelocate, &state);
     964        if (err != noErr) {
     965            goto leaveNow;
     966        }
     967
     968        while ( state.currentReloc != state.terminatingReloc ) {
     969
     970            MoreAssertQ( state.currentReloc < totalRelocs );
     971
     972            opCode = relocInstrTable[state.currentReloc];
     973            switch ( PEFRelocBasicOpcode(opCode) ) {
     974                case kPEFRelocBySectDWithSkip:
     975                    {
     976                        UInt16 skipCount;
     977                        UInt16 relocCount;
     978
     979                        skipCount = ((opCode >> 6) & 0x00FF);
     980                        relocCount = (opCode & 0x003F);
     981                        state.relocAddress += skipCount;
     982                        state.relocAddress += relocCount;
     983                    }
     984                    break;
     985                case kPEFRelocBySectC:
     986                case kPEFRelocBySectD:
     987                    {
     988                        UInt16 runLength;
     989
     990                        runLength = (opCode & 0x01FF) + 1;
     991                        state.relocAddress += runLength;
     992                    }
     993                    break;
     994                case kPEFRelocTVector12:
     995                    {
     996                        UInt16 runLength;
     997
     998                        runLength = (opCode & 0x01FF) + 1;
     999                        state.relocAddress += (runLength * 3);
     1000                    }
     1001                    break;
     1002                case kPEFRelocTVector8:
     1003                case kPEFRelocVTable8:
     1004                    {
     1005                        UInt16 runLength;
     1006
     1007                        runLength = (opCode & 0x01FF) + 1;
     1008                        state.relocAddress += (runLength * 2);
     1009                    }
     1010                    break;
     1011                case kPEFRelocImportRun:
     1012                    {
     1013                        UInt32 symbolValue;
     1014                        UInt16 runLength;
     1015
     1016                        runLength = (opCode & 0x01FF) + 1;
     1017                        while (runLength > 0) {
     1018                            if ( state.importIndex >= importLibrary->firstImportedSymbol && state.importIndex < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
     1019                                err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, state.importIndex, &symbolValue);
     1020                                if (err != noErr) {
     1021                                    goto leaveNow;
     1022                                }
     1023                                *(state.relocAddress) += symbolValue;
     1024                            }
     1025                            state.importIndex += 1;
     1026                            state.relocAddress += 1;
     1027                            runLength -= 1;
     1028                        }
     1029                    }
     1030                    break;
     1031                case kPEFRelocSmByImport:
     1032                    {
     1033                        UInt32 symbolValue;
     1034                        UInt32 index;
     1035
     1036                        index = (opCode & 0x01FF);
     1037                        if ( index >= importLibrary->firstImportedSymbol && index < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
     1038                            err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, index, &symbolValue);
     1039                            if (err != noErr) {
     1040                                goto leaveNow;
     1041                            }
     1042                            *(state.relocAddress) += symbolValue;
     1043                        }
     1044                        state.importIndex = index + 1;
     1045                        state.relocAddress += 1;
     1046                    }
     1047                    break;
     1048                case kPEFRelocSmSetSectC:
     1049                    {
     1050                        UInt32 index;
     1051
     1052                        index = (opCode & 0x01FF);
     1053                        state.sectionC = GetSectionBaseAddress(fragToFix, index);
     1054                        MoreAssertQ(state.sectionC != nil);
     1055                    }
     1056                    break;
     1057                case kPEFRelocSmSetSectD:
     1058                    {
     1059                        UInt32 index;
     1060
     1061                        index = (opCode & 0x01FF);
     1062                        state.sectionD = GetSectionBaseAddress(fragToFix, index);
     1063                        MoreAssertQ(state.sectionD != nil);
     1064                    }
     1065                    break;
     1066                case kPEFRelocSmBySection:
     1067                    state.relocAddress += 1;
     1068                    break;
     1069                case kPEFRelocIncrPosition:
     1070                    {
     1071                        UInt16 offset;
     1072
     1073                        offset = (opCode & 0x0FFF) + 1;
     1074                        ((char *) state.relocAddress) += offset;
     1075                    }
     1076                    break;
     1077                case kPEFRelocSmRepeat:
     1078                    #if MORE_DEBUG
     1079                        DebugStr("\pRunRelocationEngine: kPEFRelocSmRepeat not yet implemented");
     1080                    #endif
     1081                    err = unimpErr;
     1082                    goto leaveNow;
     1083                    break;
     1084                case kPEFRelocSetPosition:
     1085                    {
     1086                        UInt32 offset;
     1087
     1088                        // Lot's of folks have tried various interpretations of the description of
     1089                        // this opCode in "Mac OS Runtime Architectures" (which states "This instruction
     1090                        // sets relocAddress to the address of the section offset offset."  *smile*).
     1091                        // I eventually dug into the CFM source code to find my interpretation, which
     1092                        // I believe is correct.  The key point is tht the offset is relative to
     1093                        // the start of the section for which these relocations are being performed.
     1094
     1095                        // Skip to next reloc word, which is the second chunk of the offset.
     1096
     1097                        state.currentReloc += 1;
     1098
     1099                        // Extract offset based on the most significant 10 bits in opCode and
     1100                        // the next significant 16 bits in the next reloc word.
     1101
     1102                        offset = PEFRelocSetPosFullOffset(opCode, relocInstrTable[state.currentReloc]);
     1103
     1104                        state.relocAddress = (UInt32 *) ( ((char *) state.sectionBase) + offset);
     1105                    }
     1106                    break;
     1107                case kPEFRelocLgByImport:
     1108                    {
     1109                        UInt32 symbolValue;
     1110                        UInt32 index;
     1111
     1112                        // Get the 26 bit symbol index from the current and next reloc words.
     1113
     1114                        state.currentReloc += 1;
     1115                        index = PEFRelocLgByImportFullIndex(opCode, relocInstrTable[state.currentReloc]);
     1116
     1117                        if ( index >= importLibrary->firstImportedSymbol && index < (importLibrary->firstImportedSymbol + importLibrary->importedSymbolCount) ) {
     1118                            err = LookupSymbol(lookup, refCon, fragToFix->loaderSection, index, &symbolValue);
     1119                            if (err != noErr) {
     1120                                goto leaveNow;
     1121                            }
     1122                            *(state.relocAddress) += symbolValue;
     1123                        }
     1124                        state.importIndex = index + 1;
     1125                        state.relocAddress += 1;
     1126                    }
     1127                    break;
     1128                case kPEFRelocLgRepeat:
     1129                    #if MORE_DEBUG
     1130                        DebugStr("\pRunRelocationEngine: kPEFRelocLgRepeat not yet implemented");
     1131                    #endif
     1132                    err = unimpErr;
     1133                    goto leaveNow;
     1134                    break;
     1135                case kPEFRelocLgSetOrBySection:
     1136                    #if MORE_DEBUG
     1137                        DebugStr("\pRunRelocationEngine: kPEFRelocLgSetOrBySection not yet implemented");
     1138                    #endif
     1139                    err = unimpErr;
     1140                    goto leaveNow;
     1141                    break;
     1142                case kPEFRelocUndefinedOpcode:
     1143                    err = cfragFragmentCorruptErr;
     1144                    goto leaveNow;
     1145                    break;
     1146                default:
     1147                    MoreAssertQ(false);
     1148                    err = cfragFragmentCorruptErr;
     1149                    goto leaveNow;
     1150                    break;
     1151            }
     1152            state.currentReloc += 1;
     1153        }
     1154
     1155        sectionsLeftToRelocate -= 1;
     1156    }
    11571157
    11581158leaveNow:
    1159         return err;
     1159    return err;
    11601160}
    11611161
    11621162extern pascal OSStatus CFMLateImportCore(const CFragSystem7DiskFlatLocator *fragToFixLocator,
    1163                                                                                 CFragConnectionID fragToFixConnID,
    1164                                                                                 CFragInitFunction fragToFixInitRoutine,
    1165                                                                                 ConstStr255Param weakLinkedLibraryName,
    1166                                                                                 CFMLateImportLookupProc lookup,
    1167                                                                                 void *refCon)
    1168         // See comments in interface part.
    1169 {
    1170         OSStatus err;
    1171         OSStatus junk;
    1172         FragToFixInfo fragToFix;
    1173         PEFImportedLibrary *importLibrary;
    1174         char weakLinkedLibraryNameCString[256];
    1175 
    1176         MoreAssertQ(fragToFixLocator != nil);   
    1177         MoreAssertQ(fragToFixConnID != nil);
    1178         MoreAssertQ(fragToFixInitRoutine != nil);
    1179         MoreAssertQ(weakLinkedLibraryName != nil);     
    1180         MoreAssertQ(lookup != nil);     
    1181        
    1182         // Fill out the bits of fragToFix which are passed in
    1183         // by the client.
    1184        
    1185         MoreBlockZero(&fragToFix, sizeof(fragToFix));
    1186         fragToFix.locator = *fragToFixLocator;
    1187         fragToFix.connID  = fragToFixConnID;
    1188         fragToFix.initRoutine = fragToFixInitRoutine;
    1189        
    1190         // Make a C string from weakLinkedLibraryName.
    1191        
    1192         BlockMoveData(weakLinkedLibraryName + 1, weakLinkedLibraryNameCString, weakLinkedLibraryName[0]);
    1193         weakLinkedLibraryNameCString[weakLinkedLibraryName[0]] = 0;
    1194 
    1195         // Get the basic information from the fragment.
    1196         // Fills out the containerHeader, sectionHeaders, loaderSection and fileRef fields
    1197         // of fragToFix.
    1198        
    1199         err = ReadContainerBasics(&fragToFix);
    1200 
    1201         // Set up the base address fields in fragToFix (ie section0Base and section1Base)
    1202         // by looking up our init routine (fragToFix.initRoutine) and subtracting
    1203         // away the section offsets (which we get from the disk copy of the section)
    1204         // to derive the bases of the sections themselves.
    1205        
    1206         if (err == noErr) {
    1207                 err = SetupSectionBaseAddresses(&fragToFix);
    1208         }
    1209        
    1210         // Look inside the loader section for the import library description
    1211         // of weakLinkedLibraryName.  We need this to know the range of symbol
    1212         // indexes we're going to fix up.
    1213        
    1214         if (err == noErr) {
    1215                 err = FindImportLibrary(fragToFix.loaderSection, weakLinkedLibraryNameCString, &importLibrary);
    1216         }
    1217        
    1218         // Do a quick check to ensure that the library was actually imported weak.
    1219         // If it wasn't, it doesn't make much sense to resolve its weak imports
    1220         // later on.  Resolving them again is likely to be bad.
    1221        
    1222         if (err == noErr) {
    1223                 if ((importLibrary->options & kPEFWeakImportLibMask) == 0) {
    1224                         err = cfragFragmentUsageErr;
    1225                 }
    1226         }
    1227        
    1228         // Now run the main relocation engine.
    1229        
    1230         if (err == noErr) {
    1231                 err = RunRelocationEngine(&fragToFix, importLibrary, lookup, refCon);
    1232         }
    1233        
    1234         // Clean up.
    1235        
    1236         if (fragToFix.disposeSectionPointers) {
    1237                 if (fragToFix.fileRef != 0) {
    1238                         junk = FSClose(fragToFix.fileRef);
    1239                         MoreAssertQ(junk == noErr);
    1240                 }
    1241                 if (fragToFix.loaderSection != nil) {
    1242                         DisposePtr( (Ptr) fragToFix.loaderSection);
    1243                         MoreAssertQ(MemError() == noErr);
    1244                 }
    1245                 if (fragToFix.sectionHeaders != nil) {
    1246                         DisposePtr( (Ptr) fragToFix.sectionHeaders);
    1247                         MoreAssertQ(MemError() == noErr);
    1248                 }
    1249         }
    1250         return err;
     1163                                                                                CFragConnectionID fragToFixConnID,
     1164                                                                                CFragInitFunction fragToFixInitRoutine,
     1165                                                                                ConstStr255Param weakLinkedLibraryName,
     1166                                                                                CFMLateImportLookupProc lookup,
     1167                                                                                void *refCon)
     1168    // See comments in interface part.
     1169{
     1170    OSStatus err;
     1171    OSStatus junk;
     1172    FragToFixInfo fragToFix;
     1173    PEFImportedLibrary *importLibrary;
     1174    char weakLinkedLibraryNameCString[256];
     1175
     1176    MoreAssertQ(fragToFixLocator != nil);
     1177    MoreAssertQ(fragToFixConnID != nil);
     1178    MoreAssertQ(fragToFixInitRoutine != nil);
     1179    MoreAssertQ(weakLinkedLibraryName != nil);
     1180    MoreAssertQ(lookup != nil);
     1181
     1182    // Fill out the bits of fragToFix which are passed in
     1183    // by the client.
     1184
     1185    MoreBlockZero(&fragToFix, sizeof(fragToFix));
     1186    fragToFix.locator = *fragToFixLocator;
     1187    fragToFix.connID  = fragToFixConnID;
     1188    fragToFix.initRoutine = fragToFixInitRoutine;
     1189
     1190    // Make a C string from weakLinkedLibraryName.
     1191
     1192    BlockMoveData(weakLinkedLibraryName + 1, weakLinkedLibraryNameCString, weakLinkedLibraryName[0]);
     1193    weakLinkedLibraryNameCString[weakLinkedLibraryName[0]] = 0;
     1194
     1195    // Get the basic information from the fragment.
     1196    // Fills out the containerHeader, sectionHeaders, loaderSection and fileRef fields
     1197    // of fragToFix.
     1198
     1199    err = ReadContainerBasics(&fragToFix);
     1200
     1201    // Set up the base address fields in fragToFix (ie section0Base and section1Base)
     1202    // by looking up our init routine (fragToFix.initRoutine) and subtracting
     1203    // away the section offsets (which we get from the disk copy of the section)
     1204    // to derive the bases of the sections themselves.
     1205
     1206    if (err == noErr) {
     1207        err = SetupSectionBaseAddresses(&fragToFix);
     1208    }
     1209
     1210    // Look inside the loader section for the import library description
     1211    // of weakLinkedLibraryName.  We need this to know the range of symbol
     1212    // indexes we're going to fix up.
     1213
     1214    if (err == noErr) {
     1215        err = FindImportLibrary(fragToFix.loaderSection, weakLinkedLibraryNameCString, &importLibrary);
     1216    }
     1217
     1218    // Do a quick check to ensure that the library was actually imported weak.
     1219    // If it wasn't, it doesn't make much sense to resolve its weak imports
     1220    // later on.  Resolving them again is likely to be bad.
     1221
     1222    if (err == noErr) {
     1223        if ((importLibrary->options & kPEFWeakImportLibMask) == 0) {
     1224            err = cfragFragmentUsageErr;
     1225        }
     1226    }
     1227
     1228    // Now run the main relocation engine.
     1229
     1230    if (err == noErr) {
     1231        err = RunRelocationEngine(&fragToFix, importLibrary, lookup, refCon);
     1232    }
     1233
     1234    // Clean up.
     1235
     1236    if (fragToFix.disposeSectionPointers) {
     1237        if (fragToFix.fileRef != 0) {
     1238            junk = FSClose(fragToFix.fileRef);
     1239            MoreAssertQ(junk == noErr);
     1240        }
     1241        if (fragToFix.loaderSection != nil) {
     1242            DisposePtr( (Ptr) fragToFix.loaderSection);
     1243            MoreAssertQ(MemError() == noErr);
     1244        }
     1245        if (fragToFix.sectionHeaders != nil) {
     1246            DisposePtr( (Ptr) fragToFix.sectionHeaders);
     1247            MoreAssertQ(MemError() == noErr);
     1248        }
     1249    }
     1250    return err;
    12511251}
    12521252
    12531253static pascal OSStatus FragmentLookup(ConstStr255Param symName, CFragSymbolClass symClass,
    1254                                                                         void **symAddr, void *refCon)
    1255         // This is the CFMLateImportLookupProc callback used when
    1256         // late importing from a CFM shared library.
    1257 {
    1258         OSStatus err;
    1259         CFragConnectionID connIDToImport;
    1260         CFragSymbolClass  foundSymClass;
    1261        
    1262         MoreAssertQ(symName != nil);
    1263         MoreAssertQ(symAddr != nil);
    1264         MoreAssertQ(refCon  != nil);
    1265        
    1266         connIDToImport = (CFragConnectionID) refCon;
    1267        
    1268         // Shame there's no way to validate that connIDToImport is valid.
    1269 
    1270         err = FindSymbol(connIDToImport, symName, (Ptr *) symAddr, &foundSymClass);
    1271         if (err == noErr) {
    1272                 // If the symbol isn't of the right class, we act like we didn't
    1273                 // find it, but also assert in the debug build because weird things
    1274                 // are afoot.
    1275                 if (foundSymClass != symClass) {
    1276                         MoreAssertQ(false);
    1277                         *symAddr = nil;
    1278                         err = cfragNoSymbolErr;
    1279                 }
    1280         }
    1281         return err;
     1254                                                                        void **symAddr, void *refCon)
     1255    // This is the CFMLateImportLookupProc callback used when
     1256    // late importing from a CFM shared library.
     1257{
     1258    OSStatus err;
     1259    CFragConnectionID connIDToImport;
     1260    CFragSymbolClass  foundSymClass;
     1261
     1262    MoreAssertQ(symName != nil);
     1263    MoreAssertQ(symAddr != nil);
     1264    MoreAssertQ(refCon  != nil);
     1265
     1266    connIDToImport = (CFragConnectionID) refCon;
     1267
     1268    // Shame there's no way to validate that connIDToImport is valid.
     1269
     1270    err = FindSymbol(connIDToImport, symName, (Ptr *) symAddr, &foundSymClass);
     1271    if (err == noErr) {
     1272        // If the symbol isn't of the right class, we act like we didn't
     1273        // find it, but also assert in the debug build because weird things
     1274        // are afoot.
     1275        if (foundSymClass != symClass) {
     1276            MoreAssertQ(false);
     1277            *symAddr = nil;
     1278            err = cfragNoSymbolErr;
     1279        }
     1280    }
     1281    return err;
    12821282}
    12831283
    12841284extern pascal OSStatus CFMLateImportLibrary(const CFragSystem7DiskFlatLocator *fragToFixLocator,
    1285                                                                                 CFragConnectionID fragToFixConnID,
    1286                                                                                 CFragInitFunction fragToFixInitRoutine,
    1287                                                                                 ConstStr255Param weakLinkedLibraryName,
    1288                                                                                 CFragConnectionID connIDToImport)
    1289         // See comments in interface part.
    1290 {
    1291         MoreAssertQ(connIDToImport != nil);
    1292         return CFMLateImportCore(fragToFixLocator, fragToFixConnID, fragToFixInitRoutine,
    1293                                                                                 weakLinkedLibraryName, FragmentLookup, connIDToImport);
     1285                                                                                CFragConnectionID fragToFixConnID,
     1286                                                                                CFragInitFunction fragToFixInitRoutine,
     1287                                                                                ConstStr255Param weakLinkedLibraryName,
     1288                                                                                CFragConnectionID connIDToImport)
     1289    // See comments in interface part.
     1290{
     1291    MoreAssertQ(connIDToImport != nil);
     1292    return CFMLateImportCore(fragToFixLocator, fragToFixConnID, fragToFixInitRoutine,
     1293                                                                            weakLinkedLibraryName, FragmentLookup, connIDToImport);
    12941294}
    12951295
    12961296static pascal OSStatus BundleLookup(ConstStr255Param symName, CFragSymbolClass symClass,
    1297                                                                         void **symAddr, void *refCon)
    1298         // This is the CFMLateImportLookupProc callback used when
    1299         // late importing from a CFBundle.
    1300 {
    1301         OSStatus        err;
    1302         CFBundleRef bundleToImport;
    1303         CFStringRef symNameStr;
    1304        
    1305         MoreAssertQ(symName != nil);
    1306         MoreAssertQ(symAddr != nil);
    1307         MoreAssertQ(refCon  != nil);
    1308        
    1309         symNameStr = nil;
    1310        
    1311         bundleToImport = (CFBundleRef) refCon;
    1312        
    1313         // Shame there's no way to validate that bundleToImport is really a bundle.
    1314        
    1315         // We can only find function pointers because CFBundleGetFunctionPointerForName
    1316         // only works for function pointers.  So if the client is asking for something
    1317         // other than a function pointer (ie TVector symbol) then we don't even true.
    1318         // Also assert in the debug build because this shows a certain lack of
    1319         // understanding on the part of the client.
    1320         //
    1321         // CF is being revise to support accessing data symbols using a new API
    1322         // (currently this is available to Apple internal developers as
    1323         // CFBundleGetDataPointerForName).  When the new API is available in a
    1324         // public header file I should revise this code to lift this restriction.
    1325        
    1326         err = noErr;
    1327         if (symClass != kTVectorCFragSymbol) {
    1328                 MoreAssertQ(false);
    1329                 err = cfragNoSymbolErr;
    1330         }
    1331         if (err == noErr) {
    1332                 symNameStr = CFStringCreateWithPascalString(kCFAllocatorSystemDefault,
    1333                                                                                                         symName, kCFStringEncodingMacRoman);
    1334                 if (symNameStr == nil) {
    1335                         err = coreFoundationUnknownErr;
    1336                 }
    1337         }
    1338         if (err == noErr) {
    1339                 *symAddr = CFBundleGetFunctionPointerForName(bundleToImport, symNameStr);
    1340                 if (*symAddr == nil) {
    1341                         err = cfragNoSymbolErr;
    1342                 }
    1343         }
    1344         if (symNameStr != nil) {
    1345                 CFRelease(symNameStr);
    1346         }
    1347         return err;
     1297                                                                        void **symAddr, void *refCon)
     1298    // This is the CFMLateImportLookupProc callback used when
     1299    // late importing from a CFBundle.
     1300{
     1301    OSStatus            err;
     1302    CFBundleRef bundleToImport;
     1303    CFStringRef symNameStr;
     1304
     1305    MoreAssertQ(symName != nil);
     1306    MoreAssertQ(symAddr != nil);
     1307    MoreAssertQ(refCon  != nil);
     1308
     1309    symNameStr = nil;
     1310
     1311    bundleToImport = (CFBundleRef) refCon;
     1312
     1313    // Shame there's no way to validate that bundleToImport is really a bundle.
     1314
     1315    // We can only find function pointers because CFBundleGetFunctionPointerForName
     1316    // only works for function pointers.  So if the client is asking for something
     1317    // other than a function pointer (ie TVector symbol) then we don't even true.
     1318    // Also assert in the debug build because this shows a certain lack of
     1319    // understanding on the part of the client.
     1320    //
     1321    // CF is being revise to support accessing data symbols using a new API
     1322    // (currently this is available to Apple internal developers as
     1323    // CFBundleGetDataPointerForName).  When the new API is available in a
     1324    // public header file I should revise this code to lift this restriction.
     1325
     1326    err = noErr;
     1327    if (symClass != kTVectorCFragSymbol) {
     1328        MoreAssertQ(false);
     1329        err = cfragNoSymbolErr;
     1330    }
     1331    if (err == noErr) {
     1332        symNameStr = CFStringCreateWithPascalString(kCFAllocatorSystemDefault,
     1333                                                                                                symName, kCFStringEncodingMacRoman);
     1334        if (symNameStr == nil) {
     1335            err = coreFoundationUnknownErr;
     1336        }
     1337    }
     1338    if (err == noErr) {
     1339        *symAddr = CFBundleGetFunctionPointerForName(bundleToImport, symNameStr);
     1340        if (*symAddr == nil) {
     1341            err = cfragNoSymbolErr;
     1342        }
     1343    }
     1344    if (symNameStr != nil) {
     1345        CFRelease(symNameStr);
     1346    }
     1347    return err;
    13481348}
    13491349
    13501350extern pascal OSStatus CFMLateImportBundle(const CFragSystem7DiskFlatLocator *fragToFixLocator,
    1351                                                                                 CFragConnectionID fragToFixConnID,
    1352                                                                                 CFragInitFunction fragToFixInitRoutine,
    1353                                                                                 ConstStr255Param weakLinkedLibraryName,
    1354                                                                                 CFBundleRef bundleToImport)
    1355         // See comments in interface part.
    1356 {
    1357         MoreAssertQ(bundleToImport != nil);
    1358         return CFMLateImportCore(fragToFixLocator, fragToFixConnID, fragToFixInitRoutine,
    1359                                                                                 weakLinkedLibraryName, BundleLookup, bundleToImport);
    1360 }
     1351                                                                                CFragConnectionID fragToFixConnID,
     1352                                                                                CFragInitFunction fragToFixInitRoutine,
     1353                                                                                ConstStr255Param weakLinkedLibraryName,
     1354                                                                                CFBundleRef bundleToImport)
     1355    // See comments in interface part.
     1356{
     1357    MoreAssertQ(bundleToImport != nil);
     1358    return CFMLateImportCore(fragToFixLocator, fragToFixConnID, fragToFixInitRoutine,
     1359                                                                            weakLinkedLibraryName, BundleLookup, bundleToImport);
     1360}
  • python/trunk/Mac/Modules/cg/CFMLateImport.h

    r2 r391  
    11/*
    2         File:           CFMLateImport.h
    3 
    4         Contains:       Interface to CFM late import library.
    5 
    6         Written by:     Quinn
    7 
    8         Copyright:      Copyright © 1999 by Apple Computer, Inc., all rights reserved.
    9 
    10                                 You may incorporate this Apple sample source code into your program(s) without
    11                                 restriction. This Apple sample source code has been provided "AS IS" and the
    12                                 responsibility for its operation is yours. You are not permitted to redistribute
    13                                 this Apple sample source code as "Apple sample source code" after having made
    14                                 changes. If you're going to re-distribute the source, we require that you make
    15                                 it clear in the source that the code was descended from Apple sample source
    16                                 code, but that you've made changes.
    17 
    18         Change History (most recent first):
    19 
    20          <6>     21/9/01    Quinn   Changes for CWPro7 Mach-O build.
    21          <5>     19/9/01    Quinn   Change comments to reflect the fact that an unpacked data
    22                                     section is no longer required.
    23          <4>     19/9/01    Quinn   Simplified API and implementation after a suggestion by Eric
    24                                     Grant. You no longer have to CFM export a dummy function; you
    25                                     can just pass in the address of your fragment's init routine.
    26          <3>    16/11/00    Quinn   Allow symbol finding via a callback and use that to implement
    27                                     CFBundle support.
    28          <2>    18/10/99    Quinn   Renamed CFMLateImport to CFMLateImportLibrary to allow for
    29                                     possible future API expansion.
    30          <1>     15/6/99    Quinn   First checked in.
     2    File:               CFMLateImport.h
     3
     4    Contains:           Interface to CFM late import library.
     5
     6    Written by:         Quinn
     7
     8    Copyright:          Copyright © 1999 by Apple Computer, Inc., all rights reserved.
     9
     10                            You may incorporate this Apple sample source code into your program(s) without
     11                            restriction. This Apple sample source code has been provided "AS IS" and the
     12                            responsibility for its operation is yours. You are not permitted to redistribute
     13                            this Apple sample source code as "Apple sample source code" after having made
     14                            changes. If you're going to re-distribute the source, we require that you make
     15                            it clear in the source that the code was descended from Apple sample source
     16                            code, but that you've made changes.
     17
     18    Change History (most recent first):
     19
     20     <6>     21/9/01    Quinn   Changes for CWPro7 Mach-O build.
     21     <5>     19/9/01    Quinn   Change comments to reflect the fact that an unpacked data
     22                                section is no longer required.
     23     <4>     19/9/01    Quinn   Simplified API and implementation after a suggestion by Eric
     24                                Grant. You no longer have to CFM export a dummy function; you
     25                                can just pass in the address of your fragment's init routine.
     26     <3>    16/11/00    Quinn   Allow symbol finding via a callback and use that to implement
     27                                CFBundle support.
     28     <2>    18/10/99    Quinn   Renamed CFMLateImport to CFMLateImportLibrary to allow for
     29                                possible future API expansion.
     30     <1>     15/6/99    Quinn   First checked in.
    3131*/
    3232
     
    4242
    4343#if ! MORE_FRAMEWORK_INCLUDES
    44         #include <MacTypes.h>
    45         #include <CodeFragments.h>
    46         #include <Devices.h>
    47         #include <CFBundle.h>
     44    #include <MacTypes.h>
     45    #include <CodeFragments.h>
     46    #include <Devices.h>
     47    #include <CFBundle.h>
    4848#endif
    4949
     
    5454#endif
    5555
    56 /*      FAQ
    57         ---
    58        
    59         Q:      What does this library do?
    60         A:      It allows you to resolve a weak linked library at runtime,
    61                 by supply a CFM connection to the library that should substitute
    62                 for the weak linked one.
    63        
    64         Q:      Does the substituted library have to have the same name as the
    65                 weak linked library.
    66         A:      No.
    67        
    68         Q:      What's this useful for?
    69         A:      The most obvious example of where this is useful is when
    70                 you rely on shared libraries that the user might delete
    71                 or move.  To can find the shared library (possibly even
    72                 using CatSearch), call GetDiskFragment to open a connection
    73                 to it, late import it using this library, and then the
    74                 rest of your code can continue to use the shared library
    75                 as if nothing had happened.  No more defining thousands
    76                 of stub routines which call through routine pointers.
    77                
    78                 There are, however, numerous less obvious uses.  You can
    79                 use this code to make a 'self repairing' application.  If
    80                 the user removes your shared library from the Extensions
    81                 folder, the startup code for your application can offer
    82                 tor re-install it.  If the user agrees, you can then
    83                 re-install your shared library, late import it, and then
    84                 continue running your application if nothing happened.
    85                
    86                 You can even use this code to free yourself from the
    87                 Extensions folder entirely.  Say you have a suite of
    88                 applications that currently installs a dozen shared
    89                 libraries in the Extensions folder.  You can move those
    90                 libraries to another folder entirely and each application's
    91                 startup code can track down the library (using an alias
    92                 in the Preferences file) and late import it.
    93                
    94                 An even cooler use is to provide easy abstraction layers.
    95                 Say you have a network code for both the MacTCP
    96                 API and the Open Transport API.  Typically, you would be
    97                 force to do this by having an abstraction layer where every
    98                 routine contains a switch between MacTCP and OT.  Your
    99                 OpenSocket routine might look like:
    100 
    101                         static int OpenSocket(void)
    102                         {
    103                             if (gOTAvailable) {
    104                                 return OpenSocketOT();
    105                             } else {
    106                                 return OpenSocketMacTCP();
    107                             }
    108                         }
    109                
    110                 With this code, you can avoid that entirely.  Simply
    111                 weak link to a shared library that you know is never
    112                 going to be implemented ("crea;MySocketsDummy") and then,
    113                 at runtime, decide whether the system has MacTCP or OT
    114                 and late import the relevant real implementation
    115                 ("crea;MySocketsMacTCP" or "crea;MySocketsOT").
    116                 One benefit of this approach is that only the MacTCP or
    117                 the OT code is resident in memory on any given system.
     56/*      FAQ
     57    ---
     58
     59    Q:          What does this library do?
     60    A:          It allows you to resolve a weak linked library at runtime,
     61        by supply a CFM connection to the library that should substitute
     62        for the weak linked one.
     63
     64    Q:          Does the substituted library have to have the same name as the
     65        weak linked library.
     66    A:          No.
     67
     68    Q:          What's this useful for?
     69    A:          The most obvious example of where this is useful is when
     70        you rely on shared libraries that the user might delete
     71        or move.  To can find the shared library (possibly even
     72        using CatSearch), call GetDiskFragment to open a connection
     73        to it, late import it using this library, and then the
     74        rest of your code can continue to use the shared library
     75        as if nothing had happened.  No more defining thousands
     76        of stub routines which call through routine pointers.
     77
     78        There are, however, numerous less obvious uses.  You can
     79        use this code to make a 'self repairing' application.  If
     80        the user removes your shared library from the Extensions
     81        folder, the startup code for your application can offer
     82        tor re-install it.  If the user agrees, you can then
     83        re-install your shared library, late import it, and then
     84        continue running your application if nothing happened.
     85
     86        You can even use this code to free yourself from the
     87        Extensions folder entirely.  Say you have a suite of
     88        applications that currently installs a dozen shared
     89        libraries in the Extensions folder.  You can move those
     90        libraries to another folder entirely and each application's
     91        startup code can track down the library (using an alias
     92        in the Preferences file) and late import it.
     93
     94        An even cooler use is to provide easy abstraction layers.
     95        Say you have a network code for both the MacTCP
     96        API and the Open Transport API.  Typically, you would be
     97        force to do this by having an abstraction layer where every
     98        routine contains a switch between MacTCP and OT.  Your
     99        OpenSocket routine might look like:
     100
     101            static int OpenSocket(void)
     102            {
     103                if (gOTAvailable) {
     104                return OpenSocketOT();
     105                } else {
     106                return OpenSocketMacTCP();
     107                }
     108            }
     109
     110        With this code, you can avoid that entirely.  Simply
     111        weak link to a shared library that you know is never
     112        going to be implemented ("crea;MySocketsDummy") and then,
     113        at runtime, decide whether the system has MacTCP or OT
     114        and late import the relevant real implementation
     115        ("crea;MySocketsMacTCP" or "crea;MySocketsOT").
     116        One benefit of this approach is that only the MacTCP or
     117        the OT code is resident in memory on any given system.
    118118*/
    119119
    120120typedef pascal OSStatus (*CFMLateImportLookupProc)(ConstStr255Param symName, CFragSymbolClass symClass,
    121                                                                                                         void **symAddr, void *refCon);
    122         // CFMLateImportLookupProc defines a callback for CFMLateImportCore.
    123         // The routine is expected to look up the address of the symbol named
    124         // symName and return it in *symAddr.  The symbol should be of class
    125         // symClass, although the callback decides whether a class mismatch is
    126         // an error.  refCon is an application defined value that was originally
    127         // passed in to CFMLateImportCore.
    128         //
    129         // If this routine returns an error, a symbol address of 0 is assumed.
    130         // If the symbol is marked as a weak import, the CFMLateImportCore will
    131         // continue, otherwise the CFMLateImportCore routine will fail with the
    132         // error.
    133        
     121                                                                                                        void **symAddr, void *refCon);
     122    // CFMLateImportLookupProc defines a callback for CFMLateImportCore.
     123    // The routine is expected to look up the address of the symbol named
     124    // symName and return it in *symAddr.  The symbol should be of class
     125    // symClass, although the callback decides whether a class mismatch is
     126    // an error.  refCon is an application defined value that was originally
     127    // passed in to CFMLateImportCore.
     128    //
     129    // If this routine returns an error, a symbol address of 0 is assumed.
     130    // If the symbol is marked as a weak import, the CFMLateImportCore will
     131    // continue, otherwise the CFMLateImportCore routine will fail with the
     132    // error.
     133
    134134extern pascal OSStatus CFMLateImportCore(const CFragSystem7DiskFlatLocator *fragToFixLocator,
    135                                                                                 CFragConnectionID fragToFixConnID,
    136                                                                                 CFragInitFunction fragToFixInitRoutine,
    137                                                                                 ConstStr255Param weakLinkedLibraryName,
    138                                                                                 CFMLateImportLookupProc lookup,
    139                                                                                 void *refCon);
    140         // This routine will link you, at runtime, to some library
    141         // that you were weak linked to and wasn't present when your
    142         // fragment was prepared.  As well as the obvious functionality
    143         // of being able to resolve weak links after prepare time,
    144         // this functionality can be put to a number of less obvious uses,
    145         // some of which are discussed at the top of this header file.
    146         //
    147         // To call this routine, you need a number of pieces of information:
    148         //
    149         // 1. fragToFixLocator, fragToFixConnID:  The location of your own
    150         //    code fragment on disk and the CFM connection ID to your own
    151         //    code fragment.  Typically you get this information from your
    152         //    fragment's CFM init routine.  You must ensure that
    153         //    fragToFixLocator->fileSpec points to an FSSpec of the
    154         //    file which holds your code fragment.
    155         //
    156         //    IMPORTANT:
    157         //    The fact that you pass in a CFragSystem7DiskFlatLocator as the
    158         //    fragToFixLocator implies that the fragment to be fixed up must
    159         //    be in the data fork of a file.  The code could be modified
    160         //    to remove this requirement, but on disk code fragments are the most
    161         //    common case.
    162         //
    163         //    IMPORTANT:
    164         //    The fragment to fix may have a packed data section.  Packing the
    165         //    data section will reduce the size of your fragment on disk, but it
    166         //    will significantly increase the memory needed by this routine
    167         //    (it increases memory usage by the sum of the sizes of the packed
    168         //    and unpacked data section).  See below for instructions on how to
    169         //    create an unpacked data section.
    170         //
    171         // 2. fragToFixInitRoutine:  A pointer to your own code fragment's
    172         //    fragment initialiser routine.  You necessarily have one of these
    173         //    because you need it to get values for the fragToFixLocator and
    174         //    fragToFixConnID parameters.  Just pass its address in as a parameter
    175         //    as well.
    176         //
    177         // 3. weakLinkedLibraryName:  The name of the weak linked library which
    178         //    failed to link.  You must have weak linked to this library.
    179         //    It is oxymoric for you to pass a strong linked library here,
    180         //    because your code would not have prepared if a strong linked
    181         //    library failed to prepare, and so you couldn't supply a valid
    182         ///   fragToFix.
    183         //
    184         // 4. lookup, refCon:  A pointer to a callback function that the
    185         //        routine calls to look up the address of a symbol, and a refCon
    186         //    for that callback routine.
    187         //
    188         // Note:
    189         // The fragToFixLocator and fragToFixInitRoutine parameters
    190         // are artifacts of the way in which this functionality is implemented.
    191         // In an ideal world, where CFM exported decent introspection APIs
    192         // to third party developers, these parameters would not be necessary.
    193         // If you're using this code inside Apple, you probably should investigate
    194         // using the CFM private APIs for getting at the information these
    195         // parameters are needed for.  See the comments inside the implementation
    196         // for more details.
    197         //
    198         // Note:
    199         // The extra memory taken when you use a packed data section is also an
    200         // artifact of my workaround for the lack of CFM introspection APIs.  In
    201         // my opinion it's better to use an unpacked data section and consume more
    202         // space on disk while saving memory.  In CodeWarrior you can switch to an
    203         // unpacked data section by checking the "Expand Uninitialized Data"
    204         // checkbox in the "PPC PEF" settings panel.  In MPW, specified the
    205         // "-packdata off" option to PPCLink.
    206         //
    207         // When the routine returns, any symbols that you imported from the
    208         // library named weakLinkedLibraryName will be resolved to the address
    209         // of the symbol provided by the "lookup" callback routine.
    210         //
    211         // It is possible for an unresolved import to remain unresolved after
    212         // this routine returns.  If the symbol import is marked as weak (as
    213         // opposed to the library, which *must* be marked as weak) and the symbol
    214         // is not found by the "lookup" callback, the routine will simple skip
    215         // that symbol.  If the symbol isn't marked as weak, the routine will fail
    216         // in that case.
    217         //
    218         // Most of the possible error results are co-opted CFM errors.  These
    219         // include:
    220         //
    221         // cfragFragmentFormatErr  -- The fragment to fix is is an unknown format.
    222         // cfragNoSectionErr       -- Could not find the loader section in the fragment to fix.
    223         // cfragNoLibraryErr       -- The fragment to fix is not weak linked to weakLinkedLibraryName.
    224         // cfragFragmentUsageErr   -- The fragment to fix doesn't have a data section.
    225         //                         -- The fragment to fix is strong linked to weakLinkedLibraryName.
    226         //                         -- The fragment doesn't have an init routine.
    227         // cfragFragmentCorruptErr -- Encountered an undefined relocation opcode.
    228         // unimpErr                -- Encountered an unimplement relocation opcode.  The
    229         //                            relocation engine only implements a subset of the CFM
    230         //                            relocation opcodes, the subset most commonly used by
    231         //                            MPW and CodeWarrior PEF containers.  If you encounter
    232         //                            this error, you'll probably have to add the weird
    233         //                            relocation opcode to the engine, which shouldn't be
    234         //                            be too hard.
    235         // memFullErr                      -- It's likely that this error is triggered by the memory
    236         //                            needed to unpack your data section.  Either make your
    237         //                            data section smaller, or unpack it (see above).
    238         // errors returned by FindSymbol
    239         // errors returned by Memory Manager
    240         //
    241         // The routine needs enough memory to hold the loader section of the fragment
    242         // to fix in memory.  It allocates that memory using NewPtr and dispsoses of
    243         // it before it returns.  You may want to change the memory allocator, which
    244         // is very simple.
     135                                                                                CFragConnectionID fragToFixConnID,
     136                                                                                CFragInitFunction fragToFixInitRoutine,
     137                                                                                ConstStr255Param weakLinkedLibraryName,
     138                                                                                CFMLateImportLookupProc lookup,
     139                                                                                void *refCon);
     140    // This routine will link you, at runtime, to some library
     141    // that you were weak linked to and wasn't present when your
     142    // fragment was prepared.  As well as the obvious functionality
     143    // of being able to resolve weak links after prepare time,
     144    // this functionality can be put to a number of less obvious uses,
     145    // some of which are discussed at the top of this header file.
     146    //
     147    // To call this routine, you need a number of pieces of information:
     148    //
     149    // 1. fragToFixLocator, fragToFixConnID:  The location of your own
     150    //    code fragment on disk and the CFM connection ID to your own
     151    //    code fragment.  Typically you get this information from your
     152    //    fragment's CFM init routine.  You must ensure that
     153    //    fragToFixLocator->fileSpec points to an FSSpec of the
     154    //    file which holds your code fragment.
     155    //
     156    //    IMPORTANT:
     157    //    The fact that you pass in a CFragSystem7DiskFlatLocator as the
     158    //    fragToFixLocator implies that the fragment to be fixed up must
     159    //    be in the data fork of a file.  The code could be modified
     160    //    to remove this requirement, but on disk code fragments are the most
     161    //    common case.
     162    //
     163    //    IMPORTANT:
     164    //    The fragment to fix may have a packed data section.  Packing the
     165    //    data section will reduce the size of your fragment on disk, but it
     166    //    will significantly increase the memory needed by this routine
     167    //    (it increases memory usage by the sum of the sizes of the packed
     168    //    and unpacked data section).  See below for instructions on how to
     169    //    create an unpacked data section.
     170    //
     171    // 2. fragToFixInitRoutine:  A pointer to your own code fragment's
     172    //    fragment initialiser routine.  You necessarily have one of these
     173    //    because you need it to get values for the fragToFixLocator and
     174    //    fragToFixConnID parameters.  Just pass its address in as a parameter
     175    //    as well.
     176    //
     177    // 3. weakLinkedLibraryName:  The name of the weak linked library which
     178    //    failed to link.  You must have weak linked to this library.
     179    //    It is oxymoric for you to pass a strong linked library here,
     180    //    because your code would not have prepared if a strong linked
     181    //    library failed to prepare, and so you couldn't supply a valid
     182    ///   fragToFix.
     183    //
     184    // 4. lookup, refCon:  A pointer to a callback function that the
     185    //            routine calls to look up the address of a symbol, and a refCon
     186    //    for that callback routine.
     187    //
     188    // Note:
     189    // The fragToFixLocator and fragToFixInitRoutine parameters
     190    // are artifacts of the way in which this functionality is implemented.
     191    // In an ideal world, where CFM exported decent introspection APIs
     192    // to third party developers, these parameters would not be necessary.
     193    // If you're using this code inside Apple, you probably should investigate
     194    // using the CFM private APIs for getting at the information these
     195    // parameters are needed for.  See the comments inside the implementation
     196    // for more details.
     197    //
     198    // Note:
     199    // The extra memory taken when you use a packed data section is also an
     200    // artifact of my workaround for the lack of CFM introspection APIs.  In
     201    // my opinion it's better to use an unpacked data section and consume more
     202    // space on disk while saving memory.  In CodeWarrior you can switch to an
     203    // unpacked data section by checking the "Expand Uninitialized Data"
     204    // checkbox in the "PPC PEF" settings panel.  In MPW, specified the
     205    // "-packdata off" option to PPCLink.
     206    //
     207    // When the routine returns, any symbols that you imported from the
     208    // library named weakLinkedLibraryName will be resolved to the address
     209    // of the symbol provided by the "lookup" callback routine.
     210    //
     211    // It is possible for an unresolved import to remain unresolved after
     212    // this routine returns.  If the symbol import is marked as weak (as
     213    // opposed to the library, which *must* be marked as weak) and the symbol
     214    // is not found by the "lookup" callback, the routine will simple skip
     215    // that symbol.  If the symbol isn't marked as weak, the routine will fail
     216    // in that case.
     217    //
     218    // Most of the possible error results are co-opted CFM errors.  These
     219    // include:
     220    //
     221    // cfragFragmentFormatErr  -- The fragment to fix is is an unknown format.
     222    // cfragNoSectionErr       -- Could not find the loader section in the fragment to fix.
     223    // cfragNoLibraryErr       -- The fragment to fix is not weak linked to weakLinkedLibraryName.
     224    // cfragFragmentUsageErr   -- The fragment to fix doesn't have a data section.
     225    //                         -- The fragment to fix is strong linked to weakLinkedLibraryName.
     226    //                         -- The fragment doesn't have an init routine.
     227    // cfragFragmentCorruptErr -- Encountered an undefined relocation opcode.
     228    // unimpErr                -- Encountered an unimplement relocation opcode.  The
     229    //                            relocation engine only implements a subset of the CFM
     230    //                            relocation opcodes, the subset most commonly used by
     231    //                            MPW and CodeWarrior PEF containers.  If you encounter
     232    //                            this error, you'll probably have to add the weird
     233    //                            relocation opcode to the engine, which shouldn't be
     234    //                            be too hard.
     235    // memFullErr                          -- It's likely that this error is triggered by the memory
     236    //                            needed to unpack your data section.  Either make your
     237    //                            data section smaller, or unpack it (see above).
     238    // errors returned by FindSymbol
     239    // errors returned by Memory Manager
     240    //
     241    // The routine needs enough memory to hold the loader section of the fragment
     242    // to fix in memory.  It allocates that memory using NewPtr and dispsoses of
     243    // it before it returns.  You may want to change the memory allocator, which
     244    // is very simple.
    245245
    246246extern pascal OSStatus CFMLateImportLibrary(const CFragSystem7DiskFlatLocator *fragToFixLocator,
    247                                                                                 CFragConnectionID fragToFixConnID,
    248                                                                                 CFragInitFunction fragToFixInitRoutine,
    249                                                                                 ConstStr255Param weakLinkedLibraryName,
    250                                                                                 CFragConnectionID connIDToImport);
    251         // A wrapper around CFMLateImportCore that looks up symbols by calling
    252         // FindSymbol on a connection to a CFM library (connIDToImport).
    253         // You can get this connection ID through any standard CFM API, for example
    254         // GetSharedLibrary, GetDiskFragment, or GetMemFragment.
    255         //
    256         // IMPORTANT:
    257         // The fragment name for connIDToImport *does not* have to match
    258         // weakLinkedLibraryName.  This is part of the power of this library.
     247                                                                                CFragConnectionID fragToFixConnID,
     248                                                                                CFragInitFunction fragToFixInitRoutine,
     249                                                                                ConstStr255Param weakLinkedLibraryName,
     250                                                                                CFragConnectionID connIDToImport);
     251    // A wrapper around CFMLateImportCore that looks up symbols by calling
     252    // FindSymbol on a connection to a CFM library (connIDToImport).
     253    // You can get this connection ID through any standard CFM API, for example
     254    // GetSharedLibrary, GetDiskFragment, or GetMemFragment.
     255    //
     256    // IMPORTANT:
     257    // The fragment name for connIDToImport *does not* have to match
     258    // weakLinkedLibraryName.  This is part of the power of this library.
    259259
    260260extern pascal OSStatus CFMLateImportBundle(const CFragSystem7DiskFlatLocator *fragToFixLocator,
    261                                                                                 CFragConnectionID fragToFixConnID,
    262                                                                                 CFragInitFunction fragToFixInitRoutine,
    263                                                                                 ConstStr255Param weakLinkedLibraryName,
    264                                                                                 CFBundleRef bundleToImport);
    265         // A wrapper around CFMLateImportCore that looks up symbols by calling
    266         // CFBundleGetFunctionPointerForName on a reference to a Core Foundation
    267         // bundle (bundleToImport).  You can get this reference through any
    268         // Core Foundation bundle API, for example CFBundleCreate.
     261                                                                                CFragConnectionID fragToFixConnID,
     262                                                                                CFragInitFunction fragToFixInitRoutine,
     263                                                                                ConstStr255Param weakLinkedLibraryName,
     264                                                                                CFBundleRef bundleToImport);
     265    // A wrapper around CFMLateImportCore that looks up symbols by calling
     266    // CFBundleGetFunctionPointerForName on a reference to a Core Foundation
     267    // bundle (bundleToImport).  You can get this reference through any
     268    // Core Foundation bundle API, for example CFBundleCreate.
    269269
    270270#ifdef __cplusplus
  • python/trunk/Mac/Modules/cg/_CGmodule.c

    r2 r391  
    1010/* Macro to test whether a weak-loaded CFM function exists */
    1111#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
    12         PyErr_SetString(PyExc_NotImplementedError, \
    13         "Not available in this shared library/OS version"); \
    14         return NULL; \
     12    PyErr_SetString(PyExc_NotImplementedError, \
     13    "Not available in this shared library/OS version"); \
     14    return NULL; \
    1515    }} while(0)
    1616
     
    2727{
    2828
    29         return Py_BuildValue("(ff)",
    30                         itself->x,
    31                         itself->y);
     29    return Py_BuildValue("(ff)",
     30                    itself->x,
     31                    itself->y);
    3232}
    3333
     
    3535CGPoint_Convert(PyObject *v, CGPoint *p_itself)
    3636{
    37         if( !PyArg_Parse(v, "(ff)",
    38                         &p_itself->x,
    39                         &p_itself->y) )
    40                 return 0;
    41         return 1;
     37    if( !PyArg_Parse(v, "(ff)",
     38                    &p_itself->x,
     39                    &p_itself->y) )
     40        return 0;
     41    return 1;
    4242}
    4343
     
    4545{
    4646
    47         return Py_BuildValue("(ffff)",
    48                         itself->origin.x,
    49                         itself->origin.y,
    50                         itself->size.width,
    51                         itself->size.height);
     47    return Py_BuildValue("(ffff)",
     48                    itself->origin.x,
     49                    itself->origin.y,
     50                    itself->size.width,
     51                    itself->size.height);
    5252}
    5353
     
    5555CGRect_Convert(PyObject *v, CGRect *p_itself)
    5656{
    57         if( !PyArg_Parse(v, "(ffff)",
    58                         &p_itself->origin.x,
    59                         &p_itself->origin.y,
    60                         &p_itself->size.width,
    61                         &p_itself->size.height) )
    62                 return 0;
    63         return 1;
     57    if( !PyArg_Parse(v, "(ffff)",
     58                    &p_itself->origin.x,
     59                    &p_itself->origin.y,
     60                    &p_itself->size.width,
     61                    &p_itself->size.height) )
     62        return 0;
     63    return 1;
    6464}
    6565
     
    6767{
    6868
    69         return Py_BuildValue("(ffffff)",
    70                         itself->a,
    71                         itself->b,
    72                         itself->c,
    73                         itself->d,
    74                         itself->tx,
    75                         itself->ty);
     69    return Py_BuildValue("(ffffff)",
     70                    itself->a,
     71                    itself->b,
     72                    itself->c,
     73                    itself->d,
     74                    itself->tx,
     75                    itself->ty);
    7676}
    7777
     
    7979CGAffineTransform_Convert(PyObject *v, CGAffineTransform *p_itself)
    8080{
    81         if( !PyArg_Parse(v, "(ffffff)",
    82                         &p_itself->a,
    83                         &p_itself->b,
    84                         &p_itself->c,
    85                         &p_itself->d,
    86                         &p_itself->tx,
    87                         &p_itself->ty) )
    88                 return 0;
    89         return 1;
     81    if( !PyArg_Parse(v, "(ffffff)",
     82                    &p_itself->a,
     83                    &p_itself->b,
     84                    &p_itself->c,
     85                    &p_itself->d,
     86                    &p_itself->tx,
     87                    &p_itself->ty) )
     88        return 0;
     89    return 1;
    9090}
    9191
     
    9999
    100100typedef struct CGContextRefObject {
    101         PyObject_HEAD
    102         CGContextRef ob_itself;
     101    PyObject_HEAD
     102    CGContextRef ob_itself;
    103103} CGContextRefObject;
    104104
    105105PyObject *CGContextRefObj_New(CGContextRef itself)
    106106{
    107         CGContextRefObject *it;
    108         it = PyObject_NEW(CGContextRefObject, &CGContextRef_Type);
    109         if (it == NULL) return NULL;
    110         it->ob_itself = itself;
    111         return (PyObject *)it;
     107    CGContextRefObject *it;
     108    it = PyObject_NEW(CGContextRefObject, &CGContextRef_Type);
     109    if (it == NULL) return NULL;
     110    it->ob_itself = itself;
     111    return (PyObject *)it;
    112112}
    113113
    114114int CGContextRefObj_Convert(PyObject *v, CGContextRef *p_itself)
    115115{
    116         if (!CGContextRefObj_Check(v))
    117         {
    118                 PyErr_SetString(PyExc_TypeError, "CGContextRef required");
    119                 return 0;
    120         }
    121         *p_itself = ((CGContextRefObject *)v)->ob_itself;
    122         return 1;
     116    if (!CGContextRefObj_Check(v))
     117    {
     118        PyErr_SetString(PyExc_TypeError, "CGContextRef required");
     119        return 0;
     120    }
     121    *p_itself = ((CGContextRefObject *)v)->ob_itself;
     122    return 1;
    123123}
    124124
    125125static void CGContextRefObj_dealloc(CGContextRefObject *self)
    126126{
    127         CGContextRelease(self->ob_itself);
    128         self->ob_type->tp_free((PyObject *)self);
     127    CGContextRelease(self->ob_itself);
     128    self->ob_type->tp_free((PyObject *)self);
    129129}
    130130
    131131static PyObject *CGContextRefObj_CGContextSaveGState(CGContextRefObject *_self, PyObject *_args)
    132132{
    133         PyObject *_res = NULL;
    134         if (!PyArg_ParseTuple(_args, ""))
    135                 return NULL;
    136         CGContextSaveGState(_self->ob_itself);
    137         Py_INCREF(Py_None);
    138         _res = Py_None;
    139         return _res;
     133    PyObject *_res = NULL;
     134    if (!PyArg_ParseTuple(_args, ""))
     135        return NULL;
     136    CGContextSaveGState(_self->ob_itself);
     137    Py_INCREF(Py_None);
     138    _res = Py_None;
     139    return _res;
    140140}
    141141
    142142static PyObject *CGContextRefObj_CGContextRestoreGState(CGContextRefObject *_self, PyObject *_args)
    143143{
    144         PyObject *_res = NULL;
    145         if (!PyArg_ParseTuple(_args, ""))
    146                 return NULL;
    147         CGContextRestoreGState(_self->ob_itself);
    148         Py_INCREF(Py_None);
    149         _res = Py_None;
    150         return _res;
     144    PyObject *_res = NULL;
     145    if (!PyArg_ParseTuple(_args, ""))
     146        return NULL;
     147    CGContextRestoreGState(_self->ob_itself);
     148    Py_INCREF(Py_None);
     149    _res = Py_None;
     150    return _res;
    151151}
    152152
    153153static PyObject *CGContextRefObj_CGContextScaleCTM(CGContextRefObject *_self, PyObject *_args)
    154154{
    155         PyObject *_res = NULL;
    156         float sx;
    157         float sy;
    158         if (!PyArg_ParseTuple(_args, "ff",
    159                               &sx,
    160                               &sy))
    161                 return NULL;
    162         CGContextScaleCTM(_self->ob_itself,
    163                           sx,
    164                           sy);
    165         Py_INCREF(Py_None);
    166         _res = Py_None;
    167         return _res;
     155    PyObject *_res = NULL;
     156    float sx;
     157    float sy;
     158    if (!PyArg_ParseTuple(_args, "ff",
     159                          &sx,
     160                          &sy))
     161        return NULL;
     162    CGContextScaleCTM(_self->ob_itself,
     163                      sx,
     164                      sy);
     165    Py_INCREF(Py_None);
     166    _res = Py_None;
     167    return _res;
    168168}
    169169
    170170static PyObject *CGContextRefObj_CGContextTranslateCTM(CGContextRefObject *_self, PyObject *_args)
    171171{
    172         PyObject *_res = NULL;
    173         float tx;
    174         float ty;
    175         if (!PyArg_ParseTuple(_args, "ff",
    176                               &tx,
    177                               &ty))
    178                 return NULL;
    179         CGContextTranslateCTM(_self->ob_itself,
    180                               tx,
    181                               ty);
    182         Py_INCREF(Py_None);
    183         _res = Py_None;
    184         return _res;
     172    PyObject *_res = NULL;
     173    float tx;
     174    float ty;
     175    if (!PyArg_ParseTuple(_args, "ff",
     176                          &tx,
     177                          &ty))
     178        return NULL;
     179    CGContextTranslateCTM(_self->ob_itself,
     180                          tx,
     181                          ty);
     182    Py_INCREF(Py_None);
     183    _res = Py_None;
     184    return _res;
    185185}
    186186
    187187static PyObject *CGContextRefObj_CGContextRotateCTM(CGContextRefObject *_self, PyObject *_args)
    188188{
    189         PyObject *_res = NULL;
    190         float angle;
    191         if (!PyArg_ParseTuple(_args, "f",
    192                               &angle))
    193                 return NULL;
    194         CGContextRotateCTM(_self->ob_itself,
    195                            angle);
    196         Py_INCREF(Py_None);
    197         _res = Py_None;
    198         return _res;
     189    PyObject *_res = NULL;
     190    float angle;
     191    if (!PyArg_ParseTuple(_args, "f",
     192                          &angle))
     193        return NULL;
     194    CGContextRotateCTM(_self->ob_itself,
     195                       angle);
     196    Py_INCREF(Py_None);
     197    _res = Py_None;
     198    return _res;
    199199}
    200200
    201201static PyObject *CGContextRefObj_CGContextConcatCTM(CGContextRefObject *_self, PyObject *_args)
    202202{
    203         PyObject *_res = NULL;
    204         CGAffineTransform transform;
    205         if (!PyArg_ParseTuple(_args, "O&",
    206                               CGAffineTransform_Convert, &transform))
    207                 return NULL;
    208         CGContextConcatCTM(_self->ob_itself,
    209                            transform);
    210         Py_INCREF(Py_None);
    211         _res = Py_None;
    212         return _res;
     203    PyObject *_res = NULL;
     204    CGAffineTransform transform;
     205    if (!PyArg_ParseTuple(_args, "O&",
     206                          CGAffineTransform_Convert, &transform))
     207        return NULL;
     208    CGContextConcatCTM(_self->ob_itself,
     209                       transform);
     210    Py_INCREF(Py_None);
     211    _res = Py_None;
     212    return _res;
    213213}
    214214
    215215static PyObject *CGContextRefObj_CGContextGetCTM(CGContextRefObject *_self, PyObject *_args)
    216216{
    217         PyObject *_res = NULL;
    218         CGAffineTransform _rv;
    219         if (!PyArg_ParseTuple(_args, ""))
    220                 return NULL;
    221         _rv = CGContextGetCTM(_self->ob_itself);
    222         _res = Py_BuildValue("O&",
    223                              CGAffineTransform_New, &_rv);
    224         return _res;
     217    PyObject *_res = NULL;
     218    CGAffineTransform _rv;
     219    if (!PyArg_ParseTuple(_args, ""))
     220        return NULL;
     221    _rv = CGContextGetCTM(_self->ob_itself);
     222    _res = Py_BuildValue("O&",
     223                         CGAffineTransform_New, &_rv);
     224    return _res;
    225225}
    226226
    227227static PyObject *CGContextRefObj_CGContextSetLineWidth(CGContextRefObject *_self, PyObject *_args)
    228228{
    229         PyObject *_res = NULL;
    230         float width;
    231         if (!PyArg_ParseTuple(_args, "f",
    232                               &width))
    233                 return NULL;
    234         CGContextSetLineWidth(_self->ob_itself,
    235                               width);
    236         Py_INCREF(Py_None);
    237         _res = Py_None;
    238         return _res;
     229    PyObject *_res = NULL;
     230    float width;
     231    if (!PyArg_ParseTuple(_args, "f",
     232                          &width))
     233        return NULL;
     234    CGContextSetLineWidth(_self->ob_itself,
     235                          width);
     236    Py_INCREF(Py_None);
     237    _res = Py_None;
     238    return _res;
    239239}
    240240
    241241static PyObject *CGContextRefObj_CGContextSetLineCap(CGContextRefObject *_self, PyObject *_args)
    242242{
    243         PyObject *_res = NULL;
    244         int cap;
    245         if (!PyArg_ParseTuple(_args, "i",
    246                               &cap))
    247                 return NULL;
    248         CGContextSetLineCap(_self->ob_itself,
    249                             cap);
    250         Py_INCREF(Py_None);
    251         _res = Py_None;
    252         return _res;
     243    PyObject *_res = NULL;
     244    int cap;
     245    if (!PyArg_ParseTuple(_args, "i",
     246                          &cap))
     247        return NULL;
     248    CGContextSetLineCap(_self->ob_itself,
     249                        cap);
     250    Py_INCREF(Py_None);
     251    _res = Py_None;
     252    return _res;
    253253}
    254254
    255255static PyObject *CGContextRefObj_CGContextSetLineJoin(CGContextRefObject *_self, PyObject *_args)
    256256{
    257         PyObject *_res = NULL;
    258         int join;
    259         if (!PyArg_ParseTuple(_args, "i",
    260                               &join))
    261                 return NULL;
    262         CGContextSetLineJoin(_self->ob_itself,
    263                              join);
    264         Py_INCREF(Py_None);
    265         _res = Py_None;
    266         return _res;
     257    PyObject *_res = NULL;
     258    int join;
     259    if (!PyArg_ParseTuple(_args, "i",
     260                          &join))
     261        return NULL;
     262    CGContextSetLineJoin(_self->ob_itself,
     263                         join);
     264    Py_INCREF(Py_None);
     265    _res = Py_None;
     266    return _res;
    267267}
    268268
    269269static PyObject *CGContextRefObj_CGContextSetMiterLimit(CGContextRefObject *_self, PyObject *_args)
    270270{
    271         PyObject *_res = NULL;
    272         float limit;
    273         if (!PyArg_ParseTuple(_args, "f",
    274                               &limit))
    275                 return NULL;
    276         CGContextSetMiterLimit(_self->ob_itself,
    277                                limit);
    278         Py_INCREF(Py_None);
    279         _res = Py_None;
    280         return _res;
     271    PyObject *_res = NULL;
     272    float limit;
     273    if (!PyArg_ParseTuple(_args, "f",
     274                          &limit))
     275        return NULL;
     276    CGContextSetMiterLimit(_self->ob_itself,
     277                           limit);
     278    Py_INCREF(Py_None);
     279    _res = Py_None;
     280    return _res;
    281281}
    282282
    283283static PyObject *CGContextRefObj_CGContextSetFlatness(CGContextRefObject *_self, PyObject *_args)
    284284{
    285         PyObject *_res = NULL;
    286         float flatness;
    287         if (!PyArg_ParseTuple(_args, "f",
    288                               &flatness))
    289                 return NULL;
    290         CGContextSetFlatness(_self->ob_itself,
    291                              flatness);
    292         Py_INCREF(Py_None);
    293         _res = Py_None;
    294         return _res;
     285    PyObject *_res = NULL;
     286    float flatness;
     287    if (!PyArg_ParseTuple(_args, "f",
     288                          &flatness))
     289        return NULL;
     290    CGContextSetFlatness(_self->ob_itself,
     291                         flatness);
     292    Py_INCREF(Py_None);
     293    _res = Py_None;
     294    return _res;
    295295}
    296296
    297297static PyObject *CGContextRefObj_CGContextSetAlpha(CGContextRefObject *_self, PyObject *_args)
    298298{
    299         PyObject *_res = NULL;
    300         float alpha;
    301         if (!PyArg_ParseTuple(_args, "f",
    302                               &alpha))
    303                 return NULL;
    304         CGContextSetAlpha(_self->ob_itself,
    305                           alpha);
    306         Py_INCREF(Py_None);
    307         _res = Py_None;
    308         return _res;
     299    PyObject *_res = NULL;
     300    float alpha;
     301    if (!PyArg_ParseTuple(_args, "f",
     302                          &alpha))
     303        return NULL;
     304    CGContextSetAlpha(_self->ob_itself,
     305                      alpha);
     306    Py_INCREF(Py_None);
     307    _res = Py_None;
     308    return _res;
    309309}
    310310
    311311static PyObject *CGContextRefObj_CGContextBeginPath(CGContextRefObject *_self, PyObject *_args)
    312312{
    313         PyObject *_res = NULL;
    314         if (!PyArg_ParseTuple(_args, ""))
    315                 return NULL;
    316         CGContextBeginPath(_self->ob_itself);
    317         Py_INCREF(Py_None);
    318         _res = Py_None;
    319         return _res;
     313    PyObject *_res = NULL;
     314    if (!PyArg_ParseTuple(_args, ""))
     315        return NULL;
     316    CGContextBeginPath(_self->ob_itself);
     317    Py_INCREF(Py_None);
     318    _res = Py_None;
     319    return _res;
    320320}
    321321
    322322static PyObject *CGContextRefObj_CGContextMoveToPoint(CGContextRefObject *_self, PyObject *_args)
    323323{
    324         PyObject *_res = NULL;
    325         float x;
    326         float y;
    327         if (!PyArg_ParseTuple(_args, "ff",
    328                               &x,
    329                               &y))
    330                 return NULL;
    331         CGContextMoveToPoint(_self->ob_itself,
    332                              x,
    333                              y);
    334         Py_INCREF(Py_None);
    335         _res = Py_None;
    336         return _res;
     324    PyObject *_res = NULL;
     325    float x;
     326    float y;
     327    if (!PyArg_ParseTuple(_args, "ff",
     328                          &x,
     329                          &y))
     330        return NULL;
     331    CGContextMoveToPoint(_self->ob_itself,
     332                         x,
     333                         y);
     334    Py_INCREF(Py_None);
     335    _res = Py_None;
     336    return _res;
    337337}
    338338
    339339static PyObject *CGContextRefObj_CGContextAddLineToPoint(CGContextRefObject *_self, PyObject *_args)
    340340{
    341         PyObject *_res = NULL;
    342         float x;
    343         float y;
    344         if (!PyArg_ParseTuple(_args, "ff",
    345                               &x,
    346                               &y))
    347                 return NULL;
    348         CGContextAddLineToPoint(_self->ob_itself,
    349                                 x,
    350                                 y);
    351         Py_INCREF(Py_None);
    352         _res = Py_None;
    353         return _res;
     341    PyObject *_res = NULL;
     342    float x;
     343    float y;
     344    if (!PyArg_ParseTuple(_args, "ff",
     345                          &x,
     346                          &y))
     347        return NULL;
     348    CGContextAddLineToPoint(_self->ob_itself,
     349                            x,
     350                            y);
     351    Py_INCREF(Py_None);
     352    _res = Py_None;
     353    return _res;
    354354}
    355355
    356356static PyObject *CGContextRefObj_CGContextAddCurveToPoint(CGContextRefObject *_self, PyObject *_args)
    357357{
    358         PyObject *_res = NULL;
    359         float cp1x;
    360         float cp1y;
    361         float cp2x;
    362         float cp2y;
    363         float x;
    364         float y;
    365         if (!PyArg_ParseTuple(_args, "ffffff",
    366                               &cp1x,
    367                               &cp1y,
    368                               &cp2x,
    369                               &cp2y,
    370                               &x,
    371                               &y))
    372                 return NULL;
    373         CGContextAddCurveToPoint(_self->ob_itself,
    374                                  cp1x,
    375                                  cp1y,
    376                                  cp2x,
    377                                  cp2y,
    378                                  x,
    379                                  y);
    380         Py_INCREF(Py_None);
    381         _res = Py_None;
    382         return _res;
     358    PyObject *_res = NULL;
     359    float cp1x;
     360    float cp1y;
     361    float cp2x;
     362    float cp2y;
     363    float x;
     364    float y;
     365    if (!PyArg_ParseTuple(_args, "ffffff",
     366                          &cp1x,
     367                          &cp1y,
     368                          &cp2x,
     369                          &cp2y,
     370                          &x,
     371                          &y))
     372        return NULL;
     373    CGContextAddCurveToPoint(_self->ob_itself,
     374                             cp1x,
     375                             cp1y,
     376                             cp2x,
     377                             cp2y,
     378                             x,
     379                             y);
     380    Py_INCREF(Py_None);
     381    _res = Py_None;
     382    return _res;
    383383}
    384384
    385385static PyObject *CGContextRefObj_CGContextAddQuadCurveToPoint(CGContextRefObject *_self, PyObject *_args)
    386386{
    387         PyObject *_res = NULL;
    388         float cpx;
    389         float cpy;
    390         float x;
    391         float y;
    392         if (!PyArg_ParseTuple(_args, "ffff",
    393                               &cpx,
    394                               &cpy,
    395                               &x,
    396                               &y))
    397                 return NULL;
    398         CGContextAddQuadCurveToPoint(_self->ob_itself,
    399                                      cpx,
    400                                      cpy,
    401                                      x,
    402                                      y);
    403         Py_INCREF(Py_None);
    404         _res = Py_None;
    405         return _res;
     387    PyObject *_res = NULL;
     388    float cpx;
     389    float cpy;
     390    float x;
     391    float y;
     392    if (!PyArg_ParseTuple(_args, "ffff",
     393                          &cpx,
     394                          &cpy,
     395                          &x,
     396                          &y))
     397        return NULL;
     398    CGContextAddQuadCurveToPoint(_self->ob_itself,
     399                                 cpx,
     400                                 cpy,
     401                                 x,
     402                                 y);
     403    Py_INCREF(Py_None);
     404    _res = Py_None;
     405    return _res;
    406406}
    407407
    408408static PyObject *CGContextRefObj_CGContextClosePath(CGContextRefObject *_self, PyObject *_args)
    409409{
    410         PyObject *_res = NULL;
    411         if (!PyArg_ParseTuple(_args, ""))
    412                 return NULL;
    413         CGContextClosePath(_self->ob_itself);
    414         Py_INCREF(Py_None);
    415         _res = Py_None;
    416         return _res;
     410    PyObject *_res = NULL;
     411    if (!PyArg_ParseTuple(_args, ""))
     412        return NULL;
     413    CGContextClosePath(_self->ob_itself);
     414    Py_INCREF(Py_None);
     415    _res = Py_None;
     416    return _res;
    417417}
    418418
    419419static PyObject *CGContextRefObj_CGContextAddRect(CGContextRefObject *_self, PyObject *_args)
    420420{
    421         PyObject *_res = NULL;
    422         CGRect rect;
    423         if (!PyArg_ParseTuple(_args, "O&",
    424                               CGRect_Convert, &rect))
    425                 return NULL;
    426         CGContextAddRect(_self->ob_itself,
    427                          rect);
    428         Py_INCREF(Py_None);
    429         _res = Py_None;
    430         return _res;
     421    PyObject *_res = NULL;
     422    CGRect rect;
     423    if (!PyArg_ParseTuple(_args, "O&",
     424                          CGRect_Convert, &rect))
     425        return NULL;
     426    CGContextAddRect(_self->ob_itself,
     427                     rect);
     428    Py_INCREF(Py_None);
     429    _res = Py_None;
     430    return _res;
    431431}
    432432
    433433static PyObject *CGContextRefObj_CGContextAddArc(CGContextRefObject *_self, PyObject *_args)
    434434{
    435         PyObject *_res = NULL;
    436         float x;
    437         float y;
    438         float radius;
    439         float startAngle;
    440         float endAngle;
    441         int clockwise;
    442         if (!PyArg_ParseTuple(_args, "fffffi",
    443                               &x,
    444                               &y,
    445                               &radius,
    446                               &startAngle,
    447                               &endAngle,
    448                               &clockwise))
    449                 return NULL;
    450         CGContextAddArc(_self->ob_itself,
    451                         x,
    452                         y,
    453                         radius,
    454                         startAngle,
    455                         endAngle,
    456                         clockwise);
    457         Py_INCREF(Py_None);
    458         _res = Py_None;
    459         return _res;
     435    PyObject *_res = NULL;
     436    float x;
     437    float y;
     438    float radius;
     439    float startAngle;
     440    float endAngle;
     441    int clockwise;
     442    if (!PyArg_ParseTuple(_args, "fffffi",
     443                          &x,
     444                          &y,
     445                          &radius,
     446                          &startAngle,
     447                          &endAngle,
     448                          &clockwise))
     449        return NULL;
     450    CGContextAddArc(_self->ob_itself,
     451                    x,
     452                    y,
     453                    radius,
     454                    startAngle,
     455                    endAngle,
     456                    clockwise);
     457    Py_INCREF(Py_None);
     458    _res = Py_None;
     459    return _res;
    460460}
    461461
    462462static PyObject *CGContextRefObj_CGContextAddArcToPoint(CGContextRefObject *_self, PyObject *_args)
    463463{
    464         PyObject *_res = NULL;
    465         float x1;
    466         float y1;
    467         float x2;
    468         float y2;
    469         float radius;
    470         if (!PyArg_ParseTuple(_args, "fffff",
    471                               &x1,
    472                               &y1,
    473                               &x2,
    474                               &y2,
    475                               &radius))
    476                 return NULL;
    477         CGContextAddArcToPoint(_self->ob_itself,
    478                                x1,
    479                                y1,
    480                                x2,
    481                                y2,
    482                                radius);
    483         Py_INCREF(Py_None);
    484         _res = Py_None;
    485         return _res;
     464    PyObject *_res = NULL;
     465    float x1;
     466    float y1;
     467    float x2;
     468    float y2;
     469    float radius;
     470    if (!PyArg_ParseTuple(_args, "fffff",
     471                          &x1,
     472                          &y1,
     473                          &x2,
     474                          &y2,
     475                          &radius))
     476        return NULL;
     477    CGContextAddArcToPoint(_self->ob_itself,
     478                           x1,
     479                           y1,
     480                           x2,
     481                           y2,
     482                           radius);
     483    Py_INCREF(Py_None);
     484    _res = Py_None;
     485    return _res;
    486486}
    487487
    488488static PyObject *CGContextRefObj_CGContextIsPathEmpty(CGContextRefObject *_self, PyObject *_args)
    489489{
    490         PyObject *_res = NULL;
    491         int _rv;
    492         if (!PyArg_ParseTuple(_args, ""))
    493                 return NULL;
    494         _rv = CGContextIsPathEmpty(_self->ob_itself);
    495         _res = Py_BuildValue("i",
    496                              _rv);
    497         return _res;
     490    PyObject *_res = NULL;
     491    int _rv;
     492    if (!PyArg_ParseTuple(_args, ""))
     493        return NULL;
     494    _rv = CGContextIsPathEmpty(_self->ob_itself);
     495    _res = Py_BuildValue("i",
     496                         _rv);
     497    return _res;
    498498}
    499499
    500500static PyObject *CGContextRefObj_CGContextGetPathCurrentPoint(CGContextRefObject *_self, PyObject *_args)
    501501{
    502         PyObject *_res = NULL;
    503         CGPoint _rv;
    504         if (!PyArg_ParseTuple(_args, ""))
    505                 return NULL;
    506         _rv = CGContextGetPathCurrentPoint(_self->ob_itself);
    507         _res = Py_BuildValue("O&",
    508                              CGPoint_New, &_rv);
    509         return _res;
     502    PyObject *_res = NULL;
     503    CGPoint _rv;
     504    if (!PyArg_ParseTuple(_args, ""))
     505        return NULL;
     506    _rv = CGContextGetPathCurrentPoint(_self->ob_itself);
     507    _res = Py_BuildValue("O&",
     508                         CGPoint_New, &_rv);
     509    return _res;
    510510}
    511511
    512512static PyObject *CGContextRefObj_CGContextGetPathBoundingBox(CGContextRefObject *_self, PyObject *_args)
    513513{
    514         PyObject *_res = NULL;
    515         CGRect _rv;
    516         if (!PyArg_ParseTuple(_args, ""))
    517                 return NULL;
    518         _rv = CGContextGetPathBoundingBox(_self->ob_itself);
    519         _res = Py_BuildValue("O&",
    520                              CGRect_New, &_rv);
    521         return _res;
     514    PyObject *_res = NULL;
     515    CGRect _rv;
     516    if (!PyArg_ParseTuple(_args, ""))
     517        return NULL;
     518    _rv = CGContextGetPathBoundingBox(_self->ob_itself);
     519    _res = Py_BuildValue("O&",
     520                         CGRect_New, &_rv);
     521    return _res;
    522522}
    523523
    524524static PyObject *CGContextRefObj_CGContextDrawPath(CGContextRefObject *_self, PyObject *_args)
    525525{
    526         PyObject *_res = NULL;
    527         int mode;
    528         if (!PyArg_ParseTuple(_args, "i",
    529                               &mode))
    530                 return NULL;
    531         CGContextDrawPath(_self->ob_itself,
    532                           mode);
    533         Py_INCREF(Py_None);
    534         _res = Py_None;
    535         return _res;
     526    PyObject *_res = NULL;
     527    int mode;
     528    if (!PyArg_ParseTuple(_args, "i",
     529                          &mode))
     530        return NULL;
     531    CGContextDrawPath(_self->ob_itself,
     532                      mode);
     533    Py_INCREF(Py_None);
     534    _res = Py_None;
     535    return _res;
    536536}
    537537
    538538static PyObject *CGContextRefObj_CGContextFillPath(CGContextRefObject *_self, PyObject *_args)
    539539{
    540         PyObject *_res = NULL;
    541         if (!PyArg_ParseTuple(_args, ""))
    542                 return NULL;
    543         CGContextFillPath(_self->ob_itself);
    544         Py_INCREF(Py_None);
    545         _res = Py_None;
    546         return _res;
     540    PyObject *_res = NULL;
     541    if (!PyArg_ParseTuple(_args, ""))
     542        return NULL;
     543    CGContextFillPath(_self->ob_itself);
     544    Py_INCREF(Py_None);
     545    _res = Py_None;
     546    return _res;
    547547}
    548548
    549549static PyObject *CGContextRefObj_CGContextEOFillPath(CGContextRefObject *_self, PyObject *_args)
    550550{
    551         PyObject *_res = NULL;
    552         if (!PyArg_ParseTuple(_args, ""))
    553                 return NULL;
    554         CGContextEOFillPath(_self->ob_itself);
    555         Py_INCREF(Py_None);
    556         _res = Py_None;
    557         return _res;
     551    PyObject *_res = NULL;
     552    if (!PyArg_ParseTuple(_args, ""))
     553        return NULL;
     554    CGContextEOFillPath(_self->ob_itself);
     555    Py_INCREF(Py_None);
     556    _res = Py_None;
     557    return _res;
    558558}
    559559
    560560static PyObject *CGContextRefObj_CGContextStrokePath(CGContextRefObject *_self, PyObject *_args)
    561561{
    562         PyObject *_res = NULL;
    563         if (!PyArg_ParseTuple(_args, ""))
    564                 return NULL;
    565         CGContextStrokePath(_self->ob_itself);
    566         Py_INCREF(Py_None);
    567         _res = Py_None;
    568         return _res;
     562    PyObject *_res = NULL;
     563    if (!PyArg_ParseTuple(_args, ""))
     564        return NULL;
     565    CGContextStrokePath(_self->ob_itself);
     566    Py_INCREF(Py_None);
     567    _res = Py_None;
     568    return _res;
    569569}
    570570
    571571static PyObject *CGContextRefObj_CGContextFillRect(CGContextRefObject *_self, PyObject *_args)
    572572{
    573         PyObject *_res = NULL;
    574         CGRect rect;
    575         if (!PyArg_ParseTuple(_args, "O&",
    576                               CGRect_Convert, &rect))
    577                 return NULL;
    578         CGContextFillRect(_self->ob_itself,
    579                           rect);
    580         Py_INCREF(Py_None);
    581         _res = Py_None;
    582         return _res;
     573    PyObject *_res = NULL;
     574    CGRect rect;
     575    if (!PyArg_ParseTuple(_args, "O&",
     576                          CGRect_Convert, &rect))
     577        return NULL;
     578    CGContextFillRect(_self->ob_itself,
     579                      rect);
     580    Py_INCREF(Py_None);
     581    _res = Py_None;
     582    return _res;
    583583}
    584584
    585585static PyObject *CGContextRefObj_CGContextStrokeRect(CGContextRefObject *_self, PyObject *_args)
    586586{
    587         PyObject *_res = NULL;
    588         CGRect rect;
    589         if (!PyArg_ParseTuple(_args, "O&",
    590                               CGRect_Convert, &rect))
    591                 return NULL;
    592         CGContextStrokeRect(_self->ob_itself,
    593                             rect);
    594         Py_INCREF(Py_None);
    595         _res = Py_None;
    596         return _res;
     587    PyObject *_res = NULL;
     588    CGRect rect;
     589    if (!PyArg_ParseTuple(_args, "O&",
     590                          CGRect_Convert, &rect))
     591        return NULL;
     592    CGContextStrokeRect(_self->ob_itself,
     593                        rect);
     594    Py_INCREF(Py_None);
     595    _res = Py_None;
     596    return _res;
    597597}
    598598
    599599static PyObject *CGContextRefObj_CGContextStrokeRectWithWidth(CGContextRefObject *_self, PyObject *_args)
    600600{
    601         PyObject *_res = NULL;
    602         CGRect rect;
    603         float width;
    604         if (!PyArg_ParseTuple(_args, "O&f",
    605                               CGRect_Convert, &rect,
    606                               &width))
    607                 return NULL;
    608         CGContextStrokeRectWithWidth(_self->ob_itself,
    609                                      rect,
    610                                      width);
    611         Py_INCREF(Py_None);
    612         _res = Py_None;
    613         return _res;
     601    PyObject *_res = NULL;
     602    CGRect rect;
     603    float width;
     604    if (!PyArg_ParseTuple(_args, "O&f",
     605                          CGRect_Convert, &rect,
     606                          &width))
     607        return NULL;
     608    CGContextStrokeRectWithWidth(_self->ob_itself,
     609                                 rect,
     610                                 width);
     611    Py_INCREF(Py_None);
     612    _res = Py_None;
     613    return _res;
    614614}
    615615
    616616static PyObject *CGContextRefObj_CGContextClearRect(CGContextRefObject *_self, PyObject *_args)
    617617{
    618         PyObject *_res = NULL;
    619         CGRect rect;
    620         if (!PyArg_ParseTuple(_args, "O&",
    621                               CGRect_Convert, &rect))
    622                 return NULL;
    623         CGContextClearRect(_self->ob_itself,
    624                            rect);
    625         Py_INCREF(Py_None);
    626         _res = Py_None;
    627         return _res;
     618    PyObject *_res = NULL;
     619    CGRect rect;
     620    if (!PyArg_ParseTuple(_args, "O&",
     621                          CGRect_Convert, &rect))
     622        return NULL;
     623    CGContextClearRect(_self->ob_itself,
     624                       rect);
     625    Py_INCREF(Py_None);
     626    _res = Py_None;
     627    return _res;
    628628}
    629629
    630630static PyObject *CGContextRefObj_CGContextClip(CGContextRefObject *_self, PyObject *_args)
    631631{
    632         PyObject *_res = NULL;
    633         if (!PyArg_ParseTuple(_args, ""))
    634                 return NULL;
    635         CGContextClip(_self->ob_itself);
    636         Py_INCREF(Py_None);
    637         _res = Py_None;
    638         return _res;
     632    PyObject *_res = NULL;
     633    if (!PyArg_ParseTuple(_args, ""))
     634        return NULL;
     635    CGContextClip(_self->ob_itself);
     636    Py_INCREF(Py_None);
     637    _res = Py_None;
     638    return _res;
    639639}
    640640
    641641static PyObject *CGContextRefObj_CGContextEOClip(CGContextRefObject *_self, PyObject *_args)
    642642{
    643         PyObject *_res = NULL;
    644         if (!PyArg_ParseTuple(_args, ""))
    645                 return NULL;
    646         CGContextEOClip(_self->ob_itself);
    647         Py_INCREF(Py_None);
    648         _res = Py_None;
    649         return _res;
     643    PyObject *_res = NULL;
     644    if (!PyArg_ParseTuple(_args, ""))
     645        return NULL;
     646    CGContextEOClip(_self->ob_itself);
     647    Py_INCREF(Py_None);
     648    _res = Py_None;
     649    return _res;
    650650}
    651651
    652652static PyObject *CGContextRefObj_CGContextClipToRect(CGContextRefObject *_self, PyObject *_args)
    653653{
    654         PyObject *_res = NULL;
    655         CGRect rect;
    656         if (!PyArg_ParseTuple(_args, "O&",
    657                               CGRect_Convert, &rect))
    658                 return NULL;
    659         CGContextClipToRect(_self->ob_itself,
    660                             rect);
    661         Py_INCREF(Py_None);
    662         _res = Py_None;
    663         return _res;
     654    PyObject *_res = NULL;
     655    CGRect rect;
     656    if (!PyArg_ParseTuple(_args, "O&",
     657                          CGRect_Convert, &rect))
     658        return NULL;
     659    CGContextClipToRect(_self->ob_itself,
     660                        rect);
     661    Py_INCREF(Py_None);
     662    _res = Py_None;
     663    return _res;
    664664}
    665665
    666666static PyObject *CGContextRefObj_CGContextSetGrayFillColor(CGContextRefObject *_self, PyObject *_args)
    667667{
    668         PyObject *_res = NULL;
    669         float gray;
    670         float alpha;
    671         if (!PyArg_ParseTuple(_args, "ff",
    672                               &gray,
    673                               &alpha))
    674                 return NULL;
    675         CGContextSetGrayFillColor(_self->ob_itself,
    676                                   gray,
    677                                   alpha);
    678         Py_INCREF(Py_None);
    679         _res = Py_None;
    680         return _res;
     668    PyObject *_res = NULL;
     669    float gray;
     670    float alpha;
     671    if (!PyArg_ParseTuple(_args, "ff",
     672                          &gray,
     673                          &alpha))
     674        return NULL;
     675    CGContextSetGrayFillColor(_self->ob_itself,
     676                              gray,
     677                              alpha);
     678    Py_INCREF(Py_None);
     679    _res = Py_None;
     680    return _res;
    681681}
    682682
    683683static PyObject *CGContextRefObj_CGContextSetGrayStrokeColor(CGContextRefObject *_self, PyObject *_args)
    684684{
    685         PyObject *_res = NULL;
    686         float gray;
    687         float alpha;
    688         if (!PyArg_ParseTuple(_args, "ff",
    689                               &gray,
    690                               &alpha))
    691                 return NULL;
    692         CGContextSetGrayStrokeColor(_self->ob_itself,
    693                                     gray,
    694                                     alpha);
    695         Py_INCREF(Py_None);
    696         _res = Py_None;
    697         return _res;
     685    PyObject *_res = NULL;
     686    float gray;
     687    float alpha;
     688    if (!PyArg_ParseTuple(_args, "ff",
     689                          &gray,
     690                          &alpha))
     691        return NULL;
     692    CGContextSetGrayStrokeColor(_self->ob_itself,
     693                                gray,
     694                                alpha);
     695    Py_INCREF(Py_None);
     696    _res = Py_None;
     697    return _res;
    698698}
    699699
    700700static PyObject *CGContextRefObj_CGContextSetRGBFillColor(CGContextRefObject *_self, PyObject *_args)
    701701{
    702         PyObject *_res = NULL;
    703         float red;
    704         float green;
    705         float blue;
    706         float alpha;
    707         if (!PyArg_ParseTuple(_args, "ffff",
    708                               &red,
    709                               &green,
    710                               &blue,
    711                               &alpha))
    712                 return NULL;
    713         CGContextSetRGBFillColor(_self->ob_itself,
    714                                  red,
    715                                  green,
    716                                  blue,
    717                                  alpha);
    718         Py_INCREF(Py_None);
    719         _res = Py_None;
    720         return _res;
     702    PyObject *_res = NULL;
     703    float red;
     704    float green;
     705    float blue;
     706    float alpha;
     707    if (!PyArg_ParseTuple(_args, "ffff",
     708                          &red,
     709                          &green,
     710                          &blue,
     711                          &alpha))
     712        return NULL;
     713    CGContextSetRGBFillColor(_self->ob_itself,
     714                             red,
     715                             green,
     716                             blue,
     717                             alpha);
     718    Py_INCREF(Py_None);
     719    _res = Py_None;
     720    return _res;
    721721}
    722722
    723723static PyObject *CGContextRefObj_CGContextSetRGBStrokeColor(CGContextRefObject *_self, PyObject *_args)
    724724{
    725         PyObject *_res = NULL;
    726         float red;
    727         float green;
    728         float blue;
    729         float alpha;
    730         if (!PyArg_ParseTuple(_args, "ffff",
    731                               &red,
    732                               &green,
    733                               &blue,
    734                               &alpha))
    735                 return NULL;
    736         CGContextSetRGBStrokeColor(_self->ob_itself,
    737                                    red,
    738                                    green,
    739                                    blue,
    740                                    alpha);
    741         Py_INCREF(Py_None);
    742         _res = Py_None;
    743         return _res;
     725    PyObject *_res = NULL;
     726    float red;
     727    float green;
     728    float blue;
     729    float alpha;
     730    if (!PyArg_ParseTuple(_args, "ffff",
     731                          &red,
     732                          &green,
     733                          &blue,
     734                          &alpha))
     735        return NULL;
     736    CGContextSetRGBStrokeColor(_self->ob_itself,
     737                               red,
     738                               green,
     739                               blue,
     740                               alpha);
     741    Py_INCREF(Py_None);
     742    _res = Py_None;
     743    return _res;
    744744}
    745745
    746746static PyObject *CGContextRefObj_CGContextSetCMYKFillColor(CGContextRefObject *_self, PyObject *_args)
    747747{
    748         PyObject *_res = NULL;
    749         float cyan;
    750         float magenta;
    751         float yellow;
    752         float black;
    753         float alpha;
    754         if (!PyArg_ParseTuple(_args, "fffff",
    755                               &cyan,
    756                               &magenta,
    757                               &yellow,
    758                               &black,
    759                               &alpha))
    760                 return NULL;
    761         CGContextSetCMYKFillColor(_self->ob_itself,
    762                                   cyan,
    763                                   magenta,
    764                                   yellow,
    765                                   black,
    766                                   alpha);
    767         Py_INCREF(Py_None);
    768         _res = Py_None;
    769         return _res;
     748    PyObject *_res = NULL;
     749    float cyan;
     750    float magenta;
     751    float yellow;
     752    float black;
     753    float alpha;
     754    if (!PyArg_ParseTuple(_args, "fffff",
     755                          &cyan,
     756                          &magenta,
     757                          &yellow,
     758                          &black,
     759                          &alpha))
     760        return NULL;
     761    CGContextSetCMYKFillColor(_self->ob_itself,
     762                              cyan,
     763                              magenta,
     764                              yellow,
     765                              black,
     766                              alpha);
     767    Py_INCREF(Py_None);
     768    _res = Py_None;
     769    return _res;
    770770}
    771771
    772772static PyObject *CGContextRefObj_CGContextSetCMYKStrokeColor(CGContextRefObject *_self, PyObject *_args)
    773773{
    774         PyObject *_res = NULL;
    775         float cyan;
    776         float magenta;
    777         float yellow;
    778         float black;
    779         float alpha;
    780         if (!PyArg_ParseTuple(_args, "fffff",
    781                               &cyan,
    782                               &magenta,
    783                               &yellow,
    784                               &black,
    785                               &alpha))
    786                 return NULL;
    787         CGContextSetCMYKStrokeColor(_self->ob_itself,
    788                                     cyan,
    789                                     magenta,
    790                                     yellow,
    791                                     black,
    792                                     alpha);
    793         Py_INCREF(Py_None);
    794         _res = Py_None;
    795         return _res;
     774    PyObject *_res = NULL;
     775    float cyan;
     776    float magenta;
     777    float yellow;
     778    float black;
     779    float alpha;
     780    if (!PyArg_ParseTuple(_args, "fffff",
     781                          &cyan,
     782                          &magenta,
     783                          &yellow,
     784                          &black,
     785                          &alpha))
     786        return NULL;
     787    CGContextSetCMYKStrokeColor(_self->ob_itself,
     788                                cyan,
     789                                magenta,
     790                                yellow,
     791                                black,
     792                                alpha);
     793    Py_INCREF(Py_None);
     794    _res = Py_None;
     795    return _res;
    796796}
    797797
    798798static PyObject *CGContextRefObj_CGContextGetInterpolationQuality(CGContextRefObject *_self, PyObject *_args)
    799799{
    800         PyObject *_res = NULL;
    801         int _rv;
    802         if (!PyArg_ParseTuple(_args, ""))
    803                 return NULL;
    804         _rv = CGContextGetInterpolationQuality(_self->ob_itself);
    805         _res = Py_BuildValue("i",
    806                              _rv);
    807         return _res;
     800    PyObject *_res = NULL;
     801    int _rv;
     802    if (!PyArg_ParseTuple(_args, ""))
     803        return NULL;
     804    _rv = CGContextGetInterpolationQuality(_self->ob_itself);
     805    _res = Py_BuildValue("i",
     806                         _rv);
     807    return _res;
    808808}
    809809
    810810static PyObject *CGContextRefObj_CGContextSetInterpolationQuality(CGContextRefObject *_self, PyObject *_args)
    811811{
    812         PyObject *_res = NULL;
    813         int quality;
    814         if (!PyArg_ParseTuple(_args, "i",
    815                               &quality))
    816                 return NULL;
    817         CGContextSetInterpolationQuality(_self->ob_itself,
    818                                          quality);
    819         Py_INCREF(Py_None);
    820         _res = Py_None;
    821         return _res;
     812    PyObject *_res = NULL;
     813    int quality;
     814    if (!PyArg_ParseTuple(_args, "i",
     815                          &quality))
     816        return NULL;
     817    CGContextSetInterpolationQuality(_self->ob_itself,
     818                                     quality);
     819    Py_INCREF(Py_None);
     820    _res = Py_None;
     821    return _res;
    822822}
    823823
    824824static PyObject *CGContextRefObj_CGContextSetCharacterSpacing(CGContextRefObject *_self, PyObject *_args)
    825825{
    826         PyObject *_res = NULL;
    827         float spacing;
    828         if (!PyArg_ParseTuple(_args, "f",
    829                               &spacing))
    830                 return NULL;
    831         CGContextSetCharacterSpacing(_self->ob_itself,
    832                                      spacing);
    833         Py_INCREF(Py_None);
    834         _res = Py_None;
    835         return _res;
     826    PyObject *_res = NULL;
     827    float spacing;
     828    if (!PyArg_ParseTuple(_args, "f",
     829                          &spacing))
     830        return NULL;
     831    CGContextSetCharacterSpacing(_self->ob_itself,
     832                                 spacing);
     833    Py_INCREF(Py_None);
     834    _res = Py_None;
     835    return _res;
    836836}
    837837
    838838static PyObject *CGContextRefObj_CGContextSetTextPosition(CGContextRefObject *_self, PyObject *_args)
    839839{
    840         PyObject *_res = NULL;
    841         float x;
    842         float y;
    843         if (!PyArg_ParseTuple(_args, "ff",
    844                               &x,
    845                               &y))
    846                 return NULL;
    847         CGContextSetTextPosition(_self->ob_itself,
    848                                  x,
    849                                  y);
    850         Py_INCREF(Py_None);
    851         _res = Py_None;
    852         return _res;
     840    PyObject *_res = NULL;
     841    float x;
     842    float y;
     843    if (!PyArg_ParseTuple(_args, "ff",
     844                          &x,
     845                          &y))
     846        return NULL;
     847    CGContextSetTextPosition(_self->ob_itself,
     848                             x,
     849                             y);
     850    Py_INCREF(Py_None);
     851    _res = Py_None;
     852    return _res;
    853853}
    854854
    855855static PyObject *CGContextRefObj_CGContextGetTextPosition(CGContextRefObject *_self, PyObject *_args)
    856856{
    857         PyObject *_res = NULL;
    858         CGPoint _rv;
    859         if (!PyArg_ParseTuple(_args, ""))
    860                 return NULL;
    861         _rv = CGContextGetTextPosition(_self->ob_itself);
    862         _res = Py_BuildValue("O&",
    863                              CGPoint_New, &_rv);
    864         return _res;
     857    PyObject *_res = NULL;
     858    CGPoint _rv;
     859    if (!PyArg_ParseTuple(_args, ""))
     860        return NULL;
     861    _rv = CGContextGetTextPosition(_self->ob_itself);
     862    _res = Py_BuildValue("O&",
     863                         CGPoint_New, &_rv);
     864    return _res;
    865865}
    866866
    867867static PyObject *CGContextRefObj_CGContextSetTextMatrix(CGContextRefObject *_self, PyObject *_args)
    868868{
    869         PyObject *_res = NULL;
    870         CGAffineTransform transform;
    871         if (!PyArg_ParseTuple(_args, "O&",
    872                               CGAffineTransform_Convert, &transform))
    873                 return NULL;
    874         CGContextSetTextMatrix(_self->ob_itself,
    875                                transform);
    876         Py_INCREF(Py_None);
    877         _res = Py_None;
    878         return _res;
     869    PyObject *_res = NULL;
     870    CGAffineTransform transform;
     871    if (!PyArg_ParseTuple(_args, "O&",
     872                          CGAffineTransform_Convert, &transform))
     873        return NULL;
     874    CGContextSetTextMatrix(_self->ob_itself,
     875                           transform);
     876    Py_INCREF(Py_None);
     877    _res = Py_None;
     878    return _res;
    879879}
    880880
    881881static PyObject *CGContextRefObj_CGContextGetTextMatrix(CGContextRefObject *_self, PyObject *_args)
    882882{
    883         PyObject *_res = NULL;
    884         CGAffineTransform _rv;
    885         if (!PyArg_ParseTuple(_args, ""))
    886                 return NULL;
    887         _rv = CGContextGetTextMatrix(_self->ob_itself);
    888         _res = Py_BuildValue("O&",
    889                              CGAffineTransform_New, &_rv);
    890         return _res;
     883    PyObject *_res = NULL;
     884    CGAffineTransform _rv;
     885    if (!PyArg_ParseTuple(_args, ""))
     886        return NULL;
     887    _rv = CGContextGetTextMatrix(_self->ob_itself);
     888    _res = Py_BuildValue("O&",
     889                         CGAffineTransform_New, &_rv);
     890    return _res;
    891891}
    892892
    893893static PyObject *CGContextRefObj_CGContextSetTextDrawingMode(CGContextRefObject *_self, PyObject *_args)
    894894{
    895         PyObject *_res = NULL;
    896         int mode;
    897         if (!PyArg_ParseTuple(_args, "i",
    898                               &mode))
    899                 return NULL;
    900         CGContextSetTextDrawingMode(_self->ob_itself,
    901                                     mode);
    902         Py_INCREF(Py_None);
    903         _res = Py_None;
    904         return _res;
     895    PyObject *_res = NULL;
     896    int mode;
     897    if (!PyArg_ParseTuple(_args, "i",
     898                          &mode))
     899        return NULL;
     900    CGContextSetTextDrawingMode(_self->ob_itself,
     901                                mode);
     902    Py_INCREF(Py_None);
     903    _res = Py_None;
     904    return _res;
    905905}
    906906
    907907static PyObject *CGContextRefObj_CGContextSetFontSize(CGContextRefObject *_self, PyObject *_args)
    908908{
    909         PyObject *_res = NULL;
    910         float size;
    911         if (!PyArg_ParseTuple(_args, "f",
    912                               &size))
    913                 return NULL;
    914         CGContextSetFontSize(_self->ob_itself,
    915                              size);
    916         Py_INCREF(Py_None);
    917         _res = Py_None;
    918         return _res;
     909    PyObject *_res = NULL;
     910    float size;
     911    if (!PyArg_ParseTuple(_args, "f",
     912                          &size))
     913        return NULL;
     914    CGContextSetFontSize(_self->ob_itself,
     915                         size);
     916    Py_INCREF(Py_None);
     917    _res = Py_None;
     918    return _res;
    919919}
    920920
    921921static PyObject *CGContextRefObj_CGContextSelectFont(CGContextRefObject *_self, PyObject *_args)
    922922{
    923         PyObject *_res = NULL;
    924         char * name;
    925         float size;
    926         int textEncoding;
    927         if (!PyArg_ParseTuple(_args, "sfi",
    928                               &name,
    929                               &size,
    930                               &textEncoding))
    931                 return NULL;
    932         CGContextSelectFont(_self->ob_itself,
    933                             name,
    934                             size,
    935                             textEncoding);
    936         Py_INCREF(Py_None);
    937         _res = Py_None;
    938         return _res;
     923    PyObject *_res = NULL;
     924    char * name;
     925    float size;
     926    int textEncoding;
     927    if (!PyArg_ParseTuple(_args, "sfi",
     928                          &name,
     929                          &size,
     930                          &textEncoding))
     931        return NULL;
     932    CGContextSelectFont(_self->ob_itself,
     933                        name,
     934                        size,
     935                        textEncoding);
     936    Py_INCREF(Py_None);
     937    _res = Py_None;
     938    return _res;
    939939}
    940940
    941941static PyObject *CGContextRefObj_CGContextShowText(CGContextRefObject *_self, PyObject *_args)
    942942{
    943         PyObject *_res = NULL;
    944         char *cstring__in__;
    945         long cstring__len__;
    946         int cstring__in_len__;
    947         if (!PyArg_ParseTuple(_args, "s#",
    948                               &cstring__in__, &cstring__in_len__))
    949                 return NULL;
    950         cstring__len__ = cstring__in_len__;
    951         CGContextShowText(_self->ob_itself,
    952                           cstring__in__, cstring__len__);
    953         Py_INCREF(Py_None);
    954         _res = Py_None;
    955         return _res;
     943    PyObject *_res = NULL;
     944    char *cstring__in__;
     945    long cstring__len__;
     946    int cstring__in_len__;
     947    if (!PyArg_ParseTuple(_args, "s#",
     948                          &cstring__in__, &cstring__in_len__))
     949        return NULL;
     950    cstring__len__ = cstring__in_len__;
     951    CGContextShowText(_self->ob_itself,
     952                      cstring__in__, cstring__len__);
     953    Py_INCREF(Py_None);
     954    _res = Py_None;
     955    return _res;
    956956}
    957957
    958958static PyObject *CGContextRefObj_CGContextShowTextAtPoint(CGContextRefObject *_self, PyObject *_args)
    959959{
    960         PyObject *_res = NULL;
    961         float x;
    962         float y;
    963         char *cstring__in__;
    964         long cstring__len__;
    965         int cstring__in_len__;
    966         if (!PyArg_ParseTuple(_args, "ffs#",
    967                               &x,
    968                               &y,
    969                               &cstring__in__, &cstring__in_len__))
    970                 return NULL;
    971         cstring__len__ = cstring__in_len__;
    972         CGContextShowTextAtPoint(_self->ob_itself,
    973                                  x,
    974                                  y,
    975                                  cstring__in__, cstring__len__);
    976         Py_INCREF(Py_None);
    977         _res = Py_None;
    978         return _res;
     960    PyObject *_res = NULL;
     961    float x;
     962    float y;
     963    char *cstring__in__;
     964    long cstring__len__;
     965    int cstring__in_len__;
     966    if (!PyArg_ParseTuple(_args, "ffs#",
     967                          &x,
     968                          &y,
     969                          &cstring__in__, &cstring__in_len__))
     970        return NULL;
     971    cstring__len__ = cstring__in_len__;
     972    CGContextShowTextAtPoint(_self->ob_itself,
     973                             x,
     974                             y,
     975                             cstring__in__, cstring__len__);
     976    Py_INCREF(Py_None);
     977    _res = Py_None;
     978    return _res;
    979979}
    980980
    981981static PyObject *CGContextRefObj_CGContextEndPage(CGContextRefObject *_self, PyObject *_args)
    982982{
    983         PyObject *_res = NULL;
    984         if (!PyArg_ParseTuple(_args, ""))
    985                 return NULL;
    986         CGContextEndPage(_self->ob_itself);
    987         Py_INCREF(Py_None);
    988         _res = Py_None;
    989         return _res;
     983    PyObject *_res = NULL;
     984    if (!PyArg_ParseTuple(_args, ""))
     985        return NULL;
     986    CGContextEndPage(_self->ob_itself);
     987    Py_INCREF(Py_None);
     988    _res = Py_None;
     989    return _res;
    990990}
    991991
    992992static PyObject *CGContextRefObj_CGContextFlush(CGContextRefObject *_self, PyObject *_args)
    993993{
    994         PyObject *_res = NULL;
    995         if (!PyArg_ParseTuple(_args, ""))
    996                 return NULL;
    997         CGContextFlush(_self->ob_itself);
    998         Py_INCREF(Py_None);
    999         _res = Py_None;
    1000         return _res;
     994    PyObject *_res = NULL;
     995    if (!PyArg_ParseTuple(_args, ""))
     996        return NULL;
     997    CGContextFlush(_self->ob_itself);
     998    Py_INCREF(Py_None);
     999    _res = Py_None;
     1000    return _res;
    10011001}
    10021002
    10031003static PyObject *CGContextRefObj_CGContextSynchronize(CGContextRefObject *_self, PyObject *_args)
    10041004{
    1005         PyObject *_res = NULL;
    1006         if (!PyArg_ParseTuple(_args, ""))
    1007                 return NULL;
    1008         CGContextSynchronize(_self->ob_itself);
    1009         Py_INCREF(Py_None);
    1010         _res = Py_None;
    1011         return _res;
     1005    PyObject *_res = NULL;
     1006    if (!PyArg_ParseTuple(_args, ""))
     1007        return NULL;
     1008    CGContextSynchronize(_self->ob_itself);
     1009    Py_INCREF(Py_None);
     1010    _res = Py_None;
     1011    return _res;
    10121012}
    10131013
    10141014static PyObject *CGContextRefObj_CGContextSetShouldAntialias(CGContextRefObject *_self, PyObject *_args)
    10151015{
    1016         PyObject *_res = NULL;
    1017         int shouldAntialias;
    1018         if (!PyArg_ParseTuple(_args, "i",
    1019                               &shouldAntialias))
    1020                 return NULL;
    1021         CGContextSetShouldAntialias(_self->ob_itself,
    1022                                     shouldAntialias);
    1023         Py_INCREF(Py_None);
    1024         _res = Py_None;
    1025         return _res;
     1016    PyObject *_res = NULL;
     1017    int shouldAntialias;
     1018    if (!PyArg_ParseTuple(_args, "i",
     1019                          &shouldAntialias))
     1020        return NULL;
     1021    CGContextSetShouldAntialias(_self->ob_itself,
     1022                                shouldAntialias);
     1023    Py_INCREF(Py_None);
     1024    _res = Py_None;
     1025    return _res;
    10261026}
    10271027
     
    10291029static PyObject *CGContextRefObj_SyncCGContextOriginWithPort(CGContextRefObject *_self, PyObject *_args)
    10301030{
    1031         PyObject *_res = NULL;
    1032         CGrafPtr port;
    1033         if (!PyArg_ParseTuple(_args, "O&",
    1034                               GrafObj_Convert, &port))
    1035                 return NULL;
    1036         SyncCGContextOriginWithPort(_self->ob_itself,
    1037                                     port);
    1038         Py_INCREF(Py_None);
    1039         _res = Py_None;
    1040         return _res;
     1031    PyObject *_res = NULL;
     1032    CGrafPtr port;
     1033    if (!PyArg_ParseTuple(_args, "O&",
     1034                          GrafObj_Convert, &port))
     1035        return NULL;
     1036    SyncCGContextOriginWithPort(_self->ob_itself,
     1037                                port);
     1038    Py_INCREF(Py_None);
     1039    _res = Py_None;
     1040    return _res;
    10411041}
    10421042
    10431043static PyObject *CGContextRefObj_ClipCGContextToRegion(CGContextRefObject *_self, PyObject *_args)
    10441044{
    1045         PyObject *_res = NULL;
    1046         Rect portRect;
    1047         RgnHandle region;
    1048         if (!PyArg_ParseTuple(_args, "O&O&",
    1049                               PyMac_GetRect, &portRect,
    1050                               ResObj_Convert, &region))
    1051                 return NULL;
    1052         ClipCGContextToRegion(_self->ob_itself,
    1053                               &portRect,
    1054                               region);
    1055         Py_INCREF(Py_None);
    1056         _res = Py_None;
    1057         return _res;
     1045    PyObject *_res = NULL;
     1046    Rect portRect;
     1047    RgnHandle region;
     1048    if (!PyArg_ParseTuple(_args, "O&O&",
     1049                          PyMac_GetRect, &portRect,
     1050                          ResObj_Convert, &region))
     1051        return NULL;
     1052    ClipCGContextToRegion(_self->ob_itself,
     1053                          &portRect,
     1054                          region);
     1055    Py_INCREF(Py_None);
     1056    _res = Py_None;
     1057    return _res;
    10581058}
    10591059#endif
    10601060
    10611061static PyMethodDef CGContextRefObj_methods[] = {
    1062         {"CGContextSaveGState", (PyCFunction)CGContextRefObj_CGContextSaveGState, 1,
    1063         PyDoc_STR("() -> None")},
    1064         {"CGContextRestoreGState", (PyCFunction)CGContextRefObj_CGContextRestoreGState, 1,
    1065         PyDoc_STR("() -> None")},
    1066         {"CGContextScaleCTM", (PyCFunction)CGContextRefObj_CGContextScaleCTM, 1,
    1067         PyDoc_STR("(float sx, float sy) -> None")},
    1068         {"CGContextTranslateCTM", (PyCFunction)CGContextRefObj_CGContextTranslateCTM, 1,
    1069         PyDoc_STR("(float tx, float ty) -> None")},
    1070         {"CGContextRotateCTM", (PyCFunction)CGContextRefObj_CGContextRotateCTM, 1,
    1071         PyDoc_STR("(float angle) -> None")},
    1072         {"CGContextConcatCTM", (PyCFunction)CGContextRefObj_CGContextConcatCTM, 1,
    1073         PyDoc_STR("(CGAffineTransform transform) -> None")},
    1074         {"CGContextGetCTM", (PyCFunction)CGContextRefObj_CGContextGetCTM, 1,
    1075         PyDoc_STR("() -> (CGAffineTransform _rv)")},
    1076         {"CGContextSetLineWidth", (PyCFunction)CGContextRefObj_CGContextSetLineWidth, 1,
    1077         PyDoc_STR("(float width) -> None")},
    1078         {"CGContextSetLineCap", (PyCFunction)CGContextRefObj_CGContextSetLineCap, 1,
    1079         PyDoc_STR("(int cap) -> None")},
    1080         {"CGContextSetLineJoin", (PyCFunction)CGContextRefObj_CGContextSetLineJoin, 1,
    1081         PyDoc_STR("(int join) -> None")},
    1082         {"CGContextSetMiterLimit", (PyCFunction)CGContextRefObj_CGContextSetMiterLimit, 1,
    1083         PyDoc_STR("(float limit) -> None")},
    1084         {"CGContextSetFlatness", (PyCFunction)CGContextRefObj_CGContextSetFlatness, 1,
    1085         PyDoc_STR("(float flatness) -> None")},
    1086         {"CGContextSetAlpha", (PyCFunction)CGContextRefObj_CGContextSetAlpha, 1,
    1087         PyDoc_STR("(float alpha) -> None")},
    1088         {"CGContextBeginPath", (PyCFunction)CGContextRefObj_CGContextBeginPath, 1,
    1089         PyDoc_STR("() -> None")},
    1090         {"CGContextMoveToPoint", (PyCFunction)CGContextRefObj_CGContextMoveToPoint, 1,
    1091         PyDoc_STR("(float x, float y) -> None")},
    1092         {"CGContextAddLineToPoint", (PyCFunction)CGContextRefObj_CGContextAddLineToPoint, 1,
    1093         PyDoc_STR("(float x, float y) -> None")},
    1094         {"CGContextAddCurveToPoint", (PyCFunction)CGContextRefObj_CGContextAddCurveToPoint, 1,
    1095         PyDoc_STR("(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y) -> None")},
    1096         {"CGContextAddQuadCurveToPoint", (PyCFunction)CGContextRefObj_CGContextAddQuadCurveToPoint, 1,
    1097         PyDoc_STR("(float cpx, float cpy, float x, float y) -> None")},
    1098         {"CGContextClosePath", (PyCFunction)CGContextRefObj_CGContextClosePath, 1,
    1099         PyDoc_STR("() -> None")},
    1100         {"CGContextAddRect", (PyCFunction)CGContextRefObj_CGContextAddRect, 1,
    1101         PyDoc_STR("(CGRect rect) -> None")},
    1102         {"CGContextAddArc", (PyCFunction)CGContextRefObj_CGContextAddArc, 1,
    1103         PyDoc_STR("(float x, float y, float radius, float startAngle, float endAngle, int clockwise) -> None")},
    1104         {"CGContextAddArcToPoint", (PyCFunction)CGContextRefObj_CGContextAddArcToPoint, 1,
    1105         PyDoc_STR("(float x1, float y1, float x2, float y2, float radius) -> None")},
    1106         {"CGContextIsPathEmpty", (PyCFunction)CGContextRefObj_CGContextIsPathEmpty, 1,
    1107         PyDoc_STR("() -> (int _rv)")},
    1108         {"CGContextGetPathCurrentPoint", (PyCFunction)CGContextRefObj_CGContextGetPathCurrentPoint, 1,
    1109         PyDoc_STR("() -> (CGPoint _rv)")},
    1110         {"CGContextGetPathBoundingBox", (PyCFunction)CGContextRefObj_CGContextGetPathBoundingBox, 1,
    1111         PyDoc_STR("() -> (CGRect _rv)")},
    1112         {"CGContextDrawPath", (PyCFunction)CGContextRefObj_CGContextDrawPath, 1,
    1113         PyDoc_STR("(int mode) -> None")},
    1114         {"CGContextFillPath", (PyCFunction)CGContextRefObj_CGContextFillPath, 1,
    1115         PyDoc_STR("() -> None")},
    1116         {"CGContextEOFillPath", (PyCFunction)CGContextRefObj_CGContextEOFillPath, 1,
    1117         PyDoc_STR("() -> None")},
    1118         {"CGContextStrokePath", (PyCFunction)CGContextRefObj_CGContextStrokePath, 1,
    1119         PyDoc_STR("() -> None")},
    1120         {"CGContextFillRect", (PyCFunction)CGContextRefObj_CGContextFillRect, 1,
    1121         PyDoc_STR("(CGRect rect) -> None")},
    1122         {"CGContextStrokeRect", (PyCFunction)CGContextRefObj_CGContextStrokeRect, 1,
    1123         PyDoc_STR("(CGRect rect) -> None")},
    1124         {"CGContextStrokeRectWithWidth", (PyCFunction)CGContextRefObj_CGContextStrokeRectWithWidth, 1,
    1125         PyDoc_STR("(CGRect rect, float width) -> None")},
    1126         {"CGContextClearRect", (PyCFunction)CGContextRefObj_CGContextClearRect, 1,
    1127         PyDoc_STR("(CGRect rect) -> None")},
    1128         {"CGContextClip", (PyCFunction)CGContextRefObj_CGContextClip, 1,
    1129         PyDoc_STR("() -> None")},
    1130         {"CGContextEOClip", (PyCFunction)CGContextRefObj_CGContextEOClip, 1,
    1131         PyDoc_STR("() -> None")},
    1132         {"CGContextClipToRect", (PyCFunction)CGContextRefObj_CGContextClipToRect, 1,
    1133         PyDoc_STR("(CGRect rect) -> None")},
    1134         {"CGContextSetGrayFillColor", (PyCFunction)CGContextRefObj_CGContextSetGrayFillColor, 1,
    1135         PyDoc_STR("(float gray, float alpha) -> None")},
    1136         {"CGContextSetGrayStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetGrayStrokeColor, 1,
    1137         PyDoc_STR("(float gray, float alpha) -> None")},
    1138         {"CGContextSetRGBFillColor", (PyCFunction)CGContextRefObj_CGContextSetRGBFillColor, 1,
    1139         PyDoc_STR("(float red, float green, float blue, float alpha) -> None")},
    1140         {"CGContextSetRGBStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetRGBStrokeColor, 1,
    1141         PyDoc_STR("(float red, float green, float blue, float alpha) -> None")},
    1142         {"CGContextSetCMYKFillColor", (PyCFunction)CGContextRefObj_CGContextSetCMYKFillColor, 1,
    1143         PyDoc_STR("(float cyan, float magenta, float yellow, float black, float alpha) -> None")},
    1144         {"CGContextSetCMYKStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetCMYKStrokeColor, 1,
    1145         PyDoc_STR("(float cyan, float magenta, float yellow, float black, float alpha) -> None")},
    1146         {"CGContextGetInterpolationQuality", (PyCFunction)CGContextRefObj_CGContextGetInterpolationQuality, 1,
    1147         PyDoc_STR("() -> (int _rv)")},
    1148         {"CGContextSetInterpolationQuality", (PyCFunction)CGContextRefObj_CGContextSetInterpolationQuality, 1,
    1149         PyDoc_STR("(int quality) -> None")},
    1150         {"CGContextSetCharacterSpacing", (PyCFunction)CGContextRefObj_CGContextSetCharacterSpacing, 1,
    1151         PyDoc_STR("(float spacing) -> None")},
    1152         {"CGContextSetTextPosition", (PyCFunction)CGContextRefObj_CGContextSetTextPosition, 1,
    1153         PyDoc_STR("(float x, float y) -> None")},
    1154         {"CGContextGetTextPosition", (PyCFunction)CGContextRefObj_CGContextGetTextPosition, 1,
    1155         PyDoc_STR("() -> (CGPoint _rv)")},
    1156         {"CGContextSetTextMatrix", (PyCFunction)CGContextRefObj_CGContextSetTextMatrix, 1,
    1157         PyDoc_STR("(CGAffineTransform transform) -> None")},
    1158         {"CGContextGetTextMatrix", (PyCFunction)CGContextRefObj_CGContextGetTextMatrix, 1,
    1159         PyDoc_STR("() -> (CGAffineTransform _rv)")},
    1160         {"CGContextSetTextDrawingMode", (PyCFunction)CGContextRefObj_CGContextSetTextDrawingMode, 1,
    1161         PyDoc_STR("(int mode) -> None")},
    1162         {"CGContextSetFontSize", (PyCFunction)CGContextRefObj_CGContextSetFontSize, 1,
    1163         PyDoc_STR("(float size) -> None")},
    1164         {"CGContextSelectFont", (PyCFunction)CGContextRefObj_CGContextSelectFont, 1,
    1165         PyDoc_STR("(char * name, float size, int textEncoding) -> None")},
    1166         {"CGContextShowText", (PyCFunction)CGContextRefObj_CGContextShowText, 1,
    1167         PyDoc_STR("(Buffer cstring) -> None")},
    1168         {"CGContextShowTextAtPoint", (PyCFunction)CGContextRefObj_CGContextShowTextAtPoint, 1,
    1169         PyDoc_STR("(float x, float y, Buffer cstring) -> None")},
    1170         {"CGContextEndPage", (PyCFunction)CGContextRefObj_CGContextEndPage, 1,
    1171         PyDoc_STR("() -> None")},
    1172         {"CGContextFlush", (PyCFunction)CGContextRefObj_CGContextFlush, 1,
    1173         PyDoc_STR("() -> None")},
    1174         {"CGContextSynchronize", (PyCFunction)CGContextRefObj_CGContextSynchronize, 1,
    1175         PyDoc_STR("() -> None")},
    1176         {"CGContextSetShouldAntialias", (PyCFunction)CGContextRefObj_CGContextSetShouldAntialias, 1,
    1177         PyDoc_STR("(int shouldAntialias) -> None")},
     1062    {"CGContextSaveGState", (PyCFunction)CGContextRefObj_CGContextSaveGState, 1,
     1063    PyDoc_STR("() -> None")},
     1064    {"CGContextRestoreGState", (PyCFunction)CGContextRefObj_CGContextRestoreGState, 1,
     1065    PyDoc_STR("() -> None")},
     1066    {"CGContextScaleCTM", (PyCFunction)CGContextRefObj_CGContextScaleCTM, 1,
     1067    PyDoc_STR("(float sx, float sy) -> None")},
     1068    {"CGContextTranslateCTM", (PyCFunction)CGContextRefObj_CGContextTranslateCTM, 1,
     1069    PyDoc_STR("(float tx, float ty) -> None")},
     1070    {"CGContextRotateCTM", (PyCFunction)CGContextRefObj_CGContextRotateCTM, 1,
     1071    PyDoc_STR("(float angle) -> None")},
     1072    {"CGContextConcatCTM", (PyCFunction)CGContextRefObj_CGContextConcatCTM, 1,
     1073    PyDoc_STR("(CGAffineTransform transform) -> None")},
     1074    {"CGContextGetCTM", (PyCFunction)CGContextRefObj_CGContextGetCTM, 1,
     1075    PyDoc_STR("() -> (CGAffineTransform _rv)")},
     1076    {"CGContextSetLineWidth", (PyCFunction)CGContextRefObj_CGContextSetLineWidth, 1,
     1077    PyDoc_STR("(float width) -> None")},
     1078    {"CGContextSetLineCap", (PyCFunction)CGContextRefObj_CGContextSetLineCap, 1,
     1079    PyDoc_STR("(int cap) -> None")},
     1080    {"CGContextSetLineJoin", (PyCFunction)CGContextRefObj_CGContextSetLineJoin, 1,
     1081    PyDoc_STR("(int join) -> None")},
     1082    {"CGContextSetMiterLimit", (PyCFunction)CGContextRefObj_CGContextSetMiterLimit, 1,
     1083    PyDoc_STR("(float limit) -> None")},
     1084    {"CGContextSetFlatness", (PyCFunction)CGContextRefObj_CGContextSetFlatness, 1,
     1085    PyDoc_STR("(float flatness) -> None")},
     1086    {"CGContextSetAlpha", (PyCFunction)CGContextRefObj_CGContextSetAlpha, 1,
     1087    PyDoc_STR("(float alpha) -> None")},
     1088    {"CGContextBeginPath", (PyCFunction)CGContextRefObj_CGContextBeginPath, 1,
     1089    PyDoc_STR("() -> None")},
     1090    {"CGContextMoveToPoint", (PyCFunction)CGContextRefObj_CGContextMoveToPoint, 1,
     1091    PyDoc_STR("(float x, float y) -> None")},
     1092    {"CGContextAddLineToPoint", (PyCFunction)CGContextRefObj_CGContextAddLineToPoint, 1,
     1093    PyDoc_STR("(float x, float y) -> None")},
     1094    {"CGContextAddCurveToPoint", (PyCFunction)CGContextRefObj_CGContextAddCurveToPoint, 1,
     1095    PyDoc_STR("(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y) -> None")},
     1096    {"CGContextAddQuadCurveToPoint", (PyCFunction)CGContextRefObj_CGContextAddQuadCurveToPoint, 1,
     1097    PyDoc_STR("(float cpx, float cpy, float x, float y) -> None")},
     1098    {"CGContextClosePath", (PyCFunction)CGContextRefObj_CGContextClosePath, 1,
     1099    PyDoc_STR("() -> None")},
     1100    {"CGContextAddRect", (PyCFunction)CGContextRefObj_CGContextAddRect, 1,
     1101    PyDoc_STR("(CGRect rect) -> None")},
     1102    {"CGContextAddArc", (PyCFunction)CGContextRefObj_CGContextAddArc, 1,
     1103    PyDoc_STR("(float x, float y, float radius, float startAngle, float endAngle, int clockwise) -> None")},
     1104    {"CGContextAddArcToPoint", (PyCFunction)CGContextRefObj_CGContextAddArcToPoint, 1,
     1105    PyDoc_STR("(float x1, float y1, float x2, float y2, float radius) -> None")},
     1106    {"CGContextIsPathEmpty", (PyCFunction)CGContextRefObj_CGContextIsPathEmpty, 1,
     1107    PyDoc_STR("() -> (int _rv)")},
     1108    {"CGContextGetPathCurrentPoint", (PyCFunction)CGContextRefObj_CGContextGetPathCurrentPoint, 1,
     1109    PyDoc_STR("() -> (CGPoint _rv)")},
     1110    {"CGContextGetPathBoundingBox", (PyCFunction)CGContextRefObj_CGContextGetPathBoundingBox, 1,
     1111    PyDoc_STR("() -> (CGRect _rv)")},
     1112    {"CGContextDrawPath", (PyCFunction)CGContextRefObj_CGContextDrawPath, 1,
     1113    PyDoc_STR("(int mode) -> None")},
     1114    {"CGContextFillPath", (PyCFunction)CGContextRefObj_CGContextFillPath, 1,
     1115    PyDoc_STR("() -> None")},
     1116    {"CGContextEOFillPath", (PyCFunction)CGContextRefObj_CGContextEOFillPath, 1,
     1117    PyDoc_STR("() -> None")},
     1118    {"CGContextStrokePath", (PyCFunction)CGContextRefObj_CGContextStrokePath, 1,
     1119    PyDoc_STR("() -> None")},
     1120    {"CGContextFillRect", (PyCFunction)CGContextRefObj_CGContextFillRect, 1,
     1121    PyDoc_STR("(CGRect rect) -> None")},
     1122    {"CGContextStrokeRect", (PyCFunction)CGContextRefObj_CGContextStrokeRect, 1,
     1123    PyDoc_STR("(CGRect rect) -> None")},
     1124    {"CGContextStrokeRectWithWidth", (PyCFunction)CGContextRefObj_CGContextStrokeRectWithWidth, 1,
     1125    PyDoc_STR("(CGRect rect, float width) -> None")},
     1126    {"CGContextClearRect", (PyCFunction)CGContextRefObj_CGContextClearRect, 1,
     1127    PyDoc_STR("(CGRect rect) -> None")},
     1128    {"CGContextClip", (PyCFunction)CGContextRefObj_CGContextClip, 1,
     1129    PyDoc_STR("() -> None")},
     1130    {"CGContextEOClip", (PyCFunction)CGContextRefObj_CGContextEOClip, 1,
     1131    PyDoc_STR("() -> None")},
     1132    {"CGContextClipToRect", (PyCFunction)CGContextRefObj_CGContextClipToRect, 1,
     1133    PyDoc_STR("(CGRect rect) -> None")},
     1134    {"CGContextSetGrayFillColor", (PyCFunction)CGContextRefObj_CGContextSetGrayFillColor, 1,
     1135    PyDoc_STR("(float gray, float alpha) -> None")},
     1136    {"CGContextSetGrayStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetGrayStrokeColor, 1,
     1137    PyDoc_STR("(float gray, float alpha) -> None")},
     1138    {"CGContextSetRGBFillColor", (PyCFunction)CGContextRefObj_CGContextSetRGBFillColor, 1,
     1139    PyDoc_STR("(float red, float green, float blue, float alpha) -> None")},
     1140    {"CGContextSetRGBStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetRGBStrokeColor, 1,
     1141    PyDoc_STR("(float red, float green, float blue, float alpha) -> None")},
     1142    {"CGContextSetCMYKFillColor", (PyCFunction)CGContextRefObj_CGContextSetCMYKFillColor, 1,
     1143    PyDoc_STR("(float cyan, float magenta, float yellow, float black, float alpha) -> None")},
     1144    {"CGContextSetCMYKStrokeColor", (PyCFunction)CGContextRefObj_CGContextSetCMYKStrokeColor, 1,
     1145    PyDoc_STR("(float cyan, float magenta, float yellow, float black, float alpha) -> None")},
     1146    {"CGContextGetInterpolationQuality", (PyCFunction)CGContextRefObj_CGContextGetInterpolationQuality, 1,
     1147    PyDoc_STR("() -> (int _rv)")},
     1148    {"CGContextSetInterpolationQuality", (PyCFunction)CGContextRefObj_CGContextSetInterpolationQuality, 1,
     1149    PyDoc_STR("(int quality) -> None")},
     1150    {"CGContextSetCharacterSpacing", (PyCFunction)CGContextRefObj_CGContextSetCharacterSpacing, 1,
     1151    PyDoc_STR("(float spacing) -> None")},
     1152    {"CGContextSetTextPosition", (PyCFunction)CGContextRefObj_CGContextSetTextPosition, 1,
     1153    PyDoc_STR("(float x, float y) -> None")},
     1154    {"CGContextGetTextPosition", (PyCFunction)CGContextRefObj_CGContextGetTextPosition, 1,
     1155    PyDoc_STR("() -> (CGPoint _rv)")},
     1156    {"CGContextSetTextMatrix", (PyCFunction)CGContextRefObj_CGContextSetTextMatrix, 1,
     1157    PyDoc_STR("(CGAffineTransform transform) -> None")},
     1158    {"CGContextGetTextMatrix", (PyCFunction)CGContextRefObj_CGContextGetTextMatrix, 1,
     1159    PyDoc_STR("() -> (CGAffineTransform _rv)")},
     1160    {"CGContextSetTextDrawingMode", (PyCFunction)CGContextRefObj_CGContextSetTextDrawingMode, 1,
     1161    PyDoc_STR("(int mode) -> None")},
     1162    {"CGContextSetFontSize", (PyCFunction)CGContextRefObj_CGContextSetFontSize, 1,
     1163    PyDoc_STR("(float size) -> None")},
     1164    {"CGContextSelectFont", (PyCFunction)CGContextRefObj_CGContextSelectFont, 1,
     1165    PyDoc_STR("(char * name, float size, int textEncoding) -> None")},
     1166    {"CGContextShowText", (PyCFunction)CGContextRefObj_CGContextShowText, 1,
     1167    PyDoc_STR("(Buffer cstring) -> None")},
     1168    {"CGContextShowTextAtPoint", (PyCFunction)CGContextRefObj_CGContextShowTextAtPoint, 1,
     1169    PyDoc_STR("(float x, float y, Buffer cstring) -> None")},
     1170    {"CGContextEndPage", (PyCFunction)CGContextRefObj_CGContextEndPage, 1,
     1171    PyDoc_STR("() -> None")},
     1172    {"CGContextFlush", (PyCFunction)CGContextRefObj_CGContextFlush, 1,
     1173    PyDoc_STR("() -> None")},
     1174    {"CGContextSynchronize", (PyCFunction)CGContextRefObj_CGContextSynchronize, 1,
     1175    PyDoc_STR("() -> None")},
     1176    {"CGContextSetShouldAntialias", (PyCFunction)CGContextRefObj_CGContextSetShouldAntialias, 1,
     1177    PyDoc_STR("(int shouldAntialias) -> None")},
    11781178#ifndef __LP64__
    1179         {"SyncCGContextOriginWithPort", (PyCFunction)CGContextRefObj_SyncCGContextOriginWithPort, 1,
    1180         PyDoc_STR("(CGrafPtr port) -> None")},
    1181         {"ClipCGContextToRegion", (PyCFunction)CGContextRefObj_ClipCGContextToRegion, 1,
    1182         PyDoc_STR("(Rect portRect, RgnHandle region) -> None")},
     1179    {"SyncCGContextOriginWithPort", (PyCFunction)CGContextRefObj_SyncCGContextOriginWithPort, 1,
     1180    PyDoc_STR("(CGrafPtr port) -> None")},
     1181    {"ClipCGContextToRegion", (PyCFunction)CGContextRefObj_ClipCGContextToRegion, 1,
     1182    PyDoc_STR("(Rect portRect, RgnHandle region) -> None")},
    11831183#endif
    1184         {NULL, NULL, 0}
     1184    {NULL, NULL, 0}
    11851185};
    11861186
     
    11991199static PyObject *CGContextRefObj_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)
    12001200{
    1201         PyObject *_self;
    1202         CGContextRef itself;
    1203         char *kw[] = {"itself", 0};
    1204 
    1205         if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CGContextRefObj_Convert, &itself)) return NULL;
    1206         if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
    1207         ((CGContextRefObject *)_self)->ob_itself = itself;
    1208         return _self;
     1201    PyObject *_self;
     1202    CGContextRef itself;
     1203    char *kw[] = {"itself", 0};
     1204
     1205    if (!PyArg_ParseTupleAndKeywords(_args, _kwds, "O&", kw, CGContextRefObj_Convert, &itself)) return NULL;
     1206    if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;
     1207    ((CGContextRefObject *)_self)->ob_itself = itself;
     1208    return _self;
    12091209}
    12101210
     
    12131213
    12141214PyTypeObject CGContextRef_Type = {
    1215         PyObject_HEAD_INIT(NULL)
    1216         0, /*ob_size*/
    1217         "_CG.CGContextRef", /*tp_name*/
    1218         sizeof(CGContextRefObject), /*tp_basicsize*/
    1219         0, /*tp_itemsize*/
    1220         /* methods */
    1221         (destructor) CGContextRefObj_dealloc, /*tp_dealloc*/
    1222         0, /*tp_print*/
    1223         (getattrfunc)0, /*tp_getattr*/
    1224         (setattrfunc)0, /*tp_setattr*/
    1225         (cmpfunc) CGContextRefObj_compare, /*tp_compare*/
    1226         (reprfunc) CGContextRefObj_repr, /*tp_repr*/
    1227         (PyNumberMethods *)0, /* tp_as_number */
    1228         (PySequenceMethods *)0, /* tp_as_sequence */
    1229         (PyMappingMethods *)0, /* tp_as_mapping */
    1230         (hashfunc) CGContextRefObj_hash, /*tp_hash*/
    1231         0, /*tp_call*/
    1232         0, /*tp_str*/
    1233         PyObject_GenericGetAttr, /*tp_getattro*/
    1234         PyObject_GenericSetAttr, /*tp_setattro */
    1235         0, /*tp_as_buffer*/
    1236         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
    1237         0, /*tp_doc*/
    1238         0, /*tp_traverse*/
    1239         0, /*tp_clear*/
    1240         0, /*tp_richcompare*/
    1241         0, /*tp_weaklistoffset*/
    1242         0, /*tp_iter*/
    1243         0, /*tp_iternext*/
    1244         CGContextRefObj_methods, /* tp_methods */
    1245         0, /*tp_members*/
    1246         CGContextRefObj_getsetlist, /*tp_getset*/
    1247         0, /*tp_base*/
    1248         0, /*tp_dict*/
    1249         0, /*tp_descr_get*/
    1250         0, /*tp_descr_set*/
    1251         0, /*tp_dictoffset*/
    1252         CGContextRefObj_tp_init, /* tp_init */
    1253         CGContextRefObj_tp_alloc, /* tp_alloc */
    1254         CGContextRefObj_tp_new, /* tp_new */
    1255         CGContextRefObj_tp_free, /* tp_free */
     1215    PyObject_HEAD_INIT(NULL)
     1216    0, /*ob_size*/
     1217    "_CG.CGContextRef", /*tp_name*/
     1218    sizeof(CGContextRefObject), /*tp_basicsize*/
     1219    0, /*tp_itemsize*/
     1220    /* methods */
     1221    (destructor) CGContextRefObj_dealloc, /*tp_dealloc*/
     1222    0, /*tp_print*/
     1223    (getattrfunc)0, /*tp_getattr*/
     1224    (setattrfunc)0, /*tp_setattr*/
     1225    (cmpfunc) CGContextRefObj_compare, /*tp_compare*/
     1226    (reprfunc) CGContextRefObj_repr, /*tp_repr*/
     1227    (PyNumberMethods *)0, /* tp_as_number */
     1228    (PySequenceMethods *)0, /* tp_as_sequence */
     1229    (PyMappingMethods *)0, /* tp_as_mapping */
     1230    (hashfunc) CGContextRefObj_hash, /*tp_hash*/
     1231    0, /*tp_call*/
     1232    0, /*tp_str*/
     1233    PyObject_GenericGetAttr, /*tp_getattro*/
     1234    PyObject_GenericSetAttr, /*tp_setattro */
     1235    0, /*tp_as_buffer*/
     1236    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
     1237    0, /*tp_doc*/
     1238    0, /*tp_traverse*/
     1239    0, /*tp_clear*/
     1240    0, /*tp_richcompare*/
     1241    0, /*tp_weaklistoffset*/
     1242    0, /*tp_iter*/
     1243    0, /*tp_iternext*/
     1244    CGContextRefObj_methods, /* tp_methods */
     1245    0, /*tp_members*/
     1246    CGContextRefObj_getsetlist, /*tp_getset*/
     1247    0, /*tp_base*/
     1248    0, /*tp_dict*/
     1249    0, /*tp_descr_get*/
     1250    0, /*tp_descr_set*/
     1251    0, /*tp_dictoffset*/
     1252    CGContextRefObj_tp_init, /* tp_init */
     1253    CGContextRefObj_tp_alloc, /* tp_alloc */
     1254    CGContextRefObj_tp_new, /* tp_new */
     1255    CGContextRefObj_tp_free, /* tp_free */
    12561256};
    12571257
     
    12621262static PyObject *CG_CreateCGContextForPort(PyObject *_self, PyObject *_args)
    12631263{
    1264         PyObject *_res = NULL;
    1265         GrafPtr port;
    1266         CGContextRef ctx;
    1267         OSStatus _err;
    1268 
    1269         if (!PyArg_ParseTuple(_args, "O&", GrafObj_Convert, &port))
    1270                 return NULL;
    1271 
    1272         _err = CreateCGContextForPort(port, &ctx);
    1273         if (_err != noErr)
    1274                 if (_err != noErr) return PyMac_Error(_err);
    1275         _res = Py_BuildValue("O&", CGContextRefObj_New, ctx);
    1276         return _res;
     1264    PyObject *_res = NULL;
     1265    GrafPtr port;
     1266    CGContextRef ctx;
     1267    OSStatus _err;
     1268
     1269    if (!PyArg_ParseTuple(_args, "O&", GrafObj_Convert, &port))
     1270        return NULL;
     1271
     1272    _err = CreateCGContextForPort(port, &ctx);
     1273    if (_err != noErr)
     1274        if (_err != noErr) return PyMac_Error(_err);
     1275    _res = Py_BuildValue("O&", CGContextRefObj_New, ctx);
     1276    return _res;
    12771277
    12781278}
     
    12811281static PyMethodDef CG_methods[] = {
    12821282#ifndef __LP64__
    1283         {"CreateCGContextForPort", (PyCFunction)CG_CreateCGContextForPort, 1,
    1284         PyDoc_STR("(CGrafPtr) -> CGContextRef")},
     1283    {"CreateCGContextForPort", (PyCFunction)CG_CreateCGContextForPort, 1,
     1284    PyDoc_STR("(CGrafPtr) -> CGContextRef")},
    12851285#endif
    1286         {NULL, NULL, 0}
     1286    {NULL, NULL, 0}
    12871287};
    12881288
     
    12921292void init_CG(void)
    12931293{
    1294         PyObject *m;
    1295         PyObject *d;
    1296 
    1297 
    1298 
    1299 
    1300         m = Py_InitModule("_CG", CG_methods);
    1301         d = PyModule_GetDict(m);
    1302         CG_Error = PyMac_GetOSErrException();
    1303         if (CG_Error == NULL ||
    1304             PyDict_SetItemString(d, "Error", CG_Error) != 0)
    1305                 return;
    1306         CGContextRef_Type.ob_type = &PyType_Type;
    1307         if (PyType_Ready(&CGContextRef_Type) < 0) return;
    1308         Py_INCREF(&CGContextRef_Type);
    1309         PyModule_AddObject(m, "CGContextRef", (PyObject *)&CGContextRef_Type);
    1310         /* Backward-compatible name */
    1311         Py_INCREF(&CGContextRef_Type);
    1312         PyModule_AddObject(m, "CGContextRefType", (PyObject *)&CGContextRef_Type);
     1294    PyObject *m;
     1295    PyObject *d;
     1296
     1297
     1298
     1299
     1300    m = Py_InitModule("_CG", CG_methods);
     1301    d = PyModule_GetDict(m);
     1302    CG_Error = PyMac_GetOSErrException();
     1303    if (CG_Error == NULL ||
     1304        PyDict_SetItemString(d, "Error", CG_Error) != 0)
     1305        return;
     1306    CGContextRef_Type.ob_type = &PyType_Type;
     1307    if (PyType_Ready(&CGContextRef_Type) < 0) return;
     1308    Py_INCREF(&CGContextRef_Type);
     1309    PyModule_AddObject(m, "CGContextRef", (PyObject *)&CGContextRef_Type);
     1310    /* Backward-compatible name */
     1311    Py_INCREF(&CGContextRef_Type);
     1312    PyModule_AddObject(m, "CGContextRefType", (PyObject *)&CGContextRef_Type);
    13131313}
    13141314
Note: See TracChangeset for help on using the changeset viewer.