blob: e94e643c06414779c07dd9f43870bebc26e1530f [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* Frontend for vbcc */
2/* (c) in 1995-2016 by Volker Barthelmann */
3/* #define AMIGA for Amiga version */
4/* #define ATARI for Atari version */
5
6#include <stdlib.h>
7#include <string.h>
8#include <stdio.h>
9
10#ifdef AMIGA
11#pragma amiga-align
12#ifdef __amigaos4__
13#include <dos/anchorpath.h>
14#else
15#include <dos/dosasl.h>
16#endif
17#include <dos/dosextens.h>
18#include <dos/dostags.h>
19#include <exec/libraries.h>
20#include <proto/dos.h>
21#pragma default-align
22
23#ifndef EXIT_FAILURE
24#define EXIT_FAILURE 20
25#endif
26#ifndef EXIT_SUCCESS
27#define EXIT_SUCCESS 0
28#endif
29
30#if !defined(__amigaos4__) && !defined(__MORPHOS__)
31extern struct DosLibrary *DOSBase;
32#endif
33
34/* Must be 32bit-aligned - I know it will be if compiled with vbcc. */
35struct FileInfoBlock fib;
36#endif
37
38struct NameList{
39 struct NameList *next;
40 char *obj;
41} *first_obj=0,*last_obj=0,*first_scratch=0,*last_scratch=0;
42
43/* Limit fuer Laenge der Namen (wegen Wildcards) */
44#define NAMEBUF 1000 /* MUST BE >= ~TMPNAM_L+7 */
45#define USERLIBS 1000
46
47/* Ab dieser Laenge werden Objektfiles nicht direkt uebergeben, */
48/* sondern aus einem File an den Linker uebergeben */
49#ifdef AMIGA
50int MAXCLEN=500;
51#else
52int MAXCLEN=32000;
53#endif
54
55#define WPO 16384
56#define CROSSMODULE 8192
57#define SCHEDULER 4096
58#define NOTMPFILE 2048
59#define OUTPUTSET 1024
60#define NOSTDLIB 512
61#define VERBOSE 256
62#define VERYVERBOSE 128
63#define KEEPSCRATCH 64
64
65#define PPSRC 1
66#define CCSRC 2
67#define SCSRC 3
68#define ASSRC 4
69#define OBJ 5
70
71char *vbccenv;
72char empty[]="";
73/* Namen der einzelnen Phasen */
74char *ppname=empty,*ccname=empty,*asname=empty,*ldname=empty,*l2name=empty;
75char *rmname=empty,*scname=empty;
76/* dasselbe fuer VERBOSE */
77char *ppv=empty,*ccv=empty,*asv=empty,*ldv=empty,*l2v=empty;
78char *rmv=empty,*scv=empty;
79
80/* Linker-Commandfile */
81char *cf="@%s";
82char *nodb="";
83char *staticflag="";
84char *ul="-l%s";
85
86#if defined(AMIGA)
87const char *config_name="vc.config";
88const char *search_dirs[]={"","ENV:","VBCC:config/","VBCC:"};
89#elif defined(_WIN32) || defined(MSDOS)
90const char *config_name="vc.cfg";
91const char *search_dirs[]={"","%VCCFG%\\"};
92#elif defined(ATARI)
93const char *config_name="vc.cfg";
94const char *search_dirs[]={"","C:\\"};
95#else
96const char *config_name="vc.config";
97const char *search_dirs[]={"","~/","/etc/"};
98#endif
99
100/* String fuer die Default libraries */
101char userlibs[USERLIBS];
102char *nomem="Not enough memory!\n";
103
104char *destname="a.out";
105char namebuf[NAMEBUF+1],namebuf2[NAMEBUF+1];
106char *oldfile;
107
108char *cmfiles,*cmoutput,*cmname;
109#if defined(AMIGA)||defined(_WIN32)||defined(MSDOS)
110#undef USECMDFILE
111#define USECMDFILE 1
112#endif
113#ifdef USECMDFILE
114FILE *cmdfile;
115#endif
116int final;
117int compressor;
118
119char *config;
120char **confp;
121
122char *command,*options,*linkcmd,*objects,*libs,*ppopts;
123#ifdef AMIGA
124struct AnchorPath *ap;
125#endif
126
127int linklen=10,flags=0;
128
129#if defined(MSDOS)||defined(ATARI)
130char *tmpnam(char *p)
131{
132 static int c=1675;
133 static char tmp[NAMEBUF];
134 char *env;
135
136 env=getenv("TEMP");
137 if(!env) env=".";
138 if(!p) p=tmp;
139 snprintf(p,NAMEBUF,"%s\\vbcc%04x",env,++c);
140 return p;
141}
142#endif
143
144static void free_namelist(struct NameList *p)
145{
146 struct NameList *m;
147 while(p){
148 m=p->next;
149 if(flags&VERYVERBOSE){
150 puts("free p->obj");
151 if(!p->obj) puts("IS ZERO!!"); else puts(p->obj);
152 }
153 free((void *)p->obj);
154 if(flags&VERYVERBOSE){puts("free p"); if(!p) puts("IS ZERO!!");}
155 free((void *)p);
156 p=m;
157 }
158}
159
160static void raus(int rc)
161{
162 if(confp) free(confp);
163 if(config) free(config);
164 if(objects) free(objects);
165 if(libs) free(libs);
166 if(command) free(command);
167 if(ppopts) free(ppopts);
168 if(options) free(options);
169 if(linkcmd) free(linkcmd);
170#ifdef AMIGA
171 if(ap)
172#ifdef __amigaos4__
173 FreeDosObject(DOS_ANCHORPATH,ap);
174#else
175 free(ap);
176#endif
177#endif
178 free_namelist(first_obj);
179 free_namelist(first_scratch);
180 exit(rc);
181}
182
183#ifdef NO_LONGER_NEEDED
184/* Launch command from "$VBCC\bin\", when no absolute path was specified. */
185static int runcmd(char *cmd)
186{
187 char *p;
188
189 for(p=cmd;*p!=0&&*p>' ';p++){
190 if(*p==':') /* absolute path */
191 goto do_cmd;
192 }
193 if(vbccenv){
194 /* prepend "$VBCC\bin\" in front of our command */
195 int len=strlen(vbccenv);
196 if(vbccenv[len-1]=='\\') len--;
197 memmove(cmd+len+5,cmd,strlen(cmd)+1);
198 memcpy(cmd,vbccenv,len);
199 memcpy(cmd+len,"\\bin\\",5);
200 }
201do_cmd:
202 return system(cmd);
203}
204#else
205#define runcmd(c) system(c)
206#endif
207
208static void del_scratch(struct NameList *p)
209{
210 while(p){
211 sprintf(command,rmname,p->obj);
212 if(flags&VERBOSE) printf("%s\n",command);
213 if(runcmd(command)){printf("%s failed\n",command);raus(EXIT_FAILURE);}
214 p=p->next;
215 }
216}
217
218static void add_name(char *obj,struct NameList **first,struct NameList **last)
219{
220 struct NameList *new;
221 if(flags&VERYVERBOSE) printf("add_name: %s\n",obj);
222 if(!(new=malloc(sizeof(struct NameList))))
223 {printf(nomem);raus(EXIT_FAILURE);}
224 if(!(new->obj=malloc(strlen(obj)+1)))
225 {free((void *)new);printf(nomem);raus(EXIT_FAILURE);}
226 if(first==&first_obj) linklen+=strlen(obj)+1;
227 strcpy(new->obj,obj);
228 new->next=0;
229 if(!*first){
230 *first=*last=new;
231 }else{
232 (*last)->next=new;*last=new;
233 }
234}
235
236static int read_config(const char *cfg_name)
237{
238 int i,count; long size;
239 char *p,*name;
240 FILE *file=0;
241 for(i=0;i<sizeof(search_dirs)/sizeof(search_dirs[0]);i++){
242 name=malloc(strlen(search_dirs[i])+strlen(cfg_name)+1);
243 if(!name) {printf(nomem);raus(EXIT_FAILURE);}
244 strcpy(name,search_dirs[i]);
245 strcat(name,cfg_name);
246 file=fopen(name,"r");
247 free(name);
248 if(file) break;
249 }
250 if(!file){
251 if(p=vbccenv){
252 name=malloc(strlen(p)+strlen(cfg_name)+20);
253 if(!name){printf(nomem);raus(EXIT_FAILURE);}
254 strcpy(name,p);
255#if defined(_WIN32)||defined(MSDOS)||defined(ATARI)
256 strcat(name,"\\config\\");
257 strcat(name,cfg_name);
258#elif defined(AMIGA)
259 AddPart(name,"config",strlen(p)+strlen(cfg_name)+20);
260 AddPart(name,(STRPTR)cfg_name,strlen(p)+strlen(cfg_name)+20);
261#else
262 strcat(name,"/config/");
263 strcat(name,cfg_name);
264#endif
265 file=fopen(name,"r");
266 free(name);
267 }
268 }
269 if(!file) {puts("No config file!");raus(EXIT_FAILURE);}
270 if(fseek(file,0,SEEK_END)) return 0;
271 size=ftell(file);
272 if(fseek(file,0,SEEK_SET)) return 0;
273 config=malloc(size+1);
274 if(!config){printf(nomem);raus(EXIT_FAILURE);}
275 size=fread(config,1,size,file);
276 fclose(file);
277 count=0;p=config;
278 while(p<config+size&&*p){
279 count++;
280 while(p<config+size&&*p!='\n') p++;
281 if(*p=='\n') *p++=0;
282 }
283 config[size]=0;
284 confp=malloc(count*sizeof(char *));
285 for(p=config,i=0;i<count;i++){
286 confp[i]=p;
287 while(*p) p++;
288 p++;
289 }
290 return count;
291}
292
293static int typ(char *fp)
294{
295 char *p=strrchr(fp,'.');
296 if(p&&(!strcmp(p,".c")||!strcmp(p,".C"))) return ppname==empty?CCSRC:PPSRC;
297 if(p&&!strcmp(p,".i")) return CCSRC;
298 if(p&&(!strcmp(p,".s")||!strcmp(p,".S")||!strcmp(p,".asm"))) return ASSRC;
299 if(p&&!strcmp(p,".scs")) return SCSRC;
300 if(!p||!strcmp(p,".o")||!strcmp(p,".obj")){
301 FILE *f;
302 if(f=fopen(fp,"r")){
303 if(fgetc(f)==0&&fgetc(f)=='V'&&fgetc(f)=='B'&&fgetc(f)=='C'&&fgetc(f)=='C'){
304 fclose(f);
305 return CCSRC;
306 }
307 fclose(f);
308 }
309 return OBJ;
310 }
311 return OBJ;
312}
313
314static char *add_suffix(char *s,char *suffix)
315{
316 static char str[NAMEBUF+3],*p;
317 if(strlen(s)+strlen(suffix)>NAMEBUF){printf("string too long\n");raus(EXIT_FAILURE);}
318 if(s!=str) strcpy(str,s);
319 p=strrchr(str,'.');
320 if(!p) p=str+strlen(s);
321 if(!p||p==str||(p==str+1&&str[0]=='\"')) p=str+strlen(s);
322 strcpy(p,suffix);
323 strcat(p,"\"");
324 return str;
325}
326
327#if defined(_WIN32)||defined(MSDOS)||defined(ATARI)||defined(AMIGA)
328static char *convert_path(char *path)
329{
330 char c,*p,*newpath;
331 newpath=p=malloc(strlen(path)+1);
332 while(c=*path++){
333#ifdef AMIGA
334 if(c=='.'){
335 if(*path=='/') continue;
336 if(*path=='.'&&*(path+1)=='/'){
337 path++;
338 continue;
339 }
340 }
341#else
342 if(c=='/') c='\\';
343#endif
344 *p++=c;
345 }
346 *p=0;
347 return newpath;
348}
349#else
350#define convert_path(p) (p)
351#endif
352
353int main(int argc,char *argv[])
354{
355 int tfl,i,len=10,pm,count,db=0,staticmode=0,deps=0;
356 char *parm;
357 long opt=1;
358 int rc=EXIT_SUCCESS;
359
360 for(i=1;i<argc;i++){
361 if(argv[i][0]=='+'){
362 config_name=argv[i]+1;
363 argv[i][0]=0;
364 break;
365 }
366 }
367 vbccenv=getenv("VBCC");
368 count=read_config(config_name);
369#ifdef AMIGA
370#if !defined(__amigaos4__) && !defined(__MORPHOS__)
371 if(pm=DOSBase->dl_lib.lib_Version>=36)
372#else
373 if(pm=1)
374#endif
375 {
376#ifdef __amigaos4__
377 if(!(ap=(struct AnchorPath *)AllocDosObjectTags(DOS_ANCHORPATH,
378 ADO_Strlen,NAMEBUF,
379 TAG_DONE)))
380 pm=0;
381#else
382 if(ap=(struct AnchorPath *)calloc(sizeof(struct AnchorPath)+NAMEBUF,1))
383 {ap->ap_Strlen=NAMEBUF;ap->ap_BreakBits=0;} else pm=0;
384#endif
385 }
386#endif
387 for(i=1;i<argc+count;i++){
388 if(i<argc) parm=argv[i]; else parm=confp[i-argc];
389 if(!strncmp(parm,"-ul=",4)){ul=parm+4;*parm=0;}
390 }
391 for(i=1;i<argc+count;i++){
392 if(i<argc) parm=argv[i]; else parm=confp[i-argc];
393/* printf("Parameter %d=%s\n",i,parm);*/
394 if(!strncmp(parm,"-rmcfg-",7)){
395 int j,len=strlen(parm);
396 for(j=0;j<count;j++)
397 if(!strncmp(confp[j],parm+6,len-6)) confp[j][0]=0;
398 parm[0]=0;
399 continue;
400 }
401 if(!strncmp(parm,"-ldnodb=",8)){nodb=parm+8;*parm=0;}
402 if(!strncmp(parm,"-ldstatic=",10)){staticflag=parm+10;*parm=0;}
403 if(!strcmp(parm,"-g")) db=1;
404 if(!strcmp(parm,"-deps")) deps=1;
405 if(!strcmp(parm,"-static")){staticmode=1;*parm=0;}
406 if(!strncmp(parm,"-ml=",4)){MAXCLEN=atoi(parm+4);*parm=0;}
407 if(!strncmp(parm,"-pp=",4)){ppname=parm+4;*parm=0;}
408 if(!strncmp(parm,"-cc=",4)){ccname=parm+4;*parm=0;}
409 if(!strncmp(parm,"-as=",4)){asname=parm+4;*parm=0;}
410 if(!strncmp(parm,"-ld=",4)){ldname=parm+4;*parm=0;}
411 if(!strncmp(parm,"-l2=",4)){l2name=parm+4;*parm=0;}
412 if(!strncmp(parm,"-rm=",4)){rmname=parm+4;*parm=0;}
413 if(!strncmp(parm,"-ppv=",5)){ppv=parm+5;*parm=0;}
414 if(!strncmp(parm,"-ccv=",5)){ccv=parm+5;*parm=0;}
415 if(!strncmp(parm,"-asv=",5)){asv=parm+5;*parm=0;}
416 if(!strncmp(parm,"-ldv=",5)){ldv=parm+5;*parm=0;}
417 if(!strncmp(parm,"-l2v=",5)){l2v=parm+5;*parm=0;}
418 if(!strncmp(parm,"-rmv=",5)){rmv=parm+5;*parm=0;}
419 if(!strncmp(parm,"-cf=",4)){cf=parm+4;*parm=0;}
420 if(!strncmp(parm,"-isc=",5)){scname=parm+5;*parm=0;}
421 if(!strncmp(parm,"-iscv=",6)){scv=parm+6;*parm=0;}
422 /* TODO: we re-use scheduler for compressor */
423 if(!strncmp(parm,"-cpr=",5)){scname=parm+5;*parm=0;compressor=1;}
424 if(!strncmp(parm,"-cprv=",6)){scv=parm+6;*parm=0;compressor=1;}
425 if(!strcmp(parm,"-schedule")) {flags|=SCHEDULER;*parm=0;}
426 if(!strcmp(parm,"-notmpfile")) {flags|=NOTMPFILE;*parm=0;}
427 /*if(!strcmp(parm,"-E")) {flags|=CCSRC;*parm=0;}*/
428 if(!strcmp(parm,"-S")) {flags|=ASSRC;*parm=0;}
429 if(!strcmp(parm,"-SCS")) {flags|=SCSRC;*parm=0;}
430 if(!strcmp(parm,"-c")) {flags|=OBJ;*parm=0;}
431 if(!strcmp(parm,"-v")) {flags|=VERBOSE;*parm=0;}
432 if(!strcmp(parm,"-h")) {flags|=VERBOSE;*parm=0;}
433 if(!strcmp(parm,"-k")) {flags|=KEEPSCRATCH;*parm=0;}
434 if(!strcmp(parm,"-vv")) {flags|=VERBOSE|VERYVERBOSE;*parm=0;}
435 if(!strcmp(parm,"-nostdlib")) {flags|=NOSTDLIB;*parm=0;}
436 if(parm[0] == ';') {*parm=0;}
437 if(!strncmp(parm,"-O",2)){
438 static int had_opt;
439 if(had_opt){
440 puts("Optimization flags specified multiple times");
441 exit(EXIT_FAILURE);
442 }
443 had_opt=1;
444 if(parm[2]=='0') opt=0;
445 else if(parm[2]=='1'||parm[2]==0) opt=991;
446 else if(parm[2]=='2') {opt=1023;flags|=SCHEDULER;}
447 else if(parm[2]=='3') {opt=~0;flags|=(SCHEDULER|CROSSMODULE);}
448 else if(parm[2]>='4'&&parm[2]<='9') {opt=~0;flags|=(SCHEDULER|WPO);}
449
450 else if(parm[2]=='=') opt=atoi(&parm[3]);
451 *parm=0;
452 }
453 if(!strcmp(parm,"-o")&&i<argc-1) {
454 *argv[i++]=0;destname=convert_path(argv[i]);
455 flags|=OUTPUTSET;argv[i]="";continue;
456 }
457 if(!strncmp(parm,"-o=",3)){
458 destname=convert_path(parm+3);
459 flags|=OUTPUTSET;*parm=0;continue;
460 }
461 if(parm[0]=='-'&&parm[1]=='l'){
462 size_t l=strlen(userlibs);
463 if((l+strlen(parm)-2+strlen(ul)+1)>=USERLIBS){puts("Userlibs too long");exit(EXIT_FAILURE);}
464 userlibs[l]=' ';
465 sprintf(userlibs+l+1,ul,parm+2);
466 *parm=0;continue;
467 }
468 if(parm[0]=='-'&&parm[1]=='L'){
469 size_t l=strlen(userlibs);
470 if((l+strlen(parm)+1)>=USERLIBS){puts("Userlibs too long");exit(EXIT_FAILURE);}
471 userlibs[l]=' ';
472 sprintf(userlibs+l+1,"%s",parm);
473 *parm=0;continue;
474 }
475 len+=strlen(parm)+10;
476#ifdef ATARI
477 if(vbccenv)
478 len+=strlen(vbccenv)+5;
479#endif
480 }
481 if(!db&&*nodb){
482 if(strlen(userlibs)+2+strlen(nodb)>=USERLIBS){
483 puts("Userlibs too long");exit(EXIT_FAILURE);
484 }
485 strcat(userlibs," ");
486 strcat(userlibs,nodb);
487 }
488 if(staticmode&&*staticflag){
489 size_t ulen=strlen(userlibs);
490 size_t slen=strlen(staticflag);
491 if(ulen+2+slen>=USERLIBS){
492 puts("Userlibs too long");exit(EXIT_FAILURE);
493 }
494 memmove(userlibs+slen+1,userlibs,ulen+1);
495 memcpy(userlibs,staticflag,slen);
496 userlibs[slen]=' ';
497 }
498 if(flags&VERBOSE){
499 printf("vc frontend for vbcc (c) in 1995-2020 by Volker Barthelmann\n");
500#ifdef SPECIAL_COPYRIGHT
501 printf("%s\n",SPECIAL_COPYRIGHT);
502#endif
503 }
504 if(!(flags&7)) flags|=OBJ+1;
505 tfl=flags&7;
506 if((flags&WPO)&&tfl!=OBJ){
507 flags&=~WPO;
508 flags|=CROSSMODULE;
509 }
510 if(scname==empty) flags&=~SCHEDULER;
511 if(flags&VERYVERBOSE){
512 ppname=ppv;ccname=ccv;asname=asv;ldname=ldv;
513 rmname=rmv;l2name=l2v;scname=scv;
514 }
515 if(flags&NOSTDLIB){ldname=l2name;}
516 /* Nummer sicher... */
517 len+=strlen(ppname)+strlen(ccname)+strlen(asname)+
518 strlen(rmname)+strlen(scname)+strlen(userlibs)+NAMEBUF+100;
519 if(!(command=malloc(len))){printf(nomem);raus(EXIT_FAILURE);}
520 if(!(oldfile=malloc(len))){printf(nomem);raus(EXIT_FAILURE);}
521 if(!(options=malloc(len))){printf(nomem);raus(EXIT_FAILURE);}
522 if(!(ppopts=malloc(len))){printf(nomem);raus(EXIT_FAILURE);}
523 *options=0;*ppopts=0;
524 for(i=1;i<argc+count;i++){
525 if(i<argc) parm=argv[i]; else parm=confp[i-argc];
526 if(*parm=='-'){
527 if(ppname==empty||(parm[1]!='D'&&parm[1]!='I'&&parm[1]!='+')){
528 strcat(options,parm);strcat(options," ");
529 }else{
530 strcat(ppopts,parm);strcat(ppopts," ");
531 }
532 }
533 }
534 if(flags&VERYVERBOSE) printf("flags=%d opt=%ld len=%d\n",flags,opt,len);
535 namebuf[0]='\"'; namebuf2[0]='\"';
536 for(i=1;i<argc+count+((flags&CROSSMODULE)!=0);i++){
537 int t,j;char *file;
538#ifdef AMIGA
539 BPTR lock;
540#endif
541 if(i<argc)
542 parm=argv[i];
543 else if(i<argc+count)
544 parm=confp[i-argc];
545 else
546 parm=cmfiles;
547 if(!parm||(*parm=='-'&&parm!=cmfiles)||!*parm) continue;
548 if(flags&VERYVERBOSE) printf("Argument %d:%s\n",i,parm);
549#ifdef AMIGA
550 if(pm&&parm!=cmfiles)
551 if(MatchFirst((STRPTR)convert_path(parm),ap)){
552 MatchEnd(ap);
553 printf("No match for %s\n",parm);
554 rc=RETURN_WARN;
555 continue;
556 }
557#endif
558 do{
559 if(parm==cmfiles){
560 file=parm;
561 t=CCSRC;
562 }else{
563#ifdef AMIGA
564#ifdef __amigaos4__
565 if(pm) file=(char *)ap->ap_Buffer; else file=parm;
566#else
567 if(pm) file=(char *)&ap->ap_Buf[0]; else file=parm;
568#endif
569#else
570 file=convert_path(parm);
571#endif
572 t=typ(file);
573 strcpy(namebuf+1,file);
574 strcat(namebuf,"\"");
575 file=namebuf;
576 }
577 if(flags&VERYVERBOSE) printf("File %s=%d\n",file,t);
578 if(!cmname&&(flags&CROSSMODULE)&&t<=CCSRC){
579 cmname=malloc(NAMEBUF);
580 if(!cmname){printf(nomem);exit(EXIT_FAILURE);}
581 if(tfl==OBJ){
582 strcpy(cmname,file);
583 }else{
584 cmname[0]='\"';
585 tmpnam(cmname+1);
586 strcat(cmname,".");
587 }
588 }
589 for(j=t;j<tfl;j++){
590 if(j==OBJ){
591 if(j==t) add_name(file,&first_obj,&last_obj);
592 continue;
593 }
594 strcpy(oldfile,file);
595 if(file==cmfiles){
596 file=cmoutput;
597 }else{
598 if(j==t&&j!=tfl-1&&!(flags&(NOTMPFILE|KEEPSCRATCH))){
599 file=namebuf2;
600 tmpnam(file+1);
601 strcat(file,".");
602 }
603 if(j==tfl-1||(flags&WPO)) file=namebuf;
604 }
605 if(j==PPSRC){
606 file=add_suffix(file,".i");
607 if(tfl==CCSRC&&(flags&OUTPUTSET)) file=destname;
608 sprintf(command,ppname,ppopts,oldfile,file);
609 if((tfl)!=CCSRC) add_name(file,&first_scratch,&last_scratch);
610 }
611 /* MUST come before CCSRC-handling! */
612 if(j==SCSRC){
613 /*if(final) file=cmname;*/
614 file=add_suffix(file,".asm");
615 if(tfl==ASSRC&&(flags&OUTPUTSET)) file=destname;
616 sprintf(command,scname,oldfile,file);
617 if(tfl!=ASSRC) add_name(file,&first_scratch,&last_scratch);
618 }
619 if(j==CCSRC){
620 if(file!=cmoutput){
621 if(flags&WPO){
622 if(flags&OUTPUTSET)
623 file=destname;
624 else
625 file=add_suffix(file,".o");
626 }else if(flags&SCHEDULER){
627 file=add_suffix(file,".scs");
628 }else{
629 if(++j==tfl-1) file=namebuf;
630 file=add_suffix(file,".asm");
631 }
632 if(tfl==j+1&&(flags&OUTPUTSET)) file=destname;
633 if(flags&CROSSMODULE){
634#ifdef USECMDFILE
635 if(!cmdfile){
636 char *s;
637 s=tmpnam(0);
638 cmfiles=malloc(strlen(s)+16);
639 if(!cmfiles){printf(nomem);exit(EXIT_FAILURE);}
640 sprintf(cmfiles,"-cmd= \"%s\"",s);
641 cmdfile=fopen(s,"w");
642 if(!cmdfile){printf("Could not open <%s>!\n",s);exit(EXIT_FAILURE);}
643 add_name(s,&first_scratch,&last_scratch);
644 }
645 fputs(oldfile,cmdfile);
646 fputs("\n",cmdfile);
647#else
648 if(!cmfiles){
649 cmfiles=malloc(strlen(oldfile)+3);
650 if(!cmfiles){printf(nomem);exit(EXIT_FAILURE);}
651 strcpy(cmfiles,oldfile);
652 }else{
653 cmfiles=realloc(cmfiles,strlen(cmfiles)+strlen(oldfile)+3);
654 if(!cmfiles){printf(nomem);exit(EXIT_FAILURE);}
655 strcat(cmfiles," ");strcat(cmfiles,oldfile);
656 }
657#endif
658 if(!cmoutput){
659 cmoutput=malloc(strlen(file)+1);
660 if(!cmoutput){printf(nomem);exit(EXIT_FAILURE);}
661 strcpy(cmoutput,file);
662 }
663 break;
664 }
665 }
666 if(flags&CROSSMODULE){
667#ifdef USECMDFILE
668 fclose(cmdfile);
669 cmdfile=0;
670#endif
671 final=1;
672 }
673 if((flags&(CROSSMODULE|SCHEDULER))==CROSSMODULE) j++;
674 sprintf(command,ccname,oldfile,file,options,opt);
675 if(flags&WPO){
676 strcat(command," -wpo");
677 j=OBJ;
678 }else{
679 if(tfl!=j+1) add_name(file,&first_scratch,&last_scratch);
680 }
681 if(deps&&tfl==OBJ&&(flags&OUTPUTSET)){
682 strcat(command," -depobj=");
683 strcat(command,destname);
684 }
685 }
686 if(j==ASSRC){
687 if(final) file=cmname;
688 file=add_suffix(file,".o");
689 if(tfl==OBJ&&(flags&OUTPUTSET)) file=destname;
690 sprintf(command,asname,oldfile,file);
691 add_name(file,&first_obj,&last_obj);
692 if((tfl)!=OBJ) add_name(file,&first_scratch,&last_scratch);
693 }
694 if(flags&VERBOSE) printf("%s\n",command);
695#ifdef AMIGA
696#if !defined(__amigaos4__) && !defined(__MORPHOS__)
697 if(DOSBase->dl_lib.lib_Version>=36){
698#else
699 if(1){
700#endif
701 if(SystemTags(command,NP_Priority,-2,TAG_DONE)){
702 printf("%s failed\n",command);
703 if(pm) MatchEnd(ap);
704 raus(EXIT_FAILURE);
705 }
706 }else
707#endif
708 if(runcmd(command)){printf("%s failed\n",command);raus(EXIT_FAILURE);}
709 }
710#ifdef AMIGA
711 }while(pm&&!MatchNext(ap));
712 if(pm) MatchEnd(ap);
713#else
714 }while(0);
715#endif
716 }
717 if((tfl)>OBJ){
718 /* Zu Executable linken */
719 struct NameList *p;
720 FILE *objfile=0;
721 char *tfname;
722 objects=malloc(linklen);
723 if(!objects){printf(nomem);raus(EXIT_FAILURE);}
724 linklen+=strlen(ldname)+strlen(destname)+strlen(userlibs)+10;
725#ifdef ATARI
726 if(vbccenv) linklen+=strlen(vbccenv)+5;
727#endif
728 if(flags&VERYVERBOSE) printf("linklen=%d\n",linklen);
729 if(!(linkcmd=malloc(linklen))){printf(nomem);raus(EXIT_FAILURE);}
730 p=first_obj;
731 if(linklen>=MAXCLEN){
732 tfname=tmpnam(0);
733 sprintf(objects,cf,tfname);
734 if(!(objfile=fopen(tfname,"w"))){
735 printf("Could not open <%s>!\n",tfname);
736 raus(EXIT_FAILURE);
737 }
738 }else *objects=0;
739 while(p){
740 if(p->obj){
741 if(linklen>=MAXCLEN){
742 fputs(p->obj,objfile);
743 fputs("\n",objfile);
744 }else{
745 strcat(objects,p->obj);strcat(objects," ");
746 }
747 }
748 p=p->next;
749 }
750 if(objfile) fclose(objfile);
751 if(*objects){
752 sprintf(linkcmd,ldname,objects,userlibs,destname);
753 if(flags&VERBOSE) printf("%s\n",linkcmd);
754 /* hier wird objfile bei Fehler nicht geloescht */
755 if(runcmd(linkcmd)){printf("%s failed\n",linkcmd);raus(EXIT_FAILURE);}
756#ifdef AMIGA
757 if(flags&VERBOSE){
758 BPTR l;
759 if(l=Lock((STRPTR)destname,-2)){
760 if(Examine(l,&fib)) printf("Size of executable: %lu bytes\n",(unsigned long)fib.fib_Size);
761 UnLock(l);
762 }
763 }
764#endif
765 }else puts("No objects to link");
766 if(objfile) remove(tfname);
767 }
768 if(!(flags&KEEPSCRATCH)) del_scratch(first_scratch);
769 raus(rc);
770}