home *** CD-ROM | disk | FTP | other *** search
- #define MAX_NB_OFILES 64
-
- int self_refnum;
-
-
- void mem_err()
- { UseResFile( self_refnum );
- ParamText( "\pMemory full", "\p", "\p", "\p" );
- StopAlert( 128, 0L );
- ExitToShell();
- }
-
-
- void file_not_found_err( str )
- unsigned char *str;
- { UseResFile( self_refnum );
- ParamText( "\pFile \"", str, "\p\" not found", "\p" );
- StopAlert( 128, 0L );
- ExitToShell();
- }
-
-
- void too_many_ofiles_err()
- { UseResFile( self_refnum );
- ParamText( "\pToo many object files (limit is 64)", "\p", "\p", "\p" );
- StopAlert( 128, 0L );
- ExitToShell();
- }
-
-
- void io_err()
- { UseResFile( self_refnum );
- ParamText( "\pIO error", "\p", "\p", "\p" );
- StopAlert( 128, 0L );
- ExitToShell();
- }
-
-
- void link_script_io_err()
- { UseResFile( self_refnum );
- ParamText( "\pIO error while reading link script", "\p", "\p", "\p" );
- StopAlert( 128, 0L );
- ExitToShell();
- }
-
-
- void res_err()
- { UseResFile( self_refnum );
- ParamText( "\pResource error", "\p", "\p", "\p" );
- StopAlert( 128, 0L );
- ExitToShell();
- }
-
-
- void syntax_err()
- { UseResFile( self_refnum );
- ParamText( "\pLink script syntax error", "\p", "\p", "\p" );
- StopAlert( 128, 0L );
- ExitToShell();
- }
-
-
- unsigned char *p_to_p( p1 )
- unsigned char *p1;
- { int len = *p1++;
- unsigned char *str = (unsigned char *)NewPtr( (long)len+1 );
- unsigned char *p2 = str;
- if (str == NULL) mem_err();
- *p2++ = len;
- while (len>0) { *p2++ = *p1++; len--; }
- return str;
- }
-
-
- #define FontNum 4
- #define FontSize 9
- #define FontH 11
- #define FontW 6
- #define Border 3
-
-
- WindowPtr wind;
-
-
- void open_wind()
- { Rect bounds;
- int width = 40 /*(screenBits.bounds.right-SBarWidth-2*Border-11)/FontW*/;
- int height = (screenBits.bounds.bottom-2*Border-48)/FontH;
-
- bounds.left = 0;
- bounds.right = bounds.left + width*FontW + 2*Border;
- bounds.top = 43;
- bounds.bottom = bounds.top + height*FontH + 2*Border;
-
- wind = NewWindow( NULL, &bounds, "\pMacGambit Linker", TRUE,
- documentProc, (WindowPtr)-1L, TRUE, 0L );
- if (wind == NULL) mem_err();
-
- SetPort( wind );
- TextFont( FontNum );
- TextSize( FontSize );
- }
-
-
- void gotoxy( x, y )
- int x, y;
- { SetPort( wind );
- MoveTo( x*FontW + Border, y*FontH + Border + FontH );
- }
-
-
- int done;
-
- pascal int mydlog( item, dlog )
- int item;
- DialogPtr dlog;
- { done = (item == 2);
- return item;
- }
-
-
- int current_volume = 0;
-
- int open_file( filename, vol, for_output, res_fork, file_type, file_creator )
- Str255 filename;
- int vol;
- int for_output;
- int res_fork;
- ResType file_type, file_creator;
- { ioParam pb;
- fileParam fp;
- int refnum;
- int len = filename[0];
-
- pb.ioNamePtr = filename;
- pb.ioVRefNum = vol;
- pb.ioVersNum = 0;
- pb.ioPermssn = (for_output) ? fsWrPerm : fsRdPerm;
- pb.ioMisc = 0;
-
- if (for_output)
- { asm
- { lea pb,a0
- _PBCreate
- }
- if ((pb.ioResult != noErr) && (pb.ioResult != dupFNErr)) return -1;
- }
-
- if (res_fork)
- asm
- { lea pb,a0
- _PBOpenRF
- }
- else
- asm
- { lea pb,a0
- _PBOpen
- }
- if (pb.ioResult != noErr)
- { if (for_output)
- { asm
- { lea pb,a0
- _PBDelete
- }
- return -1;
- }
- if ((pb.ioResult == dirNFErr) || (pb.ioResult == fnfErr)) return -2;
- return -1;
- }
- refnum = pb.ioRefNum;
-
- if (for_output)
- asm
- { lea pb,a0
- _PBSetEOF
- }
-
- if (for_output)
- { fp.ioNamePtr = filename;
- fp.ioVRefNum = vol;
- fp.ioFVersNum = 0;
- fp.ioFDirIndex = 0;
- asm
- { lea fp,a0
- _PBGetFInfo
- bmi.s @1
- }
- fp.ioFlFndrInfo.fdType = file_type;
- fp.ioFlFndrInfo.fdCreator = file_creator;
- asm
- { lea fp,a0
- _PBSetFInfo
- @1
- }
- }
-
- return refnum;
- }
-
- struct file {
- unsigned char *name;
- int vrefnum;
- };
-
- int nb_ofiles = 0;
- struct file ofile[MAX_NB_OFILES+1];
- struct file library;
- struct file link_script;
-
- int link_script_refnum = -1;
-
- unsigned char *appl_name;
- int appl_refnum;
- int first_unused_id;
-
-
- void link_library()
- { Handle h;
-
- /* copy library file to application file and set finder info */
- int refnum_a, refnum_l;
- long len, count;
- char *mem;
-
- len = library.name[0];
- if ((len >= 5) &&
- (library.name[len-4] == '.') && (library.name[len-3] == 'r') &&
- (library.name[len-2] == 's') && (library.name[len-1] == 'r') &&
- (library.name[len] == 'c'))
- refnum_a = open_file( appl_name, current_volume, 1, 1, 'gamL', 'gamL' );
- else
- refnum_a = open_file( appl_name, current_volume, 1, 1, 'APPL', '????' );
- if (refnum_a <= -1) io_err();
- refnum_l = open_file( library.name, library.vrefnum, 0, 1, '????', '????' );
- if (refnum_l == -2) { FSClose( refnum_a ); file_not_found_err( library.name ); }
- if (refnum_l <= -1) { FSClose( refnum_a ); io_err(); }
-
- if (GetEOF( refnum_l, &len ) != noErr)
- { FSClose( refnum_a ); FSClose( refnum_l ); io_err(); }
-
- mem = NewPtr( len );
- if (mem == NULL)
- { FSClose( refnum_a ); FSClose( refnum_l ); mem_err(); }
-
- count = len;
- if ((FSRead( refnum_l, &count, mem ) != noErr) || (count != len))
- { FSClose( refnum_a ); FSClose( refnum_l ); io_err(); }
-
- if ((FSWrite( refnum_a, &count, mem ) != noErr) || (count != len))
- { FSClose( refnum_a ); FSClose( refnum_l ); io_err(); }
-
- DisposPtr( mem );
-
- FSClose( refnum_a );
- FSClose( refnum_l );
-
- /* open application file's resource fork */
- gotoxy( 0, 0 ); DrawChar( '-' );
-
- appl_refnum = OpenRFPerm( appl_name, current_volume, 0 );
- if (ResError() != noErr) res_err();
- UseResFile( appl_refnum );
- first_unused_id = 127;
- do
- { first_unused_id++;
- SetResLoad( FALSE );
- h = GetResource( 'gamO', first_unused_id );
- SetResLoad( TRUE );
- } while (h != NULL);
- UseResFile( self_refnum );
-
- if ((first_unused_id - 127) + nb_ofiles > MAX_NB_OFILES)
- too_many_ofiles_err();
-
- gotoxy( 0, 0 ); DrawChar( 0xa5 );
- }
-
-
- void link_ofiles()
- { int i;
- for (i=0; i<nb_ofiles; i++)
- { Handle h;
- int refnum;
- long len, count;
- gotoxy( 0, i+1 ); DrawChar( '-' );
-
- refnum = open_file( ofile[i].name, ofile[i].vrefnum, 0, 0, '????', '????' );
- if (refnum == -2) file_not_found_err( ofile[i].name );
- if (refnum <= -1) io_err();
-
- if (GetEOF( refnum, &len ) != noErr)
- { FSClose( refnum ); io_err(); }
-
- h = NewHandle( len );
- if (h == NULL)
- { FSClose( refnum ); mem_err(); }
-
- count = len;
- if ((FSRead( refnum, &count, *h ) != noErr) || (count != len))
- { FSClose( refnum ); io_err(); }
-
- FSClose( refnum );
-
- UseResFile( appl_refnum );
- AddResource( h, 'gamO', first_unused_id+i, 0L );
- if (ResError() != noErr) res_err();
- WriteResource( h );
- if (ResError() != noErr) res_err();
- ReleaseResource( h );
- UseResFile( self_refnum );
-
- gotoxy( 0, i+1 ); DrawChar( 0xa5 );
- }
- }
-
-
- void link_end()
- { CloseResFile( appl_refnum );
- if (ResError() != noErr) res_err();
- RsrcZoneInit();
- ExitToShell();
- }
-
-
- int read_link_script_line( f )
- struct file *f;
- {
- Str255 name;
- int n = 0, err;
- long count;
- char c;
- while (1)
- {
- count = 1;
- err = FSRead( link_script_refnum, &count, &c );
- if (err != noErr)
- { FSClose( link_script_refnum );
- if (err == eofErr) break; else link_script_io_err();
- }
- if (c == '\r') break;
- n++;
- name[n] = c;
- }
- name[0] = n;
- f->name = p_to_p( name );
- f->vrefnum = current_volume;
- return (err == eofErr);
- }
-
-
- int main( argc, argv )
- int argc;
- char *argv[];
- { int i, eof;
-
- InitGraf( &thePort );
- InitFonts();
- FlushEvents( everyEvent, 0 );
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs( 0L );
- InitCursor();
-
- self_refnum = CurResFile();
-
- open_wind();
-
- i = 0;
- { int msg, count;
- CountAppFiles( &msg, &count );
- if (msg == appOpen)
- { for (i=1; i<=count; i++)
- { AppFile file_info;
- GetAppFiles( i, &file_info );
- if (file_info.fType == 'TEXT')
- { ClrAppFiles( i );
- link_script.name = p_to_p( file_info.fName );
- link_script.vrefnum = file_info.vRefNum;
- current_volume = file_info.vRefNum;
- goto found_link_script;
- }
- else if (file_info.fType == 'gamL')
- { ClrAppFiles( i );
- library.name = p_to_p( file_info.fName );
- library.vrefnum = file_info.vRefNum;
- current_volume = file_info.vRefNum;
- goto found_lib;
- }
- }
- i = 0;
- }
- }
-
- { SFTypeList type;
- Point where = { 70, 155 };
- SFReply reply;
- type[0] = 'TEXT';
- type[1] = 'gamL';
- SFPGetFile( where, "\pSelect link script or library to link", 0L, 2, type, &mydlog, &reply, 128, 0L );
- if (!reply.good) return 0;
- if (reply.fType == 'TEXT')
- { link_script.name = p_to_p( reply.fName );
- link_script.vrefnum = reply.vRefNum;
- goto found_link_script;
- }
- else
- { library.name = p_to_p( reply.fName );
- library.vrefnum = reply.vRefNum;
- goto found_lib;
- }
- }
-
- found_link_script:
-
- link_script_refnum = open_file( link_script.name, link_script.vrefnum, 0, 0, '????', '????' );
- if (link_script_refnum <= -1) io_err();
-
- if (read_link_script_line( &library )) syntax_err();
-
- found_lib:
-
- gotoxy( 1, 0 );
- DrawString( library.name );
- DrawString( "\p (Library)" );
-
- do
- {
- if (link_script_refnum != -1)
- { eof = read_link_script_line( &ofile[nb_ofiles] );
- done = (ofile[nb_ofiles].name[0] == 0);
- if (!done)
- { nb_ofiles++;
- gotoxy( 1, nb_ofiles );
- DrawString( ofile[nb_ofiles-1].name );
- }
- else
- if (nb_ofiles == 0) syntax_err();
- }
- else
- { SFTypeList type;
- Point where = { 70, 155 };
- SFReply reply;
- type[0] = 'gamO';
- SFPGetFile( where, "\pSelect object file to link", 0L, 1, type, &mydlog, &reply, ((nb_ofiles)?129:128), 0L );
- if (!done)
- { if (!reply.good) return 0;
- ofile[nb_ofiles].name = p_to_p( reply.fName );
- ofile[nb_ofiles].vrefnum = reply.vRefNum;
- nb_ofiles++;
- gotoxy( 1, nb_ofiles );
- DrawString( ofile[nb_ofiles-1].name );
- }
- }
- } while ((!done) && (nb_ofiles <= MAX_NB_OFILES));
-
- if (nb_ofiles > MAX_NB_OFILES) too_many_ofiles_err();
-
- if ((link_script_refnum != -1) && !eof)
- { struct file f;
- if (read_link_script_line( &f )) syntax_err();
- appl_name = f.name;
- if (appl_name[0] == 0) syntax_err();
- }
- else
- { int len;
- appl_name = p_to_p( ofile[nb_ofiles-1].name );
- len = appl_name[0];
- if ((len >= 2) &&
- (appl_name[len-1] == '.') && (appl_name[len] == 'O'))
- { int i = 1, j = len;
- while ((j > 0) && (appl_name[j] != ':')) j--;
- appl_name[0] = (len-2)-j;
- j++;
- while (j <= len) appl_name[i++] = appl_name[j++];
- }
- else
- appl_name = "\pApplication";
- }
-
- link_library();
-
- link_ofiles();
-
- link_end();
- }
-